diff --git a/layers/meta-belden-marvell-bsp/conf/machine/cn9130-cex7.conf b/layers/meta-belden-marvell-bsp/conf/machine/cn9130-cex7.conf new file mode 100644 index 0000000..6c4f83a --- /dev/null +++ b/layers/meta-belden-marvell-bsp/conf/machine/cn9130-cex7.conf @@ -0,0 +1,8 @@ +#@TYPE: Machine +#@NAME: cn9130 +#@DESCRIPTION: Machine support for Marvell Opteon TX2 CN9130. +# + +require conf/machine/include/cn913x.inc + +UBOOT_BUILDENV_DEVICE_TREE ?= "cn9130-cex7-A" diff --git a/layers/meta-belden-marvell-bsp/conf/machine/include/cn913x.inc b/layers/meta-belden-marvell-bsp/conf/machine/include/cn913x.inc index bd5c8fd..e4ca763 100644 --- a/layers/meta-belden-marvell-bsp/conf/machine/include/cn913x.inc +++ b/layers/meta-belden-marvell-bsp/conf/machine/include/cn913x.inc @@ -11,7 +11,7 @@ require conf/machine/include/soc-family.inc # ***************************************************************************** PREFERRED_PROVIDER_virtual/bootloader = "u-boot" -PREFERRED_VERSION_u-boot ?= "2023.04-marvell" +PREFERRED_VERSION_u-boot ?= "2019.10-solidrun" # All cn913x use the same defconfig for u-boot, but another devicetree by # settings UBOOT_BUILDENV_DEVICE_TREE in the machine configuration file diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0001-Remove-redundant-YYLOC-global-declaration.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0001-Remove-redundant-YYLOC-global-declaration.patch new file mode 100644 index 0000000..49b5a54 --- /dev/null +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0001-Remove-redundant-YYLOC-global-declaration.patch @@ -0,0 +1,24 @@ +From 0e0801291261a2c1267a42905d647cc0d1140791 Mon Sep 17 00:00:00 2001 +From: Peter Robinson +Date: Thu, 30 Jan 2020 09:37:15 +0000 +Subject: [PATCH] Remove redundant YYLOC global declaration + +Same as the upstream fix for building dtc with gcc 10. + +Signed-off-by: Peter Robinson +--- + scripts/dtc/dtc-lexer.l | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l +index fd825ebba6..24af549977 100644 +--- a/scripts/dtc/dtc-lexer.l ++++ b/scripts/dtc/dtc-lexer.l +@@ -38,7 +38,6 @@ LINECOMMENT "//".*\n + #include "srcpos.h" + #include "dtc-parser.tab.h" + +-YYLTYPE yylloc; + extern bool treesource_error; + + /* CAUTION: this will stop working if we ever use yyless() or yyunput() */ diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0001-cn9130-fix-compatible-node-inside-dts-pt-2.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0001-cn9130-fix-compatible-node-inside-dts-pt-2.patch new file mode 100644 index 0000000..a63e32b --- /dev/null +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0001-cn9130-fix-compatible-node-inside-dts-pt-2.patch @@ -0,0 +1,26 @@ +From 841657cef0b50f6e3af4d3d3c829e438fbac7cc3 Mon Sep 17 00:00:00 2001 +From: Patrick Vogelaar +Date: Wed, 19 Apr 2023 09:07:10 +0200 +Subject: [PATCH] fix u-boot device tree compatible + +--- + arch/arm/dts/cn9131-bldn-mbv.dts | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/arch/arm/dts/cn9131-bldn-mbv.dts b/arch/arm/dts/cn9131-bldn-mbv.dts +index d10c7f032e..74322805db 100644 +--- a/arch/arm/dts/cn9131-bldn-mbv.dts ++++ b/arch/arm/dts/cn9131-bldn-mbv.dts +@@ -11,8 +11,10 @@ + + / { + model = "Belden CN9131 based Platform"; +- compatible = "marvell,cn9131-db", "marvell,armada-ap806-quad", +- "marvell,armada-ap806"; ++ compatible = "solidrun,cn9131-bldn-mbv", "marvell,cn9130-db", ++ "marvell,cn91xx", "marvell,cn9030-vd", "marvell,cn9030", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806", ++ "marvell,armada70x0"; + }; + + &cp1_comphy { diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0001-cn9130-fix-compatible-node-inside-dts.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0001-cn9130-fix-compatible-node-inside-dts.patch new file mode 100644 index 0000000..295c12b --- /dev/null +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0001-cn9130-fix-compatible-node-inside-dts.patch @@ -0,0 +1,65 @@ +From 0017797ce718f4512271deddde75120c57623049 Mon Sep 17 00:00:00 2001 +From: Samuel Dolt +Date: Tue, 24 Jan 2023 15:22:58 +0100 +Subject: [PATCH] cn9130: fix compatible node inside dts + +--- + arch/arm/dts/cn9130-bldn-mbv.dts | 7 ++++--- + arch/arm/dts/cn9130-cex7-A.dts | 7 ++++--- + arch/arm/dts/cn9130-cf-pro.dts | 7 ++++--- + 3 files changed, 12 insertions(+), 9 deletions(-) + +diff --git a/arch/arm/dts/cn9130-bldn-mbv.dts b/arch/arm/dts/cn9130-bldn-mbv.dts +index 9e10eab008..a91c490218 100644 +--- a/arch/arm/dts/cn9130-bldn-mbv.dts ++++ b/arch/arm/dts/cn9130-bldn-mbv.dts +@@ -10,9 +10,10 @@ + + / { + model = "Belden CN9130 based SOM and Carrier MBV-A/B"; +- compatible = "marvell,cn9130-db", "marvell,cn91xx", "marvell,cn9030-vd", +- "marvell,cn9030", "marvell,armada-ap806-quad", +- "marvell,armada-ap806", "marvell,armada70x0"; ++ compatible = "solidrun,cn9130-bldn-mbv", "marvell,cn9130-db", ++ "marvell,cn91xx", "marvell,cn9030-vd", "marvell,cn9030", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806", ++ "marvell,armada70x0"; + + chosen { + stdout-path = "serial0:115200n8"; +diff --git a/arch/arm/dts/cn9130-cex7-A.dts b/arch/arm/dts/cn9130-cex7-A.dts +index 209e485822..9995a586f6 100644 +--- a/arch/arm/dts/cn9130-cex7-A.dts ++++ b/arch/arm/dts/cn9130-cex7-A.dts +@@ -10,9 +10,10 @@ + + / { + model = "SolidRun CN9130 based COM express type 7"; +- compatible = "marvell,cn9130-db", "marvell,cn91xx", "marvell,cn9030-vd", +- "marvell,cn9030", "marvell,armada-ap806-quad", +- "marvell,armada-ap806", "marvell,armada70x0"; ++ compatible = "solidrun,cn9130-cex7", "marvell,cn9130-db", ++ "marvell,cn91xx", "marvell,cn9030-vd", "marvell,cn9030", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806", ++ "marvell,armada70x0"; + + chosen { + stdout-path = "serial0:115200n8"; +diff --git a/arch/arm/dts/cn9130-cf-pro.dts b/arch/arm/dts/cn9130-cf-pro.dts +index 6931818cf6..dae7a75076 100644 +--- a/arch/arm/dts/cn9130-cf-pro.dts ++++ b/arch/arm/dts/cn9130-cf-pro.dts +@@ -10,9 +10,10 @@ + + / { + model = "SolidRun CN9130 based SOM ClearFog Pro"; +- compatible = "marvell,cn9130-db", "marvell,cn91xx", "marvell,cn9030-vd", +- "marvell,cn9030", "marvell,armada-ap806-quad", +- "marvell,armada-ap806", "marvell,armada70x0"; ++ compatible = "solidrun,cn9130-cf-pro", "marvell,cn9130-db", ++ "marvell,cn91xx", "marvell,cn9030-vd", "marvell,cn9030", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806", ++ "marvell,armada70x0"; + + chosen { + stdout-path = "serial0:115200n8"; diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0001-sr_cn913x_cex7-enable-VERSION_VARIABLE.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0001-sr_cn913x_cex7-enable-VERSION_VARIABLE.patch new file mode 100644 index 0000000..9424ad4 --- /dev/null +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0001-sr_cn913x_cex7-enable-VERSION_VARIABLE.patch @@ -0,0 +1,18 @@ +From 8b62e225c541fdfcc764582ee80bf0d8a0b6bc65 Mon Sep 17 00:00:00 2001 +From: Samuel Dolt +Date: Mon, 25 Jul 2022 15:02:00 +0200 +Subject: [PATCH] sr_cn913x_cex7: enable VERSION_VARIABLE + +--- + configs/sr_cn913x_cex7_defconfig | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/configs/sr_cn913x_cex7_defconfig b/configs/sr_cn913x_cex7_defconfig +index 3e01b31371..a7c6c9f93e 100644 +--- a/configs/sr_cn913x_cex7_defconfig ++++ b/configs/sr_cn913x_cex7_defconfig +@@ -115,3 +115,4 @@ CONFIG_ZSTD=y + CONFIG_FIT=y + CONFIG_FIT_VERBOSE=y + CONFIG_OF_LIBFDT=y ++CONFIG_VERSION_VARIABLE=y diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0001-sr_cn913x_cex7-enable-more-image-formats.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0001-sr_cn913x_cex7-enable-more-image-formats.patch new file mode 100644 index 0000000..22d0bb8 --- /dev/null +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0001-sr_cn913x_cex7-enable-more-image-formats.patch @@ -0,0 +1,27 @@ +From ca34fc483e68e332c5aa6c3cc98e04604216d846 Mon Sep 17 00:00:00 2001 +From: Samuel Dolt +Date: Fri, 15 Jul 2022 15:36:12 +0200 +Subject: [PATCH] sr_cn913x_cex7: enable more image formats + +--- + configs/sr_cn913x_cex7_defconfig | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/configs/sr_cn913x_cex7_defconfig b/configs/sr_cn913x_cex7_defconfig +index d7445e9476..3e01b31371 100644 +--- a/configs/sr_cn913x_cex7_defconfig ++++ b/configs/sr_cn913x_cex7_defconfig +@@ -105,3 +105,13 @@ CONFIG_I2C_EEPROM=y + CONFIG_CMD_TLV_EEPROM=y + CONFIG_SUPPORT_EMMC_BOOT=y + CONFIG_NET_RANDOM_ETHADDR=y ++# Custom ++CONFIG_BZIP2=y ++CONFIG_GZIP=y ++CONFIG_LZ4=y ++CONFIG_LZMA=y ++CONFIG_LZO=y ++CONFIG_ZSTD=y ++CONFIG_FIT=y ++CONFIG_FIT_VERBOSE=y ++CONFIG_OF_LIBFDT=y diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0021-octeontx2_cn913x-increase-CONFIG_SYS_BOOTM_LEN-to-32.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0021-octeontx2_cn913x-increase-CONFIG_SYS_BOOTM_LEN-to-32.patch new file mode 100644 index 0000000..33e4001 --- /dev/null +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/0021-octeontx2_cn913x-increase-CONFIG_SYS_BOOTM_LEN-to-32.patch @@ -0,0 +1,22 @@ +From 7e4c3c48c4ed9dcecf5228c6b4480a7c01fc6dca Mon Sep 17 00:00:00 2001 +From: Samuel Dolt +Date: Tue, 19 Jul 2022 11:21:37 +0200 +Subject: [PATCH] octeontx2_cn913x: increase CONFIG_SYS_BOOTM_LEN to 32MB + +--- + include/configs/octeontx2_cn913x.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/include/configs/octeontx2_cn913x.h b/include/configs/octeontx2_cn913x.h +index d01644fcb5..9edf57c6c2 100644 +--- a/include/configs/octeontx2_cn913x.h ++++ b/include/configs/octeontx2_cn913x.h +@@ -22,6 +22,8 @@ + #define CONFIG_SYS_NAND_ONFI_DETECTION + #define CONFIG_SYS_NAND_USE_FLASH_BBT + ++#define CONFIG_SYS_BOOTM_LEN 0x3200000 /* 32MB */ ++ + #define CONFIG_USB_MAX_CONTROLLER_COUNT (3 + 3) + + #define BOOT_TARGET_DEVICES(func) \ diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0001-cmd-add-tlv_eeprom-command.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0001-cmd-add-tlv_eeprom-command.patch new file mode 100644 index 0000000..a27a07a --- /dev/null +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0001-cmd-add-tlv_eeprom-command.patch @@ -0,0 +1,1341 @@ +From 544924b71d15bc47aba15fa1f75ec56b25a63a6d Mon Sep 17 00:00:00 2001 +From: Baruch Siach +Date: Tue, 21 Jan 2020 15:44:54 +0200 +Subject: [PATCH] cmd: add tlv_eeprom command + +Add support for read/write of ONIE "Tlvinfo" EEPROM data format. TLV +stands for Type-Length-Value. The data format is described here: + + https://opencomputeproject.github.io/onie/design-spec/hw_requirements.html#board-eeprom-information-format + +Based on U-Boot patch from the Open Compute project: + + https://github.com/opencomputeproject/onie/blob/ec87e872d46b9805565d2c6124b2f701ef1c07b1/patches/u-boot/common/feature-sys-eeprom-tlv-common.patch + +Keep only I2C EEPROM support. Use the generic eeprom driver. Fix +checkpatch issues. + +Add support for multiple EEPROM TLV stores on the same system. This is +useful in case of SOM and carrier that both provide ID and hardware +configuration information. + +Add option to enable for SPL. This allows selection of RAM configuration +based on EEPROM stored board identification. + +Signed-off-by: Baruch Siach +--- + cmd/Kconfig | 14 + + cmd/Makefile | 2 + + cmd/tlv_eeprom.c | 1105 ++++++++++++++++++++++++++++++++++++++++++ + include/tlv_eeprom.h | 152 ++++++ + 4 files changed, 1273 insertions(+) + create mode 100644 cmd/tlv_eeprom.c + create mode 100644 include/tlv_eeprom.h + +diff --git a/cmd/Kconfig b/cmd/Kconfig +index 4e61565aab..f696645c91 100644 +--- a/cmd/Kconfig ++++ b/cmd/Kconfig +@@ -232,6 +232,20 @@ config CMD_REGINFO + help + Register dump + ++config CMD_TLV_EEPROM ++ bool "tlv_eeprom" ++ depends on I2C_EEPROM ++ help ++ Display and program the system EEPROM data block in ONIE Tlvinfo ++ format. TLV stands for Type-Length-Value. ++ ++config SPL_CMD_TLV_EEPROM ++ bool "tlv_eeprom for SPL" ++ depends on SPL_I2C_EEPROM ++ select SPL_DRIVERS_MISC_SUPPORT ++ help ++ Read system EEPROM data block in ONIE Tlvinfo format from SPL. ++ + endmenu + + menu "Boot commands" +diff --git a/cmd/Makefile b/cmd/Makefile +index ac843b4b16..c10f2e308b 100644 +--- a/cmd/Makefile ++++ b/cmd/Makefile +@@ -180,6 +180,8 @@ obj-$(CONFIG_X86) += x86/ + obj-$(CONFIG_ARCH_MVEBU) += mvebu/ + endif # !CONFIG_SPL_BUILD + ++obj-$(CONFIG_$(SPL_)CMD_TLV_EEPROM) += tlv_eeprom.o ++ + # core command + obj-y += nvedit.o + +diff --git a/cmd/tlv_eeprom.c b/cmd/tlv_eeprom.c +new file mode 100644 +index 0000000000..211ab2680f +--- /dev/null ++++ b/cmd/tlv_eeprom.c +@@ -0,0 +1,1105 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * Copyright (C) 2013 Curt Brune ++ * Copyright (C) 2014 Srideep ++ * Copyright (C) 2013 Miles Tseng ++ * Copyright (C) 2014,2016 david_yang ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "tlv_eeprom.h" ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++#define MAX_TLV_DEVICES 2 ++ ++/* File scope function prototypes */ ++static bool is_checksum_valid(u8 *eeprom); ++static int read_eeprom(u8 *eeprom); ++static void show_eeprom(u8 *eeprom); ++static void decode_tlv(struct tlvinfo_tlv *tlv); ++static void update_crc(u8 *eeprom); ++static int prog_eeprom(u8 *eeprom); ++static bool tlvinfo_find_tlv(u8 *eeprom, u8 tcode, int *eeprom_index); ++static bool tlvinfo_delete_tlv(u8 *eeprom, u8 code); ++static bool tlvinfo_add_tlv(u8 *eeprom, int tcode, char *strval); ++static int set_mac(char *buf, const char *string); ++static int set_date(char *buf, const char *string); ++static int set_bytes(char *buf, const char *string, int *converted_accum); ++static void show_tlv_devices(void); ++ ++/* Set to 1 if we've read EEPROM into memory */ ++static int has_been_read; ++/* The EERPOM contents after being read into memory */ ++static u8 eeprom[TLV_INFO_MAX_LEN]; ++ ++static struct udevice *tlv_devices[MAX_TLV_DEVICES]; ++static unsigned int current_dev; ++ ++#define to_header(p) ((struct tlvinfo_header *)p) ++#define to_entry(p) ((struct tlvinfo_tlv *)p) ++ ++#define HDR_SIZE sizeof(struct tlvinfo_header) ++#define ENT_SIZE sizeof(struct tlvinfo_tlv) ++ ++static inline bool is_digit(char c) ++{ ++ return (c >= '0' && c <= '9'); ++} ++ ++/** ++ * is_valid_tlv ++ * ++ * Perform basic sanity checks on a TLV field. The TLV is pointed to ++ * by the parameter provided. ++ * 1. The type code is not reserved (0x00 or 0xFF) ++ */ ++static inline bool is_valid_tlv(struct tlvinfo_tlv *tlv) ++{ ++ return((tlv->type != 0x00) && (tlv->type != 0xFF)); ++} ++ ++/** ++ * is_hex ++ * ++ * Tests if character is an ASCII hex digit ++ */ ++static inline u8 is_hex(char p) ++{ ++ return (((p >= '0') && (p <= '9')) || ++ ((p >= 'A') && (p <= 'F')) || ++ ((p >= 'a') && (p <= 'f'))); ++} ++ ++/** ++ * is_checksum_valid ++ * ++ * Validate the checksum in the provided TlvInfo EEPROM data. First, ++ * verify that the TlvInfo header is valid, then make sure the last ++ * TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data ++ * and compare it to the value stored in the EEPROM CRC-32 TLV. ++ */ ++static bool is_checksum_valid(u8 *eeprom) ++{ ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ struct tlvinfo_tlv *eeprom_crc; ++ unsigned int calc_crc; ++ unsigned int stored_crc; ++ ++ // Is the eeprom header valid? ++ if (!is_valid_tlvinfo_header(eeprom_hdr)) ++ return false; ++ ++ // Is the last TLV a CRC? ++ eeprom_crc = to_entry(&eeprom[HDR_SIZE + ++ be16_to_cpu(eeprom_hdr->totallen) - (ENT_SIZE + 4)]); ++ if (eeprom_crc->type != TLV_CODE_CRC_32 || eeprom_crc->length != 4) ++ return false; ++ ++ // Calculate the checksum ++ calc_crc = crc32(0, (void *)eeprom, ++ HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen) - 4); ++ stored_crc = (eeprom_crc->value[0] << 24) | ++ (eeprom_crc->value[1] << 16) | ++ (eeprom_crc->value[2] << 8) | ++ eeprom_crc->value[3]; ++ return calc_crc == stored_crc; ++} ++ ++/** ++ * read_eeprom ++ * ++ * Read the EEPROM into memory, if it hasn't already been read. ++ */ ++static int read_eeprom(u8 *eeprom) ++{ ++ int ret; ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ struct tlvinfo_tlv *eeprom_tlv = to_entry(&eeprom[HDR_SIZE]); ++ ++ if (has_been_read) ++ return 0; ++ ++ /* Read the header */ ++ ret = read_tlv_eeprom((void *)eeprom_hdr, 0, HDR_SIZE, current_dev); ++ /* If the header was successfully read, read the TLVs */ ++ if (ret == 0 && is_valid_tlvinfo_header(eeprom_hdr)) ++ ret = read_tlv_eeprom((void *)eeprom_tlv, HDR_SIZE, ++ be16_to_cpu(eeprom_hdr->totallen), ++ current_dev); ++ ++ // If the contents are invalid, start over with default contents ++ if (!is_valid_tlvinfo_header(eeprom_hdr) || ++ !is_checksum_valid(eeprom)) { ++ strcpy(eeprom_hdr->signature, TLV_INFO_ID_STRING); ++ eeprom_hdr->version = TLV_INFO_VERSION; ++ eeprom_hdr->totallen = cpu_to_be16(0); ++ update_crc(eeprom); ++ } ++ ++ has_been_read = 1; ++ ++#ifdef DEBUG ++ show_eeprom(eeprom); ++#endif ++ ++ return ret; ++} ++ ++/** ++ * show_eeprom ++ * ++ * Display the contents of the EEPROM ++ */ ++static void show_eeprom(u8 *eeprom) ++{ ++ int tlv_end; ++ int curr_tlv; ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ struct tlvinfo_tlv *eeprom_tlv; ++ ++ if (!is_valid_tlvinfo_header(eeprom_hdr)) { ++ printf("EEPROM does not contain data in a valid TlvInfo format.\n"); ++ return; ++ } ++ ++ printf("TLV: %u\n", current_dev); ++ printf("TlvInfo Header:\n"); ++ printf(" Id String: %s\n", eeprom_hdr->signature); ++ printf(" Version: %d\n", eeprom_hdr->version); ++ printf(" Total Length: %d\n", be16_to_cpu(eeprom_hdr->totallen)); ++ ++ printf("TLV Name Code Len Value\n"); ++ printf("-------------------- ---- --- -----\n"); ++ curr_tlv = HDR_SIZE; ++ tlv_end = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); ++ while (curr_tlv < tlv_end) { ++ eeprom_tlv = to_entry(&eeprom[curr_tlv]); ++ if (!is_valid_tlv(eeprom_tlv)) { ++ printf("Invalid TLV field starting at EEPROM offset %d\n", ++ curr_tlv); ++ return; ++ } ++ decode_tlv(eeprom_tlv); ++ curr_tlv += ENT_SIZE + eeprom_tlv->length; ++ } ++ ++ printf("Checksum is %s.\n", ++ is_checksum_valid(eeprom) ? "valid" : "invalid"); ++ ++#ifdef DEBUG ++ printf("EEPROM dump: (0x%x bytes)", TLV_INFO_MAX_LEN); ++ for (i = 0; i < TLV_INFO_MAX_LEN; i++) { ++ if ((i % 16) == 0) ++ printf("\n%02X: ", i); ++ printf("%02X ", eeprom[i]); ++ } ++ printf("\n"); ++#endif ++} ++ ++/** ++ * Struct for displaying the TLV codes and names. ++ */ ++struct tlv_code_desc { ++ u8 m_code; ++ char *m_name; ++}; ++ ++/** ++ * List of TLV codes and names. ++ */ ++static struct tlv_code_desc tlv_code_list[] = { ++ { TLV_CODE_PRODUCT_NAME, "Product Name"}, ++ { TLV_CODE_PART_NUMBER, "Part Number"}, ++ { TLV_CODE_SERIAL_NUMBER, "Serial Number"}, ++ { TLV_CODE_MAC_BASE, "Base MAC Address"}, ++ { TLV_CODE_MANUF_DATE, "Manufacture Date"}, ++ { TLV_CODE_DEVICE_VERSION, "Device Version"}, ++ { TLV_CODE_LABEL_REVISION, "Label Revision"}, ++ { TLV_CODE_PLATFORM_NAME, "Platform Name"}, ++ { TLV_CODE_ONIE_VERSION, "ONIE Version"}, ++ { TLV_CODE_MAC_SIZE, "MAC Addresses"}, ++ { TLV_CODE_MANUF_NAME, "Manufacturer"}, ++ { TLV_CODE_MANUF_COUNTRY, "Country Code"}, ++ { TLV_CODE_VENDOR_NAME, "Vendor Name"}, ++ { TLV_CODE_DIAG_VERSION, "Diag Version"}, ++ { TLV_CODE_SERVICE_TAG, "Service Tag"}, ++ { TLV_CODE_VENDOR_EXT, "Vendor Extension"}, ++ { TLV_CODE_CRC_32, "CRC-32"}, ++}; ++ ++/** ++ * Look up a TLV name by its type. ++ */ ++static inline const char *tlv_type2name(u8 type) ++{ ++ char *name = "Unknown"; ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(tlv_code_list); i++) { ++ if (tlv_code_list[i].m_code == type) { ++ name = tlv_code_list[i].m_name; ++ break; ++ } ++ } ++ ++ return name; ++} ++ ++/* ++ * decode_tlv ++ * ++ * Print a string representing the contents of the TLV field. The format of ++ * the string is: ++ * 1. The name of the field left justified in 20 characters ++ * 2. The type code in hex right justified in 5 characters ++ * 3. The length in decimal right justified in 4 characters ++ * 4. The value, left justified in however many characters it takes ++ * The validity of EEPROM contents and the TLV field have been verified ++ * prior to calling this function. ++ */ ++#define DECODE_NAME_MAX 20 ++ ++/* ++ * The max decode value is currently for the 'raw' type or the 'vendor ++ * extension' type, both of which have the same decode format. The ++ * max decode string size is computed as follows: ++ * ++ * strlen(" 0xFF") * TLV_VALUE_MAX_LEN + 1 ++ * ++ */ ++#define DECODE_VALUE_MAX ((5 * TLV_VALUE_MAX_LEN) + 1) ++ ++static void decode_tlv(struct tlvinfo_tlv *tlv) ++{ ++ char name[DECODE_NAME_MAX]; ++ char value[DECODE_VALUE_MAX]; ++ int i; ++ ++ strncpy(name, tlv_type2name(tlv->type), DECODE_NAME_MAX); ++ ++ switch (tlv->type) { ++ case TLV_CODE_PRODUCT_NAME: ++ case TLV_CODE_PART_NUMBER: ++ case TLV_CODE_SERIAL_NUMBER: ++ case TLV_CODE_MANUF_DATE: ++ case TLV_CODE_LABEL_REVISION: ++ case TLV_CODE_PLATFORM_NAME: ++ case TLV_CODE_ONIE_VERSION: ++ case TLV_CODE_MANUF_NAME: ++ case TLV_CODE_MANUF_COUNTRY: ++ case TLV_CODE_VENDOR_NAME: ++ case TLV_CODE_DIAG_VERSION: ++ case TLV_CODE_SERVICE_TAG: ++ memcpy(value, tlv->value, tlv->length); ++ value[tlv->length] = 0; ++ break; ++ case TLV_CODE_MAC_BASE: ++ sprintf(value, "%02X:%02X:%02X:%02X:%02X:%02X", ++ tlv->value[0], tlv->value[1], tlv->value[2], ++ tlv->value[3], tlv->value[4], tlv->value[5]); ++ break; ++ case TLV_CODE_DEVICE_VERSION: ++ sprintf(value, "%u", tlv->value[0]); ++ break; ++ case TLV_CODE_MAC_SIZE: ++ sprintf(value, "%u", (tlv->value[0] << 8) | tlv->value[1]); ++ break; ++ case TLV_CODE_VENDOR_EXT: ++ value[0] = 0; ++ for (i = 0; (i < (DECODE_VALUE_MAX / 5)) && (i < tlv->length); ++ i++) { ++ sprintf(value, "%s 0x%02X", value, tlv->value[i]); ++ } ++ break; ++ case TLV_CODE_CRC_32: ++ sprintf(value, "0x%02X%02X%02X%02X", ++ tlv->value[0], tlv->value[1], ++ tlv->value[2], tlv->value[3]); ++ break; ++ default: ++ value[0] = 0; ++ for (i = 0; (i < (DECODE_VALUE_MAX / 5)) && (i < tlv->length); ++ i++) { ++ sprintf(value, "%s 0x%02X", value, tlv->value[i]); ++ } ++ break; ++ } ++ ++ name[DECODE_NAME_MAX - 1] = 0; ++ printf("%-20s 0x%02X %3d %s\n", name, tlv->type, tlv->length, value); ++} ++ ++/** ++ * update_crc ++ * ++ * This function updates the CRC-32 TLV. If there is no CRC-32 TLV, then ++ * one is added. This function should be called after each update to the ++ * EEPROM structure, to make sure the CRC is always correct. ++ */ ++static void update_crc(u8 *eeprom) ++{ ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ struct tlvinfo_tlv *eeprom_crc; ++ unsigned int calc_crc; ++ int eeprom_index; ++ ++ // Discover the CRC TLV ++ if (!tlvinfo_find_tlv(eeprom, TLV_CODE_CRC_32, &eeprom_index)) { ++ unsigned int totallen = be16_to_cpu(eeprom_hdr->totallen); ++ ++ if ((totallen + ENT_SIZE + 4) > TLV_TOTAL_LEN_MAX) ++ return; ++ eeprom_index = HDR_SIZE + totallen; ++ eeprom_hdr->totallen = cpu_to_be16(totallen + ENT_SIZE + 4); ++ } ++ eeprom_crc = to_entry(&eeprom[eeprom_index]); ++ eeprom_crc->type = TLV_CODE_CRC_32; ++ eeprom_crc->length = 4; ++ ++ // Calculate the checksum ++ calc_crc = crc32(0, (void *)eeprom, ++ HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen) - 4); ++ eeprom_crc->value[0] = (calc_crc >> 24) & 0xFF; ++ eeprom_crc->value[1] = (calc_crc >> 16) & 0xFF; ++ eeprom_crc->value[2] = (calc_crc >> 8) & 0xFF; ++ eeprom_crc->value[3] = (calc_crc >> 0) & 0xFF; ++} ++ ++/** ++ * prog_eeprom ++ * ++ * Write the EEPROM data from CPU memory to the hardware. ++ */ ++static int prog_eeprom(u8 *eeprom) ++{ ++ int ret = 0; ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ int eeprom_len; ++ ++ update_crc(eeprom); ++ ++ eeprom_len = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); ++ ret = write_tlv_eeprom(eeprom, eeprom_len); ++ if (ret) { ++ printf("Programming failed.\n"); ++ return -1; ++ } ++ ++ printf("Programming passed.\n"); ++ return 0; ++} ++ ++/** ++ * show_tlv_code_list - Display the list of TLV codes and names ++ */ ++void show_tlv_code_list(void) ++{ ++ int i; ++ ++ printf("TLV Code TLV Name\n"); ++ printf("======== =================\n"); ++ for (i = 0; i < ARRAY_SIZE(tlv_code_list); i++) { ++ printf("0x%02X %s\n", ++ tlv_code_list[i].m_code, ++ tlv_code_list[i].m_name); ++ } ++} ++ ++/** ++ * do_tlv_eeprom ++ * ++ * This function implements the tlv_eeprom command. ++ */ ++int do_tlv_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) ++{ ++ char cmd; ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ ++ // If no arguments, read the EERPOM and display its contents ++ if (argc == 1) { ++ read_eeprom(eeprom); ++ show_eeprom(eeprom); ++ return 0; ++ } ++ ++ // We only look at the first character to the command, so "read" and ++ // "reset" will both be treated as "read". ++ cmd = argv[1][0]; ++ ++ // Read the EEPROM contents ++ if (cmd == 'r') { ++ has_been_read = 0; ++ if (!read_eeprom(eeprom)) ++ printf("EEPROM data loaded from device to memory.\n"); ++ return 0; ++ } ++ ++ // Subsequent commands require that the EEPROM has already been read. ++ if (!has_been_read) { ++ printf("Please read the EEPROM data first, using the 'tlv_eeprom read' command.\n"); ++ return 0; ++ } ++ ++ // Handle the commands that don't take parameters ++ if (argc == 2) { ++ switch (cmd) { ++ case 'w': /* write */ ++ prog_eeprom(eeprom); ++ break; ++ case 'e': /* erase */ ++ strcpy(eeprom_hdr->signature, TLV_INFO_ID_STRING); ++ eeprom_hdr->version = TLV_INFO_VERSION; ++ eeprom_hdr->totallen = cpu_to_be16(0); ++ update_crc(eeprom); ++ printf("EEPROM data in memory reset.\n"); ++ break; ++ case 'l': /* list */ ++ show_tlv_code_list(); ++ break; ++ case 'd': /* dev */ ++ show_tlv_devices(); ++ break; ++ default: ++ cmd_usage(cmdtp); ++ break; ++ } ++ return 0; ++ } ++ ++ // The set command takes one or two args. ++ if (argc > 4) { ++ cmd_usage(cmdtp); ++ return 0; ++ } ++ ++ // Set command. If the TLV exists in the EEPROM, delete it. Then if ++ // data was supplied for this TLV add the TLV with the new contents at ++ // the end. ++ if (cmd == 's') { ++ int tcode; ++ ++ tcode = simple_strtoul(argv[2], NULL, 0); ++ tlvinfo_delete_tlv(eeprom, tcode); ++ if (argc == 4) ++ tlvinfo_add_tlv(eeprom, tcode, argv[3]); ++ } else if (cmd == 'd') { /* 'dev' command */ ++ unsigned int devnum; ++ ++ devnum = simple_strtoul(argv[2], NULL, 0); ++ if (devnum > MAX_TLV_DEVICES || !tlv_devices[devnum]) { ++ printf("Invalid device number\n"); ++ return 0; ++ } ++ current_dev = devnum; ++ has_been_read = 0; ++ } else { ++ cmd_usage(cmdtp); ++ } ++ ++ return 0; ++} ++ ++/** ++ * This macro defines the tlv_eeprom command line command. ++ */ ++U_BOOT_CMD(tlv_eeprom, 4, 1, do_tlv_eeprom, ++ "Display and program the system EEPROM data block.", ++ "[read|write|set |erase|list]\n" ++ "tlv_eeprom\n" ++ " - With no arguments display the current contents.\n" ++ "tlv_eeprom dev [dev]\n" ++ " - List devices or set current EEPROM device.\n" ++ "tlv_eeprom read\n" ++ " - Load EEPROM data from device to memory.\n" ++ "tlv_eeprom write\n" ++ " - Write the EEPROM data to persistent storage.\n" ++ "tlv_eeprom set \n" ++ " - Set a field to a value.\n" ++ " - If no string_value, field is deleted.\n" ++ " - Use 'tlv_eeprom write' to make changes permanent.\n" ++ "tlv_eeprom erase\n" ++ " - Reset the in memory EEPROM data.\n" ++ " - Use 'tlv_eeprom read' to refresh the in memory EEPROM data.\n" ++ " - Use 'tlv_eeprom write' to make changes permanent.\n" ++ "tlv_eeprom list\n" ++ " - List the understood TLV codes and names.\n" ++ ); ++ ++/** ++ * tlvinfo_find_tlv ++ * ++ * This function finds the TLV with the supplied code in the EERPOM. ++ * An offset from the beginning of the EEPROM is returned in the ++ * eeprom_index parameter if the TLV is found. ++ */ ++static bool tlvinfo_find_tlv(u8 *eeprom, u8 tcode, int *eeprom_index) ++{ ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ struct tlvinfo_tlv *eeprom_tlv; ++ int eeprom_end; ++ ++ // Search through the TLVs, looking for the first one which matches the ++ // supplied type code. ++ *eeprom_index = HDR_SIZE; ++ eeprom_end = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); ++ while (*eeprom_index < eeprom_end) { ++ eeprom_tlv = to_entry(&eeprom[*eeprom_index]); ++ if (!is_valid_tlv(eeprom_tlv)) ++ return false; ++ if (eeprom_tlv->type == tcode) ++ return true; ++ *eeprom_index += ENT_SIZE + eeprom_tlv->length; ++ } ++ return(false); ++} ++ ++/** ++ * tlvinfo_delete_tlv ++ * ++ * This function deletes the TLV with the specified type code from the ++ * EEPROM. ++ */ ++static bool tlvinfo_delete_tlv(u8 *eeprom, u8 code) ++{ ++ int eeprom_index; ++ int tlength; ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ struct tlvinfo_tlv *eeprom_tlv; ++ ++ // Find the TLV and then move all following TLVs "forward" ++ if (tlvinfo_find_tlv(eeprom, code, &eeprom_index)) { ++ eeprom_tlv = to_entry(&eeprom[eeprom_index]); ++ tlength = ENT_SIZE + eeprom_tlv->length; ++ memcpy(&eeprom[eeprom_index], &eeprom[eeprom_index + tlength], ++ HDR_SIZE + ++ be16_to_cpu(eeprom_hdr->totallen) - eeprom_index - ++ tlength); ++ eeprom_hdr->totallen = ++ cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) - ++ tlength); ++ update_crc(eeprom); ++ return true; ++ } ++ return false; ++} ++ ++/** ++ * tlvinfo_add_tlv ++ * ++ * This function adds a TLV to the EEPROM, converting the value (a string) to ++ * the format in which it will be stored in the EEPROM. ++ */ ++#define MAX_TLV_VALUE_LEN 256 ++static bool tlvinfo_add_tlv(u8 *eeprom, int tcode, char *strval) ++{ ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ struct tlvinfo_tlv *eeprom_tlv; ++ int new_tlv_len = 0; ++ u32 value; ++ char data[MAX_TLV_VALUE_LEN]; ++ int eeprom_index; ++ ++ // Encode each TLV type into the format to be stored in the EERPOM ++ switch (tcode) { ++ case TLV_CODE_PRODUCT_NAME: ++ case TLV_CODE_PART_NUMBER: ++ case TLV_CODE_SERIAL_NUMBER: ++ case TLV_CODE_LABEL_REVISION: ++ case TLV_CODE_PLATFORM_NAME: ++ case TLV_CODE_ONIE_VERSION: ++ case TLV_CODE_MANUF_NAME: ++ case TLV_CODE_MANUF_COUNTRY: ++ case TLV_CODE_VENDOR_NAME: ++ case TLV_CODE_DIAG_VERSION: ++ case TLV_CODE_SERVICE_TAG: ++ strncpy(data, strval, MAX_TLV_VALUE_LEN); ++ new_tlv_len = min_t(size_t, MAX_TLV_VALUE_LEN, strlen(strval)); ++ break; ++ case TLV_CODE_DEVICE_VERSION: ++ value = simple_strtoul(strval, NULL, 0); ++ if (value >= 256) { ++ printf("ERROR: Device version must be 255 or less. Value supplied: %u", ++ value); ++ return false; ++ } ++ data[0] = value & 0xFF; ++ new_tlv_len = 1; ++ break; ++ case TLV_CODE_MAC_SIZE: ++ value = simple_strtoul(strval, NULL, 0); ++ if (value >= 65536) { ++ printf("ERROR: MAC Size must be 65535 or less. Value supplied: %u", ++ value); ++ return false; ++ } ++ data[0] = (value >> 8) & 0xFF; ++ data[1] = value & 0xFF; ++ new_tlv_len = 2; ++ break; ++ case TLV_CODE_MANUF_DATE: ++ if (set_date(data, strval) != 0) ++ return false; ++ new_tlv_len = 19; ++ break; ++ case TLV_CODE_MAC_BASE: ++ if (set_mac(data, strval) != 0) ++ return false; ++ new_tlv_len = 6; ++ break; ++ case TLV_CODE_CRC_32: ++ printf("WARNING: The CRC TLV is set automatically and cannot be set manually.\n"); ++ return false; ++ case TLV_CODE_VENDOR_EXT: ++ default: ++ if (set_bytes(data, strval, &new_tlv_len) != 0) ++ return false; ++ break; ++ } ++ ++ // Is there room for this TLV? ++ if ((be16_to_cpu(eeprom_hdr->totallen) + ENT_SIZE + new_tlv_len) > ++ TLV_TOTAL_LEN_MAX) { ++ printf("ERROR: There is not enough room in the EERPOM to save data.\n"); ++ return false; ++ } ++ ++ // Add TLV at the end, overwriting CRC TLV if it exists ++ if (tlvinfo_find_tlv(eeprom, TLV_CODE_CRC_32, &eeprom_index)) ++ eeprom_hdr->totallen = ++ cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) - ++ ENT_SIZE - 4); ++ else ++ eeprom_index = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); ++ eeprom_tlv = to_entry(&eeprom[eeprom_index]); ++ eeprom_tlv->type = tcode; ++ eeprom_tlv->length = new_tlv_len; ++ memcpy(eeprom_tlv->value, data, new_tlv_len); ++ ++ // Update the total length and calculate (add) a new CRC-32 TLV ++ eeprom_hdr->totallen = cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) + ++ ENT_SIZE + new_tlv_len); ++ update_crc(eeprom); ++ ++ return true; ++} ++ ++/** ++ * set_mac ++ * ++ * Converts a string MAC address into a binary buffer. ++ * ++ * This function takes a pointer to a MAC address string ++ * (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number). ++ * The string format is verified and then converted to binary and ++ * stored in a buffer. ++ */ ++static int set_mac(char *buf, const char *string) ++{ ++ char *p = (char *)string; ++ int i; ++ int err = 0; ++ char *end; ++ ++ if (!p) { ++ printf("ERROR: NULL mac addr string passed in.\n"); ++ return -1; ++ } ++ ++ if (strlen(p) != 17) { ++ printf("ERROR: MAC address strlen() != 17 -- %zu\n", strlen(p)); ++ printf("ERROR: Bad MAC address format: %s\n", string); ++ return -1; ++ } ++ ++ for (i = 0; i < 17; i++) { ++ if ((i % 3) == 2) { ++ if (p[i] != ':') { ++ err++; ++ printf("ERROR: mac: p[%i] != :, found: `%c'\n", ++ i, p[i]); ++ break; ++ } ++ continue; ++ } else if (!is_hex(p[i])) { ++ err++; ++ printf("ERROR: mac: p[%i] != hex digit, found: `%c'\n", ++ i, p[i]); ++ break; ++ } ++ } ++ ++ if (err != 0) { ++ printf("ERROR: Bad MAC address format: %s\n", string); ++ return -1; ++ } ++ ++ /* Convert string to binary */ ++ for (i = 0, p = (char *)string; i < 6; i++) { ++ buf[i] = p ? simple_strtoul(p, &end, 16) : 0; ++ if (p) ++ p = (*end) ? end + 1 : end; ++ } ++ ++ if (!is_valid_ethaddr((u8 *)buf)) { ++ printf("ERROR: MAC address must not be 00:00:00:00:00:00, a multicast address or FF:FF:FF:FF:FF:FF.\n"); ++ printf("ERROR: Bad MAC address format: %s\n", string); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++/** ++ * set_date ++ * ++ * Validates the format of the data string ++ * ++ * This function takes a pointer to a date string (i.e. MM/DD/YYYY hh:mm:ss) ++ * and validates that the format is correct. If so the string is copied ++ * to the supplied buffer. ++ */ ++static int set_date(char *buf, const char *string) ++{ ++ int i; ++ ++ if (!string) { ++ printf("ERROR: NULL date string passed in.\n"); ++ return -1; ++ } ++ ++ if (strlen(string) != 19) { ++ printf("ERROR: Date strlen() != 19 -- %zu\n", strlen(string)); ++ printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", ++ string); ++ return -1; ++ } ++ ++ for (i = 0; string[i] != 0; i++) { ++ switch (i) { ++ case 2: ++ case 5: ++ if (string[i] != '/') { ++ printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", ++ string); ++ return -1; ++ } ++ break; ++ case 10: ++ if (string[i] != ' ') { ++ printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", ++ string); ++ return -1; ++ } ++ break; ++ case 13: ++ case 16: ++ if (string[i] != ':') { ++ printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", ++ string); ++ return -1; ++ } ++ break; ++ default: ++ if (!is_digit(string[i])) { ++ printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", ++ string); ++ return -1; ++ } ++ break; ++ } ++ } ++ ++ strcpy(buf, string); ++ return 0; ++} ++ ++/** ++ * set_bytes ++ * ++ * Converts a space-separated string of decimal numbers into a ++ * buffer of bytes. ++ * ++ * This function takes a pointer to a space-separated string of decimal ++ * numbers (i.e. "128 0x55 0321") with "C" standard radix specifiers ++ * and converts them to an array of bytes. ++ */ ++static int set_bytes(char *buf, const char *string, int *converted_accum) ++{ ++ char *p = (char *)string; ++ int i; ++ uint byte; ++ ++ if (!p) { ++ printf("ERROR: NULL string passed in.\n"); ++ return -1; ++ } ++ ++ /* Convert string to bytes */ ++ for (i = 0, p = (char *)string; (i < TLV_VALUE_MAX_LEN) && (*p != 0); ++ i++) { ++ while ((*p == ' ') || (*p == '\t') || (*p == ',') || ++ (*p == ';')) { ++ p++; ++ } ++ if (*p != 0) { ++ if (!is_digit(*p)) { ++ printf("ERROR: Non-digit found in byte string: (%s)\n", ++ string); ++ return -1; ++ } ++ byte = simple_strtoul(p, &p, 0); ++ if (byte >= 256) { ++ printf("ERROR: The value specified is greater than 255: (%u) in string: %s\n", ++ byte, string); ++ return -1; ++ } ++ buf[i] = byte & 0xFF; ++ } ++ } ++ ++ if (i == TLV_VALUE_MAX_LEN && (*p != 0)) { ++ printf("ERROR: Trying to assign too many bytes (max: %d) in string: %s\n", ++ TLV_VALUE_MAX_LEN, string); ++ return -1; ++ } ++ ++ *converted_accum = i; ++ return 0; ++} ++ ++static void show_tlv_devices(void) ++{ ++ unsigned int dev; ++ ++ for (dev = 0; dev < MAX_TLV_DEVICES; dev++) ++ if (tlv_devices[dev]) ++ printf("TLV: %u%s\n", dev, ++ (dev == current_dev) ? " (*)" : ""); ++} ++ ++static int find_tlv_devices(struct udevice **tlv_devices_p) ++{ ++ int ret; ++ int count_dev = 0; ++ struct udevice *dev; ++ ++ for (ret = uclass_first_device_check(UCLASS_I2C_EEPROM, &dev); ++ dev; ++ ret = uclass_next_device_check(&dev)) { ++ if (ret == 0) ++ tlv_devices_p[count_dev++] = dev; ++ if (count_dev >= MAX_TLV_DEVICES) ++ break; ++ } ++ ++ return (count_dev == 0) ? -ENODEV : 0; ++} ++ ++static struct udevice *find_tlv_device_by_index(int dev_num) ++{ ++ struct udevice *local_tlv_devices[MAX_TLV_DEVICES] = {}; ++ struct udevice **tlv_devices_p; ++ int ret; ++ ++ if (gd->flags & (GD_FLG_RELOC | GD_FLG_SPL_INIT)) { ++ /* Assume BSS is initialized; use static data */ ++ if (tlv_devices[dev_num]) ++ return tlv_devices[dev_num]; ++ tlv_devices_p = tlv_devices; ++ } else { ++ tlv_devices_p = local_tlv_devices; ++ } ++ ++ ret = find_tlv_devices(tlv_devices_p); ++ if (ret == 0 && tlv_devices_p[dev_num]) ++ return tlv_devices_p[dev_num]; ++ ++ return NULL; ++} ++ ++/** ++ * read_tlv_eeprom - read the hwinfo from i2c EEPROM ++ */ ++int read_tlv_eeprom(void *eeprom, int offset, int len, int dev_num) ++{ ++ struct udevice *dev; ++ ++ if (dev_num >= MAX_TLV_DEVICES) ++ return -EINVAL; ++ ++ dev = find_tlv_device_by_index(dev_num); ++ if (!dev) ++ return -ENODEV; ++ ++ return i2c_eeprom_read(dev, offset, eeprom, len); ++} ++ ++/** ++ * write_tlv_eeprom - write the hwinfo to i2c EEPROM ++ */ ++int write_tlv_eeprom(void *eeprom, int len) ++{ ++ if (!(gd->flags & GD_FLG_RELOC)) ++ return -ENODEV; ++ if (!tlv_devices[current_dev]) ++ return -ENODEV; ++ ++ return i2c_eeprom_write(tlv_devices[current_dev], 0, eeprom, len); ++} ++ ++int read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr, ++ struct tlvinfo_tlv **first_entry, int dev_num) ++{ ++ int ret; ++ struct tlvinfo_header *tlv_hdr; ++ struct tlvinfo_tlv *tlv_ent; ++ ++ /* Read TLV header */ ++ ret = read_tlv_eeprom(eeprom, 0, HDR_SIZE, dev_num); ++ if (ret < 0) ++ return ret; ++ ++ tlv_hdr = eeprom; ++ if (!is_valid_tlvinfo_header(tlv_hdr)) ++ return -EINVAL; ++ ++ /* Read TLV entries */ ++ tlv_ent = to_entry(&tlv_hdr[1]); ++ ret = read_tlv_eeprom(tlv_ent, HDR_SIZE, ++ be16_to_cpu(tlv_hdr->totallen), dev_num); ++ if (ret < 0) ++ return ret; ++ if (!is_checksum_valid(eeprom)) ++ return -EINVAL; ++ ++ *hdr = tlv_hdr; ++ *first_entry = tlv_ent; ++ ++ return 0; ++} ++ ++/** ++ * mac_read_from_eeprom ++ * ++ * Read the MAC addresses from EEPROM ++ * ++ * This function reads the MAC addresses from EEPROM and sets the ++ * appropriate environment variables for each one read. ++ * ++ * The environment variables are only set if they haven't been set already. ++ * This ensures that any user-saved variables are never overwritten. ++ * ++ * This function must be called after relocation. ++ */ ++int mac_read_from_eeprom(void) ++{ ++ unsigned int i; ++ int eeprom_index; ++ struct tlvinfo_tlv *eeprom_tlv; ++ int maccount; ++ u8 macbase[6]; ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ ++ puts("EEPROM: "); ++ ++ if (read_eeprom(eeprom)) { ++ printf("Read failed.\n"); ++ return -1; ++ } ++ ++ maccount = 1; ++ if (tlvinfo_find_tlv(eeprom, TLV_CODE_MAC_SIZE, &eeprom_index)) { ++ eeprom_tlv = to_entry(&eeprom[eeprom_index]); ++ maccount = (eeprom_tlv->value[0] << 8) | eeprom_tlv->value[1]; ++ } ++ ++ memcpy(macbase, "\0\0\0\0\0\0", 6); ++ if (tlvinfo_find_tlv(eeprom, TLV_CODE_MAC_BASE, &eeprom_index)) { ++ eeprom_tlv = to_entry(&eeprom[eeprom_index]); ++ memcpy(macbase, eeprom_tlv->value, 6); ++ } ++ ++ for (i = 0; i < maccount; i++) { ++ if (is_valid_ethaddr(macbase)) { ++ char ethaddr[18]; ++ char enetvar[11]; ++ ++ sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X", ++ macbase[0], macbase[1], macbase[2], ++ macbase[3], macbase[4], macbase[5]); ++ sprintf(enetvar, i ? "eth%daddr" : "ethaddr", i); ++ /* Only initialize environment variables that are blank ++ * (i.e. have not yet been set) ++ */ ++ if (!env_get(enetvar)) ++ env_set(enetvar, ethaddr); ++ ++ macbase[5]++; ++ if (macbase[5] == 0) { ++ macbase[4]++; ++ if (macbase[4] == 0) { ++ macbase[3]++; ++ if (macbase[3] == 0) { ++ macbase[0] = 0; ++ macbase[1] = 0; ++ macbase[2] = 0; ++ } ++ } ++ } ++ } ++ } ++ ++ printf("%s v%u len=%u\n", eeprom_hdr->signature, eeprom_hdr->version, ++ be16_to_cpu(eeprom_hdr->totallen)); ++ ++ return 0; ++} ++ ++/** ++ * populate_serial_number - read the serial number from EEPROM ++ * ++ * This function reads the serial number from the EEPROM and sets the ++ * appropriate environment variable. ++ * ++ * The environment variable is only set if it has not been set ++ * already. This ensures that any user-saved variables are never ++ * overwritten. ++ * ++ * This function must be called after relocation. ++ */ ++int populate_serial_number(void) ++{ ++ char serialstr[257]; ++ int eeprom_index; ++ struct tlvinfo_tlv *eeprom_tlv; ++ ++ if (env_get("serial#")) ++ return 0; ++ ++ if (read_eeprom(eeprom)) { ++ printf("Read failed.\n"); ++ return -1; ++ } ++ ++ if (tlvinfo_find_tlv(eeprom, TLV_CODE_SERIAL_NUMBER, &eeprom_index)) { ++ eeprom_tlv = to_entry(&eeprom[eeprom_index]); ++ memcpy(serialstr, eeprom_tlv->value, eeprom_tlv->length); ++ serialstr[eeprom_tlv->length] = 0; ++ env_set("serial#", serialstr); ++ } ++ ++ return 0; ++} +diff --git a/include/tlv_eeprom.h b/include/tlv_eeprom.h +new file mode 100644 +index 0000000000..1de2fe2337 +--- /dev/null ++++ b/include/tlv_eeprom.h +@@ -0,0 +1,152 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ */ ++ ++#ifndef __TLV_EEPROM_H_ ++#define __TLV_EEPROM_H_ ++ ++/* ++ * The Definition of the TlvInfo EEPROM format can be found at onie.org or ++ * github.com/onie ++ */ ++ ++/* ++ * TlvInfo header: Layout of the header for the TlvInfo format ++ * ++ * See the end of this file for details of this eeprom format ++ */ ++struct __attribute__ ((__packed__)) tlvinfo_header { ++ char signature[8]; /* 0x00 - 0x07 EEPROM Tag "TlvInfo" */ ++ u8 version; /* 0x08 Structure version */ ++ u16 totallen; /* 0x09 - 0x0A Length of all data which follows */ ++}; ++ ++// Header Field Constants ++#define TLV_INFO_ID_STRING "TlvInfo" ++#define TLV_INFO_VERSION 0x01 ++#define TLV_INFO_MAX_LEN 2048 ++#define TLV_TOTAL_LEN_MAX (TLV_INFO_MAX_LEN - \ ++ sizeof(struct tlvinfo_header)) ++ ++/* ++ * TlvInfo TLV: Layout of a TLV field ++ */ ++struct __attribute__ ((__packed__)) tlvinfo_tlv { ++ u8 type; ++ u8 length; ++ u8 value[0]; ++}; ++ ++/* Maximum length of a TLV value in bytes */ ++#define TLV_VALUE_MAX_LEN 255 ++ ++/** ++ * The TLV Types. ++ * ++ * Keep these in sync with tlv_code_list in cmd/tlv_eeprom.c ++ */ ++#define TLV_CODE_PRODUCT_NAME 0x21 ++#define TLV_CODE_PART_NUMBER 0x22 ++#define TLV_CODE_SERIAL_NUMBER 0x23 ++#define TLV_CODE_MAC_BASE 0x24 ++#define TLV_CODE_MANUF_DATE 0x25 ++#define TLV_CODE_DEVICE_VERSION 0x26 ++#define TLV_CODE_LABEL_REVISION 0x27 ++#define TLV_CODE_PLATFORM_NAME 0x28 ++#define TLV_CODE_ONIE_VERSION 0x29 ++#define TLV_CODE_MAC_SIZE 0x2A ++#define TLV_CODE_MANUF_NAME 0x2B ++#define TLV_CODE_MANUF_COUNTRY 0x2C ++#define TLV_CODE_VENDOR_NAME 0x2D ++#define TLV_CODE_DIAG_VERSION 0x2E ++#define TLV_CODE_SERVICE_TAG 0x2F ++#define TLV_CODE_VENDOR_EXT 0xFD ++#define TLV_CODE_CRC_32 0xFE ++ ++#if CONFIG_IS_ENABLED(CMD_TLV_EEPROM) ++ ++/** ++ * read_tlv_eeprom - Read the EEPROM binary data from the hardware ++ * @eeprom: Pointer to buffer to hold the binary data ++ * @offset: Offset within EEPROM block to read data from ++ * @len : Maximum size of buffer ++ * @dev : EEPROM device to read ++ * ++ * Note: this routine does not validate the EEPROM data. ++ * ++ */ ++ ++int read_tlv_eeprom(void *eeprom, int offset, int len, int dev); ++ ++/** ++ * write_tlv_eeprom - Write the entire EEPROM binary data to the hardware ++ * @eeprom: Pointer to buffer to hold the binary data ++ * @len : Maximum size of buffer ++ * ++ * Note: this routine does not validate the EEPROM data. ++ * ++ */ ++int write_tlv_eeprom(void *eeprom, int len); ++ ++/** ++ * read_tlvinfo_tlv_eeprom - Read the TLV from EEPROM, and validate ++ * @eeprom: Pointer to buffer to hold the binary data. Must point to a buffer ++ * of size at least TLV_INFO_MAX_LEN. ++ * @hdr : Points to pointer to TLV header (output) ++ * @first_entry : Points to pointer to first TLV entry (output) ++ * @dev : EEPROM device to read ++ * ++ * Store the raw EEPROM data from EEPROM @dev in the @eeprom buffer. If TLV is ++ * valid set *@hdr and *@first_entry. ++ * ++ * Returns 0 when read from EEPROM is successful, and the data is valid. ++ * Returns <0 error value when EEPROM read fails. Return -EINVAL when TLV is ++ * invalid. ++ * ++ */ ++ ++int read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr, ++ struct tlvinfo_tlv **first_entry, int dev); ++ ++#else /* !CONFIG_IS_ENABLED(CMD_TLV_EEPROM) */ ++ ++static inline int read_tlv_eeprom(void *eeprom, int offset, int len, int dev) ++{ ++ return -ENOTSUPP; ++} ++ ++static inline int write_tlv_eeprom(void *eeprom, int len) ++{ ++ return -ENOTSUPP; ++} ++ ++static inline int ++read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr, ++ struct tlvinfo_tlv **first_entry, int dev) ++{ ++ return -ENOTSUPP; ++} ++ ++#endif /* CONFIG_IS_ENABLED(CMD_TLV_EEPROM) */ ++ ++/** ++ * is_valid_tlvinfo_header ++ * ++ * Perform sanity checks on the first 11 bytes of the TlvInfo EEPROM ++ * data pointed to by the parameter: ++ * 1. First 8 bytes contain null-terminated ASCII string "TlvInfo" ++ * 2. Version byte is 1 ++ * 3. Total length bytes contain value which is less than or equal ++ * to the allowed maximum (2048-11) ++ * ++ */ ++static inline bool is_valid_tlvinfo_header(struct tlvinfo_header *hdr) ++{ ++ return ((strcmp(hdr->signature, TLV_INFO_ID_STRING) == 0) && ++ (hdr->version == TLV_INFO_VERSION) && ++ (be16_to_cpu(hdr->totallen) <= TLV_TOTAL_LEN_MAX)); ++} ++ ++#endif /* __TLV_EEPROM_H_ */ diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0002-cmd-tlv_eeprom.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0002-cmd-tlv_eeprom.patch new file mode 100644 index 0000000..e85245c --- /dev/null +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0002-cmd-tlv_eeprom.patch @@ -0,0 +1,27 @@ +From 0dce367ced42c77d4de5c17b52605c6c003a4b20 Mon Sep 17 00:00:00 2001 +From: Sven Auhagen +Date: Sun, 12 Sep 2021 09:25:44 +0200 +Subject: [PATCH] cmd: tlv_eeprom + +The function show_eeprom is missing int i if debug is enabled. + +Signed-off-by: Sven Auhagen +Reviewed-by: Stefan Roese +--- + cmd/tlv_eeprom.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/cmd/tlv_eeprom.c b/cmd/tlv_eeprom.c +index 211ab2680f..96d40f4f4d 100644 +--- a/cmd/tlv_eeprom.c ++++ b/cmd/tlv_eeprom.c +@@ -166,6 +166,9 @@ static void show_eeprom(u8 *eeprom) + { + int tlv_end; + int curr_tlv; ++#ifdef DEBUG ++ int i; ++#endif + struct tlvinfo_header *eeprom_hdr = to_header(eeprom); + struct tlvinfo_tlv *eeprom_tlv; + diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0003-cmd-tlv_eeprom-remove-use-of-global-variable-current.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0003-cmd-tlv_eeprom-remove-use-of-global-variable-current.patch new file mode 100644 index 0000000..9246147 --- /dev/null +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0003-cmd-tlv_eeprom-remove-use-of-global-variable-current.patch @@ -0,0 +1,227 @@ +From 3a807537ace144e802e3421b29f3eea0e48d2f1f Mon Sep 17 00:00:00 2001 +From: Josua Mayer +Date: Thu, 17 Mar 2022 11:52:34 +0200 +Subject: [PATCH] cmd: tlv_eeprom: remove use of global variable current_dev + +Make tlv_eeprom command device selection an explicit parameter of all +function calls. + +Signed-off-by: Josua Mayer +--- + cmd/tlv_eeprom.c | 50 ++++++++++++++++++++++---------------------- + include/tlv_eeprom.h | 3 ++- + 2 files changed, 27 insertions(+), 26 deletions(-) + +diff --git a/cmd/tlv_eeprom.c b/cmd/tlv_eeprom.c +index 96d40f4f4d..05d28c26c8 100644 +--- a/cmd/tlv_eeprom.c ++++ b/cmd/tlv_eeprom.c +@@ -26,18 +26,18 @@ DECLARE_GLOBAL_DATA_PTR; + + /* File scope function prototypes */ + static bool is_checksum_valid(u8 *eeprom); +-static int read_eeprom(u8 *eeprom); +-static void show_eeprom(u8 *eeprom); ++static int read_eeprom(int devnum, u8 *eeprom); ++static void show_eeprom(int devnum, u8 *eeprom); + static void decode_tlv(struct tlvinfo_tlv *tlv); + static void update_crc(u8 *eeprom); +-static int prog_eeprom(u8 *eeprom); ++static int prog_eeprom(int devnum, u8 *eeprom); + static bool tlvinfo_find_tlv(u8 *eeprom, u8 tcode, int *eeprom_index); + static bool tlvinfo_delete_tlv(u8 *eeprom, u8 code); + static bool tlvinfo_add_tlv(u8 *eeprom, int tcode, char *strval); + static int set_mac(char *buf, const char *string); + static int set_date(char *buf, const char *string); + static int set_bytes(char *buf, const char *string, int *converted_accum); +-static void show_tlv_devices(void); ++static void show_tlv_devices(int current_dev); + + /* Set to 1 if we've read EEPROM into memory */ + static int has_been_read; +@@ -45,7 +45,6 @@ static int has_been_read; + static u8 eeprom[TLV_INFO_MAX_LEN]; + + static struct udevice *tlv_devices[MAX_TLV_DEVICES]; +-static unsigned int current_dev; + + #define to_header(p) ((struct tlvinfo_header *)p) + #define to_entry(p) ((struct tlvinfo_tlv *)p) +@@ -122,7 +121,7 @@ static bool is_checksum_valid(u8 *eeprom) + * + * Read the EEPROM into memory, if it hasn't already been read. + */ +-static int read_eeprom(u8 *eeprom) ++static int read_eeprom(int devnum, u8 *eeprom) + { + int ret; + struct tlvinfo_header *eeprom_hdr = to_header(eeprom); +@@ -132,12 +131,11 @@ static int read_eeprom(u8 *eeprom) + return 0; + + /* Read the header */ +- ret = read_tlv_eeprom((void *)eeprom_hdr, 0, HDR_SIZE, current_dev); ++ ret = read_tlv_eeprom((void *)eeprom_hdr, 0, HDR_SIZE, devnum); + /* If the header was successfully read, read the TLVs */ + if (ret == 0 && is_valid_tlvinfo_header(eeprom_hdr)) + ret = read_tlv_eeprom((void *)eeprom_tlv, HDR_SIZE, +- be16_to_cpu(eeprom_hdr->totallen), +- current_dev); ++ be16_to_cpu(eeprom_hdr->totallen), devnum); + + // If the contents are invalid, start over with default contents + if (!is_valid_tlvinfo_header(eeprom_hdr) || +@@ -162,7 +160,7 @@ static int read_eeprom(u8 *eeprom) + * + * Display the contents of the EEPROM + */ +-static void show_eeprom(u8 *eeprom) ++static void show_eeprom(int devnum, u8 *eeprom) + { + int tlv_end; + int curr_tlv; +@@ -177,7 +175,7 @@ static void show_eeprom(u8 *eeprom) + return; + } + +- printf("TLV: %u\n", current_dev); ++ printf("TLV: %u\n", devnum); + printf("TlvInfo Header:\n"); + printf(" Id String: %s\n", eeprom_hdr->signature); + printf(" Version: %d\n", eeprom_hdr->version); +@@ -386,7 +384,7 @@ static void update_crc(u8 *eeprom) + * + * Write the EEPROM data from CPU memory to the hardware. + */ +-static int prog_eeprom(u8 *eeprom) ++static int prog_eeprom(int devnum, u8 *eeprom) + { + int ret = 0; + struct tlvinfo_header *eeprom_hdr = to_header(eeprom); +@@ -395,7 +393,7 @@ static int prog_eeprom(u8 *eeprom) + update_crc(eeprom); + + eeprom_len = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); +- ret = write_tlv_eeprom(eeprom, eeprom_len); ++ ret = write_tlv_eeprom(eeprom, eeprom_len, devnum); + if (ret) { + printf("Programming failed.\n"); + return -1; +@@ -430,11 +428,12 @@ int do_tlv_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) + { + char cmd; + struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ static unsigned int current_dev = 0; + + // If no arguments, read the EERPOM and display its contents + if (argc == 1) { +- read_eeprom(eeprom); +- show_eeprom(eeprom); ++ read_eeprom(current_dev, eeprom); ++ show_eeprom(current_dev, eeprom); + return 0; + } + +@@ -445,7 +444,7 @@ int do_tlv_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) + // Read the EEPROM contents + if (cmd == 'r') { + has_been_read = 0; +- if (!read_eeprom(eeprom)) ++ if (!read_eeprom(current_dev, eeprom)) + printf("EEPROM data loaded from device to memory.\n"); + return 0; + } +@@ -460,7 +459,7 @@ int do_tlv_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) + if (argc == 2) { + switch (cmd) { + case 'w': /* write */ +- prog_eeprom(eeprom); ++ prog_eeprom(current_dev, eeprom); + break; + case 'e': /* erase */ + strcpy(eeprom_hdr->signature, TLV_INFO_ID_STRING); +@@ -473,7 +472,7 @@ int do_tlv_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) + show_tlv_code_list(); + break; + case 'd': /* dev */ +- show_tlv_devices(); ++ show_tlv_devices(current_dev); + break; + default: + cmd_usage(cmdtp); +@@ -883,7 +882,7 @@ static int set_bytes(char *buf, const char *string, int *converted_accum) + return 0; + } + +-static void show_tlv_devices(void) ++static void show_tlv_devices(int current_dev) + { + unsigned int dev; + +@@ -953,14 +952,14 @@ int read_tlv_eeprom(void *eeprom, int offset, int len, int dev_num) + /** + * write_tlv_eeprom - write the hwinfo to i2c EEPROM + */ +-int write_tlv_eeprom(void *eeprom, int len) ++int write_tlv_eeprom(void *eeprom, int len, int dev) + { + if (!(gd->flags & GD_FLG_RELOC)) + return -ENODEV; +- if (!tlv_devices[current_dev]) ++ if (!tlv_devices[dev]) + return -ENODEV; + +- return i2c_eeprom_write(tlv_devices[current_dev], 0, eeprom, len); ++ return i2c_eeprom_write(tlv_devices[dev], 0, eeprom, len); + } + + int read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr, +@@ -1015,10 +1014,11 @@ int mac_read_from_eeprom(void) + int maccount; + u8 macbase[6]; + struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ int devnum = 0; // TODO: support multiple EEPROMs + + puts("EEPROM: "); + +- if (read_eeprom(eeprom)) { ++ if (read_eeprom(devnum, eeprom)) { + printf("Read failed.\n"); + return -1; + } +@@ -1083,7 +1083,7 @@ int mac_read_from_eeprom(void) + * + * This function must be called after relocation. + */ +-int populate_serial_number(void) ++int populate_serial_number(int devnum) + { + char serialstr[257]; + int eeprom_index; +@@ -1092,7 +1092,7 @@ int populate_serial_number(void) + if (env_get("serial#")) + return 0; + +- if (read_eeprom(eeprom)) { ++ if (read_eeprom(devnum, eeprom)) { + printf("Read failed.\n"); + return -1; + } +diff --git a/include/tlv_eeprom.h b/include/tlv_eeprom.h +index 1de2fe2337..aa96c9e8d4 100644 +--- a/include/tlv_eeprom.h ++++ b/include/tlv_eeprom.h +@@ -84,11 +84,12 @@ int read_tlv_eeprom(void *eeprom, int offset, int len, int dev); + * write_tlv_eeprom - Write the entire EEPROM binary data to the hardware + * @eeprom: Pointer to buffer to hold the binary data + * @len : Maximum size of buffer ++ * @dev : EEPROM device to write + * + * Note: this routine does not validate the EEPROM data. + * + */ +-int write_tlv_eeprom(void *eeprom, int len); ++int write_tlv_eeprom(void *eeprom, int len, int dev); + + /** + * read_tlvinfo_tlv_eeprom - Read the TLV from EEPROM, and validate diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0004-cmd-tlv_eeprom-remove-use-of-global-variable-has_bee.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0004-cmd-tlv_eeprom-remove-use-of-global-variable-has_bee.patch new file mode 100644 index 0000000..0373999 --- /dev/null +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0004-cmd-tlv_eeprom-remove-use-of-global-variable-has_bee.patch @@ -0,0 +1,94 @@ +From 28da9685c7e65f70065319921ccaf2d2aea7b185 Mon Sep 17 00:00:00 2001 +From: Josua Mayer +Date: Thu, 17 Mar 2022 12:49:46 +0200 +Subject: [PATCH] cmd: tlv_eeprom: remove use of global variable has_been_read + +has_been_read is only used as an optimization for do_tlv_eeprom. +Explicitly use and set inside this function, thus making read_eeprom +stateless. + +Signed-off-by: Josua Mayer +--- + cmd/tlv_eeprom.c | 25 ++++++++++++------------- + 1 file changed, 12 insertions(+), 13 deletions(-) + +diff --git a/cmd/tlv_eeprom.c b/cmd/tlv_eeprom.c +index 05d28c26c8..70c1a2e7df 100644 +--- a/cmd/tlv_eeprom.c ++++ b/cmd/tlv_eeprom.c +@@ -39,8 +39,6 @@ static int set_date(char *buf, const char *string); + static int set_bytes(char *buf, const char *string, int *converted_accum); + static void show_tlv_devices(int current_dev); + +-/* Set to 1 if we've read EEPROM into memory */ +-static int has_been_read; + /* The EERPOM contents after being read into memory */ + static u8 eeprom[TLV_INFO_MAX_LEN]; + +@@ -127,9 +125,6 @@ static int read_eeprom(int devnum, u8 *eeprom) + struct tlvinfo_header *eeprom_hdr = to_header(eeprom); + struct tlvinfo_tlv *eeprom_tlv = to_entry(&eeprom[HDR_SIZE]); + +- if (has_been_read) +- return 0; +- + /* Read the header */ + ret = read_tlv_eeprom((void *)eeprom_hdr, 0, HDR_SIZE, devnum); + /* If the header was successfully read, read the TLVs */ +@@ -146,10 +141,8 @@ static int read_eeprom(int devnum, u8 *eeprom) + update_crc(eeprom); + } + +- has_been_read = 1; +- + #ifdef DEBUG +- show_eeprom(eeprom); ++ show_eeprom(devnum, eeprom); + #endif + + return ret; +@@ -429,10 +422,15 @@ int do_tlv_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) + char cmd; + struct tlvinfo_header *eeprom_hdr = to_header(eeprom); + static unsigned int current_dev = 0; ++ /* Set to devnum if we've read EEPROM into memory */ ++ static int has_been_read = -1; + + // If no arguments, read the EERPOM and display its contents + if (argc == 1) { +- read_eeprom(current_dev, eeprom); ++ if(has_been_read != current_dev) { ++ read_eeprom(current_dev, eeprom); ++ has_been_read = current_dev; ++ } + show_eeprom(current_dev, eeprom); + return 0; + } +@@ -443,14 +441,16 @@ int do_tlv_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) + + // Read the EEPROM contents + if (cmd == 'r') { +- has_been_read = 0; +- if (!read_eeprom(current_dev, eeprom)) ++ has_been_read = -1; ++ if (!read_eeprom(current_dev, eeprom)) { + printf("EEPROM data loaded from device to memory.\n"); ++ has_been_read = current_dev; ++ } + return 0; + } + + // Subsequent commands require that the EEPROM has already been read. +- if (!has_been_read) { ++ if (has_been_read != current_dev) { + printf("Please read the EEPROM data first, using the 'tlv_eeprom read' command.\n"); + return 0; + } +@@ -506,7 +506,6 @@ int do_tlv_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) + return 0; + } + current_dev = devnum; +- has_been_read = 0; + } else { + cmd_usage(cmdtp); + } diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0005-cmd-tlv_eeprom-do_tlv_eeprom-stop-using-non-api-read.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0005-cmd-tlv_eeprom-do_tlv_eeprom-stop-using-non-api-read.patch new file mode 100644 index 0000000..2649872 --- /dev/null +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0005-cmd-tlv_eeprom-do_tlv_eeprom-stop-using-non-api-read.patch @@ -0,0 +1,37 @@ +From 6578def0ace0d030a02b8c45031d41c5d2ef517e Mon Sep 17 00:00:00 2001 +From: Josua Mayer +Date: Thu, 17 Mar 2022 14:23:22 +0200 +Subject: [PATCH] cmd: tlv_eeprom: do_tlv_eeprom: stop using non-api + read_eeprom function + +IN the scope of do_tlv_eeprom, the error-checking provided by the +read_eeprom function is not required. +Instead use the API function read_tlv_eeprom. + +Signed-off-by: Josua Mayer +--- + cmd/tlv_eeprom.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/cmd/tlv_eeprom.c b/cmd/tlv_eeprom.c +index 70c1a2e7df..8a926ba224 100644 +--- a/cmd/tlv_eeprom.c ++++ b/cmd/tlv_eeprom.c +@@ -428,7 +428,7 @@ int do_tlv_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) + // If no arguments, read the EERPOM and display its contents + if (argc == 1) { + if(has_been_read != current_dev) { +- read_eeprom(current_dev, eeprom); ++ read_tlv_eeprom(eeprom, 0, TLV_INFO_MAX_LEN, current_dev); + has_been_read = current_dev; + } + show_eeprom(current_dev, eeprom); +@@ -442,7 +442,7 @@ int do_tlv_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) + // Read the EEPROM contents + if (cmd == 'r') { + has_been_read = -1; +- if (!read_eeprom(current_dev, eeprom)) { ++ if (read_tlv_eeprom(eeprom, 0, TLV_INFO_MAX_LEN, current_dev) == 0) { + printf("EEPROM data loaded from device to memory.\n"); + has_been_read = current_dev; + } diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0006-cmd-tlv_eeprom-convert-functions-used-by-command-to-.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0006-cmd-tlv_eeprom-convert-functions-used-by-command-to-.patch new file mode 100644 index 0000000..bf7f5f0 --- /dev/null +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0006-cmd-tlv_eeprom-convert-functions-used-by-command-to-.patch @@ -0,0 +1,278 @@ +From 62114ab82feaf919138d2d4377344072c95571de Mon Sep 17 00:00:00 2001 +From: Josua Mayer +Date: Thu, 17 Mar 2022 16:09:02 +0200 +Subject: [PATCH] cmd: tlv_eeprom: convert functions used by command to api + functions + +- prog_eeprom: write_tlvinfo_tlv_eeprom +- update_crc: tlvinfo_update_crc +- is_valid_tlv: is_valid_tlvinfo_entry +- is_checksum_valid: tlvinfo_check_crc + +Signed-off-by: Josua Mayer +--- + cmd/tlv_eeprom.c | 56 +++++++++++++++---------------------------- + include/tlv_eeprom.h | 57 ++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 76 insertions(+), 37 deletions(-) + +diff --git a/cmd/tlv_eeprom.c b/cmd/tlv_eeprom.c +index 8a926ba224..271fefc0c6 100644 +--- a/cmd/tlv_eeprom.c ++++ b/cmd/tlv_eeprom.c +@@ -25,13 +25,9 @@ DECLARE_GLOBAL_DATA_PTR; + #define MAX_TLV_DEVICES 2 + + /* File scope function prototypes */ +-static bool is_checksum_valid(u8 *eeprom); + static int read_eeprom(int devnum, u8 *eeprom); + static void show_eeprom(int devnum, u8 *eeprom); + static void decode_tlv(struct tlvinfo_tlv *tlv); +-static void update_crc(u8 *eeprom); +-static int prog_eeprom(int devnum, u8 *eeprom); +-static bool tlvinfo_find_tlv(u8 *eeprom, u8 tcode, int *eeprom_index); + static bool tlvinfo_delete_tlv(u8 *eeprom, u8 code); + static bool tlvinfo_add_tlv(u8 *eeprom, int tcode, char *strval); + static int set_mac(char *buf, const char *string); +@@ -55,18 +51,6 @@ static inline bool is_digit(char c) + return (c >= '0' && c <= '9'); + } + +-/** +- * is_valid_tlv +- * +- * Perform basic sanity checks on a TLV field. The TLV is pointed to +- * by the parameter provided. +- * 1. The type code is not reserved (0x00 or 0xFF) +- */ +-static inline bool is_valid_tlv(struct tlvinfo_tlv *tlv) +-{ +- return((tlv->type != 0x00) && (tlv->type != 0xFF)); +-} +- + /** + * is_hex + * +@@ -80,14 +64,12 @@ static inline u8 is_hex(char p) + } + + /** +- * is_checksum_valid +- * + * Validate the checksum in the provided TlvInfo EEPROM data. First, + * verify that the TlvInfo header is valid, then make sure the last + * TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data + * and compare it to the value stored in the EEPROM CRC-32 TLV. + */ +-static bool is_checksum_valid(u8 *eeprom) ++bool tlvinfo_check_crc(u8 *eeprom) + { + struct tlvinfo_header *eeprom_hdr = to_header(eeprom); + struct tlvinfo_tlv *eeprom_crc; +@@ -134,11 +116,11 @@ static int read_eeprom(int devnum, u8 *eeprom) + + // If the contents are invalid, start over with default contents + if (!is_valid_tlvinfo_header(eeprom_hdr) || +- !is_checksum_valid(eeprom)) { ++ !tlvinfo_check_crc(eeprom)) { + strcpy(eeprom_hdr->signature, TLV_INFO_ID_STRING); + eeprom_hdr->version = TLV_INFO_VERSION; + eeprom_hdr->totallen = cpu_to_be16(0); +- update_crc(eeprom); ++ tlvinfo_update_crc(eeprom); + } + + #ifdef DEBUG +@@ -180,7 +162,7 @@ static void show_eeprom(int devnum, u8 *eeprom) + tlv_end = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); + while (curr_tlv < tlv_end) { + eeprom_tlv = to_entry(&eeprom[curr_tlv]); +- if (!is_valid_tlv(eeprom_tlv)) { ++ if (!is_valid_tlvinfo_entry(eeprom_tlv)) { + printf("Invalid TLV field starting at EEPROM offset %d\n", + curr_tlv); + return; +@@ -190,7 +172,7 @@ static void show_eeprom(int devnum, u8 *eeprom) + } + + printf("Checksum is %s.\n", +- is_checksum_valid(eeprom) ? "valid" : "invalid"); ++ tlvinfo_check_crc(eeprom) ? "valid" : "invalid"); + + #ifdef DEBUG + printf("EEPROM dump: (0x%x bytes)", TLV_INFO_MAX_LEN); +@@ -337,13 +319,13 @@ static void decode_tlv(struct tlvinfo_tlv *tlv) + } + + /** +- * update_crc ++ * tlvinfo_update_crc + * + * This function updates the CRC-32 TLV. If there is no CRC-32 TLV, then + * one is added. This function should be called after each update to the + * EEPROM structure, to make sure the CRC is always correct. + */ +-static void update_crc(u8 *eeprom) ++void tlvinfo_update_crc(u8 *eeprom) + { + struct tlvinfo_header *eeprom_hdr = to_header(eeprom); + struct tlvinfo_tlv *eeprom_crc; +@@ -373,20 +355,20 @@ static void update_crc(u8 *eeprom) + } + + /** +- * prog_eeprom ++ * write_tlvinfo_tlv_eeprom + * +- * Write the EEPROM data from CPU memory to the hardware. ++ * Write the TLV data from CPU memory to the hardware. + */ +-static int prog_eeprom(int devnum, u8 *eeprom) ++int write_tlvinfo_tlv_eeprom(void *eeprom, int dev) + { + int ret = 0; + struct tlvinfo_header *eeprom_hdr = to_header(eeprom); + int eeprom_len; + +- update_crc(eeprom); ++ tlvinfo_update_crc(eeprom); + + eeprom_len = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); +- ret = write_tlv_eeprom(eeprom, eeprom_len, devnum); ++ ret = write_tlv_eeprom(eeprom, eeprom_len, dev); + if (ret) { + printf("Programming failed.\n"); + return -1; +@@ -459,13 +441,13 @@ int do_tlv_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) + if (argc == 2) { + switch (cmd) { + case 'w': /* write */ +- prog_eeprom(current_dev, eeprom); ++ write_tlvinfo_tlv_eeprom(eeprom, current_dev); + break; + case 'e': /* erase */ + strcpy(eeprom_hdr->signature, TLV_INFO_ID_STRING); + eeprom_hdr->version = TLV_INFO_VERSION; + eeprom_hdr->totallen = cpu_to_be16(0); +- update_crc(eeprom); ++ tlvinfo_update_crc(eeprom); + printf("EEPROM data in memory reset.\n"); + break; + case 'l': /* list */ +@@ -546,7 +528,7 @@ U_BOOT_CMD(tlv_eeprom, 4, 1, do_tlv_eeprom, + * An offset from the beginning of the EEPROM is returned in the + * eeprom_index parameter if the TLV is found. + */ +-static bool tlvinfo_find_tlv(u8 *eeprom, u8 tcode, int *eeprom_index) ++bool tlvinfo_find_tlv(u8 *eeprom, u8 tcode, int *eeprom_index) + { + struct tlvinfo_header *eeprom_hdr = to_header(eeprom); + struct tlvinfo_tlv *eeprom_tlv; +@@ -558,7 +540,7 @@ static bool tlvinfo_find_tlv(u8 *eeprom, u8 tcode, int *eeprom_index) + eeprom_end = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); + while (*eeprom_index < eeprom_end) { + eeprom_tlv = to_entry(&eeprom[*eeprom_index]); +- if (!is_valid_tlv(eeprom_tlv)) ++ if (!is_valid_tlvinfo_entry(eeprom_tlv)) + return false; + if (eeprom_tlv->type == tcode) + return true; +@@ -591,7 +573,7 @@ static bool tlvinfo_delete_tlv(u8 *eeprom, u8 code) + eeprom_hdr->totallen = + cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) - + tlength); +- update_crc(eeprom); ++ tlvinfo_update_crc(eeprom); + return true; + } + return false; +@@ -692,7 +674,7 @@ static bool tlvinfo_add_tlv(u8 *eeprom, int tcode, char *strval) + // Update the total length and calculate (add) a new CRC-32 TLV + eeprom_hdr->totallen = cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) + + ENT_SIZE + new_tlv_len); +- update_crc(eeprom); ++ tlvinfo_update_crc(eeprom); + + return true; + } +@@ -983,7 +965,7 @@ int read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr, + be16_to_cpu(tlv_hdr->totallen), dev_num); + if (ret < 0) + return ret; +- if (!is_checksum_valid(eeprom)) ++ if (!tlvinfo_check_crc(eeprom)) + return -EINVAL; + + *hdr = tlv_hdr; +diff --git a/include/tlv_eeprom.h b/include/tlv_eeprom.h +index aa96c9e8d4..eeb8af57f1 100644 +--- a/include/tlv_eeprom.h ++++ b/include/tlv_eeprom.h +@@ -111,6 +111,51 @@ int write_tlv_eeprom(void *eeprom, int len, int dev); + int read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr, + struct tlvinfo_tlv **first_entry, int dev); + ++/** ++ * Write TLV data to the EEPROM. ++ * ++ * - Only writes length of actual tlv data ++ * - updates checksum ++ * ++ * @eeprom: Pointer to buffer to hold the binary data. Must point to a buffer ++ * of size at least TLV_INFO_MAX_LEN. ++ * @dev : EEPROM device to write ++ * ++ */ ++int write_tlvinfo_tlv_eeprom(void *eeprom, int dev); ++ ++/** ++ * tlvinfo_find_tlv ++ * ++ * This function finds the TLV with the supplied code in the EERPOM. ++ * An offset from the beginning of the EEPROM is returned in the ++ * eeprom_index parameter if the TLV is found. ++ */ ++bool tlvinfo_find_tlv(u8 *eeprom, u8 tcode, int *eeprom_index); ++ ++/** ++ * tlvinfo_update_crc ++ * ++ * This function updates the CRC-32 TLV. If there is no CRC-32 TLV, then ++ * one is added. This function should be called after each update to the ++ * EEPROM structure, to make sure the CRC is always correct. ++ * ++ * @eeprom: Pointer to buffer to hold the binary data. Must point to a buffer ++ * of size at least TLV_INFO_MAX_LEN. ++ */ ++void tlvinfo_update_crc(u8 *eeprom); ++ ++/** ++ * Validate the checksum in the provided TlvInfo EEPROM data. First, ++ * verify that the TlvInfo header is valid, then make sure the last ++ * TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data ++ * and compare it to the value stored in the EEPROM CRC-32 TLV. ++ * ++ * @eeprom: Pointer to buffer to hold the binary data. Must point to a buffer ++ * of size at least TLV_INFO_MAX_LEN. ++ */ ++bool tlvinfo_check_crc(u8 *eeprom); ++ + #else /* !CONFIG_IS_ENABLED(CMD_TLV_EEPROM) */ + + static inline int read_tlv_eeprom(void *eeprom, int offset, int len, int dev) +@@ -150,4 +195,16 @@ static inline bool is_valid_tlvinfo_header(struct tlvinfo_header *hdr) + (be16_to_cpu(hdr->totallen) <= TLV_TOTAL_LEN_MAX)); + } + ++/** ++ * is_valid_tlv ++ * ++ * Perform basic sanity checks on a TLV field. The TLV is pointed to ++ * by the parameter provided. ++ * 1. The type code is not reserved (0x00 or 0xFF) ++ */ ++static inline bool is_valid_tlvinfo_entry(struct tlvinfo_tlv *tlv) ++{ ++ return((tlv->type != 0x00) && (tlv->type != 0xFF)); ++} ++ + #endif /* __TLV_EEPROM_H_ */ diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0007-cmd-tlv_eeprom-remove-empty-function-implementations.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0007-cmd-tlv_eeprom-remove-empty-function-implementations.patch new file mode 100644 index 0000000..1a427b6 --- /dev/null +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0007-cmd-tlv_eeprom-remove-empty-function-implementations.patch @@ -0,0 +1,56 @@ +From 04ce313a110bae4262684666c245443182d6f0bc Mon Sep 17 00:00:00 2001 +From: Josua Mayer +Date: Sun, 20 Mar 2022 11:11:25 +0200 +Subject: [PATCH] cmd: tlv_eeprom: remove empty function implementations from + header + +tlv_eeprom exposed functions are independent from platforms, hence no +stubs are required. + +Signed-off-by: Josua Mayer +--- + include/tlv_eeprom.h | 24 ++---------------------- + 1 file changed, 2 insertions(+), 22 deletions(-) + +diff --git a/include/tlv_eeprom.h b/include/tlv_eeprom.h +index eeb8af57f1..201a2b44af 100644 +--- a/include/tlv_eeprom.h ++++ b/include/tlv_eeprom.h +@@ -65,7 +65,8 @@ struct __attribute__ ((__packed__)) tlvinfo_tlv { + #define TLV_CODE_VENDOR_EXT 0xFD + #define TLV_CODE_CRC_32 0xFE + +-#if CONFIG_IS_ENABLED(CMD_TLV_EEPROM) ++/* how many EEPROMs can be used */ ++#define TLV_MAX_DEVICES 2 + + /** + * read_tlv_eeprom - Read the EEPROM binary data from the hardware +@@ -156,27 +157,6 @@ void tlvinfo_update_crc(u8 *eeprom); + */ + bool tlvinfo_check_crc(u8 *eeprom); + +-#else /* !CONFIG_IS_ENABLED(CMD_TLV_EEPROM) */ +- +-static inline int read_tlv_eeprom(void *eeprom, int offset, int len, int dev) +-{ +- return -ENOTSUPP; +-} +- +-static inline int write_tlv_eeprom(void *eeprom, int len) +-{ +- return -ENOTSUPP; +-} +- +-static inline int +-read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr, +- struct tlvinfo_tlv **first_entry, int dev) +-{ +- return -ENOTSUPP; +-} +- +-#endif /* CONFIG_IS_ENABLED(CMD_TLV_EEPROM) */ +- + /** + * is_valid_tlvinfo_header + * diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0008-cmd-tlv_eeprom-split-off-tlv-library-from-command.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0008-cmd-tlv_eeprom-split-off-tlv-library-from-command.patch new file mode 100644 index 0000000..a6e4d04 --- /dev/null +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0008-cmd-tlv_eeprom-split-off-tlv-library-from-command.patch @@ -0,0 +1,1817 @@ +From 24d0ee83a91e25af08cfee748cd4ef307d619463 Mon Sep 17 00:00:00 2001 +From: Josua Mayer +Date: Thu, 17 Mar 2022 14:16:26 +0200 +Subject: [PATCH] cmd: tlv_eeprom: split off tlv library from command + +Signed-off-by: Josua Mayer +--- + cmd/Kconfig | 2 +- + cmd/tlv_eeprom.c | 849 +++---------------------------------------- + include/tlv_eeprom.h | 33 ++ + lib/Kconfig | 2 + + lib/Makefile | 2 + + lib/tlv/Kconfig | 5 + + lib/tlv/Makefile | 5 + + lib/tlv/notes.txt | 10 + + lib/tlv/tlv_eeprom.c | 751 ++++++++++++++++++++++++++++++++++++++ + 9 files changed, 865 insertions(+), 794 deletions(-) + create mode 100644 lib/tlv/Kconfig + create mode 100644 lib/tlv/Makefile + create mode 100644 lib/tlv/notes.txt + create mode 100644 lib/tlv/tlv_eeprom.c + +diff --git a/cmd/Kconfig b/cmd/Kconfig +index f696645c91..a87bcfffbb 100644 +--- a/cmd/Kconfig ++++ b/cmd/Kconfig +@@ -234,7 +234,7 @@ config CMD_REGINFO + + config CMD_TLV_EEPROM + bool "tlv_eeprom" +- depends on I2C_EEPROM ++ select EEPROM_TLV_LIB + help + Display and program the system EEPROM data block in ONIE Tlvinfo + format. TLV stands for Type-Length-Value. +diff --git a/cmd/tlv_eeprom.c b/cmd/tlv_eeprom.c +index 271fefc0c6..fd128c15a3 100644 +--- a/cmd/tlv_eeprom.c ++++ b/cmd/tlv_eeprom.c +@@ -1,190 +1,15 @@ +-// SPDX-License-Identifier: GPL-2.0+ +-/* +- * See file CREDITS for list of people who contributed to this +- * project. +- * +- * Copyright (C) 2013 Curt Brune +- * Copyright (C) 2014 Srideep +- * Copyright (C) 2013 Miles Tseng +- * Copyright (C) 2014,2016 david_yang +- */ +- +-#include + #include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include "tlv_eeprom.h" +- +-DECLARE_GLOBAL_DATA_PTR; +- +-#define MAX_TLV_DEVICES 2 +- +-/* File scope function prototypes */ +-static int read_eeprom(int devnum, u8 *eeprom); +-static void show_eeprom(int devnum, u8 *eeprom); +-static void decode_tlv(struct tlvinfo_tlv *tlv); +-static bool tlvinfo_delete_tlv(u8 *eeprom, u8 code); +-static bool tlvinfo_add_tlv(u8 *eeprom, int tcode, char *strval); +-static int set_mac(char *buf, const char *string); +-static int set_date(char *buf, const char *string); +-static int set_bytes(char *buf, const char *string, int *converted_accum); +-static void show_tlv_devices(int current_dev); ++#include ++#include ++#include ++#include + + /* The EERPOM contents after being read into memory */ + static u8 eeprom[TLV_INFO_MAX_LEN]; + +-static struct udevice *tlv_devices[MAX_TLV_DEVICES]; +- + #define to_header(p) ((struct tlvinfo_header *)p) + #define to_entry(p) ((struct tlvinfo_tlv *)p) + +-#define HDR_SIZE sizeof(struct tlvinfo_header) +-#define ENT_SIZE sizeof(struct tlvinfo_tlv) +- +-static inline bool is_digit(char c) +-{ +- return (c >= '0' && c <= '9'); +-} +- +-/** +- * is_hex +- * +- * Tests if character is an ASCII hex digit +- */ +-static inline u8 is_hex(char p) +-{ +- return (((p >= '0') && (p <= '9')) || +- ((p >= 'A') && (p <= 'F')) || +- ((p >= 'a') && (p <= 'f'))); +-} +- +-/** +- * Validate the checksum in the provided TlvInfo EEPROM data. First, +- * verify that the TlvInfo header is valid, then make sure the last +- * TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data +- * and compare it to the value stored in the EEPROM CRC-32 TLV. +- */ +-bool tlvinfo_check_crc(u8 *eeprom) +-{ +- struct tlvinfo_header *eeprom_hdr = to_header(eeprom); +- struct tlvinfo_tlv *eeprom_crc; +- unsigned int calc_crc; +- unsigned int stored_crc; +- +- // Is the eeprom header valid? +- if (!is_valid_tlvinfo_header(eeprom_hdr)) +- return false; +- +- // Is the last TLV a CRC? +- eeprom_crc = to_entry(&eeprom[HDR_SIZE + +- be16_to_cpu(eeprom_hdr->totallen) - (ENT_SIZE + 4)]); +- if (eeprom_crc->type != TLV_CODE_CRC_32 || eeprom_crc->length != 4) +- return false; +- +- // Calculate the checksum +- calc_crc = crc32(0, (void *)eeprom, +- HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen) - 4); +- stored_crc = (eeprom_crc->value[0] << 24) | +- (eeprom_crc->value[1] << 16) | +- (eeprom_crc->value[2] << 8) | +- eeprom_crc->value[3]; +- return calc_crc == stored_crc; +-} +- +-/** +- * read_eeprom +- * +- * Read the EEPROM into memory, if it hasn't already been read. +- */ +-static int read_eeprom(int devnum, u8 *eeprom) +-{ +- int ret; +- struct tlvinfo_header *eeprom_hdr = to_header(eeprom); +- struct tlvinfo_tlv *eeprom_tlv = to_entry(&eeprom[HDR_SIZE]); +- +- /* Read the header */ +- ret = read_tlv_eeprom((void *)eeprom_hdr, 0, HDR_SIZE, devnum); +- /* If the header was successfully read, read the TLVs */ +- if (ret == 0 && is_valid_tlvinfo_header(eeprom_hdr)) +- ret = read_tlv_eeprom((void *)eeprom_tlv, HDR_SIZE, +- be16_to_cpu(eeprom_hdr->totallen), devnum); +- +- // If the contents are invalid, start over with default contents +- if (!is_valid_tlvinfo_header(eeprom_hdr) || +- !tlvinfo_check_crc(eeprom)) { +- strcpy(eeprom_hdr->signature, TLV_INFO_ID_STRING); +- eeprom_hdr->version = TLV_INFO_VERSION; +- eeprom_hdr->totallen = cpu_to_be16(0); +- tlvinfo_update_crc(eeprom); +- } +- +-#ifdef DEBUG +- show_eeprom(devnum, eeprom); +-#endif +- +- return ret; +-} +- +-/** +- * show_eeprom +- * +- * Display the contents of the EEPROM +- */ +-static void show_eeprom(int devnum, u8 *eeprom) +-{ +- int tlv_end; +- int curr_tlv; +-#ifdef DEBUG +- int i; +-#endif +- struct tlvinfo_header *eeprom_hdr = to_header(eeprom); +- struct tlvinfo_tlv *eeprom_tlv; +- +- if (!is_valid_tlvinfo_header(eeprom_hdr)) { +- printf("EEPROM does not contain data in a valid TlvInfo format.\n"); +- return; +- } +- +- printf("TLV: %u\n", devnum); +- printf("TlvInfo Header:\n"); +- printf(" Id String: %s\n", eeprom_hdr->signature); +- printf(" Version: %d\n", eeprom_hdr->version); +- printf(" Total Length: %d\n", be16_to_cpu(eeprom_hdr->totallen)); +- +- printf("TLV Name Code Len Value\n"); +- printf("-------------------- ---- --- -----\n"); +- curr_tlv = HDR_SIZE; +- tlv_end = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); +- while (curr_tlv < tlv_end) { +- eeprom_tlv = to_entry(&eeprom[curr_tlv]); +- if (!is_valid_tlvinfo_entry(eeprom_tlv)) { +- printf("Invalid TLV field starting at EEPROM offset %d\n", +- curr_tlv); +- return; +- } +- decode_tlv(eeprom_tlv); +- curr_tlv += ENT_SIZE + eeprom_tlv->length; +- } +- +- printf("Checksum is %s.\n", +- tlvinfo_check_crc(eeprom) ? "valid" : "invalid"); +- +-#ifdef DEBUG +- printf("EEPROM dump: (0x%x bytes)", TLV_INFO_MAX_LEN); +- for (i = 0; i < TLV_INFO_MAX_LEN; i++) { +- if ((i % 16) == 0) +- printf("\n%02X: ", i); +- printf("%02X ", eeprom[i]); +- } +- printf("\n"); +-#endif +-} +- + /** + * Struct for displaying the TLV codes and names. + */ +@@ -319,63 +144,58 @@ static void decode_tlv(struct tlvinfo_tlv *tlv) + } + + /** +- * tlvinfo_update_crc ++ * show_eeprom + * +- * This function updates the CRC-32 TLV. If there is no CRC-32 TLV, then +- * one is added. This function should be called after each update to the +- * EEPROM structure, to make sure the CRC is always correct. ++ * Display the contents of the EEPROM + */ +-void tlvinfo_update_crc(u8 *eeprom) ++static void show_eeprom(int devnum, u8 *eeprom) + { ++ int tlv_end; ++ int curr_tlv; ++#ifdef DEBUG ++ int i; ++#endif + struct tlvinfo_header *eeprom_hdr = to_header(eeprom); +- struct tlvinfo_tlv *eeprom_crc; +- unsigned int calc_crc; +- int eeprom_index; +- +- // Discover the CRC TLV +- if (!tlvinfo_find_tlv(eeprom, TLV_CODE_CRC_32, &eeprom_index)) { +- unsigned int totallen = be16_to_cpu(eeprom_hdr->totallen); ++ struct tlvinfo_tlv *eeprom_tlv; + +- if ((totallen + ENT_SIZE + 4) > TLV_TOTAL_LEN_MAX) +- return; +- eeprom_index = HDR_SIZE + totallen; +- eeprom_hdr->totallen = cpu_to_be16(totallen + ENT_SIZE + 4); ++ if (!is_valid_tlvinfo_header(eeprom_hdr)) { ++ printf("EEPROM does not contain data in a valid TlvInfo format.\n"); ++ return; + } +- eeprom_crc = to_entry(&eeprom[eeprom_index]); +- eeprom_crc->type = TLV_CODE_CRC_32; +- eeprom_crc->length = 4; + +- // Calculate the checksum +- calc_crc = crc32(0, (void *)eeprom, +- HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen) - 4); +- eeprom_crc->value[0] = (calc_crc >> 24) & 0xFF; +- eeprom_crc->value[1] = (calc_crc >> 16) & 0xFF; +- eeprom_crc->value[2] = (calc_crc >> 8) & 0xFF; +- eeprom_crc->value[3] = (calc_crc >> 0) & 0xFF; +-} ++ printf("TLV: %u\n", devnum); ++ printf("TlvInfo Header:\n"); ++ printf(" Id String: %s\n", eeprom_hdr->signature); ++ printf(" Version: %d\n", eeprom_hdr->version); ++ printf(" Total Length: %d\n", be16_to_cpu(eeprom_hdr->totallen)); + +-/** +- * write_tlvinfo_tlv_eeprom +- * +- * Write the TLV data from CPU memory to the hardware. +- */ +-int write_tlvinfo_tlv_eeprom(void *eeprom, int dev) +-{ +- int ret = 0; +- struct tlvinfo_header *eeprom_hdr = to_header(eeprom); +- int eeprom_len; ++ printf("TLV Name Code Len Value\n"); ++ printf("-------------------- ---- --- -----\n"); ++ curr_tlv = TLV_INFO_HEADER_SIZE; ++ tlv_end = TLV_INFO_HEADER_SIZE + be16_to_cpu(eeprom_hdr->totallen); ++ while (curr_tlv < tlv_end) { ++ eeprom_tlv = to_entry(&eeprom[curr_tlv]); ++ if (!is_valid_tlvinfo_entry(eeprom_tlv)) { ++ printf("Invalid TLV field starting at EEPROM offset %d\n", ++ curr_tlv); ++ return; ++ } ++ decode_tlv(eeprom_tlv); ++ curr_tlv += TLV_INFO_ENTRY_SIZE + eeprom_tlv->length; ++ } + +- tlvinfo_update_crc(eeprom); ++ printf("Checksum is %s.\n", ++ tlvinfo_check_crc(eeprom) ? "valid" : "invalid"); + +- eeprom_len = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); +- ret = write_tlv_eeprom(eeprom, eeprom_len, dev); +- if (ret) { +- printf("Programming failed.\n"); +- return -1; ++#ifdef DEBUG ++ printf("EEPROM dump: (0x%x bytes)", TLV_INFO_MAX_LEN); ++ for (i = 0; i < TLV_INFO_MAX_LEN; i++) { ++ if ((i % 16) == 0) ++ printf("\n%02X: ", i); ++ printf("%02X ", eeprom[i]); + } +- +- printf("Programming passed.\n"); +- return 0; ++ printf("\n"); ++#endif + } + + /** +@@ -394,6 +214,16 @@ void show_tlv_code_list(void) + } + } + ++static void show_tlv_devices(int current_dev) ++{ ++ unsigned int dev; ++ ++ for (dev = 0; dev < TLV_MAX_DEVICES; dev++) ++ if (exists_tlv_eeprom(dev)) ++ printf("TLV: %u%s\n", dev, ++ (dev == current_dev) ? " (*)" : ""); ++} ++ + /** + * do_tlv_eeprom + * +@@ -483,7 +313,7 @@ int do_tlv_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) + unsigned int devnum; + + devnum = simple_strtoul(argv[2], NULL, 0); +- if (devnum > MAX_TLV_DEVICES || !tlv_devices[devnum]) { ++ if (devnum > TLV_MAX_DEVICES || !exists_tlv_eeprom(devnum)) { + printf("Invalid device number\n"); + return 0; + } +@@ -520,570 +350,3 @@ U_BOOT_CMD(tlv_eeprom, 4, 1, do_tlv_eeprom, + "tlv_eeprom list\n" + " - List the understood TLV codes and names.\n" + ); +- +-/** +- * tlvinfo_find_tlv +- * +- * This function finds the TLV with the supplied code in the EERPOM. +- * An offset from the beginning of the EEPROM is returned in the +- * eeprom_index parameter if the TLV is found. +- */ +-bool tlvinfo_find_tlv(u8 *eeprom, u8 tcode, int *eeprom_index) +-{ +- struct tlvinfo_header *eeprom_hdr = to_header(eeprom); +- struct tlvinfo_tlv *eeprom_tlv; +- int eeprom_end; +- +- // Search through the TLVs, looking for the first one which matches the +- // supplied type code. +- *eeprom_index = HDR_SIZE; +- eeprom_end = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); +- while (*eeprom_index < eeprom_end) { +- eeprom_tlv = to_entry(&eeprom[*eeprom_index]); +- if (!is_valid_tlvinfo_entry(eeprom_tlv)) +- return false; +- if (eeprom_tlv->type == tcode) +- return true; +- *eeprom_index += ENT_SIZE + eeprom_tlv->length; +- } +- return(false); +-} +- +-/** +- * tlvinfo_delete_tlv +- * +- * This function deletes the TLV with the specified type code from the +- * EEPROM. +- */ +-static bool tlvinfo_delete_tlv(u8 *eeprom, u8 code) +-{ +- int eeprom_index; +- int tlength; +- struct tlvinfo_header *eeprom_hdr = to_header(eeprom); +- struct tlvinfo_tlv *eeprom_tlv; +- +- // Find the TLV and then move all following TLVs "forward" +- if (tlvinfo_find_tlv(eeprom, code, &eeprom_index)) { +- eeprom_tlv = to_entry(&eeprom[eeprom_index]); +- tlength = ENT_SIZE + eeprom_tlv->length; +- memcpy(&eeprom[eeprom_index], &eeprom[eeprom_index + tlength], +- HDR_SIZE + +- be16_to_cpu(eeprom_hdr->totallen) - eeprom_index - +- tlength); +- eeprom_hdr->totallen = +- cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) - +- tlength); +- tlvinfo_update_crc(eeprom); +- return true; +- } +- return false; +-} +- +-/** +- * tlvinfo_add_tlv +- * +- * This function adds a TLV to the EEPROM, converting the value (a string) to +- * the format in which it will be stored in the EEPROM. +- */ +-#define MAX_TLV_VALUE_LEN 256 +-static bool tlvinfo_add_tlv(u8 *eeprom, int tcode, char *strval) +-{ +- struct tlvinfo_header *eeprom_hdr = to_header(eeprom); +- struct tlvinfo_tlv *eeprom_tlv; +- int new_tlv_len = 0; +- u32 value; +- char data[MAX_TLV_VALUE_LEN]; +- int eeprom_index; +- +- // Encode each TLV type into the format to be stored in the EERPOM +- switch (tcode) { +- case TLV_CODE_PRODUCT_NAME: +- case TLV_CODE_PART_NUMBER: +- case TLV_CODE_SERIAL_NUMBER: +- case TLV_CODE_LABEL_REVISION: +- case TLV_CODE_PLATFORM_NAME: +- case TLV_CODE_ONIE_VERSION: +- case TLV_CODE_MANUF_NAME: +- case TLV_CODE_MANUF_COUNTRY: +- case TLV_CODE_VENDOR_NAME: +- case TLV_CODE_DIAG_VERSION: +- case TLV_CODE_SERVICE_TAG: +- strncpy(data, strval, MAX_TLV_VALUE_LEN); +- new_tlv_len = min_t(size_t, MAX_TLV_VALUE_LEN, strlen(strval)); +- break; +- case TLV_CODE_DEVICE_VERSION: +- value = simple_strtoul(strval, NULL, 0); +- if (value >= 256) { +- printf("ERROR: Device version must be 255 or less. Value supplied: %u", +- value); +- return false; +- } +- data[0] = value & 0xFF; +- new_tlv_len = 1; +- break; +- case TLV_CODE_MAC_SIZE: +- value = simple_strtoul(strval, NULL, 0); +- if (value >= 65536) { +- printf("ERROR: MAC Size must be 65535 or less. Value supplied: %u", +- value); +- return false; +- } +- data[0] = (value >> 8) & 0xFF; +- data[1] = value & 0xFF; +- new_tlv_len = 2; +- break; +- case TLV_CODE_MANUF_DATE: +- if (set_date(data, strval) != 0) +- return false; +- new_tlv_len = 19; +- break; +- case TLV_CODE_MAC_BASE: +- if (set_mac(data, strval) != 0) +- return false; +- new_tlv_len = 6; +- break; +- case TLV_CODE_CRC_32: +- printf("WARNING: The CRC TLV is set automatically and cannot be set manually.\n"); +- return false; +- case TLV_CODE_VENDOR_EXT: +- default: +- if (set_bytes(data, strval, &new_tlv_len) != 0) +- return false; +- break; +- } +- +- // Is there room for this TLV? +- if ((be16_to_cpu(eeprom_hdr->totallen) + ENT_SIZE + new_tlv_len) > +- TLV_TOTAL_LEN_MAX) { +- printf("ERROR: There is not enough room in the EERPOM to save data.\n"); +- return false; +- } +- +- // Add TLV at the end, overwriting CRC TLV if it exists +- if (tlvinfo_find_tlv(eeprom, TLV_CODE_CRC_32, &eeprom_index)) +- eeprom_hdr->totallen = +- cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) - +- ENT_SIZE - 4); +- else +- eeprom_index = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); +- eeprom_tlv = to_entry(&eeprom[eeprom_index]); +- eeprom_tlv->type = tcode; +- eeprom_tlv->length = new_tlv_len; +- memcpy(eeprom_tlv->value, data, new_tlv_len); +- +- // Update the total length and calculate (add) a new CRC-32 TLV +- eeprom_hdr->totallen = cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) + +- ENT_SIZE + new_tlv_len); +- tlvinfo_update_crc(eeprom); +- +- return true; +-} +- +-/** +- * set_mac +- * +- * Converts a string MAC address into a binary buffer. +- * +- * This function takes a pointer to a MAC address string +- * (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number). +- * The string format is verified and then converted to binary and +- * stored in a buffer. +- */ +-static int set_mac(char *buf, const char *string) +-{ +- char *p = (char *)string; +- int i; +- int err = 0; +- char *end; +- +- if (!p) { +- printf("ERROR: NULL mac addr string passed in.\n"); +- return -1; +- } +- +- if (strlen(p) != 17) { +- printf("ERROR: MAC address strlen() != 17 -- %zu\n", strlen(p)); +- printf("ERROR: Bad MAC address format: %s\n", string); +- return -1; +- } +- +- for (i = 0; i < 17; i++) { +- if ((i % 3) == 2) { +- if (p[i] != ':') { +- err++; +- printf("ERROR: mac: p[%i] != :, found: `%c'\n", +- i, p[i]); +- break; +- } +- continue; +- } else if (!is_hex(p[i])) { +- err++; +- printf("ERROR: mac: p[%i] != hex digit, found: `%c'\n", +- i, p[i]); +- break; +- } +- } +- +- if (err != 0) { +- printf("ERROR: Bad MAC address format: %s\n", string); +- return -1; +- } +- +- /* Convert string to binary */ +- for (i = 0, p = (char *)string; i < 6; i++) { +- buf[i] = p ? simple_strtoul(p, &end, 16) : 0; +- if (p) +- p = (*end) ? end + 1 : end; +- } +- +- if (!is_valid_ethaddr((u8 *)buf)) { +- printf("ERROR: MAC address must not be 00:00:00:00:00:00, a multicast address or FF:FF:FF:FF:FF:FF.\n"); +- printf("ERROR: Bad MAC address format: %s\n", string); +- return -1; +- } +- +- return 0; +-} +- +-/** +- * set_date +- * +- * Validates the format of the data string +- * +- * This function takes a pointer to a date string (i.e. MM/DD/YYYY hh:mm:ss) +- * and validates that the format is correct. If so the string is copied +- * to the supplied buffer. +- */ +-static int set_date(char *buf, const char *string) +-{ +- int i; +- +- if (!string) { +- printf("ERROR: NULL date string passed in.\n"); +- return -1; +- } +- +- if (strlen(string) != 19) { +- printf("ERROR: Date strlen() != 19 -- %zu\n", strlen(string)); +- printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", +- string); +- return -1; +- } +- +- for (i = 0; string[i] != 0; i++) { +- switch (i) { +- case 2: +- case 5: +- if (string[i] != '/') { +- printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", +- string); +- return -1; +- } +- break; +- case 10: +- if (string[i] != ' ') { +- printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", +- string); +- return -1; +- } +- break; +- case 13: +- case 16: +- if (string[i] != ':') { +- printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", +- string); +- return -1; +- } +- break; +- default: +- if (!is_digit(string[i])) { +- printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", +- string); +- return -1; +- } +- break; +- } +- } +- +- strcpy(buf, string); +- return 0; +-} +- +-/** +- * set_bytes +- * +- * Converts a space-separated string of decimal numbers into a +- * buffer of bytes. +- * +- * This function takes a pointer to a space-separated string of decimal +- * numbers (i.e. "128 0x55 0321") with "C" standard radix specifiers +- * and converts them to an array of bytes. +- */ +-static int set_bytes(char *buf, const char *string, int *converted_accum) +-{ +- char *p = (char *)string; +- int i; +- uint byte; +- +- if (!p) { +- printf("ERROR: NULL string passed in.\n"); +- return -1; +- } +- +- /* Convert string to bytes */ +- for (i = 0, p = (char *)string; (i < TLV_VALUE_MAX_LEN) && (*p != 0); +- i++) { +- while ((*p == ' ') || (*p == '\t') || (*p == ',') || +- (*p == ';')) { +- p++; +- } +- if (*p != 0) { +- if (!is_digit(*p)) { +- printf("ERROR: Non-digit found in byte string: (%s)\n", +- string); +- return -1; +- } +- byte = simple_strtoul(p, &p, 0); +- if (byte >= 256) { +- printf("ERROR: The value specified is greater than 255: (%u) in string: %s\n", +- byte, string); +- return -1; +- } +- buf[i] = byte & 0xFF; +- } +- } +- +- if (i == TLV_VALUE_MAX_LEN && (*p != 0)) { +- printf("ERROR: Trying to assign too many bytes (max: %d) in string: %s\n", +- TLV_VALUE_MAX_LEN, string); +- return -1; +- } +- +- *converted_accum = i; +- return 0; +-} +- +-static void show_tlv_devices(int current_dev) +-{ +- unsigned int dev; +- +- for (dev = 0; dev < MAX_TLV_DEVICES; dev++) +- if (tlv_devices[dev]) +- printf("TLV: %u%s\n", dev, +- (dev == current_dev) ? " (*)" : ""); +-} +- +-static int find_tlv_devices(struct udevice **tlv_devices_p) +-{ +- int ret; +- int count_dev = 0; +- struct udevice *dev; +- +- for (ret = uclass_first_device_check(UCLASS_I2C_EEPROM, &dev); +- dev; +- ret = uclass_next_device_check(&dev)) { +- if (ret == 0) +- tlv_devices_p[count_dev++] = dev; +- if (count_dev >= MAX_TLV_DEVICES) +- break; +- } +- +- return (count_dev == 0) ? -ENODEV : 0; +-} +- +-static struct udevice *find_tlv_device_by_index(int dev_num) +-{ +- struct udevice *local_tlv_devices[MAX_TLV_DEVICES] = {}; +- struct udevice **tlv_devices_p; +- int ret; +- +- if (gd->flags & (GD_FLG_RELOC | GD_FLG_SPL_INIT)) { +- /* Assume BSS is initialized; use static data */ +- if (tlv_devices[dev_num]) +- return tlv_devices[dev_num]; +- tlv_devices_p = tlv_devices; +- } else { +- tlv_devices_p = local_tlv_devices; +- } +- +- ret = find_tlv_devices(tlv_devices_p); +- if (ret == 0 && tlv_devices_p[dev_num]) +- return tlv_devices_p[dev_num]; +- +- return NULL; +-} +- +-/** +- * read_tlv_eeprom - read the hwinfo from i2c EEPROM +- */ +-int read_tlv_eeprom(void *eeprom, int offset, int len, int dev_num) +-{ +- struct udevice *dev; +- +- if (dev_num >= MAX_TLV_DEVICES) +- return -EINVAL; +- +- dev = find_tlv_device_by_index(dev_num); +- if (!dev) +- return -ENODEV; +- +- return i2c_eeprom_read(dev, offset, eeprom, len); +-} +- +-/** +- * write_tlv_eeprom - write the hwinfo to i2c EEPROM +- */ +-int write_tlv_eeprom(void *eeprom, int len, int dev) +-{ +- if (!(gd->flags & GD_FLG_RELOC)) +- return -ENODEV; +- if (!tlv_devices[dev]) +- return -ENODEV; +- +- return i2c_eeprom_write(tlv_devices[dev], 0, eeprom, len); +-} +- +-int read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr, +- struct tlvinfo_tlv **first_entry, int dev_num) +-{ +- int ret; +- struct tlvinfo_header *tlv_hdr; +- struct tlvinfo_tlv *tlv_ent; +- +- /* Read TLV header */ +- ret = read_tlv_eeprom(eeprom, 0, HDR_SIZE, dev_num); +- if (ret < 0) +- return ret; +- +- tlv_hdr = eeprom; +- if (!is_valid_tlvinfo_header(tlv_hdr)) +- return -EINVAL; +- +- /* Read TLV entries */ +- tlv_ent = to_entry(&tlv_hdr[1]); +- ret = read_tlv_eeprom(tlv_ent, HDR_SIZE, +- be16_to_cpu(tlv_hdr->totallen), dev_num); +- if (ret < 0) +- return ret; +- if (!tlvinfo_check_crc(eeprom)) +- return -EINVAL; +- +- *hdr = tlv_hdr; +- *first_entry = tlv_ent; +- +- return 0; +-} +- +-/** +- * mac_read_from_eeprom +- * +- * Read the MAC addresses from EEPROM +- * +- * This function reads the MAC addresses from EEPROM and sets the +- * appropriate environment variables for each one read. +- * +- * The environment variables are only set if they haven't been set already. +- * This ensures that any user-saved variables are never overwritten. +- * +- * This function must be called after relocation. +- */ +-int mac_read_from_eeprom(void) +-{ +- unsigned int i; +- int eeprom_index; +- struct tlvinfo_tlv *eeprom_tlv; +- int maccount; +- u8 macbase[6]; +- struct tlvinfo_header *eeprom_hdr = to_header(eeprom); +- int devnum = 0; // TODO: support multiple EEPROMs +- +- puts("EEPROM: "); +- +- if (read_eeprom(devnum, eeprom)) { +- printf("Read failed.\n"); +- return -1; +- } +- +- maccount = 1; +- if (tlvinfo_find_tlv(eeprom, TLV_CODE_MAC_SIZE, &eeprom_index)) { +- eeprom_tlv = to_entry(&eeprom[eeprom_index]); +- maccount = (eeprom_tlv->value[0] << 8) | eeprom_tlv->value[1]; +- } +- +- memcpy(macbase, "\0\0\0\0\0\0", 6); +- if (tlvinfo_find_tlv(eeprom, TLV_CODE_MAC_BASE, &eeprom_index)) { +- eeprom_tlv = to_entry(&eeprom[eeprom_index]); +- memcpy(macbase, eeprom_tlv->value, 6); +- } +- +- for (i = 0; i < maccount; i++) { +- if (is_valid_ethaddr(macbase)) { +- char ethaddr[18]; +- char enetvar[11]; +- +- sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X", +- macbase[0], macbase[1], macbase[2], +- macbase[3], macbase[4], macbase[5]); +- sprintf(enetvar, i ? "eth%daddr" : "ethaddr", i); +- /* Only initialize environment variables that are blank +- * (i.e. have not yet been set) +- */ +- if (!env_get(enetvar)) +- env_set(enetvar, ethaddr); +- +- macbase[5]++; +- if (macbase[5] == 0) { +- macbase[4]++; +- if (macbase[4] == 0) { +- macbase[3]++; +- if (macbase[3] == 0) { +- macbase[0] = 0; +- macbase[1] = 0; +- macbase[2] = 0; +- } +- } +- } +- } +- } +- +- printf("%s v%u len=%u\n", eeprom_hdr->signature, eeprom_hdr->version, +- be16_to_cpu(eeprom_hdr->totallen)); +- +- return 0; +-} +- +-/** +- * populate_serial_number - read the serial number from EEPROM +- * +- * This function reads the serial number from the EEPROM and sets the +- * appropriate environment variable. +- * +- * The environment variable is only set if it has not been set +- * already. This ensures that any user-saved variables are never +- * overwritten. +- * +- * This function must be called after relocation. +- */ +-int populate_serial_number(int devnum) +-{ +- char serialstr[257]; +- int eeprom_index; +- struct tlvinfo_tlv *eeprom_tlv; +- +- if (env_get("serial#")) +- return 0; +- +- if (read_eeprom(devnum, eeprom)) { +- printf("Read failed.\n"); +- return -1; +- } +- +- if (tlvinfo_find_tlv(eeprom, TLV_CODE_SERIAL_NUMBER, &eeprom_index)) { +- eeprom_tlv = to_entry(&eeprom[eeprom_index]); +- memcpy(serialstr, eeprom_tlv->value, eeprom_tlv->length); +- serialstr[eeprom_tlv->length] = 0; +- env_set("serial#", serialstr); +- } +- +- return 0; +-} +diff --git a/include/tlv_eeprom.h b/include/tlv_eeprom.h +index 201a2b44af..ee9f035c8c 100644 +--- a/include/tlv_eeprom.h ++++ b/include/tlv_eeprom.h +@@ -22,6 +22,7 @@ struct __attribute__ ((__packed__)) tlvinfo_header { + u8 version; /* 0x08 Structure version */ + u16 totallen; /* 0x09 - 0x0A Length of all data which follows */ + }; ++#define TLV_INFO_HEADER_SIZE sizeof(struct tlvinfo_header) + + // Header Field Constants + #define TLV_INFO_ID_STRING "TlvInfo" +@@ -38,6 +39,7 @@ struct __attribute__ ((__packed__)) tlvinfo_tlv { + u8 length; + u8 value[0]; + }; ++#define TLV_INFO_ENTRY_SIZE sizeof(struct tlvinfo_tlv) + + /* Maximum length of a TLV value in bytes */ + #define TLV_VALUE_MAX_LEN 255 +@@ -68,6 +70,13 @@ struct __attribute__ ((__packed__)) tlvinfo_tlv { + /* how many EEPROMs can be used */ + #define TLV_MAX_DEVICES 2 + ++/** ++ * Check whether eeprom device exists. ++ * ++ * @dev: EEPROM device to check. ++ */ ++bool exists_tlv_eeprom(int dev); ++ + /** + * read_tlv_eeprom - Read the EEPROM binary data from the hardware + * @eeprom: Pointer to buffer to hold the binary data +@@ -134,6 +143,30 @@ int write_tlvinfo_tlv_eeprom(void *eeprom, int dev); + */ + bool tlvinfo_find_tlv(u8 *eeprom, u8 tcode, int *eeprom_index); + ++/** ++ * tlvinfo_add_tlv ++ * ++ * This function adds a TLV to the EEPROM, converting the value (a string) to ++ * the format in which it will be stored in the EEPROM. ++ * @eeprom: Pointer to buffer to hold the binary data. Must point to a buffer ++ * of size at least TLV_INFO_MAX_LEN. ++ * @code The TLV Code for the new entry. ++ * @eeprom_index success offset into EEPROM where the new entry has been stored ++ * ++ */ ++bool tlvinfo_add_tlv(u8 *eeprom, int code, char *strval); ++ ++/** ++ * tlvinfo_delete_tlv ++ * ++ * This function deletes the TLV with the specified type code from the ++ * EEPROM. ++ * @eeprom: Pointer to buffer to hold the binary data. Must point to a buffer ++ * of size at least TLV_INFO_MAX_LEN. ++ * @code The TLV Code of the entry to delete. ++ */ ++bool tlvinfo_delete_tlv(u8 *eeprom, u8 code); ++ + /** + * tlvinfo_update_crc + * +diff --git a/lib/Kconfig b/lib/Kconfig +index 3da45a5ec3..a2ee5af8b4 100644 +--- a/lib/Kconfig ++++ b/lib/Kconfig +@@ -530,3 +530,5 @@ config TEST_FDTDEC + depends on OF_LIBFDT + + endmenu ++ ++source lib/tlv/Kconfig +diff --git a/lib/Makefile b/lib/Makefile +index 2fffd68f94..27dcb72795 100644 +--- a/lib/Makefile ++++ b/lib/Makefile +@@ -117,4 +117,6 @@ else + obj-y += vsprintf.o strto.o strmhz.o + endif + ++obj-$(CONFIG_$(SPL_)EEPROM_TLV_LIB) += tlv/ ++ + subdir-ccflags-$(CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED) += -O2 +diff --git a/lib/tlv/Kconfig b/lib/tlv/Kconfig +new file mode 100644 +index 0000000000..adbba31127 +--- /dev/null ++++ b/lib/tlv/Kconfig +@@ -0,0 +1,5 @@ ++config EEPROM_TLV_LIB ++ bool "Support EEPROM TLV library" ++ depends on I2C_EEPROM ++ help ++ Selecting this option will enable the shared EEPROM TLV library code. +diff --git a/lib/tlv/Makefile b/lib/tlv/Makefile +new file mode 100644 +index 0000000000..8e96752e75 +--- /dev/null ++++ b/lib/tlv/Makefile +@@ -0,0 +1,5 @@ ++# SPDX-License-Identifier: GPL-2.0+ ++# ++# (C) Copyright 2017 Linaro ++ ++obj-$(CONFIG_EEPROM_TLV_LIB) += tlv_eeprom.o +diff --git a/lib/tlv/notes.txt b/lib/tlv/notes.txt +new file mode 100644 +index 0000000000..c96c6ae40c +--- /dev/null ++++ b/lib/tlv/notes.txt +@@ -0,0 +1,10 @@ ++static inline bool is_digit(char c) - used inside set commands - can be internal ++static inline bool is_valid_tlv(struct tlvinfo_tlv *tlv) - maybe api, maybe internal ++static inline u8 is_hex(char p) - internal ++static bool is_checksum_valid(u8 *eeprom) - make api ++ ++static int read_eeprom(int devnum, u8 *eeprom) ++static void show_tlv_devices(int current_dev = -1) ++int write_tlv_eeprom(int dev, void *eeprom, int len) ++int populate_serial_number(int devnum)? ++static int prog_eeprom(int devnum, u8 *eeprom) +diff --git a/lib/tlv/tlv_eeprom.c b/lib/tlv/tlv_eeprom.c +new file mode 100644 +index 0000000000..fe164cabe6 +--- /dev/null ++++ b/lib/tlv/tlv_eeprom.c +@@ -0,0 +1,751 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * See file CREDITS for list of people who contributed to this ++ * project. ++ * ++ * Copyright (C) 2013 Curt Brune ++ * Copyright (C) 2014 Srideep ++ * Copyright (C) 2013 Miles Tseng ++ * Copyright (C) 2014,2016 david_yang ++ * Copyright (C) 2022 Josua Mayer ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "tlv_eeprom.h" ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++/* File scope function prototypes */ ++static int read_eeprom(int devnum, u8 *eeprom); ++static int set_mac(char *buf, const char *string); ++static int set_date(char *buf, const char *string); ++static int set_bytes(char *buf, const char *string, int *converted_accum); ++ ++static struct udevice *tlv_devices[TLV_MAX_DEVICES]; ++ ++#define to_header(p) ((struct tlvinfo_header *)p) ++#define to_entry(p) ((struct tlvinfo_tlv *)p) ++ ++#define HDR_SIZE TLV_INFO_HEADER_SIZE ++#define ENT_SIZE TLV_INFO_ENTRY_SIZE ++ ++/** ++ * Check whether eeprom device exists. ++ */ ++bool exists_tlv_eeprom(int dev) ++{ ++ return dev < TLV_MAX_DEVICES && tlv_devices[dev] != 0; ++} ++ ++static inline bool is_digit(char c) ++{ ++ return (c >= '0' && c <= '9'); ++} ++ ++/** ++ * is_hex ++ * ++ * Tests if character is an ASCII hex digit ++ */ ++static inline u8 is_hex(char p) ++{ ++ return (((p >= '0') && (p <= '9')) || ++ ((p >= 'A') && (p <= 'F')) || ++ ((p >= 'a') && (p <= 'f'))); ++} ++ ++/** ++ * Validate the checksum in the provided TlvInfo EEPROM data. First, ++ * verify that the TlvInfo header is valid, then make sure the last ++ * TLV is a CRC-32 TLV. Then calculate the CRC over the EEPROM data ++ * and compare it to the value stored in the EEPROM CRC-32 TLV. ++ */ ++bool tlvinfo_check_crc(u8 *eeprom) ++{ ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ struct tlvinfo_tlv *eeprom_crc; ++ unsigned int calc_crc; ++ unsigned int stored_crc; ++ ++ // Is the eeprom header valid? ++ if (!is_valid_tlvinfo_header(eeprom_hdr)) ++ return false; ++ ++ // Is the last TLV a CRC? ++ eeprom_crc = to_entry(&eeprom[HDR_SIZE + ++ be16_to_cpu(eeprom_hdr->totallen) - (ENT_SIZE + 4)]); ++ if (eeprom_crc->type != TLV_CODE_CRC_32 || eeprom_crc->length != 4) ++ return false; ++ ++ // Calculate the checksum ++ calc_crc = crc32(0, (void *)eeprom, ++ HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen) - 4); ++ stored_crc = (eeprom_crc->value[0] << 24) | ++ (eeprom_crc->value[1] << 16) | ++ (eeprom_crc->value[2] << 8) | ++ eeprom_crc->value[3]; ++ return calc_crc == stored_crc; ++} ++ ++/** ++ * read_eeprom ++ * ++ * Read the EEPROM into memory, if it hasn't already been read. ++ */ ++static int read_eeprom(int devnum, u8 *eeprom) ++{ ++ int ret; ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ struct tlvinfo_tlv *eeprom_tlv = to_entry(&eeprom[HDR_SIZE]); ++ ++ /* Read the header */ ++ ret = read_tlv_eeprom((void *)eeprom_hdr, 0, HDR_SIZE, devnum); ++ /* If the header was successfully read, read the TLVs */ ++ if (ret == 0 && is_valid_tlvinfo_header(eeprom_hdr)) ++ ret = read_tlv_eeprom((void *)eeprom_tlv, HDR_SIZE, ++ be16_to_cpu(eeprom_hdr->totallen), devnum); ++ ++ // If the contents are invalid, start over with default contents ++ if (!is_valid_tlvinfo_header(eeprom_hdr) || ++ !tlvinfo_check_crc(eeprom)) { ++ strcpy(eeprom_hdr->signature, TLV_INFO_ID_STRING); ++ eeprom_hdr->version = TLV_INFO_VERSION; ++ eeprom_hdr->totallen = cpu_to_be16(0); ++ tlvinfo_update_crc(eeprom); ++ } ++ ++#ifdef DEBUG ++ show_eeprom(devnum, eeprom); ++#endif ++ ++ return ret; ++} ++ ++/** ++ * tlvinfo_update_crc ++ * ++ * This function updates the CRC-32 TLV. If there is no CRC-32 TLV, then ++ * one is added. This function should be called after each update to the ++ * EEPROM structure, to make sure the CRC is always correct. ++ */ ++void tlvinfo_update_crc(u8 *eeprom) ++{ ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ struct tlvinfo_tlv *eeprom_crc; ++ unsigned int calc_crc; ++ int eeprom_index; ++ ++ // Discover the CRC TLV ++ if (!tlvinfo_find_tlv(eeprom, TLV_CODE_CRC_32, &eeprom_index)) { ++ unsigned int totallen = be16_to_cpu(eeprom_hdr->totallen); ++ ++ if ((totallen + ENT_SIZE + 4) > TLV_TOTAL_LEN_MAX) ++ return; ++ eeprom_index = HDR_SIZE + totallen; ++ eeprom_hdr->totallen = cpu_to_be16(totallen + ENT_SIZE + 4); ++ } ++ eeprom_crc = to_entry(&eeprom[eeprom_index]); ++ eeprom_crc->type = TLV_CODE_CRC_32; ++ eeprom_crc->length = 4; ++ ++ // Calculate the checksum ++ calc_crc = crc32(0, (void *)eeprom, ++ HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen) - 4); ++ eeprom_crc->value[0] = (calc_crc >> 24) & 0xFF; ++ eeprom_crc->value[1] = (calc_crc >> 16) & 0xFF; ++ eeprom_crc->value[2] = (calc_crc >> 8) & 0xFF; ++ eeprom_crc->value[3] = (calc_crc >> 0) & 0xFF; ++} ++ ++/** ++ * write_tlvinfo_tlv_eeprom ++ * ++ * Write the TLV data from CPU memory to the hardware. ++ */ ++int write_tlvinfo_tlv_eeprom(void *eeprom, int dev) ++{ ++ int ret = 0; ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ int eeprom_len; ++ ++ tlvinfo_update_crc(eeprom); ++ ++ eeprom_len = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); ++ ret = write_tlv_eeprom(eeprom, eeprom_len, dev); ++ if (ret) { ++ printf("Programming failed.\n"); ++ return -1; ++ } ++ ++ printf("Programming passed.\n"); ++ return 0; ++} ++ ++/** ++ * tlvinfo_find_tlv ++ * ++ * This function finds the TLV with the supplied code in the EERPOM. ++ * An offset from the beginning of the EEPROM is returned in the ++ * eeprom_index parameter if the TLV is found. ++ */ ++bool tlvinfo_find_tlv(u8 *eeprom, u8 tcode, int *eeprom_index) ++{ ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ struct tlvinfo_tlv *eeprom_tlv; ++ int eeprom_end; ++ ++ // Search through the TLVs, looking for the first one which matches the ++ // supplied type code. ++ *eeprom_index = HDR_SIZE; ++ eeprom_end = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); ++ while (*eeprom_index < eeprom_end) { ++ eeprom_tlv = to_entry(&eeprom[*eeprom_index]); ++ if (!is_valid_tlvinfo_entry(eeprom_tlv)) ++ return false; ++ if (eeprom_tlv->type == tcode) ++ return true; ++ *eeprom_index += ENT_SIZE + eeprom_tlv->length; ++ } ++ return(false); ++} ++ ++/** ++ * tlvinfo_delete_tlv ++ * ++ * This function deletes the TLV with the specified type code from the ++ * EEPROM. ++ */ ++bool tlvinfo_delete_tlv(u8 *eeprom, u8 code) ++{ ++ int eeprom_index; ++ int tlength; ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ struct tlvinfo_tlv *eeprom_tlv; ++ ++ // Find the TLV and then move all following TLVs "forward" ++ if (tlvinfo_find_tlv(eeprom, code, &eeprom_index)) { ++ eeprom_tlv = to_entry(&eeprom[eeprom_index]); ++ tlength = ENT_SIZE + eeprom_tlv->length; ++ memcpy(&eeprom[eeprom_index], &eeprom[eeprom_index + tlength], ++ HDR_SIZE + ++ be16_to_cpu(eeprom_hdr->totallen) - eeprom_index - ++ tlength); ++ eeprom_hdr->totallen = ++ cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) - ++ tlength); ++ tlvinfo_update_crc(eeprom); ++ return true; ++ } ++ return false; ++} ++ ++/** ++ * tlvinfo_add_tlv ++ * ++ * This function adds a TLV to the EEPROM, converting the value (a string) to ++ * the format in which it will be stored in the EEPROM. ++ */ ++#define MAX_TLV_VALUE_LEN 256 ++bool tlvinfo_add_tlv(u8 *eeprom, int code, char *strval) ++{ ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ struct tlvinfo_tlv *eeprom_tlv; ++ int new_tlv_len = 0; ++ u32 value; ++ char data[MAX_TLV_VALUE_LEN]; ++ int eeprom_index; ++ ++ // Encode each TLV type into the format to be stored in the EERPOM ++ switch (code) { ++ case TLV_CODE_PRODUCT_NAME: ++ case TLV_CODE_PART_NUMBER: ++ case TLV_CODE_SERIAL_NUMBER: ++ case TLV_CODE_LABEL_REVISION: ++ case TLV_CODE_PLATFORM_NAME: ++ case TLV_CODE_ONIE_VERSION: ++ case TLV_CODE_MANUF_NAME: ++ case TLV_CODE_MANUF_COUNTRY: ++ case TLV_CODE_VENDOR_NAME: ++ case TLV_CODE_DIAG_VERSION: ++ case TLV_CODE_SERVICE_TAG: ++ strncpy(data, strval, MAX_TLV_VALUE_LEN); ++ new_tlv_len = min_t(size_t, MAX_TLV_VALUE_LEN, strlen(strval)); ++ break; ++ case TLV_CODE_DEVICE_VERSION: ++ value = simple_strtoul(strval, NULL, 0); ++ if (value >= 256) { ++ printf("ERROR: Device version must be 255 or less. Value supplied: %u", ++ value); ++ return false; ++ } ++ data[0] = value & 0xFF; ++ new_tlv_len = 1; ++ break; ++ case TLV_CODE_MAC_SIZE: ++ value = simple_strtoul(strval, NULL, 0); ++ if (value >= 65536) { ++ printf("ERROR: MAC Size must be 65535 or less. Value supplied: %u", ++ value); ++ return false; ++ } ++ data[0] = (value >> 8) & 0xFF; ++ data[1] = value & 0xFF; ++ new_tlv_len = 2; ++ break; ++ case TLV_CODE_MANUF_DATE: ++ if (set_date(data, strval) != 0) ++ return false; ++ new_tlv_len = 19; ++ break; ++ case TLV_CODE_MAC_BASE: ++ if (set_mac(data, strval) != 0) ++ return false; ++ new_tlv_len = 6; ++ break; ++ case TLV_CODE_CRC_32: ++ printf("WARNING: The CRC TLV is set automatically and cannot be set manually.\n"); ++ return false; ++ case TLV_CODE_VENDOR_EXT: ++ default: ++ if (set_bytes(data, strval, &new_tlv_len) != 0) ++ return false; ++ break; ++ } ++ ++ // Is there room for this TLV? ++ if ((be16_to_cpu(eeprom_hdr->totallen) + ENT_SIZE + new_tlv_len) > ++ TLV_TOTAL_LEN_MAX) { ++ printf("ERROR: There is not enough room in the EERPOM to save data.\n"); ++ return false; ++ } ++ ++ // Add TLV at the end, overwriting CRC TLV if it exists ++ if (tlvinfo_find_tlv(eeprom, TLV_CODE_CRC_32, &eeprom_index)) ++ eeprom_hdr->totallen = ++ cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) - ++ ENT_SIZE - 4); ++ else ++ eeprom_index = HDR_SIZE + be16_to_cpu(eeprom_hdr->totallen); ++ eeprom_tlv = to_entry(&eeprom[eeprom_index]); ++ eeprom_tlv->type = code; ++ eeprom_tlv->length = new_tlv_len; ++ memcpy(eeprom_tlv->value, data, new_tlv_len); ++ ++ // Update the total length and calculate (add) a new CRC-32 TLV ++ eeprom_hdr->totallen = cpu_to_be16(be16_to_cpu(eeprom_hdr->totallen) + ++ ENT_SIZE + new_tlv_len); ++ tlvinfo_update_crc(eeprom); ++ ++ return true; ++} ++ ++/** ++ * set_mac ++ * ++ * Converts a string MAC address into a binary buffer. ++ * ++ * This function takes a pointer to a MAC address string ++ * (i.e."XX:XX:XX:XX:XX:XX", where "XX" is a two-digit hex number). ++ * The string format is verified and then converted to binary and ++ * stored in a buffer. ++ */ ++static int set_mac(char *buf, const char *string) ++{ ++ char *p = (char *)string; ++ int i; ++ int err = 0; ++ char *end; ++ ++ if (!p) { ++ printf("ERROR: NULL mac addr string passed in.\n"); ++ return -1; ++ } ++ ++ if (strlen(p) != 17) { ++ printf("ERROR: MAC address strlen() != 17 -- %zu\n", strlen(p)); ++ printf("ERROR: Bad MAC address format: %s\n", string); ++ return -1; ++ } ++ ++ for (i = 0; i < 17; i++) { ++ if ((i % 3) == 2) { ++ if (p[i] != ':') { ++ err++; ++ printf("ERROR: mac: p[%i] != :, found: `%c'\n", ++ i, p[i]); ++ break; ++ } ++ continue; ++ } else if (!is_hex(p[i])) { ++ err++; ++ printf("ERROR: mac: p[%i] != hex digit, found: `%c'\n", ++ i, p[i]); ++ break; ++ } ++ } ++ ++ if (err != 0) { ++ printf("ERROR: Bad MAC address format: %s\n", string); ++ return -1; ++ } ++ ++ /* Convert string to binary */ ++ for (i = 0, p = (char *)string; i < 6; i++) { ++ buf[i] = p ? simple_strtoul(p, &end, 16) : 0; ++ if (p) ++ p = (*end) ? end + 1 : end; ++ } ++ ++ if (!is_valid_ethaddr((u8 *)buf)) { ++ printf("ERROR: MAC address must not be 00:00:00:00:00:00, a multicast address or FF:FF:FF:FF:FF:FF.\n"); ++ printf("ERROR: Bad MAC address format: %s\n", string); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++/** ++ * set_date ++ * ++ * Validates the format of the data string ++ * ++ * This function takes a pointer to a date string (i.e. MM/DD/YYYY hh:mm:ss) ++ * and validates that the format is correct. If so the string is copied ++ * to the supplied buffer. ++ */ ++static int set_date(char *buf, const char *string) ++{ ++ int i; ++ ++ if (!string) { ++ printf("ERROR: NULL date string passed in.\n"); ++ return -1; ++ } ++ ++ if (strlen(string) != 19) { ++ printf("ERROR: Date strlen() != 19 -- %zu\n", strlen(string)); ++ printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", ++ string); ++ return -1; ++ } ++ ++ for (i = 0; string[i] != 0; i++) { ++ switch (i) { ++ case 2: ++ case 5: ++ if (string[i] != '/') { ++ printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", ++ string); ++ return -1; ++ } ++ break; ++ case 10: ++ if (string[i] != ' ') { ++ printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", ++ string); ++ return -1; ++ } ++ break; ++ case 13: ++ case 16: ++ if (string[i] != ':') { ++ printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", ++ string); ++ return -1; ++ } ++ break; ++ default: ++ if (!is_digit(string[i])) { ++ printf("ERROR: Bad date format (MM/DD/YYYY hh:mm:ss): %s\n", ++ string); ++ return -1; ++ } ++ break; ++ } ++ } ++ ++ strcpy(buf, string); ++ return 0; ++} ++ ++/** ++ * set_bytes ++ * ++ * Converts a space-separated string of decimal numbers into a ++ * buffer of bytes. ++ * ++ * This function takes a pointer to a space-separated string of decimal ++ * numbers (i.e. "128 0x55 0321") with "C" standard radix specifiers ++ * and converts them to an array of bytes. ++ */ ++static int set_bytes(char *buf, const char *string, int *converted_accum) ++{ ++ char *p = (char *)string; ++ int i; ++ uint byte; ++ ++ if (!p) { ++ printf("ERROR: NULL string passed in.\n"); ++ return -1; ++ } ++ ++ /* Convert string to bytes */ ++ for (i = 0, p = (char *)string; (i < TLV_VALUE_MAX_LEN) && (*p != 0); ++ i++) { ++ while ((*p == ' ') || (*p == '\t') || (*p == ',') || ++ (*p == ';')) { ++ p++; ++ } ++ if (*p != 0) { ++ if (!is_digit(*p)) { ++ printf("ERROR: Non-digit found in byte string: (%s)\n", ++ string); ++ return -1; ++ } ++ byte = simple_strtoul(p, &p, 0); ++ if (byte >= 256) { ++ printf("ERROR: The value specified is greater than 255: (%u) in string: %s\n", ++ byte, string); ++ return -1; ++ } ++ buf[i] = byte & 0xFF; ++ } ++ } ++ ++ if (i == TLV_VALUE_MAX_LEN && (*p != 0)) { ++ printf("ERROR: Trying to assign too many bytes (max: %d) in string: %s\n", ++ TLV_VALUE_MAX_LEN, string); ++ return -1; ++ } ++ ++ *converted_accum = i; ++ return 0; ++} ++ ++static int find_tlv_devices(struct udevice **tlv_devices_p) ++{ ++ int ret; ++ int count_dev = 0; ++ struct udevice *dev; ++ ++ for (ret = uclass_first_device_check(UCLASS_I2C_EEPROM, &dev); ++ dev; ++ ret = uclass_next_device_check(&dev)) { ++ if (ret == 0) ++ tlv_devices_p[count_dev++] = dev; ++ if (count_dev >= TLV_MAX_DEVICES) ++ break; ++ } ++ ++ return (count_dev == 0) ? -ENODEV : 0; ++} ++ ++static struct udevice *find_tlv_device_by_index(int dev_num) ++{ ++ struct udevice *local_tlv_devices[TLV_MAX_DEVICES] = {}; ++ struct udevice **tlv_devices_p; ++ int ret; ++ ++ if (gd->flags & (GD_FLG_RELOC | GD_FLG_SPL_INIT)) { ++ /* Assume BSS is initialized; use static data */ ++ if (tlv_devices[dev_num]) ++ return tlv_devices[dev_num]; ++ tlv_devices_p = tlv_devices; ++ } else { ++ tlv_devices_p = local_tlv_devices; ++ } ++ ++ ret = find_tlv_devices(tlv_devices_p); ++ if (ret == 0 && tlv_devices_p[dev_num]) ++ return tlv_devices_p[dev_num]; ++ ++ return NULL; ++} ++ ++/** ++ * read_tlv_eeprom - read the hwinfo from i2c EEPROM ++ */ ++int read_tlv_eeprom(void *eeprom, int offset, int len, int dev_num) ++{ ++ struct udevice *dev; ++ ++ if (dev_num >= TLV_MAX_DEVICES) ++ return -EINVAL; ++ ++ dev = find_tlv_device_by_index(dev_num); ++ if (!dev) ++ return -ENODEV; ++ ++ return i2c_eeprom_read(dev, offset, eeprom, len); ++} ++ ++/** ++ * write_tlv_eeprom - write the hwinfo to i2c EEPROM ++ */ ++int write_tlv_eeprom(void *eeprom, int len, int dev) ++{ ++ if (!(gd->flags & GD_FLG_RELOC)) ++ return -ENODEV; ++ if (!tlv_devices[dev]) ++ return -ENODEV; ++ ++ return i2c_eeprom_write(tlv_devices[dev], 0, eeprom, len); ++} ++ ++int read_tlvinfo_tlv_eeprom(void *eeprom, struct tlvinfo_header **hdr, ++ struct tlvinfo_tlv **first_entry, int dev_num) ++{ ++ int ret; ++ struct tlvinfo_header *tlv_hdr; ++ struct tlvinfo_tlv *tlv_ent; ++ ++ /* Read TLV header */ ++ ret = read_tlv_eeprom(eeprom, 0, HDR_SIZE, dev_num); ++ if (ret < 0) ++ return ret; ++ ++ tlv_hdr = eeprom; ++ if (!is_valid_tlvinfo_header(tlv_hdr)) ++ return -EINVAL; ++ ++ /* Read TLV entries */ ++ tlv_ent = to_entry(&tlv_hdr[1]); ++ ret = read_tlv_eeprom(tlv_ent, HDR_SIZE, ++ be16_to_cpu(tlv_hdr->totallen), dev_num); ++ if (ret < 0) ++ return ret; ++ if (!tlvinfo_check_crc(eeprom)) ++ return -EINVAL; ++ ++ *hdr = tlv_hdr; ++ *first_entry = tlv_ent; ++ ++ return 0; ++} ++ ++/** ++ * mac_read_from_eeprom ++ * ++ * Read the MAC addresses from EEPROM ++ * ++ * This function reads the MAC addresses from EEPROM and sets the ++ * appropriate environment variables for each one read. ++ * ++ * The environment variables are only set if they haven't been set already. ++ * This ensures that any user-saved variables are never overwritten. ++ * ++ * This function must be called after relocation. ++ */ ++int mac_read_from_eeprom(void) ++{ ++ unsigned int i; ++ int eeprom_index; ++ struct tlvinfo_tlv *eeprom_tlv; ++ int maccount; ++ u8 macbase[6]; ++ u8 eeprom[TLV_INFO_MAX_LEN]; ++ struct tlvinfo_header *eeprom_hdr = to_header(eeprom); ++ int devnum = 0; // TODO: support multiple EEPROMs ++ ++ puts("EEPROM: "); ++ ++ if (read_eeprom(devnum, eeprom)) { ++ printf("Read failed.\n"); ++ return -1; ++ } ++ ++ maccount = 1; ++ if (tlvinfo_find_tlv(eeprom, TLV_CODE_MAC_SIZE, &eeprom_index)) { ++ eeprom_tlv = to_entry(&eeprom[eeprom_index]); ++ maccount = (eeprom_tlv->value[0] << 8) | eeprom_tlv->value[1]; ++ } ++ ++ memcpy(macbase, "\0\0\0\0\0\0", 6); ++ if (tlvinfo_find_tlv(eeprom, TLV_CODE_MAC_BASE, &eeprom_index)) { ++ eeprom_tlv = to_entry(&eeprom[eeprom_index]); ++ memcpy(macbase, eeprom_tlv->value, 6); ++ } ++ ++ for (i = 0; i < maccount; i++) { ++ if (is_valid_ethaddr(macbase)) { ++ char ethaddr[18]; ++ char enetvar[11]; ++ ++ sprintf(ethaddr, "%02X:%02X:%02X:%02X:%02X:%02X", ++ macbase[0], macbase[1], macbase[2], ++ macbase[3], macbase[4], macbase[5]); ++ sprintf(enetvar, i ? "eth%daddr" : "ethaddr", i); ++ /* Only initialize environment variables that are blank ++ * (i.e. have not yet been set) ++ */ ++ if (!env_get(enetvar)) ++ env_set(enetvar, ethaddr); ++ ++ macbase[5]++; ++ if (macbase[5] == 0) { ++ macbase[4]++; ++ if (macbase[4] == 0) { ++ macbase[3]++; ++ if (macbase[3] == 0) { ++ macbase[0] = 0; ++ macbase[1] = 0; ++ macbase[2] = 0; ++ } ++ } ++ } ++ } ++ } ++ ++ printf("%s v%u len=%u\n", eeprom_hdr->signature, eeprom_hdr->version, ++ be16_to_cpu(eeprom_hdr->totallen)); ++ ++ return 0; ++} ++ ++/** ++ * populate_serial_number - read the serial number from EEPROM ++ * ++ * This function reads the serial number from the EEPROM and sets the ++ * appropriate environment variable. ++ * ++ * The environment variable is only set if it has not been set ++ * already. This ensures that any user-saved variables are never ++ * overwritten. ++ * ++ * This function must be called after relocation. ++ */ ++int populate_serial_number(int devnum) ++{ ++ char serialstr[257]; ++ int eeprom_index; ++ u8 eeprom[TLV_INFO_MAX_LEN]; ++ struct tlvinfo_tlv *eeprom_tlv; ++ ++ if (env_get("serial#")) ++ return 0; ++ ++ if (read_eeprom(devnum, eeprom)) { ++ printf("Read failed.\n"); ++ return -1; ++ } ++ ++ if (tlvinfo_find_tlv(eeprom, TLV_CODE_SERIAL_NUMBER, &eeprom_index)) { ++ eeprom_tlv = to_entry(&eeprom[eeprom_index]); ++ memcpy(serialstr, eeprom_tlv->value, eeprom_tlv->length); ++ serialstr[eeprom_tlv->length] = 0; ++ env_set("serial#", serialstr); ++ } ++ ++ return 0; ++} diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0009-lib-tlv_eeprom-add-function-for-reading-one-entry-in.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0009-lib-tlv_eeprom-add-function-for-reading-one-entry-in.patch new file mode 100644 index 0000000..a7b3d39 --- /dev/null +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0009-lib-tlv_eeprom-add-function-for-reading-one-entry-in.patch @@ -0,0 +1,69 @@ +From 40355952340169930bfbd03a6ea4de3041c39754 Mon Sep 17 00:00:00 2001 +From: Josua Mayer +Date: Sun, 20 Mar 2022 12:07:38 +0200 +Subject: [PATCH] lib: tlv_eeprom: add function for reading one entry into a C + string + +Signed-off-by: Josua Mayer +--- + include/tlv_eeprom.h | 12 ++++++++++++ + lib/tlv/tlv_eeprom.c | 23 +++++++++++++++++++++++ + 2 files changed, 35 insertions(+) + +diff --git a/include/tlv_eeprom.h b/include/tlv_eeprom.h +index ee9f035c8c..c91618e480 100644 +--- a/include/tlv_eeprom.h ++++ b/include/tlv_eeprom.h +@@ -167,6 +167,18 @@ bool tlvinfo_add_tlv(u8 *eeprom, int code, char *strval); + */ + bool tlvinfo_delete_tlv(u8 *eeprom, u8 code); + ++/** ++ * Read the TLV entry with specified code to a buffer as terminated C string. ++ * @eeprom: Pointer to buffer holding the TLV EEPROM binary data. ++ * @code: The TLV Code of the entry to read. ++ * @buffer: Pointer to buffer where the value will be stored. Must have capacity ++ * for the string representation of the data including null terminator. ++ * @length: size of the buffer where the value will be stored. ++ * ++ * Return length of string on success, -1 on error. ++ */ ++ssize_t tlvinfo_read_tlv(u8 *eeprom, u8 code, u8 *buffer, size_t length); ++ + /** + * tlvinfo_update_crc + * +diff --git a/lib/tlv/tlv_eeprom.c b/lib/tlv/tlv_eeprom.c +index fe164cabe6..e2c7a0d664 100644 +--- a/lib/tlv/tlv_eeprom.c ++++ b/lib/tlv/tlv_eeprom.c +@@ -349,6 +349,29 @@ bool tlvinfo_add_tlv(u8 *eeprom, int code, char *strval) + return true; + } + ++/** ++ * Read the TLV entry with specified code to a buffer as terminated C string. ++ */ ++ssize_t tlvinfo_read_tlv(u8 *eeprom, u8 code, u8 *buffer, size_t length) { ++ int index; ++ struct tlvinfo_tlv *tlv; ++ ++ // read sku from part-number field ++ if(tlvinfo_find_tlv(eeprom, code, &index)) { ++ tlv = (struct tlvinfo_tlv *) &eeprom[index]; ++ if(tlv->length > length) { ++ pr_err("%s: tlv value (%d) larger than buffer (%zu)!\n", __func__, tlv->length+1, length); ++ return -1; ++ } ++ memcpy(buffer, tlv->value, tlv->length); ++ buffer[tlv->length] = 0; ++ ++ return tlv->length; ++ } ++ ++ return -1; ++} ++ + /** + * set_mac + * diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0010-uboot-marvell-patches.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0010-uboot-marvell-patches.patch new file mode 100644 index 0000000..492a287 --- /dev/null +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/solidrun/0010-uboot-marvell-patches.patch @@ -0,0 +1,103255 @@ +From 69aec8c29f5d6659be7dab52eb24c618af1c13d0 Mon Sep 17 00:00:00 2001 +From: Alon Rotman +Date: Wed, 12 Jan 2022 16:32:37 +0200 +Subject: [PATCH] uboot: marvell patches + +Signed-off-by: Alon Rotman +--- + MAINTAINERS | 16 + + README | 7 + + arch/arm/Kconfig | 24 +- + arch/arm/Makefile | 2 + + arch/arm/cpu/armv8/cache_v8.c | 39 +- + arch/arm/dts/Makefile | 50 +- + arch/arm/dts/armada-3720-db.dts | 71 +- + arch/arm/dts/armada-3720-ddr3-db-v1-A.dts | 43 + + arch/arm/dts/armada-3720-ddr3-db-v1-B.dts | 55 + + arch/arm/dts/armada-3720-ddr3-db-v1-C.dts | 62 + + arch/arm/dts/armada-3720-ddr3-db-v2-B.dts | 55 + + arch/arm/dts/armada-3720-ddr3-db-v2-C.dts | 62 + + arch/arm/dts/armada-3720-ddr4-db-v1-A.dts | 47 + + arch/arm/dts/armada-3720-ddr4-db-v1-B.dts | 56 + + arch/arm/dts/armada-3720-ddr4-db-v3-A.dts | 33 + + arch/arm/dts/armada-3720-ddr4-db-v3-B.dts | 56 + + arch/arm/dts/armada-3720-ddr4-db-v3-C.dts | 63 + + arch/arm/dts/armada-3720-espressobin-emmc.dts | 19 + + arch/arm/dts/armada-3720-espressobin.dts | 110 +- + arch/arm/dts/armada-3720-turris-mox.dts | 12 +- + arch/arm/dts/armada-3720-uDPU.dts | 12 +- + arch/arm/dts/armada-375-db.dts | 2 + + arch/arm/dts/armada-385-ap.dts | 181 + + arch/arm/dts/armada-388-gp.dts | 39 +- + arch/arm/dts/armada-38x.dtsi | 8 + + arch/arm/dts/armada-7020-amc.dts | 212 + + arch/arm/dts/armada-7020-comexp.dts | 199 + + arch/arm/dts/armada-7040-db-B.dts | 221 + + arch/arm/dts/armada-7040-db-C.dts | 222 + + arch/arm/dts/armada-7040-db-D.dts | 201 + + arch/arm/dts/armada-7040-db-E.dts | 233 + + arch/arm/dts/armada-7040-db-F.dts | 235 + + arch/arm/dts/armada-7040-db-nand.dts | 223 - + arch/arm/dts/armada-7040-db.dts | 111 +- + arch/arm/dts/armada-7040-dev-info.dtsi | 73 + + arch/arm/dts/armada-7040-pcac.dts | 222 + + arch/arm/dts/armada-7040.dtsi | 56 - + arch/arm/dts/armada-70x0-db.dtsi | 90 + + arch/arm/dts/armada-70x0.dtsi | 69 + + arch/arm/dts/armada-8020.dtsi | 74 +- + arch/arm/dts/armada-8040-clearfog-gt-8k.dts | 107 +- + arch/arm/dts/armada-8040-db-B.dts | 339 + + arch/arm/dts/armada-8040-db-C.dts | 334 + + arch/arm/dts/armada-8040-db-D.dts | 316 + + arch/arm/dts/armada-8040-db-E.dts | 331 + + arch/arm/dts/armada-8040-db-F.dts | 395 + + arch/arm/dts/armada-8040-db-G.dts | 344 + + arch/arm/dts/armada-8040-db-H.dts | 351 + + arch/arm/dts/armada-8040-db.dts | 161 +- + arch/arm/dts/armada-8040-dev-info.dtsi | 64 + + .../arm/dts/armada-8040-mcbin-single-shot.dts | 28 + + arch/arm/dts/armada-8040-mcbin.dts | 190 +- + arch/arm/dts/armada-8040-ocp.dts | 339 + + arch/arm/dts/armada-8040-ucpe.dts | 382 + + arch/arm/dts/armada-8040.dtsi | 90 +- + arch/arm/dts/armada-80x0-db.dtsi | 143 + + arch/arm/dts/armada-8k.dtsi | 20 + + arch/arm/dts/armada-ap806-quad.dtsi | 82 - + arch/arm/dts/armada-ap806.dtsi | 235 +- + arch/arm/dts/armada-ap807.dtsi | 42 + + arch/arm/dts/armada-ap80x-quad.dtsi | 45 + + arch/arm/dts/armada-ap80x.dtsi | 144 + + arch/arm/dts/armada-common.dtsi | 30 + + arch/arm/dts/armada-cp110-master.dtsi | 370 - + arch/arm/dts/armada-cp110-slave.dtsi | 343 - + arch/arm/dts/armada-cp110.dtsi | 368 + + arch/arm/dts/cn9130-crb-A.dts | 57 + + arch/arm/dts/cn9130-crb-B.dts | 61 + + arch/arm/dts/cn9130-crb-C.dts | 67 + + arch/arm/dts/cn9130-crb-r1p3-A.dts | 15 + + arch/arm/dts/cn9130-crb-r1p3-B.dts | 15 + + arch/arm/dts/cn9130-crb-r1p3-C.dts | 15 + + arch/arm/dts/cn9130-crb-r1p3.dtsi | 44 + + arch/arm/dts/cn9130-crb.dtsi | 229 + + arch/arm/dts/cn9130-db-A.dts | 214 + + arch/arm/dts/cn9130-db-B.dts | 225 + + arch/arm/dts/cn9130-db-C.dts | 237 + + arch/arm/dts/cn9130-db-dev-info.dtsi | 44 + + arch/arm/dts/cn9130-db.dtsi | 153 + + arch/arm/dts/cn9130.dtsi | 87 + + arch/arm/dts/cn9131-db-A.dts | 56 + + arch/arm/dts/cn9131-db-B.dts | 71 + + arch/arm/dts/cn9131-db-C.dts | 55 + + arch/arm/dts/cn9131-db.dtsi | 178 + + arch/arm/dts/cn9132-db-A.dts | 109 + + arch/arm/dts/cn9132-db-B.dts | 109 + + arch/arm/dts/cn9132-db-C.dts | 104 + + arch/arm/dts/cn9132-db.dtsi | 134 + + arch/arm/dts/thunderx-88xx.dts | 30 - + arch/arm/dts/thunderx-88xx.dtsi | 362 - + arch/arm/include/asm/arch-armada3700/efuse.h | 137 + + arch/arm/include/asm/arch-armada3700/mbox.h | 91 + + .../arm/include/asm/arch-armada8k/cache_llc.h | 5 + + arch/arm/include/asm/arch-mvebu/thermal.h | 37 + + arch/arm/include/asm/arch-octeontx/board.h | 124 + + arch/arm/include/asm/arch-octeontx/clock.h | 25 + + .../asm/arch-octeontx/csrs/csrs-mio_emm.h | 1199 ++ + .../include/asm/arch-octeontx/csrs/csrs-xcv.h | 428 + + arch/arm/include/asm/arch-octeontx/gpio.h | 6 + + arch/arm/include/asm/arch-octeontx/lock.h | 139 + + arch/arm/include/asm/arch-octeontx/smc.h | 20 + + arch/arm/include/asm/arch-octeontx/soc.h | 73 + + arch/arm/include/asm/arch-octeontx2/board.h | 190 + + arch/arm/include/asm/arch-octeontx2/clock.h | 24 + + .../asm/arch-octeontx2/csrs/csrs-cgx.h | 7841 ++++++++++++ + .../asm/arch-octeontx2/csrs/csrs-lmt.h | 60 + + .../asm/arch-octeontx2/csrs/csrs-mio_emm.h | 1199 ++ + .../asm/arch-octeontx2/csrs/csrs-nix.h | 10548 ++++++++++++++++ + .../asm/arch-octeontx2/csrs/csrs-npa.h | 2298 ++++ + .../asm/arch-octeontx2/csrs/csrs-npc.h | 1936 +++ + .../asm/arch-octeontx2/csrs/csrs-rvu.h | 2480 ++++ + arch/arm/include/asm/arch-octeontx2/gpio.h | 6 + + arch/arm/include/asm/arch-octeontx2/lock.h | 139 + + arch/arm/include/asm/arch-octeontx2/smc-id.h | 41 + + arch/arm/include/asm/arch-octeontx2/smc.h | 26 + + arch/arm/include/asm/arch-octeontx2/soc.h | 35 + + arch/arm/include/asm/io.h | 8 + + arch/arm/include/asm/system.h | 5 + + arch/arm/lib/interrupts_64.c | 6 + + arch/arm/mach-mvebu/Kconfig | 43 +- + arch/arm/mach-mvebu/Makefile | 4 +- + arch/arm/mach-mvebu/arm64-common.c | 79 +- + arch/arm/mach-mvebu/armada3700/Kconfig | 12 + + arch/arm/mach-mvebu/armada3700/Makefile | 3 + + arch/arm/mach-mvebu/armada3700/clock.c | 244 + + arch/arm/mach-mvebu/armada3700/cpu.c | 20 + + arch/arm/mach-mvebu/armada3700/efuse.c | 448 + + arch/arm/mach-mvebu/armada3700/mbox.c | 170 + + arch/arm/mach-mvebu/armada8k/Makefile | 2 + + arch/arm/mach-mvebu/armada8k/clock.c | 53 + + arch/arm/mach-mvebu/armada8k/cpu.c | 103 +- + arch/arm/mach-mvebu/armada8k/soc.c | 347 + + arch/arm/mach-mvebu/cpu.c | 53 +- + arch/arm/mach-mvebu/efuse.c | 263 - + arch/arm/mach-mvebu/include/mach/clock.h | 23 + + arch/arm/mach-mvebu/include/mach/cpu.h | 3 +- + arch/arm/mach-mvebu/include/mach/efuse.h | 68 - + arch/arm/mach-mvebu/include/mach/fw_info.h | 23 + + arch/arm/mach-mvebu/include/mach/soc.h | 54 + + arch/arm/mach-mvebu/spl.c | 1 + + arch/arm/mach-octeontx/Kconfig | 23 + + arch/arm/mach-octeontx/Makefile | 8 + + arch/arm/mach-octeontx/clock.c | 35 + + arch/arm/mach-octeontx/cpu.c | 78 + + arch/arm/mach-octeontx/lowlevel_init.S | 33 + + arch/arm/mach-octeontx2/Kconfig | 32 + + arch/arm/mach-octeontx2/Makefile | 8 + + arch/arm/mach-octeontx2/clock.c | 35 + + arch/arm/mach-octeontx2/config.mk | 4 + + arch/arm/mach-octeontx2/cpu.c | 75 + + arch/arm/mach-octeontx2/lowlevel_init.S | 33 + + board/Marvell/common/Kconfig | 22 + + board/Marvell/common/Makefile | 9 + + board/Marvell/common/cfg_eeprom.c | 385 + + board/Marvell/common/sar.c | 516 + + board/Marvell/db-88f6820-ap/Makefile | 8 + + board/Marvell/db-88f6820-ap/db-88f6820-ap.c | 140 + + board/Marvell/db-88f6820-ap/kwbimage.cfg | 12 + + board/Marvell/mvebu_armada-37xx/board.c | 82 + + board/Marvell/mvebu_armada-8k/board.c | 209 +- + board/Marvell/octeontx/Kconfig | 14 + + board/Marvell/octeontx/MAINTAINERS | 9 + + board/Marvell/octeontx/Makefile | 9 + + board/Marvell/octeontx/board-fdt.c | 347 + + board/Marvell/octeontx/board.c | 321 + + board/Marvell/octeontx/smc.c | 29 + + board/Marvell/octeontx/soc-utils.c | 60 + + board/Marvell/octeontx2/Kconfig | 18 + + board/Marvell/octeontx2/MAINTAINERS | 9 + + board/Marvell/octeontx2/Makefile | 9 + + board/Marvell/octeontx2/board-fdt.c | 221 + + board/Marvell/octeontx2/board.c | 441 + + board/Marvell/octeontx2/smc.c | 142 + + board/Marvell/octeontx2/soc-utils.c | 53 + + board/Marvell/octeontx2_cn913x/MAINTAINERS | 4 + + board/Marvell/octeontx2_cn913x/Makefile | 8 + + board/Marvell/octeontx2_cn913x/board.c | 121 + + board/cavium/thunderx/Kconfig | 27 - + board/cavium/thunderx/MAINTAINERS | 6 - + board/cavium/thunderx/Makefile | 6 - + board/cavium/thunderx/atf.c | 309 - + board/cavium/thunderx/thunderx.c | 128 - + board/raspberrypi/rpi/rpi.c | 10 + + cmd/Kconfig | 17 + + cmd/Makefile | 4 + + cmd/fdt.c | 3 +- + cmd/marvell/Kconfig | 41 + + cmd/marvell/Makefile | 16 + + cmd/marvell/bootimgup.c | 1251 ++ + cmd/marvell/eth_cmds.c | 225 + + cmd/marvell/mdio_dbg.c | 83 + + cmd/marvell/octeontx2_attest_cmds.c | 282 + + cmd/marvell/octeontx2_failsafe_cmds.c | 22 + + cmd/marvell/octeontx2_qlm_cmds.c | 86 + + cmd/mem.c | 95 + + cmd/mii.c | 19 + + cmd/mmc.c | 4 +- + cmd/mtdparts.c | 2 +- + cmd/mvebu/Kconfig | 147 +- + cmd/mvebu/Makefile | 13 + + cmd/mvebu/avs.c | 102 + + cmd/mvebu/bubt.c | 89 +- + cmd/mvebu/ddr_phy.c | 70 + + cmd/mvebu/efuse.c | 138 + + cmd/mvebu/hw_info.c | 297 + + cmd/mvebu/map.c | 254 + + cmd/mvebu/mv88e6xxx-util.c | 633 + + cmd/mvebu/mv88e6xxx-util.h | 397 + + cmd/mvebu/mv_fw_info.c | 78 + + cmd/mvebu/mv_get_counters.c | 184 + + cmd/mvebu/pxa3xx_nand_oem.c | 587 + + cmd/mvebu/rx_training.c | 56 + + cmd/mvebu/sar.c | 108 + + cmd/mvebu/thermal.c | 47 + + common/board_f.c | 4 + + common/board_r.c | 13 + + common/fdt_support.c | 2 + + common/usb_hub.c | 3 +- + configs/clearfog_defconfig | 1 - + configs/db-88f6720_defconfig | 1 + + configs/db-88f6820-amc_defconfig | 1 + + configs/db-88f6820-ap_defconfig | 66 + + configs/db-88f6820-gp_defconfig | 17 +- + configs/mvebu_comexpress-88f7020_defconfig | 97 + + configs/mvebu_crb_cn9130_defconfig | 102 + + configs/mvebu_crb_ep_cn9130_defconfig | 105 + + configs/mvebu_db-88f3720_defconfig | 20 +- + configs/mvebu_db_armada8k_defconfig | 39 +- + configs/mvebu_db_cn91xx_defconfig | 98 + + configs/mvebu_db_ep_cn91xx_defconfig | 102 + + configs/mvebu_espressobin-88f3720_defconfig | 20 +- + configs/mvebu_mcbin-88f8040_defconfig | 26 +- + configs/mvebu_ocp-88f8040_defconfig | 93 + + configs/mvebu_ucpe-88f8040_defconfig | 86 + + configs/octeontx2_95mm_defconfig | 108 + + configs/octeontx2_95xx_defconfig | 109 + + configs/octeontx2_96xx_defconfig | 140 + + configs/octeontx2_98xx_defconfig | 133 + + configs/octeontx2_loki_defconfig | 112 + + configs/octeontx_81xx_defconfig | 136 + + configs/octeontx_83xx_defconfig | 137 + + configs/thunderx_88xx_defconfig | 29 - + doc/device-tree-bindings/mmc/xenon-mmc.txt | 46 + + doc/device-tree-bindings/net/ethernet.txt | 4 +- + doc/device-tree-bindings/phy/mvebu_comphy.txt | 68 + + .../regulator/regulator.txt | 1 + + doc/device-tree-bindings/rtc/marvell-rtc.txt | 23 + + doc/device-tree-bindings/spi/mvebu-spi.txt | 73 + + .../thermal/mvebu-thermal.txt | 63 + + .../usb/marvell.ehci-usb.txt | 22 + + .../usb/marvell.xhci-usb.txt | 3 + + doc/mvebu/a3700/armada-3700-db-setup.txt | 76 + + doc/mvebu/a7k-a8k/armada3900-db-setup.txt | 126 + + doc/mvebu/a7k-a8k/armada70x0-db-setup.txt | 243 + + doc/mvebu/a7k-a8k/armada80x0-db-setup.txt | 307 + + doc/mvebu/build.txt | 210 + + doc/mvebu/linux_boot.txt | 42 + + doc/mvebu/porting_guide.txt | 128 + + doc/mvebu/trusted_boot.txt | 540 + + doc/mvebu/uart_boot.txt | 116 + + doc/mvebu/uboot_cmd.txt | 366 + + drivers/Kconfig | 2 + + drivers/Makefile | 10 +- + drivers/ata/ahci.c | 130 +- + drivers/fuse/Kconfig | 24 + + drivers/fuse/Makefile | 4 + + drivers/fuse/fuse-mvebu-hd.c | 163 + + drivers/fuse/fuse-mvebu-init.c | 33 + + drivers/fuse/fuse-mvebu-ld.c | 111 + + drivers/fuse/fuse-mvebu.c | 266 + + drivers/gpio/Kconfig | 18 + + drivers/gpio/Makefile | 2 + + drivers/gpio/i2c_gpio.c | 236 + + drivers/gpio/mvebu_gpio.c | 19 +- + drivers/gpio/octeontx_gpio.c | 218 + + drivers/i2c/Kconfig | 7 + + drivers/i2c/Makefile | 1 + + drivers/i2c/i2c-uclass.c | 3 + + drivers/i2c/muxes/Kconfig | 4 +- + drivers/i2c/muxes/pca954x.c | 6 + + drivers/i2c/mv_i2c.c | 29 +- + drivers/i2c/mvtwsi.c | 6 +- + drivers/i2c/octeontx_i2c.c | 968 ++ + drivers/misc/Makefile | 1 + + drivers/misc/mvebu_sar/Makefile | 12 + + drivers/misc/mvebu_sar/ap806_sar.c | 263 + + drivers/misc/mvebu_sar/ap807_sar.c | 244 + + drivers/misc/mvebu_sar/cp110_sar.c | 236 + + drivers/misc/mvebu_sar/sar-uclass.c | 146 + + drivers/mmc/Kconfig | 11 + + drivers/mmc/Makefile | 1 + + drivers/mmc/mmc.c | 12 +- + drivers/mmc/octeontx_hsmmc.c | 3867 ++++++ + drivers/mmc/octeontx_hsmmc.h | 207 + + drivers/mmc/xenon_sdhci.c | 534 +- + drivers/mtd/nand/raw/Kconfig | 16 + + drivers/mtd/nand/raw/Makefile | 2 + + drivers/mtd/nand/raw/octeontx_bch.c | 424 + + drivers/mtd/nand/raw/octeontx_bch.h | 142 + + drivers/mtd/nand/raw/octeontx_bch_regs.h | 169 + + drivers/mtd/nand/raw/octeontx_nand.c | 2256 ++++ + drivers/mtd/nand/raw/pxa3xx_nand.c | 183 +- + drivers/mtd/nand/raw/pxa3xx_nand.h | 107 + + drivers/mtd/spi/spi-nor-core.c | 155 +- + drivers/mtd/spi/spi-nor-ids.c | 21 +- + drivers/net/Kconfig | 32 + + drivers/net/Makefile | 4 + + drivers/net/e1000.c | 25 +- + drivers/net/mvneta.c | 17 +- + drivers/net/mvpp2.c | 589 +- + drivers/net/octeontx/Makefile | 9 + + drivers/net/octeontx/bgx.c | 1574 +++ + drivers/net/octeontx/bgx.h | 259 + + drivers/net/octeontx/nic.h | 518 + + drivers/net/octeontx/nic_main.c | 776 ++ + drivers/net/octeontx/nic_reg.h | 252 + + drivers/net/octeontx/nicvf_main.c | 581 + + drivers/net/octeontx/nicvf_queues.c | 1141 ++ + drivers/net/octeontx/nicvf_queues.h | 355 + + drivers/net/octeontx/q_struct.h | 697 + + drivers/net/octeontx/smi.c | 382 + + drivers/net/octeontx/xcv.c | 129 + + drivers/net/octeontx2/Makefile | 10 + + drivers/net/octeontx2/cgx.c | 298 + + drivers/net/octeontx2/cgx.h | 113 + + drivers/net/octeontx2/cgx_intf.c | 714 ++ + drivers/net/octeontx2/cgx_intf.h | 450 + + drivers/net/octeontx2/lmt.h | 51 + + drivers/net/octeontx2/nix.c | 831 ++ + drivers/net/octeontx2/nix.h | 356 + + drivers/net/octeontx2/nix_af.c | 1104 ++ + drivers/net/octeontx2/npc.h | 91 + + drivers/net/octeontx2/rvu.h | 143 + + drivers/net/octeontx2/rvu_af.c | 219 + + drivers/net/octeontx2/rvu_common.c | 74 + + drivers/net/octeontx2/rvu_pf.c | 138 + + drivers/net/phy/Kconfig | 9 + + drivers/net/phy/Makefile | 2 + + drivers/net/phy/marvell.c | 269 +- + drivers/net/phy/mv88e6xxx.c | 604 + + drivers/net/phy/mv88e6xxx.h | 393 + + drivers/net/phy/mvebu_fw_download.c | 559 + + drivers/net/phy/phy.c | 2 +- + drivers/nvme/nvme.c | 3 +- + drivers/pci/Kconfig | 17 + + drivers/pci/Makefile | 1 + + drivers/pci/pci-aardvark.c | 8 + + drivers/pci/pci-uclass.c | 211 +- + drivers/pci/pci_mvebu.c | 16 + + drivers/pci/pci_octeontx.c | 553 + + drivers/pci/pcie_dw_mvebu.c | 37 +- + drivers/phy/marvell/Makefile | 1 - + drivers/phy/marvell/comphy_a3700.c | 880 +- + drivers/phy/marvell/comphy_a3700.h | 176 +- + drivers/phy/marvell/comphy_core.c | 85 +- + drivers/phy/marvell/comphy_core.h | 78 +- + drivers/phy/marvell/comphy_cp110.c | 1818 +-- + drivers/phy/marvell/comphy_hpipe.h | 660 - + drivers/phy/marvell/comphy_mux.c | 135 - + drivers/phy/marvell/utmi_phy.h | 29 +- + drivers/pinctrl/mvebu/pinctrl-armada-37xx.c | 4 +- + drivers/pinctrl/mvebu/pinctrl-mvebu.c | 7 +- + drivers/power/regulator/regulator-uclass.c | 38 + + drivers/rtc/Kconfig | 16 + + drivers/rtc/Makefile | 1 + + drivers/rtc/ds1337.c | 171 + + drivers/rtc/marvell_rtc.c | 187 + + drivers/rtc/marvell_rtc.h | 54 + + drivers/serial/Kconfig | 25 + + drivers/serial/Makefile | 2 + + drivers/serial/serial_octeontx_bootcmd.c | 300 + + drivers/serial/serial_octeontx_pcie_console.c | 1156 ++ + drivers/serial/serial_octeontx_pcie_console.h | 271 + + drivers/serial/serial_pl01x.c | 3 + + drivers/spi/Kconfig | 6 + + drivers/spi/Makefile | 1 + + drivers/spi/kirkwood_spi.c | 161 +- + drivers/spi/mvebu_a3700_spi.c | 391 +- + drivers/spi/octeontx_spi.c | 766 ++ + drivers/thermal/Kconfig | 31 + + drivers/thermal/Makefile | 3 + + drivers/thermal/mvebu_ext_thermal_28nm.c | 141 + + drivers/thermal/mvebu_thermal_28nm.c | 87 + + drivers/thermal/mvebu_thermal_core.c | 143 + + drivers/usb/eth/usb_ether.c | 1 + + drivers/usb/host/ehci-marvell.c | 45 +- + drivers/usb/host/xhci-mem.c | 10 + + drivers/usb/host/xhci-mvebu.c | 43 +- + drivers/usb/host/xhci-ring.c | 23 + + drivers/usb/host/xhci.c | 3 +- + drivers/usb/host/xhci.h | 10 + + drivers/watchdog/Kconfig | 10 + + drivers/watchdog/Makefile | 1 + + drivers/watchdog/octeontx_wdt.c | 76 + + env/common.c | 12 + + env/sf.c | 23 +- + fs/ext4/ext4_common.c | 41 +- + fs/ext4/ext4_write.c | 2 +- + include/ahci.h | 7 +- + include/cavium/atf.h | 2 +- + include/cavium/thunderx_svc.h | 3 + + include/configs/db-88f6820-ap.h | 131 + + include/configs/db-88f6820-gp.h | 12 +- + include/configs/mv-common.h | 57 + + include/configs/mvebu_armada-37xx.h | 94 +- + include/configs/mvebu_armada-8k.h | 90 +- + include/configs/mvebu_armada-common.h | 175 + + include/configs/octeontx2_95mm.h | 85 + + include/configs/octeontx2_95xx.h | 85 + + include/configs/octeontx2_96xx.h | 96 + + include/configs/octeontx2_98xx.h | 95 + + include/configs/octeontx2_cn913x.h | 43 + + include/configs/octeontx2_loki.h | 86 + + include/configs/octeontx_common.h | 101 + + include/configs/thunderx_88xx.h | 237 +- + include/dm/uclass-id.h | 1 + + include/dt-bindings/comphy/comphy_data.h | 80 +- + include/env.h | 10 + + include/ext4fs.h | 3 + + include/fdtdec.h | 15 + + include/linux/ethtool.h | 3 +- + include/linux/mtd/spi-nor.h | 1 + + include/miiphy.h | 4 + + include/mmc.h | 1 + + include/mvebu/cfg_eeprom.h | 95 + + include/mvebu/comphy.h | 2 +- + include/mvebu/fuse-mvebu.h | 54 + + include/mvebu/mvebu_chip_sar.h | 75 + + include/mvebu/sar.h | 60 + + include/mvebu/var.h | 31 + + include/net.h | 4 + + include/pci.h | 26 +- + include/pci_ep.h | 2 + + include/pci_ids.h | 2 + + include/phy.h | 11 +- + include/phy_interface.h | 6 + + include/power/regulator.h | 23 + + include/sar-uclass.h | 27 + + lib/fdtdec.c | 24 +- + localversion | 1 + + net/bootp.c | 9 + + scripts/checkpatch.pl | 397 +- + scripts/ci/baseline.txt | 7 + + scripts/ci/compile.sh | 244 + + scripts/ci/pack.sh | 25 + + scripts/ci/pack_source.sh | 42 + + scripts/ci/supported_builds.txt | 78 + + scripts/config | 225 + + scripts/const_structs.checkpatch | 66 +- + scripts/spelling.txt | 159 + + tools/mrvl_uart.sh | 42 +- + 451 files changed, 86332 insertions(+), 7560 deletions(-) + create mode 100644 arch/arm/dts/armada-3720-ddr3-db-v1-A.dts + create mode 100644 arch/arm/dts/armada-3720-ddr3-db-v1-B.dts + create mode 100644 arch/arm/dts/armada-3720-ddr3-db-v1-C.dts + create mode 100644 arch/arm/dts/armada-3720-ddr3-db-v2-B.dts + create mode 100644 arch/arm/dts/armada-3720-ddr3-db-v2-C.dts + create mode 100644 arch/arm/dts/armada-3720-ddr4-db-v1-A.dts + create mode 100644 arch/arm/dts/armada-3720-ddr4-db-v1-B.dts + create mode 100644 arch/arm/dts/armada-3720-ddr4-db-v3-A.dts + create mode 100644 arch/arm/dts/armada-3720-ddr4-db-v3-B.dts + create mode 100644 arch/arm/dts/armada-3720-ddr4-db-v3-C.dts + create mode 100644 arch/arm/dts/armada-3720-espressobin-emmc.dts + create mode 100644 arch/arm/dts/armada-385-ap.dts + create mode 100644 arch/arm/dts/armada-7020-amc.dts + create mode 100644 arch/arm/dts/armada-7020-comexp.dts + create mode 100644 arch/arm/dts/armada-7040-db-B.dts + create mode 100644 arch/arm/dts/armada-7040-db-C.dts + create mode 100644 arch/arm/dts/armada-7040-db-D.dts + create mode 100644 arch/arm/dts/armada-7040-db-E.dts + create mode 100644 arch/arm/dts/armada-7040-db-F.dts + delete mode 100644 arch/arm/dts/armada-7040-db-nand.dts + create mode 100644 arch/arm/dts/armada-7040-dev-info.dtsi + create mode 100644 arch/arm/dts/armada-7040-pcac.dts + delete mode 100644 arch/arm/dts/armada-7040.dtsi + create mode 100644 arch/arm/dts/armada-70x0-db.dtsi + create mode 100644 arch/arm/dts/armada-70x0.dtsi + create mode 100644 arch/arm/dts/armada-8040-db-B.dts + create mode 100644 arch/arm/dts/armada-8040-db-C.dts + create mode 100644 arch/arm/dts/armada-8040-db-D.dts + create mode 100644 arch/arm/dts/armada-8040-db-E.dts + create mode 100644 arch/arm/dts/armada-8040-db-F.dts + create mode 100644 arch/arm/dts/armada-8040-db-G.dts + create mode 100644 arch/arm/dts/armada-8040-db-H.dts + create mode 100644 arch/arm/dts/armada-8040-dev-info.dtsi + create mode 100644 arch/arm/dts/armada-8040-mcbin-single-shot.dts + create mode 100644 arch/arm/dts/armada-8040-ocp.dts + create mode 100644 arch/arm/dts/armada-8040-ucpe.dts + create mode 100644 arch/arm/dts/armada-80x0-db.dtsi + create mode 100644 arch/arm/dts/armada-8k.dtsi + delete mode 100644 arch/arm/dts/armada-ap806-quad.dtsi + create mode 100644 arch/arm/dts/armada-ap807.dtsi + create mode 100644 arch/arm/dts/armada-ap80x-quad.dtsi + create mode 100644 arch/arm/dts/armada-ap80x.dtsi + create mode 100644 arch/arm/dts/armada-common.dtsi + delete mode 100644 arch/arm/dts/armada-cp110-master.dtsi + delete mode 100644 arch/arm/dts/armada-cp110-slave.dtsi + create mode 100644 arch/arm/dts/armada-cp110.dtsi + create mode 100644 arch/arm/dts/cn9130-crb-A.dts + create mode 100644 arch/arm/dts/cn9130-crb-B.dts + create mode 100644 arch/arm/dts/cn9130-crb-C.dts + create mode 100644 arch/arm/dts/cn9130-crb-r1p3-A.dts + create mode 100644 arch/arm/dts/cn9130-crb-r1p3-B.dts + create mode 100644 arch/arm/dts/cn9130-crb-r1p3-C.dts + create mode 100644 arch/arm/dts/cn9130-crb-r1p3.dtsi + create mode 100644 arch/arm/dts/cn9130-crb.dtsi + create mode 100644 arch/arm/dts/cn9130-db-A.dts + create mode 100644 arch/arm/dts/cn9130-db-B.dts + create mode 100644 arch/arm/dts/cn9130-db-C.dts + create mode 100644 arch/arm/dts/cn9130-db-dev-info.dtsi + create mode 100644 arch/arm/dts/cn9130-db.dtsi + create mode 100644 arch/arm/dts/cn9130.dtsi + create mode 100644 arch/arm/dts/cn9131-db-A.dts + create mode 100644 arch/arm/dts/cn9131-db-B.dts + create mode 100644 arch/arm/dts/cn9131-db-C.dts + create mode 100644 arch/arm/dts/cn9131-db.dtsi + create mode 100644 arch/arm/dts/cn9132-db-A.dts + create mode 100644 arch/arm/dts/cn9132-db-B.dts + create mode 100644 arch/arm/dts/cn9132-db-C.dts + create mode 100644 arch/arm/dts/cn9132-db.dtsi + delete mode 100644 arch/arm/dts/thunderx-88xx.dts + delete mode 100644 arch/arm/dts/thunderx-88xx.dtsi + create mode 100644 arch/arm/include/asm/arch-armada3700/efuse.h + create mode 100644 arch/arm/include/asm/arch-armada3700/mbox.h + create mode 100644 arch/arm/include/asm/arch-mvebu/thermal.h + create mode 100644 arch/arm/include/asm/arch-octeontx/board.h + create mode 100644 arch/arm/include/asm/arch-octeontx/clock.h + create mode 100644 arch/arm/include/asm/arch-octeontx/csrs/csrs-mio_emm.h + create mode 100644 arch/arm/include/asm/arch-octeontx/csrs/csrs-xcv.h + create mode 100644 arch/arm/include/asm/arch-octeontx/gpio.h + create mode 100644 arch/arm/include/asm/arch-octeontx/lock.h + create mode 100644 arch/arm/include/asm/arch-octeontx/smc.h + create mode 100644 arch/arm/include/asm/arch-octeontx/soc.h + create mode 100644 arch/arm/include/asm/arch-octeontx2/board.h + create mode 100644 arch/arm/include/asm/arch-octeontx2/clock.h + create mode 100644 arch/arm/include/asm/arch-octeontx2/csrs/csrs-cgx.h + create mode 100644 arch/arm/include/asm/arch-octeontx2/csrs/csrs-lmt.h + create mode 100644 arch/arm/include/asm/arch-octeontx2/csrs/csrs-mio_emm.h + create mode 100644 arch/arm/include/asm/arch-octeontx2/csrs/csrs-nix.h + create mode 100644 arch/arm/include/asm/arch-octeontx2/csrs/csrs-npa.h + create mode 100644 arch/arm/include/asm/arch-octeontx2/csrs/csrs-npc.h + create mode 100644 arch/arm/include/asm/arch-octeontx2/csrs/csrs-rvu.h + create mode 100644 arch/arm/include/asm/arch-octeontx2/gpio.h + create mode 100644 arch/arm/include/asm/arch-octeontx2/lock.h + create mode 100644 arch/arm/include/asm/arch-octeontx2/smc-id.h + create mode 100644 arch/arm/include/asm/arch-octeontx2/smc.h + create mode 100644 arch/arm/include/asm/arch-octeontx2/soc.h + create mode 100644 arch/arm/mach-mvebu/armada3700/Kconfig + create mode 100644 arch/arm/mach-mvebu/armada3700/clock.c + create mode 100644 arch/arm/mach-mvebu/armada3700/efuse.c + create mode 100644 arch/arm/mach-mvebu/armada3700/mbox.c + create mode 100644 arch/arm/mach-mvebu/armada8k/clock.c + create mode 100644 arch/arm/mach-mvebu/armada8k/soc.c + delete mode 100644 arch/arm/mach-mvebu/efuse.c + create mode 100644 arch/arm/mach-mvebu/include/mach/clock.h + delete mode 100644 arch/arm/mach-mvebu/include/mach/efuse.h + create mode 100644 arch/arm/mach-mvebu/include/mach/fw_info.h + create mode 100644 arch/arm/mach-octeontx/Kconfig + create mode 100644 arch/arm/mach-octeontx/Makefile + create mode 100644 arch/arm/mach-octeontx/clock.c + create mode 100644 arch/arm/mach-octeontx/cpu.c + create mode 100644 arch/arm/mach-octeontx/lowlevel_init.S + create mode 100644 arch/arm/mach-octeontx2/Kconfig + create mode 100644 arch/arm/mach-octeontx2/Makefile + create mode 100644 arch/arm/mach-octeontx2/clock.c + create mode 100644 arch/arm/mach-octeontx2/config.mk + create mode 100644 arch/arm/mach-octeontx2/cpu.c + create mode 100644 arch/arm/mach-octeontx2/lowlevel_init.S + create mode 100644 board/Marvell/common/Kconfig + create mode 100644 board/Marvell/common/Makefile + create mode 100644 board/Marvell/common/cfg_eeprom.c + create mode 100644 board/Marvell/common/sar.c + create mode 100644 board/Marvell/db-88f6820-ap/Makefile + create mode 100644 board/Marvell/db-88f6820-ap/db-88f6820-ap.c + create mode 100644 board/Marvell/db-88f6820-ap/kwbimage.cfg + create mode 100644 board/Marvell/octeontx/Kconfig + create mode 100644 board/Marvell/octeontx/MAINTAINERS + create mode 100644 board/Marvell/octeontx/Makefile + create mode 100644 board/Marvell/octeontx/board-fdt.c + create mode 100644 board/Marvell/octeontx/board.c + create mode 100644 board/Marvell/octeontx/smc.c + create mode 100644 board/Marvell/octeontx/soc-utils.c + create mode 100644 board/Marvell/octeontx2/Kconfig + create mode 100644 board/Marvell/octeontx2/MAINTAINERS + create mode 100644 board/Marvell/octeontx2/Makefile + create mode 100644 board/Marvell/octeontx2/board-fdt.c + create mode 100644 board/Marvell/octeontx2/board.c + create mode 100644 board/Marvell/octeontx2/smc.c + create mode 100644 board/Marvell/octeontx2/soc-utils.c + create mode 100644 board/Marvell/octeontx2_cn913x/MAINTAINERS + create mode 100644 board/Marvell/octeontx2_cn913x/Makefile + create mode 100644 board/Marvell/octeontx2_cn913x/board.c + delete mode 100644 board/cavium/thunderx/Kconfig + delete mode 100644 board/cavium/thunderx/MAINTAINERS + delete mode 100644 board/cavium/thunderx/Makefile + delete mode 100644 board/cavium/thunderx/atf.c + delete mode 100644 board/cavium/thunderx/thunderx.c + create mode 100644 cmd/marvell/Kconfig + create mode 100644 cmd/marvell/Makefile + create mode 100644 cmd/marvell/bootimgup.c + create mode 100644 cmd/marvell/eth_cmds.c + create mode 100644 cmd/marvell/mdio_dbg.c + create mode 100644 cmd/marvell/octeontx2_attest_cmds.c + create mode 100644 cmd/marvell/octeontx2_failsafe_cmds.c + create mode 100644 cmd/marvell/octeontx2_qlm_cmds.c + create mode 100644 cmd/mvebu/avs.c + create mode 100644 cmd/mvebu/ddr_phy.c + create mode 100644 cmd/mvebu/efuse.c + create mode 100644 cmd/mvebu/hw_info.c + create mode 100644 cmd/mvebu/map.c + create mode 100644 cmd/mvebu/mv88e6xxx-util.c + create mode 100644 cmd/mvebu/mv88e6xxx-util.h + create mode 100644 cmd/mvebu/mv_fw_info.c + create mode 100644 cmd/mvebu/mv_get_counters.c + create mode 100644 cmd/mvebu/pxa3xx_nand_oem.c + create mode 100644 cmd/mvebu/rx_training.c + create mode 100644 cmd/mvebu/sar.c + create mode 100644 cmd/mvebu/thermal.c + create mode 100644 configs/db-88f6820-ap_defconfig + create mode 100644 configs/mvebu_comexpress-88f7020_defconfig + create mode 100644 configs/mvebu_crb_cn9130_defconfig + create mode 100644 configs/mvebu_crb_ep_cn9130_defconfig + create mode 100644 configs/mvebu_db_cn91xx_defconfig + create mode 100644 configs/mvebu_db_ep_cn91xx_defconfig + create mode 100644 configs/mvebu_ocp-88f8040_defconfig + create mode 100644 configs/mvebu_ucpe-88f8040_defconfig + create mode 100644 configs/octeontx2_95mm_defconfig + create mode 100644 configs/octeontx2_95xx_defconfig + create mode 100644 configs/octeontx2_96xx_defconfig + create mode 100644 configs/octeontx2_98xx_defconfig + create mode 100644 configs/octeontx2_loki_defconfig + create mode 100644 configs/octeontx_81xx_defconfig + create mode 100644 configs/octeontx_83xx_defconfig + delete mode 100644 configs/thunderx_88xx_defconfig + create mode 100644 doc/device-tree-bindings/mmc/xenon-mmc.txt + create mode 100644 doc/device-tree-bindings/phy/mvebu_comphy.txt + create mode 100644 doc/device-tree-bindings/rtc/marvell-rtc.txt + create mode 100644 doc/device-tree-bindings/spi/mvebu-spi.txt + create mode 100644 doc/device-tree-bindings/thermal/mvebu-thermal.txt + create mode 100644 doc/device-tree-bindings/usb/marvell.ehci-usb.txt + create mode 100644 doc/mvebu/a3700/armada-3700-db-setup.txt + create mode 100644 doc/mvebu/a7k-a8k/armada3900-db-setup.txt + create mode 100644 doc/mvebu/a7k-a8k/armada70x0-db-setup.txt + create mode 100644 doc/mvebu/a7k-a8k/armada80x0-db-setup.txt + create mode 100644 doc/mvebu/build.txt + create mode 100644 doc/mvebu/linux_boot.txt + create mode 100644 doc/mvebu/porting_guide.txt + create mode 100644 doc/mvebu/trusted_boot.txt + create mode 100644 doc/mvebu/uart_boot.txt + create mode 100644 doc/mvebu/uboot_cmd.txt + create mode 100644 drivers/fuse/Kconfig + create mode 100644 drivers/fuse/Makefile + create mode 100644 drivers/fuse/fuse-mvebu-hd.c + create mode 100644 drivers/fuse/fuse-mvebu-init.c + create mode 100644 drivers/fuse/fuse-mvebu-ld.c + create mode 100644 drivers/fuse/fuse-mvebu.c + create mode 100644 drivers/gpio/i2c_gpio.c + create mode 100644 drivers/gpio/octeontx_gpio.c + create mode 100644 drivers/i2c/octeontx_i2c.c + create mode 100644 drivers/misc/mvebu_sar/Makefile + create mode 100644 drivers/misc/mvebu_sar/ap806_sar.c + create mode 100644 drivers/misc/mvebu_sar/ap807_sar.c + create mode 100644 drivers/misc/mvebu_sar/cp110_sar.c + create mode 100644 drivers/misc/mvebu_sar/sar-uclass.c + create mode 100644 drivers/mmc/octeontx_hsmmc.c + create mode 100644 drivers/mmc/octeontx_hsmmc.h + create mode 100644 drivers/mtd/nand/raw/octeontx_bch.c + create mode 100644 drivers/mtd/nand/raw/octeontx_bch.h + create mode 100644 drivers/mtd/nand/raw/octeontx_bch_regs.h + create mode 100644 drivers/mtd/nand/raw/octeontx_nand.c + mode change 100644 => 100755 drivers/mtd/spi/spi-nor-core.c + create mode 100644 drivers/net/octeontx/Makefile + create mode 100644 drivers/net/octeontx/bgx.c + create mode 100644 drivers/net/octeontx/bgx.h + create mode 100644 drivers/net/octeontx/nic.h + create mode 100644 drivers/net/octeontx/nic_main.c + create mode 100644 drivers/net/octeontx/nic_reg.h + create mode 100644 drivers/net/octeontx/nicvf_main.c + create mode 100644 drivers/net/octeontx/nicvf_queues.c + create mode 100644 drivers/net/octeontx/nicvf_queues.h + create mode 100644 drivers/net/octeontx/q_struct.h + create mode 100644 drivers/net/octeontx/smi.c + create mode 100644 drivers/net/octeontx/xcv.c + create mode 100644 drivers/net/octeontx2/Makefile + create mode 100644 drivers/net/octeontx2/cgx.c + create mode 100644 drivers/net/octeontx2/cgx.h + create mode 100644 drivers/net/octeontx2/cgx_intf.c + create mode 100644 drivers/net/octeontx2/cgx_intf.h + create mode 100644 drivers/net/octeontx2/lmt.h + create mode 100644 drivers/net/octeontx2/nix.c + create mode 100644 drivers/net/octeontx2/nix.h + create mode 100644 drivers/net/octeontx2/nix_af.c + create mode 100644 drivers/net/octeontx2/npc.h + create mode 100644 drivers/net/octeontx2/rvu.h + create mode 100644 drivers/net/octeontx2/rvu_af.c + create mode 100644 drivers/net/octeontx2/rvu_common.c + create mode 100644 drivers/net/octeontx2/rvu_pf.c + create mode 100644 drivers/net/phy/mv88e6xxx.c + create mode 100644 drivers/net/phy/mv88e6xxx.h + create mode 100644 drivers/net/phy/mvebu_fw_download.c + create mode 100644 drivers/pci/pci_octeontx.c + delete mode 100644 drivers/phy/marvell/comphy_hpipe.h + delete mode 100644 drivers/phy/marvell/comphy_mux.c + create mode 100644 drivers/rtc/marvell_rtc.c + create mode 100644 drivers/rtc/marvell_rtc.h + create mode 100644 drivers/serial/serial_octeontx_bootcmd.c + create mode 100644 drivers/serial/serial_octeontx_pcie_console.c + create mode 100644 drivers/serial/serial_octeontx_pcie_console.h + create mode 100644 drivers/spi/octeontx_spi.c + create mode 100644 drivers/thermal/mvebu_ext_thermal_28nm.c + create mode 100644 drivers/thermal/mvebu_thermal_28nm.c + create mode 100644 drivers/thermal/mvebu_thermal_core.c + create mode 100644 drivers/watchdog/octeontx_wdt.c + create mode 100644 include/configs/db-88f6820-ap.h + create mode 100644 include/configs/mvebu_armada-common.h + create mode 100644 include/configs/octeontx2_95mm.h + create mode 100644 include/configs/octeontx2_95xx.h + create mode 100644 include/configs/octeontx2_96xx.h + create mode 100644 include/configs/octeontx2_98xx.h + create mode 100644 include/configs/octeontx2_cn913x.h + create mode 100644 include/configs/octeontx2_loki.h + create mode 100644 include/configs/octeontx_common.h + create mode 100644 include/mvebu/cfg_eeprom.h + create mode 100644 include/mvebu/fuse-mvebu.h + create mode 100644 include/mvebu/mvebu_chip_sar.h + create mode 100644 include/mvebu/sar.h + create mode 100644 include/mvebu/var.h + create mode 100644 include/sar-uclass.h + create mode 100644 localversion + create mode 100644 scripts/ci/baseline.txt + create mode 100755 scripts/ci/compile.sh + create mode 100755 scripts/ci/pack.sh + create mode 100755 scripts/ci/pack_source.sh + create mode 100644 scripts/ci/supported_builds.txt + create mode 100755 scripts/config + +diff --git a/MAINTAINERS b/MAINTAINERS +index c53656695a..e70ac727ad 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -170,6 +170,22 @@ F: board/CZ.NIC/ + F: configs/turris_*_defconfig + F: include/configs/turris_*.h + ++ARM OCTEONTX ++M: Aaron Williams ++M: Suneel Garapati ++S: Maintained ++F: arch/arm/mach-octeontx/ ++F: arch/arm/include/asm/arch-octeontx/ ++F: board/Marvell/octeontx/ ++ ++ARM OCTEONTX2 ++M: Aaron Williams ++M: Suneel Garapati ++S: Maintained ++F: arch/arm/mach-octeontx2/ ++F: arch/arm/include/asm/arch-octeontx2/ ++F: board/Marvell/octeontx2/ ++ + ARM FREESCALE IMX + M: Stefano Babic + M: Fabio Estevam +diff --git a/README b/README +index 1389e8ff12..567a045d34 100644 +--- a/README ++++ b/README +@@ -1446,6 +1446,7 @@ The following options need to be configured: + CONFIG_BOOTP_BOOTFILESIZE + CONFIG_BOOTP_SEND_HOSTNAME + CONFIG_BOOTP_NTPSERVER ++ CONFIG_BOOTP_TFTP_SERVERIP + CONFIG_BOOTP_TIMEOFFSET + CONFIG_BOOTP_VENDOREX + CONFIG_BOOTP_MAY_FAIL +@@ -1466,6 +1467,12 @@ The following options need to be configured: + of the "hostname" environment variable is passed as + option 12 to the DHCP server. + ++ CONFIG_BOOTP_TFTP_SERVERIP - Some DHCP servers can send ++ the IP address of the TFTP server. By setting this, ++ the DHCP client will automatically set the serverip ++ based on the response from the DHCP server via option ++ 150. ++ + CONFIG_BOOTP_DHCP_REQUEST_DELAY + + A 32bit value in microseconds for a delay between +diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig +index 3b0e315061..49b2061de2 100644 +--- a/arch/arm/Kconfig ++++ b/arch/arm/Kconfig +@@ -1599,6 +1599,22 @@ config ARCH_ROCKCHIP + imply TPL_SYSRESET + imply USB_FUNCTION_FASTBOOT + ++config ARCH_OCTEONTX ++ bool "Support OcteonTX SoCs" ++ select DM ++ select ARM64 ++ select OF_CONTROL ++ select BOARD_LATE_INIT ++ select SYS_CACHE_SHIFT_7 ++ ++config ARCH_OCTEONTX2 ++ bool "Support OcteonTX2 SoCs" ++ select DM ++ select ARM64 ++ select OF_CONTROL ++ select BOARD_LATE_INIT ++ select SYS_CACHE_SHIFT_7 ++ + config TARGET_THUNDERX_88XX + bool "Support ThunderX 88xx" + select ARM64 +@@ -1676,6 +1692,10 @@ source "arch/arm/cpu/arm926ejs/lpc32xx/Kconfig" + + source "arch/arm/mach-mvebu/Kconfig" + ++source "arch/arm/mach-octeontx/Kconfig" ++ ++source "arch/arm/mach-octeontx2/Kconfig" ++ + source "arch/arm/cpu/armv7/ls102xa/Kconfig" + + source "arch/arm/mach-imx/mx2/Kconfig" +@@ -1753,6 +1773,8 @@ source "board/bosch/guardian/Kconfig" + source "board/CarMediaLab/flea3/Kconfig" + source "board/Marvell/aspenite/Kconfig" + source "board/Marvell/gplugd/Kconfig" ++source "board/Marvell/octeontx/Kconfig" ++source "board/Marvell/octeontx2/Kconfig" + source "board/armadeus/apf27/Kconfig" + source "board/armltd/vexpress/Kconfig" + source "board/armltd/vexpress64/Kconfig" +@@ -1763,7 +1785,6 @@ source "board/broadcom/bcm968580xref/Kconfig" + source "board/broadcom/bcmcygnus/Kconfig" + source "board/broadcom/bcmnsp/Kconfig" + source "board/broadcom/bcmns2/Kconfig" +-source "board/cavium/thunderx/Kconfig" + source "board/cirrus/edb93xx/Kconfig" + source "board/eets/pdu001/Kconfig" + source "board/emulation/qemu-arm/Kconfig" +@@ -1794,6 +1815,7 @@ source "board/hisilicon/hikey/Kconfig" + source "board/hisilicon/hikey960/Kconfig" + source "board/hisilicon/poplar/Kconfig" + source "board/isee/igep003x/Kconfig" ++source "board/Marvell/common/Kconfig" + source "board/phytec/pcm051/Kconfig" + source "board/silica/pengwyn/Kconfig" + source "board/spear/spear300/Kconfig" +diff --git a/arch/arm/Makefile b/arch/arm/Makefile +index 5384981c17..80c7c61061 100644 +--- a/arch/arm/Makefile ++++ b/arch/arm/Makefile +@@ -79,6 +79,8 @@ machine-$(CONFIG_ARCH_ROCKCHIP) += rockchip + machine-$(CONFIG_STM32) += stm32 + machine-$(CONFIG_ARCH_STM32MP) += stm32mp + machine-$(CONFIG_TEGRA) += tegra ++machine-$(CONFIG_ARCH_OCTEONTX) += octeontx ++machine-$(CONFIG_ARCH_OCTEONTX2) += octeontx2 + machine-$(CONFIG_ARCH_UNIPHIER) += uniphier + machine-$(CONFIG_ARCH_ZYNQ) += zynq + machine-$(CONFIG_ARCH_ZYNQMP) += zynqmp +diff --git a/arch/arm/cpu/armv8/cache_v8.c b/arch/arm/cpu/armv8/cache_v8.c +index e500e722e5..d4fc59eded 100644 +--- a/arch/arm/cpu/armv8/cache_v8.c ++++ b/arch/arm/cpu/armv8/cache_v8.c +@@ -10,7 +10,7 @@ + #include + #include + #include +- ++#undef DEBUG_CACHE + DECLARE_GLOBAL_DATA_PTR; + + #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) +@@ -107,9 +107,9 @@ static u64 *find_pte(u64 addr, int level) + u64 idx; + u64 va_bits; + int i; +- ++#ifdef DEBUG_CACHE + debug("addr=%llx level=%d\n", addr, level); +- ++#endif + get_tcr(0, NULL, &va_bits); + if (va_bits < 39) + start_level = 1; +@@ -122,8 +122,9 @@ static u64 *find_pte(u64 addr, int level) + for (i = start_level; i < 4; i++) { + idx = (addr >> level2shift(i)) & 0x1FF; + pte += idx; ++#ifdef DEBUG_CACHE + debug("idx=%llx PTE %p at level %d: %llx\n", idx, pte, i, *pte); +- ++#endif + /* Found it */ + if (i == level) + return pte; +@@ -162,7 +163,9 @@ static u64 *create_table(void) + static void set_pte_table(u64 *pte, u64 *table) + { + /* Point *pte to the new table */ ++#ifdef DEBUG_CACHE + debug("Setting %p to addr=%p\n", pte, table); ++#endif + *pte = PTE_TYPE_TABLE | (ulong)table; + } + +@@ -181,8 +184,9 @@ static void split_block(u64 *pte, int level) + "mem_map.", pte, old_pte); + + new_table = create_table(); ++#ifdef DEBUG_CACHE + debug("Splitting pte %p (%llx) into %p\n", pte, old_pte, new_table); +- ++#endif + for (i = 0; i < MAX_PTE_ENTRIES; i++) { + new_table[i] = old_pte | (i << levelshift); + +@@ -190,7 +194,9 @@ static void split_block(u64 *pte, int level) + if ((level + 1) == 3) + new_table[i] |= PTE_TYPE_TABLE; + ++#ifdef DEBUG_CACHE + debug("Setting new_table[%lld] = %llx\n", i, new_table[i]); ++#endif + } + + /* Set the new table into effect */ +@@ -212,7 +218,9 @@ static void add_map(struct mm_region *map) + while (size) { + pte = find_pte(virt, 0); + if (pte && (pte_type(pte) == PTE_TYPE_FAULT)) { ++#ifdef DEBUG_CACHE + debug("Creating table for virt 0x%llx\n", virt); ++#endif + new_table = create_table(); + set_pte_table(pte, new_table); + } +@@ -223,12 +231,16 @@ static void add_map(struct mm_region *map) + panic("pte not found\n"); + + blocksize = 1ULL << level2shift(level); ++#ifdef DEBUG_CACHE + debug("Checking if pte fits for virt=%llx size=%llx blocksize=%llx\n", + virt, size, blocksize); ++#endif + if (size >= blocksize && !(virt & (blocksize - 1))) { + /* Page fits, create block PTE */ ++#ifdef DEBUG_CACHE + debug("Setting PTE %p to block virt=%llx\n", + pte, virt); ++#endif + if (level == 3) + *pte = phys | attrs | PTE_TYPE_PAGE; + else +@@ -239,13 +251,17 @@ static void add_map(struct mm_region *map) + break; + } else if (pte_type(pte) == PTE_TYPE_FAULT) { + /* Page doesn't fit, create subpages */ ++#ifdef DEBUG_CACHE + debug("Creating subtable for virt 0x%llx blksize=%llx\n", + virt, blocksize); ++#endif + new_table = create_table(); + set_pte_table(pte, new_table); + } else if (pte_type(pte) == PTE_TYPE_BLOCK) { ++#ifdef DEBUG_CACHE + debug("Split block into subtable for virt 0x%llx blksize=0x%llx\n", + virt, blocksize); ++#endif + split_block(pte, level); + } + } +@@ -433,14 +449,16 @@ void invalidate_dcache_all(void) + */ + inline void flush_dcache_all(void) + { +- int ret; ++ int __maybe_unused ret; + + __asm_flush_dcache_all(); + ret = __asm_flush_l3_dcache(); ++#ifdef DEBUG_CACHE + if (ret) + debug("flushing dcache returns 0x%x\n", ret); + else + debug("flushing dcache successfully.\n"); ++#endif + } + + #ifndef CONFIG_SYS_DISABLE_DCACHE_OPS +@@ -529,14 +547,16 @@ static u64 set_one_region(u64 start, u64 size, u64 attrs, bool flag, int level) + *pte &= ~PMD_ATTRINDX_MASK; + *pte |= attrs & PMD_ATTRINDX_MASK; + } ++#ifdef DEBUG_CACHE + debug("Set attrs=%llx pte=%p level=%d\n", attrs, pte, level); +- ++#endif + return levelsize; + } + + /* Unaligned or doesn't fit, maybe split block into table */ ++#ifdef DEBUG_CACHE + debug("addr=%llx level=%d pte=%p (%llx)\n", start, level, pte, *pte); +- ++#endif + /* Maybe we need to split the block into a table */ + if (pte_type(pte) == PTE_TYPE_BLOCK) + split_block(pte, level); +@@ -557,8 +577,9 @@ void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size, + u64 real_start = start; + u64 real_size = size; + ++#ifdef DEBUG_CACHE + debug("start=%lx size=%lx\n", (ulong)start, (ulong)size); +- ++#endif + if (!gd->arch.tlb_emerg) + panic("Emergency page table not setup."); + +diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile +index 62da168ef8..61bf75a5b6 100644 +--- a/arch/arm/dts/Makefile ++++ b/arch/arm/dts/Makefile +@@ -171,20 +171,49 @@ dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \ + + dtb-$(CONFIG_ARCH_MVEBU) += \ + armada-3720-db.dtb \ ++ armada-3720-ddr3-db-v2-B.dtb \ ++ armada-3720-ddr3-db-v2-C.dtb \ ++ armada-3720-ddr3-db-v1-A.dtb \ ++ armada-3720-ddr3-db-v1-B.dtb \ ++ armada-3720-ddr3-db-v1-C.dtb \ ++ armada-3720-ddr4-db-v3-A.dtb \ ++ armada-3720-ddr4-db-v3-B.dtb \ ++ armada-3720-ddr4-db-v3-C.dtb \ ++ armada-3720-ddr4-db-v1-A.dtb \ ++ armada-3720-ddr4-db-v1-B.dtb \ + armada-3720-espressobin.dtb \ ++ armada-3720-espressobin-emmc.dtb \ + armada-3720-turris-mox.dtb \ + armada-3720-uDPU.dtb \ + armada-375-db.dtb \ + armada-388-clearfog.dtb \ + armada-388-gp.dtb \ ++ armada-385-ap.dtb \ + armada-388-helios4.dtb \ + armada-385-db-88f6820-amc.dtb \ + armada-385-turris-omnia.dtb \ ++ armada-7020-amc.dtb \ ++ armada-7020-comexp.dtb \ ++ armada-7040-pcac.dtb \ + armada-7040-db.dtb \ +- armada-7040-db-nand.dtb \ ++ armada-7040-db-B.dtb \ ++ armada-7040-db-C.dtb \ ++ armada-7040-db-D.dtb \ ++ armada-7040-db-E.dtb \ ++ armada-7040-db-F.dtb \ + armada-8040-db.dtb \ ++ armada-8040-db-B.dtb \ ++ armada-8040-db-C.dtb \ ++ armada-8040-db-D.dtb \ ++ armada-8040-db-E.dtb \ ++ armada-8040-db-F.dtb \ ++ armada-8040-db-G.dtb \ ++ armada-8040-db-H.dtb \ + armada-8040-mcbin.dtb \ ++ armada-8040-mcbin-single-shot.dtb \ + armada-8040-clearfog-gt-8k.dtb \ ++ armada-8040-ocp.dtb \ ++ armada-8040-ucpe.dtb \ + armada-xp-gp.dtb \ + armada-xp-maxbcm.dtb \ + armada-xp-synology-ds414.dtb \ +@@ -193,7 +222,22 @@ dtb-$(CONFIG_ARCH_MVEBU) += \ + armada-385-atl-x530.dtb \ + armada-385-atl-x530DP.dtb \ + armada-xp-db-xc3-24g4xg.dtb \ +- armada-xp-crs305-1g-4s.dtb ++ armada-xp-crs305-1g-4s.dtb \ ++ cn9130-crb-A.dtb \ ++ cn9130-crb-B.dtb \ ++ cn9130-crb-C.dtb \ ++ cn9130-crb-r1p3-A.dtb \ ++ cn9130-crb-r1p3-B.dtb \ ++ cn9130-crb-r1p3-C.dtb \ ++ cn9130-db-A.dtb \ ++ cn9130-db-B.dtb \ ++ cn9130-db-C.dtb \ ++ cn9131-db-A.dtb \ ++ cn9131-db-B.dtb \ ++ cn9131-db-C.dtb \ ++ cn9132-db-A.dtb \ ++ cn9132-db-B.dtb \ ++ cn9132-db-C.dtb + + dtb-$(CONFIG_ARCH_UNIPHIER_LD11) += \ + uniphier-ld11-global.dtb \ +@@ -306,7 +350,7 @@ dtb-$(CONFIG_AM43XX) += am437x-gp-evm.dtb am437x-sk-evm.dtb \ + am437x-cm-t43.dtb + dtb-$(CONFIG_TARGET_AM3517_EVM) += am3517-evm.dtb + dtb-$(CONFIG_TI816X) += dm8168-evm.dtb +-dtb-$(CONFIG_THUNDERX) += thunderx-88xx.dtb ++dtb-$(CONFIG_OCTEONTX) += octeontx-88xx.dtb + + dtb-$(CONFIG_ARCH_SOCFPGA) += \ + socfpga_arria5_socdk.dtb \ +diff --git a/arch/arm/dts/armada-3720-db.dts b/arch/arm/dts/armada-3720-db.dts +index 1b219c423b..adba9ead48 100644 +--- a/arch/arm/dts/armada-3720-db.dts ++++ b/arch/arm/dts/armada-3720-db.dts +@@ -49,8 +49,10 @@ + #include "armada-372x.dtsi" + + / { +- model = "Marvell Armada 3720 Development Board DB-88F3720-DDR3"; +- compatible = "marvell,armada-3720-db", "marvell,armada3720", "marvell,armada3710"; ++ model = "Marvell Armada 3720 Development Board DB-88F3720-DDR3-V2"; ++ compatible = "marvell,armada-3720-db-v2", ++ "marvell,armada3720", ++ "marvell,armada3710"; + + chosen { + stdout-path = "serial0:115200n8"; +@@ -66,17 +68,61 @@ + device_type = "memory"; + reg = <0x00000000 0x00000000 0x00000000 0x20000000>; + }; ++ ++ reg_usb3_vbus: usb3_vbus@0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "usb3-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ shutdown-delay-us = <1000000>; ++ gpio = <&expander0 1 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ reg_usb2_vbus: usb2_vbus@0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "usb2-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ shutdown-delay-us = <1000000>; ++ gpio = <&expander0 0 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ vcc_sd_reg0: regulator@0 { ++ compatible = "regulator-gpio"; ++ regulator-name = "vcc_sd0"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-type = "voltage"; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ gpios = <&gpiosb 23 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ vcc_sd_reg1: regulator@1 { ++ compatible = "regulator-fixed"; ++ regulator-name = "vcc_sd1"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ shutdown-delay-us = <1000000>; ++ gpio = <&expander0 4 GPIO_ACTIVE_HIGH>; ++ }; + }; + + &comphy { + phy0 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; ++ phy-speed = ; + }; + + phy1 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ phy-speed = ; ++ phy-invert = ; + }; + }; + +@@ -91,6 +137,15 @@ + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_pins>; + status = "okay"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ expander0: pca953x@22 { ++ compatible = "nxp,pca9555"; ++ #gpio-cells = <2>; ++ reg = <0x22>; ++ status = "okay"; ++ }; + }; + + /* CON3 */ +@@ -100,6 +155,8 @@ + + &sdhci0 { + bus-width = <4>; ++ vqmmc-supply = <&vcc_sd_reg0>; ++ vmmc-supply = <&vcc_sd_reg1>; + pinctrl-names = "default"; + pinctrl-0 = <&sdio_pins>; + status = "okay"; +@@ -147,11 +204,13 @@ + + /* CON29 */ + &usb2 { ++ vbus-supply = <®_usb2_vbus>; + status = "okay"; + }; + + /* CON31 */ + &usb3 { ++ vbus-supply = <®_usb3_vbus>; + status = "okay"; + }; + +diff --git a/arch/arm/dts/armada-3720-ddr3-db-v1-A.dts b/arch/arm/dts/armada-3720-ddr3-db-v1-A.dts +new file mode 100644 +index 0000000000..4fe02d0acc +--- /dev/null ++++ b/arch/arm/dts/armada-3720-ddr3-db-v1-A.dts +@@ -0,0 +1,43 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#include "armada-3720-db.dts" ++ ++/* detail board setup: ++ * Pcie Jumper slot : DB-88F3720-PCIe-mPCIe-Jumper ++ * SGMII module slot : DB-88F3720-SerDes-Jumper ++ * RGMII module slot : DB-88F3720-PHY module ++ * eMMC slot : DB-88F3720-eMMC_NAND module ++ * SDIO slot : DB-88F3720-SDcard module ++ * ++ * PHY0 (USB3/SGMII1) : USB3 ++ * PHY1 (PCIe/SGMII0) : PCIe (WiFi via mini_PCIe module) ++ * PHY2 (SATA) : SATA ++ * RGMII-0 : Ethernet via PHY (1 Lane) ++ * USB2 Port 0 : USB2 as part USB3 ++ * USB2 Port 1 : USB2 Host ++ * eMMC* : eMMC NAND, ++ connected to SD / eMMC Host 1 in North Bridge ++ * SDIO* : SD card, ++ connected to SDIO Host 0 in South Bridge ++ */ ++ ++/ { ++ model = "Marvell Armada 3720 Development Board DB-88F3720-DDR3-V1"; ++ compatible = "marvell,armada-3720-db-v1", ++ "marvell,armada3720", ++ "marvell,armada3710"; ++ ++ soc { ++ internal-regs { ++ comphy: comphy@18300 { ++ phy2 { ++ phy-invert = ++ ; ++ }; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/armada-3720-ddr3-db-v1-B.dts b/arch/arm/dts/armada-3720-ddr3-db-v1-B.dts +new file mode 100644 +index 0000000000..11122f9189 +--- /dev/null ++++ b/arch/arm/dts/armada-3720-ddr3-db-v1-B.dts +@@ -0,0 +1,55 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#include "armada-3720-ddr3-db-v1-A.dts" ++ ++/* detail board setup: ++ * Pcie Jumper slot : DB-88F3720-PCIe-mPCIe-Jumper ++ * SGMII module slot : DB-88F3720-SerDes-Jumper ++ * RGMII module slot : DB-88F3720-PHY module ++ * eMMC slot : DB-88F3720-eMMC_NAND module ++ * SDIO slot : DB-88F3720-SDcard module ++ * ++ * PHY0 (USB3/SGMII1) : SGMII1_Ethernet via PHY (1 Lane) ++ * PHY1 (PCIe/SGMII0) : PCIe (WiFi via mini_PCIe module) ++ * PHY2 (SATA) : SATA ++ * RGMII : Ethernet via PHY (1 Lane) ++ * USB2 Port 0 : USB2 only ++ * USB2 Port 1 : USB2 Host ++ * eMMC* : eMMC NAND, ++ connected to SD / eMMC Host 1 in North Bridge ++ * SDIO* : SD card, ++ connected to SDIO Host 0 in South Bridge ++ */ ++ ++/ { ++ model = "Marvell Armada 3720 Development Board DB-88F3720-DDR3-V1-B"; ++ compatible = "marvell,armada-3720-db-v1", ++ "marvell,armada3720", ++ "marvell,armada3710"; ++ ++ soc { ++ internal-regs { ++ comphy: comphy@18300 { ++ phy0 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ }; ++ mdio@32004 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ethphy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++ }; ++ eth1: neta@40000 { ++ status = "okay"; ++ phy-mode = "sgmii"; ++ phy = <ðphy1>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/armada-3720-ddr3-db-v1-C.dts b/arch/arm/dts/armada-3720-ddr3-db-v1-C.dts +new file mode 100644 +index 0000000000..e17d5c2714 +--- /dev/null ++++ b/arch/arm/dts/armada-3720-ddr3-db-v1-C.dts +@@ -0,0 +1,62 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#include "armada-3720-ddr3-db-v1-A.dts" ++ ++/* detail board setup: ++ * Pcie Jumper slot : DB-88F3720-PCIe-mPCIe-Jumper ++ * SGMII module slot : DB-88F3720-SerDes-Jumper ++ * RGMII module slot : DB-88F3720-PHY module ++ * eMMC slot : DB-88F3720-eMMC_NAND module ++ * SDIO slot : DB-88F3720-SDcard module ++ * ++ * PHY0 (USB3/SGMII1) : SGMII1_Ethernet via SFP2.5G (1 Lane) ++ * PHY1 (PCIe/SGMII0) : PCIe (WiFi via mini_PCIe module) ++ * PHY2 (SATA) : SATA ++ * RGMII : Ethernet via PHY (1 Lane) ++ * USB2 Port 0 : USB2 only ++ * USB2 Port 1 : USB2 Host ++ * eMMC* : eMMC NAND, ++ connected to SD / eMMC Host 1 in North Bridge ++ * SDIO* : SD card, ++ connected to SDIO Host 0 in South Bridge ++ */ ++ ++/ { ++ model = "Marvell Armada 3720 Development Board DB-88F3720-DDR3-V1-C"; ++ compatible = "marvell,armada-3720-db-v1", ++ "marvell,armada3720", ++ "marvell,armada3710"; ++ ++ soc { ++ internal-regs { ++ comphy: comphy@18300 { ++ phy0 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ }; ++ eth1: neta@40000 { ++ status = "okay"; ++ phy-mode = "sgmii"; ++ fixed-link { ++ /* Here "speed" is set to 1000, GBE MAC ++ * is running in 1G mode, but the ++ * actuall PHY speed may be 1 Gbps or ++ * 2.5 Gbps, it's up to the ++ * corresponding SERDES speed in comphy ++ * node. ++ * If SERDES speed is set to 3.125G, it ++ * implies sgmii 2.5 Gbps; ++ * if SERDES speed is set to 1.25G, it ++ * implies sgmii 1 Gbps. ++ */ ++ speed = <1000>; ++ full-duplex; ++ }; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/armada-3720-ddr3-db-v2-B.dts b/arch/arm/dts/armada-3720-ddr3-db-v2-B.dts +new file mode 100644 +index 0000000000..6f16c82491 +--- /dev/null ++++ b/arch/arm/dts/armada-3720-ddr3-db-v2-B.dts +@@ -0,0 +1,55 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#include "armada-3720-db.dts" ++ ++/* detail board setup: ++ * Pcie Jumper slot : DB-88F3720-PCIe-mPCIe-Jumper ++ * SGMII module slot : DB-88F3720-SerDes-Jumper ++ * RGMII module slot : DB-88F3720-PHY module ++ * eMMC slot : DB-88F3720-eMMC_NAND module ++ * SDIO slot : DB-88F3720-SDcard module ++ * ++ * PHY0 (USB3/SGMII1) : SGMII1_Ethernet via PHY (1 Lane) ++ * PHY1 (PCIe/SGMII0) : PCIe (WiFi via mini_PCIe module) ++ * PHY2 (SATA) : SATA ++ * RGMII : Ethernet via PHY (1 Lane) ++ * USB2 Port 0 : USB2 only ++ * USB2 Port 1 : USB2 Host ++ * eMMC* : eMMC NAND, ++ connected to SD / eMMC Host 1 in North Bridge ++ * SDIO* : SD card, ++ connected to SDIO Host 0 in South Bridge ++ */ ++ ++/ { ++ model = "Marvell Armada 3720 Development Board DB-88F3720-DDR3-V2-B"; ++ compatible = "marvell,armada-3720-db-v2", ++ "marvell,armada3720", ++ "marvell,armada3710"; ++ ++ soc { ++ internal-regs { ++ comphy: comphy@18300 { ++ phy0 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ }; ++ mdio@32004 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ethphy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++ }; ++ eth1: neta@40000 { ++ status = "okay"; ++ phy-mode = "sgmii"; ++ phy = <ðphy1>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/armada-3720-ddr3-db-v2-C.dts b/arch/arm/dts/armada-3720-ddr3-db-v2-C.dts +new file mode 100644 +index 0000000000..3b5b764748 +--- /dev/null ++++ b/arch/arm/dts/armada-3720-ddr3-db-v2-C.dts +@@ -0,0 +1,62 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#include "armada-3720-db.dts" ++ ++/* detail board setup: ++ * Pcie Jumper slot : DB-88F3720-PCIe-mPCIe-Jumper ++ * SGMII module slot : DB-88F3720-SerDes-Jumper ++ * RGMII module slot : DB-88F3720-PHY module ++ * eMMC slot : DB-88F3720-eMMC_NAND module ++ * SDIO slot : DB-88F3720-SDcard module ++ * ++ * PHY0 (USB3/SGMII1) : SGMII1_Ethernet via SFP2.5G (1 Lane) ++ * PHY1 (PCIe/SGMII0) : PCIe (WiFi via mini_PCIe module) ++ * PHY2 (SATA) : SATA ++ * RGMII : Ethernet via PHY (1 Lane) ++ * USB2 Port 0 : USB2 only ++ * USB2 Port 1 : USB2 Host ++ * eMMC* : eMMC NAND, ++ connected to SD / eMMC Host 1 in North Bridge ++ * SDIO* : SD card, ++ connected to SDIO Host 0 in South Bridge ++*/ ++ ++/ { ++ model = "Marvell Armada 3720 Development Board DB-88F3720-DDR3-V2-C"; ++ compatible = "marvell,armada-3720-db-v2", ++ "marvell,armada3720", ++ "marvell,armada3710"; ++ ++ soc { ++ internal-regs { ++ comphy: comphy@18300 { ++ phy0 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ }; ++ eth1: neta@40000 { ++ status = "okay"; ++ phy-mode = "sgmii"; ++ fixed-link { ++ /* Here "speed" is set to 1000, GBE MAC ++ * is running in 1G mode, but the ++ * actuall PHY speed may be 1 Gbps or ++ * 2.5 Gbps, it's up to the ++ * corresponding SERDES speed in comphy ++ * node. ++ * If SERDES speed is set to 3.125G, it ++ * implies sgmii 2.5 Gbps; ++ * if SERDES speed is set to 1.25G, it ++ * implies sgmii 1 Gbps. ++ */ ++ speed = <1000>; ++ full-duplex; ++ }; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/armada-3720-ddr4-db-v1-A.dts b/arch/arm/dts/armada-3720-ddr4-db-v1-A.dts +new file mode 100644 +index 0000000000..76545695cd +--- /dev/null ++++ b/arch/arm/dts/armada-3720-ddr4-db-v1-A.dts +@@ -0,0 +1,47 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#include "armada-3720-ddr3-db-v1-A.dts" ++ ++/* detail board setup: ++ * Pcie Jumper slot : DB-88F3720-PCIe-mPCIe-Jumper ++ * SGMII module slot : DB-88F3720-SerDes-Jumper ++ * RGMII module slot : DB-88F3720-PHY module ++ * eMMC slot : DB-88F3720-eMMC_NAND module ++ * SDIO slot : DB-88F3720-SDcard module ++ * ++ * PHY0 (USB3/SGMII1) : USB3 ++ * PHY1 (PCIe/SGMII0) : PCIe (WiFi via mini_PCIe module) ++ * PHY2 (SATA) : SATA ++ * RGMII-0 : Ethernet via PHY (1 Lane) ++ * USB2 Port 0 : USB2 as part USB3 ++ * USB2 Port 1 : USB2 Host ++ * eMMC* : eMMC NAND, ++ connected to SD / eMMC Host 1 in North Bridge ++ * SDIO* : SD card, ++ connected to SDIO Host 0 in South Bridge ++ */ ++ ++/ { ++ model = "Marvell Armada 3720 Development Board DB-88F3720-DDR4-V1"; ++ compatible = "marvell,armada-3720-db-v2", ++ "marvell,armada3720", ++ "marvell,armada3710"; ++ ++ soc { ++ internal-regs { ++ comphy: comphy@18300 { ++ phy2 { ++ phy-invert = ++ ; ++ }; ++ }; ++ }; ++ }; ++ ++ vcc_sd_reg0: regulator@0 { ++ gpios = <&gpiosb 22 GPIO_ACTIVE_HIGH>; ++ }; ++}; +diff --git a/arch/arm/dts/armada-3720-ddr4-db-v1-B.dts b/arch/arm/dts/armada-3720-ddr4-db-v1-B.dts +new file mode 100644 +index 0000000000..2e73878aae +--- /dev/null ++++ b/arch/arm/dts/armada-3720-ddr4-db-v1-B.dts +@@ -0,0 +1,56 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#include "armada-3720-ddr4-db-v1-A.dts" ++ ++/* detail board setup: ++ * Pcie Jumper slot : DB-88F3720-PCIe-mPCIe-Jumper ++ * SGMII module slot : DB-88F3720-SerDes-Jumper ++ * RGMII module slot : DB-88F3720-PHY module ++ * eMMC slot : DB-88F3720-eMMC_NAND module ++ * SDIO slot : DB-88F3720-SDcard module ++ * ++ * PHY0 (USB3/SGMII1) : SGMII1 ++ * PHY1 (PCIe/SGMII0) : PCIe (WiFi via mini_PCIe module) ++ * PHY2 (SATA) : SATA ++ * RGMII-0 : Ethernet via PHY (1 Lane) ++ * USB2 Port 0 : USB2 as part USB3 ++ * USB2 Port 1 : USB2 Host ++ * eMMC* : eMMC NAND, ++ connected to SD / eMMC Host 1 in North Bridge ++ * SDIO* : SD card, ++ connected to SDIO Host 0 in South Bridge ++ */ ++ ++/ { ++ model = "Marvell Armada 3720 Development Board DB-88F3720-DDR4-V1-B"; ++ compatible = "marvell,armada-3720-db-v2", ++ "marvell,armada3720", ++ "marvell,armada3710"; ++ ++ soc { ++ internal-regs { ++ comphy: comphy@18300 { ++ phy0 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ }; ++ mdio@32004 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ethphy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++ }; ++ eth1: neta@40000 { ++ status = "okay"; ++ phy-mode = "sgmii"; ++ phy = <ðphy1>; ++ }; ++ }; ++ }; ++ ++}; +diff --git a/arch/arm/dts/armada-3720-ddr4-db-v3-A.dts b/arch/arm/dts/armada-3720-ddr4-db-v3-A.dts +new file mode 100644 +index 0000000000..a956ec6cc4 +--- /dev/null ++++ b/arch/arm/dts/armada-3720-ddr4-db-v3-A.dts +@@ -0,0 +1,33 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#include "armada-3720-db.dts" ++ ++/* detail board setup: ++ * Pcie Jumper slot : DB-88F3720-PCIe-mPCIe-Jumper ++ * SGMII module slot : DB-88F3720-SerDes-Jumper ++ * RGMII module slot : DB-88F3720-PHY module ++ * eMMC slot : DB-88F3720-eMMC_NAND module ++ * SDIO slot : DB-88F3720-SDcard module ++ * ++ * PHY0 (USB3/SGMII1) : USB3 ++ * PHY1 (PCIe/SGMII0) : PCIe (WiFi via mini_PCIe module) ++ * PHY2 (SATA) : SATA ++ * RGMII-0 : Ethernet via PHY (1 Lane) ++ * USB2 Port 0 : USB2 as part USB3 ++ * USB2 Port 1 : USB2 Host ++ * eMMC* : eMMC NAND, ++ connected to SD / eMMC Host 1 in North Bridge ++ * SDIO* : SD card, ++ connected to SDIO Host 0 in South Bridge ++ */ ++ ++/ { ++ model = "Marvell Armada 3720 Development Board DB-88F3720-DDR4-V3"; ++ compatible = "marvell,armada-3720-db-v3", ++ "marvell,armada3720", ++ "marvell,armada3710"; ++ ++}; +diff --git a/arch/arm/dts/armada-3720-ddr4-db-v3-B.dts b/arch/arm/dts/armada-3720-ddr4-db-v3-B.dts +new file mode 100644 +index 0000000000..85530f78b3 +--- /dev/null ++++ b/arch/arm/dts/armada-3720-ddr4-db-v3-B.dts +@@ -0,0 +1,56 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#include "armada-3720-ddr4-db-v3-A.dts" ++ ++/* detail board setup: ++ * Pcie Jumper slot : DB-88F3720-PCIe-mPCIe-Jumper ++ * SGMII module slot : DB-88F3720-SerDes-Jumper ++ * RGMII module slot : DB-88F3720-PHY module ++ * eMMC slot : DB-88F3720-eMMC_NAND module ++ * SDIO slot : DB-88F3720-SDcard module ++ * ++ * PHY0 (USB3/SGMII1) : SGMII1 ++ * PHY1 (PCIe/SGMII0) : PCIe (WiFi via mini_PCIe module) ++ * PHY2 (SATA) : SATA ++ * RGMII-0 : Ethernet via PHY (1 Lane) ++ * USB2 Port 0 : USB2 as part USB3 ++ * USB2 Port 1 : USB2 Host ++ * eMMC* : eMMC NAND, ++ connected to SD / eMMC Host 1 in North Bridge ++ * SDIO* : SD card, ++ connected to SDIO Host 0 in South Bridge ++ */ ++ ++/ { ++ model = "Marvell Armada 3720 Development Board DB-88F3720-DDR4-V3-B"; ++ compatible = "marvell,armada-3720-db-v3", ++ "marvell,armada3720", ++ "marvell,armada3710"; ++ ++ soc { ++ internal-regs { ++ comphy: comphy@18300 { ++ phy0 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ }; ++ mdio@32004 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ethphy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++ }; ++ eth1: neta@40000 { ++ status = "okay"; ++ phy-mode = "sgmii"; ++ phy = <ðphy1>; ++ }; ++ }; ++ }; ++ ++}; +diff --git a/arch/arm/dts/armada-3720-ddr4-db-v3-C.dts b/arch/arm/dts/armada-3720-ddr4-db-v3-C.dts +new file mode 100644 +index 0000000000..1fa8b5409d +--- /dev/null ++++ b/arch/arm/dts/armada-3720-ddr4-db-v3-C.dts +@@ -0,0 +1,63 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#include "armada-3720-ddr4-db-v3-A.dts" ++ ++/* detail board setup: ++ * Pcie Jumper slot : DB-88F3720-PCIe-mPCIe-Jumper ++ * SGMII module slot : DB-88F3720-SerDes-Jumper ++ * RGMII module slot : DB-88F3720-PHY module ++ * eMMC slot : DB-88F3720-eMMC_NAND module ++ * SDIO slot : DB-88F3720-SDcard module ++ * ++ * PHY0 (USB3/SGMII1) : SGMII1 via SFP2.5G (1 Lane) ++ * PHY1 (PCIe/SGMII0) : PCIe (WiFi via mini_PCIe module) ++ * PHY2 (SATA) : SATA ++ * RGMII-0 : Ethernet via PHY (1 Lane) ++ * USB2 Port 0 : USB2 as part USB3 ++ * USB2 Port 1 : USB2 Host ++ * eMMC* : eMMC NAND, ++ connected to SD / eMMC Host 1 in North Bridge ++ * SDIO* : SD card, ++ connected to SDIO Host 0 in South Bridge ++ */ ++ ++/ { ++ model = "Marvell Armada 3720 Development Board DB-88F3720-DDR4-V3-C"; ++ compatible = "marvell,armada-3720-db-v3", ++ "marvell,armada3720", ++ "marvell,armada3710"; ++ ++ soc { ++ internal-regs { ++ comphy: comphy@18300 { ++ phy0 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ }; ++ eth1: neta@40000 { ++ status = "okay"; ++ phy-mode = "sgmii"; ++ fixed-link { ++ /* Here "speed" is set to 1000, GBE MAC ++ * is running in 1G mode, but the ++ * actuall PHY speed may be 1 Gbps or ++ * 2.5 Gbps, it's up to the ++ * corresponding SERDES speed in comphy ++ * node. ++ * If SERDES speed is set to 3.125G, it ++ * implies sgmii 2.5 Gbps; ++ * if SERDES speed is set to 1.25G, it ++ * implies sgmii 1 Gbps. ++ */ ++ speed = <1000>; ++ full-duplex; ++ }; ++ }; ++ }; ++ }; ++ ++}; +diff --git a/arch/arm/dts/armada-3720-espressobin-emmc.dts b/arch/arm/dts/armada-3720-espressobin-emmc.dts +new file mode 100644 +index 0000000000..0dd59af9c0 +--- /dev/null ++++ b/arch/arm/dts/armada-3720-espressobin-emmc.dts +@@ -0,0 +1,19 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#include "armada-3720-espressobin.dts" ++ ++/ { ++ model = "Marvell Armada 3720 Community Board ESPRESSOBin (eMMC)"; ++ compatible = "marvell,armada-3720-espressobin", ++ "marvell,armada-3720-espressobin-emmc", ++ "marvell,armada3720", "marvell,armada3710"; ++ ++}; ++ ++/* U11 */ ++&sdhci1 { ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/armada-3720-espressobin.dts b/arch/arm/dts/armada-3720-espressobin.dts +index 84e2c2adba..169060fb23 100644 +--- a/arch/arm/dts/armada-3720-espressobin.dts ++++ b/arch/arm/dts/armada-3720-espressobin.dts +@@ -1,3 +1,4 @@ ++// SPDX-License-Identifier: GPL-2.0+ + /* + * Device Tree file for Marvell Armada 3720 community board + * (ESPRESSOBin) +@@ -5,53 +6,15 @@ + * + * Gregory CLEMENT + * Konstantin Porotchkin +- * +- * This file is dual-licensed: you can use it either under the terms +- * of the GPL or the X11 license, at your option. Note that this dual +- * licensing only applies to this file, and not this project as a +- * whole. +- * +- * a) This file is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License as +- * published by the Free Software Foundation; either version 2 of the +- * License, or (at your option) any later version. +- * +- * This file is distributed in the hope that it will be useful +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * Or, alternatively +- * +- * b) Permission is hereby granted, free of charge, to any person +- * obtaining a copy of this software and associated documentation +- * files (the "Software"), to deal in the Software without +- * restriction, including without limitation the rights to use +- * copy, modify, merge, publish, distribute, sublicense, and/or +- * sell copies of the Software, and to permit persons to whom the +- * Software is furnished to do so, subject to the following +- * conditions: +- * +- * The above copyright notice and this permission notice shall be +- * included in all copies or substantial portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND +- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY +- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +- * OTHER DEALINGS IN THE SOFTWARE. + */ +- + /dts-v1/; + + #include "armada-372x.dtsi" + + / { + model = "Marvell Armada 3720 Community Board ESPRESSOBin"; +- compatible = "marvell,armada-3720-espressobin", "marvell,armada3720", "marvell,armada3710"; ++ compatible = "marvell,armada-3720-espressobin", ++ "marvell,armada3720", "marvell,armada3710"; + + chosen { + stdout-path = "serial0:115200n8"; +@@ -67,23 +30,48 @@ + device_type = "memory"; + reg = <0x00000000 0x00000000 0x00000000 0x20000000>; + }; ++ ++ vcc_sd_reg0: regulator@0 { ++ compatible = "regulator-gpio"; ++ regulator-name = "vcc_sd0"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-type = "voltage"; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ gpios = <&gpionb 4 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ mdio@32004 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ mvswitch: switch@000000{ ++ compatible = "marvell,mv88e6xxx"; ++ status = "okay"; ++ phy-addr = <1>; ++ cpu-port = <0x0>; ++ port-mask = <0xf>; ++ }; ++ }; + }; + + &comphy { + max-lanes = <3>; + phy0 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; ++ phy-speed = ; + }; + + phy1 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; ++ phy-speed = ; + }; + + phy2 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; ++ phy-speed = ; + }; + }; + +@@ -93,6 +81,8 @@ + pinctrl-0 = <&rgmii_pins>, <&smi_pins>; + phy-mode = "rgmii"; + phy_addr = <0x1>; ++ phy = <&mvswitch>; ++ + fixed-link { + speed = <1000>; + full-duplex; +@@ -110,6 +100,34 @@ + status = "okay"; + }; + ++/* J1 */ ++&sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdio_pins>; ++ bus-width = <4>; ++ vqmmc-supply = <&vcc_sd_reg0>; ++ status = "okay"; ++}; ++ ++/* U11 */ ++&sdhci1 { ++ non-removable; ++ bus-width = <8>; ++ mmc-ddr-1_8v; ++ mmc-hs400-1_8v; ++ marvell,pad-type = "fixed-1-8v"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mmc_pins>; ++ status = "disabled"; ++ ++ #address-cells = <1>; ++ #size-cells = <0>; ++ mmccard: mmccard@0 { ++ compatible = "mmc-card"; ++ reg = <0>; ++ }; ++}; ++ + &spi0 { + status = "okay"; + pinctrl-names = "default"; +diff --git a/arch/arm/dts/armada-3720-turris-mox.dts b/arch/arm/dts/armada-3720-turris-mox.dts +index c36a5b8895..0b1da93229 100644 +--- a/arch/arm/dts/armada-3720-turris-mox.dts ++++ b/arch/arm/dts/armada-3720-turris-mox.dts +@@ -58,18 +58,18 @@ + &comphy { + max-lanes = <3>; + phy0 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; ++ phy-speed = ; + }; + + phy1 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; ++ phy-speed = ; + }; + + phy2 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; ++ phy-speed = ; + }; + }; + +diff --git a/arch/arm/dts/armada-3720-uDPU.dts b/arch/arm/dts/armada-3720-uDPU.dts +index 683dac2a7c..42fe726a8e 100644 +--- a/arch/arm/dts/armada-3720-uDPU.dts ++++ b/arch/arm/dts/armada-3720-uDPU.dts +@@ -108,17 +108,17 @@ + + &comphy { + phy0 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; ++ phy-speed = ; + }; + phy1 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; ++ phy-speed = ; + }; + + phy2 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; ++ phy-speed = ; + }; + }; + +diff --git a/arch/arm/dts/armada-375-db.dts b/arch/arm/dts/armada-375-db.dts +index 343349b8fd..7571bacd60 100644 +--- a/arch/arm/dts/armada-375-db.dts ++++ b/arch/arm/dts/armada-375-db.dts +@@ -171,6 +171,8 @@ + }; + + mdio { ++ status = "okay"; ++ + phy0: ethernet-phy@0 { + reg = <0>; + }; +diff --git a/arch/arm/dts/armada-385-ap.dts b/arch/arm/dts/armada-385-ap.dts +new file mode 100644 +index 0000000000..dc527d548a +--- /dev/null ++++ b/arch/arm/dts/armada-385-ap.dts +@@ -0,0 +1,181 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ */ ++ ++/dts-v1/; ++#include "armada-385.dtsi" ++ ++#include ++ ++/ { ++ model = "Marvell Armada 385 Access Point Development Board"; ++ compatible = "marvell,a385-db-ap", "marvell,armada385", ++ "marvell,armada380"; ++ ++ aliases { ++ ethernet0 = ð0; ++ ethernet1 = ð1; ++ ethernet2 = ð2; ++ serial0 = &uart0; ++ serial1 = &uart1; ++ }; ++ ++ chosen { ++ stdout-path = "serial1:115200n8"; ++ }; ++ ++ memory { ++ device_type = "memory"; ++ reg = <0x00000000 0x80000000>; /* 2GB */ ++ }; ++ ++ soc { ++ ranges = ; ++ ++ internal-regs { ++ ++ i2c0: i2c@11000 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c0_pins>; ++ status = "okay"; ++ ++ /* ++ * This bus is wired to two EEPROM ++ * sockets, one of which holding the ++ * board ID used by the bootloader. ++ * Erasing this EEPROM's content will ++ * brick the board. ++ * Use this bus with caution. ++ */ ++ }; ++ mdio@72004 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&mdio_pins>; ++ ++ phy0: ethernet-phy@1 { ++ reg = <1>; ++ }; ++ ++ phy1: ethernet-phy@4 { ++ reg = <4>; ++ }; ++ ++ phy2: ethernet-phy@6 { ++ reg = <6>; ++ }; ++ }; ++ ++ /* UART0 is exposed through the JP8 connector */ ++ uart0: serial@12000 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_pins>; ++ status = "okay"; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ /* ++ * UART1 is exposed through a FTDI chip ++ * wired to the mini-USB connector ++ */ ++ uart1: serial@12100 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ status = "okay"; ++ u-boot,dm-pre-reloc; ++ }; ++ ++ pinctrl@18000 { ++ xhci0_vbus_pins: xhci0-vbus-pins { ++ marvell,pins = "mpp44"; ++ marvell,function = "gpio"; ++ }; ++ }; ++ ++ ethernet@30000 { ++ status = "okay"; ++ phy = <&phy2>; ++ phy-mode = "sgmii"; ++ }; ++ ++ ethernet@34000 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "sgmii"; ++ }; ++ ++ usb@58000 { ++ status = "okay"; ++ }; ++ ++ ethernet@70000 { ++ pinctrl-names = "default"; ++ ++ /* ++ * The Reference Clock 0 is used to ++ * provide a clock to the PHY ++ */ ++ pinctrl-0 = <&ge0_rgmii_pins>, <&ref_clk0_pins>; ++ status = "okay"; ++ phy = <&phy0>; ++ phy-mode = "rgmii-id"; ++ }; ++ ++ nand_controller: nand-controller@d0000 { ++ status = "okay"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ num-cs = <1>; ++ nand-ecc-strength = <4>; ++ nand-ecc-step-size = <512>; ++ marvell,nand-keep-config; ++ marvell,nand-enable-arbiter; ++ nand-on-flash-bbt; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0x00000000 0x00800000>; ++ read-only; ++ }; ++ ++ partition@800000 { ++ label = "uImage"; ++ reg = <0x00800000 0x00400000>; ++ read-only; ++ }; ++ ++ partition@c00000 { ++ label = "Root"; ++ reg = <0x00c00000 0x3f400000>; ++ }; ++ }; ++ ++ }; ++ ++ pciec: pcie { ++ status = "okay"; ++ ++ /* ++ * The three PCIe units are accessible through ++ * standard mini-PCIe slots on the board. ++ */ ++ pcie@1,0 { ++ /* Port 0, Lane 0 */ ++ status = "okay"; ++ }; ++ ++ pcie@2,0 { ++ /* Port 1, Lane 0 */ ++ status = "okay"; ++ }; ++ ++ pcie@3,0 { ++ /* Port 2, Lane 0 */ ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/armada-388-gp.dts b/arch/arm/dts/armada-388-gp.dts +index d5ad2fd7e2..a2bb198236 100644 +--- a/arch/arm/dts/armada-388-gp.dts ++++ b/arch/arm/dts/armada-388-gp.dts +@@ -55,6 +55,7 @@ + ethernet0 = ð0; + ethernet1 = ð1; + spi0 = &spi0; ++ fuse0 = &efuse; + }; + + memory { +@@ -66,23 +67,26 @@ + ranges = ; + +- internal-regs { +- spi@10600 { +- pinctrl-names = "default"; +- pinctrl-0 = <&spi0_pins>; +- status = "okay"; +- u-boot,dm-pre-reloc; ++ spi0: spi@10600 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins>; ++ status = "okay"; ++ u-boot,dm-pre-reloc; + +- spi-flash@0 { +- u-boot,dm-pre-reloc; +- #address-cells = <1>; +- #size-cells = <1>; +- compatible = "st,m25p128", "jedec,spi-nor"; +- reg = <0>; /* Chip select 0 */ +- spi-max-frequency = <50000000>; +- m25p,fast-read; +- }; ++ spi-flash@0 { ++ u-boot,dm-pre-reloc; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "st,m25p128", ++ "jedec,spi-nor", "spi-flash"; ++ reg = <0>; /* Chip select 0 */ ++ spi-max-frequency = <50000000>; ++ m25p,fast-read; + }; ++ }; ++ ++ internal-regs { ++ + + i2c@11000 { + pinctrl-names = "default"; +@@ -232,6 +236,11 @@ + vcc-supply = <®_usb3_vbus>; + status = "okay"; + }; ++ ++ efuse@f9000 { ++ status = "okay"; ++ }; ++ + }; + + pcie { +diff --git a/arch/arm/dts/armada-38x.dtsi b/arch/arm/dts/armada-38x.dtsi +index 72c49beb71..28151f61ac 100644 +--- a/arch/arm/dts/armada-38x.dtsi ++++ b/arch/arm/dts/armada-38x.dtsi +@@ -590,6 +590,14 @@ + clocks = <&gateclk 10>; + status = "disabled"; + }; ++ ++ efuse: efuse@f9000 { ++ compatible = "marvell,mvebu-fuse-hd"; ++ reg = <0xe4008 0x4>; ++ otp-mem = <0xf9000>; ++ rows-count = <64>; ++ status = "disabled"; ++ }; + }; + + crypto_sram0: sa-sram0 { +diff --git a/arch/arm/dts/armada-7020-amc.dts b/arch/arm/dts/armada-7020-amc.dts +new file mode 100644 +index 0000000000..b0682e7d9e +--- /dev/null ++++ b/arch/arm/dts/armada-7020-amc.dts +@@ -0,0 +1,212 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada 7020 AMC board ++ * Boot device: NAND ++ */ ++ ++#include "armada-70x0.dtsi" ++ ++/ { ++ model = "Marvell Armada 7020 AMC"; ++ compatible = "marvell,armada7020-amc", "marvell,armada7020", ++ "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ i2c1 = &cp0_mss_i2c0; ++ i2c2 = &ap_i2c0; ++ spi0 = &ap_spi0; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; /* 2GB */ ++ }; ++ ++ simple-bus { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ reg_smi0: reg_smi { ++ compatible = "regulator-fixed"; ++ regulator-name = "reg-smi"; ++ /* ++ * set GPIO[31] to 0 to connect SMI to main switch ++ * board ++ */ ++ gpio = <&cp0_gpio0 31 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ reg_i2c0: reg_i2c { ++ compatible = "regulator-fixed"; ++ regulator-name = "reg-i2c"; ++ enable-active-high; ++ /* ++ * set GPIO[44] to 1 to connect ap_i2c0 to main switch ++ * board ++ */ ++ gpio = <&cp0_gpio1 12 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++}; ++ ++&ap_pinctl { ++ /* MPP Bus: ++ * SPI [0-3] ++ * I2C [4-5] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 3 3 3 3 3 3 0 0 0 0 ++ 0 3 0 0 0 0 0 0 0 3 >; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ap_i2c0_pins>; ++ enable_gpios = <®_i2c0>; ++ status = "okay"; ++}; ++ ++&ap_spi0 { ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <0x1>; ++ #size-cells = <0x1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0x0>; ++ spi-max-frequency = <108000000>; ++ }; ++}; ++ ++&cp0_nand { ++ status = "okay"; ++}; ++ ++&cp0_pcie0 { ++ num-lanes = <4>; ++ ranges = ++ /* downstream I/O */ ++ <0x81000000 0 0xfa000000 0 0xfa000000 0 0x10000 ++ /* non-prefetchable memory */ ++ 0x82000000 0 0xf6000000 0 0xf6000000 0 0x4000000>; ++ ++ status = "okay"; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_mss_i2c0 { ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_pinctl { ++ /* MPP Bus: ++ * RGMII [0-11] ++ * Device Bus [13-27] ++ * SATA1 [28] ++ * UART0 [29-30] ++ * SMI [32,34] ++ * XSMI [35-36] ++ * I2C0 [37-38] ++ * I2C1 [50-51] ++ * SD [49, 55-61] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 3 3 3 3 3 3 3 3 3 3 ++ 3 3 0 2 3 1 1 1 1 1 ++ 1 1 1 1 1 1 1 1 9 0xA ++ 0xA 0 7 0 7 7 7 2 2 0xFF ++ 0xFF 0xFF 0xFF 0xFF 0 0 0 0 0 0xA ++ 2 2 0 0 0 0xB 0xE 0xE 0xE 0xE ++ 0xE 0xE 0>; ++}; ++ ++&cp0_sata0 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp0_usb3_0 { ++ status = "okay"; ++}; ++ ++&cp0_utmi0 { ++ status = "okay"; ++}; ++ ++&cp0_sdhci0 { ++ status = "okay"; ++ bus-width = <4>; ++ no-1-8-v; ++ non-removable; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ enable_gpios = <®_smi0>; ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; ++}; ++ ++&cp0_eth1 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "rgmii-id"; ++}; +diff --git a/arch/arm/dts/armada-7020-comexp.dts b/arch/arm/dts/armada-7020-comexp.dts +new file mode 100644 +index 0000000000..6f5c9b2075 +--- /dev/null ++++ b/arch/arm/dts/armada-7020-comexp.dts +@@ -0,0 +1,199 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada 7020 COMEXPRESS board ++ * Boot device: NAND ++ */ ++ ++#include "armada-70x0.dtsi" ++ ++/ { ++ model = "Marvell Armada-7020 COMEXPRESS board setup"; ++ compatible = "marvell,armada7020-comexp", "marvell,armada702", ++ "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ i2c1 = &cp0_mss_i2c0; ++ i2c2 = &ap_i2c0; ++ spi0 = &ap_spi0; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; /* 2GB */ ++ }; ++ ++ simple-bus { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ reg_smi0: reg_smi { ++ compatible = "regulator-fixed"; ++ regulator-name = "reg-smi"; ++ /* ++ * set GPIO[31] to 0 to connect SMI to main switch ++ * board ++ */ ++ gpio = <&cp0_gpio0 31 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ reg_i2c0: reg_i2c { ++ compatible = "regulator-fixed"; ++ regulator-name = "reg-i2c"; ++ enable-active-high; ++ /* ++ * set GPIO[44] to 1 to connect ap_i2c0 to main switch ++ * board ++ */ ++ gpio = <&cp0_gpio1 12 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++}; ++ ++&ap_pinctl { ++ /* MPP Bus: ++ * SPI [0-3] ++ * I2C [4-5] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 3 3 3 3 3 3 0 0 0 0 ++ 0 3 0 0 0 0 0 0 0 3 >; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ap_i2c0_pins>; ++ enable_gpios = <®_i2c0>; ++ status = "okay"; ++}; ++ ++&cp0_pinctl { ++ /* MPP Bus: ++ * RGMII [0-11] ++ * Device Bus [13-27] ++ * SATA1 [28] ++ * UART0 [29-30] ++ * SMI [32,34] ++ * XSMI [35-36] ++ * I2C0 [37-38] ++ * I2C1 [50-51] ++ * SD [55-61] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 3 3 3 3 3 3 3 3 3 3 ++ 3 3 0 2 0 1 1 1 1 1 ++ 1 1 1 1 1 1 1 1 9 0xA ++ 0xA 0 7 0 7 7 7 2 2 0 ++ 0 0 0 0 0 0 0 0 0 0 ++ 2 2 0 0 0 0xB 0xE 0xE 0xE 0xE ++ 0xE 0xE 0>; ++}; ++ ++&cp0_comphy { ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp0_nand { ++ /* MT29F8G08ABACAWP, ID=0xd32c, ONFI, page:4KB-224B, 8bit ECC, ++ * 1GByte total. ++ */ ++ status = "okay"; ++ nand-enable-arbiter; ++ num-cs = <1>; ++ nand-ecc-strength = <8>; ++ nand-ecc-step-size = <512>; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_mss_i2c0 { ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_sata0 { ++ status = "okay"; ++}; ++ ++&cp0_sdhci0 { ++ status = "okay"; ++ bus-width = <4>; ++ no-1-8-v; ++ non-removable; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ enable_gpios = <®_smi0>; ++ phy1: ethernet-phy@1 { ++ reg = <0x10>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; ++}; ++ ++&cp0_eth1 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "rgmii-id"; ++}; ++ ++&cp0_pcie0 { ++ num-lanes = <4>; ++ ranges = ++ /* downstream I/O */ ++ <0x81000000 0 0xfa000000 0 0xfa000000 0 0x10000 ++ /* non-prefetchable memory */ ++ 0x82000000 0 0xf6000000 0 0xf6000000 0 0x4000000>; ++ ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/armada-7040-db-B.dts b/arch/arm/dts/armada-7040-db-B.dts +new file mode 100644 +index 0000000000..479523165b +--- /dev/null ++++ b/arch/arm/dts/armada-7040-db-B.dts +@@ -0,0 +1,221 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada 7040 Development board platform ++ * Boot device: SPI NOR, 0x32 (SW3) ++ */ ++ ++#include "armada-70x0-db.dtsi" ++ ++/ { ++ model = "Marvell Armada 7040 Development Board DB-88FA7040 setup(B)"; ++ compatible = "marvell,armada7040-db", "marvell,armada7040", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp0_spi1; ++ fuse0 = &ap_hd_efuse0; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++}; ++ ++&ap_pinctl { ++ /* MPP Bus: ++ * SDIO [0-5] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 0 0 0 0 ++ 0 3 0 0 0 0 0 0 0 3 >; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_pcie2 { ++ status = "okay"; ++}; ++ ++&cp0_pcie0 { ++ status = "okay"; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_pinctl { ++ /* MPP Bus: ++ * RGMII1 [0-11] ++ * SPI [13-16] ++ * SATA1 [28] ++ * UART0 [29-30] ++ * SMI [32,34] ++ * XSMI [35-36] ++ * I2C [37-38] ++ * RGMII2 [44-55] ++ * SD [56-61] ++ * GPIO [62] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 3 3 3 3 3 3 3 3 3 3 ++ 3 3 0 3 3 3 3 0 0 0 ++ 0 0 0 0 0 0 0 0 9 0xA ++ 0xA 0 7 0 7 7 7 2 2 0 ++ 0 0 0 0 1 1 1 1 1 1 ++ 1 1 1 1 1 1 0xE 0xE 0xE 0xE ++ 0xE 0xE 0>; ++}; ++ ++&cp0_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_spi0_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>, /* CS1 */ ++ <0 0xffffffff>, /* CS2 */ ++ <0 0xffffffff>; /* CS3 */ ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <0x1>; ++ #size-cells = <0x1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0x0>; ++ spi-max-frequency = <108000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0x0 0x200000>; ++ }; ++ ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xe00000>; ++ }; ++ }; ++ }; ++}; ++ ++&cp0_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_usb3_1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp0_utmi0 { ++ status = "okay"; ++}; ++ ++&cp0_utmi1 { ++ status = "okay"; ++}; ++ ++&ap_sdhci0 { ++ status = "okay"; ++ bus-width = <4>; ++ no-1-8-v; ++ non-removable; ++}; ++ ++&cp0_sdhci0 { ++ status = "okay"; ++ bus-width = <4>; ++ no-1-8-v; ++ non-removable; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp0_eth1 { ++ status = "okay"; ++ phy = <&phy0>; ++ phy-mode = "rgmii-id"; ++}; ++ ++&cp0_eth2 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "rgmii-id"; ++}; +diff --git a/arch/arm/dts/armada-7040-db-C.dts b/arch/arm/dts/armada-7040-db-C.dts +new file mode 100644 +index 0000000000..ec4e114322 +--- /dev/null ++++ b/arch/arm/dts/armada-7040-db-C.dts +@@ -0,0 +1,222 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada 7040 Development board platform ++ * Boot device: SPI NOR, 0x32 (SW3) ++ */ ++ ++#include "armada-70x0-db.dtsi" ++ ++/ { ++ model = "Marvell Armada 7040 Development Board DB-88FA7040 setup(C)"; ++ compatible = "marvell,armada7040-db", "marvell,armada7040", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp0_spi1; ++ fuse0 = &ap_hd_efuse0; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++}; ++ ++&ap_pinctl { ++ /* MPP Bus: ++ * SDIO [0-5] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 0 0 0 0 ++ 0 3 0 0 0 0 0 0 0 3 >; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_pcie0 { ++ status = "okay"; ++}; ++ ++&cp0_pcie2 { ++ status = "okay"; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_pinctl { ++ /* MPP Bus: ++ * TDM [0-5] ++ * SPI0 [6-11] ++ * SPI1 [13-16] ++ * SATA1 [28] ++ * UART0 [29-30] ++ * SMI [32,34] ++ * XSMI [35-36] ++ * I2C [37-38] ++ * RGMII1 [44-55] ++ * SD [56-61] ++ * GPIO [62] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 4 4 4 4 4 4 4 4 4 4 ++ 4 4 0 3 3 3 3 0 0 0 ++ 0 0 0 0 0 0 0 0 9 0xA ++ 0xA 0 7 0 7 7 7 2 2 0 ++ 0 0 0 0 1 1 1 1 1 1 ++ 1 1 1 1 1 1 0xE 0xE 0xE 0xE ++ 0xE 0xE 0>; ++}; ++ ++&cp0_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_spi0_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>, /* CS1 */ ++ <0 0xffffffff>, /* CS2 */ ++ <0 0xffffffff>; /* CS3 */ ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <0x1>; ++ #size-cells = <0x1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0x0>; ++ spi-max-frequency = <108000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0x0 0x200000>; ++ }; ++ ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xe00000>; ++ }; ++ }; ++ }; ++}; ++ ++&cp0_sata0 { ++ status = "okay"; ++}; ++ ++&cp0_usb3_0 { ++ status = "okay"; ++}; ++ ++&cp0_usb3_1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp0_utmi0 { ++ status = "okay"; ++}; ++ ++&cp0_utmi1 { ++ status = "okay"; ++}; ++ ++&ap_sdhci0 { ++ status = "okay"; ++ bus-width = <4>; ++ no-1-8-v; ++ non-removable; ++}; ++ ++&cp0_sdhci0 { ++ status = "okay"; ++ bus-width = <4>; ++ no-1-8-v; ++ non-removable; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-2 */ ++}; ++ ++&cp0_eth2 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "rgmii-id"; ++}; +diff --git a/arch/arm/dts/armada-7040-db-D.dts b/arch/arm/dts/armada-7040-db-D.dts +new file mode 100644 +index 0000000000..95d8e06d10 +--- /dev/null ++++ b/arch/arm/dts/armada-7040-db-D.dts +@@ -0,0 +1,201 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada 7040 Development board platform ++ * Boot device: SPI NOR, 0x32 (SW3) ++ */ ++ ++#include "armada-70x0-db.dtsi" ++ ++/ { ++ model = "Marvell Armada 7040 Development Board DB-88FA7040 setup(D)"; ++ compatible = "marvell,armada7040-db", "marvell,armada7040", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp0_spi1; ++ fuse0 = &ap_hd_efuse0; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++ ++ cp0_sar { ++ boot_mode { ++ default = <0xe>; ++ }; ++ }; ++}; ++ ++&ap_pinctl { ++ /* MPP Bus: ++ * SDIO [0-5] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 0 0 0 0 ++ 0 3 0 0 0 0 0 0 0 3 >; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_pcie0 { ++ status = "okay"; ++}; ++ ++&cp0_pcie2 { ++ status = "okay"; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_pinctl { ++ /* MPP Bus: ++ * AUDIO [0-5] ++ * SS_PWDN [12] ++ * NF_RBn [13] ++ * DEV_BUS [14-27] ++ * SATA1 [28] ++ * UART0 [29-30] ++ * MSS_VTT [31] ++ * SMI [32,34] ++ * XSMI [35-36] ++ * I2C [37-38] ++ * RGMII1 [44-55] ++ * SD [56-61] ++ * GPIO [62] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 2 2 2 2 2 2 0 0 0 0 ++ 0 0 0 2 0 1 1 1 1 1 ++ 1 1 1 1 1 1 1 1 9 0xA ++ 0xA 0 7 0 7 7 7 2 2 0 ++ 0 0 0 0 1 1 1 1 1 1 ++ 1 1 1 1 1 1 0xE 0xE 0xE 0xE ++ 0xE 0xE 0>; ++}; ++ ++&cp0_nand { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_sata0 { ++ status = "okay"; ++}; ++ ++&cp0_usb3_1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp0_utmi0 { ++ utmi-port = ; ++ status = "okay"; ++}; ++ ++&cp0_utmi1 { ++ status = "okay"; ++}; ++ ++&ap_sdhci0 { ++ status = "okay"; ++ bus-width = <4>; ++ no-1-8-v; ++ non-removable; ++}; ++ ++&cp0_sdhci0 { ++ status = "okay"; ++ bus-width = <4>; ++ no-1-8-v; ++ non-removable; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-2 */ ++}; ++ ++&cp0_eth2 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "rgmii-id"; ++}; +diff --git a/arch/arm/dts/armada-7040-db-E.dts b/arch/arm/dts/armada-7040-db-E.dts +new file mode 100644 +index 0000000000..871734f881 +--- /dev/null ++++ b/arch/arm/dts/armada-7040-db-E.dts +@@ -0,0 +1,233 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada 7040 Development board platform ++ * Boot device: SPI NOR, 0x32 (SW3) ++ */ ++ ++#include "armada-70x0-db.dtsi" ++ ++/ { ++ model = "Marvell Armada 7040 Development Board DB-88FA7040 setup(E)"; ++ compatible = "marvell,armada7040-db", "marvell,armada7040", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp0_spi1; ++ fuse0 = &ap_hd_efuse0; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++}; ++ ++&ap_spi0 { ++ status = "okay"; ++}; ++ ++&ap_i2c0 { ++ status = "okay"; ++}; ++ ++&ap_pinctl { ++ /* MPP Bus: ++ * SPI0 [0-3] ++ * I2C0 [4-5] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 3 3 3 3 3 3 0 0 0 0 ++ 0 3 0 0 0 0 0 0 0 3 >; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_pcie0 { ++ status = "okay"; ++}; ++ ++&cp0_pcie2 { ++ status = "okay"; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_i2c1 { ++ status = "okay"; ++}; ++ ++&cp0_pinctl { ++ /* MPP Bus: ++ * RGMII0 [0-11] ++ * SPI1 [13-16] ++ * SATA1 [28] ++ * UART0 [29-30] ++ * SMI [32,34] ++ * I2C1 [35-36] ++ * I2C0 [37-38] ++ * UART1 [47-49] ++ * UART0 [50-51] ++ * SD [56-61] ++ * GPIO [62] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 3 3 3 3 3 3 3 3 3 3 ++ 3 3 0 3 3 3 3 0 0 0 ++ 0 0 0 0 0 0 0 0 9 0xA ++ 0xA 0 7 0 7 2 2 2 2 0 ++ 0 0 0 0 1 1 1 7 1 7 ++ 6 6 1 1 0xA 1 0xE 0xE 0xE 0xE ++ 0xE 0xE 0>; ++}; ++ ++&cp0_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_spi0_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>, /* CS1 */ ++ <0 0xffffffff>, /* CS2 */ ++ <0 0xffffffff>; /* CS3 */ ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <0x1>; ++ #size-cells = <0x1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0x0>; ++ spi-max-frequency = <108000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0x0 0x200000>; ++ }; ++ ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xe00000>; ++ }; ++ }; ++ }; ++}; ++ ++&cp0_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_sata0 { ++ status = "okay"; ++}; ++ ++&cp0_usb3_0 { ++ status = "okay"; ++}; ++ ++&cp0_usb3_1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp0_utmi0 { ++ status = "okay"; ++}; ++ ++&cp0_utmi1 { ++ status = "okay"; ++}; ++ ++&cp0_sdhci0 { ++ status = "okay"; ++ bus-width = <4>; ++ no-1-8-v; ++ non-removable; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sgmii"; /* lane-2 */ ++}; ++ ++&cp0_eth1 { ++ status = "okay"; ++ phy = <&phy0>; ++ phy-mode = "rgmii-id"; /* lane-0 */ ++}; +diff --git a/arch/arm/dts/armada-7040-db-F.dts b/arch/arm/dts/armada-7040-db-F.dts +new file mode 100644 +index 0000000000..bba2cdf8da +--- /dev/null ++++ b/arch/arm/dts/armada-7040-db-F.dts +@@ -0,0 +1,235 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2020 Marvell International Ltd. ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada 7040 Development board platform ++ * Boot device: SPI NOR, 0x32 (SW3) ++ */ ++ ++#include "armada-70x0-db.dtsi" ++ ++/ { ++ model = "Marvell Armada 7040 Development Board DB-88FA7040 setup(F)"; ++ compatible = "marvell,armada7040-db", "marvell,armada7040", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp0_spi1; ++ fuse0 = &ap_hd_efuse0; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++}; ++ ++&ap_pinctl { ++ /* MPP Bus: ++ * SDIO [0-5] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 0 0 0 0 ++ 0 3 0 0 0 0 0 0 0 3 >; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_pcie2 { ++ status = "okay"; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_pinctl { ++ /* MPP Bus: ++ * SPI [13-16] ++ * SATA1 [28] ++ * UART0 [29-30] ++ * SMI [32,34] ++ * XSMI [35-36] ++ * I2C [37-38] ++ * RGMII [44-55] ++ * SD [56-61] ++ * GPIO [62] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 3 3 3 3 0 0 0 ++ 0 0 0 0 0 0 0 0 9 0xA ++ 0xA 0 7 0 7 7 7 2 2 0 ++ 0 0 0 0 1 1 1 1 1 1 ++ 1 1 1 1 1 1 0xE 0xE 0xE 0xE ++ 0xE 0xE 0>; ++}; ++ ++&cp0_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_spi0_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>, /* CS1 */ ++ <0 0xffffffff>, /* CS2 */ ++ <0 0xffffffff>; /* CS3 */ ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <0x1>; ++ #size-cells = <0x1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0x0>; ++ spi-max-frequency = <108000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0x0 0x200000>; ++ }; ++ ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xe00000>; ++ }; ++ }; ++ }; ++}; ++ ++&cp0_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_sata0 { ++ status = "okay"; ++}; ++ ++&cp0_usb3_0 { ++ status = "okay"; ++}; ++ ++&cp0_usb3_1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { ++ phy0 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp0_utmi0 { ++ status = "okay"; ++}; ++ ++&cp0_utmi1 { ++ status = "okay"; ++}; ++ ++&ap_sdhci0 { ++ status = "okay"; ++ bus-width = <4>; ++ no-1-8-v; ++ non-removable; ++}; ++ ++&cp0_sdhci0 { ++ status = "okay"; ++ bus-width = <4>; ++ no-1-8-v; ++ non-removable; ++}; ++ ++&cp0_mdio { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "okay"; ++ ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-2 */ ++}; ++ ++&cp0_eth1 { ++ status = "okay"; ++ phy-mode = "sgmii-2500"; /* lane-0 */ ++ ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ }; ++}; ++ ++&cp0_eth2 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "rgmii-id"; ++}; +diff --git a/arch/arm/dts/armada-7040-db-nand.dts b/arch/arm/dts/armada-7040-db-nand.dts +deleted file mode 100644 +index 3a9df21a8c..0000000000 +--- a/arch/arm/dts/armada-7040-db-nand.dts ++++ /dev/null +@@ -1,223 +0,0 @@ +-/* +- * Copyright (C) 2017 Marvell Technology Group Ltd. +- * +- * This file is dual-licensed: you can use it either under the terms +- * of the GPLv2 or the X11 license, at your option. Note that this dual +- * licensing only applies to this file, and not this project as a +- * whole. +- * +- * a) This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License as +- * published by the Free Software Foundation; either version 2 of the +- * License, or (at your option) any later version. +- * +- * This library is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * Or, alternatively, +- * +- * b) Permission is hereby granted, free of charge, to any person +- * obtaining a copy of this software and associated documentation +- * files (the "Software"), to deal in the Software without +- * restriction, including without limitation the rights to use, +- * copy, modify, merge, publish, distribute, sublicense, and/or +- * sell copies of the Software, and to permit persons to whom the +- * Software is furnished to do so, subject to the following +- * conditions: +- * +- * The above copyright notice and this permission notice shall be +- * included in all copies or substantial portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +- * OTHER DEALINGS IN THE SOFTWARE. +- */ +- +-/* +- * Device Tree file for Marvell Armada 7040 Development board platform +- * Boot device: NAND, 0xE (SW3) +- */ +- +-#include "armada-7040.dtsi" +- +-/ { +- model = "Marvell Armada 7040 DB board with NAND"; +- compatible = "marvell,armada7040-db-nand", "marvell,armada7040-db", +- "marvell,armada7040", "marvell,armada-ap806-quad", +- "marvell,armada-ap806"; +- +- chosen { +- stdout-path = "serial0:115200n8"; +- }; +- +- aliases { +- i2c0 = &cpm_i2c0; +- spi0 = &cpm_spi1; +- }; +- +- memory@00000000 { +- device_type = "memory"; +- reg = <0x0 0x0 0x0 0x80000000>; +- }; +-}; +- +-&ap_pinctl { +- /* MPP Bus: +- * SDIO [0-5] +- * UART0 [11,19] +- */ +- /* 0 1 2 3 4 5 6 7 8 9 */ +- pin-func = < 0x1 0x1 0x1 0x1 0x1 0x1 0x0 0x0 0x0 0x0 +- 0x0 0x3 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x3 >; +-}; +- +-&uart0 { +- status = "okay"; +-}; +- +- +-&cpm_pcie2 { +- status = "okay"; +-}; +- +-&cpm_i2c0 { +- pinctrl-names = "default"; +- pinctrl-0 = <&cpm_i2c0_pins>; +- status = "okay"; +- clock-frequency = <100000>; +-}; +- +-&cpm_pinctl { +- /* MPP Bus: +- * AUDIO [0-5] +- * GBE [6-11] +- * SS_PWDN [12] +- * NF_RBn [13] +- * GPIO [14] +- * DEV_BUS [15-27] +- * SATA1 [28] +- * UART0 [29-30] +- * MSS_VTT_EN [31] +- * SMI [32,34] +- * XSMI [35-36] +- * I2C [37-38] +- * RGMII1 [44-55] +- * SD [56-61] +- * GPIO [62] +- */ +- /* 0 1 2 3 4 5 6 7 8 9 */ +- pin-func = < 0x2 0x2 0x2 0x2 0x2 0x2 0x3 0x3 0x3 0x3 +- 0x3 0x3 0x0 0x2 0x0 0x1 0x1 0x1 0x1 0x1 +- 0x1 0x1 0x1 0x1 0x1 0x1 0x1 0x1 0x9 0xa +- 0xa 0x0 0x7 0x0 0x7 0x7 0x7 0x2 0x2 0x0 +- 0x0 0x0 0x0 0x0 0x1 0x1 0x1 0x1 0x1 0x1 +- 0x1 0x1 0x1 0x1 0x1 0x1 0xe 0xe 0xe 0xe +- 0xe 0xe 0x0>; +-}; +- +-&cpm_spi1 { +- pinctrl-names = "default"; +- pinctrl-0 = <&cpm_spi0_pins>; +- status = "disabled"; +- +- spi-flash@0 { +- #address-cells = <0x1>; +- #size-cells = <0x1>; +- compatible = "jedec,spi-nor"; +- reg = <0x0>; +- spi-max-frequency = <20000000>; +- +- partitions { +- compatible = "fixed-partitions"; +- #address-cells = <1>; +- #size-cells = <1>; +- +- partition@0 { +- label = "U-Boot"; +- reg = <0x0 0x200000>; +- }; +- +- partition@400000 { +- label = "Filesystem"; +- reg = <0x200000 0xe00000>; +- }; +- }; +- }; +-}; +- +-&cpm_sata0 { +- status = "okay"; +-}; +- +-&cpm_usb3_0 { +- status = "okay"; +-}; +- +-&cpm_usb3_1 { +- status = "okay"; +-}; +- +-&cpm_comphy { +- phy0 { +- phy-type = ; +- phy-speed = ; +- }; +- +- phy1 { +- phy-type = ; +- phy-speed = ; +- }; +- +- phy2 { +- phy-type = ; +- phy-speed = ; +- }; +- +- phy3 { +- phy-type = ; +- phy-speed = ; +- }; +- +- phy4 { +- phy-type = ; +- phy-speed = ; +- }; +- +- phy5 { +- phy-type = ; +- phy-speed = ; +- }; +-}; +- +-&cpm_nand { +- status = "okay"; +-}; +- +-&cpm_utmi0 { +- status = "okay"; +-}; +- +-&cpm_utmi1 { +- status = "okay"; +-}; +- +-&ap_sdhci0 { +- status = "okay"; +- bus-width = <4>; +- no-1-8-v; +- non-removable; +-}; +- +-&cpm_sdhci0 { +- status = "okay"; +- bus-width = <4>; +- no-1-8-v; +- non-removable; +-}; +diff --git a/arch/arm/dts/armada-7040-db.dts b/arch/arm/dts/armada-7040-db.dts +index cfd2b4baf3..170b8553c9 100644 +--- a/arch/arm/dts/armada-7040-db.dts ++++ b/arch/arm/dts/armada-7040-db.dts +@@ -45,10 +45,10 @@ + * Boot device: SPI NOR, 0x32 (SW3) + */ + +-#include "armada-7040.dtsi" ++#include "armada-70x0-db.dtsi" + + / { +- model = "Marvell Armada 7040 DB board"; ++ model = "Marvell Armada 7040 Development Board DB-88FA7040"; + compatible = "marvell,armada7040-db", "marvell,armada7040", + "marvell,armada-ap806-quad", "marvell,armada-ap806"; + +@@ -57,8 +57,13 @@ + }; + + aliases { +- i2c0 = &cpm_i2c0; +- spi0 = &cpm_spi1; ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp0_spi1; ++ fuse0 = &ap_hd_efuse0; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; + }; + + memory@00000000 { +@@ -81,51 +86,67 @@ + status = "okay"; + }; + ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; + +-&cpm_pcie2 { ++&cp0_pcie2 { + status = "okay"; + }; + +-&cpm_i2c0 { ++&cp0_i2c0 { + pinctrl-names = "default"; +- pinctrl-0 = <&cpm_i2c0_pins>; ++ pinctrl-0 = <&cp0_i2c0_pins>; + status = "okay"; + clock-frequency = <100000>; + }; + +-&cpm_pinctl { ++&cp0_pinctl { + /* MPP Bus: +- * TDM [0-11] + * SPI [13-16] + * SATA1 [28] + * UART0 [29-30] + * SMI [32,34] + * XSMI [35-36] + * I2C [37-38] +- * RGMII1[44-55] +- * SD [56-62] ++ * RGMII [44-55] ++ * SD [56-61] ++ * GPIO [62] + */ + /* 0 1 2 3 4 5 6 7 8 9 */ +- pin-func = < 4 4 4 4 4 4 4 4 4 4 +- 4 4 0 3 3 3 3 0 0 0 ++ pin-func = < 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 3 3 3 3 0 0 0 + 0 0 0 0 0 0 0 0 9 0xA + 0xA 0 7 0 7 7 7 2 2 0 + 0 0 0 0 1 1 1 1 1 1 + 1 1 1 1 1 1 0xE 0xE 0xE 0xE +- 0xE 0xE 0xE >; ++ 0xE 0xE 0>; + }; + +-&cpm_spi1 { ++&cp0_spi1 { + pinctrl-names = "default"; +- pinctrl-0 = <&cpm_spi0_pins>; ++ pinctrl-0 = <&cp0_spi0_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>, /* CS1 */ ++ <0 0xffffffff>, /* CS2 */ ++ <0 0xffffffff>; /* CS3 */ + status = "okay"; + + spi-flash@0 { + #address-cells = <0x1>; + #size-cells = <0x1>; +- compatible = "jedec,spi-nor"; ++ compatible = "jedec,spi-nor", "spi-flash"; + reg = <0x0>; +- spi-max-frequency = <20000000>; ++ spi-max-frequency = <108000000>; + + partitions { + compatible = "fixed-partitions"; +@@ -145,54 +166,59 @@ + }; + }; + +-&cpm_sata0 { ++&cp0_ld_efuse0 { + status = "okay"; + }; + +-&cpm_usb3_0 { ++&cp0_ld_efuse1 { + status = "okay"; + }; + +-&cpm_usb3_1 { ++&cp0_sata0 { + status = "okay"; + }; + +-&cpm_comphy { ++&cp0_usb3_0 { ++ status = "okay"; ++}; ++ ++&cp0_usb3_1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { + phy0 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; ++ phy-speed = ; + }; + + phy1 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; + }; + + phy2 { +- phy-type = ; ++ phy-type = ; ++ phy-speed = ; + }; + + phy3 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; + }; + + phy4 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; + }; + + phy5 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; + }; + }; + +-&cpm_utmi0 { ++&cp0_utmi0 { + status = "okay"; + }; + +-&cpm_utmi1 { ++&cp0_utmi1 { + status = "okay"; + }; + +@@ -203,14 +229,15 @@ + non-removable; + }; + +-&cpm_sdhci0 { ++&cp0_sdhci0 { + status = "okay"; + bus-width = <4>; + no-1-8-v; + non-removable; + }; + +-&cpm_mdio { ++&cp0_mdio { ++ status = "okay"; + phy0: ethernet-phy@0 { + reg = <0>; + }; +@@ -219,22 +246,22 @@ + }; + }; + +-&cpm_ethernet { ++&cp0_ethernet { + status = "okay"; + }; + +-&cpm_eth0 { ++&cp0_eth0 { + status = "okay"; + phy-mode = "sfi"; /* lane-2 */ + }; + +-&cpm_eth1 { ++&cp0_eth1 { + status = "okay"; + phy = <&phy0>; +- phy-mode = "sgmii"; ++ phy-mode = "sgmii"; /* lane-0 */ + }; + +-&cpm_eth2 { ++&cp0_eth2 { + status = "okay"; + phy = <&phy1>; + phy-mode = "rgmii-id"; +diff --git a/arch/arm/dts/armada-7040-dev-info.dtsi b/arch/arm/dts/armada-7040-dev-info.dtsi +new file mode 100644 +index 0000000000..42b63f0968 +--- /dev/null ++++ b/arch/arm/dts/armada-7040-dev-info.dtsi +@@ -0,0 +1,73 @@ ++/* ++ * *************************************************************************** ++ * Copyright (C) 2017 Marvell International Ltd. ++ * *************************************************************************** ++ * This program is free software: you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the Free ++ * Software Foundation, either version 2 of the License, or any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ * *************************************************************************** ++ */ ++ ++/ { ++ /* This should go only into devel boards */ ++ compatible = "marvell,cp110"; ++ sar { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ sar_fields { ++ compatible = "marvell,sample-at-reset"; ++ reg = <0x4c 0x4e>; ++ chip_count = <2>; ++ bit_width = <5>; ++ ++ freq { ++ key = "freq"; ++ description = "CPU/DDR frequencies"; ++ start-bit = <0>; ++ bit-length = <3>; ++ option-cnt = <7>; ++ options = "0x0", "1600/800 Mhz", ++ "0x2", "1000/650 Mhz", ++ "0x3", "1200/800 Mhz", ++ "0x4", "1400/800 Mhz", ++ "0x5", "600/800 Mhz", ++ "0x6", "800/800 Mhz", ++ "0x7", "1000/800 Mhz"; ++ default = <0x3>; ++ status = "okay"; ++ }; ++ boot_mode { ++ key = "boot_mode"; ++ description = "Boot mode options"; ++ start-bit = <4>; ++ bit-length = <6>; ++ option-cnt = <14>; ++ options = "0xE", "NAND IHB BW-8bit, PS-4KB, ECC-4bit", ++ "0xF", "NAND IHB BW-8bit, PS-4KB, ECC-8bit", ++ "0x28", "AP_SD", ++ "0x29", "CP_SD", ++ "0x2A", "AP_EMMC", ++ "0x2B", "CP_EMMC", ++ "0x30", "AP_SPI 24bits", ++ "0x31", "AP SPI BR-Disabled 24bits", ++ "0x32", "CP_SPI_1 24bits", ++ "0x33", "CP_SPI_1 32bits", ++ "0x34", "CP_SPI_0 24bits", ++ "0x35", "CP_SPI_0 32bits", ++ "0x36", "CP_SPI_1 BR-Disabled 24bits", ++ "0x37", "CP_SPI_1 BR-Disabled 32bits"; ++ default = <0x32>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/armada-7040-pcac.dts b/arch/arm/dts/armada-7040-pcac.dts +new file mode 100644 +index 0000000000..3b429a5178 +--- /dev/null ++++ b/arch/arm/dts/armada-7040-pcac.dts +@@ -0,0 +1,222 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada 7040 Development board platform ++ * Boot device: SPI NOR, 0x32 (SW3) ++ */ ++ ++#include "armada-70x0-db.dtsi" ++ ++/ { ++ model = "Marvell Armada 7040 Development Board DB-88FA7040-PCAC"; ++ compatible = "marvell, armada7040-pcac", "marvell,armada7040", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806"; ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp0_spi1; ++ fuse0 = &ap_hd_efuse0; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++ ++ simple-bus { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ reg_usb3h1_current_limiter: usb3-current-limiter1 { ++ compatible = "regulator-fixed"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_xhci_vbus_pins>; ++ regulator-name = "reg-usb3h1-current-limiter"; ++ regulator-min-microvolt = <900000>; ++ regulator-max-microvolt = <900000>; ++ regulator-force-boot-off; ++ gpio = <&cp0_gpio1 14 GPIO_ACTIVE_HIGH>; /* GPIO[46] */ ++ }; ++ }; ++}; ++ ++&ap_pinctl { ++ /* MPP Bus: ++ * SDIO [0-10] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 1 1 1 1 ++ 1 3 0 0 0 0 0 0 0 3 >; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_pinctl { ++ /* MPP Bus: ++ * RGMII0[0-11] ++ * SPI [13-16] ++ * SATA1 [28] ++ * UART0 [29-30] ++ * PCI_RST [31] ++ * SMI [32,34] ++ * XSMI [35-36] ++ * I2C [37-38] ++ * UART1 [40-41] ++ * USB CURRENT-LIMIT [46] ++ * UART2 [50-51] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 3 3 3 3 3 3 3 3 3 3 ++ 3 3 0 3 3 3 3 0 0 0 ++ 0 0 0 0 0 0 0 0 9 0xA ++ 0xA 6 7 0 7 0 0 2 2 0 ++ 0 0 0 0 0 0 0 7 0 7 ++ 6 6 0 0 0 0 0 0 0 0 ++ 0 0 0>; ++ ++ cp0_xhci_vbus_pins: cp0-xhci-vbus-pins { ++ marvell,pins = < 46 >; ++ marvell,function = <0>; ++ }; ++}; ++ ++&cp0_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_spi0_pins>; ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <0x1>; ++ #size-cells = <0x1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0x0>; ++ spi-max-frequency = <108000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0x0 0x200000>; ++ }; ++ ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xe00000>; ++ }; ++ }; ++ }; ++}; ++ ++&cp0_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_sata0 { ++ status = "okay"; ++}; ++ ++&cp0_usb3_1 { ++ vbus-supply = <®_usb3h1_current_limiter>; ++ status = "okay"; ++}; ++ ++&cp0_comphy { ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&ap_sdhci0 { ++ ++ status = "okay"; ++ bus-width = <4>; ++ no-1-8-v; ++ non-removable; ++}; ++ ++&cp0_utmi0 { ++ status = "okay"; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ phy0: ethernet-phy@0 { ++ reg = <1>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-4*/ ++}; ++ ++&cp0_eth1 { ++ status = "okay"; ++ phy = <&phy0>; ++ phy-mode = "rgmii-id"; /* rgmii-0*/ ++}; +diff --git a/arch/arm/dts/armada-7040.dtsi b/arch/arm/dts/armada-7040.dtsi +deleted file mode 100644 +index b5be0c4652..0000000000 +--- a/arch/arm/dts/armada-7040.dtsi ++++ /dev/null +@@ -1,56 +0,0 @@ +-/* +- * Copyright (C) 2016 Marvell Technology Group Ltd. +- * +- * This file is dual-licensed: you can use it either under the terms +- * of the GPLv2 or the X11 license, at your option. Note that this dual +- * licensing only applies to this file, and not this project as a +- * whole. +- * +- * a) This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License as +- * published by the Free Software Foundation; either version 2 of the +- * License, or (at your option) any later version. +- * +- * This library is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * Or, alternatively, +- * +- * b) Permission is hereby granted, free of charge, to any person +- * obtaining a copy of this software and associated documentation +- * files (the "Software"), to deal in the Software without +- * restriction, including without limitation the rights to use, +- * copy, modify, merge, publish, distribute, sublicense, and/or +- * sell copies of the Software, and to permit persons to whom the +- * Software is furnished to do so, subject to the following +- * conditions: +- * +- * The above copyright notice and this permission notice shall be +- * included in all copies or substantial portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +- * OTHER DEALINGS IN THE SOFTWARE. +- */ +- +-/* +- * Device Tree file for the Armada 7040 SoC, made of an AP806 Quad and +- * one CP110. +- */ +- +-#include +-#include "armada-ap806-quad.dtsi" +-#include "armada-cp110-master.dtsi" +- +-/ { +- model = "Marvell Armada 7040"; +- compatible = "marvell,armada7040", "marvell,armada-ap806-quad", +- "marvell,armada-ap806"; +-}; +diff --git a/arch/arm/dts/armada-70x0-db.dtsi b/arch/arm/dts/armada-70x0-db.dtsi +new file mode 100644 +index 0000000000..02db64794c +--- /dev/null ++++ b/arch/arm/dts/armada-70x0-db.dtsi +@@ -0,0 +1,90 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#include "armada-70x0.dtsi" /* include SoC device tree */ ++#include "armada-7040-dev-info.dtsi" ++ ++#define CP110_NUM 0 ++#define SPI_DIRECT_BASE (0xf9000000) ++ ++/ { ++ model = "DB-ARMADA-70x0"; ++ compatible = "marvell,armada-70x0-db", "marvell,armada-70x0"; ++ ++ cp0 { ++ config-space { ++ ranges = <0x0 U64_TO_U32_H(CP110_BASE) U64_TO_U32_L(CP110_BASE) 0x2000000>, /* internal regs */ ++ <0x2000000 U64_TO_U32_H(SPI_DIRECT_BASE) U64_TO_U32_L(SPI_DIRECT_BASE) 0x1000000>; /* SPI1-DEV0 */ ++ i2c@701000 { ++ expander0: pca953x@21 { ++ compatible = "nxp,pca9555"; ++ #gpio-cells = <2>; ++ reg = <0x21>; ++ status = "okay"; ++ }; ++ }; ++ ++ sdhci@780000 { ++ vqmmc-supply = <&cp0_reg_sd_vccq>; ++ }; ++ ++ cp0_reg_usb3_vbus0:cp0_usb3_vbus@0 { ++ compatible = "regulator-fixed"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <100000>; ++ regulator-force-boot-off; ++ gpio = <&expander0 0 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ cp0_reg_usb3_vbus1: cp0_usb3_vbus@1 { ++ compatible = "regulator-fixed"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <100000>; ++ regulator-force-boot-off; ++ gpio = <&expander0 1 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ cp0_reg_usb3_current_limiter0:cp0_usb3_current_limiter@0 { ++ compatible = "regulator-fixed"; ++ regulator-min-microamp = <900000>; ++ regulator-max-microamp = <900000>; ++ regulator-force-boot-off; ++ gpio = <&expander0 4 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ cp0_reg_usb3_current_limiter1: cp0_usb3_current_limiter@1 { ++ compatible = "regulator-fixed"; ++ regulator-min-microamp = <900000>; ++ regulator-max-microamp = <900000>; ++ regulator-force-boot-off; ++ gpio = <&expander0 5 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ cp0_usb3_0: usb3@500000 { ++ vbus-supply = <&cp0_reg_usb3_vbus0>; ++ current-limiter = <&cp0_reg_usb3_current_limiter0>; ++ vbus-disable-delay = <500>; ++ }; ++ ++ cp0_usb3_1: usb3@510000 { ++ vbus-supply = <&cp0_reg_usb3_vbus1>; ++ current-limiter = <&cp0_reg_usb3_current_limiter1>; ++ vbus-disable-delay = <500>; ++ }; ++ ++ cp0_reg_sd_vccq: cp0_sd_vccq@0 { ++ compatible = "regulator-gpio"; ++ regulator-name = "cp0_sd_vcc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ gpios = <&expander0 15 GPIO_ACTIVE_HIGH>; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/armada-70x0.dtsi b/arch/arm/dts/armada-70x0.dtsi +new file mode 100644 +index 0000000000..d6b9cab366 +--- /dev/null ++++ b/arch/arm/dts/armada-70x0.dtsi +@@ -0,0 +1,69 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++/* ++ * Device Tree file for the Armada 7040 SoC, made of an AP806 Quad and ++ * one CP110. ++ */ ++ ++#include ++#include "armada-common.dtsi" ++#include "armada-8k.dtsi" ++#include "armada-ap806.dtsi" ++#include "armada-ap80x-quad.dtsi" ++ ++/* CP110-0 Settings */ ++#define CP110_NAME cp0 ++#define CP110_NUM 0 ++ ++#include "armada-cp110.dtsi" ++ ++#undef CP110_NAME ++#undef CP110_NUM ++ ++/ { ++ model = "Marvell Armada 7040"; ++ compatible = "marvell,armada7040", "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++}; ++ ++&cp0_rtc { ++ status = "okay"; ++}; ++ ++&cp0_pinctl { ++ compatible = "marvell,mvebu-pinctrl", "marvell,armada-7k-pinctrl"; ++ bank-name ="cp0-110"; ++ ++ cp0_i2c0_pins: cp0-i2c-pins-0 { ++ marvell,pins = < 37 38 >; ++ marvell,function = <2>; ++ }; ++ cp0_i2c1_pins: cp0-i2c-pins-1 { ++ marvell,pins = < 35 36 >; ++ marvell,function = <2>; ++ }; ++ cp0_ge1_rgmii_pins: cp0-ge-rgmii-pins-0 { ++ marvell,pins = < 0 1 2 3 4 5 6 7 8 9 10 11>; ++ marvell,function = <3>; ++ }; ++ cp0_ge2_rgmii_pins: cp0-ge-rgmii-pins-1 { ++ marvell,pins = < 44 45 46 47 48 49 50 51 ++ 52 53 54 55 >; ++ marvell,function = <1>; ++ }; ++ cp0_pca0_pins: cp0-pca0_pins { ++ marvell,pins = <62>; ++ marvell,function = <0>; ++ }; ++ cp0_sdhci_pins: cp0-sdhi-pins-0 { ++ marvell,pins = < 56 57 58 59 60 61 >; ++ marvell,function = <14>; ++ }; ++ cp0_spi0_pins: cp0-spi-pins-0 { ++ marvell,pins = < 13 14 15 16 >; ++ marvell,function = <3>; ++ }; ++}; +diff --git a/arch/arm/dts/armada-8020.dtsi b/arch/arm/dts/armada-8020.dtsi +index 048e5cf516..3f33e78e0b 100644 +--- a/arch/arm/dts/armada-8020.dtsi ++++ b/arch/arm/dts/armada-8020.dtsi +@@ -45,12 +45,82 @@ + * two CP110. + */ + ++#include ++#include "armada-common.dtsi" + #include "armada-ap806-dual.dtsi" +-#include "armada-cp110-master.dtsi" +-#include "armada-cp110-slave.dtsi" ++ ++#define CP110_NAME cp0 ++#define CP110_BASE 0xf2000000 ++#define CP110_PCIE_MEM_BASE 0xf6000000 ++#define CP110_PCIE_MEM_OFFSET 0x1000000 ++ ++#include "armada-cp110.dtsi" ++ ++#undef CP110_NAME ++#undef CP110_BASE ++#undef CP110_PCIE_MEM_BASE ++ ++#define CP110_NAME cp1 ++#define CP110_BASE 0xf4000000 ++#define CP110_PCIE_MEM_BASE 0xfa000000 ++ ++#include "armada-cp110.dtsi" ++ ++#undef CP110_NAME ++#undef CP110_BASE ++#undef CP110_PCIE_MEM_BASE + + / { + model = "Marvell Armada 8020"; + compatible = "marvell,armada8020", "marvell,armada-ap806-dual", + "marvell,armada-ap806"; + }; ++ ++&cp0_pinctl { ++ compatible = "marvell,mvebu-pinctrl", "marvell,armada-8k-cpm-pinctrl"; ++ bank-name ="cp0-110"; ++ ++ cp0_i2c0_pins: cp0-i2c-pins-0 { ++ marvell,pins = < 37 38 >; ++ marvell,function = <2>; ++ }; ++ cp0_i2c1_pins: cp0-i2c-pins-1 { ++ marvell,pins = < 35 36 >; ++ marvell,function = <2>; ++ }; ++ cp0_ge1_rgmii_pins: cp0-ge-rgmii-pins-0 { ++ marvell,pins = < 0 1 2 3 4 5 6 7 8 9 10 11>; ++ marvell,function = <3>; ++ }; ++ cp0_ge2_rgmii_pins: cp0-ge-rgmii-pins-1 { ++ marvell,pins = < 44 45 46 47 48 49 50 51 ++ 52 53 54 55 >; ++ marvell,function = <1>; ++ }; ++ cp0_pca0_pins: cp0-pca0_pins { ++ marvell,pins = <62>; ++ marvell,function = <0>; ++ }; ++ cp0_sdhci_pins: cp0-sdhi-pins-0 { ++ marvell,pins = < 56 57 58 59 60 61 >; ++ marvell,function = <14>; ++ }; ++ cp0_spi0_pins: cp0-spi-pins-0 { ++ marvell,pins = < 13 14 15 16 >; ++ marvell,function = <3>; ++ }; ++}; ++ ++&cp1_pinctl { ++ compatible = "marvell,mvebu-pinctrl", "marvell,armada-8k-cps-pinctrl"; ++ bank-name ="cp1-110"; ++ ++ cp1_ge1_rgmii_pins: cp1-ge-rgmii-pins-0 { ++ marvell,pins = < 0 1 2 3 4 5 6 7 8 9 10 11 >; ++ marvell,function = <3>; ++ }; ++ cp1_spi1_pins: cp1-spi-pins-1 { ++ marvell,pins = < 13 14 15 16 >; ++ marvell,function = <3>; ++ }; ++}; +diff --git a/arch/arm/dts/armada-8040-clearfog-gt-8k.dts b/arch/arm/dts/armada-8040-clearfog-gt-8k.dts +index 720c95082b..5db5bb8bea 100644 +--- a/arch/arm/dts/armada-8040-clearfog-gt-8k.dts ++++ b/arch/arm/dts/armada-8040-clearfog-gt-8k.dts +@@ -15,9 +15,9 @@ + }; + + aliases { +- i2c0 = &cpm_i2c0; +- i2c1 = &cpm_i2c1; +- spi0 = &cps_spi1; ++ i2c0 = &cp0_i2c0; ++ i2c1 = &cp0_i2c1; ++ spi0 = &cp1_spi1; + }; + + memory@00000000 { +@@ -31,14 +31,14 @@ + reg_usb3h0_vbus: usb3-vbus0 { + compatible = "regulator-fixed"; + pinctrl-names = "default"; +- pinctrl-0 = <&cpm_xhci_vbus_pins>; ++ pinctrl-0 = <&cp0_xhci_vbus_pins>; + regulator-name = "reg-usb3h0-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + startup-delay-us = <300000>; + shutdown-delay-us = <500000>; + regulator-force-boot-off; +- gpio = <&cpm_gpio1 15 GPIO_ACTIVE_LOW>; /* GPIO[47] */ ++ gpio = <&cp0_gpio1 15 GPIO_ACTIVE_LOW>; /* GPIO[47] */ + }; + }; + }; +@@ -66,7 +66,7 @@ + status = "okay"; + }; + +-&cpm_pinctl { ++&cp0_pinctl { + /* + * MPP Bus: + * [0-31] = 0xff: Keep default CP0_shared_pins: +@@ -99,111 +99,111 @@ + 0 0 0 0 0 0 0xe 0xe 0xe 0xe + 0xe 0xe 0 >; + +- cpm_pcie_reset_pins: cpm-pcie-reset-pins { ++ cp0_pcie_reset_pins: cp0-pcie-reset-pins { + marvell,pins = < 32 >; + marvell,function = <0>; + }; + +- cpm_xhci_vbus_pins: cpm-xhci-vbus-pins { ++ cp0_xhci_vbus_pins: cp0-xhci-vbus-pins { + marvell,pins = < 47 >; + marvell,function = <0>; + }; + +- cps_1g_phy_reset: cps-1g-phy-reset { ++ cp1_1g_phy_reset: cp1-1g-phy-reset { + marvell,pins = < 43 >; + marvell,function = <0>; + }; + }; + + /* uSD slot */ +-&cpm_sdhci0 { ++&cp0_sdhci0 { + pinctrl-names = "default"; +- pinctrl-0 = <&cpm_sdhci_pins>; ++ pinctrl-0 = <&cp0_sdhci_pins>; + bus-width = <4>; + status = "okay"; + }; + +-&cpm_pcie0 { ++&cp0_pcie0 { + num-lanes = <1>; + pinctrl-names = "default"; +- pinctrl-0 = <&cpm_pcie_reset_pins>; +- marvell,reset-gpio = <&cpm_gpio1 0 GPIO_ACTIVE_LOW>; ++ pinctrl-0 = <&cp0_pcie_reset_pins>; ++ marvell,reset-gpio = <&cp0_gpio1 0 GPIO_ACTIVE_LOW>; + status = "okay"; + }; + +-&cpm_i2c0 { ++&cp0_i2c0 { + pinctrl-names = "default"; +- pinctrl-0 = <&cpm_i2c0_pins>; ++ pinctrl-0 = <&cp0_i2c0_pins>; + status = "okay"; + clock-frequency = <100000>; + }; + +-&cpm_i2c1 { ++&cp0_i2c1 { + pinctrl-names = "default"; +- pinctrl-0 = <&cpm_i2c1_pins>; ++ pinctrl-0 = <&cp0_i2c1_pins>; + status = "okay"; + clock-frequency = <100000>; + }; + +-&cpm_sata0 { ++&cp0_sata0 { + status = "okay"; + }; + +-&cpm_comphy { ++&cp0_comphy { + /* + * CP0 Serdes Configuration: + * Lane 0: PCIe0 (x1) + * Lane 1: Not connected +- * Lane 2: SFI (10G) ++ * Lane 2: SFI0 (10G) + * Lane 3: Not connected + * Lane 4: USB 3.0 host port1 (can be PCIe) + * Lane 5: Not connected + */ + phy0 { +- phy-type = ; ++ phy-type = ; + }; + phy1 { +- phy-type = ; ++ phy-type = ; + }; + phy2 { +- phy-type = ; ++ phy-type = ; + }; + phy3 { +- phy-type = ; ++ phy-type = ; + }; + phy4 { +- phy-type = ; ++ phy-type = ; + }; + phy5 { +- phy-type = ; ++ phy-type = ; + }; + }; + +-&cpm_ethernet { ++&cp0_ethernet { + pinctrl-names = "default"; + status = "okay"; + }; + + /* 10G SFI SFP */ +-&cpm_eth0 { ++&cp0_eth0 { + status = "okay"; + phy-mode = "sfi"; + }; + +-&cps_sata0 { ++&cp1_sata0 { + status = "okay"; + }; + +-&cps_usb3_0 { ++&cp1_usb3_0 { + vbus-supply = <®_usb3h0_vbus>; + status = "okay"; + }; + +-&cps_utmi0 { ++&cp1_utmi0 { + status = "okay"; + }; + +-&cps_pinctl { ++&cp1_pinctl { + /* + * MPP Bus: + * [0-5] TDM +@@ -234,9 +234,9 @@ + 0xff 0xff 0xff>; + }; + +-&cps_spi1 { ++&cp1_spi1 { + pinctrl-names = "default"; +- pinctrl-0 = <&cps_spi1_pins>; ++ pinctrl-0 = <&cp1_spi1_pins>; + status = "okay"; + + spi-flash@0 { +@@ -261,7 +261,7 @@ + }; + }; + +-&cps_comphy { ++&cp1_comphy { + /* + * CP1 Serdes Configuration: + * Lane 0: SATA 1 (RX swapped). Can be PCIe0 +@@ -272,52 +272,51 @@ + * Lane 5: SGMII2 - Connected to Topaz switch + */ + phy0 { +- phy-type = ; +- phy-invert = ; ++ phy-type = ; ++ phy-invert = ; + }; + phy1 { +- phy-type = ; ++ phy-type = ; + }; + phy2 { +- phy-type = ; ++ phy-type = ; + }; + phy3 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; ++ phy-speed = ; + }; + phy4 { +- phy-type = ; ++ phy-type = ; + }; + phy5 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; ++ phy-speed = ; + }; + }; + +-&cps_mdio { ++&cp1_mdio { + phy0: ethernet-phy@0 { + reg = <0>; + }; + }; + +-&cps_ethernet { ++&cp1_ethernet { + pinctrl-names = "default"; +- pinctrl-0 = <&cps_1g_phy_reset>; ++ pinctrl-0 = <&cp1_1g_phy_reset>; + status = "okay"; + }; + + /* 1G SGMII */ +-&cps_eth1 { ++&cp1_eth1 { + status = "okay"; + phy-mode = "sgmii"; + phy = <&phy0>; +- phy-reset-gpios = <&cpm_gpio1 11 GPIO_ACTIVE_LOW>; ++ phy-reset-gpios = <&cp0_gpio1 11 GPIO_ACTIVE_LOW>; + }; + + /* 2.5G to Topaz switch */ +-&cps_eth2 { ++&cp1_eth2 { + status = "okay"; +- phy-mode = "sgmii"; +- phy-speed = <2500>; +- phy-reset-gpios = <&cps_gpio0 24 GPIO_ACTIVE_LOW>; ++ phy-mode = "sgmii-2500"; ++ phy-reset-gpios = <&cp1_gpio0 24 GPIO_ACTIVE_LOW>; + }; +diff --git a/arch/arm/dts/armada-8040-db-B.dts b/arch/arm/dts/armada-8040-db-B.dts +new file mode 100644 +index 0000000000..74f9fc2ef1 +--- /dev/null ++++ b/arch/arm/dts/armada-8040-db-B.dts +@@ -0,0 +1,339 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada 8040 Development board platform ++ */ ++ ++#include "armada-80x0-db.dtsi" ++ ++/ { ++ model = "Marvell Armada 8040 Development Board DB-88F8040 setup(B)"; ++ compatible = "marvell,armada8040-db", "marvell,armada8040", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp1_spi1; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; ++ fuse5 = &cp1_ld_efuse0; ++ fuse6 = &cp1_ld_efuse1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++}; ++ ++/* Accessible over the mini-USB CON9 connector on the main board */ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&ap_pinctl { ++ /* MPP Bus: ++ * SDIO [0-10] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 1 1 1 1 ++ 1 3 0 0 0 0 0 0 0 3 >; ++}; ++ ++&ap_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ap_emmc_pins>; ++ bus-width = <8>; ++ status = "okay"; ++}; ++ ++&cp0_pinctl { ++ /* MPP Bus: ++ * [0-31] = 0xff: Keep default CP0_shared_pins ++ * [11] CLKOUT_MPP_11 (out) ++ * [23] LINK_RD_IN_CP2CP (in) ++ * [25] CLKOUT_MPP_25 (out) ++ * [29] AVS_FB_IN_CP2CP (in) ++ * [32,34] GE_MDIO/MDC ++ * [33] GPIO: GE_INT#/push button/Wake ++ * [35] MSS_GPIO[3]: MSS_PWDN ++ * [36] MSS_GPIO[5]: MSS_VTT_EN ++ * [37-38] I2C0 ++ * [39] PTP_CLK ++ * [40-41] SATA[0/1]_PRESENT_ACTIVEn ++ * [42-43] XG_MDC/XG_MDIO (XSMI) ++ * [44-55] RGMII1 ++ * [56-62] SD ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0x7 0x0 0x7 0xa 0xa 0x2 0x2 0x5 ++ 0x9 0x9 0x8 0x8 0x1 0x1 0x1 0x1 0x1 0x1 ++ 0x1 0x1 0x1 0x1 0x1 0x1 0xe 0xe 0xe 0xe ++ 0xe 0xe 0xe>; ++}; ++ ++&cp0_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { ++ /* Serdes Configuration: ++ * Lane 0-3: PCIe0 (x4) ++ * Lane 4: USB3_HOST1 ++ * Lane 5: PCIe2 (x1) ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++/* CON6 on CP0 expansion */ ++&cp0_pcie0 { ++ status = "okay"; ++}; ++ ++&cp0_pcie1 { ++ status = "disabled"; ++}; ++ ++/* CON5 on CP0 expansion */ ++&cp0_pcie2 { ++ status = "okay"; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++/* CON9 on CP0 expansion */ ++&cp0_usb3_0 { ++ status = "okay"; ++}; ++ ++/* CON10 on CP0 expansion */ ++&cp0_usb3_1 { ++ status = "okay"; ++}; ++ ++&cp0_utmi0 { ++ status = "okay"; ++}; ++ ++&cp0_utmi1 { ++ status = "okay"; ++}; ++ ++&cp0_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_sdhci_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp0_eth2 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "rgmii-id"; ++}; ++ ++&cp1_pinctl { ++ /* MPP Bus: ++ * [0-11] RGMII0 ++ * [13-16] SPI1 ++ * [27,31] GE_MDIO/MDC ++ * [28] SATA1_PRESENT_ACTIVEn ++ * [29-30] UART0 ++ * [32-62] = 0xff: Keep default CP1_shared_pins ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 ++ 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x8 0x9 0xa ++ 0xA 0x8 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff>; ++}; ++ ++&cp1_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp1_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp1_comphy { ++ /* Serdes Configuration: ++ * Lane 0: PCIe0 (x1) ++ * Lane 1: USB3_HOST0 ++ * Lane 2: SFI0 (10G) ++ * Lane 3: SATA1 ++ * Lane 4: PCIe1 (x1) ++ * Lane 5: PCIe2 (x1) ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ phy1 { ++ phy-type = ; ++ }; ++ phy2 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ phy3 { ++ phy-type = ; ++ }; ++ phy4 { ++ phy-type = ; ++ }; ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++/* CON6 on CP1 expansion */ ++&cp1_pcie0 { ++ status = "okay"; ++}; ++ ++&cp1_pcie1 { ++ status = "okay"; ++}; ++ ++/* CON5 on CP1 expansion */ ++&cp1_pcie2 { ++ status = "okay"; ++}; ++ ++&cp1_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp1_spi1_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>; /* CS1 */ ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0>; ++ spi-max-frequency = <108000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0 0x200000>; ++ }; ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xce0000>; ++ }; ++ }; ++ }; ++}; ++ ++/* CON4 on CP1 expansion */ ++&cp1_sata0 { ++ status = "okay"; ++}; ++ ++/* CON9 on CP1 expansion */ ++&cp1_usb3_0 { ++ status = "okay"; ++}; ++ ++&cp1_utmi0 { ++ status = "okay"; ++}; ++ ++&cp1_mdio { ++ status = "okay"; ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++}; ++ ++&cp1_ethernet { ++ status = "okay"; ++}; ++ ++&cp1_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-2 */ ++}; ++ ++&cp1_eth1 { ++ status = "okay"; ++ phy = <&phy0>; ++ phy-mode = "rgmii-id"; ++}; +diff --git a/arch/arm/dts/armada-8040-db-C.dts b/arch/arm/dts/armada-8040-db-C.dts +new file mode 100644 +index 0000000000..a3977c9e4f +--- /dev/null ++++ b/arch/arm/dts/armada-8040-db-C.dts +@@ -0,0 +1,334 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada 8040 Development board platform ++ */ ++ ++#include "armada-80x0-db.dtsi" ++ ++/ { ++ model = "Marvell Armada 8040 Development Board DB-88F8040 setup(C)"; ++ compatible = "marvell,armada8040-db", "marvell,armada8040", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp1_spi1; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; ++ fuse5 = &cp1_ld_efuse0; ++ fuse6 = &cp1_ld_efuse1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++}; ++ ++/* Accessible over the mini-USB CON9 connector on the main board */ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&ap_pinctl { ++ /* MPP Bus: ++ * SDIO [0-10] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 1 1 1 1 ++ 1 3 0 0 0 0 0 0 0 3 >; ++}; ++ ++&ap_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ap_emmc_pins>; ++ bus-width = <8>; ++ status = "okay"; ++}; ++ ++&cp0_pinctl { ++ /* MPP Bus: ++ * [0-31] = 0xff: Keep default CP0_shared_pins ++ * [11] CLKOUT_MPP_11 (out) ++ * [23] LINK_RD_IN_CP2CP (in) ++ * [25] CLKOUT_MPP_25 (out) ++ * [29] AVS_FB_IN_CP2CP (in) ++ * [32,34] GE_MDIO/MDC ++ * [33] GPIO: GE_INT#/push button/Wake ++ * [35] MSS_GPIO[3]: MSS_PWDN ++ * [36] MSS_GPIO[5]: MSS_VTT_EN ++ * [37-38] I2C0 ++ * [39] PTP_CLK ++ * [40-41] SATA[0/1]_PRESENT_ACTIVEn ++ * [42-43] XG_MDC/XG_MDIO (XSMI) ++ * [44-55] RGMII1 ++ * [56-62] SD ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0x7 0x0 0x7 0xa 0xa 0x2 0x2 0x5 ++ 0x9 0x9 0x8 0x8 0x1 0x1 0x1 0x1 0x1 0x1 ++ 0x1 0x1 0x1 0x1 0x1 0x1 0xe 0xe 0xe 0xe ++ 0xe 0xe 0xe>; ++}; ++ ++&cp0_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { ++ /* Serdes Configuration: ++ * Lane 0: PCIe0 (x1) ++ * Lane 1: SATA0 ++ * Lane 2: SFI (10G) ++ * Lane 3: SATA1 ++ * Lane 4: USB3_HOST1 ++ * Lane 5: PCIe2 (x1) ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ phy1 { ++ phy-type = ; ++ }; ++ phy2 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ phy3 { ++ phy-type = ; ++ }; ++ phy4 { ++ phy-type = ; ++ }; ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++/* CON6 on CP0 expansion */ ++&cp0_pcie0 { ++ status = "okay"; ++}; ++ ++&cp0_pcie1 { ++ status = "disabled"; ++}; ++ ++/* CON5 on CP0 expansion */ ++&cp0_pcie2 { ++ status = "okay"; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++/* CON4 on CP0 expansion */ ++&cp0_sata0 { ++ status = "okay"; ++}; ++ ++/* CON9 on CP0 expansion */ ++&cp0_usb3_0 { ++ status = "okay"; ++}; ++ ++/* CON10 on CP0 expansion */ ++&cp0_usb3_1 { ++ status = "okay"; ++}; ++ ++&cp0_utmi0 { ++ status = "okay"; ++}; ++ ++&cp0_utmi1 { ++ status = "okay"; ++}; ++ ++&cp0_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_sdhci_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-2 */ ++}; ++ ++&cp0_eth2 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "rgmii-id"; ++}; ++ ++&cp1_pinctl { ++ /* MPP Bus: ++ * [0-11] TDM ++ * [13-16] SPI1 ++ * [27-28] SATA[0/1]_PRESENT_ACTIVEn ++ * [29-30] UART0 ++ * [32-62] = 0xff: Keep default CP1_shared_pins ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0x4 0x4 0x4 0x4 0x4 0x4 0x4 0x4 0x4 0x4 ++ 0x4 0x4 0x3 0x3 0x3 0x3 0x3 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x9 0x9 0xA ++ 0xA 0x0 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff>; ++}; ++ ++&cp1_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp1_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp1_comphy { ++ /* Serdes Configuration: ++ * Lane 0: PCIe0 (x1) ++ * Lane 1: SATA0 ++ * Lane 2: SFI (10G) ++ * Lane 3: SATA1 ++ * Lane 4: PCIe1 (x1) ++ * Lane 5: PCIe2 (x1) ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ phy1 { ++ phy-type = ; ++ }; ++ phy2 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ phy3 { ++ phy-type = ; ++ }; ++ phy4 { ++ phy-type = ; ++ }; ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++/* CON6 on CP1 expansion */ ++&cp1_pcie0 { ++ status = "okay"; ++}; ++ ++&cp1_pcie1 { ++ status = "okay"; ++}; ++ ++/* CON5 on CP1 expansion */ ++&cp1_pcie2 { ++ status = "okay"; ++}; ++ ++&cp1_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp1_spi1_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>; /* CS1 */ ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0>; ++ spi-max-frequency = <108000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0 0x200000>; ++ }; ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xce0000>; ++ }; ++ }; ++ }; ++}; ++ ++/* CON4 on CP1 expansion */ ++&cp1_sata0 { ++ status = "okay"; ++}; ++ ++/* CON9 on CP1 expansion */ ++&cp1_usb3_0 { ++ status = "okay"; ++}; ++ ++&cp1_utmi0 { ++ status = "okay"; ++}; ++ ++&cp1_ethernet { ++ status = "okay"; ++}; ++ ++&cp1_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-2 */ ++}; +diff --git a/arch/arm/dts/armada-8040-db-D.dts b/arch/arm/dts/armada-8040-db-D.dts +new file mode 100644 +index 0000000000..82679f67c9 +--- /dev/null ++++ b/arch/arm/dts/armada-8040-db-D.dts +@@ -0,0 +1,316 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada 8040 Development board platform ++ */ ++ ++#include "armada-80x0-db.dtsi" ++ ++/ { ++ model = "Marvell Armada 8040 Development Board DB-88F8040 setup(D)"; ++ compatible = "marvell,armada8040-db", "marvell,armada8040", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp1_spi1; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; ++ fuse5 = &cp1_ld_efuse0; ++ fuse6 = &cp1_ld_efuse1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++ ++ cp0_sar { ++ boot_mode { ++ default = <0xe>; ++ }; ++ }; ++}; ++ ++/* Accessible over the mini-USB CON9 connector on the main board */ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&ap_pinctl { ++ /* MPP Bus: ++ * SDIO [0-10] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 1 1 1 1 ++ 1 3 0 0 0 0 0 0 0 3 >; ++}; ++ ++&ap_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ap_emmc_pins>; ++ bus-width = <8>; ++ status = "okay"; ++}; ++ ++&cp0_pinctl { ++ /* MPP Bus: ++ * [0-31] = 0xff: Keep default CP0_shared_pins ++ * [11] CLKOUT_MPP_11 (out) ++ * [23] LINK_RD_IN_CP2CP (in) ++ * [25] CLKOUT_MPP_25 (out) ++ * [29] AVS_FB_IN_CP2CP (in) ++ * [32,34] GE_MDIO/MDC ++ * [33] GPIO: GE_INT#/push button/Wake ++ * [35] MSS_GPIO[3]: MSS_PWDN ++ * [36] MSS_GPIO[5]: MSS_VTT_EN ++ * [37-38] I2C0 ++ * [39] PTP_CLK ++ * [40-41] SATA[0/1]_PRESENT_ACTIVEn ++ * [42-43] XG_MDC/XG_MDIO (XSMI) ++ * [44-55] RGMII1 ++ * [56-62] SD ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0x7 0x0 0x7 0xa 0xa 0x2 0x2 0x5 ++ 0x9 0x9 0x8 0x8 0x1 0x1 0x1 0x1 0x1 0x1 ++ 0x1 0x1 0x1 0x1 0x1 0x1 0xe 0xe 0xe 0xe ++ 0xe 0xe 0xe>; ++}; ++ ++&cp0_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { ++ /* Serdes Configuration: ++ * Lane 0: PCIe0 (x1) ++ * Lane 1: SATA0 ++ * Lane 2: SFI (10G) ++ * Lane 3: SATA1 ++ * Lane 4: USB3_HOST1 ++ * Lane 5: PCIe2 (x1) ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ phy1 { ++ phy-type = ; ++ }; ++ phy2 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ phy3 { ++ phy-type = ; ++ }; ++ phy4 { ++ phy-type = ; ++ }; ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++/* CON6 on CP0 expansion */ ++&cp0_pcie0 { ++ status = "okay"; ++}; ++ ++&cp0_pcie1 { ++ status = "disabled"; ++}; ++ ++/* CON5 on CP0 expansion */ ++&cp0_pcie2 { ++ status = "okay"; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++/* CON4 on CP0 expansion */ ++&cp0_sata0 { ++ status = "okay"; ++}; ++ ++/* CON9 on CP0 expansion */ ++&cp0_usb3_0 { ++ status = "okay"; ++}; ++ ++/* CON10 on CP0 expansion */ ++&cp0_usb3_1 { ++ status = "okay"; ++}; ++ ++&cp0_utmi0 { ++ status = "okay"; ++}; ++ ++&cp0_utmi1 { ++ status = "okay"; ++}; ++ ++&cp0_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_sdhci_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-2 */ ++}; ++ ++&cp0_eth2 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "rgmii-id"; ++}; ++ ++&cp1_pinctl { ++ /* MPP Bus: ++ * [0-11] DEV_AD ++ * [12,13] ND_RBn ++ * [14-27] DEV_AD ++ * [28] SATA1_PRESENT_ACTIVEn ++ * [29-30] UART0 ++ * [32-62] = 0xff: Keep default CP1_shared_pins ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0x1 0x1 0x1 0x1 0x1 0x1 0x1 0x1 0x1 0x1 ++ 0x1 0x1 0x2 0x2 0x1 0x1 0x1 0x1 0x1 0x1 ++ 0x1 0x1 0x1 0x1 0x1 0x1 0x1 0x1 0x9 0xA ++ 0xA 0x0 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff>; ++}; ++ ++&cp1_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp1_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp1_comphy { ++ /* Serdes Configuration: ++ * Lane 0: PCIe0 (x1) ++ * Lane 1: SATA0 ++ * Lane 2: SGMII0 (1.25G) ++ * Lane 3: SATA1 ++ * Lane 4: PCIe1 (x1) ++ * Lane 5: PCIe2 (x1) ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ phy1 { ++ phy-type = ; ++ }; ++ phy2 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ phy3 { ++ phy-type = ; ++ }; ++ phy4 { ++ phy-type = ; ++ }; ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++/* CON6 on CP1 expansion */ ++&cp1_pcie0 { ++ status = "okay"; ++}; ++ ++&cp1_pcie1 { ++ status = "okay"; ++}; ++ ++/* CON5 on CP1 expansion */ ++&cp1_pcie2 { ++ status = "okay"; ++}; ++ ++/* CON4 on CP1 expansion */ ++&cp1_sata0 { ++ status = "okay"; ++}; ++ ++/* CON9 on CP1 expansion */ ++&cp1_usb3_0 { ++ status = "okay"; ++}; ++ ++&cp1_utmi0 { ++ status = "okay"; ++}; ++ ++&cp1_nand { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp1_nand_pins &cp1_nand_rb>; ++ ++ status = "okay"; ++}; ++ ++&cp1_ethernet { ++ status = "okay"; ++}; ++ ++&cp1_eth0 { ++ status = "okay"; ++ phy-mode = "sgmii"; /* lane-2 */ ++}; +diff --git a/arch/arm/dts/armada-8040-db-E.dts b/arch/arm/dts/armada-8040-db-E.dts +new file mode 100644 +index 0000000000..22d4617d2a +--- /dev/null ++++ b/arch/arm/dts/armada-8040-db-E.dts +@@ -0,0 +1,331 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada 8040 Development board platform ++ */ ++ ++#include "armada-80x0-db.dtsi" ++ ++/ { ++ model = "Marvell Armada 8040 Development Board DB-88F8040 setup(E)"; ++ compatible = "marvell,armada8040-db", "marvell,armada8040", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp1_spi1; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; ++ fuse5 = &cp1_ld_efuse0; ++ fuse6 = &cp1_ld_efuse1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++}; ++ ++/* Accessible over the mini-USB CON9 connector on the main board */ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&ap_pinctl { ++ /* MPP Bus: ++ * SPI0 [0-3] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 3 3 3 3 0 0 0 0 0 0 ++ 0 3 0 0 0 0 0 0 0 3 >; ++}; ++ ++&ap_spi0 { ++ status = "okay"; ++}; ++ ++&cp0_pinctl { ++ /* MPP Bus: ++ * [0-31] = 0xff: Keep default CP0_shared_pins ++ * [11] CLKOUT_MPP_11 (out) ++ * [23] LINK_RD_IN_CP2CP (in) ++ * [25] CLKOUT_MPP_25 (out) ++ * [29] AVS_FB_IN_CP2CP (in) ++ * [32,34] GE_MDIO/MDC ++ * [33] GPIO: GE_INT#/push button/Wake ++ * [35] MSS_GPIO[3]: MSS_PWDN ++ * [36] MSS_GPIO[5]: MSS_VTT_EN ++ * [35-36] I2C1 ++ * [37-38] I2C0 ++ * [39] PTP_CLK ++ * [40-41] SATA[0/1]_PRESENT_ACTIVEn ++ * [42-43] XG_MDC/XG_MDIO (XSMI) ++ * [47,49] UART1 ++ * [50-51] UART2 ++ * [54] SDIO_HW_RST ++ * [56-62] SD ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0x0 0xff 0x2 0x2 0x2 0x2 0x5 ++ 0x9 0x9 0x8 0x8 0xff 0xff 0xff 0x7 0xff 0x7 ++ 0x6 0x6 0xff 0xff 0xa 0xff 0xe 0xe 0xe 0xe ++ 0xe 0xe 0xe>; ++}; ++ ++&cp0_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { ++ /* Serdes Configuration: ++ * Lane 0: PCIe0 (x1) ++ * Lane 1: SATA0 ++ * Lane 2: SFI (10G) ++ * Lane 3: SATA1 ++ * Lane 4: USB3_HOST1 ++ * Lane 5: PCIe2 (x1) ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ phy1 { ++ phy-type = ; ++ }; ++ phy2 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ phy3 { ++ phy-type = ; ++ }; ++ phy4 { ++ phy-type = ; ++ }; ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++/* CON6 on CP0 expansion */ ++&cp0_pcie0 { ++ status = "okay"; ++}; ++ ++/* CON5 on CP0 expansion */ ++&cp0_pcie2 { ++ status = "okay"; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++/* CON4 on CP0 expansion */ ++&cp0_sata0 { ++ status = "okay"; ++}; ++ ++/* CON9 on CP0 expansion */ ++&cp0_usb3_0 { ++ status = "okay"; ++}; ++ ++/* CON10 on CP0 expansion */ ++&cp0_usb3_1 { ++ status = "okay"; ++}; ++ ++&cp0_utmi0 { ++ status = "okay"; ++}; ++ ++&cp0_utmi1 { ++ status = "okay"; ++}; ++ ++&cp0_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_sdhci_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-2 */ ++}; ++ ++&cp1_pinctl { ++ /* MPP Bus: ++ * [0-11] RGMII0 ++ * [13-16] SPI1 ++ * [27,31] GE_MDIO/MDC ++ * [28] SATA1_PRESENT_ACTIVEn ++ * [29-30] UART0 ++ * [32-62] = 0xff: Keep default CP1_shared_pins ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 ++ 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x8 0x9 0xa ++ 0xA 0x8 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff>; ++}; ++ ++&cp1_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp1_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp1_comphy { ++ /* Serdes Configuration: ++ * Lane 0: PCIe0 (x1) ++ * Lane 1: SATA0 ++ * Lane 2: SGMII (3.125G) ++ * Lane 3: SATA1 ++ * Lane 4: PCIe1 (x1) ++ * Lane 5: PCIe2 (x1) ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ phy1 { ++ phy-type = ; ++ }; ++ phy2 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ phy3 { ++ phy-type = ; ++ }; ++ phy4 { ++ phy-type = ; ++ }; ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++/* CON6 on CP1 expansion */ ++&cp1_pcie0 { ++ status = "okay"; ++}; ++ ++&cp1_pcie1 { ++ status = "okay"; ++}; ++ ++/* CON5 on CP1 expansion */ ++&cp1_pcie2 { ++ status = "okay"; ++}; ++ ++&cp1_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp1_spi1_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>; /* CS1 */ ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0>; ++ spi-max-frequency = <108000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0 0x200000>; ++ }; ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xce0000>; ++ }; ++ }; ++ }; ++}; ++ ++/* CON4 on CP1 expansion */ ++&cp1_sata0 { ++ status = "disabled"; ++}; ++ ++/* CON9 on CP1 expansion */ ++&cp1_usb3_0 { ++ status = "okay"; ++}; ++ ++&cp1_utmi0 { ++ status = "okay"; ++}; ++ ++&cp1_mdio { ++ status = "okay"; ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++}; ++ ++&cp1_ethernet { ++ status = "okay"; ++}; ++ ++&cp1_eth0 { ++ status = "okay"; ++ phy-mode = "sgmii"; /* lane-2 */ ++}; ++ ++&cp1_eth1 { ++ status = "okay"; ++ phy = <&phy0>; ++ phy-mode = "rgmii-id"; ++}; +diff --git a/arch/arm/dts/armada-8040-db-F.dts b/arch/arm/dts/armada-8040-db-F.dts +new file mode 100644 +index 0000000000..6d3596eb3e +--- /dev/null ++++ b/arch/arm/dts/armada-8040-db-F.dts +@@ -0,0 +1,395 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada 8040 Development board platform ++ */ ++ ++#include "armada-8040.dtsi" ++ ++/ { ++ model = "Marvell Armada 8040 Development Board DB-88F8040 setup(F)"; ++ compatible = "marvell,armada8040-db", "marvell,armada8040", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp1_spi1; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; ++ fuse5 = &cp1_ld_efuse0; ++ fuse6 = &cp1_ld_efuse1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++ ++ cp0_reg_usb3_vbus0:cp0_usb3_vbus@0 { ++ compatible = "regulator-fixed"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <100000>; ++ regulator-force-boot-off; ++ gpio = <&expander0 0 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ cp0_reg_usb3_vbus1: cp0_usb3_vbus@1 { ++ compatible = "regulator-fixed"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <100000>; ++ regulator-force-boot-off; ++ gpio = <&expander0 1 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ /* even though this node used for enable/disable cp1 usb vbus-supply, ++ * we use "cp0" prefix since the expander is connected to cp0. ++ */ ++ cp0_reg_usb3_vbus2: cp0_usb3_vbus@2 { ++ compatible = "regulator-fixed"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <100000>; ++ regulator-force-boot-off; ++ gpio = <&expander1 0 GPIO_ACTIVE_HIGH>; ++ }; ++}; ++ ++/* Accessible over the mini-USB CON9 connector on the main board */ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&ap_pinctl { ++ /* MPP Bus: ++ * SDIO [0-10] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 1 1 1 1 ++ 1 3 0 0 0 0 0 0 0 3 >; ++}; ++ ++&ap_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ap_emmc_pins>; ++ bus-width = <8>; ++ status = "okay"; ++}; ++ ++&cp0_pinctl { ++ /* MPP Bus: ++ * [0-31] = 0xff: Keep default CP0_shared_pins ++ * [11] CLKOUT_MPP_11 (out) ++ * [23] LINK_RD_IN_CP2CP (in) ++ * [25] CLKOUT_MPP_25 (out) ++ * [29] AVS_FB_IN_CP2CP (in) ++ * [32,34] GE_MDIO/MDC ++ * [33] GPIO: GE_INT#/push button/Wake ++ * [35] MSS_GPIO[3]: MSS_PWDN ++ * [36] MSS_GPIO[5]: MSS_VTT_EN ++ * [37-38] I2C0 ++ * [39] PTP_CLK ++ * [40-41] SATA[0/1]_PRESENT_ACTIVEn ++ * [42-43] XG_MDC/XG_MDIO (XSMI) ++ * [44-55] RGMII1 ++ * [56-62] SD ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0x7 0x0 0x7 0xa 0xa 0x2 0x2 0x5 ++ 0x9 0x9 0x8 0x8 0x1 0x1 0x1 0x1 0x1 0x1 ++ 0x1 0x1 0x1 0x1 0x1 0x1 0xe 0xe 0xe 0xe ++ 0xe 0xe 0xe>; ++}; ++ ++&cp0_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { ++ /* Serdes Configuration: ++ * Lane 0: PCIe0 (x1) ++ * Lane 1: SATA0 ++ * Lane 2: SFI (10G) ++ * Lane 3: SATA1 ++ * Lane 4: USB3_HOST1 ++ * Lane 5: PCIe2 (x1) ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ phy1 { ++ phy-type = ; ++ }; ++ phy2 { ++ phy-type = ; ++ }; ++ phy3 { ++ phy-type = ; ++ }; ++ phy4 { ++ phy-type = ; ++ }; ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++/* CON6 on CP0 expansion */ ++&cp0_pcie0 { ++ status = "okay"; ++}; ++ ++&cp0_pcie1 { ++ status = "disabled"; ++}; ++ ++/* CON5 on CP0 expansion */ ++&cp0_pcie2 { ++ status = "okay"; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++ expander0: pca953x@21 { ++ compatible = "nxp,pca9555"; ++ #gpio-cells = <2>; ++ reg = <0x21>; ++ status = "okay"; ++ }; ++ expander1: pca953x@25 { ++ compatible = "nxp,pca9555"; ++ #gpio-cells = <2>; ++ reg = <0x25>; ++ status = "okay"; ++ }; ++}; ++ ++/* CON4 on CP0 expansion */ ++&cp0_sata0 { ++ status = "okay"; ++}; ++ ++/* CON9 on CP0 expansion */ ++&cp0_usb3_0 { ++ vbus-supply = <&cp0_reg_usb3_vbus0>; ++ vbus-disable-delay = <500>; ++ status = "okay"; ++}; ++ ++/* CON10 on CP0 expansion */ ++&cp0_usb3_1 { ++ vbus-supply = <&cp0_reg_usb3_vbus1>; ++ vbus-disable-delay = <500>; ++ status = "okay"; ++}; ++ ++&cp0_utmi0 { ++ status = "okay"; ++}; ++ ++&cp0_utmi1 { ++ status = "okay"; ++}; ++ ++&cp0_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_sdhci_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "ap"; /* lane-2: left for auto-neg */ ++}; ++ ++&cp0_eth2 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "rgmii-id"; ++}; ++ ++&cp1_pinctl { ++ /* MPP Bus: ++ * [0-11] RGMII0 ++ * [13-16] SPI1 ++ * [27,31] GE_MDIO/MDC ++ * [28] SATA1_PRESENT_ACTIVEn ++ * [29-30] UART0 ++ * [32-62] = 0xff: Keep default CP1_shared_pins ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 ++ 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x8 0x9 0xa ++ 0xA 0x8 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff>; ++}; ++ ++&cp1_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp1_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp1_comphy { ++ /* Serdes Configuration: ++ * Lane 0: PCIe0 (x1) ++ * Lane 1: SATA0 ++ * Lane 2: SFI (10G) ++ * Lane 3: SATA1 ++ * Lane 4: PCIe1 (x1) ++ * Lane 5: PCIe2 (x1) ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ phy1 { ++ phy-type = ; ++ }; ++ phy2 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ phy3 { ++ phy-type = ; ++ }; ++ phy4 { ++ phy-type = ; ++ }; ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++/* CON6 on CP1 expansion */ ++&cp1_pcie0 { ++ status = "okay"; ++}; ++ ++&cp1_pcie1 { ++ status = "okay"; ++}; ++ ++/* CON5 on CP1 expansion */ ++&cp1_pcie2 { ++ status = "okay"; ++}; ++ ++&cp1_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp1_spi1_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>; /* CS1 */ ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0>; ++ spi-max-frequency = <108000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0 0x200000>; ++ }; ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xce0000>; ++ }; ++ }; ++ }; ++}; ++ ++/* CON4 on CP1 expansion */ ++&cp1_sata0 { ++ status = "okay"; ++}; ++ ++/* CON9 on CP1 expansion */ ++&cp1_usb3_0 { ++ vbus-supply = <&cp0_reg_usb3_vbus2>; ++ vbus-disable-delay = <500>; ++ status = "okay"; ++}; ++ ++&cp1_utmi0 { ++ status = "okay"; ++}; ++ ++&cp1_mdio { ++ status = "okay"; ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++}; ++ ++&cp1_ethernet { ++ status = "okay"; ++}; ++ ++&cp1_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-2 */ ++}; ++ ++&cp1_eth1 { ++ status = "okay"; ++ phy = <&phy0>; ++ phy-mode = "rgmii-id"; ++}; +diff --git a/arch/arm/dts/armada-8040-db-G.dts b/arch/arm/dts/armada-8040-db-G.dts +new file mode 100644 +index 0000000000..964c71d064 +--- /dev/null ++++ b/arch/arm/dts/armada-8040-db-G.dts +@@ -0,0 +1,344 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada 8040 Development board platform ++ */ ++ ++#include "armada-80x0-db.dtsi" ++ ++/ { ++ model = "Marvell Armada 8040 Development Board DB-88F8040 setup(G)"; ++ compatible = "marvell,armada8040-db", "marvell,armada8040", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp1_spi1; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; ++ fuse5 = &cp1_ld_efuse0; ++ fuse6 = &cp1_ld_efuse1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++}; ++ ++/* Accessible over the mini-USB CON9 connector on the main board */ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&ap_pinctl { ++ /* MPP Bus: ++ * SDIO [0-10] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 1 1 1 1 ++ 1 3 0 0 0 0 0 0 0 3 >; ++}; ++ ++&ap_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ap_emmc_pins>; ++ bus-width = <8>; ++ status = "okay"; ++}; ++ ++&cp0_pinctl { ++ /* MPP Bus: ++ * [0-31] = 0xff: Keep default CP0_shared_pins ++ * [11] CLKOUT_MPP_11 (out) ++ * [23] LINK_RD_IN_CP2CP (in) ++ * [25] CLKOUT_MPP_25 (out) ++ * [29] AVS_FB_IN_CP2CP (in) ++ * [32,34] GE_MDIO/MDC ++ * [33] GPIO: GE_INT#/push button/Wake ++ * [35] MSS_GPIO[3]: MSS_PWDN ++ * [36] MSS_GPIO[5]: MSS_VTT_EN ++ * [37-38] I2C0 ++ * [39] PTP_CLK ++ * [40-41] SATA[0/1]_PRESENT_ACTIVEn ++ * [42-43] XG_MDC/XG_MDIO (XSMI) ++ * [44-55] RGMII1 ++ * [56-62] SD ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0x7 0x0 0x7 0xa 0xa 0x2 0x2 0x5 ++ 0x9 0x9 0x8 0x8 0x1 0x1 0x1 0x1 0x1 0x1 ++ 0x1 0x1 0x1 0x1 0x1 0x1 0xe 0xe 0xe 0xe ++ 0xe 0xe 0xe>; ++}; ++ ++&cp0_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { ++ /* Serdes Configuration: ++ * Lane 0-3: PCIe0 (x4) ++ * Lane 4: USB3_HOST1 ++ * Lane 5: PCIe2 (x1) ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++/* CON6 on CP0 expansion */ ++&cp0_pcie0 { ++ status = "okay"; ++}; ++ ++&cp0_pcie1 { ++ status = "disabled"; ++}; ++ ++/* CON5 on CP0 expansion */ ++&cp0_pcie2 { ++ status = "okay"; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++/* CON9 on CP0 expansion */ ++&cp0_usb3_0 { ++ status = "okay"; ++}; ++ ++/* CON10 on CP0 expansion */ ++&cp0_usb3_1 { ++ status = "okay"; ++}; ++ ++&cp0_utmi0 { ++ status = "okay"; ++}; ++ ++&cp0_utmi1 { ++ status = "okay"; ++}; ++ ++&cp0_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_sdhci_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp0_eth2 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "rgmii-id"; ++}; ++ ++&cp1_pinctl { ++ /* MPP Bus: ++ * [0-11] RGMII0 ++ * [13-16] SPI1 ++ * [27,31] GE_MDIO/MDC ++ * [28] SATA1_PRESENT_ACTIVEn ++ * [29-30] UART0 ++ * [32-62] = 0xff: Keep default CP1_shared_pins ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 ++ 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x8 0x9 0xa ++ 0xA 0x8 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff>; ++}; ++ ++&cp1_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp1_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp1_comphy { ++ /* Serdes Configuration: ++ * Lane 0-3: PCIe0 (x4) ++ * Lane 4: USB3_HOST1 ++ * Lane 5: PCIe2 (x1) ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++/* CON6 on CP1 expansion */ ++&cp1_pcie0 { ++ status = "okay"; ++}; ++ ++&cp1_pcie1 { ++ status = "disabled"; ++}; ++ ++/* CON5 on CP1 expansion */ ++&cp1_pcie2 { ++ status = "okay"; ++}; ++ ++&cp1_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp1_spi1_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>; /* CS1 */ ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0>; ++ spi-max-frequency = <108000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0 0x200000>; ++ }; ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xce0000>; ++ }; ++ }; ++ }; ++}; ++ ++/* CON9 on CP1 expansion */ ++&cp1_usb3_0 { ++ status = "okay"; ++}; ++ ++/* CON10 on CP0 expansion */ ++&cp1_usb3_1 { ++ status = "okay"; ++}; ++ ++&cp1_utmi0 { ++ status = "okay"; ++}; ++ ++&cp1_utmi1 { ++ status = "okay"; ++}; ++ ++&cp1_mdio { ++ status = "okay"; ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++}; ++ ++&cp1_ethernet { ++ status = "okay"; ++}; ++ ++&cp1_eth0 { ++ status = "disabled"; ++ phy-mode = "sfi"; /* lane-2 */ ++}; ++ ++&cp1_eth1 { ++ status = "okay"; ++ phy = <&phy0>; ++ phy-mode = "rgmii-id"; ++}; +diff --git a/arch/arm/dts/armada-8040-db-H.dts b/arch/arm/dts/armada-8040-db-H.dts +new file mode 100644 +index 0000000000..d8b78cd4ce +--- /dev/null ++++ b/arch/arm/dts/armada-8040-db-H.dts +@@ -0,0 +1,351 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada 8040 Development board platform ++ */ ++ ++#include "armada-80x0-db.dtsi" ++ ++/ { ++ model = "Marvell Armada 8040 Development Board DB-88F8040 setup(H)"; ++ compatible = "marvell,armada8040-db", "marvell,armada8040", ++ "marvell,armada-ap806-quad", "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp1_spi1; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; ++ fuse5 = &cp1_ld_efuse0; ++ fuse6 = &cp1_ld_efuse1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++}; ++ ++/* Accessible over the mini-USB CON9 connector on the main board */ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&ap_pinctl { ++ /* MPP Bus: ++ * SDIO [0-10] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 1 1 1 1 ++ 1 3 0 0 0 0 0 0 0 3 >; ++}; ++ ++&ap_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ap_emmc_pins>; ++ bus-width = <8>; ++ status = "okay"; ++}; ++ ++&cp0_pinctl { ++ /* MPP Bus: ++ * [0-31] = 0xff: Keep default CP0_shared_pins ++ * [11] CLKOUT_MPP_11 (out) ++ * [23] LINK_RD_IN_CP2CP (in) ++ * [25] CLKOUT_MPP_25 (out) ++ * [29] AVS_FB_IN_CP2CP (in) ++ * [32,34] GE_MDIO/MDC ++ * [33] GPIO: GE_INT#/push button/Wake ++ * [35] MSS_GPIO[3]: MSS_PWDN ++ * [36] MSS_GPIO[5]: MSS_VTT_EN ++ * [37-38] I2C0 ++ * [39] PTP_CLK ++ * [40-41] SATA[0/1]_PRESENT_ACTIVEn ++ * [42-43] XG_MDC/XG_MDIO (XSMI) ++ * [44-55] RGMII1 ++ * [56-62] SD ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0x7 0x0 0x7 0xa 0xa 0x2 0x2 0x5 ++ 0x9 0x9 0x8 0x8 0x1 0x1 0x1 0x1 0x1 0x1 ++ 0x1 0x1 0x1 0x1 0x1 0x1 0xe 0xe 0xe 0xe ++ 0xe 0xe 0xe>; ++}; ++ ++&cp0_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { ++ /* Serdes Configuration: ++ * Lane 0-3: PCIe0 (x4) ++ * Lane 4: SFI0 (10G) ++ * Lane 5: PCIe2 (x1) ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++/* CON6 on CP0 expansion */ ++&cp0_pcie0 { ++ status = "okay"; ++}; ++ ++&cp0_pcie1 { ++ status = "disabled"; ++}; ++ ++/* CON5 on CP0 expansion */ ++&cp0_pcie2 { ++ status = "okay"; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++/* CON9 on CP0 expansion */ ++&cp0_usb3_0 { ++ status = "okay"; ++}; ++ ++/* CON10 on CP0 expansion */ ++&cp0_usb3_1 { ++ status = "okay"; ++}; ++ ++&cp0_utmi0 { ++ status = "okay"; ++}; ++ ++&cp0_utmi1 { ++ status = "okay"; ++}; ++ ++&cp0_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_sdhci_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-4 */ ++}; ++ ++&cp0_eth2 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "rgmii-id"; ++}; ++ ++&cp1_pinctl { ++ /* MPP Bus: ++ * [0-11] RGMII0 ++ * [13-16] SPI1 ++ * [27,31] GE_MDIO/MDC ++ * [28] SATA1_PRESENT_ACTIVEn ++ * [29-30] UART0 ++ * [32-62] = 0xff: Keep default CP1_shared_pins ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0x3 ++ 0x3 0x3 0x3 0x3 0x3 0x3 0x3 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0x8 0x9 0xa ++ 0xA 0x8 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff>; ++}; ++ ++&cp1_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp1_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp1_comphy { ++ /* Serdes Configuration: ++ * Lane 0-3: PCIe0 (x4) ++ * Lane 4: SFI0 (10G) ++ * Lane 5: PCIe2 (x1) ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++/* CON6 on CP1 expansion */ ++&cp1_pcie0 { ++ status = "okay"; ++}; ++ ++&cp1_pcie1 { ++ status = "disabled"; ++}; ++ ++/* CON5 on CP1 expansion */ ++&cp1_pcie2 { ++ status = "okay"; ++}; ++ ++&cp1_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp1_spi1_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>; /* CS1 */ ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0>; ++ spi-max-frequency = <108000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0 0x200000>; ++ }; ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xce0000>; ++ }; ++ }; ++ }; ++}; ++ ++/* CON9 on CP1 expansion */ ++&cp1_usb3_0 { ++ status = "okay"; ++}; ++ ++/* CON10 on CP0 expansion */ ++&cp1_usb3_1 { ++ status = "okay"; ++}; ++ ++&cp1_utmi0 { ++ status = "okay"; ++}; ++ ++&cp1_utmi1 { ++ status = "okay"; ++}; ++ ++&cp1_mdio { ++ status = "okay"; ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++}; ++ ++&cp1_ethernet { ++ status = "okay"; ++}; ++ ++&cp1_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-4 */ ++}; ++ ++&cp1_eth1 { ++ status = "okay"; ++ phy = <&phy0>; ++ phy-mode = "rgmii-id"; ++}; +diff --git a/arch/arm/dts/armada-8040-db.dts b/arch/arm/dts/armada-8040-db.dts +index 65b30bbc64..65214d6f73 100644 +--- a/arch/arm/dts/armada-8040-db.dts ++++ b/arch/arm/dts/armada-8040-db.dts +@@ -44,10 +44,10 @@ + * Device Tree file for Marvell Armada 8040 Development board platform + */ + +-#include "armada-8040.dtsi" ++#include "armada-80x0-db.dtsi" + + / { +- model = "Marvell Armada 8040 DB board"; ++ model = "Marvell Armada 8040 Development Board DB-88F8040"; + compatible = "marvell,armada8040-db", "marvell,armada8040", + "marvell,armada-ap806-quad", "marvell,armada-ap806"; + +@@ -56,8 +56,14 @@ + }; + + aliases { +- i2c0 = &cpm_i2c0; +- spi0 = &cps_spi1; ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp1_spi1; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; ++ fuse5 = &cp1_ld_efuse0; ++ fuse6 = &cp1_ld_efuse1; + }; + + memory@00000000 { +@@ -71,6 +77,18 @@ + status = "okay"; + }; + ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ + &ap_pinctl { + /* MPP Bus: + * SDIO [0-10] +@@ -85,10 +103,11 @@ + pinctrl-names = "default"; + pinctrl-0 = <&ap_emmc_pins>; + bus-width = <8>; ++ no-1-8-v; + status = "okay"; + }; + +-&cpm_pinctl { ++&cp0_pinctl { + /* MPP Bus: + * [0-31] = 0xff: Keep default CP0_shared_pins + * [11] CLKOUT_MPP_11 (out) +@@ -116,7 +135,15 @@ + 0xe 0xe 0xe>; + }; + +-&cpm_comphy { ++&cp0_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { + /* Serdes Configuration: + * Lane 0: PCIe0 (x1) + * Lane 1: SATA0 +@@ -126,77 +153,78 @@ + * Lane 5: PCIe2 (x1) + */ + phy0 { +- phy-type = ; ++ phy-type = ; + }; + phy1 { +- phy-type = ; ++ phy-type = ; + }; + phy2 { +- phy-type = ; ++ phy-type = ; ++ phy-speed = ; + }; + phy3 { +- phy-type = ; ++ phy-type = ; + }; + phy4 { +- phy-type = ; ++ phy-type = ; + }; + phy5 { +- phy-type = ; ++ phy-type = ; + }; + }; + + /* CON6 on CP0 expansion */ +-&cpm_pcie0 { ++&cp0_pcie0 { + status = "okay"; + }; + +-&cpm_pcie1 { ++&cp0_pcie1 { + status = "disabled"; + }; + + /* CON5 on CP0 expansion */ +-&cpm_pcie2 { ++&cp0_pcie2 { + status = "okay"; + }; + +-&cpm_i2c0 { ++&cp0_i2c0 { + pinctrl-names = "default"; +- pinctrl-0 = <&cpm_i2c0_pins>; ++ pinctrl-0 = <&cp0_i2c0_pins>; + status = "okay"; + clock-frequency = <100000>; + }; + + /* CON4 on CP0 expansion */ +-&cpm_sata0 { ++&cp0_sata0 { + status = "okay"; + }; + + /* CON9 on CP0 expansion */ +-&cpm_usb3_0 { ++&cp0_usb3_0 { + status = "okay"; + }; + + /* CON10 on CP0 expansion */ +-&cpm_usb3_1 { ++&cp0_usb3_1 { + status = "okay"; + }; + +-&cpm_utmi0 { ++&cp0_utmi0 { + status = "okay"; + }; + +-&cpm_utmi1 { ++&cp0_utmi1 { + status = "okay"; + }; + +-&cpm_sdhci0 { ++&cp0_sdhci0 { + pinctrl-names = "default"; +- pinctrl-0 = <&cpm_sdhci_pins>; ++ pinctrl-0 = <&cp0_sdhci_pins>; + bus-width = <4>; + status = "okay"; + }; + +-&cps_pinctl { ++&cp1_pinctl { + /* MPP Bus: + * [0-11] RGMII0 + * [13-16] SPI1 +@@ -215,7 +243,15 @@ + 0xff 0xff 0xff>; + }; + +-&cps_comphy { ++&cp1_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp1_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp1_comphy { + /* Serdes Configuration: + * Lane 0: PCIe0 (x1) + * Lane 1: SATA0 +@@ -225,50 +261,54 @@ + * Lane 5: PCIe2 (x1) + */ + phy0 { +- phy-type = ; ++ phy-type = ; + }; + phy1 { +- phy-type = ; ++ phy-type = ; + }; + phy2 { +- phy-type = ; ++ phy-type = ; ++ phy-speed = ; + }; + phy3 { +- phy-type = ; ++ phy-type = ; + }; + phy4 { +- phy-type = ; ++ phy-type = ; + }; + phy5 { +- phy-type = ; ++ phy-type = ; + }; + }; + + /* CON6 on CP1 expansion */ +-&cps_pcie0 { ++&cp1_pcie0 { + status = "okay"; + }; + +-&cps_pcie1 { ++&cp1_pcie1 { + status = "okay"; + }; + + /* CON5 on CP1 expansion */ +-&cps_pcie2 { ++&cp1_pcie2 { + status = "okay"; + }; + +-&cps_spi1 { ++&cp1_spi1 { + pinctrl-names = "default"; +- pinctrl-0 = <&cps_spi1_pins>; ++ pinctrl-0 = <&cp1_spi1_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>; /* CS1 */ + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; +- compatible = "jedec,spi-nor"; ++ compatible = "jedec,spi-nor", "spi-flash"; + reg = <0>; +- spi-max-frequency = <10000000>; ++ spi-max-frequency = <108000000>; + + partitions { + compatible = "fixed-partitions"; +@@ -288,36 +328,59 @@ + }; + + /* CON4 on CP1 expansion */ +-&cps_sata0 { ++&cp1_sata0 { + status = "okay"; + }; + + /* CON9 on CP1 expansion */ +-&cps_usb3_0 { ++&cp1_usb3_0 { + status = "okay"; + }; + +-/* CON10 on CP1 expansion */ +-&cps_usb3_1 { ++&cp1_utmi0 { + status = "okay"; + }; + +-&cps_utmi0 { ++&cp0_mdio { + status = "okay"; +-}; +- +-&cpm_mdio { + phy1: ethernet-phy@1 { + reg = <1>; + }; + }; + +-&cpm_ethernet { ++&cp1_mdio { ++ status = "okay"; ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp1_ethernet { + status = "okay"; + }; + +-&cpm_eth2 { ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-2 */ ++}; ++ ++&cp0_eth2 { + status = "okay"; + phy = <&phy1>; + phy-mode = "rgmii-id"; + }; ++ ++&cp1_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-2 */ ++}; ++ ++&cp1_eth1 { ++ status = "okay"; ++ phy = <&phy0>; ++ phy-mode = "rgmii-id"; ++}; +diff --git a/arch/arm/dts/armada-8040-dev-info.dtsi b/arch/arm/dts/armada-8040-dev-info.dtsi +new file mode 100644 +index 0000000000..a8a51f225a +--- /dev/null ++++ b/arch/arm/dts/armada-8040-dev-info.dtsi +@@ -0,0 +1,64 @@ ++/* ++ * *************************************************************************** ++ * Copyright (C) 2017 Marvell International Ltd. ++ * *************************************************************************** ++ * This program is free software: you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the Free ++ * Software Foundation, either version 2 of the License, or any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ * *************************************************************************** ++ */ ++ ++/ { ++ /* This should go only into devel boards */ ++ compatible = "marvell,cp110"; ++ sar { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ sar_fields { ++ ++ compatible = "marvell,sample-at-reset"; ++ reg = <0x4c 0x4e>; ++ chip_count = <2>; ++ bit_width = <5>; ++ ++ freq { ++ key = "freq"; ++ description = "CPU/DDR and PIDI frequencies"; ++ start-bit = <0>; ++ bit-length = <4>; ++ option-cnt = <4>; ++ options = "0x1", "CPU/DDR = 0x1: 2000/1050 Mhz, PIDI = 0: 1Ghz", ++ "0x3", "CPU/DDR = 0x3: 1800/1050 Mhz, PIDI = 0: 1Ghz", ++ "0x4", "CPU/DDR = 0x4: 1600/1050 Mhz, PIDI = 0: 1Ghz", ++ "0xe", "CPU/DDR = 0x34: 1300/800 Mhz, PIDI = 1: 500Mhz"; ++ default = <0x1>; ++ status = "okay"; ++ }; ++ boot_mode { ++ key = "boot_mode"; ++ description = "Boot mode options"; ++ start-bit = <4>; ++ bit-length = <6>; ++ option-cnt = <7>; ++ options = "0xE", "CP1_NAND IHB BW-8bit, PS-4KB, ECC-4bit\t(supported configuration: D)", ++ "0xF", "CP1_NAND IHB BW-8bit, PS-4KB, ECC-8bit\t(supported configuration: D)", ++ "0x29", "CP0_SD\t\t\t\t\t(supported configurations: C, D and E)", ++ "0x2A", "AP_EMMC\t\t\t\t\t(supported configurations: A, B, C and D)", ++ "0x2B", "CP0_EMMC\t\t\t\t\t(supported configurations: A and B)", ++ "0x30", "AP_SPI 24bits\t\t\t\t(supported configurations: E and A0)", ++ "0x32", "CP1_SPI_1 24bits\t\t\t\t(supported configurations: A, B, C and E)"; ++ default = <0x32>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/armada-8040-mcbin-single-shot.dts b/arch/arm/dts/armada-8040-mcbin-single-shot.dts +new file mode 100644 +index 0000000000..44135daba7 +--- /dev/null ++++ b/arch/arm/dts/armada-8040-mcbin-single-shot.dts +@@ -0,0 +1,28 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++ ++#include "armada-8040-mcbin.dts" ++ ++/{ ++ model = "Marvell 8040 MACHIATOBin SingleShot"; ++ compatible = "marvell,armada8040-mcbin-single-shot", ++ "marvell,armada8040-mcbin", ++ "marvell,armada8040"; ++}; ++ ++/* 10G SFI/copper */ ++&cp0_eth0 { ++ /delete-property/phy; ++}; ++ ++/* 10G SFI/copper */ ++&cp1_eth0 { ++ /delete-property/phy; ++}; ++ ++/delete-node/ &sfi_phy0; ++/delete-node/ &sfi_phy8; +diff --git a/arch/arm/dts/armada-8040-mcbin.dts b/arch/arm/dts/armada-8040-mcbin.dts +index 5a046d9de4..d5ec4fba7c 100644 +--- a/arch/arm/dts/armada-8040-mcbin.dts ++++ b/arch/arm/dts/armada-8040-mcbin.dts +@@ -3,10 +3,10 @@ + * Copyright (C) 2016 Marvell International Ltd. + */ + +-#include "armada-8040.dtsi" /* include SoC device tree */ ++#include "armada-80x0-db.dtsi" /* include SoC device tree */ + + / { +- model = "MACCHIATOBin-8040"; ++ model = "Marvell Armada 8040 MACCHIATOBin"; + compatible = "marvell,armada8040-mcbin", + "marvell,armada8040"; + +@@ -15,12 +15,18 @@ + }; + + aliases { +- i2c0 = &cpm_i2c0; +- i2c1 = &cpm_i2c1; +- spi0 = &cps_spi1; ++ i2c0 = &cp0_i2c0; ++ i2c1 = &cp0_i2c1; ++ spi0 = &cp1_spi1; + gpio0 = &ap_gpio0; +- gpio1 = &cpm_gpio0; +- gpio2 = &cpm_gpio1; ++ gpio1 = &cp0_gpio0; ++ gpio2 = &cp0_gpio1; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; ++ fuse5 = &cp1_ld_efuse0; ++ fuse6 = &cp1_ld_efuse1; + }; + + memory@00000000 { +@@ -36,15 +42,13 @@ + reg_usb3h0_vbus: usb3-vbus0 { + compatible = "regulator-fixed"; + pinctrl-names = "default"; +- pinctrl-0 = <&cpm_xhci_vbus_pins>; ++ pinctrl-0 = <&cp0_xhci_vbus_pins>; + regulator-name = "reg-usb3h0-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; +- startup-delay-us = <500000>; +- enable-active-high; +- regulator-always-on; +- regulator-boot-on; +- gpio = <&cpm_gpio1 15 GPIO_ACTIVE_HIGH>; /* GPIO[47] */ ++ startup-delay-us = <300000>; ++ regulator-force-boot-off; ++ gpio = <&cp0_gpio1 15 GPIO_ACTIVE_HIGH>; /* GPIO[47] */ + }; + }; + }; +@@ -54,6 +58,18 @@ + status = "okay"; + }; + ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ + &ap_pinctl { + /* + * MPP Bus: +@@ -69,11 +85,11 @@ + &ap_sdhci0 { + pinctrl-names = "default"; + pinctrl-0 = <&ap_emmc_pins>; +- bus-width= <8>; ++ bus-width = <8>; + status = "okay"; + }; + +-&cpm_pinctl { ++&cp0_pinctl { + /* + * MPP Bus: + * [0-31] = 0xff: Keep default CP0_shared_pins: +@@ -108,59 +124,68 @@ + 0 0 0 0 0 0 0xe 0xe 0xe 0xe + 0xe 0xe 0 >; + +- cpm_xhci_vbus_pins: cpm-xhci-vbus-pins { ++ cp0_xhci_vbus_pins: cp0-xhci-vbus-pins { + marvell,pins = < 47 >; + marvell,function = <0>; + }; + +- cpm_pcie_reset_pins: cpm-pcie-reset-pins { ++ cp0_pcie_reset_pins: cp0-pcie-reset-pins { + marvell,pins = < 52 >; + marvell,function = <0>; + }; + }; + + /* uSD slot */ +-&cpm_sdhci0 { ++&cp0_sdhci0 { + pinctrl-names = "default"; +- pinctrl-0 = <&cpm_sdhci_pins>; ++ pinctrl-0 = <&cp0_sdhci_pins>; + bus-width= <4>; + status = "okay"; + }; + + /* PCIe x4 */ +-&cpm_pcie0 { ++&cp0_pcie0 { + num-lanes = <4>; + pinctrl-names = "default"; +- pinctrl-0 = <&cpm_pcie_reset_pins>; +- marvell,reset-gpio = <&cpm_gpio1 20 GPIO_ACTIVE_LOW>; /* GPIO[52] */ ++ pinctrl-0 = <&cp0_pcie_reset_pins>; ++ marvell,reset-gpio = <&cp0_gpio1 20 GPIO_ACTIVE_LOW>; /* GPIO[52] */ + status = "okay"; + }; + +-&cpm_i2c0 { ++&cp0_i2c0 { + pinctrl-names = "default"; +- pinctrl-0 = <&cpm_i2c0_pins>; ++ pinctrl-0 = <&cp0_i2c0_pins>; + status = "okay"; + clock-frequency = <100000>; + }; + +-&cpm_i2c1 { ++&cp0_i2c1 { + pinctrl-names = "default"; +- pinctrl-0 = <&cpm_i2c1_pins>; ++ pinctrl-0 = <&cp0_i2c1_pins>; + status = "okay"; + clock-frequency = <100000>; + }; + +-&cpm_sata0 { ++&cp0_sata0 { + status = "okay"; + }; + +-&cpm_mdio { ++&cp0_mdio { ++ status = "okay"; + ge_phy: ethernet-phy@0 { + reg = <0>; + }; + }; + +-&cpm_comphy { ++&cp0_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { + /* + * CP0 Serdes Configuration: + * Lane 0: PCIe0 (x4) +@@ -171,49 +196,93 @@ + * Lane 5: SATA1 + */ + phy0 { +- phy-type = ; ++ phy-type = ; + }; + phy1 { +- phy-type = ; ++ phy-type = ; + }; + phy2 { +- phy-type = ; ++ phy-type = ; + }; + phy3 { +- phy-type = ; ++ phy-type = ; + }; + phy4 { +- phy-type = ; ++ phy-type = ; ++ phy-speed = ; + }; + phy5 { +- phy-type = ; ++ phy-type = ; ++ }; ++}; ++ ++&cp0_xmdio { ++ status = "okay"; ++ sfi_phy0: ethernet-phy@0 { ++ reg = <0>; + }; ++ ++ sfi_phy8: ethernet-phy@8 { ++ reg = <8>; ++ }; ++}; ++ ++&cp0_ethernet { ++ pinctrl-names = "default"; ++ status = "okay"; + }; + +-&cps_sata0 { ++/* 10G SFI/copper */ ++&cp0_eth0 { + status = "okay"; ++ phy-mode = "sfi"; ++ phy = <&sfi_phy0>; ++ phy-reset-gpios = <&cp1_gpio0 31 GPIO_ACTIVE_LOW>; ++ marvell,sfp-tx-disable-gpio = <&cp1_gpio0 29 GPIO_ACTIVE_HIGH>; + }; + +-&cps_usb3_0 { ++&cp1_sata0 { ++ status = "okay"; ++}; ++ ++&cp1_usb3_0 { + vbus-supply = <®_usb3h0_vbus>; ++ /delete-property/ current-limiter; + status = "okay"; + }; + +-&cps_utmi0 { ++&cp1_utmi0 { + status = "okay"; + }; + +-&cps_ethernet { ++&cp1_ethernet { + status = "okay"; + }; + +-&cps_eth1 { ++/* 10G SFI/copper */ ++&cp1_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; ++ phy = <&sfi_phy8>; ++ phy-reset-gpios = <&cp1_gpio0 9 GPIO_ACTIVE_LOW>; ++ marvell,sfp-tx-disable-gpio = <&cp1_gpio0 10 GPIO_ACTIVE_HIGH>; ++}; ++ ++/* 1G SGMII */ ++&cp1_eth1 { + status = "okay"; + phy = <&ge_phy>; + phy-mode = "sgmii"; + }; + +-&cps_pinctl { ++/* 2.5G SGMII */ ++&cp1_eth2 { ++ status = "okay"; ++ phy-mode = "sgmii-2500"; ++ marvell,sfp-tx-disable-gpio = <&cp1_gpio0 24 GPIO_ACTIVE_HIGH>; ++}; ++ ++&cp1_pinctl { + /* + * MPP Bus: + * [0-5] TDM +@@ -246,17 +315,20 @@ + 0xff 0xff 0xff>; + }; + +-&cps_spi1 { ++&cp1_spi1 { + pinctrl-names = "default"; +- pinctrl-0 = <&cps_spi1_pins>; ++ pinctrl-0 = <&cp1_spi1_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>; /* CS1 */ + status = "okay"; + + spi-flash@0 { + #address-cells = <1>; + #size-cells = <1>; +- compatible = "jedec,spi-nor"; ++ compatible = "jedec,spi-nor", "spi-flash"; + reg = <0>; +- spi-max-frequency = <10000000>; ++ spi-max-frequency = <108000000>; + + partitions { + compatible = "fixed-partitions"; +@@ -275,7 +347,15 @@ + }; + }; + +-&cps_comphy { ++&cp1_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp1_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp1_comphy { + /* + * CP1 Serdes Configuration: + * Lane 0: SGMII1 +@@ -283,25 +363,27 @@ + * Lane 2: USB HOST 0 + * Lane 3: SATA1 + * Lane 4: SFI (10G) +- * Lane 5: SGMII3 ++ * Lane 5: SGMII2 + */ + phy0 { +- phy-type = ; +- phy-speed = ; ++ phy-type = ; ++ phy-speed = ; + }; + phy1 { +- phy-type = ; ++ phy-type = ; + }; + phy2 { +- phy-type = ; ++ phy-type = ; + }; + phy3 { +- phy-type = ; ++ phy-type = ; + }; + phy4 { +- phy-type = ; ++ phy-type = ; ++ phy-speed = ; + }; + phy5 { +- phy-type = ; ++ phy-type = ; ++ phy-speed = ; + }; + }; +diff --git a/arch/arm/dts/armada-8040-ocp.dts b/arch/arm/dts/armada-8040-ocp.dts +new file mode 100644 +index 0000000000..b8af2f154b +--- /dev/null ++++ b/arch/arm/dts/armada-8040-ocp.dts +@@ -0,0 +1,339 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#include "armada-8040.dtsi" /* include SoC device tree */ ++ ++/ { ++ model = "OCP-8K"; /* PCB model */ ++ compatible = "marvell,armada8040-ocp", ++ "marvell,armada8040"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ i2c1 = &cp0_i2c1; ++ spi0 = &cp1_spi1; ++ gpio0 = &ap_gpio0; ++ gpio1 = &cp0_gpio0; ++ gpio2 = &cp0_gpio1; ++ fuse1 = &ap_ld_efuse0; ++ fuse2 = &ap_ld_efuse1; ++ fuse3 = &cp0_ld_efuse0; ++ fuse4 = &cp0_ld_efuse1; ++ fuse5 = &cp1_ld_efuse0; ++ fuse6 = &cp1_ld_efuse1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++ ++ simple-bus { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ reg_usb3h0_vbus: usb3-vbus0 { ++ compatible = "regulator-fixed"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_xhci_vbus_pins>; ++ regulator-name = "reg-usb3h0-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <300000>; ++ shutdown-delay-us = <500000>; ++ regulator-force-boot-off; ++ gpio = <&cp0_gpio1 15 GPIO_ACTIVE_HIGH>; /* GPIO[47] */ ++ }; ++ }; ++ ++ reserved-memory { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ /* The PCI console memory must be reserved */ ++ console_reserved: pci-console-nexus@3f000000 { ++ compatible = "marvell,pci-console-nexus-memory"; ++ reg = <0 0x3f000000 0 0x1000000>; ++ no-map; ++ }; ++ }; ++ ++}; ++ ++/* ++ * Accessible over the front panel micro USB connector CON9 or the ++ * three pin header (default unsoldered) J27 where the pinout is as follows - ++ * 1-GND, 2-8040 SoC RX, 3-8040 SoC TX. ++ */ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&ap_pinctl { ++ /* ++ * MPP Bus: ++ * eMMC [0-10] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 1 1 1 1 ++ 1 3 2 0 0 0 0 0 0 3 >; ++}; ++ ++/* on-board eMMC */ ++&ap_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ap_emmc_pins>; ++ bus-width = <8>; ++ no-1-8-v; ++ non-removable; ++ status = "okay"; ++}; ++ ++&cp0_bootcmd { ++ status = "okay"; ++}; ++ ++&cp0_pinctl { ++/* ++ * [0-32] = 0xff: Keep default CP1_shared_pins ++ * [32..34] Front panel LEDs (active low) ++ * [35-38] CP0 I2C1 and I2C0 ++ * [39] MSS_GPIO ++ * [40-41] NC ++ * [42] LED ++ * [43] Mask system reset (active high) ++ * [47] USB VBUS EN GPIO ++ * [48-49] NC ++ * [50,51] CP0 MSS I2C ++ * [52-61] NC ++ * [62] CP1 SFI SFP FAULT ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0 0 0 2 2 2 2 0 ++ 7 7 0 0 0 0 0 0 0xff 0xff ++ 0 0 0 0 0 0 0xe 0xe 0xe 0xe ++ 0xe 0xe 0 >; ++ ++ cp0_xhci_vbus_pins: cp0-xhci-vbus-pins { ++ marvell,pins = < 47 >; ++ marvell,function = <0>; ++ }; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c1_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { ++ /* ++ * CP0 Serdes Configuration: ++ * PCIex4 is connected to CP0 ++ * Lane 0: IGNORE (x4) ++ * Lane 1: IGNORE (x4) ++ * Lane 2: IGNORE (x4) ++ * Lane 3: IGNORE (x4) ++ * Lane 4: SFI (10G) ++ * Lane 5: UNCONNECTED ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ phy1 { ++ phy-type = ; ++ }; ++ phy2 { ++ phy-type = ; ++ }; ++ phy3 { ++ phy-type = ; ++ }; ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp0_ethernet { ++ pinctrl-names = "default"; ++ status = "okay"; ++}; ++ ++/* 10G SFI/copper */ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; ++ marvell,sfp-tx-disable-gpio = <&cp1_gpio0 24 GPIO_ACTIVE_HIGH>; ++}; ++ ++&cp1_utmi0 { ++ status = "okay"; ++}; ++ ++&cp1_usb3_0 { ++ vbus-supply = <®_usb3h0_vbus>; ++ status = "okay"; ++}; ++ ++&cp1_pinctl { ++ /* ++ * MPP Bus: ++ * [0-5] NC ++ * [6,7] UART0 ++ * [8] CP1 10G SFP LOS ++ * [9] NC ++ * [10] CP1 10G SFP TX Disable ++ * [11] CP1 10G SFP Mode ++ * [12] SPI1 CS1n ++ * [13] SPI1 MISO (TDM and SPI ROM shared) ++ * [14] SPI1 CS0n ++ * [15] SPI1 MOSI (TDM and SPI ROM shared) ++ * [16] SPI1 CLK (TDM and SPI ROM shared) ++ * [17-23] NC ++ * [24] CP0_10G_SFP_TX_DISABLE ++ * [25] NC ++ * [26] CP0 10G SFP TX Fault ++ * [27] CP0 10G SFP Mode ++ * [28] CP0 10G SFP LOS ++ * [29] MSS_TWSI_SDA - NOTE: set as gpio, to be used ++ * when MSS is used for power cooling ++ * [30] MSS_TWSI_SDA - NOTE: set as gpio, to be used ++ * when MSS is used for power cooling ++ * [31] USB Over current indication ++ * [32-62] = 0xff: Keep default CP0_shared_pins: ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0x8 0x8 0 0xff ++ 0 0 3 3 3 3 3 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0 0xff 0 0 0 0 ++ 0 0 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff>; ++}; ++ ++&cp1_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp1_spi1_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>; /* CS1 */ ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0>; ++ spi-max-frequency = <108000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0 0x200000>; ++ }; ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xce0000>; ++ }; ++ }; ++ }; ++}; ++ ++&cp1_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp1_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp1_comphy { ++ /* check if PCI is here, else none ++ * CP1 Serdes Configuration: ++ * Lane 0: UNCONNECTED ++ * Lane 1: UNCONNECTED ++ * Lane 2: UNCONNECTED ++ * Lane 3: UNCONNECTED ++ * Lane 4: SFI (10G) ++ * Lane 5: UNCONNECTED ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ phy1 { ++ phy-type = ; ++ }; ++ phy2 { ++ phy-type = ; ++ }; ++ phy3 { ++ phy-type = ; ++ }; ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp1_ethernet { ++ status = "okay"; ++}; ++ ++/* 10G SFI/copper */ ++&cp1_eth0 { ++ status = "okay"; ++ phy-mode = "sgmii"; ++ marvell,sfp-tx-disable-gpio = <&cp1_gpio0 10 GPIO_ACTIVE_HIGH>; ++}; +diff --git a/arch/arm/dts/armada-8040-ucpe.dts b/arch/arm/dts/armada-8040-ucpe.dts +new file mode 100644 +index 0000000000..5455095179 +--- /dev/null ++++ b/arch/arm/dts/armada-8040-ucpe.dts +@@ -0,0 +1,382 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++ ++#include "armada-8040.dtsi" /* include SoC device tree */ ++ ++/ { ++ model = "Marvell Armada 8040 uCPE"; ++ compatible = "marvell,armada-8040-ucpe", ++ "marvell,armada8040"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ i2c1 = &cp0_i2c1; ++ spi0 = &cp1_spi1; ++ gpio0 = &ap_gpio0; ++ gpio1 = &cp0_gpio0; ++ gpio2 = &cp0_gpio1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++ ++ simple-bus { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cp0_reg_usb3h0_vbus: usb3-right-port-vbus { ++ compatible = "regulator-fixed"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_xhci_vbus_pins0>; ++ regulator-name = "cp0_reg-usb3h0-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <300000>; ++ shutdown-delay-us = <500000>; ++ gpio = <&cp0_gpio1 10 GPIO_ACTIVE_LOW>; /* GPIO[42] */ ++ }; ++ ++ cp0_reg_usb3h1_vbus: usb3-left-port-vbus { ++ compatible = "regulator-fixed"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_xhci_vbus_pins1>; ++ regulator-name = "cp0_reg-usb3h1-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <300000>; ++ shutdown-delay-us = <500000>; ++ gpio = <&cp0_gpio1 11 GPIO_ACTIVE_LOW>; /* GPIO[43] */ ++ }; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&ap_pinctl { ++ /* ++ * MPP Bus: ++ * AP_SD_CLK [0] ++ * AP_SD_CMD [1] ++ * AP_SD_D[0~7] [2-10] ++ * UART0 [11,19] ++ * AP_SD_HW_RST [12] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 1 1 1 1 ++ 1 3 2 0 0 0 0 0 0 3 >; ++}; ++ ++/* on-board eMMC, KLM8G1GEME-B041 */ ++&ap_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ap_emmc_pins>; ++ bus-width = <8>; ++ status = "okay"; ++}; ++ ++&cp0_pinctl { ++ /* ++ * MPP Bus: ++ * [0-31] = 0xff: Keep default CP0_shared_pins: ++ * [32] CP1_PCIE1_CLKREQn ++ * [33] 10_SFP_LED ++ * [34] CP1_PCIE0_CLKREQn ++ * [35-36] CP0 I2C1 ++ * [37-38] CP0 I2C0 ++ * [39] PWM IC enable ++ * [40,41] CP0 SMI ++ * [42] USB3 PWR EN Port1 ++ * [43] USB3 PWR EN Port2 ++ * [44] CP0_PCIe0_clk_en ++ * [45] CP0 PCIe0 and PCIe1 RSTOUTn ++ * [46] CP0_PCIe0_waken ++ * [47] CP0_PCIe1_waken ++ * [48] CP0_PCIe1_clk_en / SFP 1G LED SW4 ++ * [49] CP0 PCIe0 wifi disable ++ * [50-51] CP0_UA2 ++ * [52] TP31 --> CP0_LED_CLK ? ++ * [53] TP32 --> CP0_LED_STB ? ++ * [54] CP0 LED data ++ * [55] Micro SD card detect ++ * [56-61] Micro SD ++ * [62] CP0 PCIe1 wifi disable ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0 0x9 0x0 0x9 0x2 0x2 0x2 0x2 0x0 ++ 0x8 0x8 0x0 0x0 0x0 0x9 0x0 0x0 0x0 0x0 ++ 0x6 0x6 0x8 0x8 0x0 0x0 0xe 0xe 0xe 0xe ++ 0xe 0xe 0x0 >; ++ ++ cp0_xhci_vbus_pins0: cpm-xhci-vbus-pins { ++ marvell,pins = < 42 >; ++ marvell,function = <0>; ++ }; ++ ++ cp0_xhci_vbus_pins1: cpm-xhci-vbus-pins { ++ marvell,pins = < 43 >; ++ marvell,function = <0>; ++ }; ++}; ++ ++&cp0_pcie0 { ++ status = "okay"; ++ reset-gpios = <&cp0_gpio1 13 GPIO_ACTIVE_HIGH>; ++ gpio = <&cp0_gpio1 12 GPIO_ACTIVE_HIGH>; /* MPP[44] clock enable*/ ++}; ++ ++&cp0_pcie1 { ++ status = "okay"; ++ reset-gpios = <&cp0_gpio1 13 GPIO_ACTIVE_HIGH>; ++ gpio = <&cp0_gpio1 16 GPIO_ACTIVE_HIGH>; /* MPP[48] clock enable*/ ++}; ++ ++&cp0_pcie2 { ++ status = "disabled"; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_i2c1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c1_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++/* uSD slot */ ++&cp0_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_sdhci_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&cp0_usb3_0 { ++ status = "okay"; ++ /* MPP[42] for USB3 port0 vbus on/off*/ ++ vbus-supply = <&cp0_reg_usb3h0_vbus>; ++}; ++ ++&cp0_usb3_1 { ++ status = "okay"; ++ /* MPP[43] for USB3 port0 vbus on/off*/ ++ vbus-supply = <&cp0_reg_usb3h1_vbus>; ++}; ++ ++&cp0_utmi0 { ++ status = "okay"; ++}; ++ ++&cp0_utmi1 { ++ status = "okay"; ++}; ++ ++&cp0_comphy { ++ /* ++ * CP0 Serdes Configuration: ++ * Lane 0: PCIE0 ++ * Lane 1: USB3 HOST0 ++ * Lane 2: SFI ++ * Lane 3: USB3 HOST1 ++ * Lane 4: PCIE1 ++ * Lane 5: NC ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ phy1 { ++ phy-type = ; ++ }; ++ phy2 { ++ phy-type = ; ++ }; ++ phy3 { ++ phy-type = ; ++ }; ++ phy4 { ++ phy-type = ; ++ }; ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ ++ mvswitch: switch@0{ ++ compatible = "marvell,mv88e6xxx"; ++ status = "okay"; ++ phy-addr = <0x0>; ++ cpu-port = <0xa>; ++ port-mask = <0x7FF>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++/* 10G SFI/copper */ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; ++}; ++ ++&cp1_sata0 { ++ status = "okay"; ++ gpio = <&cp1_gpio0 17 GPIO_ACTIVE_LOW>; ++}; ++ ++&cp1_usb3_0 { ++ status = "okay"; ++}; ++ ++&cp1_utmi0 { ++ status = "okay"; ++}; ++ ++&cp1_pinctl { ++ /* ++ * MPP Bus: ++ * [0-5] TDM ++ * [6,7] CP1_UART 0 ++ * [8] CP1 10G SFP LOS ++ * [9] CP1 10G TX FAULT ++ * [10] CP1 10G SFP TX Disable ++ * [11] CP1 10G SFP Mode ++ * [12] SPI1 CS1n ++ * [13] SPI1 MISO (TDM and SPI ROM shared) ++ * [14] SPI1 CS0n ++ * [15] SPI1 MOSI (TDM and SPI ROM shared) ++ * [16] SPI1 CLK (TDM and SPI ROM shared) ++ * [17] SSD DEV SLEEP (pull down to wake up SSD) ++ * [18] FAN PWM ++ * [19] PWM Sense ++ * [20] SFP 1G LED SW1 ++ * [21] SFP 1G LED SW2 ++ * [22] USB3 Port1 PWR overcurrent ? ++ * [23] USB3 Port2 PWR overcurrent ? ++ * [24] TP33 ++ * [25-28] LTE ++ * [29] PCA9535 int ++ * [30] E6390 int ++ * [31] E6390 RESETn ++ * [32-62] = 0xff: Keep default CP1_shared_pins: ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0x4 0x4 0x4 0x4 0x4 0x4 0x8 0x8 0x0 0x0 ++ 0x0 0x0 0x3 0x3 0x3 0x3 0x3 0x0 0x0 0x0 ++ 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ++ 0x0 0x0 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff 0xff ++ 0xff 0xff 0xff>; ++}; ++ ++&cp1_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp1_spi1_pins>; ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "jedec,spi-nor"; ++ reg = <0>; ++ spi-max-frequency = <10000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0 0x200000>; ++ }; ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xce0000>; ++ }; ++ }; ++ }; ++}; ++ ++&cp1_comphy { ++ /* ++ * CP1 Serdes Configuration: ++ * Lane 0: SATA 1 ++ * Lane 1: SATA 0 ++ * Lane 2: USB HOST 0 ++ * Lane 3: HS-SGMII ++ * Lane 4: RXAUI0 ++ * Lane 5: RXAUI1 ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ phy1 { ++ phy-type = ; ++ }; ++ phy2 { ++ phy-type = ; ++ }; ++ phy3 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ phy4 { ++ phy-type = ; ++ }; ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp1_ethernet { ++ status = "okay"; ++}; ++ ++/* 10G RXAUI to E6390X port9 - CP1 SRDS[4:5] */ ++&cp1_eth0 { ++ status = "disabled"; ++ phy-mode = "rxaui"; ++}; ++ ++/* 2.5G SGMii to E6390X port10 - CP1 SRDS[3] */ ++&cp1_eth1 { ++ status = "okay"; ++ phy-mode = "sgmii-2500"; ++ phy = <&mvswitch>; ++ marvell,sfp-tx-disable-gpio = <&cp1_gpio0 24 GPIO_ACTIVE_HIGH>; ++ fixed-link { ++ speed = <2500>; ++ full-duplex; ++ }; ++}; ++ ++&cp1_eth2 { ++ status = "disabled"; ++}; +diff --git a/arch/arm/dts/armada-8040.dtsi b/arch/arm/dts/armada-8040.dtsi +index 96cc112ac9..9d701c4a87 100644 +--- a/arch/arm/dts/armada-8040.dtsi ++++ b/arch/arm/dts/armada-8040.dtsi +@@ -46,12 +46,96 @@ + */ + + #include +-#include "armada-ap806-quad.dtsi" +-#include "armada-cp110-master.dtsi" +-#include "armada-cp110-slave.dtsi" ++#include "armada-common.dtsi" ++#include "armada-8k.dtsi" ++#include "armada-ap806.dtsi" ++#include "armada-ap80x-quad.dtsi" ++ ++/* CP110-0 Settings */ ++#define CP110_NAME cp0 ++#define CP110_NUM 0 ++ ++#include "armada-cp110.dtsi" ++ ++#undef CP110_NAME ++#undef CP110_NUM ++ ++/* CP110-1 Settings */ ++#define CP110_NAME cp1 ++#define CP110_NUM 1 ++ ++#include "armada-cp110.dtsi" ++ ++#undef CP110_NAME ++#undef CP110_NUM + + / { + model = "Marvell Armada 8040"; + compatible = "marvell,armada8040", "marvell,armada-ap806-quad", + "marvell,armada-ap806"; + }; ++ ++&cp0_rtc { ++ status = "okay"; ++}; ++ ++&cp0_pinctl { ++ compatible = "marvell,mvebu-pinctrl", "marvell,armada-8k-cpm-pinctrl"; ++ bank-name ="cp0-110"; ++ ++ cp0_i2c0_pins: cp0-i2c-pins-0 { ++ marvell,pins = < 37 38 >; ++ marvell,function = <2>; ++ }; ++ cp0_i2c1_pins: cp0-i2c-pins-1 { ++ marvell,pins = < 35 36 >; ++ marvell,function = <2>; ++ }; ++ cp0_ge1_rgmii_pins: cp0-ge-rgmii-pins-0 { ++ marvell,pins = < 0 1 2 3 4 5 6 7 8 9 10 11>; ++ marvell,function = <3>; ++ }; ++ cp0_ge2_rgmii_pins: cp0-ge-rgmii-pins-1 { ++ marvell,pins = < 44 45 46 47 48 49 50 51 ++ 52 53 54 55 >; ++ marvell,function = <1>; ++ }; ++ cp0_pca0_pins: cp0-pca0_pins { ++ marvell,pins = <62>; ++ marvell,function = <0>; ++ }; ++ cp0_sdhci_pins: cp0-sdhi-pins-0 { ++ marvell,pins = < 56 57 58 59 60 61 >; ++ marvell,function = <14>; ++ }; ++ cp0_spi0_pins: cp0-spi-pins-0 { ++ marvell,pins = < 13 14 15 16 >; ++ marvell,function = <3>; ++ }; ++}; ++ ++&cp1_pinctl { ++ compatible = "marvell,mvebu-pinctrl", "marvell,armada-8k-cps-pinctrl"; ++ bank-name ="cp1-110"; ++ ++ cp1_ge1_rgmii_pins: cp1-ge-rgmii-pins-0 { ++ marvell,pins = < 0 1 2 3 4 5 6 7 8 9 10 11 >; ++ marvell,function = <3>; ++ }; ++ cp1_spi1_pins: cp1-spi-pins-1 { ++ marvell,pins = < 13 14 15 16 >; ++ marvell,function = <3>; ++ }; ++ ++ cp1_nand_pins: cp1-nand-pins { ++ marvell,pins = < 0 1 2 3 4 5 6 7 8 ++ 9 10 11 14 15 16 17 18 19 ++ 20 21 22 23 24 25 26 27 >; ++ marvell,function = <1>; ++ }; ++ ++ cp1_nand_rb: cp1-nand-rb { ++ marvell,pins = < 12 13 >; ++ marvell,function = <2>; ++ }; ++}; +diff --git a/arch/arm/dts/armada-80x0-db.dtsi b/arch/arm/dts/armada-80x0-db.dtsi +new file mode 100644 +index 0000000000..fe074e07bf +--- /dev/null ++++ b/arch/arm/dts/armada-80x0-db.dtsi +@@ -0,0 +1,143 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#include "armada-8040.dtsi" /* include SoC device tree */ ++#include "armada-8040-dev-info.dtsi" ++ ++/ { ++ compatible = "marvell,armada-80x0-db", "marvell,armada-8040"; ++ model = "DB-ARMADA-80x0"; ++ ++ cp0 { ++ config-space { ++ i2c@701000 { ++ expander0: pca953x@21 { ++ compatible = "nxp,pca9555"; ++ #gpio-cells = <2>; ++ reg = <0x21>; ++ status = "okay"; ++ }; ++ expander1: pca953x@25 { ++ compatible = "nxp,pca9555"; ++ #gpio-cells = <2>; ++ reg = <0x25>; ++ status = "okay"; ++ }; ++ }; ++ ++ sdhci@780000 { ++ vqmmc-supply = <&cp0_reg_sd_vccq>; ++ }; ++ ++ cp0_reg_usb3_vbus0:cp0_usb3_vbus@0 { ++ compatible = "regulator-fixed"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <100000>; ++ regulator-force-boot-off; ++ gpio = <&expander0 0 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ cp0_reg_usb3_vbus1: cp0_usb3_vbus@1 { ++ compatible = "regulator-fixed"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <100000>; ++ regulator-force-boot-off; ++ gpio = <&expander0 1 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ cp0_reg_usb3_current_limiter0:cp0_usb3_current_limiter@0 { ++ compatible = "regulator-fixed"; ++ regulator-min-microamp = <900000>; ++ regulator-max-microamp = <900000>; ++ regulator-force-boot-off; ++ gpio = <&expander0 4 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ cp0_reg_usb3_current_limiter1: cp0_usb3_current_limiter@1 { ++ compatible = "regulator-fixed"; ++ regulator-min-microamp = <900000>; ++ regulator-max-microamp = <900000>; ++ regulator-force-boot-off; ++ gpio = <&expander0 5 GPIO_ACTIVE_HIGH>; ++ }; ++ /* ++ * Even though this node used for enable/disable ++ * cp1 usb vbus-supply, we use "cp0" prefix since ++ * the expander is connected to cp0. ++ */ ++ cp0_reg_usb3_vbus2: cp0_usb3_vbus@2 { ++ compatible = "regulator-fixed"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <100000>; ++ regulator-force-boot-off; ++ gpio = <&expander1 0 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ cp0_reg_usb3_vbus3: cp0_usb3_vbus@3 { ++ compatible = "regulator-fixed"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <100000>; ++ regulator-force-boot-off; ++ gpio = <&expander1 1 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ cp0_reg_usb3_current_limiter2: cp0_usb3_current_limiter@2 { ++ compatible = "regulator-fixed"; ++ regulator-min-microamp = <900000>; ++ regulator-max-microamp = <900000>; ++ regulator-force-boot-off; ++ gpio = <&expander1 4 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ cp0_usb3_0: usb3@500000 { ++ vbus-supply = <&cp0_reg_usb3_vbus0>; ++ current-limiter = <&cp0_reg_usb3_current_limiter0>; ++ vbus-disable-delay = <500>; ++ }; ++ cp0_usb3_1: usb3@510000 { ++ vbus-supply = <&cp0_reg_usb3_vbus1>; ++ current-limiter = <&cp0_reg_usb3_current_limiter1>; ++ vbus-disable-delay = <500>; ++ }; ++ ++ cp0_reg_sd_vccq: cp0_sd_vccq@0 { ++ compatible = "regulator-gpio"; ++ regulator-name = "cp0_sd_vcc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ gpios = <&expander0 15 GPIO_ACTIVE_HIGH>; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ }; ++ }; ++ }; ++ ++#define CP110_NUM 1 ++#define SPI_DIRECT_BASE (0xf9000000) ++ ++ cp1 { ++ config-space { ++ ranges = <0x0 U64_TO_U32_H(CP110_BASE) U64_TO_U32_L(CP110_BASE) 0x2000000>, /* internal regs */ ++ <0x2000000 U64_TO_U32_H(SPI_DIRECT_BASE) U64_TO_U32_L(SPI_DIRECT_BASE) 0x1000000>; /* SPI1-DEV0 */ ++ ++ cp1_usb3_0: usb3@500000 { ++ vbus-supply = <&cp0_reg_usb3_vbus2>; ++ current-limiter = <&cp0_reg_usb3_current_limiter2>; ++ vbus-disable-delay = <500>; ++ }; ++ ++ cp1_usb3_1: usb3@510000 { ++ vbus-supply = <&cp0_reg_usb3_vbus3>; ++ vbus-disable-delay = <500>; ++ }; ++ ++ }; ++ }; ++#undef CP110_NUM ++}; +diff --git a/arch/arm/dts/armada-8k.dtsi b/arch/arm/dts/armada-8k.dtsi +new file mode 100644 +index 0000000000..60076d48c2 +--- /dev/null ++++ b/arch/arm/dts/armada-8k.dtsi +@@ -0,0 +1,20 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++/* Common definitions used by Armada 8K DTs */ ++ ++/* This defines used to calculate the base address of each CP */ ++#define CP110_BASE_OFFSET (0xf2000000) ++#define CP110_SPACE_SIZE (0x02000000) ++#define CP110_BASE (CP110_BASE_OFFSET + \ ++ ((CP110_NUM % 2) * CP110_SPACE_SIZE)) ++ ++#define CP110_PCIE_MEM_SIZE(iface) (0xf00000) ++#define CP110_PCIEx_CPU_MEM_BASE(iface) \ ++ (0xf6000000 + (CP110_NUM % 2) * 0x4000000 + (iface) * 0x1000000) ++#define CP110_PCIEx_BUS_MEM_BASE(iface) \ ++ (CP110_PCIEx_CPU_MEM_BASE(iface)) ++#define CP110_PCIE_BUS_MEM_CFG (0x82000000) +diff --git a/arch/arm/dts/armada-ap806-quad.dtsi b/arch/arm/dts/armada-ap806-quad.dtsi +deleted file mode 100644 +index ba43a4357b..0000000000 +--- a/arch/arm/dts/armada-ap806-quad.dtsi ++++ /dev/null +@@ -1,82 +0,0 @@ +-/* +- * Copyright (C) 2016 Marvell Technology Group Ltd. +- * +- * This file is dual-licensed: you can use it either under the terms +- * of the GPLv2 or the X11 license, at your option. Note that this dual +- * licensing only applies to this file, and not this project as a +- * whole. +- * +- * a) This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License as +- * published by the Free Software Foundation; either version 2 of the +- * License, or (at your option) any later version. +- * +- * This library is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * Or, alternatively, +- * +- * b) Permission is hereby granted, free of charge, to any person +- * obtaining a copy of this software and associated documentation +- * files (the "Software"), to deal in the Software without +- * restriction, including without limitation the rights to use, +- * copy, modify, merge, publish, distribute, sublicense, and/or +- * sell copies of the Software, and to permit persons to whom the +- * Software is furnished to do so, subject to the following +- * conditions: +- * +- * The above copyright notice and this permission notice shall be +- * included in all copies or substantial portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +- * OTHER DEALINGS IN THE SOFTWARE. +- */ +- +-/* +- * Device Tree file for Marvell Armada AP806. +- */ +- +-#include "armada-ap806.dtsi" +- +-/ { +- model = "Marvell Armada AP806 Quad"; +- compatible = "marvell,armada-ap806-quad", "marvell,armada-ap806"; +- +- cpus { +- #address-cells = <1>; +- #size-cells = <0>; +- +- cpu@000 { +- device_type = "cpu"; +- compatible = "arm,cortex-a72", "arm,armv8"; +- reg = <0x000>; +- enable-method = "psci"; +- }; +- cpu@001 { +- device_type = "cpu"; +- compatible = "arm,cortex-a72", "arm,armv8"; +- reg = <0x001>; +- enable-method = "psci"; +- }; +- cpu@100 { +- device_type = "cpu"; +- compatible = "arm,cortex-a72", "arm,armv8"; +- reg = <0x100>; +- enable-method = "psci"; +- }; +- cpu@101 { +- device_type = "cpu"; +- compatible = "arm,cortex-a72", "arm,armv8"; +- reg = <0x101>; +- enable-method = "psci"; +- }; +- }; +-}; +diff --git a/arch/arm/dts/armada-ap806.dtsi b/arch/arm/dts/armada-ap806.dtsi +index 713c2dba74..6a8eced524 100644 +--- a/arch/arm/dts/armada-ap806.dtsi ++++ b/arch/arm/dts/armada-ap806.dtsi +@@ -44,231 +44,32 @@ + * Device Tree file for Marvell Armada AP806. + */ + +-#include ++/* AP806 Settings */ ++#define AP_NAME ap806 + +-/dts-v1/; ++#include "armada-ap80x.dtsi" + + / { + model = "Marvell Armada AP806"; +- compatible = "marvell,armada-ap806"; +- #address-cells = <2>; +- #size-cells = <2>; +- +- aliases { +- serial0 = &uart0; +- serial1 = &uart1; +- }; +- +- psci { +- compatible = "arm,psci-0.2"; +- method = "smc"; +- }; +- +- reserved-memory { +- #address-cells = <2>; +- #size-cells = <2>; +- ranges; +- +- psci-area@4000000 { +- reg = <0x0 0x4000000 0x0 0x200000>; +- no-map; +- }; +- }; +- +- ap806 { +- #address-cells = <2>; +- #size-cells = <2>; +- compatible = "simple-bus"; +- interrupt-parent = <&gic>; +- ranges; + ++ AP_NAME { + config-space { +- #address-cells = <1>; +- #size-cells = <1>; +- compatible = "simple-bus"; +- ranges = <0x0 0x0 0xf0000000 0x1000000>; +- +- gic: interrupt-controller@210000 { +- compatible = "arm,gic-400"; +- #interrupt-cells = <3>; +- #address-cells = <1>; +- #size-cells = <1>; +- ranges; +- interrupt-controller; +- interrupts = ; +- reg = <0x210000 0x10000>, +- <0x220000 0x20000>, +- <0x240000 0x20000>, +- <0x260000 0x20000>; +- +- gic_v2m0: v2m@280000 { +- compatible = "arm,gic-v2m-frame"; +- msi-controller; +- reg = <0x280000 0x1000>; +- arm,msi-base-spi = <160>; +- arm,msi-num-spis = <32>; +- }; +- gic_v2m1: v2m@290000 { +- compatible = "arm,gic-v2m-frame"; +- msi-controller; +- reg = <0x290000 0x1000>; +- arm,msi-base-spi = <192>; +- arm,msi-num-spis = <32>; +- }; +- gic_v2m2: v2m@2a0000 { +- compatible = "arm,gic-v2m-frame"; +- msi-controller; +- reg = <0x2a0000 0x1000>; +- arm,msi-base-spi = <224>; +- arm,msi-num-spis = <32>; +- }; +- gic_v2m3: v2m@2b0000 { +- compatible = "arm,gic-v2m-frame"; +- msi-controller; +- reg = <0x2b0000 0x1000>; +- arm,msi-base-spi = <256>; +- arm,msi-num-spis = <32>; +- }; +- }; +- +- timer { +- compatible = "arm,armv8-timer"; +- interrupts = , +- , +- , +- ; +- }; +- +- odmi: odmi@300000 { +- compatible = "marvell,odmi-controller"; +- interrupt-controller; +- msi-controller; +- marvell,odmi-frames = <4>; +- reg = <0x300000 0x4000>, +- <0x304000 0x4000>, +- <0x308000 0x4000>, +- <0x30C000 0x4000>; +- marvell,spi-base = <128>, <136>, <144>, <152>; +- }; +- +- ap_pinctl: ap-pinctl@6F4000 { +- compatible = "marvell,ap806-pinctrl"; +- bank-name ="apn-806"; +- reg = <0x6F4000 0x10>; +- pin-count = <20>; +- max-func = <3>; +- +- ap_i2c0_pins: i2c-pins-0 { +- marvell,pins = < 4 5 >; +- marvell,function = <3>; +- }; +- ap_emmc_pins: emmc-pins-0 { +- marvell,pins = < 0 1 2 3 4 5 6 7 +- 8 9 10 >; +- marvell,function = <1>; +- }; +- }; +- +- ap_gpio0: gpio@6F5040 { +- compatible = "marvell,orion-gpio"; +- reg = <0x6F5040 0x40>; +- ngpios = <20>; +- gpio-controller; +- #gpio-cells = <2>; +- }; +- +- xor@400000 { +- compatible = "marvell,mv-xor-v2"; +- reg = <0x400000 0x1000>, +- <0x410000 0x1000>; +- msi-parent = <&gic_v2m0>; +- dma-coherent; +- }; +- +- xor@420000 { +- compatible = "marvell,mv-xor-v2"; +- reg = <0x420000 0x1000>, +- <0x430000 0x1000>; +- msi-parent = <&gic_v2m0>; +- dma-coherent; +- }; +- +- xor@440000 { +- compatible = "marvell,mv-xor-v2"; +- reg = <0x440000 0x1000>, +- <0x450000 0x1000>; +- msi-parent = <&gic_v2m0>; +- dma-coherent; +- }; +- +- xor@460000 { +- compatible = "marvell,mv-xor-v2"; +- reg = <0x460000 0x1000>, +- <0x470000 0x1000>; +- msi-parent = <&gic_v2m0>; +- dma-coherent; +- }; +- +- spi0: spi@510600 { +- compatible = "marvell,armada-380-spi"; +- reg = <0x510600 0x50>; +- #address-cells = <1>; +- #size-cells = <0>; +- cell-index = <0>; +- interrupts = ; +- clocks = <&ap_syscon 3>; +- status = "disabled"; +- }; +- +- i2c0: i2c@511000 { +- compatible = "marvell,mv78230-i2c"; +- reg = <0x511000 0x20>; +- #address-cells = <1>; +- #size-cells = <0>; +- interrupts = ; +- timeout-ms = <1000>; +- clocks = <&ap_syscon 3>; +- status = "disabled"; +- }; +- +- uart0: serial@512000 { +- compatible = "snps,dw-apb-uart"; +- reg = <0x512000 0x100>; +- reg-shift = <2>; +- interrupts = ; +- reg-io-width = <1>; +- clocks = <&ap_syscon 3>; +- status = "disabled"; +- clock-frequency = <200000000>; +- }; +- +- uart1: serial@512100 { +- compatible = "snps,dw-apb-uart"; +- reg = <0x512100 0x100>; +- reg-shift = <2>; +- interrupts = ; +- reg-io-width = <1>; +- clocks = <&ap_syscon 3>; +- status = "disabled"; +- +- }; +- +- ap_sdhci0: sdhci@6e0000 { +- compatible = "marvell,armada-8k-sdhci"; +- reg = <0x6e0000 0x300>; +- interrupts = ; +- dma-coherent; +- status = "disabled"; ++ sar-reg { ++ compatible = "marvell,sample-at-reset-common", ++ "marvell,sample-at-reset-ap806"; ++ reg = <0x6F8200 0x8>; ++ sar-driver = "ap806_sar"; ++ sar-name = "ap806_sar"; ++ status = "okay"; + }; + +- ap_syscon: system-controller@6f4000 { +- compatible = "marvell,ap806-system-controller", +- "syscon"; +- #clock-cells = <1>; +- clock-output-names = "ap-cpu-cluster-0", +- "ap-cpu-cluster-1", +- "ap-fixed", "ap-mss"; +- reg = <0x6f4000 0x1000>; ++ thermal: thermal@6f8084 { ++ compatible = "marvell,mvebu-thermal", "marvell,thermal-ext-sensor"; ++ reg = <0x6f8084 0x12>; ++ gain = <425>; ++ offset = <153400>; ++ divisor = <1000>; ++ status = "okay"; + }; + }; + }; +diff --git a/arch/arm/dts/armada-ap807.dtsi b/arch/arm/dts/armada-ap807.dtsi +new file mode 100644 +index 0000000000..848e3fb363 +--- /dev/null ++++ b/arch/arm/dts/armada-ap807.dtsi +@@ -0,0 +1,42 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada AP807. ++ */ ++ ++/* AP807 Settings */ ++#define AP_NAME ap807 ++ ++#include "armada-ap80x.dtsi" ++ ++/ { ++ model = "Marvell Armada AP807"; ++ ++ AP_NAME { ++ config-space { ++ sar-reg { ++ compatible = "marvell,sample-at-reset-common", ++ "marvell,sample-at-reset-ap807"; ++ reg = <0x6F8200 0x8>; ++ sar-driver = "ap807_sar"; ++ sar-name = "ap807_sar"; ++ status = "okay"; ++ }; ++ ++ thermal: thermal@6f8084 { ++ compatible = "marvell,mvebu-thermal", ++ "marvell,thermal-ext-sensor"; ++ reg = <0x6f8084 0x12>; ++ gain = <394>; ++ offset = <128900>; ++ divisor = <1000>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/armada-ap80x-quad.dtsi b/arch/arm/dts/armada-ap80x-quad.dtsi +new file mode 100644 +index 0000000000..d5d85db619 +--- /dev/null ++++ b/arch/arm/dts/armada-ap80x-quad.dtsi +@@ -0,0 +1,45 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada AP806/AP807. ++ */ ++ ++/ { ++ model = "Marvell Armada AP80X Quad"; ++ compatible = "marvell,armada-ap806-quad", "marvell,armada-ap806"; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@000 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a72", "arm,armv8"; ++ reg = <0x000>; ++ enable-method = "psci"; ++ }; ++ cpu@001 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a72", "arm,armv8"; ++ reg = <0x001>; ++ enable-method = "psci"; ++ }; ++ cpu@100 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a72", "arm,armv8"; ++ reg = <0x100>; ++ enable-method = "psci"; ++ }; ++ cpu@101 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a72", "arm,armv8"; ++ reg = <0x101>; ++ enable-method = "psci"; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/armada-ap80x.dtsi b/arch/arm/dts/armada-ap80x.dtsi +new file mode 100644 +index 0000000000..51bb6082be +--- /dev/null ++++ b/arch/arm/dts/armada-ap80x.dtsi +@@ -0,0 +1,144 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++/* ++ * Device Tree file for Marvell Armada AP806/AP807. ++ */ ++ ++/dts-v1/; ++/ { ++ compatible = "marvell,armada-ap806"; ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ }; ++ ++ psci { ++ compatible = "arm,psci-0.2"; ++ method = "smc"; ++ }; ++ ++ reserved-memory { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ psci-area@4000000 { ++ reg = <0x0 0x4000000 0x0 0x200000>; ++ no-map; ++ }; ++ }; ++ ++ AP_NAME { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ compatible = "simple-bus"; ++ ranges; ++ ++ config-space { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "simple-bus"; ++ ranges = <0x0 0x0 0xf0000000 0x1000000>; ++ ++ ap_pinctl: ap-pinctl@6F4000 { ++ compatible = "marvell,ap806-pinctrl"; ++ bank-name ="apn-806"; ++ reg = <0x6F4000 0x10>; ++ pin-count = <20>; ++ max-func = <3>; ++ ++ ap_i2c0_pins: i2c-pins-0 { ++ marvell,pins = < 4 5 >; ++ marvell,function = <3>; ++ }; ++ ap_emmc_pins: emmc-pins-0 { ++ marvell,pins = < 0 1 2 3 4 5 6 7 ++ 8 9 10 12 >; ++ marvell,function = <1>; ++ }; ++ }; ++ ++ ap_gpio0: gpio@6F5040 { ++ compatible = "marvell,orion-gpio"; ++ reg = <0x6F5040 0x40>; ++ ngpios = <20>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ }; ++ ++ ap_spi0: spi@510600 { ++ compatible = "marvell,armada-380-spi"; ++ reg = <0x510600 0x50>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ cell-index = <0>; ++ spi-max-frequency = <50000000>; ++ status = "disabled"; ++ }; ++ ++ ap_i2c0: i2c@511000 { ++ compatible = "marvell,mv78230-i2c"; ++ reg = <0x511000 0x20>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ timeout-ms = <1000>; ++ status = "disabled"; ++ }; ++ ++ uart0: serial@512000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x512000 0x100>; ++ reg-shift = <2>; ++ reg-io-width = <1>; ++ status = "disabled"; ++ clock-frequency = <200000000>; ++ }; ++ ++ uart1: serial@512100 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x512100 0x100>; ++ reg-shift = <2>; ++ reg-io-width = <1>; ++ status = "disabled"; ++ ++ }; ++ ++ ap_sdhci0: sdhci@6e0000 { ++ compatible = "marvell,armada-8k-sdhci"; ++ reg = <0x6e0000 0x300>; ++ dma-coherent; ++ status = "disabled"; ++ }; ++ ++ ap_ld_efuse0: efuse-0@6F8F00 { ++ compatible = "marvell,mvebu-fuse-ld-user"; ++ reg = <0x6F8008 0x4>; ++ otp-mem = <0x6F8F00>; ++ status = "disabled"; ++ }; ++ ++ ap_ld_efuse1: efuse-1@6F8F00 { ++ compatible = "marvell,mvebu-fuse-ld-prop"; ++ reg = <0x6F8008 0x4>; ++ otp-mem = <0x6F8F00>; ++ status = "disabled"; ++ }; ++ ++ ap_hd_efuse0: efuse@6F9000 { ++ compatible = "marvell,mvebu-fuse-hd"; ++ reg = <0x6F8008 0x4>; ++ otp-mem = <0x6F9000>; ++ rows-count = <64>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/armada-common.dtsi b/arch/arm/dts/armada-common.dtsi +new file mode 100644 +index 0000000000..34bd7e3230 +--- /dev/null ++++ b/arch/arm/dts/armada-common.dtsi +@@ -0,0 +1,30 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++/* Common definitions used by Armada 7K/8K DTs */ ++#define PASTER(x, y) x ## _ ## y ++#define EVALUATOR(x, y) PASTER(x, y) ++ ++/* This define used to create die label: ++ * For example: ++ * CP110 master: ++ * CP110_LABEL(spi0) -> cp0_spi0 ++ * CP110 slave: ++ * CP110_LABEL(usb0) -> cp1_usb0 ++ */ ++#define CP110_LABEL(name) EVALUATOR(CP110_NAME, name) ++ ++#define APPEND_NX(A, B) A ##-## B ++#define APPEND(A, B) APPEND_NX(A, B) ++ ++#define STRINGIZE_NX(x) #x ++#define STRINGIZE(x) STRINGIZE_NX(x) ++ ++/* Same idea here, but this define convert the name to string: ++ * For example: ++ * master: CP110_STRING_LABEL(ppv2) -> "cp0-ppv2" ++ * slave: CP110_STRING_LABEL(ppv2) -> "cp1-ppv2" ++ */ ++#define CP110_STRING_LABEL(name) STRINGIZE(APPEND(CP110_NAME, name)) +diff --git a/arch/arm/dts/armada-cp110-master.dtsi b/arch/arm/dts/armada-cp110-master.dtsi +deleted file mode 100644 +index e4c17e9f4b..0000000000 +--- a/arch/arm/dts/armada-cp110-master.dtsi ++++ /dev/null +@@ -1,370 +0,0 @@ +-/* +- * Copyright (C) 2016 Marvell Technology Group Ltd. +- * +- * This file is dual-licensed: you can use it either under the terms +- * of the GPLv2 or the X11 license, at your option. Note that this dual +- * licensing only applies to this file, and not this project as a +- * whole. +- * +- * a) This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License as +- * published by the Free Software Foundation; either version 2 of the +- * License, or (at your option) any later version. +- * +- * This library is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * Or, alternatively, +- * +- * b) Permission is hereby granted, free of charge, to any person +- * obtaining a copy of this software and associated documentation +- * files (the "Software"), to deal in the Software without +- * restriction, including without limitation the rights to use, +- * copy, modify, merge, publish, distribute, sublicense, and/or +- * sell copies of the Software, and to permit persons to whom the +- * Software is furnished to do so, subject to the following +- * conditions: +- * +- * The above copyright notice and this permission notice shall be +- * included in all copies or substantial portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +- * OTHER DEALINGS IN THE SOFTWARE. +- */ +- +-/* +- * Device Tree file for Marvell Armada CP110 Master. +- */ +- +-#include +- +-/ { +- cp110-master { +- #address-cells = <2>; +- #size-cells = <2>; +- compatible = "simple-bus"; +- interrupt-parent = <&gic>; +- ranges; +- +- config-space { +- #address-cells = <1>; +- #size-cells = <1>; +- compatible = "simple-bus"; +- interrupt-parent = <&gic>; +- ranges = <0x0 0x0 0xf2000000 0x2000000>; +- +- cpm_ethernet: ethernet@0 { +- compatible = "marvell,armada-7k-pp22"; +- reg = <0x0 0x100000>, <0x129000 0xb000>; +- clocks = <&cpm_syscon0 1 3>, <&cpm_syscon0 1 9>, <&cpm_syscon0 1 5>; +- clock-names = "pp_clk", "gop_clk", "mg_clk"; +- status = "disabled"; +- dma-coherent; +- +- cpm_eth0: eth0 { +- interrupts = ; +- port-id = <0>; +- gop-port-id = <0>; +- status = "disabled"; +- }; +- +- cpm_eth1: eth1 { +- interrupts = ; +- port-id = <1>; +- gop-port-id = <2>; +- status = "disabled"; +- }; +- +- cpm_eth2: eth2 { +- interrupts = ; +- port-id = <2>; +- gop-port-id = <3>; +- status = "disabled"; +- }; +- }; +- +- cpm_mdio: mdio@12a200 { +- #address-cells = <1>; +- #size-cells = <0>; +- compatible = "marvell,orion-mdio"; +- reg = <0x12a200 0x10>; +- device-name = "cpm-mdio"; +- }; +- +- cpm_syscon0: system-controller@440000 { +- compatible = "marvell,cp110-system-controller0", +- "syscon"; +- reg = <0x440000 0x1000>; +- #clock-cells = <2>; +- core-clock-output-names = +- "cpm-apll", "cpm-ppv2-core", "cpm-eip", +- "cpm-core", "cpm-nand-core"; +- gate-clock-output-names = +- "cpm-audio", "cpm-communit", "cpm-nand", +- "cpm-ppv2", "cpm-sdio", "cpm-mg-domain", +- "cpm-mg-core", "cpm-xor1", "cpm-xor0", +- "cpm-gop-dp", "none", "cpm-pcie_x10", +- "cpm-pcie_x11", "cpm-pcie_x4", "cpm-pcie-xor", +- "cpm-sata", "cpm-sata-usb", "cpm-main", +- "cpm-sd-mmc", "none", "none", +- "cpm-slow-io", "cpm-usb3h0", "cpm-usb3h1", +- "cpm-usb3dev", "cpm-eip150", "cpm-eip197"; +- }; +- +- cpm_pinctl: cpm-pinctl@440000 { +- compatible = "marvell,mvebu-pinctrl", +- "marvell,armada-7k-pinctrl", +- "marvell,armada-8k-cpm-pinctrl"; +- bank-name ="cp0-110"; +- reg = <0x440000 0x20>; +- pin-count = <63>; +- max-func = <0xf>; +- +- cpm_i2c0_pins: cpm-i2c-pins-0 { +- marvell,pins = < 37 38 >; +- marvell,function = <2>; +- }; +- cpm_i2c1_pins: cpm-i2c-pins-1 { +- marvell,pins = < 35 36 >; +- marvell,function = <2>; +- }; +- cpm_ge2_rgmii_pins: cpm-ge-rgmii-pins-0 { +- marvell,pins = < 44 45 46 47 48 49 50 51 +- 52 53 54 55 >; +- marvell,function = <1>; +- }; +- pca0_pins: cpm-pca0_pins { +- marvell,pins = <62>; +- marvell,function = <0>; +- }; +- cpm_sdhci_pins: cpm-sdhi-pins-0 { +- marvell,pins = < 56 57 58 59 60 61 >; +- marvell,function = <14>; +- }; +- cpm_spi0_pins: cpm-spi-pins-0 { +- marvell,pins = < 13 14 15 16 >; +- marvell,function = <3>; +- }; +- }; +- +- cpm_gpio0: gpio@440100 { +- compatible = "marvell,orion-gpio"; +- reg = <0x440100 0x40>; +- ngpios = <32>; +- gpiobase = <20>; +- gpio-controller; +- #gpio-cells = <2>; +- }; +- +- cpm_gpio1: gpio@440140 { +- compatible = "marvell,orion-gpio"; +- reg = <0x440140 0x40>; +- ngpios = <31>; +- gpiobase = <52>; +- gpio-controller; +- #gpio-cells = <2>; +- }; +- +- cpm_sata0: sata@540000 { +- compatible = "marvell,armada-8k-ahci"; +- reg = <0x540000 0x30000>; +- interrupts = ; +- clocks = <&cpm_syscon0 1 15>; +- status = "disabled"; +- }; +- +- cpm_usb3_0: usb3@500000 { +- compatible = "marvell,armada-8k-xhci", +- "generic-xhci"; +- reg = <0x500000 0x4000>; +- dma-coherent; +- interrupts = ; +- clocks = <&cpm_syscon0 1 22>; +- status = "disabled"; +- }; +- +- cpm_usb3_1: usb3@510000 { +- compatible = "marvell,armada-8k-xhci", +- "generic-xhci"; +- reg = <0x510000 0x4000>; +- dma-coherent; +- interrupts = ; +- clocks = <&cpm_syscon0 1 23>; +- status = "disabled"; +- }; +- +- cpm_spi0: spi@700600 { +- compatible = "marvell,armada-380-spi"; +- reg = <0x700600 0x50>; +- #address-cells = <0x1>; +- #size-cells = <0x0>; +- cell-index = <1>; +- clocks = <&cpm_syscon0 0 3>; +- status = "disabled"; +- }; +- +- cpm_spi1: spi@700680 { +- compatible = "marvell,armada-380-spi"; +- reg = <0x700680 0x50>; +- #address-cells = <1>; +- #size-cells = <0>; +- cell-index = <2>; +- clocks = <&cpm_syscon0 1 21>; +- status = "disabled"; +- }; +- +- cpm_i2c0: i2c@701000 { +- compatible = "marvell,mv78230-i2c"; +- reg = <0x701000 0x20>; +- #address-cells = <1>; +- #size-cells = <0>; +- interrupts = ; +- clocks = <&cpm_syscon0 1 21>; +- status = "disabled"; +- }; +- +- cpm_i2c1: i2c@701100 { +- compatible = "marvell,mv78230-i2c"; +- reg = <0x701100 0x20>; +- #address-cells = <1>; +- #size-cells = <0>; +- interrupts = ; +- clocks = <&cpm_syscon0 1 21>; +- status = "disabled"; +- }; +- +- cpm_comphy: comphy@441000 { +- compatible = "marvell,mvebu-comphy", "marvell,comphy-cp110"; +- reg = <0x441000 0x8>, +- <0x120000 0x8>; +- mux-bitcount = <4>; +- max-lanes = <6>; +- }; +- +- cpm_utmi0: utmi@580000 { +- compatible = "marvell,mvebu-utmi-2.6.0"; +- reg = <0x580000 0x1000>, /* utmi-unit */ +- <0x440420 0x4>, /* usb-cfg */ +- <0x440440 0x4>; /* utmi-cfg */ +- utmi-port = ; +- status = "disabled"; +- }; +- +- cpm_utmi1: utmi@581000 { +- compatible = "marvell,mvebu-utmi-2.6.0"; +- reg = <0x581000 0x1000>, /* utmi-unit */ +- <0x440420 0x4>, /* usb-cfg */ +- <0x440444 0x4>; /* utmi-cfg */ +- utmi-port = ; +- status = "disabled"; +- }; +- +- cpm_sdhci0: sdhci@780000 { +- compatible = "marvell,armada-8k-sdhci"; +- reg = <0x780000 0x300>; +- interrupts = ; +- dma-coherent; +- status = "disabled"; +- }; +- +- cpm_nand: nand@720000 { +- compatible = "marvell,mvebu-pxa3xx-nand"; +- reg = <0x720000 0x100>; +- #address-cells = <1>; +- +- clocks = <&cpm_syscon0 1 2>; +- nand-enable-arbiter; +- num-cs = <1>; +- nand-ecc-strength = <4>; +- nand-ecc-step-size = <512>; +- status = "disabled"; +- }; +- +- }; +- +- cpm_pcie0: pcie@f2600000 { +- compatible = "marvell,armada8k-pcie", "snps,dw-pcie"; +- reg = <0 0xf2600000 0 0x10000>, +- <0 0xf6f00000 0 0x80000>; +- reg-names = "ctrl", "config"; +- #address-cells = <3>; +- #size-cells = <2>; +- #interrupt-cells = <1>; +- device_type = "pci"; +- dma-coherent; +- +- bus-range = <0 0xff>; +- ranges = +- /* downstream I/O */ +- <0x81000000 0 0xf9000000 0 0xf9000000 0 0x10000 +- /* non-prefetchable memory */ +- 0x82000000 0 0xf6000000 0 0xf6000000 0 0xf00000>; +- interrupt-map-mask = <0 0 0 0>; +- interrupt-map = <0 0 0 0 &gic 0 GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH>; +- interrupts = ; +- num-lanes = <1>; +- clocks = <&cpm_syscon0 1 13>; +- status = "disabled"; +- }; +- +- cpm_pcie1: pcie@f2620000 { +- compatible = "marvell,armada8k-pcie", "snps,dw-pcie"; +- reg = <0 0xf2620000 0 0x10000>, +- <0 0xf7f00000 0 0x80000>; +- reg-names = "ctrl", "config"; +- #address-cells = <3>; +- #size-cells = <2>; +- #interrupt-cells = <1>; +- device_type = "pci"; +- dma-coherent; +- +- bus-range = <0 0xff>; +- ranges = +- /* downstream I/O */ +- <0x81000000 0 0xf9010000 0 0xf9010000 0 0x10000 +- /* non-prefetchable memory */ +- 0x82000000 0 0xf7000000 0 0xf7000000 0 0xf00000>; +- interrupt-map-mask = <0 0 0 0>; +- interrupt-map = <0 0 0 0 &gic 0 GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; +- interrupts = ; +- +- num-lanes = <1>; +- clocks = <&cpm_syscon0 1 11>; +- status = "disabled"; +- }; +- +- cpm_pcie2: pcie@f2640000 { +- compatible = "marvell,armada8k-pcie", "snps,dw-pcie"; +- reg = <0 0xf2640000 0 0x10000>, +- <0 0xf8f00000 0 0x80000>; +- reg-names = "ctrl", "config"; +- #address-cells = <3>; +- #size-cells = <2>; +- #interrupt-cells = <1>; +- device_type = "pci"; +- dma-coherent; +- +- bus-range = <0 0xff>; +- ranges = +- /* downstream I/O */ +- <0x81000000 0 0xf9020000 0 0xf9020000 0 0x10000 +- /* non-prefetchable memory */ +- 0x82000000 0 0xf8000000 0 0xf8000000 0 0xf00000>; +- interrupt-map-mask = <0 0 0 0>; +- interrupt-map = <0 0 0 0 &gic 0 GIC_SPI 33 IRQ_TYPE_LEVEL_HIGH>; +- interrupts = ; +- +- num-lanes = <1>; +- clocks = <&cpm_syscon0 1 12>; +- status = "disabled"; +- }; +- }; +-}; +diff --git a/arch/arm/dts/armada-cp110-slave.dtsi b/arch/arm/dts/armada-cp110-slave.dtsi +deleted file mode 100644 +index 2fbd7b5514..0000000000 +--- a/arch/arm/dts/armada-cp110-slave.dtsi ++++ /dev/null +@@ -1,343 +0,0 @@ +-/* +- * Copyright (C) 2016 Marvell Technology Group Ltd. +- * +- * This file is dual-licensed: you can use it either under the terms +- * of the GPLv2 or the X11 license, at your option. Note that this dual +- * licensing only applies to this file, and not this project as a +- * whole. +- * +- * a) This library is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License as +- * published by the Free Software Foundation; either version 2 of the +- * License, or (at your option) any later version. +- * +- * This library is distributed in the hope that it will be useful, +- * but WITHOUT ANY WARRANTY; without even the implied warranty of +- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +- * GNU General Public License for more details. +- * +- * Or, alternatively, +- * +- * b) Permission is hereby granted, free of charge, to any person +- * obtaining a copy of this software and associated documentation +- * files (the "Software"), to deal in the Software without +- * restriction, including without limitation the rights to use, +- * copy, modify, merge, publish, distribute, sublicense, and/or +- * sell copies of the Software, and to permit persons to whom the +- * Software is furnished to do so, subject to the following +- * conditions: +- * +- * The above copyright notice and this permission notice shall be +- * included in all copies or substantial portions of the Software. +- * +- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +- * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +- * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +- * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +- * OTHER DEALINGS IN THE SOFTWARE. +- */ +- +-/* +- * Device Tree file for Marvell Armada CP110 Slave. +- */ +- +-#include +- +-/ { +- cp110-slave { +- #address-cells = <2>; +- #size-cells = <2>; +- compatible = "simple-bus"; +- interrupt-parent = <&gic>; +- ranges; +- +- config-space { +- #address-cells = <1>; +- #size-cells = <1>; +- compatible = "simple-bus"; +- interrupt-parent = <&gic>; +- ranges = <0x0 0x0 0xf4000000 0x2000000>; +- +- cps_ethernet: ethernet@0 { +- compatible = "marvell,armada-7k-pp22"; +- reg = <0x0 0x100000>, <0x129000 0xb000>; +- clocks = <&cps_syscon0 1 3>, <&cps_syscon0 1 9>, <&cps_syscon0 1 5>; +- clock-names = "pp_clk", "gop_clk", "mg_clk"; +- status = "disabled"; +- dma-coherent; +- +- cps_eth0: eth0 { +- interrupts = ; +- port-id = <0>; +- gop-port-id = <0>; +- status = "disabled"; +- }; +- +- cps_eth1: eth1 { +- interrupts = ; +- port-id = <1>; +- gop-port-id = <2>; +- status = "disabled"; +- }; +- +- cps_eth2: eth2 { +- interrupts = ; +- port-id = <2>; +- gop-port-id = <3>; +- status = "disabled"; +- }; +- }; +- +- cps_mdio: mdio@12a200 { +- #address-cells = <1>; +- #size-cells = <0>; +- compatible = "marvell,orion-mdio"; +- reg = <0x12a200 0x10>; +- device-name = "cps-mdio"; +- }; +- +- cps_syscon0: system-controller@440000 { +- compatible = "marvell,cp110-system-controller0", +- "syscon"; +- reg = <0x440000 0x1000>; +- #clock-cells = <2>; +- core-clock-output-names = +- "cps-apll", "cps-ppv2-core", "cps-eip", +- "cps-core", "cps-nand-core"; +- gate-clock-output-names = +- "cps-audio", "cps-communit", "cps-nand", +- "cps-ppv2", "cps-sdio", "cps-mg-domain", +- "cps-mg-core", "cps-xor1", "cps-xor0", +- "cps-gop-dp", "none", "cps-pcie_x10", +- "cps-pcie_x11", "cps-pcie_x4", "cps-pcie-xor", +- "cps-sata", "cps-sata-usb", "cps-main", +- "cps-sd-mmc", "none", "none", +- "cps-slow-io", "cps-usb3h0", "cps-usb3h1", +- "cps-usb3dev", "cps-eip150", "cps-eip197"; +- }; +- +- cps_pinctl: cps-pinctl@440000 { +- compatible = "marvell,mvebu-pinctrl", +- "marvell,armada-8k-cps-pinctrl"; +- bank-name ="cp1-110"; +- reg = <0x440000 0x20>; +- pin-count = <63>; +- max-func = <0xf>; +- +- cps_ge1_rgmii_pins: cps-ge-rgmii-pins-0 { +- marvell,pins = < 0 1 2 3 4 5 6 7 +- 8 9 10 11 >; +- marvell,function = <3>; +- }; +- cps_spi1_pins: cps-spi-pins-1 { +- marvell,pins = < 13 14 15 16 >; +- marvell,function = <3>; +- }; +- }; +- +- cps_gpio0: gpio@440100 { +- compatible = "marvell,orion-gpio"; +- reg = <0x440100 0x40>; +- ngpios = <32>; +- gpiobase = <20>; +- gpio-controller; +- #gpio-cells = <2>; +- }; +- +- cps_gpio1: gpio@440140 { +- compatible = "marvell,orion-gpio"; +- reg = <0x440140 0x40>; +- ngpios = <31>; +- gpiobase = <52>; +- gpio-controller; +- #gpio-cells = <2>; +- }; +- +- cps_sata0: sata@540000 { +- compatible = "marvell,armada-8k-ahci"; +- reg = <0x540000 0x30000>; +- interrupts = ; +- clocks = <&cps_syscon0 1 15>; +- status = "disabled"; +- }; +- +- cps_usb3_0: usb3@500000 { +- compatible = "marvell,armada-8k-xhci", +- "generic-xhci"; +- reg = <0x500000 0x4000>; +- dma-coherent; +- interrupts = ; +- clocks = <&cps_syscon0 1 22>; +- status = "disabled"; +- }; +- +- cps_usb3_1: usb3@510000 { +- compatible = "marvell,armada-8k-xhci", +- "generic-xhci"; +- reg = <0x510000 0x4000>; +- dma-coherent; +- interrupts = ; +- clocks = <&cps_syscon0 1 23>; +- status = "disabled"; +- }; +- +- cps_xor0: xor@6a0000 { +- compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; +- reg = <0x6a0000 0x1000>, +- <0x6b0000 0x1000>; +- dma-coherent; +- msi-parent = <&gic_v2m0>; +- clocks = <&cps_syscon0 1 8>; +- }; +- +- cps_xor1: xor@6c0000 { +- compatible = "marvell,armada-7k-xor", "marvell,xor-v2"; +- reg = <0x6c0000 0x1000>, +- <0x6d0000 0x1000>; +- dma-coherent; +- msi-parent = <&gic_v2m0>; +- clocks = <&cps_syscon0 1 7>; +- }; +- +- cps_spi0: spi@700600 { +- compatible = "marvell,armada-380-spi"; +- reg = <0x700600 0x50>; +- #address-cells = <0x1>; +- #size-cells = <0x0>; +- cell-index = <1>; +- clocks = <&cps_syscon0 0 3>; +- status = "disabled"; +- }; +- +- cps_spi1: spi@700680 { +- compatible = "marvell,armada-380-spi"; +- reg = <0x700680 0x50>; +- #address-cells = <1>; +- #size-cells = <0>; +- cell-index = <2>; +- clocks = <&cps_syscon0 1 21>; +- status = "disabled"; +- }; +- +- cps_i2c0: i2c@701000 { +- compatible = "marvell,mv78230-i2c"; +- reg = <0x701000 0x20>; +- #address-cells = <1>; +- #size-cells = <0>; +- interrupts = ; +- clocks = <&cps_syscon0 1 21>; +- status = "disabled"; +- }; +- +- cps_i2c1: i2c@701100 { +- compatible = "marvell,mv78230-i2c"; +- reg = <0x701100 0x20>; +- #address-cells = <1>; +- #size-cells = <0>; +- interrupts = ; +- clocks = <&cps_syscon0 1 21>; +- status = "disabled"; +- }; +- +- cps_comphy: comphy@441000 { +- compatible = "marvell,mvebu-comphy", "marvell,comphy-cp110"; +- reg = <0x441000 0x8>, +- <0x120000 0x8>; +- mux-bitcount = <4>; +- max-lanes = <6>; +- }; +- +- cps_utmi0: utmi@580000 { +- compatible = "marvell,mvebu-utmi-2.6.0"; +- reg = <0x580000 0x1000>, /* utmi-unit */ +- <0x440420 0x4>, /* usb-cfg */ +- <0x440440 0x4>; /* utmi-cfg */ +- utmi-port = ; +- status = "disabled"; +- }; +- }; +- +- cps_pcie0: pcie@f4600000 { +- compatible = "marvell,armada8k-pcie", "snps,dw-pcie"; +- reg = <0 0xf4600000 0 0x10000>, +- <0 0xfaf00000 0 0x80000>; +- reg-names = "ctrl", "config"; +- #address-cells = <3>; +- #size-cells = <2>; +- #interrupt-cells = <1>; +- device_type = "pci"; +- dma-coherent; +- msi-parent = <&gic_v2m0>; +- +- bus-range = <0 0xff>; +- ranges = +- /* downstream I/O */ +- <0x81000000 0 0xfd000000 0 0xfd000000 0 0x10000 +- /* non-prefetchable memory */ +- 0x82000000 0 0xfa000000 0 0xfa000000 0 0xf00000>; +- interrupt-map-mask = <0 0 0 0>; +- interrupt-map = <0 0 0 0 &gic 0 GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>; +- interrupts = ; +- num-lanes = <1>; +- clocks = <&cps_syscon0 1 13>; +- status = "disabled"; +- }; +- +- cps_pcie1: pcie@f4620000 { +- compatible = "marvell,armada8k-pcie", "snps,dw-pcie"; +- reg = <0 0xf4620000 0 0x10000>, +- <0 0xfbf00000 0 0x80000>; +- reg-names = "ctrl", "config"; +- #address-cells = <3>; +- #size-cells = <2>; +- #interrupt-cells = <1>; +- device_type = "pci"; +- dma-coherent; +- msi-parent = <&gic_v2m0>; +- +- bus-range = <0 0xff>; +- ranges = +- /* downstream I/O */ +- <0x81000000 0 0xfd010000 0 0xfd010000 0 0x10000 +- /* non-prefetchable memory */ +- 0x82000000 0 0xfb000000 0 0xfb000000 0 0xf00000>; +- interrupt-map-mask = <0 0 0 0>; +- interrupt-map = <0 0 0 0 &gic 0 GIC_SPI 258 IRQ_TYPE_LEVEL_HIGH>; +- interrupts = ; +- +- num-lanes = <1>; +- clocks = <&cps_syscon0 1 11>; +- status = "disabled"; +- }; +- +- cps_pcie2: pcie@f4640000 { +- compatible = "marvell,armada8k-pcie", "snps,dw-pcie"; +- reg = <0 0xf4640000 0 0x10000>, +- <0 0xfcf00000 0 0x80000>; +- reg-names = "ctrl", "config"; +- #address-cells = <3>; +- #size-cells = <2>; +- #interrupt-cells = <1>; +- device_type = "pci"; +- dma-coherent; +- msi-parent = <&gic_v2m0>; +- +- bus-range = <0 0xff>; +- ranges = +- /* downstream I/O */ +- <0x81000000 0 0xfd020000 0 0xfd020000 0 0x10000 +- /* non-prefetchable memory */ +- 0x82000000 0 0xfc000000 0 0xfc000000 0 0xf00000>; +- interrupt-map-mask = <0 0 0 0>; +- interrupt-map = <0 0 0 0 &gic 0 GIC_SPI 257 IRQ_TYPE_LEVEL_HIGH>; +- interrupts = ; +- +- num-lanes = <1>; +- clocks = <&cps_syscon0 1 12>; +- status = "disabled"; +- }; +- }; +-}; +diff --git a/arch/arm/dts/armada-cp110.dtsi b/arch/arm/dts/armada-cp110.dtsi +new file mode 100644 +index 0000000000..448cdb2f80 +--- /dev/null ++++ b/arch/arm/dts/armada-cp110.dtsi +@@ -0,0 +1,368 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++/* ++ * Generic Device Tree describing Marvell Armada CP-110 device ++ */ ++#include ++ ++#define U64_TO_U32_H(addr) (((addr) >> 32) & 0xffffffff) ++#define U64_TO_U32_L(addr) ((addr) & 0xffffffff) ++ ++#define CP110_PCIEx_REG0_BASE(iface) \ ++ (CP110_BASE + 0x600000 + (iface) * 0x20000) ++#define CP110_PCIEx_REG1_BASE(iface) \ ++ (CP110_PCIEx_CPU_MEM_BASE(iface) + CP110_PCIE_MEM_SIZE(iface)) ++#define CP110_PCIE_EP_REG_BASE(iface) (CP110_BASE + 0x600000 + \ ++ (iface) * 0x4000) ++ ++/ { ++ CP110_NAME { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ compatible = "simple-bus"; ++ ranges; ++ ++ config-space { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "simple-bus"; ++ ranges = <0x0 U64_TO_U32_H(CP110_BASE) U64_TO_U32_L(CP110_BASE) 0x2000000>; ++ ++ CP110_LABEL(mdio): mdio@12a200 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "marvell,orion-mdio"; ++ reg = <0x12a200 0x10>; ++ mdio-name = CP110_STRING_LABEL(mdio); ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(xmdio): mdio@12a600 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "marvell,xmdio"; ++ reg = <0x12a600 0x200>; ++ mdio-name = CP110_STRING_LABEL(xmdio); ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(sar-reg) { ++ compatible = "marvell,sample-at-reset-common", ++ "marvell,sample-at-reset-cp110"; ++ reg = <0x400200 0x8>; ++ sar-driver = "cp110_sar"; ++ sar-name = CP110_STRING_LABEL(sar); ++ status = "okay"; ++ }; ++ ++ CP110_LABEL(ld_efuse0): CP110_LABEL(efuse0)@400F00 { ++ compatible = "marvell,mvebu-fuse-ld-user"; ++ reg = <0x400008 0x4>; ++ otp-mem = <0x400F00>; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(ld_efuse1): CP110_LABEL(efuse1)@400F00 { ++ compatible = "marvell,mvebu-fuse-ld-prop"; ++ reg = <0x400008 0x4>; ++ otp-mem = <0x400F00>; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(pinctl): pinctl@440000 { ++ compatible = "marvell,mvebu-pinctrl"; ++ reg = <0x440000 0x20>; ++ pin-count = <63>; ++ max-func = <0xf>; ++ }; ++ ++ CP110_LABEL(gpio0): gpio@440100 { ++ compatible = "marvell,orion-gpio"; ++ reg = <0x440100 0x40>; ++ ngpios = <32>; ++ gpiobase = <20>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ }; ++ ++ CP110_LABEL(thermal): thermal@400070 { ++ compatible = "marvell,mvebu-thermal", "marvell,thermal-sensor"; ++ reg = <0x400070 0x12>; ++ gain = <4761>; ++ offset = <2791000>; ++ divisor = <10000>; ++ status = "okay"; ++ }; ++ ++ CP110_LABEL(gpio1): gpio@440140 { ++ compatible = "marvell,orion-gpio"; ++ reg = <0x440140 0x40>; ++ ngpios = <31>; ++ gpiobase = <52>; ++ gpio-controller; ++ #gpio-cells = <2>; ++ }; ++ ++ CP110_LABEL(sata0): sata@540000 { ++ compatible = "marvell,armada-8k-ahci"; ++ reg = <0x540000 0x30000>; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(usb3_0): usb3@500000 { ++ compatible = "marvell,armada-8k-xhci", ++ "generic-xhci"; ++ reg = <0x500000 0x4000>; ++ dma-coherent; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(usb3_1): usb3@510000 { ++ compatible = "marvell,armada-8k-xhci", ++ "generic-xhci"; ++ reg = <0x510000 0x4000>; ++ dma-coherent; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(spi0): spi@700600 { ++ compatible = "marvell,armada-380-spi"; ++ reg = <0x700600 0x50>; ++ #address-cells = <0x1>; ++ #size-cells = <0x0>; ++ cell-index = <1>; ++ spi-max-frequency = <50000000>; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(spi1): spi@700680 { ++ compatible = "marvell,armada-380-spi"; ++ reg = <0x700680 0x50>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ cell-index = <2>; ++ spi-max-frequency = <50000000>; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(i2c0): i2c@701000 { ++ compatible = "marvell,mv78230-i2c"; ++ reg = <0x701000 0x20>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(i2c1): i2c@701100 { ++ compatible = "marvell,mv78230-i2c"; ++ reg = <0x701100 0x20>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(mss_i2c0): i2c@211000 { ++ compatible = "marvell,mv78230-i2c"; ++ reg = <0x211000 0x20>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(comphy): comphy@441000 { ++ compatible = "marvell,mvebu-comphy", "marvell,comphy-cp110"; ++ reg = <0x441000 0x8>, ++ <0x120000 0x8>; ++ mux-bitcount = <4>; ++ max-lanes = <6>; ++ }; ++ ++ CP110_LABEL(utmi): utmi@580000 { ++ compatible = "marvell,mvebu-utmi"; ++ reg = <0x580000 0xc>; /* utmi-common-pll */ ++ #address-cells = <1>; ++ #size-cells = <1>; ++ CP110_LABEL(utmi0): utmi@58000c { ++ compatible = "marvell,mvebu-utmi-2.6.0"; ++ reg = <0x58000c 0x100>,/* utmi-unit */ ++ <0x440420 0x4>, /* usb-cfg */ ++ <0x440440 0x4>; /* utmi-cfg */ ++ utmi-port = ; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(utmi1): utmi@58100c { ++ compatible = "marvell,mvebu-utmi-2.6.0"; ++ reg = <0x58100c 0x100>,/* utmi-unit */ ++ <0x440420 0x4>, /* usb-cfg */ ++ <0x440444 0x4>; /* utmi-cfg */ ++ utmi-port = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ CP110_LABEL(sdhci0): sdhci@780000 { ++ compatible = "marvell,armada-8k-sdhci"; ++ reg = <0x780000 0x300>; ++ dma-coherent; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(nand): nand@720000 { ++ compatible = "marvell,mvebu-pxa3xx-nand"; ++ reg = <0x720000 0x100>, ++ <0x440700 0x20>, ++ <0x440208 0x20>; ++ reg-names = "ctrl_base", ++ "flash_clock", ++ "dev_mux"; ++ #address-cells = <1>; ++ ++ nand-enable-arbiter; ++ num-cs = <1>; ++ nand-ecc-strength = <8>; ++ nand-ecc-step-size = <512>; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(rtc): rtc-reg@284000 { ++ compatible = "marvell,armada-8k-rtc"; ++ reg = <0x284000 104>; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(ethernet): ethernet@0 { ++ compatible = "marvell,armada-7k-pp22"; ++ reg = <0x0 0x100000>, ++ <0x129000 0xb000>, ++ <0x120000 0x6000>; ++ status = "disabled"; ++ dma-coherent; ++ ++ CP110_LABEL(eth0): eth0 { ++ port-id = <0>; ++ gop-port-id = <0>; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(eth1): eth1 { ++ port-id = <1>; ++ gop-port-id = <2>; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(eth2): eth2 { ++ port-id = <2>; ++ gop-port-id = <3>; ++ status = "disabled"; ++ }; ++ }; ++ }; ++ ++ CP110_LABEL(pcie_ep): pcie-ep@600000 { ++ compatible = "marvell,armada-pcie-ep", "snps,dw-pcie"; ++ reg = , ++ , ++ ; ++ reg-names = "core", "lm", "shadow_core"; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(pci_ep_uio): pci-ep-uio { ++ compatible = "marvell,pci-ep-uio"; ++ reg = <0x00 0x00000000 0x0 0x00100000>, ++ <0x00 0x3f000000 0x0 0x01000000>, ++ <0x00 0xf0000000 0x0 0x01000000>, ++ <0x80 0x00000000 0x4 0x00000000>; ++ reg-names = "bar0", "bar2", "bar4", "host-map"; ++ device-id = <0x7080>; ++ vf-device-id = <0x7081>; ++ class-code = <0x2>; ++ subclass-code = <0x0>; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(bootcmd): pci-bootcmd@3ffff000 { ++ /* remote bootcmd buffer location */ ++ compatible = "marvell,pci-bootcmd"; ++ reg = <0 0x3ffff000 0 0x1000>; ++ skip-init; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(pcie0): pcie0@600000 { ++ compatible = "marvell,armada8k-pcie", "snps,dw-pcie"; ++ reg = ++ , ++ /* Last 512KB of mem space */ ++ ; ++ reg-names = "ctrl", "config"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ dma-coherent; ++ ++ bus-range = <0 0xff>; ++ ranges = ++ /* non-prefetchable memory */ ++ ; ++ num-lanes = <1>; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(pcie1): pcie1@620000 { ++ compatible = "marvell,armada8k-pcie", "snps,dw-pcie"; ++ reg = ++ , ++ /* Last 512KB of mem space */ ++ ; ++ reg-names = "ctrl", "config"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ dma-coherent; ++ ++ bus-range = <0 0xff>; ++ ranges = ++ /* non-prefetchable memory */ ++ ; ++ num-lanes = <1>; ++ status = "disabled"; ++ }; ++ ++ CP110_LABEL(pcie2): pcie2@640000 { ++ compatible = "marvell,armada8k-pcie", "snps,dw-pcie"; ++ reg = ++ , ++ /* Last 64KB of mem space */ ++ ; ++ reg-names = "ctrl", "config"; ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ dma-coherent; ++ ++ bus-range = <0 0xff>; ++ ranges = ++ /* non-prefetchable memory */ ++ ; ++ num-lanes = <1>; ++ status = "disabled"; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/cn9130-crb-A.dts b/arch/arm/dts/cn9130-crb-A.dts +new file mode 100644 +index 0000000000..e3fd22746f +--- /dev/null ++++ b/arch/arm/dts/cn9130-crb-A.dts +@@ -0,0 +1,57 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ */ ++ ++#include "cn9130-crb.dtsi" ++ ++/ { ++ model = "CN9130-CRB-A"; ++ compatible = "marvell,cn9130-crb-A", ++ "marvell,cn9130", ++ "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++}; ++ ++&cp0_comphy { ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++}; ++ ++&cp0_pcie0 { ++ num-lanes = <4>; ++ /* non-prefetchable memory */ ++ ranges =<0x82000000 0 0xc0000000 0 0xc0000000 0 0x2000000>; ++ status = "okay"; ++}; ++ ++&cp0_usb3_0 { ++ status = "okay"; ++}; ++ ++&cp0_usb3_1 { ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/cn9130-crb-B.dts b/arch/arm/dts/cn9130-crb-B.dts +new file mode 100644 +index 0000000000..52204d52d9 +--- /dev/null ++++ b/arch/arm/dts/cn9130-crb-B.dts +@@ -0,0 +1,61 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ */ ++ ++#include "cn9130-crb.dtsi" ++ ++/ { ++ model = "CN9130-CRB-B"; ++ compatible = "marvell,cn9130-crb-B", ++ "marvell,cn9130", ++ "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++}; ++ ++&cp0_comphy { ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++}; ++ ++&cp0_sata0 { ++ status = "okay"; ++}; ++ ++&cp0_pcie0 { ++ num-lanes = <1>; ++ /* non-prefetchable memory */ ++ ranges =<0x82000000 0 0xc0000000 0 0xc0000000 0 0x2000000>; ++ status = "okay"; ++}; ++ ++&cp0_usb3_0 { ++ status = "okay"; ++}; ++ ++&cp0_usb3_1 { ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/cn9130-crb-C.dts b/arch/arm/dts/cn9130-crb-C.dts +new file mode 100644 +index 0000000000..c457e8304d +--- /dev/null ++++ b/arch/arm/dts/cn9130-crb-C.dts +@@ -0,0 +1,67 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ */ ++ ++#include "cn9130-crb.dtsi" ++ ++/ { ++ model = "CN9130-CRB-C (PCIe EP)"; ++ compatible = "marvell,cn9130-crb-C", ++ "marvell,cn9130", ++ "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++ ++ reserved-memory { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ /* The PCI console memory must be reserved */ ++ console_reserved: pci-console-nexus@3f000000 { ++ compatible = "marvell,pci-console-nexus-memory"; ++ reg = <0 0x3f000000 0 0x1000000>; ++ no-map; ++ }; ++ }; ++}; ++ ++&cp0_comphy { ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++}; ++ ++&cp0_bootcmd { ++ status = "okay"; ++}; ++ ++&cp0_usb3_0 { ++ status = "okay"; ++}; ++ ++&cp0_usb3_1 { ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/cn9130-crb-r1p3-A.dts b/arch/arm/dts/cn9130-crb-r1p3-A.dts +new file mode 100644 +index 0000000000..6959242fcd +--- /dev/null ++++ b/arch/arm/dts/cn9130-crb-r1p3-A.dts +@@ -0,0 +1,15 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2020 Marvell International Ltd. ++ */ ++ ++#include "cn9130-crb-A.dts" ++#include "cn9130-crb-r1p3.dtsi" ++ ++/ { ++ model = "CN9130-CRB-A"; ++ compatible = "marvell,cn9130-crb-A", ++ "marvell,cn9130", ++ "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++}; +diff --git a/arch/arm/dts/cn9130-crb-r1p3-B.dts b/arch/arm/dts/cn9130-crb-r1p3-B.dts +new file mode 100644 +index 0000000000..f30221588d +--- /dev/null ++++ b/arch/arm/dts/cn9130-crb-r1p3-B.dts +@@ -0,0 +1,15 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2020 Marvell International Ltd. ++ */ ++ ++#include "cn9130-crb-B.dts" ++#include "cn9130-crb-r1p3.dtsi" ++ ++/ { ++ model = "CN9130-CRB-B"; ++ compatible = "marvell,cn9130-crb-B", ++ "marvell,cn9130", ++ "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++}; +diff --git a/arch/arm/dts/cn9130-crb-r1p3-C.dts b/arch/arm/dts/cn9130-crb-r1p3-C.dts +new file mode 100644 +index 0000000000..4d034fae26 +--- /dev/null ++++ b/arch/arm/dts/cn9130-crb-r1p3-C.dts +@@ -0,0 +1,15 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2020 Marvell International Ltd. ++ */ ++ ++#include "cn9130-crb-C.dts" ++#include "cn9130-crb-r1p3.dtsi" ++ ++/ { ++ model = "CN9130-CRB-C (PCIe EP)"; ++ compatible = "marvell,cn9130-crb-C", ++ "marvell,cn9130", ++ "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++}; +diff --git a/arch/arm/dts/cn9130-crb-r1p3.dtsi b/arch/arm/dts/cn9130-crb-r1p3.dtsi +new file mode 100644 +index 0000000000..8922c0d7e8 +--- /dev/null ++++ b/arch/arm/dts/cn9130-crb-r1p3.dtsi +@@ -0,0 +1,44 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2020 Marvell International Ltd. ++ */ ++ ++/* ++ * CP related configuration ++ */ ++&cp0_pinctl { ++ /* MPP Bus: ++ * [0-11] RGMII1 ++ * [12] GPIO ++ * [13-16] SPI1 ++ * [17-32] GPIO ++ * [33] SD_PWR_OFF ++ * [34] CP_PCIE0_CLKREQn ++ * [35-38] I2C1 I2C0 ++ * [39] GPIO ++ * [40-43] SMI/XSMI ++ * [44-46] GPIO ++ * [47] UART1_TX ++ * [48] GPIO ++ * [49] SD_HST_18_EN ++ * [50] GPIO ++ * [51] SD_PWR_0 ++ * [52] PCIE_RSTn ++ * [53] UART1_RX ++ * [54] GPIO ++ * [55] SD_DT ++ * [56-61] SDIO ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 3 3 3 3 3 3 3 3 3 3 ++ 3 3 0 3 3 3 3 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 6 9 2 2 2 2 0 ++ 8 8 8 8 0 0 0 7 0 0xa ++ 0 0xa 9 7 0 0xb 0xe 0xe 0xe 0xe ++ 0xe 0xe 0xe>; ++}; ++ ++&cp0_spi1 { ++ pinctrl-0 = <&cp0_spi0_pins>; ++}; +diff --git a/arch/arm/dts/cn9130-crb.dtsi b/arch/arm/dts/cn9130-crb.dtsi +new file mode 100644 +index 0000000000..41906511ab +--- /dev/null ++++ b/arch/arm/dts/cn9130-crb.dtsi +@@ -0,0 +1,229 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ */ ++ ++#include "cn9130.dtsi" /* include SoC device tree */ ++ ++/ { ++ model = "CN9130-CRB"; ++ compatible = "marvell,cn9130-crb", ++ "marvell,cn9130", ++ "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp0_spi1; ++ gpio0 = &ap_gpio0; ++ gpio1 = &cp0_gpio0; ++ gpio2 = &cp0_gpio1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++ ++ cp0 { ++ config-space { ++ sdhci@780000 { ++ vqmmc-supply = <&cp0_reg_sd_vccq>; ++ vmmc-supply = <&cp0_reg_sd_vcc>; ++ }; ++ cp0_reg_sd_vccq: cp0_sd_vccq@0 { ++ compatible = "regulator-gpio"; ++ regulator-name = "cp0_sd_vccq"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ gpios = <&cp0_gpio1 18 GPIO_ACTIVE_HIGH>; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ }; ++ cp0_reg_sd_vcc: cp0_sd_vcc@0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "cp0_sd_vcc"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ gpio = <&cp0_gpio1 22 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ regulator-always-on; ++ }; ++ }; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++/* ++ * AP related configuration ++ */ ++&ap_pinctl { ++ /* MPP Bus: ++ * SDIO [0-10, 12] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 1 1 1 1 ++ 1 3 1 0 0 0 0 0 0 3 >; ++}; ++ ++/* on-board eMMC - U6 */ ++&ap_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ap_emmc_pins>; ++ bus-width = <8>; ++ status = "okay"; ++}; ++ ++/* ++ * CP related configuration ++ */ ++&cp0_pinctl { ++ /* MPP Bus: ++ * [0-11] RGMII1 ++ * [12-26] GPIO ++ * [27-30] SPI1 ++ * [31] GPIO ++ * [32] GPIO ++ * [33] SD_PWR_OFF ++ * [34] CP_PCIE0_CLKREQn ++ * [35-38] I2C1 I2C0 ++ * [39] GPIO ++ * [40-43] SMI/XSMI ++ * [44-46] GPIO ++ * [47] UART1_TX ++ * [48] GPIO ++ * [49] SD_HST_18_EN ++ * [50] GPIO ++ * [51] SD_PWR_0 ++ * [52] PCIE_RSTn ++ * [53] UART1_RX ++ * [54] GPIO ++ * [55] SD_DT ++ * [56-61] SDIO ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 3 3 3 3 3 3 3 3 3 3 ++ 3 3 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 2 2 2 ++ 2 0 0 6 9 2 2 2 2 0 ++ 8 8 8 8 0 0 0 7 0 0xa ++ 0 0xa 9 7 0 0xb 0xe 0xe 0xe 0xe ++ 0xe 0xe 0xe>; ++}; ++ ++&cp0_pinctl { ++ cp0_spi1_pins_crb: cp0-spi-pins-crb { ++ marvell,pins = < 27 28 29 30 >; ++ marvell,function = <2>; ++ }; ++}; ++ ++/* ++ * CP0 ++ */ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_i2c1 { ++ status = "okay"; ++}; ++ ++&cp0_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_sdhci_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++&cp0_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_spi1_pins_crb>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>, /* CS1 */ ++ <0 0xffffffff>, /* CS2 */ ++ <0 0xffffffff>; /* CS3 */ ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <0x1>; ++ #size-cells = <0x1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0x0>; ++ /* On-board MUX does not allow higher frequencies */ ++ spi-max-frequency = <40000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0x0 0x200000>; ++ }; ++ ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xe00000>; ++ }; ++ }; ++ }; ++}; ++ ++&cp0_utmi0 { ++ status = "okay"; ++}; ++ ++&cp0_utmi1 { ++ status = "okay"; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++ switch6: ethernet-switch@6 { ++ reg = <6>; ++ }; ++}; ++ ++&cp0_xmdio { ++ status = "okay"; ++ nbaset_phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; ++}; ++ ++&cp0_eth1 { ++ status = "okay"; ++ phy = <&phy0>; ++ phy-mode = "rgmii-id"; ++}; ++ ++&cp0_eth2 { ++ status = "okay"; ++ phy = <&nbaset_phy0>; ++ phy-mode = "sgmii-2500"; ++}; +diff --git a/arch/arm/dts/cn9130-db-A.dts b/arch/arm/dts/cn9130-db-A.dts +new file mode 100644 +index 0000000000..ea1a8cc95e +--- /dev/null ++++ b/arch/arm/dts/cn9130-db-A.dts +@@ -0,0 +1,214 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++ ++#include "cn9130-db.dtsi" ++ ++/ { ++ model = "Marvell CN9130 development board (CP NOR) setup(A)"; ++ compatible = "marvell,cn9130-db", "marvell,cn91xx", "marvell,cn9030-vd", ++ "marvell,cn9030", "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp0_spi1; ++ gpio0 = &ap_gpio0; ++ gpio1 = &cp0_gpio0; ++ gpio2 = &cp0_gpio1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++/* ++ * AP related configuration ++ */ ++&ap_pinctl { ++ /* MPP Bus: ++ * SDIO [0-10, 12] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 1 1 1 1 ++ 1 3 1 0 0 0 0 0 0 3 >; ++}; ++ ++/* ++ * CP related configuration ++ */ ++&cp0_pinctl { ++ /* MPP Bus: ++ * [0-11] RGMII1 ++ * [12] GPIO GE-IN ++ * [13-16] SPI1 ++ * [17-27] NAND ++ * [28] MSS_GPIO[5] XXX:(mode nr from a3900) ++ * [29-30] SATA ++ * [31] MSS_GPIO[4] XXX:(mode nr from a3900) ++ * [32,34] SMI ++ * [33] SDIO ++ * [35-36] I2C1 ++ * [37-38] I2C0 ++ * [39-43] SDIOctrl ++ * [44-55] RGMII2 ++ * [56-62] SDIO ++ */ ++ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 3 3 3 3 3 3 3 3 3 3 ++ 3 3 0 3 3 3 3 1 1 1 ++ 1 1 1 1 1 1 1 1 3 9 ++ 9 3 7 6 7 2 2 2 2 1 ++ 1 1 1 1 1 1 1 1 1 1 ++ 1 1 1 1 1 1 0xe 0xe 0xe 0xe ++ 0xe 0xe 0xe>; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_i2c1 { ++ status = "okay"; ++}; ++ ++/* CON 28 */ ++&cp0_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_sdhci_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++/* U54 */ ++&cp0_nand { ++ status = "disabled"; ++}; ++ ++/* U55 */ ++&cp0_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_spi0_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>, /* CS1 */ ++ <0 0xffffffff>, /* CS2 */ ++ <0 0xffffffff>; /* CS3 */ ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <0x1>; ++ #size-cells = <0x1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0x0>; ++ /* On-board MUX does not allow higher frequencies */ ++ spi-max-frequency = <40000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0x0 0x200000>; ++ }; ++ ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xe00000>; ++ }; ++ }; ++ }; ++}; ++ ++&cp0_comphy { ++ ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++/* SLM-1521-V2, CON6 */ ++&cp0_pcie0 { ++ num-lanes = <4>; ++ status = "okay"; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++/* SLM-1521-V2, CON9 */ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; ++}; ++ ++/* CON56 */ ++&cp0_eth1 { ++ status = "okay"; ++ phy = <&phy0>; ++ phy-mode = "rgmii-id"; ++}; ++ ++/* CON57 */ ++&cp0_eth2 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "rgmii-id"; ++}; ++ ++/* SLM-1521-V2, CON2 */ ++&cp0_sata0 { ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/cn9130-db-B.dts b/arch/arm/dts/cn9130-db-B.dts +new file mode 100644 +index 0000000000..ff15246e7c +--- /dev/null ++++ b/arch/arm/dts/cn9130-db-B.dts +@@ -0,0 +1,225 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++ ++#include "cn9130-db.dtsi" ++ ++/ { ++ model = "Marvell CN9130 development board (CP NAND) setup(B)"; ++ compatible = "marvell,cn9130-db", "marvell,cn91xx", "marvell,cn9030-vd", ++ "marvell,cn9030", "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ gpio0 = &ap_gpio0; ++ gpio1 = &cp0_gpio0; ++ gpio2 = &cp0_gpio1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++/* ++ * AP related configuration ++ */ ++&ap_pinctl { ++ /* MPP Bus: ++ * SDIO [0-10, 12] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 1 1 1 1 ++ 1 3 1 0 0 0 0 0 0 3 >; ++}; ++ ++/* ++ * CP related configuration ++ */ ++&cp0_pinctl { ++ cp0_nand_pins: cp0-nand-pins { ++ marvell,pins = <15 16 17 18 19 20 21 22 23 24 25 26 27 >; ++ marvell,function = <1>; ++ }; ++ cp0_nand_rb: cp0-nand-rb { ++ marvell,pins = < 13 >; ++ marvell,function = <2>; ++ }; ++}; ++ ++&cp0_pinctl { ++ /* MPP Bus: ++ * [0-11] RGMII1 ++ * [12] GPIO GE-IN ++ * [13-14] SPI1 ++ * [15-27] NAND ++ * [28] MSS_GPIO[5] XXX:(mode nr from a3900) ++ * [29-30] SATA ++ * [31] MSS_GPIO[4] XXX:(mode nr from a3900) ++ * [32,34] SMI ++ * [33] SDIO ++ * [35-36] I2C1 ++ * [37-38] I2C0 ++ * [39-43] SDIOctrl ++ * [44-55] RGMII2 ++ * [56-62] SDIO ++ */ ++ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 3 3 3 3 3 3 3 3 3 3 ++ 3 3 0 2 3 1 1 1 1 1 ++ 1 1 1 1 1 1 1 1 3 9 ++ 9 3 7 6 7 2 2 2 2 1 ++ 1 1 1 1 1 1 1 1 1 1 ++ 1 1 1 1 1 1 0xe 0xe 0xe 0xe ++ 0xe 0xe 0xe>; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_i2c1 { ++ status = "okay"; ++}; ++ ++/* CON 28 */ ++&cp0_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_sdhci_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++/* U54 */ ++&cp0_nand { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_nand_pins &cp0_nand_rb>; ++ status = "okay"; ++}; ++ ++/* U55 */ ++&cp0_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_spi0_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>, /* CS1 */ ++ <0 0xffffffff>, /* CS2 */ ++ <0 0xffffffff>; /* CS3 */ ++ status = "disabled"; ++ ++ spi-flash@0 { ++ #address-cells = <0x1>; ++ #size-cells = <0x1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0x0>; ++ /* On-board MUX does not allow higher frequencies */ ++ spi-max-frequency = <40000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0x0 0x200000>; ++ }; ++ ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xe00000>; ++ }; ++ }; ++ }; ++}; ++ ++&cp0_comphy { ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++/* SLM-1521-V2, CON6 */ ++&cp0_pcie0 { ++ num-lanes = <4>; ++ status = "okay"; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++/* SLM-1521-V2, CON9 */ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; ++}; ++ ++/* CON56 */ ++&cp0_eth1 { ++ status = "okay"; ++ phy = <&phy0>; ++ phy-mode = "rgmii-id"; ++}; ++ ++/* CON57 */ ++&cp0_eth2 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "rgmii-id"; ++}; ++ ++/* SLM-1521-V2, CON2 */ ++&cp0_sata0 { ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/cn9130-db-C.dts b/arch/arm/dts/cn9130-db-C.dts +new file mode 100644 +index 0000000000..c08aaf428f +--- /dev/null ++++ b/arch/arm/dts/cn9130-db-C.dts +@@ -0,0 +1,237 @@ ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++ ++#include "cn9130-db.dtsi" ++ ++/ { ++ model = "Marvell CN9130 development board (CP NOR) setup(C) PCIe EP"; ++ compatible = "marvell,cn9130-db", "marvell,cn91xx", "marvell,cn9030-vd", ++ "marvell,cn9030", "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++ ++ chosen { ++ stdout-path = "serial0:115200n8"; ++ }; ++ ++ aliases { ++ i2c0 = &cp0_i2c0; ++ spi0 = &cp0_spi1; ++ gpio0 = &ap_gpio0; ++ gpio1 = &cp0_gpio0; ++ gpio2 = &cp0_gpio1; ++ }; ++ ++ memory@00000000 { ++ device_type = "memory"; ++ reg = <0x0 0x0 0x0 0x80000000>; ++ }; ++ ++ reserved-memory { ++ #address-cells = <2>; ++ #size-cells = <2>; ++ ranges; ++ ++ /* The PCI console memory must be reserved */ ++ console_reserved: pci-console-nexus@3f000000 { ++ compatible = "marvell,pci-console-nexus-memory"; ++ reg = <0 0x3f000000 0 0x1000000>; ++ no-map; ++ }; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++/* ++ * AP related configuration ++ */ ++&ap_pinctl { ++ /* MPP Bus: ++ * SDIO [0-10, 12] ++ * UART0 [11,19] ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 1 1 1 1 1 1 1 1 1 1 ++ 1 3 1 0 0 0 0 0 0 3 >; ++}; ++ ++/* on-board eMMC - U9 */ ++&ap_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ap_emmc_pins>; ++ bus-width = <8>; ++ status = "okay"; ++}; ++ ++/* ++ * CP related configuration ++ */ ++&cp0_pinctl { ++ /* MPP Bus: ++ * [0-11] RGMII1 ++ * [12] GPIO GE-IN ++ * [13-16] SPI1 ++ * [17-27] NAND ++ * [28] MSS_GPIO[5] XXX:(mode nr from a3900) ++ * [29-30] SATA ++ * [31] MSS_GPIO[4] XXX:(mode nr from a3900) ++ * [32,34] SMI ++ * [33] SDIO ++ * [35-36] I2C1 ++ * [37-38] I2C0 ++ * [39-43] SDIOctrl ++ * [44-55] RGMII2 ++ * [56-62] SDIO ++ */ ++ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 3 3 3 3 3 3 3 3 3 3 ++ 3 3 0 3 3 3 3 1 1 1 ++ 1 1 1 1 1 1 1 1 3 9 ++ 9 3 7 6 7 2 2 2 2 1 ++ 1 1 1 1 1 1 1 1 1 1 ++ 1 1 1 1 1 1 0xe 0xe 0xe 0xe ++ 0xe 0xe 0xe>; ++}; ++ ++&cp0_bootcmd { ++ status = "okay"; ++}; ++ ++&cp0_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp0_i2c1 { ++ status = "okay"; ++}; ++ ++/* CON 28 */ ++&cp0_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_sdhci_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++/* U54 */ ++&cp0_nand { ++ status = "disabled"; ++}; ++ ++/* U55 */ ++&cp0_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp0_spi0_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>, /* CS1 */ ++ <0 0xffffffff>, /* CS2 */ ++ <0 0xffffffff>; /* CS3 */ ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <0x1>; ++ #size-cells = <0x1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0x0>; ++ /* On-board MUX does not allow higher frequencies */ ++ spi-max-frequency = <40000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0x0 0x200000>; ++ }; ++ ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xe00000>; ++ }; ++ }; ++ }; ++}; ++ ++&cp0_comphy { ++ ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp0_mdio { ++ status = "okay"; ++ phy0: ethernet-phy@0 { ++ reg = <0>; ++ }; ++ phy1: ethernet-phy@1 { ++ reg = <1>; ++ }; ++}; ++ ++&cp0_ethernet { ++ status = "okay"; ++}; ++ ++/* SLM-1521-V2, CON9 */ ++&cp0_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; ++}; ++ ++/* CON56 */ ++&cp0_eth1 { ++ status = "okay"; ++ phy = <&phy0>; ++ phy-mode = "rgmii-id"; ++}; ++ ++/* CON57 */ ++&cp0_eth2 { ++ status = "okay"; ++ phy = <&phy1>; ++ phy-mode = "rgmii-id"; ++}; ++ ++/* SLM-1521-V2, CON2 */ ++&cp0_sata0 { ++ status = "okay"; ++}; ++ ++&cp0_pcie0{ ++ status = "disabled"; ++}; +diff --git a/arch/arm/dts/cn9130-db-dev-info.dtsi b/arch/arm/dts/cn9130-db-dev-info.dtsi +new file mode 100644 +index 0000000000..f2e7c033b7 +--- /dev/null ++++ b/arch/arm/dts/cn9130-db-dev-info.dtsi +@@ -0,0 +1,44 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++/ { ++ /* This should go only into devel boards */ ++ compatible = "marvell,cp110"; ++ sar { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ sar_fields { ++ compatible = "marvell,sample-at-reset"; ++ reg = <0x4c 0x4e>; ++ chip_count = <2>; ++ bit_width = <5>; ++ freq { ++ key = "freq"; ++ description = "CPU/DDR and PIDI frequencies"; ++ start-bit = <0>; ++ bit-length = <4>; ++ option-cnt = <3>; ++ options = "0x0", "CPU/DDR = 0x0: 2000/1200 Mhz, PIDI = 0: 1Ghz", ++ "0x2", "CPU/DDR = 0x6: 2200/1200 Mhz, PIDI = 0: 1Ghz", ++ "0x4", "CPU/DDR = 0xD: 1600/1200 Mhz, PIDI = 0: 1Ghz"; ++ default = <0x2>; ++ status = "okay"; ++ }; ++ boot_mode { ++ key = "boot_mode"; ++ description = "Boot mode options"; ++ start-bit = <4>; ++ bit-length = <6>; ++ option-cnt = <4>; ++ options = "0xE", "CP0_NAND PIDI BW-8bit, PS-4KB, ECC-4bit\t(supported configuration: B)", ++ "0xF", "CP0_NAND PIDI BW-8bit, PS-4KB, ECC-8bit\t(supported configuration: B)", ++ "0x2A", "AP_EMMC", ++ "0x32", "CP1_SPI_1 24bits"; ++ default = <0x32>; ++ status = "okay"; ++ }; ++ }; ++ }; ++}; +diff --git a/arch/arm/dts/cn9130-db.dtsi b/arch/arm/dts/cn9130-db.dtsi +new file mode 100644 +index 0000000000..fa79d15673 +--- /dev/null ++++ b/arch/arm/dts/cn9130-db.dtsi +@@ -0,0 +1,153 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#include "cn9130.dtsi" /* include SoC device tree */ ++#include "cn9130-db-dev-info.dtsi" ++ ++/ { ++ model = "DB-CN-9130"; ++ compatible = "marvell,cn9030", "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++ ++ cp0 { ++ config-space { ++ i2c@701000 { ++ /* U36 */ ++ expander0: pca953x@21 { ++ compatible = "nxp,pca9555"; ++ #gpio-cells = <2>; ++ reg = <0x21>; ++ status = "okay"; ++ }; ++ }; ++ sdhci@780000 { ++ vqmmc-supply = <&cp0_reg_sd_vccq>; ++ vmmc-supply = <&cp0_reg_sd_vcc>; ++ }; ++ ++ ap_reg_mmc_vccq: ap_mmc_vccq@0 { ++ compatible = "regulator-gpio"; ++ regulator-name = "ap_mmc_vccq"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ gpios = <&expander0 8 GPIO_ACTIVE_HIGH>; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ }; ++ cp0_reg_usb3_vbus0: cp0_usb3_vbus@0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "cp0-xhci0-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <100000>; ++ regulator-force-boot-off; ++ gpio = <&expander0 0 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ cp0_reg_usb3_vbus1: cp0_usb3_vbus@1 { ++ compatible = "regulator-fixed"; ++ regulator-name = "cp0-xhci1-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <100000>; ++ regulator-force-boot-off; ++ gpio = <&expander0 1 GPIO_ACTIVE_HIGH>; ++ }; ++ cp0_reg_sd_vccq: cp0_sd_vccq@0 { ++ compatible = "regulator-gpio"; ++ regulator-name = "cp0_sd_vccq"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ gpios = <&expander0 15 GPIO_ACTIVE_HIGH>; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ }; ++ cp0_reg_sd_vcc: cp0_sd_vcc@0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "cp0_sd_vcc"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ gpio = <&expander0 14 GPIO_ACTIVE_HIGH>; ++ enable-active-high; ++ regulator-always-on; ++ }; ++ cp0_reg_usb3_current_lim0:cp0_usb3_current_limiter@0 { ++ compatible = "regulator-fixed"; ++ regulator-min-microamp = <900000>; ++ regulator-max-microamp = <900000>; ++ regulator-force-boot-off; ++ gpio = <&expander0 4 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ cp0_reg_usb3_current_lim1: cp0_usb3_current_limiter@1 { ++ compatible = "regulator-fixed"; ++ regulator-min-microamp = <900000>; ++ regulator-max-microamp = <900000>; ++ regulator-force-boot-off; ++ gpio = <&expander0 5 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++ }; ++}; ++ ++&ap_hd_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&ap_ld_efuse1 { ++ status = "okay"; ++}; ++ ++/* on-board eMMC - U9 */ ++&ap_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ap_emmc_pins>; ++ vqmmc-supply = <&ap_reg_mmc_vccq>; ++ bus-width = <8>; ++ mmc-ddr-1_8v; ++ mmc-hs400-1_8v; ++ status = "okay"; ++}; ++ ++/* ++ * CP0 ++ */ ++&cp0_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp0_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp0_utmi0 { ++ status = "okay"; ++}; ++ ++&cp0_utmi1 { ++ status = "okay"; ++}; ++ ++&cp0_usb3_0 { ++ status = "okay"; ++ vbus-supply = <&cp0_reg_usb3_vbus0>; ++ current-limiter = <&cp0_reg_usb3_current_lim0>; ++ vbus-disable-delay = <500>; ++}; ++ ++&cp0_usb3_1 { ++ status = "okay"; ++ vbus-supply = <&cp0_reg_usb3_vbus1>; ++ current-limiter = <&cp0_reg_usb3_current_lim1>; ++ vbus-disable-delay = <500>; ++}; ++ ++&cp0_pcie0 { ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/cn9130.dtsi b/arch/arm/dts/cn9130.dtsi +new file mode 100644 +index 0000000000..c02af096e4 +--- /dev/null ++++ b/arch/arm/dts/cn9130.dtsi +@@ -0,0 +1,87 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++ ++/* ++ * Device Tree file for the CN 9030 SoC, made of an AP806 Quad and ++ * one CP110. ++ */ ++ ++#include ++#include "armada-common.dtsi" ++#include "armada-ap807.dtsi" ++#include "armada-ap80x-quad.dtsi" ++ ++/* This defines used to calculate the base address of each CP */ ++#define CP110_BASE_OFFSET (0xf2000000) ++#define CP110_SPACE_SIZE (0x02000000) ++#define CP110_BASE (CP110_BASE_OFFSET + \ ++ (CP110_NUM * CP110_SPACE_SIZE)) ++ ++#define CP110_PCIE_MEM_SIZE(iface) ((iface == 0) ? 0x1ff00000 : 0xf00000) ++#define CP110_PCIE_BUS_MEM_CFG (0x82000000) ++ ++/* CP110-0 Settings */ ++#define CP110_NAME cp0 ++#define CP110_NUM 0 ++#define CP110_PCIEx_CPU_MEM_BASE(iface) ((iface == 0) ? 0xc0000000 : \ ++ (0xe0000000 + (iface - 1) * 0x1000000)) ++#define CP110_PCIEx_BUS_MEM_BASE(iface) (CP110_PCIEx_CPU_MEM_BASE(iface)) ++ ++#include "armada-cp110.dtsi" ++ ++/ { ++ model = "Marvell CN 9030"; ++ compatible = "marvell,armada70x0", "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++ ++ aliases { ++ fuse0 = &ap_hd_efuse0; /* banks 0-63 RW */ ++ fuse1 = &ap_ld_efuse0; /* bank 64 RO */ ++ fuse2 = &ap_ld_efuse1; /* bank 65 RW */ ++ fuse3 = &cp0_ld_efuse0; /* bank 66 RO */ ++ fuse4 = &cp0_ld_efuse1; /* bank 67 RW */ ++ }; ++}; ++ ++&cp0_rtc { ++ status = "okay"; ++}; ++ ++&cp0_pinctl { ++ compatible = "marvell,mvebu-pinctrl", "marvell,armada-8k-cpm-pinctrl"; ++ bank-name ="cp0-110"; ++ ++ cp0_i2c0_pins: cp0-i2c-pins-0 { ++ marvell,pins = < 37 38 >; ++ marvell,function = <2>; ++ }; ++ cp0_i2c1_pins: cp0-i2c-pins-1 { ++ marvell,pins = < 35 36 >; ++ marvell,function = <2>; ++ }; ++ cp0_ge1_rgmii_pins: cp0-ge-rgmii-pins-0 { ++ marvell,pins = < 0 1 2 3 4 5 6 7 8 9 10 11>; ++ marvell,function = <3>; ++ }; ++ cp0_ge2_rgmii_pins: cp0-ge-rgmii-pins-1 { ++ marvell,pins = < 44 45 46 47 48 49 50 51 ++ 52 53 54 55 >; ++ marvell,function = <1>; ++ }; ++ cp0_pca0_pins: cp0-pca0_pins { ++ marvell,pins = <62>; ++ marvell,function = <0>; ++ }; ++ cp0_sdhci_pins: cp0-sdhi-pins-0 { ++ marvell,pins = < 56 57 58 59 60 61 >; ++ marvell,function = <14>; ++ }; ++ cp0_spi0_pins: cp0-spi-pins-0 { ++ marvell,pins = < 13 14 15 16 >; ++ marvell,function = <3>; ++ }; ++}; +diff --git a/arch/arm/dts/cn9131-db-A.dts b/arch/arm/dts/cn9131-db-A.dts +new file mode 100644 +index 0000000000..74a19c7dc2 +--- /dev/null ++++ b/arch/arm/dts/cn9131-db-A.dts +@@ -0,0 +1,56 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++ ++#include "cn9130-db-A.dts" ++#include "cn9131-db.dtsi" ++ ++/ { ++ model = "Marvell CN9131 development board (CP NOR) setup(A)"; ++ compatible = "marvell,cn9131-db", "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++}; ++ ++&cp1_comphy { ++ /* Serdes Configuration: ++ * Lane 0: PCIe0 (x2) ++ * Lane 1: PCIe0 (x2) ++ * Lane 2: unconnected ++ * Lane 3: USB1 ++ * Lane 4: SFP (port 0) ++ * Lane 5: SATA1 ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ phy1 { ++ phy-type = ; ++ }; ++ phy2 { ++ phy-type = ; ++ }; ++ phy3 { ++ phy-type = ; ++ }; ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp1_ethernet { ++ status = "okay"; ++}; ++ ++/* CON50 */ ++&cp1_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-4 */ ++ marvell,sfp-tx-disable-gpio = <&cp1_gpio0 9 GPIO_ACTIVE_HIGH>; ++}; +diff --git a/arch/arm/dts/cn9131-db-B.dts b/arch/arm/dts/cn9131-db-B.dts +new file mode 100644 +index 0000000000..cd67ed7858 +--- /dev/null ++++ b/arch/arm/dts/cn9131-db-B.dts +@@ -0,0 +1,71 @@ ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++ ++#include "cn9130-db-B.dts" ++#include "cn9131-db.dtsi" ++ ++/ { ++ model = "Marvell CN9131 development board (CP NAND) setup(B)"; ++ compatible = "marvell,cn9131-db", "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++}; ++ ++&cp1_comphy { ++ /* Serdes Configuration: ++ * Lane 0: PCIe0 (x2) ++ * Lane 1: PCIe0 (x2) ++ * Lane 2: SFI (port 0) ++ * Lane 3: USB1 ++ * Lane 4: SGMII (port 1) ++ * Lane 5: SATA1 ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ phy1 { ++ phy-type = ; ++ }; ++ phy2 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ phy3 { ++ phy-type = ; ++ }; ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp1_ethernet { ++ status = "okay"; ++}; ++ ++/* 3310 RJ45 CON55 */ ++&cp1_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-2 */ ++ phy = <&sfi_phy8>; /* required by 3310 fw download */ ++}; ++ ++/* CON50 */ ++&cp1_eth1 { ++ status = "okay"; ++ phy-mode = "sgmii"; /* lane-4 */ ++ marvell,sfp-tx-disable-gpio = <&cp1_gpio0 9 GPIO_ACTIVE_HIGH>; ++}; ++ ++&cp1_xmdio { ++ status = "okay"; ++ sfi_phy8: ethernet-phy@8 { ++ reg = <8>; ++ }; ++}; +diff --git a/arch/arm/dts/cn9131-db-C.dts b/arch/arm/dts/cn9131-db-C.dts +new file mode 100644 +index 0000000000..7365479f4d +--- /dev/null ++++ b/arch/arm/dts/cn9131-db-C.dts +@@ -0,0 +1,55 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++#include "cn9130-db-C.dts" ++#include "cn9131-db.dtsi" ++ ++/ { ++ model = "Marvell CN9131 development board (CP NOR) setup(C)"; ++ compatible = "marvell,cn9131-db", "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++}; ++ ++&cp1_comphy { ++ /* Serdes Configuration: ++ * Lane 0: PCIe0 (x2) ++ * Lane 1: PCIe0 (x2) ++ * Lane 2: unconnected ++ * Lane 3: USB1 ++ * Lane 4: SFP (port 0) ++ * Lane 5: SATA1 ++ */ ++ phy0 { ++ phy-type = ; ++ }; ++ phy1 { ++ phy-type = ; ++ }; ++ phy2 { ++ phy-type = ; ++ }; ++ phy3 { ++ phy-type = ; ++ }; ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp0_pcie0{ ++ status = "disabled"; ++}; ++ ++&cp1_ethernet { ++ status = "okay"; ++}; ++ ++/* CON50 */ ++&cp1_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; /* lane-4 */ ++ marvell,sfp-tx-disable-gpio = <&cp1_gpio0 9 GPIO_ACTIVE_HIGH>; ++}; +diff --git a/arch/arm/dts/cn9131-db.dtsi b/arch/arm/dts/cn9131-db.dtsi +new file mode 100644 +index 0000000000..8dbf61ac1f +--- /dev/null ++++ b/arch/arm/dts/cn9131-db.dtsi +@@ -0,0 +1,178 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++ ++#undef CP110_NAME ++#undef CP110_NUM ++#undef CP110_PCIE_MEM_SIZE ++#undef CP110_PCIEx_CPU_MEM_BASE ++#undef CP110_PCIEx_BUS_MEM_BASE ++ ++/* CP110-1 Settings */ ++#define CP110_NAME cp1 ++#define CP110_NUM 1 ++#define CP110_PCIE_MEM_SIZE(iface) (0xf00000) ++#define CP110_PCIEx_CPU_MEM_BASE(iface) (0xe2000000 + (iface) * 0x1000000) ++#define CP110_PCIEx_BUS_MEM_BASE(iface) (CP110_PCIEx_CPU_MEM_BASE(iface)) ++ ++#include "armada-cp110.dtsi" ++ ++/ { ++ model = "Marvell CN9131 development board"; ++ compatible = "marvell,cn9131-db"; ++ ++ aliases { ++ gpio3 = &cp1_gpio0; ++ gpio4 = &cp1_gpio1; ++ fuse5 = &cp1_ld_efuse0; /* bank 68 RO */ ++ fuse6 = &cp1_ld_efuse1; /* bank 69 RW */ ++ }; ++ ++ cp1 { ++ config-space { ++ cp1_reg_usb3_vbus0: cp1_usb3_vbus@0 { ++ compatible = "regulator-fixed"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp1_xhci0_vbus_pins>; ++ regulator-name = "cp1-xhci0-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <100000>; ++ regulator-force-boot-off; ++ gpio = <&cp1_gpio0 3 GPIO_ACTIVE_HIGH>; ++ }; ++ cp1_reg_usb3_current_lim0: cp1_usb3_current_limiter@0 { ++ compatible = "regulator-fixed"; ++ regulator-min-microamp = <900000>; ++ regulator-max-microamp = <900000>; ++ regulator-force-boot-off; ++ gpio = <&cp1_gpio0 2 GPIO_ACTIVE_HIGH>; ++ }; ++ cp1_pcie_reset_pins: cp1-pcie-reset-pins { ++ marvell,pins = <0>; ++ marvell,function = <0>; ++ }; ++ }; ++ }; ++}; ++ ++&cp1_ld_efuse0 { ++ status = "okay"; ++}; ++ ++&cp1_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp1_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp1_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++/* CON40 */ ++&cp1_pcie0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp1_pcie_reset_pins>; ++ marvell,reset-gpio = <&cp1_gpio0 0 GPIO_ACTIVE_LOW>; ++ status = "okay"; ++ num-lanes = <2>; ++ /* non-prefetchable memory */ ++ ranges = <0x82000000 0 0xe2000000 0 0xe2000000 0 0xf00000>; ++}; ++ ++&cp1_pinctl { ++ compatible = "marvell,mvebu-pinctrl", ++ "marvell,cp115-standalone-pinctrl"; ++ bank-name ="cp1-110"; ++ ++ /* MPP Bus: ++ * [0-12] GPIO ++ * [13-16] SPI1 ++ * [17-27] GPIO (Default) ++ * [28] SATA1_PRESENT_ACTIVEn ++ * [29-34] GPIO (Default) ++ * [35-36] xSMI ++ * [37-38] I2C0 ++ * [39-62] GPIO ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ++ 0x0 0x0 0x0 0x3 0x3 0x3 0x3 0x0 0x0 0x0 ++ 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x9 0x0 ++ 0x0 0x0 0x0 0x0 0x0 0x7 0x7 0x2 0x2 0x0 ++ 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ++ 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ++ 0x0 0x0 0x0 >; ++ ++ cp1_i2c0_pins: cp1-i2c-pins-0 { ++ marvell,pins = < 37 38 >; ++ marvell,function = <2>; ++ }; ++ cp1_spi0_pins: cp1-spi-pins-0 { ++ marvell,pins = < 13 14 15 16 >; ++ marvell,function = <3>; ++ }; ++ cp1_xhci0_vbus_pins: cp1-xhci0-vbus-pins { ++ marvell,pins = <3>; ++ marvell,function = <0>; ++ }; ++}; ++ ++/* CON32 */ ++&cp1_sata0 { ++ status = "okay"; ++}; ++ ++/* U24 */ ++&cp1_spi1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp1_spi0_pins>; ++ reg = <0x700680 0x50>, /* control */ ++ <0x2000000 0x1000000>, /* CS0 */ ++ <0 0xffffffff>, /* CS1 */ ++ <0 0xffffffff>, /* CS2 */ ++ <0 0xffffffff>; /* CS3 */ ++ status = "okay"; ++ ++ spi-flash@0 { ++ #address-cells = <0x1>; ++ #size-cells = <0x1>; ++ compatible = "jedec,spi-nor", "spi-flash"; ++ reg = <0x0>; ++ /* On-board MUX does not allow higher frequencies */ ++ spi-max-frequency = <40000000>; ++ ++ partitions { ++ compatible = "fixed-partitions"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "U-Boot"; ++ reg = <0x0 0x200000>; ++ }; ++ ++ partition@400000 { ++ label = "Filesystem"; ++ reg = <0x200000 0xe00000>; ++ }; ++ }; ++ }; ++}; ++ ++/* CON58 */ ++&cp1_usb3_1 { ++ vbus-supply = <&cp1_reg_usb3_vbus0>; ++ current-limiter = <&cp1_reg_usb3_current_lim0>; ++ vbus-disable-delay = <500>; ++ status = "okay"; ++}; ++ ++&cp1_utmi1 { ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/cn9132-db-A.dts b/arch/arm/dts/cn9132-db-A.dts +new file mode 100644 +index 0000000000..a8930d46d8 +--- /dev/null ++++ b/arch/arm/dts/cn9132-db-A.dts +@@ -0,0 +1,109 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++ ++#include "cn9131-db-A.dts" ++#include "cn9132-db.dtsi" ++ ++/ { ++ model = "Marvell CN9132 development board (CP NOR) setup(A)"; ++ compatible = "marvell,cn9132-db", "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++}; ++ ++&cp2_comphy { ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp2_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp2_ethernet { ++ status = "okay"; ++}; ++ ++/* SLM-1521-V2, CON9 */ ++&cp2_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; ++}; ++ ++/* SLM-1521-V2, CON6 */ ++&cp2_pcie0 { ++ num-lanes = <2>; ++ status = "okay"; ++}; ++ ++/* SLM-1521-V2, CON8 */ ++&cp2_pcie2 { ++ num-lanes = <1>; ++ status = "okay"; ++}; ++ ++&cp2_pinctl { ++ /* MPP Bus: ++ * [0-26] GPIO ++ * [27] SATA0_PRESENT_ACTIVEn ++ * [28] SATA1_PRESENT_ACTIVEn ++ * [29-31, 33] GPIO (Default) ++ * [32,34] SMI ++ * [37-38] I2C0 ++ * [39-53] GPIO ++ * [54] SD_CRD_RSTn (out) ++ * [55] SD_CRD_DT (in) ++ * [56-62] SDIO ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ++ 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ++ 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x9 0x9 0x0 ++ 0x0 0x0 0x8 0x0 0x8 0x0 0x0 0x2 0x2 0x0 ++ 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ++ 0x0 0x0 0x0 0x0 0xa 0xb 0xe 0xe 0xe 0xe ++ 0xe 0xe 0xe >; ++}; ++ ++/* SLM-1521-V2, CON4 */ ++&cp2_sata0 { ++ status = "okay"; ++}; ++ ++/* CON 2 on SLM-1683 - microSD */ ++&cp2_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp2_sdhci_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++/* SLM-1521-V2, CON11 */ ++&cp2_usb3_1 { ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/cn9132-db-B.dts b/arch/arm/dts/cn9132-db-B.dts +new file mode 100644 +index 0000000000..1575995213 +--- /dev/null ++++ b/arch/arm/dts/cn9132-db-B.dts +@@ -0,0 +1,109 @@ ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++ ++#include "cn9131-db-B.dts" ++#include "cn9132-db.dtsi" ++ ++/ { ++ model = "Marvell CN9132 development board (CP NAND) setup(B)"; ++ compatible = "marvell,cn9132-db-B", "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++}; ++ ++&cp2_comphy { ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp2_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp2_ethernet { ++ status = "okay"; ++}; ++ ++/* SLM-1521-V2, CON9 */ ++&cp2_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; ++}; ++ ++/* SLM-1521-V2, CON6 */ ++&cp2_pcie0 { ++ num-lanes = <2>; ++ status = "okay"; ++}; ++ ++/* SLM-1521-V2, CON8 */ ++&cp2_pcie2 { ++ num-lanes = <1>; ++ status = "okay"; ++}; ++ ++&cp2_pinctl { ++ /* MPP Bus: ++ * [0-26] GPIO ++ * [27] SATA0_PRESENT_ACTIVEn ++ * [28] SATA1_PRESENT_ACTIVEn ++ * [29-31, 33] GPIO (Default) ++ * [32,34] SMI ++ * [37-38] I2C0 ++ * [39-53] GPIO ++ * [54] SD_CRD_RSTn (out) ++ * [55] SD_CRD_DT (in) ++ * [56-62] SDIO ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ++ 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ++ 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x9 0x9 0x0 ++ 0x0 0x0 0x8 0x0 0x8 0x0 0x0 0x2 0x2 0x0 ++ 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ++ 0x0 0x0 0x0 0x0 0xa 0xb 0xe 0xe 0xe 0xe ++ 0xe 0xe 0xe >; ++}; ++ ++/* SLM-1521-V2, CON4 */ ++&cp2_sata0 { ++ status = "okay"; ++}; ++ ++/* CON 2 on SLM-1683 - microSD */ ++&cp2_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp2_sdhci_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++/* SLM-1521-V2, CON11 */ ++&cp2_usb3_1 { ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/cn9132-db-C.dts b/arch/arm/dts/cn9132-db-C.dts +new file mode 100644 +index 0000000000..87bf79db5c +--- /dev/null ++++ b/arch/arm/dts/cn9132-db-C.dts +@@ -0,0 +1,104 @@ ++// SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ ++#include "cn9131-db-C.dts" ++#include "cn9132-db.dtsi" ++ ++/ { ++ model = "Marvell CN9132 development board (CP NOR) setup(C)"; ++ compatible = "marvell,cn9132-db", "marvell,armada-ap806-quad", ++ "marvell,armada-ap806"; ++}; ++ ++&cp2_comphy { ++ phy0 { ++ phy-type = ; ++ }; ++ ++ phy1 { ++ phy-type = ; ++ }; ++ ++ phy2 { ++ phy-type = ; ++ }; ++ ++ phy3 { ++ phy-type = ; ++ }; ++ ++ phy4 { ++ phy-type = ; ++ phy-speed = ; ++ }; ++ ++ phy5 { ++ phy-type = ; ++ }; ++}; ++ ++&cp2_ld_efuse1 { ++ status = "okay"; ++}; ++ ++&cp2_ethernet { ++ status = "okay"; ++}; ++ ++/* SLM-1521-V2, CON9 */ ++&cp2_eth0 { ++ status = "okay"; ++ phy-mode = "sfi"; ++}; ++ ++/* SLM-1521-V2, CON6 */ ++&cp2_pcie0 { ++ num-lanes = <2>; ++ status = "okay"; ++}; ++ ++/* SLM-1521-V2, CON8 */ ++&cp2_pcie2 { ++ num-lanes = <1>; ++ status = "okay"; ++}; ++ ++&cp2_pinctl { ++ /* MPP Bus: ++ * [0-26] GPIO ++ * [27] SATA0_PRESENT_ACTIVEn ++ * [28] SATA1_PRESENT_ACTIVEn ++ * [29-31, 33] GPIO (Default) ++ * [32,34] SMI ++ * [37-38] I2C0 ++ * [39-53] GPIO ++ * [54] SD_CRD_RSTn (out) ++ * [55] SD_CRD_DT (in) ++ * [56-62] SDIO ++ */ ++ /* 0 1 2 3 4 5 6 7 8 9 */ ++ pin-func = < 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ++ 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ++ 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x9 0x9 0x0 ++ 0x0 0x0 0x8 0x0 0x8 0x0 0x0 0x2 0x2 0x0 ++ 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0 ++ 0x0 0x0 0x0 0x0 0xa 0xb 0xe 0xe 0xe 0xe ++ 0xe 0xe 0xe >; ++}; ++ ++/* SLM-1521-V2, CON4 */ ++&cp2_sata0 { ++ status = "okay"; ++}; ++ ++/* CON 2 on SLM-1683 - microSD */ ++&cp2_sdhci0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp2_sdhci_pins>; ++ bus-width = <4>; ++ status = "okay"; ++}; ++ ++/* SLM-1521-V2, CON11 */ ++&cp2_usb3_1 { ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/cn9132-db.dtsi b/arch/arm/dts/cn9132-db.dtsi +new file mode 100644 +index 0000000000..add9f60237 +--- /dev/null ++++ b/arch/arm/dts/cn9132-db.dtsi +@@ -0,0 +1,134 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++ ++#undef CP110_NAME ++#undef CP110_NUM ++#undef CP110_PCIE_MEM_SIZE ++#undef CP110_PCIEx_CPU_MEM_BASE ++#undef CP110_PCIEx_BUS_MEM_BASE ++ ++/* CP110-2 Settings */ ++#define CP110_NAME cp2 ++#define CP110_NUM 2 ++#define CP110_PCIE_MEM_SIZE(iface) (0xf00000) ++#define CP110_PCIEx_CPU_MEM_BASE(iface) (0xe5000000 + (iface) * 0x1000000) ++#define CP110_PCIEx_BUS_MEM_BASE(iface) (CP110_PCIEx_CPU_MEM_BASE(iface)) ++ ++#include "armada-cp110.dtsi" ++ ++/ { ++ model = "Marvell CN9132 development board"; ++ compatible = "marvell,cn9132-db"; ++ ++ aliases { ++ gpio5 = &cp2_gpio0; ++ gpio6 = &cp2_gpio1; ++ fuse7 = &cp2_ld_efuse0; /* bank 70 RO */ ++ fuse8 = &cp2_ld_efuse1; /* bank 71 RW */ ++ }; ++ ++ cp2 { ++ config-space { ++ sdhci@780000 { ++ vqmmc-supply = <&cp2_reg_sd_vccq>; ++ }; ++ cp2_reg_usb3_vbus0: cp2_usb3_vbus@0 { ++ compatible = "regulator-fixed"; ++ regulator-name = "cp2-xhci0-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <100000>; ++ regulator-force-boot-off; ++ gpio = <&cp2_gpio0 2 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ cp2_reg_usb3_vbus1: cp2_usb3_vbus@1 { ++ compatible = "regulator-fixed"; ++ regulator-name = "cp2-xhci1-vbus"; ++ regulator-min-microvolt = <5000000>; ++ regulator-max-microvolt = <5000000>; ++ startup-delay-us = <100000>; ++ regulator-force-boot-off; ++ gpio = <&cp2_gpio0 3 GPIO_ACTIVE_HIGH>; ++ }; ++ cp2_reg_sd_vccq: cp2_sd_vccq@0 { ++ compatible = "regulator-gpio"; ++ regulator-name = "cp2_sd_vcc"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <3300000>; ++ /* cp2_mpp49 */ ++ gpios = <&cp2_gpio1 17 GPIO_ACTIVE_HIGH>; ++ states = <1800000 0x1 ++ 3300000 0x0>; ++ }; ++ cp2_reg_usb3_current_lim0: cp2_usb3_current_limiter@0 { ++ compatible = "regulator-fixed"; ++ regulator-min-microamp = <900000>; ++ regulator-max-microamp = <900000>; ++ regulator-force-boot-off; ++ gpio = <&cp2_gpio0 0 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ cp2_reg_usb3_current_lim1: cp2_usb3_current_limiter@1 { ++ compatible = "regulator-fixed"; ++ regulator-min-microamp = <900000>; ++ regulator-max-microamp = <900000>; ++ regulator-force-boot-off; ++ gpio = <&cp2_gpio0 1 GPIO_ACTIVE_HIGH>; ++ }; ++ }; ++ }; ++}; ++ ++&cp2_i2c0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&cp2_i2c0_pins>; ++ status = "okay"; ++ clock-frequency = <100000>; ++}; ++ ++&cp2_pcie0 { ++ /* non-prefetchable memory */ ++ ranges =<0x82000000 0 0xe5000000 0 0xe5000000 0 0x1000000>; ++}; ++ ++&cp2_pinctl { ++ compatible = "marvell,mvebu-pinctrl", ++ "marvell,cp115-standalone-pinctrl"; ++ bank-name ="cp2-110"; ++ ++ cp2_i2c0_pins: cp2-i2c-pins-0 { ++ marvell,pins = < 37 38 >; ++ marvell,function = <2>; ++ }; ++ cp2_sdhci_pins: cp2-sdhi-pins-0 { ++ marvell,pins = < 56 57 58 59 60 61 >; ++ marvell,function = <14>; ++ }; ++}; ++ ++&cp2_usb3_0 { ++ status = "okay"; ++ vbus-supply = <&cp2_reg_usb3_vbus0>; ++ current-limiter = <&cp2_reg_usb3_current_lim0>; ++ vbus-disable-delay = <500>; ++}; ++ ++&cp2_usb3_1 { ++ status = "okay"; ++ vbus-supply = <&cp2_reg_usb3_vbus1>; ++ current-limiter = <&cp2_reg_usb3_current_lim1>; ++ vbus-disable-delay = <500>; ++}; ++ ++&cp2_utmi0 { ++ status = "okay"; ++}; ++ ++&cp2_utmi1 { ++ status = "okay"; ++}; +diff --git a/arch/arm/dts/thunderx-88xx.dts b/arch/arm/dts/thunderx-88xx.dts +deleted file mode 100644 +index 22d8f7efb2..0000000000 +--- a/arch/arm/dts/thunderx-88xx.dts ++++ /dev/null +@@ -1,30 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0+ OR X11 +-/* +- * Cavium Thunder DTS file - Thunder board description +- * +- * Copyright (C) 2014, Cavium Inc. +- * +- */ +- +-/dts-v1/; +- +-/include/ "thunderx-88xx.dtsi" +- +-/ { +- model = "Cavium ThunderX CN88XX board"; +- compatible = "cavium,thunder-88xx"; +- +- aliases { +- serial0 = &uaa0; +- serial1 = &uaa1; +- }; +- +- chosen { +- stdout-path = &uaa0; +- }; +- +- memory@00000000 { +- device_type = "memory"; +- reg = <0x0 0x00000000 0x0 0x80000000>; +- }; +-}; +diff --git a/arch/arm/dts/thunderx-88xx.dtsi b/arch/arm/dts/thunderx-88xx.dtsi +deleted file mode 100644 +index b8d6f7b315..0000000000 +--- a/arch/arm/dts/thunderx-88xx.dtsi ++++ /dev/null +@@ -1,362 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0+ OR X11 +-/* +- * Cavium Thunder DTS file - Thunder SoC description +- * +- * Copyright (C) 2014, Cavium Inc. +- * +- */ +- +-/ { +- compatible = "cavium,thunder-88xx"; +- interrupt-parent = <&gic0>; +- #address-cells = <2>; +- #size-cells = <2>; +- +- psci { +- compatible = "arm,psci-0.2"; +- method = "smc"; +- }; +- +- cpus { +- #address-cells = <2>; +- #size-cells = <0>; +- +- cpu@000 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x000>; +- enable-method = "psci"; +- }; +- cpu@001 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x001>; +- enable-method = "psci"; +- }; +- cpu@002 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x002>; +- enable-method = "psci"; +- }; +- cpu@003 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x003>; +- enable-method = "psci"; +- }; +- cpu@004 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x004>; +- enable-method = "psci"; +- }; +- cpu@005 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x005>; +- enable-method = "psci"; +- }; +- cpu@006 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x006>; +- enable-method = "psci"; +- }; +- cpu@007 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x007>; +- enable-method = "psci"; +- }; +- cpu@008 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x008>; +- enable-method = "psci"; +- }; +- cpu@009 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x009>; +- enable-method = "psci"; +- }; +- cpu@00a { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x00a>; +- enable-method = "psci"; +- }; +- cpu@00b { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x00b>; +- enable-method = "psci"; +- }; +- cpu@00c { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x00c>; +- enable-method = "psci"; +- }; +- cpu@00d { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x00d>; +- enable-method = "psci"; +- }; +- cpu@00e { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x00e>; +- enable-method = "psci"; +- }; +- cpu@00f { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x00f>; +- enable-method = "psci"; +- }; +- cpu@100 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x100>; +- enable-method = "psci"; +- }; +- cpu@101 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x101>; +- enable-method = "psci"; +- }; +- cpu@102 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x102>; +- enable-method = "psci"; +- }; +- cpu@103 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x103>; +- enable-method = "psci"; +- }; +- cpu@104 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x104>; +- enable-method = "psci"; +- }; +- cpu@105 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x105>; +- enable-method = "psci"; +- }; +- cpu@106 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x106>; +- enable-method = "psci"; +- }; +- cpu@107 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x107>; +- enable-method = "psci"; +- }; +- cpu@108 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x108>; +- enable-method = "psci"; +- }; +- cpu@109 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x109>; +- enable-method = "psci"; +- }; +- cpu@10a { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x10a>; +- enable-method = "psci"; +- }; +- cpu@10b { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x10b>; +- enable-method = "psci"; +- }; +- cpu@10c { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x10c>; +- enable-method = "psci"; +- }; +- cpu@10d { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x10d>; +- enable-method = "psci"; +- }; +- cpu@10e { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x10e>; +- enable-method = "psci"; +- }; +- cpu@10f { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x10f>; +- enable-method = "psci"; +- }; +- cpu@200 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x200>; +- enable-method = "psci"; +- }; +- cpu@201 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x201>; +- enable-method = "psci"; +- }; +- cpu@202 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x202>; +- enable-method = "psci"; +- }; +- cpu@203 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x203>; +- enable-method = "psci"; +- }; +- cpu@204 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x204>; +- enable-method = "psci"; +- }; +- cpu@205 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x205>; +- enable-method = "psci"; +- }; +- cpu@206 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x206>; +- enable-method = "psci"; +- }; +- cpu@207 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x207>; +- enable-method = "psci"; +- }; +- cpu@208 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x208>; +- enable-method = "psci"; +- }; +- cpu@209 { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x209>; +- enable-method = "psci"; +- }; +- cpu@20a { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x20a>; +- enable-method = "psci"; +- }; +- cpu@20b { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x20b>; +- enable-method = "psci"; +- }; +- cpu@20c { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x20c>; +- enable-method = "psci"; +- }; +- cpu@20d { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x20d>; +- enable-method = "psci"; +- }; +- cpu@20e { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x20e>; +- enable-method = "psci"; +- }; +- cpu@20f { +- device_type = "cpu"; +- compatible = "cavium,thunder", "arm,armv8"; +- reg = <0x0 0x20f>; +- enable-method = "psci"; +- }; +- }; +- +- timer { +- compatible = "arm,armv8-timer"; +- interrupts = <1 13 0xff01>, +- <1 14 0xff01>, +- <1 11 0xff01>, +- <1 10 0xff01>; +- }; +- +- soc { +- compatible = "simple-bus"; +- #address-cells = <2>; +- #size-cells = <2>; +- ranges; +- +- refclk50mhz: refclk50mhz { +- compatible = "fixed-clock"; +- #clock-cells = <0>; +- clock-frequency = <50000000>; +- clock-output-names = "refclk50mhz"; +- }; +- +- gic0: interrupt-controller@8010,00000000 { +- compatible = "arm,gic-v3"; +- #interrupt-cells = <3>; +- interrupt-controller; +- reg = <0x8010 0x00000000 0x0 0x010000>, /* GICD */ +- <0x8010 0x80000000 0x0 0x600000>; /* GICR */ +- interrupts = <1 9 0xf04>; +- }; +- +- uaa0: serial@87e0,24000000 { +- compatible = "arm,pl011", "arm,primecell"; +- reg = <0x87e0 0x24000000 0x0 0x1000>; +- interrupts = <1 21 4>; +- clocks = <&refclk50mhz>; +- clock-names = "apb_pclk"; +- uboot,skip-init; +- }; +- +- uaa1: serial@87e0,25000000 { +- compatible = "arm,pl011", "arm,primecell"; +- reg = <0x87e0 0x25000000 0x0 0x1000>; +- interrupts = <1 22 4>; +- clocks = <&refclk50mhz>; +- clock-names = "apb_pclk"; +- uboot,skip-init; +- }; +- }; +-}; +diff --git a/arch/arm/include/asm/arch-armada3700/efuse.h b/arch/arm/include/asm/arch-armada3700/efuse.h +new file mode 100644 +index 0000000000..d509966593 +--- /dev/null ++++ b/arch/arm/include/asm/arch-armada3700/efuse.h +@@ -0,0 +1,137 @@ ++/* ++* *************************************************************************** ++* Copyright (C) 2017 Marvell International Ltd. ++* *************************************************************************** ++* ++* 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 Marvell nor the names of its 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 HOLDER 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. ++* ++*************************************************************************** ++*/ ++#ifndef _A3700_EFUSE_H_ ++#define _A3700_EFUSE_H_ ++ ++#define MVEBU_EFUSE_256B_ASCII_LEN (64) ++ /* 256 bit key ASCII representation length */ ++#define MVEBU_EFUSE_512B_ASCII_LEN (128) ++ /* 256 bit key ASCII representation length */ ++#define MVEBU_EFUSE_MAX_STRLEN (MVEBU_EFUSE_512B_ASCII_LEN + 1) ++ /* MAX key length in ASCII + \0 */ ++ ++enum efuse_id { ++ EFUSE_ID_BOOT_DEVICE = 0, ++ /* Platform boot device in trusted boot mode */ ++ EFUSE_ID_KAK_DIGEST = 1, ++ /* KAK key digest (OEM key hash) */ ++ EFUSE_ID_CSK_INDEX = 2, ++ /* CSK key valid index (0-15) */ ++ EFUSE_ID_AES_KEY = 3, ++ /* Symmetric key / RKEK (write only) */ ++ EFUSE_ID_ENCRYPTION_EN = 4, ++ /* Enable boot image encryption */ ++ EFUSE_ID_JTAG_DIGECT = 5, ++ /* JTAG key digest */ ++ EFUSE_ID_SEC_JTAG_DIS = 6, ++ /* Secure CPU JTAG disable */ ++ EFUSE_ID_SEC_JTAG_PERM_DIS = 7, ++ /* Secure CPU permanent JTAG disable */ ++ EFUSE_ID_AP_JTAG_DIS = 8, ++ /* Application CPU JTAG disable */ ++ EFUSE_ID_AP_JTAG_PERM_DIS = 9, ++ /* Application CPU permanent JTAG disable */ ++ EFUSE_ID_SPI_NAND_CFG = 10, ++ /* SPI NAND configuration */ ++ EFUSE_ID_PIN = 11, ++ /* PIN */ ++ EFUSE_ID_TOKEN = 12, ++ /* Token */ ++ EFUSE_ID_SPI_CS = 13, ++ /* SPI chip select (0-4) */ ++ EFUSE_ID_EMMC_CLOCK = 14, ++ /* EMMC boot clock */ ++ EFUSE_ID_OPERATION_MODE = 15, ++ /* Operation mode trusted/untrusted/etc. */ ++ EFUSE_ID_UART_DIS = 16, ++ /* UART boot disable */ ++ EFUSE_ID_UART_PERM_DIS = 17, ++ /* UART boot permanent disable */ ++ EFUSE_ID_ESC_SEQ_DIS = 18, ++ /* UART escape sequence disable */ ++ EFUSE_ID_GPIO_TOGGLE_DIS = 19, ++ /* GPIO toggle disable */ ++ EFUSE_ID_LONG_KEY_EN = 20, ++ /* Long key enable */ ++ EFUSE_ID_MAX ++}; ++ ++struct efuse_info { ++ char *name; ++ char *note; ++}; ++ ++#define MVEBU_EFUSE_INFO { \ ++ {"BOOT_DEVICE", "SPINOR, SPINAND, EMMCNORM, EMMCALT, SATA, UART, AUTO"}, \ ++ {"KAK_DIGEST", "SHA-256 KAK key digest in HEX format"}, \ ++ {"CSK_INDEX", "CSK index in range 0 to 15 in DEC format"}, \ ++ {"AES256_KEY", "AES-256 symmetric encryption key in HEX format"}, \ ++ {"ENCRYPTION", "Enabe/Disable image encryption (2 bits, binary value):\n" \ ++ "\t\t\t00 - Encryption is disabled\n" \ ++ "\t\t\t01 - Encryption is enabled for recovery type images for eMMC only\n" \ ++ "\t\t\t10 - Encryption is enabled for primary type images\n" \ ++ "\t\t\t11 - Encryption is enabled for primary and recovery type images"}, \ ++ {"JTAG_DIGEST", "JTAG KAK key digest in HEX format"}, \ ++ {"SEC_JTAG_DIS", "Enabe/Disable secure JTAG - 0 or 1"}, \ ++ {"SEC_JTAG_PR_DIS", "Enabe/Disable secure JTAG permanently - 0 or 1"}, \ ++ {"AP_JTAG_DIS", "Enabe/Disable application CPU JTAG - 0 or 1"}, \ ++ {"AP_JTAG_PR_DIS", "Enabe/Disable application CPU JTAG permanently - 0 or 1"}, \ ++ {"SPI_NAND_CFG", "SPI NAND parameters in format PZ.BP.SO.SN, where (all decimal numbers):\n" \ ++ "\t\t\tPZ - Page Size (for instance 2048)\n" \ ++ "\t\t\tBP - Number of Pages per Block (for instance 64)\n" \ ++ "\t\t\tSO - Spare area byte Offset\n" \ ++ "\t\t\tSN - Spare area page Number"}, \ ++ {"PIN_CODE", "64-bit pin code in HEX format"}, \ ++ {"TOKEN", "\t64-bit token in HEX format"}, \ ++ {"SPI_CS", "\tSPI chip select 0 to 3"}, \ ++ {"EMMC_CLOCK", "EMMC clock - 0 - 12.5MHz, 1 - 50MHz"}, \ ++ {"OPER_MODE", "Operation mode in range of 0 to 3, where:\n" \ ++ "\t\t\t0 - Non-trusted BootROM, unprogrammed\n" \ ++ "\t\t\t1 - Non-trusted boot, no security check on the boot device content\n" \ ++ "\t\t\t2 - Trusted boot, security check is performed on the boot device content\n" \ ++ "\t\t\t3 - Tamper state; BootROM does not boot device"}, \ ++ {"UART_DIS", "Enabe/Disable UART port - 0 or 1"}, \ ++ {"UART_PR_DIS", "Enabe/Disable UART port permanently - 0 or 1"}, \ ++ {"ESC_SEQ_DIS", "Enabe/Disable Escape sequence in trusted boot mode - 0 or 1"}, \ ++ {"GPIO_TOGGLE_DIS", "Enabe/Disable GPIO pin 11 and 12 toogle - 0 or 1"}, \ ++ {"LONG_KEY_EN", "Enabe/Disable long key (512b) support - 0 or 1"}, \ ++ {"INVALID", "Invalid ID"} \ ++ } ++ ++int efuse_id_valid(enum efuse_id fid); ++int efuse_write(enum efuse_id fid, const char *value); ++int efuse_read(enum efuse_id fid, char *value); ++void efuse_raw_dump(void); ++ ++#endif /* _A3700_EFUSE_H_ */ +diff --git a/arch/arm/include/asm/arch-armada3700/mbox.h b/arch/arm/include/asm/arch-armada3700/mbox.h +new file mode 100644 +index 0000000000..29ac6424aa +--- /dev/null ++++ b/arch/arm/include/asm/arch-armada3700/mbox.h +@@ -0,0 +1,91 @@ ++/* ++ * *************************************************************************** ++ * Copyright (C) 2017 Marvell International Ltd. ++ * *************************************************************************** ++ * ++ * 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 Marvell nor the names of its 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 HOLDER 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. ++ * ++ *************************************************************************** ++ */ ++ ++#ifndef _A3700_MBOX_H_ ++#define _A3700_MBOX_H_ ++ ++#define MBOX_MAX_ARGS (16) ++#define MBOX_CMD_TIMEOUT (100000) ++#define A3700_MBOX_BASE (MVEBU_REGISTER(0xb0000)) ++ ++/* Mailbox command, arguments and status */ ++#define MBOX_SEND_ARG_OFFS(n) (A3700_MBOX_BASE + (n) * 4) ++#define MBOX_SEND_CMD_OFFS (A3700_MBOX_BASE + 0x40) ++#define MBOX_RECEIVE_STAT_OFFS (A3700_MBOX_BASE + 0x80) ++#define MBOX_RECEIVE_ARG_OFFS(n) (A3700_MBOX_BASE + 0x84 + (n) * 4) ++ ++/* Host intterrupt reset - to complete received command/status processing */ ++#define MBOX_HOST_INT_RESET (A3700_MBOX_BASE + 0xC8) ++#define MBOX_SEC_CPU_CMD_COMPLETE BIT(0) ++ ++/* ++ * Host interrupt status - to poll for new command/status ++ * received from secure CPU ++ */ ++#define MBOX_SEC_CPU_INT_STAT_REG (SOC_REGS_PHY_BASE + 0x17814) ++#define MBOX_SEC_CPU_CMD_SET BIT(31) ++ ++#define MBOX_COMMAND(sz, op) ((sz) | ((op) << 8)) ++#define MBOX_OP_SIZE(cmd) ((cmd) & 0xF) ++#define MBOX_OPERATION(cmd) (((cmd) >> 8) & 0xF) ++ ++enum mbox_opsize { ++ MB_OPSZ_BIT = 1, /* single bit */ ++ MB_OPSZ_BYTE = 2, /* single byte */ ++ MB_OPSZ_WORD = 3, /* 4 bytes - half row */ ++ MB_OPSZ_DWORD = 4, /* 8 bytes - one row */ ++ MB_OPSZ_256B = 5, /* 32 bytes - 4 rows */ ++ MB_OPSZ_MAX ++}; ++ ++enum mbox_op { ++ MB_OP_READ = 1, ++ MB_OP_WRITE = 2, ++ MB_OP_MAX ++}; ++ ++enum mbox_status { ++ MB_STAT_SUCCESS = 0, ++ MB_STAT_HW_ERROR = 1, ++ MB_STAT_TIMEOUT = 2, ++ MB_STAT_BAD_ARGUMENT = 3, ++ ++ MB_STAT_MAX ++}; ++ ++int mbox_send(enum mbox_opsize opsz, enum mbox_op op, uint32_t row, ++ uint32_t offs, uint32_t *args); ++int mbox_receive(enum mbox_status *stat, uint32_t *args, uint32_t timeout_us); ++ ++#endif /* _A3700_MBOX_H_ */ +diff --git a/arch/arm/include/asm/arch-armada8k/cache_llc.h b/arch/arm/include/asm/arch-armada8k/cache_llc.h +index 8cb114496a..1ef61ca1f6 100644 +--- a/arch/arm/include/asm/arch-armada8k/cache_llc.h ++++ b/arch/arm/include/asm/arch-armada8k/cache_llc.h +@@ -17,4 +17,9 @@ + #define LLC_WAY_MASK 0xffffffff + #define LLC_CACHE_SYNC_MASK 0x1 + ++#define MVEBU_LLC_BASE (MVEBU_REGISTER(LLC_BASE_ADDR)) ++#define LLC_CTRL_REG_OFFSET 0x100 ++#define LLC_EN 0x1 ++#define LLC_EXCL_EN 0x100 ++ + #endif /* _CACHE_LLC_H_ */ +diff --git a/arch/arm/include/asm/arch-mvebu/thermal.h b/arch/arm/include/asm/arch-mvebu/thermal.h +new file mode 100644 +index 0000000000..a16b22955d +--- /dev/null ++++ b/arch/arm/include/asm/arch-mvebu/thermal.h +@@ -0,0 +1,37 @@ ++/* SPDX-License-Identifier: GPL-2.0+ */ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#ifndef _MVEBU_THERMAL_H_ ++#define _MVEBU_THERMAL_H_ ++ ++#include ++#include ++ ++struct thermal_unit_config { ++ /* thermal temperature parameters */ ++ s32 tsen_offset; ++ s32 tsen_gain; ++ s32 tsen_divisor; ++ /* thermal data */ ++ s32 tsen_ready; ++ void __iomem *regs_base; ++ /* thermal functionality */ ++ u32 (*ptr_thermal_sensor_probe)(struct thermal_unit_config *cfg); ++ s32 (*ptr_thermal_sensor_read)(struct thermal_unit_config *cfg, ++ int *temp); ++ u32 fw_smc_support; ++}; ++ ++/* Thermal sensors APIs */ ++s32 mvebu_thermal_sensor_read(struct thermal_unit_config *thermal_config, ++ int *temp); ++u32 mvebu_thermal_sensor_probe(struct thermal_unit_config *thermal_config); ++ ++/* External Thermal sensors APIs */ ++s32 mvebu_thermal_ext_sensor_read(struct thermal_unit_config *thermal_config, ++ int *temp); ++u32 mvebu_thermal_ext_sensor_probe(struct thermal_unit_config *thermal_config); ++ ++#endif /* _THERMAL_H_ */ +diff --git a/arch/arm/include/asm/arch-octeontx/board.h b/arch/arm/include/asm/arch-octeontx/board.h +new file mode 100644 +index 0000000000..139e56e423 +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx/board.h +@@ -0,0 +1,124 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#ifndef __BOARD_H__ ++#define __BOARD_H__ ++ ++#include ++ ++#define MAX_LMAC_PER_BGX 4 ++#define LMAC_CNT MAX_LMAC_PER_BGX ++ ++#if defined(CONFIG_TARGET_OCTEONTX_81XX) ++ ++/** Maximum number of BGX interfaces per CPU node */ ++#define MAX_BGX_PER_NODE 3 ++#define OCTEONTX_XCV /* RGMII Interface */ ++ ++#elif defined(CONFIG_TARGET_OCTEONTX_83XX) ++ ++/** Maximum number of BGX interfaces per CPU node */ ++#define MAX_BGX_PER_NODE 4 ++ ++#endif ++ ++/** Reg offsets */ ++#define RST_BOOT 0x87E006001600ULL ++ ++/** Structure definitions */ ++ ++/** ++ * Register (RSL) rst_boot ++ * ++ * RST Boot Register This register is not accessible through ROM scripts; ++ * see SCR_WRITE32_S[ADDR]. ++ */ ++union rst_boot { ++ u64 u; ++ struct rst_boot_s { ++ u64 rboot_pin : 1; ++ u64 rboot : 1; ++ u64 reserved_2_32 : 31; ++ u64 pnr_mul : 6; ++ u64 reserved_39 : 1; ++ u64 c_mul : 7; ++ u64 reserved_47_52 : 6; ++ u64 gpio_ejtag : 1; ++ u64 mcp_jtagdis : 1; ++ u64 dis_scan : 1; ++ u64 dis_huk : 1; ++ u64 vrm_err : 1; ++ u64 jt_tstmode : 1; ++ u64 ckill_ppdis : 1; ++ u64 trusted_mode : 1; ++ u64 reserved_61_62 : 2; ++ u64 chipkill : 1; ++ } s; ++ struct rst_boot_cn81xx { ++ u64 rboot_pin : 1; ++ u64 rboot : 1; ++ u64 lboot : 10; ++ u64 lboot_ext23 : 6; ++ u64 lboot_ext45 : 6; ++ u64 lboot_jtg : 1; ++ u64 lboot_ckill : 1; ++ u64 reserved_26_29 : 4; ++ u64 lboot_oci : 3; ++ u64 pnr_mul : 6; ++ u64 reserved_39 : 1; ++ u64 c_mul : 7; ++ u64 reserved_47_54 : 8; ++ u64 dis_scan : 1; ++ u64 dis_huk : 1; ++ u64 vrm_err : 1; ++ u64 jt_tstmode : 1; ++ u64 ckill_ppdis : 1; ++ u64 trusted_mode : 1; ++ u64 ejtagdis : 1; ++ u64 jtcsrdis : 1; ++ u64 chipkill : 1; ++ } cn81xx; ++ struct rst_boot_cn83xx { ++ u64 rboot_pin : 1; ++ u64 rboot : 1; ++ u64 lboot : 10; ++ u64 lboot_ext23 : 6; ++ u64 lboot_ext45 : 6; ++ u64 lboot_jtg : 1; ++ u64 lboot_ckill : 1; ++ u64 lboot_pf_flr : 4; ++ u64 lboot_oci : 3; ++ u64 pnr_mul : 6; ++ u64 reserved_39 : 1; ++ u64 c_mul : 7; ++ u64 reserved_47_54 : 8; ++ u64 dis_scan : 1; ++ u64 dis_huk : 1; ++ u64 vrm_err : 1; ++ u64 jt_tstmode : 1; ++ u64 ckill_ppdis : 1; ++ u64 trusted_mode : 1; ++ u64 ejtagdis : 1; ++ u64 jtcsrdis : 1; ++ u64 chipkill : 1; ++ } cn83xx; ++}; ++ ++/** Function definitions */ ++void mem_map_fill(void); ++int octeontx_board_has_pmp(void); ++const char *fdt_get_board_model(void); ++const char *fdt_get_board_serial(void); ++const char *fdt_get_board_revision(void); ++void fdt_parse_phy_info(void); ++void fdt_board_get_ethaddr(int bgx, int lmac, unsigned char *eth); ++#ifdef ALLOW_USER_MAC_ADDR ++void fdt_board_update_macaddr(int bgx_idx, int lmacid, char *mac); ++#endif ++void bgx_set_board_info(int bgx_id, int *mdio_bus, int *phy_addr, ++ bool *autoneg_dis, bool *lmac_reg, bool *lmac_enable); ++#endif /* __BOARD_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx/clock.h b/arch/arm/include/asm/arch-octeontx/clock.h +new file mode 100644 +index 0000000000..7bf600a1f2 +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx/clock.h +@@ -0,0 +1,25 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#ifndef __CLOCK_H__ ++#define __CLOCK_H__ ++ ++/** System PLL reference clock */ ++#define PLL_REF_CLK 50000000 /* 50 MHz */ ++#define NS_PER_REF_CLK_TICK (1000000000 / PLL_REF_CLK) ++ ++/** ++ * Returns the I/O clock speed in Hz ++ */ ++u64 octeontx_get_io_clock(void); ++ ++/** ++ * Returns the core clock speed in Hz ++ */ ++u64 octeontx_get_core_clock(void); ++ ++#endif /* __CLOCK_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx/csrs/csrs-mio_emm.h b/arch/arm/include/asm/arch-octeontx/csrs/csrs-mio_emm.h +new file mode 100644 +index 0000000000..4dd8958d2f +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx/csrs/csrs-mio_emm.h +@@ -0,0 +1,1199 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++#ifndef __CSRS_MIO_EMM_H__ ++#define __CSRS_MIO_EMM_H__ ++ ++/** ++ * @file ++ * ++ * Configuration and status register (CSR) address and type definitions for ++ * MIO_EMM. ++ * ++ * This file is auto generated. Do not edit. ++ * ++ */ ++ ++/** ++ * Enumeration mio_emm_bar_e ++ * ++ * eMMC Base Address Register Enumeration Enumerates the base address ++ * registers. ++ */ ++#define MIO_EMM_BAR_E_MIO_EMM_PF_BAR0_CN8 (0x87e009000000ll) ++#define MIO_EMM_BAR_E_MIO_EMM_PF_BAR0_CN8_SIZE 0x800000ull ++#define MIO_EMM_BAR_E_MIO_EMM_PF_BAR0_CN9 (0x87e009000000ll) ++#define MIO_EMM_BAR_E_MIO_EMM_PF_BAR0_CN9_SIZE 0x10000ull ++#define MIO_EMM_BAR_E_MIO_EMM_PF_BAR4 (0x87e009f00000ll) ++#define MIO_EMM_BAR_E_MIO_EMM_PF_BAR4_SIZE 0x100000ull ++ ++/** ++ * Enumeration mio_emm_int_vec_e ++ * ++ * eMMC MSI-X Vector Enumeration Enumerates the MSI-X interrupt vectors. ++ */ ++#define MIO_EMM_INT_VEC_E_DMA_INT_DONE (8) ++#define MIO_EMM_INT_VEC_E_DMA_INT_FIFO (7) ++#define MIO_EMM_INT_VEC_E_EMM_BUF_DONE (0) ++#define MIO_EMM_INT_VEC_E_EMM_CMD_DONE (1) ++#define MIO_EMM_INT_VEC_E_EMM_CMD_ERR (3) ++#define MIO_EMM_INT_VEC_E_EMM_DMA_DONE (2) ++#define MIO_EMM_INT_VEC_E_EMM_DMA_ERR (4) ++#define MIO_EMM_INT_VEC_E_EMM_SWITCH_DONE (5) ++#define MIO_EMM_INT_VEC_E_EMM_SWITCH_ERR (6) ++#define MIO_EMM_INT_VEC_E_NCB_FLT (9) ++#define MIO_EMM_INT_VEC_E_NCB_RAS (0xa) ++ ++/** ++ * Register (RSL) mio_emm_access_wdog ++ * ++ * eMMC Access Watchdog Register ++ */ ++union mio_emm_access_wdog { ++ u64 u; ++ struct mio_emm_access_wdog_s { ++ u64 clk_cnt : 32; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct mio_emm_access_wdog_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_ACCESS_WDOG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_ACCESS_WDOG(void) ++{ ++ return 0x20f0; ++} ++ ++/** ++ * Register (RSL) mio_emm_buf_dat ++ * ++ * eMMC Data Buffer Access Register ++ */ ++union mio_emm_buf_dat { ++ u64 u; ++ struct mio_emm_buf_dat_s { ++ u64 dat : 64; ++ } s; ++ /* struct mio_emm_buf_dat_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_BUF_DAT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_BUF_DAT(void) ++{ ++ return 0x20e8; ++} ++ ++/** ++ * Register (RSL) mio_emm_buf_idx ++ * ++ * eMMC Data Buffer Address Register ++ */ ++union mio_emm_buf_idx { ++ u64 u; ++ struct mio_emm_buf_idx_s { ++ u64 offset : 6; ++ u64 buf_num : 1; ++ u64 reserved_7_15 : 9; ++ u64 inc : 1; ++ u64 reserved_17_63 : 47; ++ } s; ++ /* struct mio_emm_buf_idx_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_BUF_IDX(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_BUF_IDX(void) ++{ ++ return 0x20e0; ++} ++ ++/** ++ * Register (RSL) mio_emm_calb ++ * ++ * eMMC Calbration Register This register initiates delay line ++ * characterization. ++ */ ++union mio_emm_calb { ++ u64 u; ++ struct mio_emm_calb_s { ++ u64 start : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct mio_emm_calb_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_CALB(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_CALB(void) ++{ ++ return 0x20c0; ++} ++ ++/** ++ * Register (RSL) mio_emm_cfg ++ * ++ * eMMC Configuration Register ++ */ ++union mio_emm_cfg { ++ u64 u; ++ struct mio_emm_cfg_s { ++ u64 bus_ena : 4; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct mio_emm_cfg_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_CFG(void) ++{ ++ return 0x2000; ++} ++ ++/** ++ * Register (RSL) mio_emm_cmd ++ * ++ * eMMC Command Register ++ */ ++union mio_emm_cmd { ++ u64 u; ++ struct mio_emm_cmd_s { ++ u64 arg : 32; ++ u64 cmd_idx : 6; ++ u64 rtype_xor : 3; ++ u64 ctype_xor : 2; ++ u64 reserved_43_48 : 6; ++ u64 offset : 6; ++ u64 dbuf : 1; ++ u64 reserved_56_58 : 3; ++ u64 cmd_val : 1; ++ u64 bus_id : 2; ++ u64 skip_busy : 1; ++ u64 reserved_63 : 1; ++ } s; ++ /* struct mio_emm_cmd_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_CMD(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_CMD(void) ++{ ++ return 0x2058; ++} ++ ++/** ++ * Register (RSL) mio_emm_comp ++ * ++ * eMMC Compensation Register ++ */ ++union mio_emm_comp { ++ u64 u; ++ struct mio_emm_comp_s { ++ u64 nctl : 3; ++ u64 reserved_3_7 : 5; ++ u64 pctl : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct mio_emm_comp_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_COMP(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_COMP(void) ++{ ++ return 0x2040; ++} ++ ++/** ++ * Register (RSL) mio_emm_debug ++ * ++ * eMMC Debug Register ++ */ ++union mio_emm_debug { ++ u64 u; ++ struct mio_emm_debug_s { ++ u64 clk_on : 1; ++ u64 reserved_1_7 : 7; ++ u64 cmd_sm : 4; ++ u64 data_sm : 4; ++ u64 dma_sm : 4; ++ u64 emmc_clk_disable : 1; ++ u64 rdsync_rst : 1; ++ u64 reserved_22_63 : 42; ++ } s; ++ struct mio_emm_debug_cn96xxp1 { ++ u64 clk_on : 1; ++ u64 reserved_1_7 : 7; ++ u64 cmd_sm : 4; ++ u64 data_sm : 4; ++ u64 dma_sm : 4; ++ u64 reserved_20_63 : 44; ++ } cn96xxp1; ++ /* struct mio_emm_debug_s cn96xxp3; */ ++ /* struct mio_emm_debug_s cn98xx; */ ++ /* struct mio_emm_debug_cn96xxp1 cnf95xx; */ ++ /* struct mio_emm_debug_s loki; */ ++}; ++ ++static inline u64 MIO_EMM_DEBUG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DEBUG(void) ++{ ++ return 0x20f8; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma ++ * ++ * eMMC External DMA Configuration Register ++ */ ++union mio_emm_dma { ++ u64 u; ++ struct mio_emm_dma_s { ++ u64 card_addr : 32; ++ u64 block_cnt : 16; ++ u64 multi : 1; ++ u64 rw : 1; ++ u64 rel_wr : 1; ++ u64 thres : 6; ++ u64 dat_null : 1; ++ u64 sector : 1; ++ u64 dma_val : 1; ++ u64 bus_id : 2; ++ u64 skip_busy : 1; ++ u64 extra_args : 1; ++ } s; ++ struct mio_emm_dma_cn8 { ++ u64 card_addr : 32; ++ u64 block_cnt : 16; ++ u64 multi : 1; ++ u64 rw : 1; ++ u64 rel_wr : 1; ++ u64 thres : 6; ++ u64 dat_null : 1; ++ u64 sector : 1; ++ u64 dma_val : 1; ++ u64 bus_id : 2; ++ u64 skip_busy : 1; ++ u64 reserved_63 : 1; ++ } cn8; ++ struct mio_emm_dma_cn9 { ++ u64 card_addr : 32; ++ u64 block_cnt : 16; ++ u64 multi : 1; ++ u64 rw : 1; ++ u64 reserved_50 : 1; ++ u64 thres : 6; ++ u64 dat_null : 1; ++ u64 sector : 1; ++ u64 dma_val : 1; ++ u64 bus_id : 2; ++ u64 skip_busy : 1; ++ u64 extra_args : 1; ++ } cn9; ++}; ++ ++static inline u64 MIO_EMM_DMA(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA(void) ++{ ++ return 0x2050; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_adr ++ * ++ * eMMC DMA Address Register This register sets the address for eMMC/SD ++ * flash transfers to/from memory. Sixty-four-bit operations must be used ++ * to access this register. This register is updated by the DMA hardware ++ * and can be reloaded by the values placed in the MIO_EMM_DMA_FIFO_ADR. ++ */ ++union mio_emm_dma_adr { ++ u64 u; ++ struct mio_emm_dma_adr_s { ++ u64 adr : 53; ++ u64 reserved_53_63 : 11; ++ } s; ++ struct mio_emm_dma_adr_cn8 { ++ u64 adr : 49; ++ u64 reserved_49_63 : 15; ++ } cn8; ++ /* struct mio_emm_dma_adr_s cn9; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_ADR(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_ADR(void) ++{ ++ return 0x188; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_arg ++ * ++ * eMMC External DMA Extra Arguments Register ++ */ ++union mio_emm_dma_arg { ++ u64 u; ++ struct mio_emm_dma_arg_s { ++ u64 cmd23_args : 8; ++ u64 force_pgm : 1; ++ u64 context_id : 4; ++ u64 tag_req : 1; ++ u64 pack_cmd : 1; ++ u64 rel_wr : 1; ++ u64 alt_cmd : 6; ++ u64 skip_blk_cmd : 1; ++ u64 reserved_23_31 : 9; ++ u64 alt_cmd_arg : 32; ++ } s; ++ /* struct mio_emm_dma_arg_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_ARG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_ARG(void) ++{ ++ return 0x2090; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_cfg ++ * ++ * eMMC DMA Configuration Register This register controls the internal ++ * DMA engine used with the eMMC/SD flash controller. Sixty- four-bit ++ * operations must be used to access this register. This register is ++ * updated by the hardware DMA engine and can also be reloaded by writes ++ * to the MIO_EMM_DMA_FIFO_CMD register. ++ */ ++union mio_emm_dma_cfg { ++ u64 u; ++ struct mio_emm_dma_cfg_s { ++ u64 reserved_0_35 : 36; ++ u64 size : 20; ++ u64 endian : 1; ++ u64 swap8 : 1; ++ u64 swap16 : 1; ++ u64 swap32 : 1; ++ u64 reserved_60 : 1; ++ u64 clr : 1; ++ u64 rw : 1; ++ u64 en : 1; ++ } s; ++ /* struct mio_emm_dma_cfg_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_CFG(void) ++{ ++ return 0x180; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_fifo_adr ++ * ++ * eMMC Internal DMA FIFO Address Register This register specifies the ++ * internal address that is loaded into the eMMC internal DMA FIFO. The ++ * FIFO is used to queue up operations for the ++ * MIO_EMM_DMA_CFG/MIO_EMM_DMA_ADR when the DMA completes successfully. ++ */ ++union mio_emm_dma_fifo_adr { ++ u64 u; ++ struct mio_emm_dma_fifo_adr_s { ++ u64 reserved_0_2 : 3; ++ u64 adr : 50; ++ u64 reserved_53_63 : 11; ++ } s; ++ struct mio_emm_dma_fifo_adr_cn8 { ++ u64 reserved_0_2 : 3; ++ u64 adr : 46; ++ u64 reserved_49_63 : 15; ++ } cn8; ++ /* struct mio_emm_dma_fifo_adr_s cn9; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_FIFO_ADR(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_FIFO_ADR(void) ++{ ++ return 0x170; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_fifo_cfg ++ * ++ * eMMC Internal DMA FIFO Configuration Register This register controls ++ * DMA FIFO operations. ++ */ ++union mio_emm_dma_fifo_cfg { ++ u64 u; ++ struct mio_emm_dma_fifo_cfg_s { ++ u64 count : 5; ++ u64 reserved_5_7 : 3; ++ u64 int_lvl : 5; ++ u64 reserved_13_15 : 3; ++ u64 clr : 1; ++ u64 reserved_17_63 : 47; ++ } s; ++ /* struct mio_emm_dma_fifo_cfg_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_FIFO_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_FIFO_CFG(void) ++{ ++ return 0x160; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_fifo_cmd ++ * ++ * eMMC Internal DMA FIFO Command Register This register specifies a ++ * command that is loaded into the eMMC internal DMA FIFO. The FIFO is ++ * used to queue up operations for the MIO_EMM_DMA_CFG/MIO_EMM_DMA_ADR ++ * when the DMA completes successfully. Writes to this register store ++ * both the MIO_EMM_DMA_FIFO_CMD and the MIO_EMM_DMA_FIFO_ADR contents ++ * into the FIFO and increment the MIO_EMM_DMA_FIFO_CFG[COUNT] field. ++ * Note: This register has a similar format to MIO_EMM_DMA_CFG with the ++ * exception that the EN and CLR fields are absent. These are supported ++ * in MIO_EMM_DMA_FIFO_CFG. ++ */ ++union mio_emm_dma_fifo_cmd { ++ u64 u; ++ struct mio_emm_dma_fifo_cmd_s { ++ u64 reserved_0_35 : 36; ++ u64 size : 20; ++ u64 endian : 1; ++ u64 swap8 : 1; ++ u64 swap16 : 1; ++ u64 swap32 : 1; ++ u64 intdis : 1; ++ u64 reserved_61 : 1; ++ u64 rw : 1; ++ u64 reserved_63 : 1; ++ } s; ++ /* struct mio_emm_dma_fifo_cmd_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_FIFO_CMD(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_FIFO_CMD(void) ++{ ++ return 0x178; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_int ++ * ++ * eMMC DMA Interrupt Register Sixty-four-bit operations must be used to ++ * access this register. ++ */ ++union mio_emm_dma_int { ++ u64 u; ++ struct mio_emm_dma_int_s { ++ u64 done : 1; ++ u64 fifo : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct mio_emm_dma_int_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_INT(void) ++{ ++ return 0x190; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_int_ena_w1c ++ * ++ * eMMC DMA Interrupt Enable Clear Register This register clears ++ * interrupt enable bits. ++ */ ++union mio_emm_dma_int_ena_w1c { ++ u64 u; ++ struct mio_emm_dma_int_ena_w1c_s { ++ u64 done : 1; ++ u64 fifo : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct mio_emm_dma_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_INT_ENA_W1C(void) ++{ ++ return 0x1a8; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_int_ena_w1s ++ * ++ * eMMC DMA Interrupt Enable Set Register This register sets interrupt ++ * enable bits. ++ */ ++union mio_emm_dma_int_ena_w1s { ++ u64 u; ++ struct mio_emm_dma_int_ena_w1s_s { ++ u64 done : 1; ++ u64 fifo : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct mio_emm_dma_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_INT_ENA_W1S(void) ++{ ++ return 0x1a0; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_int_w1s ++ * ++ * eMMC DMA Interrupt Set Register This register sets interrupt bits. ++ */ ++union mio_emm_dma_int_w1s { ++ u64 u; ++ struct mio_emm_dma_int_w1s_s { ++ u64 done : 1; ++ u64 fifo : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct mio_emm_dma_int_w1s_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_INT_W1S(void) ++{ ++ return 0x198; ++} ++ ++/** ++ * Register (RSL) mio_emm_int ++ * ++ * eMMC Interrupt Register ++ */ ++union mio_emm_int { ++ u64 u; ++ struct mio_emm_int_s { ++ u64 buf_done : 1; ++ u64 cmd_done : 1; ++ u64 dma_done : 1; ++ u64 cmd_err : 1; ++ u64 dma_err : 1; ++ u64 switch_done : 1; ++ u64 switch_err : 1; ++ u64 ncb_flt : 1; ++ u64 ncb_ras : 1; ++ u64 reserved_9_63 : 55; ++ } s; ++ struct mio_emm_int_cn8 { ++ u64 buf_done : 1; ++ u64 cmd_done : 1; ++ u64 dma_done : 1; ++ u64 cmd_err : 1; ++ u64 dma_err : 1; ++ u64 switch_done : 1; ++ u64 switch_err : 1; ++ u64 reserved_7_63 : 57; ++ } cn8; ++ /* struct mio_emm_int_s cn9; */ ++}; ++ ++static inline u64 MIO_EMM_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_INT(void) ++{ ++ return 0x2078; ++} ++ ++/** ++ * Register (RSL) mio_emm_int_ena_w1c ++ * ++ * eMMC Interrupt Enable Clear Register This register clears interrupt ++ * enable bits. ++ */ ++union mio_emm_int_ena_w1c { ++ u64 u; ++ struct mio_emm_int_ena_w1c_s { ++ u64 buf_done : 1; ++ u64 cmd_done : 1; ++ u64 dma_done : 1; ++ u64 cmd_err : 1; ++ u64 dma_err : 1; ++ u64 switch_done : 1; ++ u64 switch_err : 1; ++ u64 ncb_flt : 1; ++ u64 ncb_ras : 1; ++ u64 reserved_9_63 : 55; ++ } s; ++ struct mio_emm_int_ena_w1c_cn8 { ++ u64 buf_done : 1; ++ u64 cmd_done : 1; ++ u64 dma_done : 1; ++ u64 cmd_err : 1; ++ u64 dma_err : 1; ++ u64 switch_done : 1; ++ u64 switch_err : 1; ++ u64 reserved_7_63 : 57; ++ } cn8; ++ /* struct mio_emm_int_ena_w1c_s cn9; */ ++}; ++ ++static inline u64 MIO_EMM_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_INT_ENA_W1C(void) ++{ ++ return 0x20b8; ++} ++ ++/** ++ * Register (RSL) mio_emm_int_ena_w1s ++ * ++ * eMMC Interrupt Enable Set Register This register sets interrupt enable ++ * bits. ++ */ ++union mio_emm_int_ena_w1s { ++ u64 u; ++ struct mio_emm_int_ena_w1s_s { ++ u64 buf_done : 1; ++ u64 cmd_done : 1; ++ u64 dma_done : 1; ++ u64 cmd_err : 1; ++ u64 dma_err : 1; ++ u64 switch_done : 1; ++ u64 switch_err : 1; ++ u64 ncb_flt : 1; ++ u64 ncb_ras : 1; ++ u64 reserved_9_63 : 55; ++ } s; ++ struct mio_emm_int_ena_w1s_cn8 { ++ u64 buf_done : 1; ++ u64 cmd_done : 1; ++ u64 dma_done : 1; ++ u64 cmd_err : 1; ++ u64 dma_err : 1; ++ u64 switch_done : 1; ++ u64 switch_err : 1; ++ u64 reserved_7_63 : 57; ++ } cn8; ++ /* struct mio_emm_int_ena_w1s_s cn9; */ ++}; ++ ++static inline u64 MIO_EMM_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_INT_ENA_W1S(void) ++{ ++ return 0x20b0; ++} ++ ++/** ++ * Register (RSL) mio_emm_int_w1s ++ * ++ * eMMC Interrupt Set Register This register sets interrupt bits. ++ */ ++union mio_emm_int_w1s { ++ u64 u; ++ struct mio_emm_int_w1s_s { ++ u64 buf_done : 1; ++ u64 cmd_done : 1; ++ u64 dma_done : 1; ++ u64 cmd_err : 1; ++ u64 dma_err : 1; ++ u64 switch_done : 1; ++ u64 switch_err : 1; ++ u64 ncb_flt : 1; ++ u64 ncb_ras : 1; ++ u64 reserved_9_63 : 55; ++ } s; ++ struct mio_emm_int_w1s_cn8 { ++ u64 buf_done : 1; ++ u64 cmd_done : 1; ++ u64 dma_done : 1; ++ u64 cmd_err : 1; ++ u64 dma_err : 1; ++ u64 switch_done : 1; ++ u64 switch_err : 1; ++ u64 reserved_7_63 : 57; ++ } cn8; ++ /* struct mio_emm_int_w1s_s cn9; */ ++}; ++ ++static inline u64 MIO_EMM_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_INT_W1S(void) ++{ ++ return 0x2080; ++} ++ ++/** ++ * Register (RSL) mio_emm_io_ctl ++ * ++ * eMMC I/O Control Register ++ */ ++union mio_emm_io_ctl { ++ u64 u; ++ struct mio_emm_io_ctl_s { ++ u64 slew : 1; ++ u64 reserved_1 : 1; ++ u64 drive : 2; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct mio_emm_io_ctl_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_IO_CTL(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_IO_CTL(void) ++{ ++ return 0x2040; ++} ++ ++/** ++ * Register (RSL) mio_emm_mode# ++ * ++ * eMMC Operating Mode Register ++ */ ++union mio_emm_modex { ++ u64 u; ++ struct mio_emm_modex_s { ++ u64 clk_lo : 16; ++ u64 clk_hi : 16; ++ u64 power_class : 4; ++ u64 clk_swap : 1; ++ u64 reserved_37_39 : 3; ++ u64 bus_width : 3; ++ u64 reserved_43_47 : 5; ++ u64 hs_timing : 1; ++ u64 hs200_timing : 1; ++ u64 hs400_timing : 1; ++ u64 reserved_51_63 : 13; ++ } s; ++ struct mio_emm_modex_cn8 { ++ u64 clk_lo : 16; ++ u64 clk_hi : 16; ++ u64 power_class : 4; ++ u64 reserved_36_39 : 4; ++ u64 bus_width : 3; ++ u64 reserved_43_47 : 5; ++ u64 hs_timing : 1; ++ u64 reserved_49_63 : 15; ++ } cn8; ++ struct mio_emm_modex_cn96xxp1 { ++ u64 clk_lo : 16; ++ u64 clk_hi : 16; ++ u64 power_class : 4; ++ u64 reserved_36_39 : 4; ++ u64 bus_width : 3; ++ u64 reserved_43_47 : 5; ++ u64 hs_timing : 1; ++ u64 hs200_timing : 1; ++ u64 hs400_timing : 1; ++ u64 reserved_51_63 : 13; ++ } cn96xxp1; ++ /* struct mio_emm_modex_s cn96xxp3; */ ++ /* struct mio_emm_modex_s cn98xx; */ ++ /* struct mio_emm_modex_s cnf95xx; */ ++ /* struct mio_emm_modex_s loki; */ ++}; ++ ++static inline u64 MIO_EMM_MODEX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_MODEX(u64 a) ++{ ++ return 0x2008 + 8 * a; ++} ++ ++/** ++ * Register (RSL) mio_emm_msix_pba# ++ * ++ * eMMC MSI-X Pending Bit Array Registers This register is the MSI-X PBA ++ * table; the bit number is indexed by the MIO_EMM_INT_VEC_E enumeration. ++ */ ++union mio_emm_msix_pbax { ++ u64 u; ++ struct mio_emm_msix_pbax_s { ++ u64 pend : 64; ++ } s; ++ /* struct mio_emm_msix_pbax_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_MSIX_PBAX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_MSIX_PBAX(u64 a) ++{ ++ return 0xf0000 + 8 * a; ++} ++ ++/** ++ * Register (RSL) mio_emm_msix_vec#_addr ++ * ++ * eMMC MSI-X Vector-Table Address Register This register is the MSI-X ++ * vector table, indexed by the MIO_EMM_INT_VEC_E enumeration. ++ */ ++union mio_emm_msix_vecx_addr { ++ u64 u; ++ struct mio_emm_msix_vecx_addr_s { ++ u64 secvec : 1; ++ u64 reserved_1 : 1; ++ u64 addr : 51; ++ u64 reserved_53_63 : 11; ++ } s; ++ struct mio_emm_msix_vecx_addr_cn8 { ++ u64 secvec : 1; ++ u64 reserved_1 : 1; ++ u64 addr : 47; ++ u64 reserved_49_63 : 15; ++ } cn8; ++ /* struct mio_emm_msix_vecx_addr_s cn9; */ ++}; ++ ++static inline u64 MIO_EMM_MSIX_VECX_ADDR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_MSIX_VECX_ADDR(u64 a) ++{ ++ return 0 + 0x10 * a; ++} ++ ++/** ++ * Register (RSL) mio_emm_msix_vec#_ctl ++ * ++ * eMMC MSI-X Vector-Table Control and Data Register This register is the ++ * MSI-X vector table, indexed by the MIO_EMM_INT_VEC_E enumeration. ++ */ ++union mio_emm_msix_vecx_ctl { ++ u64 u; ++ struct mio_emm_msix_vecx_ctl_s { ++ u64 data : 32; ++ u64 mask : 1; ++ u64 reserved_33_63 : 31; ++ } s; ++ struct mio_emm_msix_vecx_ctl_cn8 { ++ u64 data : 20; ++ u64 reserved_20_31 : 12; ++ u64 mask : 1; ++ u64 reserved_33_63 : 31; ++ } cn8; ++ /* struct mio_emm_msix_vecx_ctl_s cn9; */ ++}; ++ ++static inline u64 MIO_EMM_MSIX_VECX_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_MSIX_VECX_CTL(u64 a) ++{ ++ return 8 + 0x10 * a; ++} ++ ++/** ++ * Register (RSL) mio_emm_rca ++ * ++ * eMMC Relative Card Address Register ++ */ ++union mio_emm_rca { ++ u64 u; ++ struct mio_emm_rca_s { ++ u64 card_rca : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct mio_emm_rca_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_RCA(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_RCA(void) ++{ ++ return 0x20a0; ++} ++ ++/** ++ * Register (RSL) mio_emm_rsp_hi ++ * ++ * eMMC Response Data High Register ++ */ ++union mio_emm_rsp_hi { ++ u64 u; ++ struct mio_emm_rsp_hi_s { ++ u64 dat : 64; ++ } s; ++ /* struct mio_emm_rsp_hi_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_RSP_HI(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_RSP_HI(void) ++{ ++ return 0x2070; ++} ++ ++/** ++ * Register (RSL) mio_emm_rsp_lo ++ * ++ * eMMC Response Data Low Register ++ */ ++union mio_emm_rsp_lo { ++ u64 u; ++ struct mio_emm_rsp_lo_s { ++ u64 dat : 64; ++ } s; ++ /* struct mio_emm_rsp_lo_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_RSP_LO(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_RSP_LO(void) ++{ ++ return 0x2068; ++} ++ ++/** ++ * Register (RSL) mio_emm_rsp_sts ++ * ++ * eMMC Response Status Register ++ */ ++union mio_emm_rsp_sts { ++ u64 u; ++ struct mio_emm_rsp_sts_s { ++ u64 cmd_done : 1; ++ u64 cmd_idx : 6; ++ u64 cmd_type : 2; ++ u64 rsp_type : 3; ++ u64 rsp_val : 1; ++ u64 rsp_bad_sts : 1; ++ u64 rsp_crc_err : 1; ++ u64 rsp_timeout : 1; ++ u64 stp_val : 1; ++ u64 stp_bad_sts : 1; ++ u64 stp_crc_err : 1; ++ u64 stp_timeout : 1; ++ u64 rsp_busybit : 1; ++ u64 blk_crc_err : 1; ++ u64 blk_timeout : 1; ++ u64 dbuf : 1; ++ u64 reserved_24_27 : 4; ++ u64 dbuf_err : 1; ++ u64 reserved_29_54 : 26; ++ u64 acc_timeout : 1; ++ u64 dma_pend : 1; ++ u64 dma_val : 1; ++ u64 switch_val : 1; ++ u64 cmd_val : 1; ++ u64 bus_id : 2; ++ u64 reserved_62_63 : 2; ++ } s; ++ /* struct mio_emm_rsp_sts_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_RSP_STS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_RSP_STS(void) ++{ ++ return 0x2060; ++} ++ ++/** ++ * Register (RSL) mio_emm_sample ++ * ++ * eMMC Sampling Register ++ */ ++union mio_emm_sample { ++ u64 u; ++ struct mio_emm_sample_s { ++ u64 dat_cnt : 10; ++ u64 reserved_10_15 : 6; ++ u64 cmd_cnt : 10; ++ u64 reserved_26_63 : 38; ++ } s; ++ /* struct mio_emm_sample_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_SAMPLE(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_SAMPLE(void) ++{ ++ return 0x2090; ++} ++ ++/** ++ * Register (RSL) mio_emm_sts_mask ++ * ++ * eMMC Status Mask Register ++ */ ++union mio_emm_sts_mask { ++ u64 u; ++ struct mio_emm_sts_mask_s { ++ u64 sts_msk : 32; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct mio_emm_sts_mask_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_STS_MASK(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_STS_MASK(void) ++{ ++ return 0x2098; ++} ++ ++/** ++ * Register (RSL) mio_emm_switch ++ * ++ * eMMC Operating Mode Switch Register This register allows software to ++ * change eMMC related parameters associated with a specific BUS_ID. The ++ * MIO_EMM_MODE() registers contain the current setting for each BUS. ++ * This register is also used to switch the [CLK_HI] and [CLK_LO] ++ * settings associated with the common EMMC_CLK. These settings can only ++ * be changed when [BUS_ID] = 0. ++ */ ++union mio_emm_switch { ++ u64 u; ++ struct mio_emm_switch_s { ++ u64 clk_lo : 16; ++ u64 clk_hi : 16; ++ u64 power_class : 4; ++ u64 clk_swap : 1; ++ u64 reserved_37_39 : 3; ++ u64 bus_width : 3; ++ u64 reserved_43_47 : 5; ++ u64 hs_timing : 1; ++ u64 hs200_timing : 1; ++ u64 hs400_timing : 1; ++ u64 reserved_51_55 : 5; ++ u64 switch_err2 : 1; ++ u64 switch_err1 : 1; ++ u64 switch_err0 : 1; ++ u64 switch_exe : 1; ++ u64 bus_id : 2; ++ u64 reserved_62_63 : 2; ++ } s; ++ struct mio_emm_switch_cn8 { ++ u64 clk_lo : 16; ++ u64 clk_hi : 16; ++ u64 power_class : 4; ++ u64 reserved_36_39 : 4; ++ u64 bus_width : 3; ++ u64 reserved_43_47 : 5; ++ u64 hs_timing : 1; ++ u64 reserved_49_55 : 7; ++ u64 switch_err2 : 1; ++ u64 switch_err1 : 1; ++ u64 switch_err0 : 1; ++ u64 switch_exe : 1; ++ u64 bus_id : 2; ++ u64 reserved_62_63 : 2; ++ } cn8; ++ struct mio_emm_switch_cn96xxp1 { ++ u64 clk_lo : 16; ++ u64 clk_hi : 16; ++ u64 power_class : 4; ++ u64 reserved_36_39 : 4; ++ u64 bus_width : 3; ++ u64 reserved_43_47 : 5; ++ u64 hs_timing : 1; ++ u64 hs200_timing : 1; ++ u64 hs400_timing : 1; ++ u64 reserved_51_55 : 5; ++ u64 switch_err2 : 1; ++ u64 switch_err1 : 1; ++ u64 switch_err0 : 1; ++ u64 switch_exe : 1; ++ u64 bus_id : 2; ++ u64 reserved_62_63 : 2; ++ } cn96xxp1; ++ /* struct mio_emm_switch_s cn96xxp3; */ ++ /* struct mio_emm_switch_s cn98xx; */ ++ /* struct mio_emm_switch_s cnf95xx; */ ++ /* struct mio_emm_switch_s loki; */ ++}; ++ ++static inline u64 MIO_EMM_SWITCH(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_SWITCH(void) ++{ ++ return 0x2048; ++} ++ ++/** ++ * Register (RSL) mio_emm_tap ++ * ++ * eMMC TAP Delay Register This register indicates the delay line ++ * characteristics. ++ */ ++union mio_emm_tap { ++ u64 u; ++ struct mio_emm_tap_s { ++ u64 delay : 8; ++ u64 reserved_8_63 : 56; ++ } s; ++ /* struct mio_emm_tap_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_TAP(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_TAP(void) ++{ ++ return 0x20c8; ++} ++ ++/** ++ * Register (RSL) mio_emm_timing ++ * ++ * eMMC Timing Register This register determines the number of tap delays ++ * the EMM_DAT, EMM_DS, and EMM_CMD lines are transmitted or received in ++ * relation to EMM_CLK. These values should only be changed when the eMMC ++ * bus is idle. ++ */ ++union mio_emm_timing { ++ u64 u; ++ struct mio_emm_timing_s { ++ u64 data_out_tap : 6; ++ u64 reserved_6_15 : 10; ++ u64 data_in_tap : 6; ++ u64 reserved_22_31 : 10; ++ u64 cmd_out_tap : 6; ++ u64 reserved_38_47 : 10; ++ u64 cmd_in_tap : 6; ++ u64 reserved_54_63 : 10; ++ } s; ++ /* struct mio_emm_timing_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_TIMING(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_TIMING(void) ++{ ++ return 0x20d0; ++} ++ ++/** ++ * Register (RSL) mio_emm_wdog ++ * ++ * eMMC Watchdog Register ++ */ ++union mio_emm_wdog { ++ u64 u; ++ struct mio_emm_wdog_s { ++ u64 clk_cnt : 26; ++ u64 reserved_26_63 : 38; ++ } s; ++ /* struct mio_emm_wdog_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_WDOG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_WDOG(void) ++{ ++ return 0x2088; ++} ++ ++#endif /* __CSRS_MIO_EMM_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx/csrs/csrs-xcv.h b/arch/arm/include/asm/arch-octeontx/csrs/csrs-xcv.h +new file mode 100644 +index 0000000000..575f6dce82 +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx/csrs/csrs-xcv.h +@@ -0,0 +1,428 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++#ifndef __CSRS_XCV_H__ ++#define __CSRS_XCV_H__ ++ ++/** ++ * @file ++ * ++ * Configuration and status register (CSR) address and type definitions for ++ * XCV. ++ * ++ * This file is auto generated. Do not edit. ++ * ++ */ ++ ++/** ++ * Enumeration xcv_bar_e ++ * ++ * XCV Base Address Register Enumeration Enumerates the base address ++ * registers. ++ */ ++#define XCV_BAR_E_XCVX_PF_BAR0(a) (0x87e0db000000ll + 0ll * (a)) ++#define XCV_BAR_E_XCVX_PF_BAR0_SIZE 0x100000ull ++#define XCV_BAR_E_XCVX_PF_BAR4(a) (0x87e0dbf00000ll + 0ll * (a)) ++#define XCV_BAR_E_XCVX_PF_BAR4_SIZE 0x100000ull ++ ++/** ++ * Enumeration xcv_int_vec_e ++ * ++ * XCV MSI-X Vector Enumeration Enumerates the MSI-X interrupt vectors. ++ */ ++#define XCV_INT_VEC_E_INT (0) ++ ++/** ++ * Register (RSL) xcv#_batch_crd_ret ++ * ++ * XCV Batch Credit Return Register ++ */ ++union xcvx_batch_crd_ret { ++ u64 u; ++ struct xcvx_batch_crd_ret_s { ++ u64 crd_ret : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct xcvx_batch_crd_ret_s cn; */ ++}; ++ ++static inline u64 XCVX_BATCH_CRD_RET(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 XCVX_BATCH_CRD_RET(u64 a) ++{ ++ return 0x100 + 0 * a; ++} ++ ++/** ++ * Register (RSL) xcv#_comp_ctl ++ * ++ * XCV Compensation Controller Register This register controls ++ * programmable compensation. ++ */ ++union xcvx_comp_ctl { ++ u64 u; ++ struct xcvx_comp_ctl_s { ++ u64 nctl_sat : 1; ++ u64 reserved_1_26 : 26; ++ u64 nctl_lock : 1; ++ u64 reserved_28 : 1; ++ u64 pctl_sat : 1; ++ u64 pctl_lock : 1; ++ u64 reserved_31 : 1; ++ u64 drv_nctl : 5; ++ u64 reserved_37_39 : 3; ++ u64 drv_pctl : 5; ++ u64 reserved_45_47 : 3; ++ u64 cmp_nctl : 5; ++ u64 reserved_53_55 : 3; ++ u64 cmp_pctl : 5; ++ u64 reserved_61_62 : 2; ++ u64 drv_byp : 1; ++ } s; ++ /* struct xcvx_comp_ctl_s cn; */ ++}; ++ ++static inline u64 XCVX_COMP_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 XCVX_COMP_CTL(u64 a) ++{ ++ return 0x20 + 0 * a; ++} ++ ++/** ++ * Register (RSL) xcv#_ctl ++ * ++ * XCV Control Register This register contains the status control bits. ++ */ ++union xcvx_ctl { ++ u64 u; ++ struct xcvx_ctl_s { ++ u64 speed : 2; ++ u64 lpbk_int : 1; ++ u64 lpbk_ext : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct xcvx_ctl_s cn; */ ++}; ++ ++static inline u64 XCVX_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 XCVX_CTL(u64 a) ++{ ++ return 0x30 + 0 * a; ++} ++ ++/** ++ * Register (RSL) xcv#_dll_ctl ++ * ++ * XCV DLL Controller Register The RGMII timing specification requires ++ * that devices transmit clock and data synchronously. The specification ++ * requires external sources (namely the PC board trace routes) to ++ * introduce the appropriate 1.5 to 2.0 ns of delay. To eliminate the ++ * need for the PC board delays, the RGMII interface has optional on- ++ * board DLLs for both transmit and receive. For correct operation, at ++ * most one of the transmitter, board, or receiver involved in an RGMII ++ * link should introduce delay. By default/reset, the RGMII receivers ++ * delay the received clock, and the RGMII transmitters do not delay the ++ * transmitted clock. Whether this default works as-is with a given link ++ * partner depends on the behavior of the link partner and the PC board. ++ * These are the possible modes of RGMII receive operation: * ++ * XCV()_DLL_CTL[CLKRX_BYP] = 0 (reset value) - The RGMII receive ++ * interface introduces clock delay using its internal DLL. This mode is ++ * appropriate if neither the remote transmitter nor the PC board delays ++ * the clock. * XCV()_DLL_CTL[CLKRX_BYP] = 1, [CLKRX_SET] = 0x0 - The ++ * RGMII receive interface introduces no clock delay. This mode is ++ * appropriate if either the remote transmitter or the PC board delays ++ * the clock. These are the possible modes of RGMII transmit operation: ++ * * XCV()_DLL_CTL[CLKTX_BYP] = 1, [CLKTX_SET] = 0x0 (reset value) - The ++ * RGMII transmit interface introduces no clock delay. This mode is ++ * appropriate is either the remote receiver or the PC board delays the ++ * clock. * XCV()_DLL_CTL[CLKTX_BYP] = 0 - The RGMII transmit interface ++ * introduces clock delay using its internal DLL. This mode is ++ * appropriate if neither the remote receiver nor the PC board delays the ++ * clock. ++ */ ++union xcvx_dll_ctl { ++ u64 u; ++ struct xcvx_dll_ctl_s { ++ u64 refclk_sel : 2; ++ u64 reserved_2_7 : 6; ++ u64 clktx_set : 7; ++ u64 clktx_byp : 1; ++ u64 clkrx_set : 7; ++ u64 clkrx_byp : 1; ++ u64 clk_set : 7; ++ u64 lock : 1; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct xcvx_dll_ctl_s cn; */ ++}; ++ ++static inline u64 XCVX_DLL_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 XCVX_DLL_CTL(u64 a) ++{ ++ return 0x10 + 0 * a; ++} ++ ++/** ++ * Register (RSL) xcv#_eco ++ * ++ * INTERNAL: XCV ECO Register ++ */ ++union xcvx_eco { ++ u64 u; ++ struct xcvx_eco_s { ++ u64 eco_rw : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct xcvx_eco_s cn; */ ++}; ++ ++static inline u64 XCVX_ECO(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 XCVX_ECO(u64 a) ++{ ++ return 0x200 + 0 * a; ++} ++ ++/** ++ * Register (RSL) xcv#_inbnd_status ++ * ++ * XCV Inband Status Register This register contains RGMII inband status. ++ */ ++union xcvx_inbnd_status { ++ u64 u; ++ struct xcvx_inbnd_status_s { ++ u64 link : 1; ++ u64 speed : 2; ++ u64 duplex : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct xcvx_inbnd_status_s cn; */ ++}; ++ ++static inline u64 XCVX_INBND_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 XCVX_INBND_STATUS(u64 a) ++{ ++ return 0x80 + 0 * a; ++} ++ ++/** ++ * Register (RSL) xcv#_int ++ * ++ * XCV Interrupt Register This register flags error for TX FIFO overflow, ++ * TX FIFO underflow and incomplete byte for 10/100 Mode. It also flags ++ * status change for link duplex, link speed and link up/down. ++ */ ++union xcvx_int { ++ u64 u; ++ struct xcvx_int_s { ++ u64 link : 1; ++ u64 speed : 1; ++ u64 reserved_2 : 1; ++ u64 duplex : 1; ++ u64 incomp_byte : 1; ++ u64 tx_undflw : 1; ++ u64 tx_ovrflw : 1; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct xcvx_int_s cn; */ ++}; ++ ++static inline u64 XCVX_INT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 XCVX_INT(u64 a) ++{ ++ return 0x40 + 0 * a; ++} ++ ++/** ++ * Register (RSL) xcv#_int_ena_w1c ++ * ++ * Loopback Error Interrupt Enable Clear Register This register clears ++ * interrupt enable bits. ++ */ ++union xcvx_int_ena_w1c { ++ u64 u; ++ struct xcvx_int_ena_w1c_s { ++ u64 link : 1; ++ u64 speed : 1; ++ u64 reserved_2 : 1; ++ u64 duplex : 1; ++ u64 incomp_byte : 1; ++ u64 tx_undflw : 1; ++ u64 tx_ovrflw : 1; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct xcvx_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 XCVX_INT_ENA_W1C(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 XCVX_INT_ENA_W1C(u64 a) ++{ ++ return 0x50 + 0 * a; ++} ++ ++/** ++ * Register (RSL) xcv#_int_ena_w1s ++ * ++ * Loopback Error Interrupt Enable Set Register This register sets ++ * interrupt enable bits. ++ */ ++union xcvx_int_ena_w1s { ++ u64 u; ++ struct xcvx_int_ena_w1s_s { ++ u64 link : 1; ++ u64 speed : 1; ++ u64 reserved_2 : 1; ++ u64 duplex : 1; ++ u64 incomp_byte : 1; ++ u64 tx_undflw : 1; ++ u64 tx_ovrflw : 1; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct xcvx_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 XCVX_INT_ENA_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 XCVX_INT_ENA_W1S(u64 a) ++{ ++ return 0x58 + 0 * a; ++} ++ ++/** ++ * Register (RSL) xcv#_int_w1s ++ * ++ * Loopback Error Interrupt Set Register This register sets interrupt ++ * bits. ++ */ ++union xcvx_int_w1s { ++ u64 u; ++ struct xcvx_int_w1s_s { ++ u64 link : 1; ++ u64 speed : 1; ++ u64 reserved_2 : 1; ++ u64 duplex : 1; ++ u64 incomp_byte : 1; ++ u64 tx_undflw : 1; ++ u64 tx_ovrflw : 1; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct xcvx_int_w1s_s cn; */ ++}; ++ ++static inline u64 XCVX_INT_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 XCVX_INT_W1S(u64 a) ++{ ++ return 0x48 + 0 * a; ++} ++ ++/** ++ * Register (RSL) xcv#_msix_pba# ++ * ++ * XCV MSI-X Pending Bit Array Registers This register is the MSI-X PBA ++ * table; the bit number is indexed by the XCV_INT_VEC_E enumeration. ++ */ ++union xcvx_msix_pbax { ++ u64 u; ++ struct xcvx_msix_pbax_s { ++ u64 pend : 64; ++ } s; ++ /* struct xcvx_msix_pbax_s cn; */ ++}; ++ ++static inline u64 XCVX_MSIX_PBAX(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 XCVX_MSIX_PBAX(u64 a, u64 b) ++{ ++ return 0xf0000 + 0 * a + 8 * b; ++} ++ ++/** ++ * Register (RSL) xcv#_msix_vec#_addr ++ * ++ * XCV MSI-X Vector-Table Address Register This register is the MSI-X ++ * vector table, indexed by the XCV_INT_VEC_E enumeration. ++ */ ++union xcvx_msix_vecx_addr { ++ u64 u; ++ struct xcvx_msix_vecx_addr_s { ++ u64 secvec : 1; ++ u64 reserved_1 : 1; ++ u64 addr : 47; ++ u64 reserved_49_63 : 15; ++ } s; ++ /* struct xcvx_msix_vecx_addr_s cn; */ ++}; ++ ++static inline u64 XCVX_MSIX_VECX_ADDR(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 XCVX_MSIX_VECX_ADDR(u64 a, u64 b) ++{ ++ return 0 + 0 * a + 0x10 * b; ++} ++ ++/** ++ * Register (RSL) xcv#_msix_vec#_ctl ++ * ++ * XCV MSI-X Vector-Table Control and Data Register This register is the ++ * MSI-X vector table, indexed by the XCV_INT_VEC_E enumeration. ++ */ ++union xcvx_msix_vecx_ctl { ++ u64 u; ++ struct xcvx_msix_vecx_ctl_s { ++ u64 data : 20; ++ u64 reserved_20_31 : 12; ++ u64 mask : 1; ++ u64 reserved_33_63 : 31; ++ } s; ++ /* struct xcvx_msix_vecx_ctl_s cn; */ ++}; ++ ++static inline u64 XCVX_MSIX_VECX_CTL(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 XCVX_MSIX_VECX_CTL(u64 a, u64 b) ++{ ++ return 8 + 0 * a + 0x10 * b; ++} ++ ++/** ++ * Register (RSL) xcv#_reset ++ * ++ * XCV Reset Registers This register controls reset. ++ */ ++union xcvx_reset { ++ u64 u; ++ struct xcvx_reset_s { ++ u64 rx_dat_rst_n : 1; ++ u64 rx_pkt_rst_n : 1; ++ u64 tx_dat_rst_n : 1; ++ u64 tx_pkt_rst_n : 1; ++ u64 reserved_4_6 : 3; ++ u64 comp : 1; ++ u64 reserved_8_10 : 3; ++ u64 dllrst : 1; ++ u64 reserved_12_14 : 3; ++ u64 clkrst : 1; ++ u64 reserved_16_62 : 47; ++ u64 enable : 1; ++ } s; ++ /* struct xcvx_reset_s cn; */ ++}; ++ ++static inline u64 XCVX_RESET(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 XCVX_RESET(u64 a) ++{ ++ return 0 + 0 * a; ++} ++ ++#endif /* __CSRS_XCV_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx/gpio.h b/arch/arm/include/asm/arch-octeontx/gpio.h +new file mode 100644 +index 0000000000..3943ffd952 +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx/gpio.h +@@ -0,0 +1,6 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ +diff --git a/arch/arm/include/asm/arch-octeontx/lock.h b/arch/arm/include/asm/arch-octeontx/lock.h +new file mode 100644 +index 0000000000..65fab6865f +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx/lock.h +@@ -0,0 +1,139 @@ ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ */ ++ ++#ifndef __OCTEONTX2_LOCK_H__ ++#define __OCTEONTX2_LOCK_H__ ++ ++/** ++ * U-Boot doesn't implement spinlocks but we need them here since ++ * we could be sharing with other processes (i.e. ATF) ++ * ++ * This is copied from the Linux kernel arm64 implementation. ++ */ ++typedef struct octeontx_spinlock { ++ u16 next; ++ u16 owner; ++} __aligned(4) octeontx_spinlock_t; ++ ++/** ++ * Atomic compare and exchange, derived from atomic_ll_sc.h in Linux ++ * ++ * @param ptr pointer to 128 bits to compare and exchange ++ * @param old_hi expected old value first 64 bits ++ * @param old_lo expected old value second 64 bits ++ * @param new_hi new first 64-bit value to set ++ * @param new_lo new second 64-bit value to set ++ * @param last_hi pointer to previous first 64-bit value ++ * @param last_lo pointer previous second 64-bit value ++ * ++ * @return true if successful, false if the old values mismatched ++ * ++ * last_hi and last_lo may be NULL. ++ */ ++static inline bool octeontx_cmpxchg_atomic128(volatile void *ptr, ++ u64 old_hi, u64 old_lo, ++ u64 new_hi, u64 new_lo, ++ u64 *last_hi, u64 *last_lo) ++{ ++ u64 tmp_hi, tmp_lo, oldval_hi, oldval_lo; ++ u32 tmp; ++ ++ asm volatile ( ++ " prfm pstl1strm, %[v] \n" ++ "1: ldaxp %[oldval_lo], %[oldval_hi], %[v] \n" ++ " eor %[tmp_lo], %[oldval_lo], %[old_lo] \n" ++ " eor %[tmp_hi], %[oldval_hi], %[old_hi] \n" ++ " cbnz %[tmp_lo], 2f \n" ++ " cbnz %[tmp_hi], 2f \n" ++ " stxp %w[tmp], %[new_hi], %[new_lo], %[v] \n" ++ " cbnz %w[tmp], 1b \n" ++ "2: \n" ++ : [tmp] "=&r" (tmp), ++ [oldval_lo] "=&r" (oldval_lo), ++ [oldval_hi] "=&r" (oldval_hi), ++ [v] "+Q" (*(u64 *)ptr), ++ [tmp_lo] "=&r" (tmp_lo), [tmp_hi] "=&r" (tmp_hi) ++ : [old_lo] "Lr" (old_lo), [old_hi] "Lr" (old_hi), ++ [new_lo] "r" (new_lo), [new_hi] "r" (new_hi) ++ : "memory"); ++ if (last_hi) ++ *last_hi = oldval_hi; ++ if (last_lo) ++ *last_lo = oldval_lo; ++ return !(tmp_hi | tmp_lo); ++} ++ ++static inline void octeontx_init_spin_lock(octeontx_spinlock_t *lock) ++{ ++ *(u32 *)lock = 0; ++ __iowmb(); ++} ++ ++/** ++ * Acquires a spinlock ++ * ++ * @param lock pointer to lock ++ * ++ * This code is copied from the Linux aarch64 spinlock.h file ++ * and is compatible with it. ++ */ ++static inline void octeontx_spin_lock(octeontx_spinlock_t *lock) ++{ ++ unsigned int tmp; ++ octeontx_spinlock_t lockval, newval; ++ ++ asm volatile ( ++ /* Atomically increment the next ticket. */ ++ /* LL/SC */ ++" prfm pstl1strm, %3 \n" ++"1: ldaxr %w0, %3 \n" ++" add %w1, %w0, %w5 \n" ++" stxr %w2, %w1, %3 \n" ++" cbnz %w2, 1b \n" ++ ++ /* Did we get the lock? */ ++" eor %w1, %w0, %w0, ror #16 \n" ++" cbz %w1, 3f \n" ++ /* ++ * No: spin on the owner. Send a local event to avoid missing an ++ * unlock before the exclusive load. ++ */ ++" sevl \n" ++"2: wfe \n" ++" ldaxrh %w2, %4 \n" ++" eor %w1, %w2, %w0, lsr #16 \n" ++" cbnz %w1, 2b \n" ++ /* We got the lock. Critical section starts here. */ ++"3:" ++ : "=&r" (lockval), "=&r" (newval), "=&r" (tmp), "+Q" (*lock) ++ : "Q" (lock->owner), "I" (1 << 16) ++ : "memory"); ++} ++ ++/** ++ * Releases a spinlock ++ * ++ * @param lock pointer to lock ++ * ++ * This code is copied from the Linux aarch64 spinlock.h file. ++ */ ++static inline void octeontx_spin_unlock(octeontx_spinlock_t *lock) ++{ ++ unsigned long tmp; ++ ++ asm volatile ( ++ " ldrh %w1, %0 \n" ++ " add %w1, %w1, #1 \n" ++ " stlrh %w1, %0 \n" ++ " nop \n" ++ : "=Q" (lock->owner), "=&r" (tmp) ++ : ++ : "memory" ++ ++ ); ++} ++ ++#endif /* __OCTEONTX2_LOCK_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx/smc.h b/arch/arm/include/asm/arch-octeontx/smc.h +new file mode 100644 +index 0000000000..beff4d158f +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx/smc.h +@@ -0,0 +1,20 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#ifndef __SMC_H__ ++#define __SMC_H__ ++ ++/* OcteonTX Service Calls version numbers */ ++#define OCTEONTX_VERSION_MAJOR 0x1 ++#define OCTEONTX_VERSION_MINOR 0x0 ++ ++/* x1 - node number */ ++#define OCTEONTX_DRAM_SIZE 0xc2000301 ++ ++ssize_t smc_dram_size(unsigned int node); ++ ++#endif /* __SMC_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx/soc.h b/arch/arm/include/asm/arch-octeontx/soc.h +new file mode 100644 +index 0000000000..6d780929ec +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx/soc.h +@@ -0,0 +1,73 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#ifndef __SOC_H__ ++#define __SOC_H__ ++ ++/* Product PARTNUM */ ++#define CN81XX 0xA2 ++#define CN83XX 0xA3 ++ ++/* Register defines */ ++#define MIO_FUS_DAT2 0x87E003001410ULL ++ ++#define otx_is_altpkg() read_alt_pkg() ++#define otx_is_soc(soc) (read_partnum() == (soc)) ++#define otx_is_board(model) (!strcmp(read_board_name(), model)) ++#define otx_is_platform(platform) (read_platform() == (platform)) ++ ++typedef enum { ++ PLATFORM_HW = 0, ++ PLATFORM_EMULATOR = 1, ++ PLATFORM_ASIM = 3, ++} platform_t; ++ ++/** ++ * Register (RSL) mio_fus_dat2 ++ * ++ * MIO Fuse Data Register 2 ++ */ ++union mio_fus_dat2 { ++ u64 u; ++ struct mio_fus_dat2_s { ++ u64 reserved_0 : 1; ++ u64 ddf_dis : 1; ++ u64 bgx2_dis : 1; ++ u64 bgx3_dis : 1; ++ u64 tim_dis : 1; ++ u64 lmc_half : 1; ++ u64 pem_dis : 3; ++ u64 sata_dis : 4; ++ u64 bgx_dis : 2; ++ u64 ocx_dis : 1; ++ u64 chip_id : 8; ++ u64 reserved_24 : 1; ++ u64 trustzone_en : 1; ++ u64 nocrypto : 1; ++ u64 nomul : 1; ++ u64 nodfa_cp2 : 1; ++ u64 reserved_29 : 1; ++ u64 lmc_mode32 : 1; ++ u64 reserved_31 : 1; ++ u64 raid_en : 1; ++ u64 fus318 : 1; ++ u64 dorm_crypto : 1; ++ u64 power_limit : 2; ++ u64 rom_info : 10; ++ u64 fus118 : 1; ++ u64 gbl_pwr_throttle : 8; ++ u64 run_platform : 3; ++ u64 reserved_59_63 : 5; ++ } s; ++}; ++ ++platform_t read_platform(void); ++u8 read_partnum(void); ++const char *read_board_name(void); ++bool read_alt_pkg(void); ++ ++#endif /* __SOC_H */ +diff --git a/arch/arm/include/asm/arch-octeontx2/board.h b/arch/arm/include/asm/arch-octeontx2/board.h +new file mode 100644 +index 0000000000..ca189b9a65 +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx2/board.h +@@ -0,0 +1,190 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#ifndef __BOARD_H__ ++#define __BOARD_H__ ++ ++#include ++ ++/** Reg offsets */ ++#define RST_BOOT 0x87E006001600ULL ++ ++#define CPC_BOOT_OWNERX(a) 0x86D000000160ULL + (8 * (a)) ++ ++/* attestation definitions shared with ATF (see 'plat_octeontx.h') */ ++ ++#define ATTESTATION_MAGIC_ID 0x5f415454 /* "_ATT" */ ++ ++enum sw_attestation_tlv_type { ++ ATT_IMG_INIT_BIN, ++ ATT_IMG_ATF_BL1, ++ ATT_IMG_BOARD_DT, ++ ATT_IMG_LINUX_DT, ++ ATT_IMG_SCP_TBL1FW, ++ ATT_IMG_MCP_TBL1FW, ++ ATT_IMG_AP_TBL1FW, ++ ATT_IMG_ATF_BL2, ++ ATT_IMG_ATF_BL31, ++ ATT_IMG_ATF_BL33, ++ ATT_SIG_NONCE, ++ ATT_IMG_FIT_KERNEL, ++ ++ ATT_TLV_TYPE_COUNT, ++}; ++ ++typedef struct sw_attestation_tlv { ++ u16 type_be; /* sw_attestation_tlv_type */ ++ u16 length_be; ++ u8 value[0]; /* array of 'length_be' bytes */ ++} sw_attestation_tlv_t; ++ ++#define SW_ATT_INFO_NONCE_MAX_LEN 256 ++ ++typedef struct sw_attestation_info_hdr { ++ u32 magic_be; ++ u16 tlv_len_be; ++ u16 total_len_be; ++ u16 certificate_len_be; ++ u16 signature_len_be; ++ union { ++ sw_attestation_tlv_t tlv_list[0]; ++ s8 input_nonce[0]; ++ }; ++} __packed sw_attestation_info_hdr_t; ++ ++/** Structure definitions */ ++/** ++ * Register (NCB32b) cpc_boot_owner# ++ * ++ * CPC Boot Owner Registers These registers control an external arbiter ++ * for the boot device (SPI/eMMC) across multiple external devices. There ++ * is a register for each requester: _ \<0\> - SCP - reset on ++ * SCP reset _ \<1\> - MCP - reset on MCP reset _ \<2\> - AP ++ * Secure - reset on core reset _ \<3\> - AP Nonsecure - reset on core ++ * reset These register is only writable to the corresponding ++ * requestor(s) permitted with CPC_PERMIT. ++ */ ++union cpc_boot_ownerx { ++ u32 u; ++ struct cpc_boot_ownerx_s { ++ u32 boot_req : 1; ++ u32 reserved_1_7 : 7; ++ u32 boot_wait : 1; ++ u32 reserved_9_31 : 23; ++ } s; ++}; ++ ++/** ++ * Register (RSL) rst_boot ++ * ++ * RST Boot Register This register is not accessible through ROM scripts; ++ * see SCR_WRITE32_S[ADDR]. ++ */ ++union rst_boot { ++ u64 u; ++ struct rst_boot_s { ++ u64 rboot_pin : 1; ++ u64 rboot : 1; ++ u64 reserved_2_32 : 31; ++ u64 pnr_mul : 6; ++ u64 reserved_39 : 1; ++ u64 c_mul : 7; ++ u64 reserved_47_52 : 6; ++ u64 gpio_ejtag : 1; ++ u64 mcp_jtagdis : 1; ++ u64 dis_scan : 1; ++ u64 dis_huk : 1; ++ u64 vrm_err : 1; ++ u64 jt_tstmode : 1; ++ u64 ckill_ppdis : 1; ++ u64 trusted_mode : 1; ++ u64 reserved_61_62 : 2; ++ u64 chipkill : 1; ++ } s; ++ struct rst_boot_cn96xx { ++ u64 rboot_pin : 1; ++ u64 rboot : 1; ++ u64 reserved_2_23 : 22; ++ u64 cpt_mul : 7; ++ u64 reserved_31_32 : 2; ++ u64 pnr_mul : 6; ++ u64 reserved_39 : 1; ++ u64 c_mul : 7; ++ u64 reserved_47_52 : 6; ++ u64 gpio_ejtag : 1; ++ u64 mcp_jtagdis : 1; ++ u64 dis_scan : 1; ++ u64 dis_huk : 1; ++ u64 vrm_err : 1; ++ u64 reserved_58_59 : 2; ++ u64 trusted_mode : 1; ++ u64 scp_jtagdis : 1; ++ u64 jtagdis : 1; ++ u64 chipkill : 1; ++ } cn96xx; ++ struct rst_boot_cn98xx { ++ u64 rboot_pin : 1; ++ u64 rboot : 1; ++ u64 reserved_2_7 : 6; ++ u64 rxp_mul : 7; ++ u64 reserved_15 : 1; ++ u64 cpt1_mul : 7; ++ u64 reserved_23 : 1; ++ u64 cpt_mul : 7; ++ u64 reserved_31_32 : 2; ++ u64 pnr_mul : 6; ++ u64 reserved_39 : 1; ++ u64 c_mul : 7; ++ u64 reserved_47_52 : 6; ++ u64 gpio_ejtag : 1; ++ u64 mcp_jtagdis : 1; ++ u64 dis_scan : 1; ++ u64 dis_huk : 1; ++ u64 vrm_err : 1; ++ u64 reserved_58_59 : 2; ++ u64 trusted_mode : 1; ++ u64 scp_jtagdis : 1; ++ u64 jtagdis : 1; ++ u64 chipkill : 1; ++ } cn98xx; ++ struct rst_boot_cnf95xx { ++ u64 rboot_pin : 1; ++ u64 rboot : 1; ++ u64 reserved_2_7 : 6; ++ u64 bphy_mul : 7; ++ u64 reserved_15 : 1; ++ u64 dsp_mul : 7; ++ u64 reserved_23 : 1; ++ u64 cpt_mul : 7; ++ u64 reserved_31_32 : 2; ++ u64 pnr_mul : 6; ++ u64 reserved_39 : 1; ++ u64 c_mul : 7; ++ u64 reserved_47_52 : 6; ++ u64 gpio_ejtag : 1; ++ u64 mcp_jtagdis : 1; ++ u64 dis_scan : 1; ++ u64 dis_huk : 1; ++ u64 vrm_err : 1; ++ u64 reserved_58_59 : 2; ++ u64 trusted_mode : 1; ++ u64 scp_jtagdis : 1; ++ u64 jtagdis : 1; ++ u64 chipkill : 1; ++ } cnf95xx; ++}; ++ ++/** Function definitions */ ++void mem_map_fill(void); ++int fdt_get_board_mac_cnt(void); ++u64 fdt_get_board_mac_addr(void); ++const char *fdt_get_board_model(void); ++const char *fdt_get_board_serial(void); ++const char *fdt_get_board_revision(void); ++void octeontx2_board_get_mac_addr(u8 index, u8 *mac_addr); ++void acquire_flash_arb(bool acquire); ++#endif /* __BOARD_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx2/clock.h b/arch/arm/include/asm/arch-octeontx2/clock.h +new file mode 100644 +index 0000000000..7be8852a55 +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx2/clock.h +@@ -0,0 +1,24 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#ifndef __CLOCK_H__ ++ ++/** System PLL reference clock */ ++#define PLL_REF_CLK 50000000 /* 50 MHz */ ++#define NS_PER_REF_CLK_TICK (1000000000 / PLL_REF_CLK) ++ ++/** ++ * Returns the I/O clock speed in Hz ++ */ ++u64 octeontx_get_io_clock(void); ++ ++/** ++ * Returns the core clock speed in Hz ++ */ ++u64 octeontx_get_core_clock(void); ++ ++#endif /* __CLOCK_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx2/csrs/csrs-cgx.h b/arch/arm/include/asm/arch-octeontx2/csrs/csrs-cgx.h +new file mode 100644 +index 0000000000..281008365c +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx2/csrs/csrs-cgx.h +@@ -0,0 +1,7841 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++#ifndef __CSRS_CGX_H__ ++#define __CSRS_CGX_H__ ++ ++/** ++ * @file ++ * ++ * Configuration and status register (CSR) address and type definitions for ++ * CGX. ++ * ++ * This file is auto generated. Do not edit. ++ * ++ */ ++ ++/** ++ * Enumeration cgx_bar_e ++ * ++ * CGX Base Address Register Enumeration Enumerates the base address ++ * registers. ++ */ ++#define CGX_BAR_E_CGXX_PF_BAR0(a) (0x87e0e0000000ll + 0x1000000ll * (a)) ++#define CGX_BAR_E_CGXX_PF_BAR0_SIZE 0x100000ull ++#define CGX_BAR_E_CGXX_PF_BAR4(a) (0x87e0e0400000ll + 0x1000000ll * (a)) ++#define CGX_BAR_E_CGXX_PF_BAR4_SIZE 0x100000ull ++ ++/** ++ * Enumeration cgx_int_vec_e ++ * ++ * CGX MSI-X Vector Enumeration Enumeration the MSI-X interrupt vectors. ++ */ ++#define CGX_INT_VEC_E_CMRX_INT(a) (0 + 9 * (a)) ++#define CGX_INT_VEC_E_CMRX_SW(a) (0x26 + (a)) ++#define CGX_INT_VEC_E_CMR_MEM_INT (0x24) ++#define CGX_INT_VEC_E_GMPX_GMI_RX_INT(a) (5 + 9 * (a)) ++#define CGX_INT_VEC_E_GMPX_GMI_TX_INT(a) (6 + 9 * (a)) ++#define CGX_INT_VEC_E_GMPX_GMI_WOL_INT(a) (7 + 9 * (a)) ++#define CGX_INT_VEC_E_GMPX_PCS_INT(a) (4 + 9 * (a)) ++#define CGX_INT_VEC_E_SMUX_RX_INT(a) (2 + 9 * (a)) ++#define CGX_INT_VEC_E_SMUX_RX_WOL_INT(a) (8 + 9 * (a)) ++#define CGX_INT_VEC_E_SMUX_TX_INT(a) (3 + 9 * (a)) ++#define CGX_INT_VEC_E_SPUX_INT(a) (1 + 9 * (a)) ++#define CGX_INT_VEC_E_SW (0x25) ++ ++/** ++ * Enumeration cgx_lmac_types_e ++ * ++ * CGX LMAC Type Enumeration Enumerates the LMAC Types that CGX supports. ++ */ ++#define CGX_LMAC_TYPES_E_FIFTYG_R (8) ++#define CGX_LMAC_TYPES_E_FORTYG_R (4) ++#define CGX_LMAC_TYPES_E_HUNDREDG_R (9) ++#define CGX_LMAC_TYPES_E_QSGMII (6) ++#define CGX_LMAC_TYPES_E_RGMII (5) ++#define CGX_LMAC_TYPES_E_RXAUI (2) ++#define CGX_LMAC_TYPES_E_SGMII (0) ++#define CGX_LMAC_TYPES_E_TENG_R (3) ++#define CGX_LMAC_TYPES_E_TWENTYFIVEG_R (7) ++#define CGX_LMAC_TYPES_E_USXGMII (0xa) ++#define CGX_LMAC_TYPES_E_XAUI (1) ++ ++/** ++ * Enumeration cgx_opcode_e ++ * ++ * INTERNAL: CGX Error Opcode Enumeration Enumerates the error opcodes ++ * created by CGX and presented to NCSI/NIX. ++ */ ++#define CGX_OPCODE_E_RE_FCS (7) ++#define CGX_OPCODE_E_RE_FCS_RCV (8) ++#define CGX_OPCODE_E_RE_JABBER (2) ++#define CGX_OPCODE_E_RE_NONE (0) ++#define CGX_OPCODE_E_RE_PARTIAL (1) ++#define CGX_OPCODE_E_RE_RX_CTL (0xb) ++#define CGX_OPCODE_E_RE_SKIP (0xc) ++#define CGX_OPCODE_E_RE_TERMINATE (9) ++ ++/** ++ * Enumeration cgx_spu_br_train_cst_e ++ * ++ * CGX Training Coefficient Status Enumeration 2-bit status for each ++ * coefficient as defined in IEEE 802.3, Table 72-5. ++ */ ++#define CGX_SPU_BR_TRAIN_CST_E_MAXIMUM (3) ++#define CGX_SPU_BR_TRAIN_CST_E_MINIMUM (2) ++#define CGX_SPU_BR_TRAIN_CST_E_NOT_UPDATED (0) ++#define CGX_SPU_BR_TRAIN_CST_E_UPDATED (1) ++ ++/** ++ * Enumeration cgx_spu_br_train_cup_e ++ * ++ * CGX Training Coefficient Enumeration 2-bit command for each ++ * coefficient as defined in IEEE 802.3, Table 72-4. ++ */ ++#define CGX_SPU_BR_TRAIN_CUP_E_DECREMENT (1) ++#define CGX_SPU_BR_TRAIN_CUP_E_HOLD (0) ++#define CGX_SPU_BR_TRAIN_CUP_E_INCREMENT (2) ++#define CGX_SPU_BR_TRAIN_CUP_E_RSV_CMD (3) ++ ++/** ++ * Enumeration cgx_usxgmii_rate_e ++ * ++ * CGX USXGMII Rate Enumeration Enumerates the USXGMII sub-port type ++ * rate, CGX()_SPU()_CONTROL1[USXGMII_RATE]. Selecting a rate higher ++ * than the maximum allowed for a given port sub-type (specified by ++ * CGX()_SPU()_CONTROL1[USXGMII_TYPE]), e.g., selecting ::RATE_2HG (2.5 ++ * Gbps) for CGX_USXGMII_TYPE_E::SXGMII_2G, will cause unpredictable ++ * behavior. USXGMII hardware-based autonegotiation may change this ++ * setting. ++ */ ++#define CGX_USXGMII_RATE_E_RATE_100M (1) ++#define CGX_USXGMII_RATE_E_RATE_10G (5) ++#define CGX_USXGMII_RATE_E_RATE_10M (0) ++#define CGX_USXGMII_RATE_E_RATE_1G (2) ++#define CGX_USXGMII_RATE_E_RATE_20G (6) ++#define CGX_USXGMII_RATE_E_RATE_2HG (3) ++#define CGX_USXGMII_RATE_E_RATE_5G (4) ++#define CGX_USXGMII_RATE_E_RSV_RATE (7) ++ ++/** ++ * Enumeration cgx_usxgmii_type_e ++ * ++ * CGX USXGMII Port Sub-Type Enumeration Enumerates the USXGMII sub-port ++ * type, CGX()_SPU()_CONTROL1[USXGMII_TYPE]. The description indicates ++ * the maximum rate and the maximum number of ports (LMACs) for each sub- ++ * type. The minimum rate for any port is 10M. The rate selection for ++ * each LMAC is made using CGX()_SPU()_CONTROL1[USXGMII_RATE] and the ++ * number of active ports/LMACs is implicitly determined by the value ++ * given to CGX()_CMR()_CONFIG[ENABLE] for each LMAC. Selecting a rate ++ * higher than the maximum allowed for a given port sub-type or enabling ++ * more LMACs than the maximum allowed for a given port sub-type will ++ * cause unpredictable behavior. ++ */ ++#define CGX_USXGMII_TYPE_E_DXGMII_10G (3) ++#define CGX_USXGMII_TYPE_E_DXGMII_20G (5) ++#define CGX_USXGMII_TYPE_E_DXGMII_5G (4) ++#define CGX_USXGMII_TYPE_E_QXGMII_10G (7) ++#define CGX_USXGMII_TYPE_E_QXGMII_20G (6) ++#define CGX_USXGMII_TYPE_E_SXGMII_10G (0) ++#define CGX_USXGMII_TYPE_E_SXGMII_2G (2) ++#define CGX_USXGMII_TYPE_E_SXGMII_5G (1) ++ ++/** ++ * Structure cgx_spu_br_lane_train_status_s ++ * ++ * CGX Lane Training Status Structure This is the group of lane status ++ * bits for a single lane in the BASE-R PMD status register (MDIO address ++ * 1.151) as defined in IEEE 802.3ba-2010, Table 45-55. ++ */ ++union cgx_spu_br_lane_train_status_s { ++ u32 u; ++ struct cgx_spu_br_lane_train_status_s_s { ++ u32 rx_trained : 1; ++ u32 frame_lock : 1; ++ u32 training : 1; ++ u32 training_failure : 1; ++ u32 reserved_4_31 : 28; ++ } s; ++ /* struct cgx_spu_br_lane_train_status_s_s cn; */ ++}; ++ ++/** ++ * Structure cgx_spu_br_train_cup_s ++ * ++ * CGX Lane Training Coefficient Structure This is the coefficient update ++ * field of the BASE-R link training packet as defined in IEEE 802.3, ++ * Table 72-4. ++ */ ++union cgx_spu_br_train_cup_s { ++ u32 u; ++ struct cgx_spu_br_train_cup_s_s { ++ u32 pre_cup : 2; ++ u32 main_cup : 2; ++ u32 post_cup : 2; ++ u32 reserved_6_11 : 6; ++ u32 init : 1; ++ u32 preset : 1; ++ u32 reserved_14_31 : 18; ++ } s; ++ struct cgx_spu_br_train_cup_s_cn { ++ u32 pre_cup : 2; ++ u32 main_cup : 2; ++ u32 post_cup : 2; ++ u32 reserved_6_11 : 6; ++ u32 init : 1; ++ u32 preset : 1; ++ u32 reserved_14_15 : 2; ++ u32 reserved_16_31 : 16; ++ } cn; ++}; ++ ++/** ++ * Structure cgx_spu_br_train_rep_s ++ * ++ * CGX Training Report Structure This is the status report field of the ++ * BASE-R link training packet as defined in IEEE 802.3, Table 72-5. ++ */ ++union cgx_spu_br_train_rep_s { ++ u32 u; ++ struct cgx_spu_br_train_rep_s_s { ++ u32 pre_cst : 2; ++ u32 main_cst : 2; ++ u32 post_cst : 2; ++ u32 reserved_6_14 : 9; ++ u32 rx_ready : 1; ++ u32 reserved_16_31 : 16; ++ } s; ++ /* struct cgx_spu_br_train_rep_s_s cn; */ ++}; ++ ++/** ++ * Structure cgx_spu_sds_cu_s ++ * ++ * INTERNAL: CGX Training Coeffiecient Structure This structure is ++ * similar to CGX_SPU_BR_TRAIN_CUP_S format, but with reserved fields ++ * removed and [RCVR_READY] field added. ++ */ ++union cgx_spu_sds_cu_s { ++ u32 u; ++ struct cgx_spu_sds_cu_s_s { ++ u32 pre_cu : 2; ++ u32 main_cu : 2; ++ u32 post_cu : 2; ++ u32 initialize : 1; ++ u32 preset : 1; ++ u32 rcvr_ready : 1; ++ u32 reserved_9_31 : 23; ++ } s; ++ /* struct cgx_spu_sds_cu_s_s cn; */ ++}; ++ ++/** ++ * Structure cgx_spu_sds_skew_status_s ++ * ++ * CGX Skew Status Structure Provides receive skew information detected ++ * for a physical SerDes lane when it is assigned to a multilane ++ * LMAC/LPCS. Contents are valid when RX deskew is done for the ++ * associated LMAC/LPCS. ++ */ ++union cgx_spu_sds_skew_status_s { ++ u32 u; ++ struct cgx_spu_sds_skew_status_s_s { ++ u32 am_timestamp : 12; ++ u32 reserved_12_15 : 4; ++ u32 am_lane_id : 5; ++ u32 reserved_21_22 : 2; ++ u32 lane_skew : 7; ++ u32 reserved_30_31 : 2; ++ } s; ++ /* struct cgx_spu_sds_skew_status_s_s cn; */ ++}; ++ ++/** ++ * Structure cgx_spu_sds_sr_s ++ * ++ * INTERNAL: CGX Lane Training Coefficient Structure Similar to ++ * CGX_SPU_BR_TRAIN_REP_S format, but with reserved and RX ready fields ++ * removed. ++ */ ++union cgx_spu_sds_sr_s { ++ u32 u; ++ struct cgx_spu_sds_sr_s_s { ++ u32 pre_status : 2; ++ u32 main_status : 2; ++ u32 post_status : 2; ++ u32 reserved_6_31 : 26; ++ } s; ++ /* struct cgx_spu_sds_sr_s_s cn; */ ++}; ++ ++/** ++ * Register (RSL) cgx#_active_pc ++ * ++ * CGX ACTIVE PC Register This register counts the conditional clocks for ++ * power management. ++ */ ++union cgxx_active_pc { ++ u64 u; ++ struct cgxx_active_pc_s { ++ u64 cnt : 64; ++ } s; ++ /* struct cgxx_active_pc_s cn; */ ++}; ++ ++static inline u64 CGXX_ACTIVE_PC(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_ACTIVE_PC(void) ++{ ++ return 0x2010; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_activity ++ * ++ * CGX CMR Activity Registers ++ */ ++union cgxx_cmrx_activity { ++ u64 u; ++ struct cgxx_cmrx_activity_s { ++ u64 act_tx_lo : 1; ++ u64 act_tx_hi : 1; ++ u64 pause_tx : 1; ++ u64 act_rx_lo : 1; ++ u64 act_rx_hi : 1; ++ u64 pause_rx : 1; ++ u64 reserved_6_63 : 58; ++ } s; ++ /* struct cgxx_cmrx_activity_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_ACTIVITY(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_ACTIVITY(u64 a) ++{ ++ return 0x5f8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_config ++ * ++ * CGX CMR Configuration Registers Logical MAC/PCS configuration ++ * registers; one per LMAC. The maximum number of LMACs (and maximum LMAC ++ * ID) that can be enabled by these registers is limited by ++ * CGX()_CMR_RX_LMACS[LMACS] and CGX()_CMR_TX_LMACS[LMACS]. Internal: ++ * \ Example configurations: ------------------------------------ ++ * --------------------------------------- Configuration ++ * LMACS Register [ENABLE] [LMAC_TYPE] ---------------- ++ * ----------------------------------------------------------- ++ * 1x50G+1x25G+1xSGMII 4 CGXn_CMR0_CONFIG 1 8 ++ * CGXn_CMR1_CONFIG 0 -- ++ * CGXn_CMR2_CONFIG 1 7 ++ * CGXn_CMR3_CONFIG 1 0 --------------------------------- ++ * ------------------------------------------ USXGMII ++ * 1-4 CGXn_CMR0_CONFIG 1 a ++ * CGXn_CMR1_CONFIG 1 a ++ * CGXn_CMR2_CONFIG 1 a ++ * CGXn_CMR3_CONFIG 1 a --------------------------------- ++ * ------------------------------------------ 1x100GBASE-R4 1 ++ * CGXn_CMR0_CONFIG 1 9 ++ * CGXn_CMR1_CONFIG 0 -- ++ * CGXn_CMR2_CONFIG 0 -- ++ * CGXn_CMR3_CONFIG 0 -- -------------------------------- ++ * ------------------------------------------- 2x50GBASE-R2 ++ * 2 CGXn_CMR0_CONFIG 1 8 ++ * CGXn_CMR1_CONFIG 1 8 ++ * CGXn_CMR2_CONFIG 0 -- ++ * CGXn_CMR3_CONFIG 0 -- -------------------------------- ++ * ------------------------------------------- 4x25GBASE-R ++ * 4 CGXn_CMR0_CONFIG 1 7 ++ * CGXn_CMR1_CONFIG 1 7 ++ * CGXn_CMR2_CONFIG 1 7 ++ * CGXn_CMR3_CONFIG 1 7 --------------------------------- ++ * ------------------------------------------ QSGMII 4 ++ * CGXn_CMR0_CONFIG 1 6 ++ * CGXn_CMR1_CONFIG 1 6 ++ * CGXn_CMR2_CONFIG 1 6 ++ * CGXn_CMR3_CONFIG 1 6 --------------------------------- ++ * ------------------------------------------ 1x40GBASE-R4 1 ++ * CGXn_CMR0_CONFIG 1 4 ++ * CGXn_CMR1_CONFIG 0 -- ++ * CGXn_CMR2_CONFIG 0 -- ++ * CGXn_CMR3_CONFIG 0 -- -------------------------------- ++ * ------------------------------------------- 4x10GBASE-R ++ * 4 CGXn_CMR0_CONFIG 1 3 ++ * CGXn_CMR1_CONFIG 1 3 ++ * CGXn_CMR2_CONFIG 1 3 ++ * CGXn_CMR3_CONFIG 1 3 --------------------------------- ++ * ------------------------------------------ 2xRXAUI 2 ++ * CGXn_CMR0_CONFIG 1 2 ++ * CGXn_CMR1_CONFIG 1 2 ++ * CGXn_CMR2_CONFIG 0 -- ++ * CGXn_CMR3_CONFIG 0 -- -------------------------------- ++ * ------------------------------------------- 1x10GBASE-X/XAUI/DXAUI ++ * 1 CGXn_CMR0_CONFIG 1 1 ++ * CGXn_CMR1_CONFIG 0 -- ++ * CGXn_CMR2_CONFIG 0 -- ++ * CGXn_CMR3_CONFIG 0 -- -------------------------------- ++ * ------------------------------------------- 4xSGMII/1000BASE-X ++ * 4 CGXn_CMR0_CONFIG 1 0 ++ * CGXn_CMR1_CONFIG 1 0 ++ * CGXn_CMR2_CONFIG 1 0 ++ * CGXn_CMR3_CONFIG 1 0 --------------------------------- ++ * ------------------------------------------ \ ++ */ ++union cgxx_cmrx_config { ++ u64 u; ++ struct cgxx_cmrx_config_s { ++ u64 lane_to_sds : 8; ++ u64 reserved_8_39 : 32; ++ u64 lmac_type : 4; ++ u64 unused : 8; ++ u64 int_beat_gen : 1; ++ u64 data_pkt_tx_en : 1; ++ u64 data_pkt_rx_en : 1; ++ u64 enable : 1; ++ u64 x2p_select : 3; ++ u64 p2x_select : 3; ++ u64 reserved_62_63 : 2; ++ } s; ++ /* struct cgxx_cmrx_config_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_CONFIG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_CONFIG(u64 a) ++{ ++ return 0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_int ++ * ++ * CGX CMR Interrupt Register ++ */ ++union cgxx_cmrx_int { ++ u64 u; ++ struct cgxx_cmrx_int_s { ++ u64 pause_drp : 1; ++ u64 overflw : 1; ++ u64 nic_nxc : 1; ++ u64 nix0_nxc : 1; ++ u64 nix1_nxc : 1; ++ u64 nix0_e_nxc : 1; ++ u64 nix1_e_nxc : 1; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct cgxx_cmrx_int_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_INT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_INT(u64 a) ++{ ++ return 0x40 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_int_ena_w1c ++ * ++ * CGX CMR Interrupt Enable Clear Register This register clears interrupt ++ * enable bits. ++ */ ++union cgxx_cmrx_int_ena_w1c { ++ u64 u; ++ struct cgxx_cmrx_int_ena_w1c_s { ++ u64 pause_drp : 1; ++ u64 overflw : 1; ++ u64 nic_nxc : 1; ++ u64 nix0_nxc : 1; ++ u64 nix1_nxc : 1; ++ u64 nix0_e_nxc : 1; ++ u64 nix1_e_nxc : 1; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct cgxx_cmrx_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_INT_ENA_W1C(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_INT_ENA_W1C(u64 a) ++{ ++ return 0x50 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_int_ena_w1s ++ * ++ * CGX CMR Interrupt Enable Set Register This register sets interrupt ++ * enable bits. ++ */ ++union cgxx_cmrx_int_ena_w1s { ++ u64 u; ++ struct cgxx_cmrx_int_ena_w1s_s { ++ u64 pause_drp : 1; ++ u64 overflw : 1; ++ u64 nic_nxc : 1; ++ u64 nix0_nxc : 1; ++ u64 nix1_nxc : 1; ++ u64 nix0_e_nxc : 1; ++ u64 nix1_e_nxc : 1; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct cgxx_cmrx_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_INT_ENA_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_INT_ENA_W1S(u64 a) ++{ ++ return 0x58 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_int_w1s ++ * ++ * CGX CMR Interrupt Set Register This register sets interrupt bits. ++ */ ++union cgxx_cmrx_int_w1s { ++ u64 u; ++ struct cgxx_cmrx_int_w1s_s { ++ u64 pause_drp : 1; ++ u64 overflw : 1; ++ u64 nic_nxc : 1; ++ u64 nix0_nxc : 1; ++ u64 nix1_nxc : 1; ++ u64 nix0_e_nxc : 1; ++ u64 nix1_e_nxc : 1; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct cgxx_cmrx_int_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_INT_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_INT_W1S(u64 a) ++{ ++ return 0x48 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_led_timing ++ * ++ * CGX MAC LED Activity Timing Registers ++ */ ++union cgxx_cmrx_led_timing { ++ u64 u; ++ struct cgxx_cmrx_led_timing_s { ++ u64 extension : 8; ++ u64 reserved_8_63 : 56; ++ } s; ++ /* struct cgxx_cmrx_led_timing_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_LED_TIMING(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_LED_TIMING(u64 a) ++{ ++ return 0x5f0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_prt_cbfc_ctl ++ * ++ * CGX CMR LMAC PFC Control Registers See CGX()_CMR()_RX_LOGL_XOFF[XOFF]. ++ */ ++union cgxx_cmrx_prt_cbfc_ctl { ++ u64 u; ++ struct cgxx_cmrx_prt_cbfc_ctl_s { ++ u64 reserved_0_15 : 16; ++ u64 phys_bp : 16; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct cgxx_cmrx_prt_cbfc_ctl_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_PRT_CBFC_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_PRT_CBFC_CTL(u64 a) ++{ ++ return 0x608 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_bp_drop ++ * ++ * CGX Receive Backpressure Drop Register ++ */ ++union cgxx_cmrx_rx_bp_drop { ++ u64 u; ++ struct cgxx_cmrx_rx_bp_drop_s { ++ u64 mark : 7; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct cgxx_cmrx_rx_bp_drop_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_BP_DROP(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_BP_DROP(u64 a) ++{ ++ return 0xd8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_bp_off ++ * ++ * CGX Receive Backpressure Off Register ++ */ ++union cgxx_cmrx_rx_bp_off { ++ u64 u; ++ struct cgxx_cmrx_rx_bp_off_s { ++ u64 mark : 7; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct cgxx_cmrx_rx_bp_off_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_BP_OFF(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_BP_OFF(u64 a) ++{ ++ return 0xe8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_bp_on ++ * ++ * CGX Receive Backpressure On Register ++ */ ++union cgxx_cmrx_rx_bp_on { ++ u64 u; ++ struct cgxx_cmrx_rx_bp_on_s { ++ u64 mark : 13; ++ u64 reserved_13_63 : 51; ++ } s; ++ /* struct cgxx_cmrx_rx_bp_on_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_BP_ON(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_BP_ON(u64 a) ++{ ++ return 0xe0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_bp_status ++ * ++ * CGX CMR Receive Backpressure Status Registers ++ */ ++union cgxx_cmrx_rx_bp_status { ++ u64 u; ++ struct cgxx_cmrx_rx_bp_status_s { ++ u64 bp : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_cmrx_rx_bp_status_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_BP_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_BP_STATUS(u64 a) ++{ ++ return 0xf0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_dmac_ctl0 ++ * ++ * CGX CMR Receive DMAC Address-Control0 Register DMAC CAM control ++ * register for use by X2P/NIX bound traffic. Received packets are only ++ * passed to X2P/NIX when the DMAC0 filter result is ACCEPT and STEERING0 ++ * filter result is PASS. See also CGX()_CMR_RX_DMAC()_CAM0 and ++ * CGX()_CMR_RX_STEERING0(). Internal: "* ALGORITHM Here is some pseudo ++ * code that represents the address filter behavior. \ ++ * dmac_addr_filter(uint8 prt, uint48 dmac) { for (lmac=0, lmac\<4, ++ * lmac++) { if (is_bcst(dmac)) // ++ * broadcast accept return (CGX()_CMR(lmac)_RX_DMAC_CTL0[BCST_ACCEPT] ++ * ? ACCEPT : REJECT); if (is_mcst(dmac) && ++ * CGX()_CMR(lmac)_RX_DMAC_CTL0[MCST_MODE] == 0) // multicast reject ++ * return REJECT; if (is_mcst(dmac) && ++ * CGX()_CMR(lmac)_RX_DMAC_CTL0[MCST_MODE] == 1) // multicast accept ++ * return ACCEPT; else // DMAC CAM filter cam_hit = 0; for ++ * (i=0; i\<32; i++) { cam = CGX()_CMR_RX_DMAC(i)_CAM0; if ++ * (cam[EN] && cam[ID] == lmac && cam[ADR] == dmac) { cam_hit = 1; ++ * break; } } if (cam_hit) { return ++ * (CGX()_CMR(lmac)_RX_DMAC_CTL0[CAM_ACCEPT] ? ACCEPT : REJECT); else ++ * return (CGX()_CMR(lmac)_RX_DMAC_CTL0[CAM_ACCEPT] ? REJECT : ACCEPT); ++ * } } \" ++ */ ++union cgxx_cmrx_rx_dmac_ctl0 { ++ u64 u; ++ struct cgxx_cmrx_rx_dmac_ctl0_s { ++ u64 bcst_accept : 1; ++ u64 mcst_mode : 2; ++ u64 cam_accept : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct cgxx_cmrx_rx_dmac_ctl0_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_DMAC_CTL0(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_DMAC_CTL0(u64 a) ++{ ++ return 0x1f8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_dmac_ctl1 ++ * ++ * CGX CMR Receive DMAC Address-Control1 Register DMAC CAM control ++ * register for use by NCSI bound traffic. Received packets are only ++ * passed to NCSI when the DMAC1 filter result is ACCEPT and STEERING1 ++ * filter result is PASS. See also CGX()_CMR_RX_DMAC()_CAM1 and ++ * CGX()_CMR_RX_STEERING1(). For use with the LMAC associated with NCSI; ++ * see CGX()_CMR_GLOBAL_CONFIG[NCSI_LMAC_ID]. Internal: ALGORITHM: See ++ * CGX()_CMR()_RX_DMAC_CTL0. ++ */ ++union cgxx_cmrx_rx_dmac_ctl1 { ++ u64 u; ++ struct cgxx_cmrx_rx_dmac_ctl1_s { ++ u64 bcst_accept : 1; ++ u64 mcst_mode : 2; ++ u64 cam_accept : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct cgxx_cmrx_rx_dmac_ctl1_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_DMAC_CTL1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_DMAC_CTL1(u64 a) ++{ ++ return 0x3f8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_fifo_len ++ * ++ * CGX CMR Receive Fifo Length Registers ++ */ ++union cgxx_cmrx_rx_fifo_len { ++ u64 u; ++ struct cgxx_cmrx_rx_fifo_len_s { ++ u64 fifo_len : 14; ++ u64 busy : 1; ++ u64 fifo_len_e : 14; ++ u64 busy_e : 1; ++ u64 reserved_30_63 : 34; ++ } s; ++ /* struct cgxx_cmrx_rx_fifo_len_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_FIFO_LEN(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_FIFO_LEN(u64 a) ++{ ++ return 0x108 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_id_map ++ * ++ * CGX CMR Receive ID Map Register These registers set the RX LMAC ID ++ * mapping for X2P/NIX. ++ */ ++union cgxx_cmrx_rx_id_map { ++ u64 u; ++ struct cgxx_cmrx_rx_id_map_s { ++ u64 pknd : 6; ++ u64 unused : 2; ++ u64 rid : 7; ++ u64 reserved_15_63 : 49; ++ } s; ++ /* struct cgxx_cmrx_rx_id_map_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_ID_MAP(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_ID_MAP(u64 a) ++{ ++ return 0x60 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_logl_xoff ++ * ++ * CGX CMR Receive Logical XOFF Registers ++ */ ++union cgxx_cmrx_rx_logl_xoff { ++ u64 u; ++ struct cgxx_cmrx_rx_logl_xoff_s { ++ u64 xoff : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_cmrx_rx_logl_xoff_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_LOGL_XOFF(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_LOGL_XOFF(u64 a) ++{ ++ return 0xf8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_logl_xon ++ * ++ * CGX CMR Receive Logical XON Registers ++ */ ++union cgxx_cmrx_rx_logl_xon { ++ u64 u; ++ struct cgxx_cmrx_rx_logl_xon_s { ++ u64 xon : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_cmrx_rx_logl_xon_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_LOGL_XON(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_LOGL_XON(u64 a) ++{ ++ return 0x100 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_merge_stat0 ++ * ++ * CGX RX Preemption Status Register 0 ++ */ ++union cgxx_cmrx_rx_merge_stat0 { ++ u64 u; ++ struct cgxx_cmrx_rx_merge_stat0_s { ++ u64 fa_err_cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_rx_merge_stat0_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_MERGE_STAT0(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_MERGE_STAT0(u64 a) ++{ ++ return 0x138 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_merge_stat1 ++ * ++ * CGX RX Preemption Status Register 1 ++ */ ++union cgxx_cmrx_rx_merge_stat1 { ++ u64 u; ++ struct cgxx_cmrx_rx_merge_stat1_s { ++ u64 fs_err_cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_rx_merge_stat1_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_MERGE_STAT1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_MERGE_STAT1(u64 a) ++{ ++ return 0x140 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_merge_stat2 ++ * ++ * CGX RX Preemption Status Register 2 ++ */ ++union cgxx_cmrx_rx_merge_stat2 { ++ u64 u; ++ struct cgxx_cmrx_rx_merge_stat2_s { ++ u64 fa_ok_cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_rx_merge_stat2_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_MERGE_STAT2(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_MERGE_STAT2(u64 a) ++{ ++ return 0x148 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_merge_stat3 ++ * ++ * CGX RX Preemption Status Register 3 ++ */ ++union cgxx_cmrx_rx_merge_stat3 { ++ u64 u; ++ struct cgxx_cmrx_rx_merge_stat3_s { ++ u64 ff_cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_rx_merge_stat3_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_MERGE_STAT3(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_MERGE_STAT3(u64 a) ++{ ++ return 0x150 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_merge_stat4 ++ * ++ * CGX RX Preemption Status Register 4 ++ */ ++union cgxx_cmrx_rx_merge_stat4 { ++ u64 u; ++ struct cgxx_cmrx_rx_merge_stat4_s { ++ u64 cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_rx_merge_stat4_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_MERGE_STAT4(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_MERGE_STAT4(u64 a) ++{ ++ return 0x158 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_pause_drop_time ++ * ++ * CGX CMR Receive Pause Drop-Time Register ++ */ ++union cgxx_cmrx_rx_pause_drop_time { ++ u64 u; ++ struct cgxx_cmrx_rx_pause_drop_time_s { ++ u64 pause_time : 16; ++ u64 pause_time_e : 16; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct cgxx_cmrx_rx_pause_drop_time_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_PAUSE_DROP_TIME(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_PAUSE_DROP_TIME(u64 a) ++{ ++ return 0x68 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_stat0 ++ * ++ * CGX Receive Status Register 0 These registers provide a count of ++ * received packets that meet the following conditions: * are not ++ * recognized as ERROR packets(any OPCODE). * are not recognized as PAUSE ++ * packets. * are not dropped due FIFO full status. * are not dropped due ++ * DMAC0 or STEERING0 filtering. Internal: "This pseudo code represents ++ * the RX STAT0 through STAT8 accounting: \ If (errored) incr ++ * RX_STAT8 else if (ctrl packet, i.e. Pause/PFC) incr RX_STAT2,3 else ++ * if (fifo full drop) incr RX_STAT6,7 else if (DMAC0/VLAN0 filter ++ * drop) incr RX_STAT4,5 if not a filter+decision else incr ++ * RX_STAT0,1 end \" ++ */ ++union cgxx_cmrx_rx_stat0 { ++ u64 u; ++ struct cgxx_cmrx_rx_stat0_s { ++ u64 cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_rx_stat0_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_STAT0(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_STAT0(u64 a) ++{ ++ return 0x70 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_stat1 ++ * ++ * CGX Receive Status Register 1 These registers provide a count of ++ * octets of received packets. ++ */ ++union cgxx_cmrx_rx_stat1 { ++ u64 u; ++ struct cgxx_cmrx_rx_stat1_s { ++ u64 cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_rx_stat1_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_STAT1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_STAT1(u64 a) ++{ ++ return 0x78 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_stat2 ++ * ++ * CGX Receive Status Register 2 These registers provide a count of ++ * received packets that meet the following conditions: * are not ++ * recognized as ERROR packets(any OPCODE). * are recognized as PAUSE ++ * packets. Pause packets can be optionally dropped or forwarded based ++ * on ++ * CGX()_SMU()_RX_FRM_CTL[CTL_DRP]/CGX()_GMP_GMI_RX()_FRM_CTL[CTL_DRP]. ++ * This count increments regardless of whether the packet is dropped. ++ */ ++union cgxx_cmrx_rx_stat2 { ++ u64 u; ++ struct cgxx_cmrx_rx_stat2_s { ++ u64 cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_rx_stat2_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_STAT2(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_STAT2(u64 a) ++{ ++ return 0x80 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_stat3 ++ * ++ * CGX Receive Status Register 3 These registers provide a count of ++ * octets of received PAUSE and control packets. ++ */ ++union cgxx_cmrx_rx_stat3 { ++ u64 u; ++ struct cgxx_cmrx_rx_stat3_s { ++ u64 cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_rx_stat3_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_STAT3(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_STAT3(u64 a) ++{ ++ return 0x88 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_stat4 ++ * ++ * CGX Receive Status Register 4 These registers provide a count of ++ * received packets that meet the following conditions: * are not ++ * recognized as ERROR packets(any OPCODE). * are not recognized as PAUSE ++ * packets. * are not dropped due FIFO full status. * are dropped due ++ * DMAC0 or STEERING0 filtering. 16B packets or smaller (20B in case of ++ * FCS strip) as the result of truncation or other means are not dropped ++ * by CGX (unless filter and decision is also asserted) and will never ++ * appear in this count. Should the MAC signal to the CMR that the packet ++ * be filtered upon decision before the end of packet, then STAT4 and ++ * STAT5 will not be updated. ++ */ ++union cgxx_cmrx_rx_stat4 { ++ u64 u; ++ struct cgxx_cmrx_rx_stat4_s { ++ u64 cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_rx_stat4_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_STAT4(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_STAT4(u64 a) ++{ ++ return 0x90 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_stat5 ++ * ++ * CGX Receive Status Register 5 These registers provide a count of ++ * octets of filtered DMAC0 or VLAN STEERING0 packets. ++ */ ++union cgxx_cmrx_rx_stat5 { ++ u64 u; ++ struct cgxx_cmrx_rx_stat5_s { ++ u64 cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_rx_stat5_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_STAT5(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_STAT5(u64 a) ++{ ++ return 0x98 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_stat6 ++ * ++ * CGX Receive Status Register 6 These registers provide a count of ++ * received packets that meet the following conditions: * are not ++ * recognized as ERROR packets(any OPCODE). * are not recognized as PAUSE ++ * packets. * are dropped due FIFO full status. They do not count any ++ * packet that is truncated at the point of overflow and sent on to the ++ * NIX. The truncated packet will be marked with error and increment ++ * STAT8. These registers count all entire packets dropped by the FIFO ++ * for a given LMAC. ++ */ ++union cgxx_cmrx_rx_stat6 { ++ u64 u; ++ struct cgxx_cmrx_rx_stat6_s { ++ u64 cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_rx_stat6_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_STAT6(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_STAT6(u64 a) ++{ ++ return 0xa0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_stat7 ++ * ++ * CGX Receive Status Register 7 These registers provide a count of ++ * octets of received packets that were dropped due to a full receive ++ * FIFO. ++ */ ++union cgxx_cmrx_rx_stat7 { ++ u64 u; ++ struct cgxx_cmrx_rx_stat7_s { ++ u64 cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_rx_stat7_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_STAT7(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_STAT7(u64 a) ++{ ++ return 0xa8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_stat8 ++ * ++ * CGX Receive Status Register 8 These registers provide a count of ++ * received packets that meet the following conditions: * are recognized ++ * as ERROR packets(any OPCODE). ++ */ ++union cgxx_cmrx_rx_stat8 { ++ u64 u; ++ struct cgxx_cmrx_rx_stat8_s { ++ u64 cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_rx_stat8_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_STAT8(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_STAT8(u64 a) ++{ ++ return 0xb0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_rx_stat_pri#_xoff ++ * ++ * CGX CMR RX XON to XOFF transition Registers ++ */ ++union cgxx_cmrx_rx_stat_prix_xoff { ++ u64 u; ++ struct cgxx_cmrx_rx_stat_prix_xoff_s { ++ u64 cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_rx_stat_prix_xoff_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_RX_STAT_PRIX_XOFF(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_RX_STAT_PRIX_XOFF(u64 a, u64 b) ++{ ++ return 0x7c0 + 0x40000 * a + 8 * b; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_scratch# ++ * ++ * CGX CMR Scratch Registers ++ */ ++union cgxx_cmrx_scratchx { ++ u64 u; ++ struct cgxx_cmrx_scratchx_s { ++ u64 scratch : 64; ++ } s; ++ /* struct cgxx_cmrx_scratchx_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_SCRATCHX(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_SCRATCHX(u64 a, u64 b) ++{ ++ return 0x1050 + 0x40000 * a + 8 * b; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_sw_int ++ * ++ * CGX CMR Interrupt Register ++ */ ++union cgxx_cmrx_sw_int { ++ u64 u; ++ struct cgxx_cmrx_sw_int_s { ++ u64 sw_set : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_cmrx_sw_int_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_SW_INT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_SW_INT(u64 a) ++{ ++ return 0x180 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_sw_int_ena_w1c ++ * ++ * CGX CMR Interrupt Enable Clear Register This register clears interrupt ++ * enable bits. ++ */ ++union cgxx_cmrx_sw_int_ena_w1c { ++ u64 u; ++ struct cgxx_cmrx_sw_int_ena_w1c_s { ++ u64 sw_set : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_cmrx_sw_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_SW_INT_ENA_W1C(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_SW_INT_ENA_W1C(u64 a) ++{ ++ return 0x190 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_sw_int_ena_w1s ++ * ++ * CGX CMR Interrupt Enable Set Register This register sets interrupt ++ * enable bits. ++ */ ++union cgxx_cmrx_sw_int_ena_w1s { ++ u64 u; ++ struct cgxx_cmrx_sw_int_ena_w1s_s { ++ u64 sw_set : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_cmrx_sw_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_SW_INT_ENA_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_SW_INT_ENA_W1S(u64 a) ++{ ++ return 0x198 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_sw_int_w1s ++ * ++ * CGX CMR Interrupt Set Register This register sets interrupt bits. ++ */ ++union cgxx_cmrx_sw_int_w1s { ++ u64 u; ++ struct cgxx_cmrx_sw_int_w1s_s { ++ u64 sw_set : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_cmrx_sw_int_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_SW_INT_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_SW_INT_W1S(u64 a) ++{ ++ return 0x188 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_channel ++ * ++ * CGX CMR Transmit-Channels Registers ++ */ ++union cgxx_cmrx_tx_channel { ++ u64 u; ++ struct cgxx_cmrx_tx_channel_s { ++ u64 msk : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_cmrx_tx_channel_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_CHANNEL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_CHANNEL(u64 a) ++{ ++ return 0x600 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_fifo_len ++ * ++ * CGX CMR Transmit Fifo Length Registers ++ */ ++union cgxx_cmrx_tx_fifo_len { ++ u64 u; ++ struct cgxx_cmrx_tx_fifo_len_s { ++ u64 fifo_len : 14; ++ u64 lmac_idle : 1; ++ u64 fifo_e_len : 14; ++ u64 lmac_e_idle : 1; ++ u64 reserved_30_63 : 34; ++ } s; ++ /* struct cgxx_cmrx_tx_fifo_len_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_FIFO_LEN(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_FIFO_LEN(u64 a) ++{ ++ return 0x618 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_hg2_status ++ * ++ * CGX CMR Transmit HiGig2 Status Registers ++ */ ++union cgxx_cmrx_tx_hg2_status { ++ u64 u; ++ struct cgxx_cmrx_tx_hg2_status_s { ++ u64 lgtim2go : 16; ++ u64 xof : 16; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct cgxx_cmrx_tx_hg2_status_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_HG2_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_HG2_STATUS(u64 a) ++{ ++ return 0x610 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_merge_stat0 ++ * ++ * CGX TX Preemption Status Register 0 ++ */ ++union cgxx_cmrx_tx_merge_stat0 { ++ u64 u; ++ struct cgxx_cmrx_tx_merge_stat0_s { ++ u64 ff_cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_merge_stat0_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_MERGE_STAT0(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_MERGE_STAT0(u64 a) ++{ ++ return 0x160 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_ovr_bp ++ * ++ * CGX CMR Transmit-Channels Backpressure Override Registers ++ */ ++union cgxx_cmrx_tx_ovr_bp { ++ u64 u; ++ struct cgxx_cmrx_tx_ovr_bp_s { ++ u64 tx_chan_bp : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_cmrx_tx_ovr_bp_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_OVR_BP(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_OVR_BP(u64 a) ++{ ++ return 0x620 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat0 ++ * ++ * CGX CMR Transmit Statistics Registers 0 ++ */ ++union cgxx_cmrx_tx_stat0 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat0_s { ++ u64 xscol : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat0_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT0(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT0(u64 a) ++{ ++ return 0x700 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat1 ++ * ++ * CGX CMR Transmit Statistics Registers 1 ++ */ ++union cgxx_cmrx_tx_stat1 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat1_s { ++ u64 xsdef : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat1_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT1(u64 a) ++{ ++ return 0x708 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat10 ++ * ++ * CGX CMR Transmit Statistics Registers 10 ++ */ ++union cgxx_cmrx_tx_stat10 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat10_s { ++ u64 hist4 : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat10_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT10(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT10(u64 a) ++{ ++ return 0x750 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat11 ++ * ++ * CGX CMR Transmit Statistics Registers 11 ++ */ ++union cgxx_cmrx_tx_stat11 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat11_s { ++ u64 hist5 : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat11_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT11(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT11(u64 a) ++{ ++ return 0x758 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat12 ++ * ++ * CGX CMR Transmit Statistics Registers 12 ++ */ ++union cgxx_cmrx_tx_stat12 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat12_s { ++ u64 hist6 : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat12_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT12(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT12(u64 a) ++{ ++ return 0x760 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat13 ++ * ++ * CGX CMR Transmit Statistics Registers 13 ++ */ ++union cgxx_cmrx_tx_stat13 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat13_s { ++ u64 hist7 : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat13_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT13(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT13(u64 a) ++{ ++ return 0x768 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat14 ++ * ++ * CGX CMR Transmit Statistics Registers 14 ++ */ ++union cgxx_cmrx_tx_stat14 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat14_s { ++ u64 bcst : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat14_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT14(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT14(u64 a) ++{ ++ return 0x770 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat15 ++ * ++ * CGX CMR Transmit Statistics Registers 15 ++ */ ++union cgxx_cmrx_tx_stat15 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat15_s { ++ u64 mcst : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat15_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT15(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT15(u64 a) ++{ ++ return 0x778 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat16 ++ * ++ * CGX CMR Transmit Statistics Registers 16 ++ */ ++union cgxx_cmrx_tx_stat16 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat16_s { ++ u64 undflw : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat16_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT16(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT16(u64 a) ++{ ++ return 0x780 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat17 ++ * ++ * CGX CMR Transmit Statistics Registers 17 ++ */ ++union cgxx_cmrx_tx_stat17 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat17_s { ++ u64 ctl : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat17_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT17(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT17(u64 a) ++{ ++ return 0x788 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat2 ++ * ++ * CGX CMR Transmit Statistics Registers 2 ++ */ ++union cgxx_cmrx_tx_stat2 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat2_s { ++ u64 mcol : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat2_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT2(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT2(u64 a) ++{ ++ return 0x710 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat3 ++ * ++ * CGX CMR Transmit Statistics Registers 3 ++ */ ++union cgxx_cmrx_tx_stat3 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat3_s { ++ u64 scol : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat3_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT3(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT3(u64 a) ++{ ++ return 0x718 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat4 ++ * ++ * CGX CMR Transmit Statistics Registers 4 ++ */ ++union cgxx_cmrx_tx_stat4 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat4_s { ++ u64 octs : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat4_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT4(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT4(u64 a) ++{ ++ return 0x720 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat5 ++ * ++ * CGX CMR Transmit Statistics Registers 5 ++ */ ++union cgxx_cmrx_tx_stat5 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat5_s { ++ u64 pkts : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat5_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT5(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT5(u64 a) ++{ ++ return 0x728 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat6 ++ * ++ * CGX CMR Transmit Statistics Registers 6 ++ */ ++union cgxx_cmrx_tx_stat6 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat6_s { ++ u64 hist0 : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat6_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT6(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT6(u64 a) ++{ ++ return 0x730 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat7 ++ * ++ * CGX CMR Transmit Statistics Registers 7 ++ */ ++union cgxx_cmrx_tx_stat7 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat7_s { ++ u64 hist1 : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat7_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT7(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT7(u64 a) ++{ ++ return 0x738 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat8 ++ * ++ * CGX CMR Transmit Statistics Registers 8 ++ */ ++union cgxx_cmrx_tx_stat8 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat8_s { ++ u64 hist2 : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat8_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT8(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT8(u64 a) ++{ ++ return 0x740 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat9 ++ * ++ * CGX CMR Transmit Statistics Registers 9 ++ */ ++union cgxx_cmrx_tx_stat9 { ++ u64 u; ++ struct cgxx_cmrx_tx_stat9_s { ++ u64 hist3 : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat9_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT9(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT9(u64 a) ++{ ++ return 0x748 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr#_tx_stat_pri#_xoff ++ * ++ * CGX CMR TX XON to XOFF transition Registers ++ */ ++union cgxx_cmrx_tx_stat_prix_xoff { ++ u64 u; ++ struct cgxx_cmrx_tx_stat_prix_xoff_s { ++ u64 cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmrx_tx_stat_prix_xoff_s cn; */ ++}; ++ ++static inline u64 CGXX_CMRX_TX_STAT_PRIX_XOFF(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMRX_TX_STAT_PRIX_XOFF(u64 a, u64 b) ++{ ++ return 0x800 + 0x40000 * a + 8 * b; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_bad ++ * ++ * CGX CMR Bad Registers ++ */ ++union cgxx_cmr_bad { ++ u64 u; ++ struct cgxx_cmr_bad_s { ++ u64 rxb_nxl : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_cmr_bad_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_BAD(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_BAD(void) ++{ ++ return 0x1020; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_chan_msk_and ++ * ++ * CGX CMR Backpressure Channel Mask AND Registers ++ */ ++union cgxx_cmr_chan_msk_and { ++ u64 u; ++ struct cgxx_cmr_chan_msk_and_s { ++ u64 msk_and : 64; ++ } s; ++ /* struct cgxx_cmr_chan_msk_and_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_CHAN_MSK_AND(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_CHAN_MSK_AND(void) ++{ ++ return 0x110; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_chan_msk_or ++ * ++ * CGX Backpressure Channel Mask OR Registers ++ */ ++union cgxx_cmr_chan_msk_or { ++ u64 u; ++ struct cgxx_cmr_chan_msk_or_s { ++ u64 msk_or : 64; ++ } s; ++ /* struct cgxx_cmr_chan_msk_or_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_CHAN_MSK_OR(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_CHAN_MSK_OR(void) ++{ ++ return 0x118; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_eco ++ * ++ * INTERNAL: CGX ECO Registers ++ */ ++union cgxx_cmr_eco { ++ u64 u; ++ struct cgxx_cmr_eco_s { ++ u64 eco_rw : 32; ++ u64 eco_ro : 32; ++ } s; ++ /* struct cgxx_cmr_eco_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_ECO(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_ECO(void) ++{ ++ return 0x1028; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_global_config ++ * ++ * CGX CMR Global Configuration Register These registers configure the ++ * global CMR, PCS, and MAC. ++ */ ++union cgxx_cmr_global_config { ++ u64 u; ++ struct cgxx_cmr_global_config_s { ++ u64 pmux_sds_sel : 1; ++ u64 cgx_clk_enable : 1; ++ u64 cmr_x2p_reset : 3; ++ u64 interleave_mode : 1; ++ u64 fcs_strip : 1; ++ u64 ncsi_lmac_id : 2; ++ u64 cmr_ncsi_drop : 1; ++ u64 cmr_ncsi_reset : 1; ++ u64 cmr_ncsi_tag_cnt : 13; ++ u64 cmr_clken_ovrd : 1; ++ u64 reserved_25_63 : 39; ++ } s; ++ /* struct cgxx_cmr_global_config_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_GLOBAL_CONFIG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_GLOBAL_CONFIG(void) ++{ ++ return 8; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_mem_int ++ * ++ * CGX CMR Memory Interrupt Register ++ */ ++union cgxx_cmr_mem_int { ++ u64 u; ++ struct cgxx_cmr_mem_int_s { ++ u64 gmp_in_overfl : 1; ++ u64 smu_in_overfl : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct cgxx_cmr_mem_int_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_MEM_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_MEM_INT(void) ++{ ++ return 0x10; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_mem_int_ena_w1c ++ * ++ * CGX CMR Memory Interrupt Enable Clear Register This register clears ++ * interrupt enable bits. ++ */ ++union cgxx_cmr_mem_int_ena_w1c { ++ u64 u; ++ struct cgxx_cmr_mem_int_ena_w1c_s { ++ u64 gmp_in_overfl : 1; ++ u64 smu_in_overfl : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct cgxx_cmr_mem_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_MEM_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_MEM_INT_ENA_W1C(void) ++{ ++ return 0x20; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_mem_int_ena_w1s ++ * ++ * CGX CMR Memory Interrupt Enable Set Register This register sets ++ * interrupt enable bits. ++ */ ++union cgxx_cmr_mem_int_ena_w1s { ++ u64 u; ++ struct cgxx_cmr_mem_int_ena_w1s_s { ++ u64 gmp_in_overfl : 1; ++ u64 smu_in_overfl : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct cgxx_cmr_mem_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_MEM_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_MEM_INT_ENA_W1S(void) ++{ ++ return 0x28; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_mem_int_w1s ++ * ++ * CGX CMR Memory Interrupt Set Register This register sets interrupt ++ * bits. ++ */ ++union cgxx_cmr_mem_int_w1s { ++ u64 u; ++ struct cgxx_cmr_mem_int_w1s_s { ++ u64 gmp_in_overfl : 1; ++ u64 smu_in_overfl : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct cgxx_cmr_mem_int_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_MEM_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_MEM_INT_W1S(void) ++{ ++ return 0x18; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_nic_nxc_adr ++ * ++ * CGX CMR NIC NXC Exception Registers ++ */ ++union cgxx_cmr_nic_nxc_adr { ++ u64 u; ++ struct cgxx_cmr_nic_nxc_adr_s { ++ u64 channel : 12; ++ u64 lmac_id : 4; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_cmr_nic_nxc_adr_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_NIC_NXC_ADR(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_NIC_NXC_ADR(void) ++{ ++ return 0x1030; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_nix0_nxc_adr ++ * ++ * CGX CMR NIX0 NXC Exception Registers ++ */ ++union cgxx_cmr_nix0_nxc_adr { ++ u64 u; ++ struct cgxx_cmr_nix0_nxc_adr_s { ++ u64 channel : 12; ++ u64 lmac_id : 4; ++ u64 channel_e : 12; ++ u64 lmac_e_id : 4; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct cgxx_cmr_nix0_nxc_adr_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_NIX0_NXC_ADR(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_NIX0_NXC_ADR(void) ++{ ++ return 0x1038; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_nix1_nxc_adr ++ * ++ * CGX CMR NIX1 NXC Exception Registers ++ */ ++union cgxx_cmr_nix1_nxc_adr { ++ u64 u; ++ struct cgxx_cmr_nix1_nxc_adr_s { ++ u64 channel : 12; ++ u64 lmac_id : 4; ++ u64 channel_e : 12; ++ u64 lmac_e_id : 4; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct cgxx_cmr_nix1_nxc_adr_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_NIX1_NXC_ADR(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_NIX1_NXC_ADR(void) ++{ ++ return 0x1040; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_p2x#_count ++ * ++ * CGX P2X Activity Register ++ */ ++union cgxx_cmr_p2xx_count { ++ u64 u; ++ struct cgxx_cmr_p2xx_count_s { ++ u64 p2x_cnt : 64; ++ } s; ++ /* struct cgxx_cmr_p2xx_count_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_P2XX_COUNT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_P2XX_COUNT(u64 a) ++{ ++ return 0x168 + 0x1000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_rx_dmac#_cam0 ++ * ++ * CGX CMR Receive CAM Registers These registers provide access to the 32 ++ * DMAC CAM0 entries in CGX, for use by X2P/NIX bound traffic. ++ */ ++union cgxx_cmr_rx_dmacx_cam0 { ++ u64 u; ++ struct cgxx_cmr_rx_dmacx_cam0_s { ++ u64 adr : 48; ++ u64 en : 1; ++ u64 id : 2; ++ u64 reserved_51_63 : 13; ++ } s; ++ /* struct cgxx_cmr_rx_dmacx_cam0_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_RX_DMACX_CAM0(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_RX_DMACX_CAM0(u64 a) ++{ ++ return 0x200 + 8 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_rx_dmac#_cam1 ++ * ++ * CGX CMR Receive CAM Registers These registers provide access to the 32 ++ * DMAC CAM entries in CGX for use by NCSI bound traffic. See ++ * CGX()_CMR_GLOBAL_CONFIG[NCSI_LMAC_ID] and CGX()_CMR_RX_STEERING1() ++ * registers. ++ */ ++union cgxx_cmr_rx_dmacx_cam1 { ++ u64 u; ++ struct cgxx_cmr_rx_dmacx_cam1_s { ++ u64 adr : 48; ++ u64 en : 1; ++ u64 id : 2; ++ u64 reserved_51_63 : 13; ++ } s; ++ /* struct cgxx_cmr_rx_dmacx_cam1_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_RX_DMACX_CAM1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_RX_DMACX_CAM1(u64 a) ++{ ++ return 0x400 + 8 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_rx_lmacs ++ * ++ * CGX CMR Receive Logical MACs Registers ++ */ ++union cgxx_cmr_rx_lmacs { ++ u64 u; ++ struct cgxx_cmr_rx_lmacs_s { ++ u64 lmacs : 3; ++ u64 reserved_3_63 : 61; ++ } s; ++ /* struct cgxx_cmr_rx_lmacs_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_RX_LMACS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_RX_LMACS(void) ++{ ++ return 0x128; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_rx_ovr_bp ++ * ++ * CGX CMR Receive-Ports Backpressure Override Registers Per-LMAC ++ * backpressure override register. For SMU, CGX()_CMR_RX_OVR_BP[EN]\<0\> ++ * must be set to one and CGX()_CMR_RX_OVR_BP[BP]\<0\> must be cleared to ++ * zero (to forcibly disable hardware-automatic 802.3 PAUSE packet ++ * generation) with the HiGig2 Protocol when ++ * CGX()_SMU()_HG2_CONTROL[HG2TX_EN]=0. (The HiGig2 protocol is indicated ++ * by CGX()_SMU()_TX_CTL[HG_EN]=1 and CGX()_SMU()_RX_UDD_SKP[LEN]=16). ++ * Hardware can only auto-generate backpressure through HiGig2 messages ++ * (optionally, when CGX()_SMU()_HG2_CONTROL[HG2TX_EN]=1) with the HiGig2 ++ * protocol. ++ */ ++union cgxx_cmr_rx_ovr_bp { ++ u64 u; ++ struct cgxx_cmr_rx_ovr_bp_s { ++ u64 ign_fifo_bp : 4; ++ u64 bp : 4; ++ u64 en : 4; ++ u64 reserved_12_63 : 52; ++ } s; ++ /* struct cgxx_cmr_rx_ovr_bp_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_RX_OVR_BP(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_RX_OVR_BP(void) ++{ ++ return 0x130; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_rx_stat10 ++ * ++ * CGX Receive Status Register 10 These registers provide a count of ++ * octets of filtered DMAC1 or VLAN STEERING1 packets. ++ */ ++union cgxx_cmr_rx_stat10 { ++ u64 u; ++ struct cgxx_cmr_rx_stat10_s { ++ u64 cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmr_rx_stat10_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_RX_STAT10(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_RX_STAT10(void) ++{ ++ return 0xc0; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_rx_stat11 ++ * ++ * CGX Receive Status Register 11 This registers provides a count of ++ * packets dropped at the NCSI interface. This includes drops due to ++ * CGX()_CMR_GLOBAL_CONFIG[CMR_NCSI_DROP] or NCSI FIFO full. The count of ++ * dropped NCSI packets is not accounted for in any other stats ++ * registers. ++ */ ++union cgxx_cmr_rx_stat11 { ++ u64 u; ++ struct cgxx_cmr_rx_stat11_s { ++ u64 cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmr_rx_stat11_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_RX_STAT11(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_RX_STAT11(void) ++{ ++ return 0xc8; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_rx_stat12 ++ * ++ * CGX Receive Status Register 12 This register provide a count of octets ++ * of dropped at the NCSI interface. ++ */ ++union cgxx_cmr_rx_stat12 { ++ u64 u; ++ struct cgxx_cmr_rx_stat12_s { ++ u64 cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmr_rx_stat12_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_RX_STAT12(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_RX_STAT12(void) ++{ ++ return 0xd0; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_rx_stat9 ++ * ++ * CGX Receive Status Register 9 These registers provide a count of all ++ * received packets that were dropped by the DMAC1 or VLAN STEERING1 ++ * filter. Packets that are dropped by the DMAC1 or VLAN STEERING1 ++ * filters are counted here regardless of whether they were ERR packets, ++ * but does not include those reported in CGX()_CMR()_RX_STAT6. 16B ++ * packets or smaller (20B in case of FCS strip) as the result of ++ * truncation or other means are not dropped by CGX (unless filter and ++ * decision is also asserted) and will never appear in this count. Should ++ * the MAC signal to the CMR that the packet be filtered upon decision ++ * before the end of packet, then STAT9 and STAT10 will not be updated. ++ */ ++union cgxx_cmr_rx_stat9 { ++ u64 u; ++ struct cgxx_cmr_rx_stat9_s { ++ u64 cnt : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_cmr_rx_stat9_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_RX_STAT9(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_RX_STAT9(void) ++{ ++ return 0xb8; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_rx_steering0# ++ * ++ * CGX CMR Receive Steering0 Registers These registers, along with ++ * CGX()_CMR_RX_STEERING_VETYPE0(), provide eight filters for identifying ++ * and steering receive traffic to X2P/NIX. Received packets are only ++ * passed to X2P/NIX when the DMAC0 filter result is ACCEPT and STEERING0 ++ * filter result is PASS. See also CGX()_CMR()_RX_DMAC_CTL0. Internal: ++ * "* ALGORITHM \ rx_steering(uint48 pkt_dmac, uint16 pkt_etype, ++ * uint16 pkt_vlan_id) { for (int i = 0; i \< 8; i++) { steer = ++ * CGX()_CMR_RX_STEERING0(i); vetype = ++ * CGX()_CMR_RX_STEERING_VETYPE0(i); if (steer[MCST_EN] || ++ * steer[DMAC_EN] || vetype[VLAN_EN] || vetype[VLAN_TAG_EN]) { ++ * // Filter is enabled. if ( (!steer[MCST_EN] || ++ * is_mcst(pkt_dmac)) && (!steer[DMAC_EN] || pkt_dmac == ++ * steer[DMAC]) && (!vetype[VLAN_EN] || pkt_vlan_id == ++ * vetype[VLAN_ID]) && (!vetype[VLAN_TAG_EN] || pkt_etype == ++ * vetype[VLAN_ETYPE]) ) { // Filter match (all ++ * enabled matching criteria are met). return steer[PASS]; ++ * } } } return CGX()_CMR_RX_STEERING_DEFAULT0[PASS]; // No ++ * match } \" ++ */ ++union cgxx_cmr_rx_steering0x { ++ u64 u; ++ struct cgxx_cmr_rx_steering0x_s { ++ u64 dmac : 48; ++ u64 dmac_en : 1; ++ u64 mcst_en : 1; ++ u64 pass : 1; ++ u64 reserved_51_63 : 13; ++ } s; ++ /* struct cgxx_cmr_rx_steering0x_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_RX_STEERING0X(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_RX_STEERING0X(u64 a) ++{ ++ return 0x300 + 8 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_rx_steering1# ++ * ++ * CGX CMR Receive Steering1 Registers These registers, along with ++ * CGX()_CMR_RX_STEERING_VETYPE1(), provide eight filters for identifying ++ * and steering NCSI receive traffic. Received packets are only passed to ++ * NCSI when the DMAC1 filter result is ACCEPT and STEERING1 filter ++ * result is PASS. See also CGX()_CMR_RX_DMAC()_CAM1 and ++ * CGX()_CMR_RX_STEERING1(). For use with the LMAC associated with NCSI. ++ * See CGX()_CMR_GLOBAL_CONFIG[NCSI_LMAC_ID]. Internal: ALGORITHM: See ++ * CGX()_CMR_RX_STEERING0(). ++ */ ++union cgxx_cmr_rx_steering1x { ++ u64 u; ++ struct cgxx_cmr_rx_steering1x_s { ++ u64 dmac : 48; ++ u64 dmac_en : 1; ++ u64 mcst_en : 1; ++ u64 pass : 1; ++ u64 reserved_51_63 : 13; ++ } s; ++ /* struct cgxx_cmr_rx_steering1x_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_RX_STEERING1X(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_RX_STEERING1X(u64 a) ++{ ++ return 0x500 + 8 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_rx_steering_default0 ++ * ++ * CGX CMR Receive Steering Default0 Destination Register For determining ++ * destination of traffic that does not meet matching algorithm described ++ * in registers CGX()_CMR_RX_STEERING0() and ++ * CGX()_CMR_RX_STEERING_VETYPE0(). All 16B packets or smaller (20B in ++ * case of FCS strip) as the result of truncation will steer to default ++ * destination ++ */ ++union cgxx_cmr_rx_steering_default0 { ++ u64 u; ++ struct cgxx_cmr_rx_steering_default0_s { ++ u64 pass : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_cmr_rx_steering_default0_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_RX_STEERING_DEFAULT0(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_RX_STEERING_DEFAULT0(void) ++{ ++ return 0x3f0; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_rx_steering_default1 ++ * ++ * CGX CMR Receive Steering Default1 Destination Register For use with ++ * the lmac_id associated with NCSI. See ++ * CGX()_CMR_GLOBAL_CONFIG[NCSI_LMAC_ID]. For determining destination of ++ * traffic that does not meet matching algorithm described in registers ++ * CGX()_CMR_RX_STEERING1() and CGX()_CMR_RX_STEERING_VETYPE1(). All 16B ++ * packets or smaller (20B in case of FCS strip) as the result of ++ * truncation will steer to default destination ++ */ ++union cgxx_cmr_rx_steering_default1 { ++ u64 u; ++ struct cgxx_cmr_rx_steering_default1_s { ++ u64 pass : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_cmr_rx_steering_default1_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_RX_STEERING_DEFAULT1(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_RX_STEERING_DEFAULT1(void) ++{ ++ return 0x5e0; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_rx_steering_vetype0# ++ * ++ * CGX CMR Receive VLAN Ethertype1 Register These registers, along with ++ * CGX()_CMR_RX_STEERING0(), provide eight filters for identifying and ++ * steering X2P/NIX receive traffic. ++ */ ++union cgxx_cmr_rx_steering_vetype0x { ++ u64 u; ++ struct cgxx_cmr_rx_steering_vetype0x_s { ++ u64 vlan_etype : 16; ++ u64 vlan_tag_en : 1; ++ u64 vlan_id : 12; ++ u64 vlan_en : 1; ++ u64 reserved_30_63 : 34; ++ } s; ++ /* struct cgxx_cmr_rx_steering_vetype0x_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_RX_STEERING_VETYPE0X(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_RX_STEERING_VETYPE0X(u64 a) ++{ ++ return 0x380 + 8 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_rx_steering_vetype1# ++ * ++ * CGX CMR Receive VLAN Ethertype1 Register For use with the lmac_id ++ * associated with NCSI. See CGX()_CMR_GLOBAL_CONFIG[NCSI_LMAC_ID]. These ++ * registers, along with CGX()_CMR_RX_STEERING1(), provide eight filters ++ * for identifying and steering NCSI receive traffic. ++ */ ++union cgxx_cmr_rx_steering_vetype1x { ++ u64 u; ++ struct cgxx_cmr_rx_steering_vetype1x_s { ++ u64 vlan_etype : 16; ++ u64 vlan_tag_en : 1; ++ u64 vlan_id : 12; ++ u64 vlan_en : 1; ++ u64 reserved_30_63 : 34; ++ } s; ++ /* struct cgxx_cmr_rx_steering_vetype1x_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_RX_STEERING_VETYPE1X(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_RX_STEERING_VETYPE1X(u64 a) ++{ ++ return 0x580 + 8 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_tx_lmacs ++ * ++ * CGX CMR Transmit Logical MACs Registers This register sets the number ++ * of LMACs allowed on the TX interface. The value is important for ++ * defining the partitioning of the transmit FIFO. ++ */ ++union cgxx_cmr_tx_lmacs { ++ u64 u; ++ struct cgxx_cmr_tx_lmacs_s { ++ u64 lmacs : 3; ++ u64 reserved_3_63 : 61; ++ } s; ++ /* struct cgxx_cmr_tx_lmacs_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_TX_LMACS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_TX_LMACS(void) ++{ ++ return 0x1000; ++} ++ ++/** ++ * Register (RSL) cgx#_cmr_x2p#_count ++ * ++ * CGX X2P Activity Register ++ */ ++union cgxx_cmr_x2px_count { ++ u64 u; ++ struct cgxx_cmr_x2px_count_s { ++ u64 x2p_cnt : 64; ++ } s; ++ /* struct cgxx_cmr_x2px_count_s cn; */ ++}; ++ ++static inline u64 CGXX_CMR_X2PX_COUNT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CMR_X2PX_COUNT(u64 a) ++{ ++ return 0x170 + 0x1000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_const ++ * ++ * CGX CONST Registers This register contains constants for software ++ * discovery. ++ */ ++union cgxx_const { ++ u64 u; ++ struct cgxx_const_s { ++ u64 tx_fifosz : 24; ++ u64 lmacs : 8; ++ u64 rx_fifosz : 24; ++ u64 reserved_56_63 : 8; ++ } s; ++ /* struct cgxx_const_s cn; */ ++}; ++ ++static inline u64 CGXX_CONST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CONST(void) ++{ ++ return 0x2000; ++} ++ ++/** ++ * Register (RSL) cgx#_const1 ++ * ++ * CGX CONST1 Registers This register contains constants for software ++ * discovery. ++ */ ++union cgxx_const1 { ++ u64 u; ++ struct cgxx_const1_s { ++ u64 types : 11; ++ u64 res_types : 21; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct cgxx_const1_s cn; */ ++}; ++ ++static inline u64 CGXX_CONST1(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_CONST1(void) ++{ ++ return 0x2008; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi#_rx_wol_ctrl0 ++ * ++ * CGX GMP GMI RX Wake-on-LAN Control 0 Registers ++ */ ++union cgxx_gmp_gmix_rx_wol_ctrl0 { ++ u64 u; ++ struct cgxx_gmp_gmix_rx_wol_ctrl0_s { ++ u64 dmac : 48; ++ u64 pswd_len : 4; ++ u64 reserved_52_63 : 12; ++ } s; ++ /* struct cgxx_gmp_gmix_rx_wol_ctrl0_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMIX_RX_WOL_CTRL0(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMIX_RX_WOL_CTRL0(u64 a) ++{ ++ return 0x38a00 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi#_rx_wol_ctrl1 ++ * ++ * CGX GMP GMI RX Wake-on-LAN Control 1 Registers ++ */ ++union cgxx_gmp_gmix_rx_wol_ctrl1 { ++ u64 u; ++ struct cgxx_gmp_gmix_rx_wol_ctrl1_s { ++ u64 pswd : 64; ++ } s; ++ /* struct cgxx_gmp_gmix_rx_wol_ctrl1_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMIX_RX_WOL_CTRL1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMIX_RX_WOL_CTRL1(u64 a) ++{ ++ return 0x38a08 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi#_tx_eee ++ * ++ * INTERNAL: CGX GMP GMI TX EEE Configure Registers Reserved. Internal: ++ * These registers control when GMP GMI TX requests to enter or exist ++ * LPI. Those registers take effect only when EEE is supported and ++ * enabled for a given LMAC. ++ */ ++union cgxx_gmp_gmix_tx_eee { ++ u64 u; ++ struct cgxx_gmp_gmix_tx_eee_s { ++ u64 idle_thresh : 28; ++ u64 reserved_28 : 1; ++ u64 force_lpi : 1; ++ u64 wakeup : 1; ++ u64 auto_lpi : 1; ++ u64 idle_cnt : 28; ++ u64 tx_lpi : 1; ++ u64 tx_lpi_wait : 1; ++ u64 sync_status_lpi_enable : 1; ++ u64 reserved_63 : 1; ++ } s; ++ /* struct cgxx_gmp_gmix_tx_eee_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMIX_TX_EEE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMIX_TX_EEE(u64 a) ++{ ++ return 0x38800 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi#_tx_eee_cfg1 ++ * ++ * INTERNAL: CGX GMP GMI TX EEE Configure More Configuration Registers ++ * Reserved. Internal: Controls the GMP exiting of LPI and starting to ++ * send data. ++ */ ++union cgxx_gmp_gmix_tx_eee_cfg1 { ++ u64 u; ++ struct cgxx_gmp_gmix_tx_eee_cfg1_s { ++ u64 wake2data_time : 24; ++ u64 reserved_24_35 : 12; ++ u64 tx_eee_enable : 1; ++ u64 reserved_37_39 : 3; ++ u64 sync2lpi_time : 21; ++ u64 reserved_61_63 : 3; ++ } s; ++ struct cgxx_gmp_gmix_tx_eee_cfg1_cn { ++ u64 wake2data_time : 24; ++ u64 reserved_24_31 : 8; ++ u64 reserved_32_35 : 4; ++ u64 tx_eee_enable : 1; ++ u64 reserved_37_39 : 3; ++ u64 sync2lpi_time : 21; ++ u64 reserved_61_63 : 3; ++ } cn; ++}; ++ ++static inline u64 CGXX_GMP_GMIX_TX_EEE_CFG1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMIX_TX_EEE_CFG1(u64 a) ++{ ++ return 0x38808 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi#_wol_int ++ * ++ * CGX GMP GMI RX WOL Interrupt Registers These registers allow WOL ++ * interrupts to be sent to the control processor. ++ */ ++union cgxx_gmp_gmix_wol_int { ++ u64 u; ++ struct cgxx_gmp_gmix_wol_int_s { ++ u64 wol_rcvd : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_gmp_gmix_wol_int_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMIX_WOL_INT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMIX_WOL_INT(u64 a) ++{ ++ return 0x38a80 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi#_wol_int_ena_w1c ++ * ++ * CGX GMP GMI RX WOL Interrupt Enable Clear Registers This register ++ * clears interrupt enable bits. ++ */ ++union cgxx_gmp_gmix_wol_int_ena_w1c { ++ u64 u; ++ struct cgxx_gmp_gmix_wol_int_ena_w1c_s { ++ u64 wol_rcvd : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_gmp_gmix_wol_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMIX_WOL_INT_ENA_W1C(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMIX_WOL_INT_ENA_W1C(u64 a) ++{ ++ return 0x38a90 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi#_wol_int_ena_w1s ++ * ++ * CGX GMP GMI RX WOL Interrupt Enable Set Registers This register sets ++ * interrupt enable bits. ++ */ ++union cgxx_gmp_gmix_wol_int_ena_w1s { ++ u64 u; ++ struct cgxx_gmp_gmix_wol_int_ena_w1s_s { ++ u64 wol_rcvd : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_gmp_gmix_wol_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMIX_WOL_INT_ENA_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMIX_WOL_INT_ENA_W1S(u64 a) ++{ ++ return 0x38a98 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi#_wol_int_w1s ++ * ++ * CGX GMP GMI RX WOL Interrupt Set Registers This register sets ++ * interrupt bits. ++ */ ++union cgxx_gmp_gmix_wol_int_w1s { ++ u64 u; ++ struct cgxx_gmp_gmix_wol_int_w1s_s { ++ u64 wol_rcvd : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_gmp_gmix_wol_int_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMIX_WOL_INT_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMIX_WOL_INT_W1S(u64 a) ++{ ++ return 0x38a88 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_prt#_cfg ++ * ++ * CGX GMP GMI LMAC Configuration Registers This register controls the ++ * configuration of the LMAC. ++ */ ++union cgxx_gmp_gmi_prtx_cfg { ++ u64 u; ++ struct cgxx_gmp_gmi_prtx_cfg_s { ++ u64 reserved_0 : 1; ++ u64 speed : 1; ++ u64 duplex : 1; ++ u64 slottime : 1; ++ u64 reserved_4_7 : 4; ++ u64 speed_msb : 1; ++ u64 reserved_9_11 : 3; ++ u64 rx_idle : 1; ++ u64 tx_idle : 1; ++ u64 reserved_14_63 : 50; ++ } s; ++ /* struct cgxx_gmp_gmi_prtx_cfg_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_PRTX_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_PRTX_CFG(u64 a) ++{ ++ return 0x38020 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_rx#_decision ++ * ++ * CGX GMP Packet-Decision Registers This register specifies the byte ++ * count used to determine when to accept or to filter a packet. As each ++ * byte in a packet is received by GMI, the L2 byte count is compared ++ * against [CNT]. In normal operation, the L2 header begins after the ++ * PREAMBLE + SFD (CGX()_GMP_GMI_RX()_FRM_CTL[PRE_CHK] = 1) and any ++ * optional UDD skip data (CGX()_GMP_GMI_RX()_UDD_SKP[LEN]). Internal: ++ * Notes: As each byte in a packet is received by GMI, the L2 byte count ++ * is compared against the [CNT]. The L2 byte count is the number of ++ * bytes from the beginning of the L2 header (DMAC). In normal ++ * operation, the L2 header begins after the PREAMBLE+SFD ++ * (CGX()_GMP_GMI_RX()_FRM_CTL[PRE_CHK]=1) and any optional UDD skip data ++ * (CGX()_GMP_GMI_RX()_UDD_SKP[LEN]). When ++ * CGX()_GMP_GMI_RX()_FRM_CTL[PRE_CHK] is clear, PREAMBLE+SFD are ++ * prepended to the packet and would require UDD skip length to account ++ * for them. Full Duplex: _ L2 Size \< [CNT] - Accept packet. No ++ * filtering is applied. _ L2 Size \>= [CNT] - Apply filter. Accept ++ * packet based on PAUSE packet filter. Half Duplex: _ L2 Size \< ++ * [CNT] - Drop packet. Packet is unconditionally dropped. _ L2 Size ++ * \>= [CNT] - Accept packet. where L2_size = MAX(0, total_packet_size - ++ * CGX()_GMP_GMI_RX()_UDD_SKP[LEN] - ++ * ((CGX()_GMP_GMI_RX()_FRM_CTL[PRE_CHK]==1)*8)). ++ */ ++union cgxx_gmp_gmi_rxx_decision { ++ u64 u; ++ struct cgxx_gmp_gmi_rxx_decision_s { ++ u64 cnt : 5; ++ u64 reserved_5_63 : 59; ++ } s; ++ /* struct cgxx_gmp_gmi_rxx_decision_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_RXX_DECISION(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_RXX_DECISION(u64 a) ++{ ++ return 0x38040 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_rx#_frm_chk ++ * ++ * CGX GMP Frame Check Registers ++ */ ++union cgxx_gmp_gmi_rxx_frm_chk { ++ u64 u; ++ struct cgxx_gmp_gmi_rxx_frm_chk_s { ++ u64 minerr : 1; ++ u64 carext : 1; ++ u64 reserved_2 : 1; ++ u64 jabber : 1; ++ u64 fcserr : 1; ++ u64 reserved_5_6 : 2; ++ u64 rcverr : 1; ++ u64 skperr : 1; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct cgxx_gmp_gmi_rxx_frm_chk_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_RXX_FRM_CHK(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_RXX_FRM_CHK(u64 a) ++{ ++ return 0x38030 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_rx#_frm_ctl ++ * ++ * CGX GMP Frame Control Registers This register controls the handling of ++ * the frames. The [CTL_BCK] and [CTL_DRP] bits control how the hardware ++ * handles incoming PAUSE packets. The most common modes of operation: _ ++ * [CTL_BCK] = 1, [CTL_DRP] = 1: hardware handles everything. _ [CTL_BCK] ++ * = 0, [CTL_DRP] = 0: software sees all PAUSE frames. _ [CTL_BCK] = 0, ++ * [CTL_DRP] = 1: all PAUSE frames are completely ignored. These control ++ * bits should be set to [CTL_BCK] = 0, [CTL_DRP] = 0 in half-duplex ++ * mode. Since PAUSE packets only apply to full duplex operation, any ++ * PAUSE packet would constitute an exception which should be handled by ++ * the processing cores. PAUSE packets should not be forwarded. ++ * Internal: Notes: [PRE_STRP]: When [PRE_CHK] is set (indicating that ++ * the PREAMBLE will be sent), [PRE_STRP] determines if the PREAMBLE+SFD ++ * bytes are thrown away or sent to the Octane core as part of the ++ * packet. In either mode, the PREAMBLE+SFD bytes are not counted toward ++ * the packet size when checking against the MIN and MAX bounds. ++ * Furthermore, the bytes are skipped when locating the start of the L2 ++ * header for DMAC and Control frame recognition. ++ */ ++union cgxx_gmp_gmi_rxx_frm_ctl { ++ u64 u; ++ struct cgxx_gmp_gmi_rxx_frm_ctl_s { ++ u64 pre_chk : 1; ++ u64 pre_strp : 1; ++ u64 ctl_drp : 1; ++ u64 ctl_bck : 1; ++ u64 ctl_mcst : 1; ++ u64 ctl_smac : 1; ++ u64 pre_free : 1; ++ u64 reserved_7_8 : 2; ++ u64 pre_align : 1; ++ u64 null_dis : 1; ++ u64 reserved_11 : 1; ++ u64 ptp_mode : 1; ++ u64 rx_fc_type : 1; ++ u64 reserved_14_63 : 50; ++ } s; ++ struct cgxx_gmp_gmi_rxx_frm_ctl_cn { ++ u64 pre_chk : 1; ++ u64 pre_strp : 1; ++ u64 ctl_drp : 1; ++ u64 ctl_bck : 1; ++ u64 ctl_mcst : 1; ++ u64 ctl_smac : 1; ++ u64 pre_free : 1; ++ u64 reserved_7 : 1; ++ u64 reserved_8 : 1; ++ u64 pre_align : 1; ++ u64 null_dis : 1; ++ u64 reserved_11 : 1; ++ u64 ptp_mode : 1; ++ u64 rx_fc_type : 1; ++ u64 reserved_14_63 : 50; ++ } cn; ++}; ++ ++static inline u64 CGXX_GMP_GMI_RXX_FRM_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_RXX_FRM_CTL(u64 a) ++{ ++ return 0x38028 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_rx#_ifg ++ * ++ * CGX GMI Minimum Interframe-Gap Cycles Registers This register ++ * specifies the minimum number of interframe-gap (IFG) cycles between ++ * packets. ++ */ ++union cgxx_gmp_gmi_rxx_ifg { ++ u64 u; ++ struct cgxx_gmp_gmi_rxx_ifg_s { ++ u64 ifg : 4; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct cgxx_gmp_gmi_rxx_ifg_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_RXX_IFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_RXX_IFG(u64 a) ++{ ++ return 0x38058 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_rx#_int ++ * ++ * CGX GMP GMI RX Interrupt Registers These registers allow interrupts to ++ * be sent to the control processor. * Exception conditions \<10:0\> can ++ * also set the rcv/opcode in the received packet's work-queue entry. ++ * CGX()_GMP_GMI_RX()_FRM_CHK provides a bit mask for configuring which ++ * conditions set the error. In half duplex operation, the expectation is ++ * that collisions will appear as either MINERR or CAREXT errors. ++ * Internal: Notes: (1) exception conditions 10:0 can also set the ++ * rcv/opcode in the received packet's workQ entry. The ++ * CGX()_GMP_GMI_RX()_FRM_CHK register provides a bit mask for ++ * configuring which conditions set the error. (2) in half duplex ++ * operation, the expectation is that collisions will appear as either ++ * MINERR o r CAREXT errors. (3) JABBER An RX jabber error indicates ++ * that a packet was received which is longer than the maximum allowed ++ * packet as defined by the system. GMI will truncate the packet at the ++ * JABBER count. Failure to do so could lead to system instabilty. (4) ++ * NIBERR This error is illegal at 1000Mbs speeds ++ * (CGX()_GMP_GMI_PRT()_CFG[SPEED]==0) and will never assert. (5) MINERR ++ * total frame DA+SA+TL+DATA+PAD+FCS \< 64 (6) ALNERR Indicates that the ++ * packet received was not an integer number of bytes. If FCS checking ++ * is enabled, ALNERR will only assert if the FCS is bad. If FCS ++ * checking is disabled, ALNERR will assert in all non-integer frame ++ * cases. (7) Collisions Collisions can only occur in half-duplex mode. ++ * A collision is assumed by the receiver when the slottime ++ * (CGX()_GMP_GMI_PRT()_CFG[SLOTTIME]) is not satisfied. In 10/100 mode, ++ * this will result in a frame \< SLOTTIME. In 1000 mode, it could ++ * result either in frame \< SLOTTIME or a carrier extend error with the ++ * SLOTTIME. These conditions are visible by... . transfer ended before ++ * slottime COLDET . carrier extend error CAREXT (A) LENERR ++ * Length errors occur when the received packet does not match the length ++ * field. LENERR is only checked for packets between 64 and 1500 bytes. ++ * For untagged frames, the length must exact match. For tagged frames ++ * the length or length+4 must match. (B) PCTERR checks that the frame ++ * begins with a valid PREAMBLE sequence. Does not check the number of ++ * PREAMBLE cycles. (C) OVRERR *DON'T PUT IN HRM* OVRERR is an ++ * architectural assertion check internal to GMI to make sure no ++ * assumption was violated. In a correctly operating system, this ++ * interrupt can never fire. GMI has an internal arbiter which selects ++ * which of four ports to buffer in the main RX FIFO. If we normally ++ * buffer eight bytes, then each port will typically push a tick every ++ * eight cycles if the packet interface is going as fast as possible. If ++ * there are four ports, they push every two cycles. So that's the ++ * assumption. That the inbound module will always be able to consume ++ * the tick before another is produced. If that doesn't happen that's ++ * when OVRERR will assert." ++ */ ++union cgxx_gmp_gmi_rxx_int { ++ u64 u; ++ struct cgxx_gmp_gmi_rxx_int_s { ++ u64 minerr : 1; ++ u64 carext : 1; ++ u64 jabber : 1; ++ u64 fcserr : 1; ++ u64 rcverr : 1; ++ u64 skperr : 1; ++ u64 ovrerr : 1; ++ u64 pcterr : 1; ++ u64 rsverr : 1; ++ u64 falerr : 1; ++ u64 coldet : 1; ++ u64 ifgerr : 1; ++ u64 reserved_12_63 : 52; ++ } s; ++ struct cgxx_gmp_gmi_rxx_int_cn { ++ u64 minerr : 1; ++ u64 carext : 1; ++ u64 jabber : 1; ++ u64 fcserr : 1; ++ u64 rcverr : 1; ++ u64 skperr : 1; ++ u64 ovrerr : 1; ++ u64 pcterr : 1; ++ u64 rsverr : 1; ++ u64 falerr : 1; ++ u64 coldet : 1; ++ u64 ifgerr : 1; ++ u64 reserved_12_15 : 4; ++ u64 reserved_16_63 : 48; ++ } cn; ++}; ++ ++static inline u64 CGXX_GMP_GMI_RXX_INT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_RXX_INT(u64 a) ++{ ++ return 0x38000 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_rx#_int_ena_w1c ++ * ++ * CGX GMP GMI RX Interrupt Enable Clear Registers This register clears ++ * interrupt enable bits. ++ */ ++union cgxx_gmp_gmi_rxx_int_ena_w1c { ++ u64 u; ++ struct cgxx_gmp_gmi_rxx_int_ena_w1c_s { ++ u64 minerr : 1; ++ u64 carext : 1; ++ u64 jabber : 1; ++ u64 fcserr : 1; ++ u64 rcverr : 1; ++ u64 skperr : 1; ++ u64 ovrerr : 1; ++ u64 pcterr : 1; ++ u64 rsverr : 1; ++ u64 falerr : 1; ++ u64 coldet : 1; ++ u64 ifgerr : 1; ++ u64 reserved_12_63 : 52; ++ } s; ++ struct cgxx_gmp_gmi_rxx_int_ena_w1c_cn { ++ u64 minerr : 1; ++ u64 carext : 1; ++ u64 jabber : 1; ++ u64 fcserr : 1; ++ u64 rcverr : 1; ++ u64 skperr : 1; ++ u64 ovrerr : 1; ++ u64 pcterr : 1; ++ u64 rsverr : 1; ++ u64 falerr : 1; ++ u64 coldet : 1; ++ u64 ifgerr : 1; ++ u64 reserved_12_15 : 4; ++ u64 reserved_16_63 : 48; ++ } cn; ++}; ++ ++static inline u64 CGXX_GMP_GMI_RXX_INT_ENA_W1C(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_RXX_INT_ENA_W1C(u64 a) ++{ ++ return 0x38010 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_rx#_int_ena_w1s ++ * ++ * CGX GMP GMI RX Interrupt Enable Set Registers This register sets ++ * interrupt enable bits. ++ */ ++union cgxx_gmp_gmi_rxx_int_ena_w1s { ++ u64 u; ++ struct cgxx_gmp_gmi_rxx_int_ena_w1s_s { ++ u64 minerr : 1; ++ u64 carext : 1; ++ u64 jabber : 1; ++ u64 fcserr : 1; ++ u64 rcverr : 1; ++ u64 skperr : 1; ++ u64 ovrerr : 1; ++ u64 pcterr : 1; ++ u64 rsverr : 1; ++ u64 falerr : 1; ++ u64 coldet : 1; ++ u64 ifgerr : 1; ++ u64 reserved_12_63 : 52; ++ } s; ++ struct cgxx_gmp_gmi_rxx_int_ena_w1s_cn { ++ u64 minerr : 1; ++ u64 carext : 1; ++ u64 jabber : 1; ++ u64 fcserr : 1; ++ u64 rcverr : 1; ++ u64 skperr : 1; ++ u64 ovrerr : 1; ++ u64 pcterr : 1; ++ u64 rsverr : 1; ++ u64 falerr : 1; ++ u64 coldet : 1; ++ u64 ifgerr : 1; ++ u64 reserved_12_15 : 4; ++ u64 reserved_16_63 : 48; ++ } cn; ++}; ++ ++static inline u64 CGXX_GMP_GMI_RXX_INT_ENA_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_RXX_INT_ENA_W1S(u64 a) ++{ ++ return 0x38018 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_rx#_int_w1s ++ * ++ * CGX GMP GMI RX Interrupt Set Registers This register sets interrupt ++ * bits. ++ */ ++union cgxx_gmp_gmi_rxx_int_w1s { ++ u64 u; ++ struct cgxx_gmp_gmi_rxx_int_w1s_s { ++ u64 minerr : 1; ++ u64 carext : 1; ++ u64 jabber : 1; ++ u64 fcserr : 1; ++ u64 rcverr : 1; ++ u64 skperr : 1; ++ u64 ovrerr : 1; ++ u64 pcterr : 1; ++ u64 rsverr : 1; ++ u64 falerr : 1; ++ u64 coldet : 1; ++ u64 ifgerr : 1; ++ u64 reserved_12_63 : 52; ++ } s; ++ struct cgxx_gmp_gmi_rxx_int_w1s_cn { ++ u64 minerr : 1; ++ u64 carext : 1; ++ u64 jabber : 1; ++ u64 fcserr : 1; ++ u64 rcverr : 1; ++ u64 skperr : 1; ++ u64 ovrerr : 1; ++ u64 pcterr : 1; ++ u64 rsverr : 1; ++ u64 falerr : 1; ++ u64 coldet : 1; ++ u64 ifgerr : 1; ++ u64 reserved_12_15 : 4; ++ u64 reserved_16_63 : 48; ++ } cn; ++}; ++ ++static inline u64 CGXX_GMP_GMI_RXX_INT_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_RXX_INT_W1S(u64 a) ++{ ++ return 0x38008 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_rx#_jabber ++ * ++ * CGX GMP Maximum Packet-Size Registers This register specifies the ++ * maximum size for packets, beyond which the GMI truncates. ++ */ ++union cgxx_gmp_gmi_rxx_jabber { ++ u64 u; ++ struct cgxx_gmp_gmi_rxx_jabber_s { ++ u64 cnt : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_gmi_rxx_jabber_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_RXX_JABBER(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_RXX_JABBER(u64 a) ++{ ++ return 0x38038 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_rx#_udd_skp ++ * ++ * CGX GMP GMI User-Defined Data Skip Registers This register specifies ++ * the amount of user-defined data (UDD) added before the start of the ++ * L2C data. Internal: Notes: (1) The skip bytes are part of the packet ++ * and will be handled by NIX. (2) The system can determine if the UDD ++ * bytes are included in the FCS check by using the FCSSEL field - if the ++ * FCS check is enabled. (3) Assume that the preamble/sfd is always at ++ * the start of the frame - even before UDD bytes. In most cases, there ++ * will be no preamble in these cases since it will be packet interface ++ * in direct communication to another packet interface (MAC to MAC) ++ * without a PHY involved. (4) We can still do address filtering and ++ * control packet filtering is the user desires. (5) ++ * CGX()_GMP_GMI_RX()_UDD_SKP[LEN] must be 0 in half-duplex operation ++ * unless CGX()_GMP_GMI_RX()_FRM_CTL[PRE_CHK] is clear. If ++ * CGX()_GMP_GMI_RX()_FRM_CTL[PRE_CHK] is clear, then ++ * CGX()_GMP_GMI_RX()_UDD_SKP[LEN] will normally be 8. (6) In all cases, ++ * the UDD bytes will be sent down the packet interface as part of the ++ * packet. The UDD bytes are never stripped from the actual packet. ++ */ ++union cgxx_gmp_gmi_rxx_udd_skp { ++ u64 u; ++ struct cgxx_gmp_gmi_rxx_udd_skp_s { ++ u64 len : 7; ++ u64 reserved_7 : 1; ++ u64 fcssel : 1; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct cgxx_gmp_gmi_rxx_udd_skp_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_RXX_UDD_SKP(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_RXX_UDD_SKP(u64 a) ++{ ++ return 0x38048 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_smac# ++ * ++ * CGX GMI SMAC Registers ++ */ ++union cgxx_gmp_gmi_smacx { ++ u64 u; ++ struct cgxx_gmp_gmi_smacx_s { ++ u64 smac : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_gmp_gmi_smacx_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_SMACX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_SMACX(u64 a) ++{ ++ return 0x38230 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx#_append ++ * ++ * CGX GMI TX Append Control Registers ++ */ ++union cgxx_gmp_gmi_txx_append { ++ u64 u; ++ struct cgxx_gmp_gmi_txx_append_s { ++ u64 preamble : 1; ++ u64 pad : 1; ++ u64 fcs : 1; ++ u64 force_fcs : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct cgxx_gmp_gmi_txx_append_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TXX_APPEND(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TXX_APPEND(u64 a) ++{ ++ return 0x38218 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx#_burst ++ * ++ * CGX GMI TX Burst-Counter Registers ++ */ ++union cgxx_gmp_gmi_txx_burst { ++ u64 u; ++ struct cgxx_gmp_gmi_txx_burst_s { ++ u64 burst : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_gmi_txx_burst_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TXX_BURST(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TXX_BURST(u64 a) ++{ ++ return 0x38228 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx#_ctl ++ * ++ * CGX GMI Transmit Control Registers ++ */ ++union cgxx_gmp_gmi_txx_ctl { ++ u64 u; ++ struct cgxx_gmp_gmi_txx_ctl_s { ++ u64 xscol_en : 1; ++ u64 xsdef_en : 1; ++ u64 tx_fc_type : 1; ++ u64 link_drain : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct cgxx_gmp_gmi_txx_ctl_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TXX_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TXX_CTL(u64 a) ++{ ++ return 0x38270 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx#_int ++ * ++ * CGX GMI TX Interrupt Registers ++ */ ++union cgxx_gmp_gmi_txx_int { ++ u64 u; ++ struct cgxx_gmp_gmi_txx_int_s { ++ u64 undflw : 1; ++ u64 xscol : 1; ++ u64 xsdef : 1; ++ u64 late_col : 1; ++ u64 ptp_lost : 1; ++ u64 reserved_5_63 : 59; ++ } s; ++ struct cgxx_gmp_gmi_txx_int_cn { ++ u64 undflw : 1; ++ u64 xscol : 1; ++ u64 xsdef : 1; ++ u64 late_col : 1; ++ u64 ptp_lost : 1; ++ u64 reserved_5_7 : 3; ++ u64 reserved_8 : 1; ++ u64 reserved_9_63 : 55; ++ } cn; ++}; ++ ++static inline u64 CGXX_GMP_GMI_TXX_INT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TXX_INT(u64 a) ++{ ++ return 0x38500 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx#_int_ena_w1c ++ * ++ * CGX GMI TX Interrupt Enable Clear Registers This register clears ++ * interrupt enable bits. ++ */ ++union cgxx_gmp_gmi_txx_int_ena_w1c { ++ u64 u; ++ struct cgxx_gmp_gmi_txx_int_ena_w1c_s { ++ u64 undflw : 1; ++ u64 xscol : 1; ++ u64 xsdef : 1; ++ u64 late_col : 1; ++ u64 ptp_lost : 1; ++ u64 reserved_5_63 : 59; ++ } s; ++ struct cgxx_gmp_gmi_txx_int_ena_w1c_cn { ++ u64 undflw : 1; ++ u64 xscol : 1; ++ u64 xsdef : 1; ++ u64 late_col : 1; ++ u64 ptp_lost : 1; ++ u64 reserved_5_7 : 3; ++ u64 reserved_8 : 1; ++ u64 reserved_9_63 : 55; ++ } cn; ++}; ++ ++static inline u64 CGXX_GMP_GMI_TXX_INT_ENA_W1C(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TXX_INT_ENA_W1C(u64 a) ++{ ++ return 0x38510 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx#_int_ena_w1s ++ * ++ * CGX GMI TX Interrupt Enable Set Registers This register sets interrupt ++ * enable bits. ++ */ ++union cgxx_gmp_gmi_txx_int_ena_w1s { ++ u64 u; ++ struct cgxx_gmp_gmi_txx_int_ena_w1s_s { ++ u64 undflw : 1; ++ u64 xscol : 1; ++ u64 xsdef : 1; ++ u64 late_col : 1; ++ u64 ptp_lost : 1; ++ u64 reserved_5_63 : 59; ++ } s; ++ struct cgxx_gmp_gmi_txx_int_ena_w1s_cn { ++ u64 undflw : 1; ++ u64 xscol : 1; ++ u64 xsdef : 1; ++ u64 late_col : 1; ++ u64 ptp_lost : 1; ++ u64 reserved_5_7 : 3; ++ u64 reserved_8 : 1; ++ u64 reserved_9_63 : 55; ++ } cn; ++}; ++ ++static inline u64 CGXX_GMP_GMI_TXX_INT_ENA_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TXX_INT_ENA_W1S(u64 a) ++{ ++ return 0x38518 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx#_int_w1s ++ * ++ * CGX GMI TX Interrupt Set Registers This register sets interrupt bits. ++ */ ++union cgxx_gmp_gmi_txx_int_w1s { ++ u64 u; ++ struct cgxx_gmp_gmi_txx_int_w1s_s { ++ u64 undflw : 1; ++ u64 xscol : 1; ++ u64 xsdef : 1; ++ u64 late_col : 1; ++ u64 ptp_lost : 1; ++ u64 reserved_5_63 : 59; ++ } s; ++ struct cgxx_gmp_gmi_txx_int_w1s_cn { ++ u64 undflw : 1; ++ u64 xscol : 1; ++ u64 xsdef : 1; ++ u64 late_col : 1; ++ u64 ptp_lost : 1; ++ u64 reserved_5_7 : 3; ++ u64 reserved_8 : 1; ++ u64 reserved_9_63 : 55; ++ } cn; ++}; ++ ++static inline u64 CGXX_GMP_GMI_TXX_INT_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TXX_INT_W1S(u64 a) ++{ ++ return 0x38508 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx#_min_pkt ++ * ++ * CGX GMI TX Minimum-Size-Packet Registers ++ */ ++union cgxx_gmp_gmi_txx_min_pkt { ++ u64 u; ++ struct cgxx_gmp_gmi_txx_min_pkt_s { ++ u64 min_size : 8; ++ u64 reserved_8_63 : 56; ++ } s; ++ /* struct cgxx_gmp_gmi_txx_min_pkt_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TXX_MIN_PKT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TXX_MIN_PKT(u64 a) ++{ ++ return 0x38240 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx#_pause_pkt_interval ++ * ++ * CGX GMI TX PAUSE-Packet Transmission-Interval Registers This register ++ * specifies how often PAUSE packets are sent. Internal: Notes: Choosing ++ * proper values of CGX()_GMP_GMI_TX()_PAUSE_PKT_TIME[PTIME] and ++ * CGX()_GMP_GMI_TX()_PAUSE_PKT_INTERVAL[INTERVAL] can be challenging to ++ * the system designer. It is suggested that TIME be much greater than ++ * INTERVAL and CGX()_GMP_GMI_TX()_PAUSE_ZERO[SEND] be set. This allows ++ * a periodic refresh of the PAUSE count and then when the backpressure ++ * condition is lifted, a PAUSE packet with TIME==0 will be sent ++ * indicating that Octane is ready for additional data. If the system ++ * chooses to not set CGX()_GMP_GMI_TX()_PAUSE_ZERO[SEND], then it is ++ * suggested that TIME and INTERVAL are programmed such that they ++ * satisify the following rule: _ INTERVAL \<= TIME - (largest_pkt_size ++ * + IFG + pause_pkt_size) where largest_pkt_size is that largest packet ++ * that the system can send (normally 1518B), IFG is the interframe gap ++ * and pause_pkt_size is the size of the PAUSE packet (normally 64B). ++ */ ++union cgxx_gmp_gmi_txx_pause_pkt_interval { ++ u64 u; ++ struct cgxx_gmp_gmi_txx_pause_pkt_interval_s { ++ u64 interval : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_gmi_txx_pause_pkt_interval_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TXX_PAUSE_PKT_INTERVAL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TXX_PAUSE_PKT_INTERVAL(u64 a) ++{ ++ return 0x38248 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx#_pause_pkt_time ++ * ++ * CGX GMI TX PAUSE Packet PAUSE-Time Registers ++ */ ++union cgxx_gmp_gmi_txx_pause_pkt_time { ++ u64 u; ++ struct cgxx_gmp_gmi_txx_pause_pkt_time_s { ++ u64 ptime : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_gmi_txx_pause_pkt_time_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TXX_PAUSE_PKT_TIME(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TXX_PAUSE_PKT_TIME(u64 a) ++{ ++ return 0x38238 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx#_pause_togo ++ * ++ * CGX GMI TX Time-to-Backpressure Registers ++ */ ++union cgxx_gmp_gmi_txx_pause_togo { ++ u64 u; ++ struct cgxx_gmp_gmi_txx_pause_togo_s { ++ u64 ptime : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_gmi_txx_pause_togo_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TXX_PAUSE_TOGO(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TXX_PAUSE_TOGO(u64 a) ++{ ++ return 0x38258 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx#_pause_zero ++ * ++ * CGX GMI TX PAUSE-Zero-Enable Registers ++ */ ++union cgxx_gmp_gmi_txx_pause_zero { ++ u64 u; ++ struct cgxx_gmp_gmi_txx_pause_zero_s { ++ u64 send : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_gmp_gmi_txx_pause_zero_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TXX_PAUSE_ZERO(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TXX_PAUSE_ZERO(u64 a) ++{ ++ return 0x38260 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx#_sgmii_ctl ++ * ++ * CGX SGMII Control Registers ++ */ ++union cgxx_gmp_gmi_txx_sgmii_ctl { ++ u64 u; ++ struct cgxx_gmp_gmi_txx_sgmii_ctl_s { ++ u64 align : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_gmp_gmi_txx_sgmii_ctl_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TXX_SGMII_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TXX_SGMII_CTL(u64 a) ++{ ++ return 0x38300 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx#_slot ++ * ++ * CGX GMI TX Slottime Counter Registers ++ */ ++union cgxx_gmp_gmi_txx_slot { ++ u64 u; ++ struct cgxx_gmp_gmi_txx_slot_s { ++ u64 slot : 10; ++ u64 reserved_10_63 : 54; ++ } s; ++ /* struct cgxx_gmp_gmi_txx_slot_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TXX_SLOT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TXX_SLOT(u64 a) ++{ ++ return 0x38220 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx#_soft_pause ++ * ++ * CGX GMI TX Software PAUSE Registers ++ */ ++union cgxx_gmp_gmi_txx_soft_pause { ++ u64 u; ++ struct cgxx_gmp_gmi_txx_soft_pause_s { ++ u64 ptime : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_gmi_txx_soft_pause_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TXX_SOFT_PAUSE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TXX_SOFT_PAUSE(u64 a) ++{ ++ return 0x38250 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx#_thresh ++ * ++ * CGX GMI TX Threshold Registers ++ */ ++union cgxx_gmp_gmi_txx_thresh { ++ u64 u; ++ struct cgxx_gmp_gmi_txx_thresh_s { ++ u64 cnt : 11; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct cgxx_gmp_gmi_txx_thresh_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TXX_THRESH(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TXX_THRESH(u64 a) ++{ ++ return 0x38210 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx_col_attempt ++ * ++ * CGX TX Collision Attempts Before Dropping Frame Registers ++ */ ++union cgxx_gmp_gmi_tx_col_attempt { ++ u64 u; ++ struct cgxx_gmp_gmi_tx_col_attempt_s { ++ u64 limit : 5; ++ u64 reserved_5_63 : 59; ++ } s; ++ /* struct cgxx_gmp_gmi_tx_col_attempt_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TX_COL_ATTEMPT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TX_COL_ATTEMPT(void) ++{ ++ return 0x39010; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx_ifg ++ * ++ * CGX GMI TX Interframe-Gap Cycles Registers Consider the following when ++ * programming IFG1 and IFG2: * For 10/100/1000 Mb/s half-duplex systems ++ * that require IEEE 802.3 compatibility, IFG1 must be in the range of ++ * 1-8, [IFG2] must be in the range of 4-12, and the [IFG1] + [IFG2] sum ++ * must be 12. * For 10/100/1000 Mb/s full-duplex systems that require ++ * IEEE 802.3 compatibility, IFG1 must be in the range of 1-11, [IFG2] ++ * must be in the range of 1-11, and the [IFG1] + [IFG2] sum must be 12. ++ * For all other systems, IFG1 and IFG2 can be any value in the range of ++ * 1-15, allowing for a total possible IFG sum of 2-30. ++ */ ++union cgxx_gmp_gmi_tx_ifg { ++ u64 u; ++ struct cgxx_gmp_gmi_tx_ifg_s { ++ u64 ifg1 : 4; ++ u64 ifg2 : 4; ++ u64 reserved_8_63 : 56; ++ } s; ++ /* struct cgxx_gmp_gmi_tx_ifg_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TX_IFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TX_IFG(void) ++{ ++ return 0x39000; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx_jam ++ * ++ * CGX GMI TX JAM Pattern Registers This register provides the pattern ++ * used in JAM bytes. ++ */ ++union cgxx_gmp_gmi_tx_jam { ++ u64 u; ++ struct cgxx_gmp_gmi_tx_jam_s { ++ u64 jam : 8; ++ u64 reserved_8_63 : 56; ++ } s; ++ /* struct cgxx_gmp_gmi_tx_jam_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TX_JAM(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TX_JAM(void) ++{ ++ return 0x39008; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx_lfsr ++ * ++ * CGX GMI TX LFSR Registers This register shows the contents of the ++ * linear feedback shift register (LFSR), which is used to implement ++ * truncated binary exponential backoff. ++ */ ++union cgxx_gmp_gmi_tx_lfsr { ++ u64 u; ++ struct cgxx_gmp_gmi_tx_lfsr_s { ++ u64 lfsr : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_gmi_tx_lfsr_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TX_LFSR(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TX_LFSR(void) ++{ ++ return 0x39028; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx_pause_pkt_dmac ++ * ++ * CGX TX PAUSE-Packet DMAC-Field Registers ++ */ ++union cgxx_gmp_gmi_tx_pause_pkt_dmac { ++ u64 u; ++ struct cgxx_gmp_gmi_tx_pause_pkt_dmac_s { ++ u64 dmac : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_gmp_gmi_tx_pause_pkt_dmac_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TX_PAUSE_PKT_DMAC(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TX_PAUSE_PKT_DMAC(void) ++{ ++ return 0x39018; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_gmi_tx_pause_pkt_type ++ * ++ * CGX GMI TX PAUSE-Packet-PTYPE Field Registers This register provides ++ * the PTYPE field that is placed in outbound PAUSE packets. ++ */ ++union cgxx_gmp_gmi_tx_pause_pkt_type { ++ u64 u; ++ struct cgxx_gmp_gmi_tx_pause_pkt_type_s { ++ u64 ptype : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_gmi_tx_pause_pkt_type_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_GMI_TX_PAUSE_PKT_TYPE(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_GMI_TX_PAUSE_PKT_TYPE(void) ++{ ++ return 0x39020; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_misc#_cfg ++ * ++ * CGX GMP PCS Miscellaneous Control Registers This register contains ++ * general configuration that should not need to be changed from reset ++ * settings. Internal: Per lmac diagnostic and chicken bits. ++ */ ++union cgxx_gmp_miscx_cfg { ++ u64 u; ++ struct cgxx_gmp_miscx_cfg_s { ++ u64 tx_eee_quiet_credit_mode : 1; ++ u64 tx_eee_wait_gmi_fast_idle : 1; ++ u64 tx_qsgmii_port0_init : 1; ++ u64 tx_eee_rx_sync_status_enable : 1; ++ u64 pcs_alt_an : 1; ++ u64 reserved_5_7 : 3; ++ u64 rx_pcs_sync_signal_detect : 1; ++ u64 rx_pcs_sync_timeout : 1; ++ u64 rx_pcs_eee_mode_enable : 1; ++ u64 rx_pcs_lpi_enable : 1; ++ u64 rx_pcs_802_rx_k : 1; ++ u64 rx_pcs_alt_qlb2i : 1; ++ u64 reserved_14_15 : 2; ++ u64 rx_cgp_gser_throttle : 1; ++ u64 rx_cgp_edet_filter : 1; ++ u64 rx_cgp_edet_qlm_val : 1; ++ u64 reserved_19_63 : 45; ++ } s; ++ /* struct cgxx_gmp_miscx_cfg_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_MISCX_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_MISCX_CFG(u64 a) ++{ ++ return 0x34000 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs#_an_expansion ++ * ++ * CGX GMP PCS AN Expansion register Register 6 AN status ++ */ ++union cgxx_gmp_pcsx_an_expansion { ++ u64 u; ++ struct cgxx_gmp_pcsx_an_expansion_s { ++ u64 reserved_0 : 1; ++ u64 page_received : 1; ++ u64 next_page_able : 1; ++ u64 reserved_3_63 : 61; ++ } s; ++ /* struct cgxx_gmp_pcsx_an_expansion_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCSX_AN_EXPANSION(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCSX_AN_EXPANSION(u64 a) ++{ ++ return 0x30a60 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs#_an_lp_abil_np ++ * ++ * CGX GMP PCS AN Link Partner Ability Next Page Register 8 This register ++ * contains the advertised ability of the link partners Next Page. The ++ * definition for this register is provided in 32.5.4.2 for changes to ++ * 28.2.4.1.4. ++ */ ++union cgxx_gmp_pcsx_an_lp_abil_np { ++ u64 u; ++ struct cgxx_gmp_pcsx_an_lp_abil_np_s { ++ u64 m_u : 11; ++ u64 toggle : 1; ++ u64 ack2 : 1; ++ u64 mp : 1; ++ u64 ack : 1; ++ u64 np : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_pcsx_an_lp_abil_np_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCSX_AN_LP_ABIL_NP(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCSX_AN_LP_ABIL_NP(u64 a) ++{ ++ return 0x30a80 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs#_an_np_tx ++ * ++ * CGX GMP PCS AN Next Page Transmit Register 7 Software programs this ++ * register with the contents of the AN message next page or unformatted ++ * next page link code word to be transmitted during autonegotiation. ++ * Next page exchange occurs after the base link code words have been ++ * exchanged if either end of the link segment sets the NP bit to 1, ++ * indicating that it has at least one next page to send. Once initiated, ++ * next page exchange continues until both ends of the link segment set ++ * their NP bits to 0. Both sides must be NP capable to use NP exchanges. ++ */ ++union cgxx_gmp_pcsx_an_np_tx { ++ u64 u; ++ struct cgxx_gmp_pcsx_an_np_tx_s { ++ u64 m_u : 11; ++ u64 toggle : 1; ++ u64 ack2 : 1; ++ u64 mp : 1; ++ u64 ack : 1; ++ u64 np : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_pcsx_an_np_tx_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCSX_AN_NP_TX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCSX_AN_NP_TX(u64 a) ++{ ++ return 0x30a70 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs#_dbg_control ++ * ++ * CGX PCS Debug Control Registers ++ */ ++union cgxx_gmp_pcsx_dbg_control { ++ u64 u; ++ struct cgxx_gmp_pcsx_dbg_control_s { ++ u64 us_clk_period : 7; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct cgxx_gmp_pcsx_dbg_control_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCSX_DBG_CONTROL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCSX_DBG_CONTROL(u64 a) ++{ ++ return 0x31000 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs#_rx_eee_wake ++ * ++ * INTERNAL: CGX GMP PCS RX EEE Wake Error Counter Registers Reserved. ++ * Internal: This register is used by PHY types that support EEE to count ++ * wake time faults where the PHY fails to complete its normal wake ++ * sequence within the time required for the specific PHY type. The ++ * definition of the fault event to be counted is defined for each PHY ++ * and may occur during a refresh or a wake-up as defined by the PHY. ++ * This 16-bit counter shall be reset to all zeros upon execution of the ++ * PCS reset. This counter shall be held at all ones in the case of ++ * overflow. ++ */ ++union cgxx_gmp_pcsx_rx_eee_wake { ++ u64 u; ++ struct cgxx_gmp_pcsx_rx_eee_wake_s { ++ u64 error_counter : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_pcsx_rx_eee_wake_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCSX_RX_EEE_WAKE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCSX_RX_EEE_WAKE(u64 a) ++{ ++ return 0x30910 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs#_rx_lpi_timing ++ * ++ * INTERNAL: CGX GMP PCS RX EEE LPI Timing Parameters Registers ++ * Reserved. Internal: Receiver LPI timing parameters Tqr, Twr and Twtf. ++ */ ++union cgxx_gmp_pcsx_rx_lpi_timing { ++ u64 u; ++ struct cgxx_gmp_pcsx_rx_lpi_timing_s { ++ u64 twtf : 18; ++ u64 reserved_18_19 : 2; ++ u64 twr : 12; ++ u64 tqr : 20; ++ u64 reserved_52_63 : 12; ++ } s; ++ /* struct cgxx_gmp_pcsx_rx_lpi_timing_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCSX_RX_LPI_TIMING(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCSX_RX_LPI_TIMING(u64 a) ++{ ++ return 0x30900 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs#_status1 ++ * ++ * CGX GMP PCS Status 1 Register PCS LPI Status, Link OK. Register 3.1 ++ */ ++union cgxx_gmp_pcsx_status1 { ++ u64 u; ++ struct cgxx_gmp_pcsx_status1_s { ++ u64 reserved_0_1 : 2; ++ u64 receive_link_status : 1; ++ u64 reserved_3_7 : 5; ++ u64 rx_lpi_indication : 1; ++ u64 tx_lpi_indication : 1; ++ u64 rx_lpi_received : 1; ++ u64 tx_lpi_received : 1; ++ u64 reserved_12_63 : 52; ++ } s; ++ /* struct cgxx_gmp_pcsx_status1_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCSX_STATUS1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCSX_STATUS1(u64 a) ++{ ++ return 0x30880 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs#_tx_lpi_timing ++ * ++ * INTERNAL: CGX GMP GMI TX EEE LPI Timing Parameters Registers ++ * Reserved. Internal: Transmitter LPI timing parameters Tsl, Tql and ++ * Tul. ++ */ ++union cgxx_gmp_pcsx_tx_lpi_timing { ++ u64 u; ++ struct cgxx_gmp_pcsx_tx_lpi_timing_s { ++ u64 tql : 19; ++ u64 reserved_19_31 : 13; ++ u64 tul : 12; ++ u64 reserved_44_47 : 4; ++ u64 tsl : 12; ++ u64 reserved_60_63 : 4; ++ } s; ++ /* struct cgxx_gmp_pcsx_tx_lpi_timing_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCSX_TX_LPI_TIMING(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCSX_TX_LPI_TIMING(u64 a) ++{ ++ return 0x30800 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_an#_adv ++ * ++ * CGX GMP PCS Autonegotiation Advertisement Registers ++ */ ++union cgxx_gmp_pcs_anx_adv { ++ u64 u; ++ struct cgxx_gmp_pcs_anx_adv_s { ++ u64 reserved_0_4 : 5; ++ u64 fd : 1; ++ u64 hfd : 1; ++ u64 pause : 2; ++ u64 reserved_9_11 : 3; ++ u64 rem_flt : 2; ++ u64 reserved_14 : 1; ++ u64 np : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_pcs_anx_adv_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCS_ANX_ADV(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_ANX_ADV(u64 a) ++{ ++ return 0x30010 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_an#_ext_st ++ * ++ * CGX GMO PCS Autonegotiation Extended Status Registers ++ */ ++union cgxx_gmp_pcs_anx_ext_st { ++ u64 u; ++ struct cgxx_gmp_pcs_anx_ext_st_s { ++ u64 reserved_0_11 : 12; ++ u64 thou_thd : 1; ++ u64 thou_tfd : 1; ++ u64 thou_xhd : 1; ++ u64 thou_xfd : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_pcs_anx_ext_st_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCS_ANX_EXT_ST(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_ANX_EXT_ST(u64 a) ++{ ++ return 0x30028 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_an#_lp_abil ++ * ++ * CGX GMP PCS Autonegotiation Link Partner Ability Registers This is the ++ * autonegotiation link partner ability register 5 as per IEEE 802.3, ++ * Clause 37. ++ */ ++union cgxx_gmp_pcs_anx_lp_abil { ++ u64 u; ++ struct cgxx_gmp_pcs_anx_lp_abil_s { ++ u64 reserved_0_4 : 5; ++ u64 fd : 1; ++ u64 hfd : 1; ++ u64 pause : 2; ++ u64 reserved_9_11 : 3; ++ u64 rem_flt : 2; ++ u64 ack : 1; ++ u64 np : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_pcs_anx_lp_abil_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCS_ANX_LP_ABIL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_ANX_LP_ABIL(u64 a) ++{ ++ return 0x30018 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_an#_results ++ * ++ * CGX GMP PCS Autonegotiation Results Registers This register is not ++ * valid when CGX()_GMP_PCS_MISC()_CTL[AN_OVRD] is set to 1. If ++ * CGX()_GMP_PCS_MISC()_CTL[AN_OVRD] is set to 0 and ++ * CGX()_GMP_PCS_AN()_RESULTS[AN_CPT] is set to 1, this register is ++ * valid. ++ */ ++union cgxx_gmp_pcs_anx_results { ++ u64 u; ++ struct cgxx_gmp_pcs_anx_results_s { ++ u64 link_ok : 1; ++ u64 dup : 1; ++ u64 an_cpt : 1; ++ u64 spd : 2; ++ u64 pause : 2; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct cgxx_gmp_pcs_anx_results_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCS_ANX_RESULTS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_ANX_RESULTS(u64 a) ++{ ++ return 0x30020 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_int# ++ * ++ * CGX GMP PCS Interrupt Registers ++ */ ++union cgxx_gmp_pcs_intx { ++ u64 u; ++ struct cgxx_gmp_pcs_intx_s { ++ u64 lnkspd : 1; ++ u64 xmit : 1; ++ u64 an_err : 1; ++ u64 txfifu : 1; ++ u64 txfifo : 1; ++ u64 txbad : 1; ++ u64 rxerr : 1; ++ u64 rxbad : 1; ++ u64 rxlock : 1; ++ u64 an_bad : 1; ++ u64 sync_bad : 1; ++ u64 dup : 1; ++ u64 dbg_sync : 1; ++ u64 reserved_13_15 : 3; ++ u64 an_page_received : 1; ++ u64 an_complete : 1; ++ u64 reserved_18_19 : 2; ++ u64 eee_tx_change : 1; ++ u64 eee_rx_change : 1; ++ u64 eee_rx_link_fail : 1; ++ u64 reserved_23_63 : 41; ++ } s; ++ /* struct cgxx_gmp_pcs_intx_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCS_INTX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_INTX(u64 a) ++{ ++ return 0x30080 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_int#_ena_w1c ++ * ++ * CGX GMP PCS Interrupt Enable Clear Registers This register clears ++ * interrupt enable bits. ++ */ ++union cgxx_gmp_pcs_intx_ena_w1c { ++ u64 u; ++ struct cgxx_gmp_pcs_intx_ena_w1c_s { ++ u64 lnkspd : 1; ++ u64 xmit : 1; ++ u64 an_err : 1; ++ u64 txfifu : 1; ++ u64 txfifo : 1; ++ u64 txbad : 1; ++ u64 rxerr : 1; ++ u64 rxbad : 1; ++ u64 rxlock : 1; ++ u64 an_bad : 1; ++ u64 sync_bad : 1; ++ u64 dup : 1; ++ u64 dbg_sync : 1; ++ u64 reserved_13_15 : 3; ++ u64 an_page_received : 1; ++ u64 an_complete : 1; ++ u64 reserved_18_19 : 2; ++ u64 eee_tx_change : 1; ++ u64 eee_rx_change : 1; ++ u64 eee_rx_link_fail : 1; ++ u64 reserved_23_63 : 41; ++ } s; ++ /* struct cgxx_gmp_pcs_intx_ena_w1c_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCS_INTX_ENA_W1C(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_INTX_ENA_W1C(u64 a) ++{ ++ return 0x30090 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_int#_ena_w1s ++ * ++ * CGX GMP PCS Interrupt Enable Set Registers This register sets ++ * interrupt enable bits. ++ */ ++union cgxx_gmp_pcs_intx_ena_w1s { ++ u64 u; ++ struct cgxx_gmp_pcs_intx_ena_w1s_s { ++ u64 lnkspd : 1; ++ u64 xmit : 1; ++ u64 an_err : 1; ++ u64 txfifu : 1; ++ u64 txfifo : 1; ++ u64 txbad : 1; ++ u64 rxerr : 1; ++ u64 rxbad : 1; ++ u64 rxlock : 1; ++ u64 an_bad : 1; ++ u64 sync_bad : 1; ++ u64 dup : 1; ++ u64 dbg_sync : 1; ++ u64 reserved_13_15 : 3; ++ u64 an_page_received : 1; ++ u64 an_complete : 1; ++ u64 reserved_18_19 : 2; ++ u64 eee_tx_change : 1; ++ u64 eee_rx_change : 1; ++ u64 eee_rx_link_fail : 1; ++ u64 reserved_23_63 : 41; ++ } s; ++ /* struct cgxx_gmp_pcs_intx_ena_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCS_INTX_ENA_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_INTX_ENA_W1S(u64 a) ++{ ++ return 0x30098 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_int#_w1s ++ * ++ * CGX GMP PCS Interrupt Set Registers This register sets interrupt bits. ++ */ ++union cgxx_gmp_pcs_intx_w1s { ++ u64 u; ++ struct cgxx_gmp_pcs_intx_w1s_s { ++ u64 lnkspd : 1; ++ u64 xmit : 1; ++ u64 an_err : 1; ++ u64 txfifu : 1; ++ u64 txfifo : 1; ++ u64 txbad : 1; ++ u64 rxerr : 1; ++ u64 rxbad : 1; ++ u64 rxlock : 1; ++ u64 an_bad : 1; ++ u64 sync_bad : 1; ++ u64 dup : 1; ++ u64 dbg_sync : 1; ++ u64 reserved_13_15 : 3; ++ u64 an_page_received : 1; ++ u64 an_complete : 1; ++ u64 reserved_18_19 : 2; ++ u64 eee_tx_change : 1; ++ u64 eee_rx_change : 1; ++ u64 eee_rx_link_fail : 1; ++ u64 reserved_23_63 : 41; ++ } s; ++ /* struct cgxx_gmp_pcs_intx_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCS_INTX_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_INTX_W1S(u64 a) ++{ ++ return 0x30088 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_link#_timer ++ * ++ * CGX GMP PCS Link Timer Registers This is the 1.6 ms nominal link timer ++ * register. ++ */ ++union cgxx_gmp_pcs_linkx_timer { ++ u64 u; ++ struct cgxx_gmp_pcs_linkx_timer_s { ++ u64 count : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_pcs_linkx_timer_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCS_LINKX_TIMER(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_LINKX_TIMER(u64 a) ++{ ++ return 0x30040 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_misc#_ctl ++ * ++ * CGX GMP SGMII Miscellaneous Control Registers Internal: SGMII bit [12] ++ * is really a misnomer, it is a decode of pi_qlm_cfg pins to indicate ++ * SGMII or 1000Base-X modes. Note: The SGMII AN Advertisement Register ++ * above will be sent during Auto Negotiation if [MAC_PHY] is set (1=PHY ++ * mode). If the bit is not set (0=MAC mode), the tx_Config_Reg\<14\> ++ * becomes ACK bit and tx_Config_Reg\<0\> is always 1. All other bits in ++ * tx_Config_Reg sent will be 0. The PHY dictates the Auto Negotiation ++ * results. ++ */ ++union cgxx_gmp_pcs_miscx_ctl { ++ u64 u; ++ struct cgxx_gmp_pcs_miscx_ctl_s { ++ u64 samp_pt : 7; ++ u64 an_ovrd : 1; ++ u64 mode : 1; ++ u64 mac_phy : 1; ++ u64 loopbck2 : 1; ++ u64 gmxeno : 1; ++ u64 reserved_12 : 1; ++ u64 disp_en : 1; ++ u64 reserved_14_15 : 2; ++ u64 qsgmii_comma_wd : 16; ++ u64 qsgmii_comma_wd_en : 1; ++ u64 reserved_33_63 : 31; ++ } s; ++ struct cgxx_gmp_pcs_miscx_ctl_cn { ++ u64 samp_pt : 7; ++ u64 an_ovrd : 1; ++ u64 mode : 1; ++ u64 mac_phy : 1; ++ u64 loopbck2 : 1; ++ u64 gmxeno : 1; ++ u64 reserved_12 : 1; ++ u64 disp_en : 1; ++ u64 reserved_14_15 : 2; ++ u64 qsgmii_comma_wd : 16; ++ u64 qsgmii_comma_wd_en : 1; ++ u64 reserved_33_35 : 3; ++ u64 reserved_36_63 : 28; ++ } cn; ++}; ++ ++static inline u64 CGXX_GMP_PCS_MISCX_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_MISCX_CTL(u64 a) ++{ ++ return 0x30078 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_mr#_control ++ * ++ * CGX GMP PCS Control Registers ++ */ ++union cgxx_gmp_pcs_mrx_control { ++ u64 u; ++ struct cgxx_gmp_pcs_mrx_control_s { ++ u64 reserved_0_4 : 5; ++ u64 uni : 1; ++ u64 spdmsb : 1; ++ u64 coltst : 1; ++ u64 dup : 1; ++ u64 rst_an : 1; ++ u64 reserved_10 : 1; ++ u64 pwr_dn : 1; ++ u64 an_en : 1; ++ u64 spdlsb : 1; ++ u64 loopbck1 : 1; ++ u64 reset : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_pcs_mrx_control_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCS_MRX_CONTROL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_MRX_CONTROL(u64 a) ++{ ++ return 0x30000 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_mr#_status ++ * ++ * CGX GMP PCS Status Registers Bits \<15:9\> in this register indicate ++ * the ability to operate when CGX()_GMP_PCS_MISC()_CTL[MAC_PHY] is set ++ * to MAC mode. Bits \<15:9\> are always read as 0, indicating that the ++ * chip cannot operate in the corresponding modes. The field [RM_FLT] is ++ * a 'don't care' when the selected mode is SGMII/QSGMII. ++ */ ++union cgxx_gmp_pcs_mrx_status { ++ u64 u; ++ struct cgxx_gmp_pcs_mrx_status_s { ++ u64 extnd : 1; ++ u64 reserved_1 : 1; ++ u64 lnk_st : 1; ++ u64 an_abil : 1; ++ u64 rm_flt : 1; ++ u64 an_cpt : 1; ++ u64 prb_sup : 1; ++ u64 reserved_7 : 1; ++ u64 ext_st : 1; ++ u64 hun_t2hd : 1; ++ u64 hun_t2fd : 1; ++ u64 ten_hd : 1; ++ u64 ten_fd : 1; ++ u64 hun_xhd : 1; ++ u64 hun_xfd : 1; ++ u64 hun_t4 : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_pcs_mrx_status_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCS_MRX_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_MRX_STATUS(u64 a) ++{ ++ return 0x30008 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_rx#_states ++ * ++ * CGX GMP PCS RX State-Machines States Registers ++ */ ++union cgxx_gmp_pcs_rxx_states { ++ u64 u; ++ struct cgxx_gmp_pcs_rxx_states_s { ++ u64 an_st : 4; ++ u64 an_bad : 1; ++ u64 sync : 4; ++ u64 sync_bad : 1; ++ u64 rx_st : 5; ++ u64 rx_bad : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_pcs_rxx_states_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCS_RXX_STATES(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_RXX_STATES(u64 a) ++{ ++ return 0x30058 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_rx#_sync ++ * ++ * CGX GMP PCS Code Group Synchronization Registers ++ */ ++union cgxx_gmp_pcs_rxx_sync { ++ u64 u; ++ struct cgxx_gmp_pcs_rxx_sync_s { ++ u64 bit_lock : 1; ++ u64 sync : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct cgxx_gmp_pcs_rxx_sync_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCS_RXX_SYNC(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_RXX_SYNC(u64 a) ++{ ++ return 0x30050 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_sgm#_an_adv ++ * ++ * CGX GMP PCS SGMII Autonegotiation Advertisement Registers This is the ++ * SGMII autonegotiation advertisement register (sent out as ++ * tx_Config_Reg\<15:0\> as defined in IEEE 802.3 clause 37). This ++ * register is sent during autonegotiation if ++ * CGX()_GMP_PCS_MISC()_CTL[MAC_PHY] is set (1 = PHY mode). If the bit is ++ * not set (0 = MAC mode), then tx_Config_Reg\<14\> becomes ACK bit and ++ * tx_Config_Reg\<0\> is always 1. All other bits in tx_Config_Reg sent ++ * will be 0. The PHY dictates the autonegotiation results. ++ */ ++union cgxx_gmp_pcs_sgmx_an_adv { ++ u64 u; ++ struct cgxx_gmp_pcs_sgmx_an_adv_s { ++ u64 one : 1; ++ u64 reserved_1_9 : 9; ++ u64 speed : 2; ++ u64 dup : 1; ++ u64 reserved_13 : 1; ++ u64 ack : 1; ++ u64 link : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_gmp_pcs_sgmx_an_adv_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCS_SGMX_AN_ADV(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_SGMX_AN_ADV(u64 a) ++{ ++ return 0x30068 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_sgm#_lp_adv ++ * ++ * CGX GMP PCS SGMII Link-Partner-Advertisement Registers This is the ++ * SGMII link partner advertisement register (received as ++ * rx_Config_Reg\<15:0\> as defined in IEEE 802.3 clause 37). ++ */ ++union cgxx_gmp_pcs_sgmx_lp_adv { ++ u64 u; ++ struct cgxx_gmp_pcs_sgmx_lp_adv_s { ++ u64 one : 1; ++ u64 reserved_1_9 : 9; ++ u64 speed : 2; ++ u64 dup : 1; ++ u64 reserved_13_14 : 2; ++ u64 link : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ struct cgxx_gmp_pcs_sgmx_lp_adv_cn { ++ u64 one : 1; ++ u64 reserved_1_9 : 9; ++ u64 speed : 2; ++ u64 dup : 1; ++ u64 reserved_13 : 1; ++ u64 reserved_14 : 1; ++ u64 link : 1; ++ u64 reserved_16_63 : 48; ++ } cn; ++}; ++ ++static inline u64 CGXX_GMP_PCS_SGMX_LP_ADV(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_SGMX_LP_ADV(u64 a) ++{ ++ return 0x30070 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_tx#_states ++ * ++ * CGX GMP PCS TX State-Machines States Registers ++ */ ++union cgxx_gmp_pcs_txx_states { ++ u64 u; ++ struct cgxx_gmp_pcs_txx_states_s { ++ u64 ord_st : 4; ++ u64 tx_bad : 1; ++ u64 xmit : 2; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct cgxx_gmp_pcs_txx_states_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCS_TXX_STATES(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_TXX_STATES(u64 a) ++{ ++ return 0x30060 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_gmp_pcs_tx_rx#_polarity ++ * ++ * CGX GMP PCS TX/RX Polarity Registers ++ * CGX()_GMP_PCS_TX_RX()_POLARITY[AUTORXPL] shows correct polarity needed ++ * on the link receive path after code group synchronization is achieved. ++ * When LMAC_TYPE=QSGMII, only lane 0 polarity data and settings are ++ * relevant and settings for lanes 1, 2 and 3 are unused. ++ */ ++union cgxx_gmp_pcs_tx_rxx_polarity { ++ u64 u; ++ struct cgxx_gmp_pcs_tx_rxx_polarity_s { ++ u64 txplrt : 1; ++ u64 rxplrt : 1; ++ u64 autorxpl : 1; ++ u64 rxovrd : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct cgxx_gmp_pcs_tx_rxx_polarity_s cn; */ ++}; ++ ++static inline u64 CGXX_GMP_PCS_TX_RXX_POLARITY(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_GMP_PCS_TX_RXX_POLARITY(u64 a) ++{ ++ return 0x30048 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_msix_pba# ++ * ++ * CGX MSI-X Pending Bit Array Registers This register is the MSI-X PBA ++ * table, the bit number is indexed by the CGX_INT_VEC_E enumeration. ++ */ ++union cgxx_msix_pbax { ++ u64 u; ++ struct cgxx_msix_pbax_s { ++ u64 pend : 64; ++ } s; ++ /* struct cgxx_msix_pbax_s cn; */ ++}; ++ ++static inline u64 CGXX_MSIX_PBAX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_MSIX_PBAX(u64 a) ++{ ++ return 0xf0000 + 8 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_msix_vec#_addr ++ * ++ * CGX MSI-X Vector Table Address Registers This register is the MSI-X ++ * vector table, indexed by the CGX_INT_VEC_E enumeration. ++ */ ++union cgxx_msix_vecx_addr { ++ u64 u; ++ struct cgxx_msix_vecx_addr_s { ++ u64 secvec : 1; ++ u64 reserved_1 : 1; ++ u64 addr : 51; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct cgxx_msix_vecx_addr_s cn; */ ++}; ++ ++static inline u64 CGXX_MSIX_VECX_ADDR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_MSIX_VECX_ADDR(u64 a) ++{ ++ return 0 + 0x10 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_msix_vec#_ctl ++ * ++ * CGX MSI-X Vector Table Control and Data Registers This register is the ++ * MSI-X vector table, indexed by the CGX_INT_VEC_E enumeration. ++ */ ++union cgxx_msix_vecx_ctl { ++ u64 u; ++ struct cgxx_msix_vecx_ctl_s { ++ u64 data : 32; ++ u64 mask : 1; ++ u64 reserved_33_63 : 31; ++ } s; ++ /* struct cgxx_msix_vecx_ctl_s cn; */ ++}; ++ ++static inline u64 CGXX_MSIX_VECX_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_MSIX_VECX_CTL(u64 a) ++{ ++ return 8 + 0x10 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_bp_test ++ * ++ * INTERNAL: CGX SMU TX Backpressure Test Registers ++ */ ++union cgxx_smux_bp_test { ++ u64 u; ++ struct cgxx_smux_bp_test_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 8; ++ u64 reserved_24_47 : 24; ++ u64 enable : 4; ++ u64 reserved_52_63 : 12; ++ } s; ++ /* struct cgxx_smux_bp_test_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_BP_TEST(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_BP_TEST(u64 a) ++{ ++ return 0x20230 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_cbfc_ctl ++ * ++ * CGX SMU PFC Control Registers Internal: INTERNAL: XOFF for a specific ++ * class/channel \ is XOFF\ = ([PHYS_EN]\ & cmr_rx_phys_bp) | ++ * ([LOGL_EN]\ & cmr_rx_logl_xoff\). ++ */ ++union cgxx_smux_cbfc_ctl { ++ u64 u; ++ struct cgxx_smux_cbfc_ctl_s { ++ u64 rx_en : 1; ++ u64 tx_en : 1; ++ u64 drp_en : 1; ++ u64 bck_en : 1; ++ u64 reserved_4_31 : 28; ++ u64 logl_en : 16; ++ u64 phys_en : 16; ++ } s; ++ /* struct cgxx_smux_cbfc_ctl_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_CBFC_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_CBFC_CTL(u64 a) ++{ ++ return 0x20218 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_ctrl ++ * ++ * CGX SMU Control Registers ++ */ ++union cgxx_smux_ctrl { ++ u64 u; ++ struct cgxx_smux_ctrl_s { ++ u64 rx_idle : 1; ++ u64 tx_idle : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct cgxx_smux_ctrl_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_CTRL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_CTRL(u64 a) ++{ ++ return 0x20200 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_ext_loopback ++ * ++ * CGX SMU External Loopback Registers In loopback mode, the IFG1+IFG2 of ++ * local and remote parties must match exactly; otherwise loopback FIFO ++ * will overrun: CGX()_SMU()_TX_INT[LB_OVRFLW]. ++ */ ++union cgxx_smux_ext_loopback { ++ u64 u; ++ struct cgxx_smux_ext_loopback_s { ++ u64 thresh : 6; ++ u64 reserved_6_7 : 2; ++ u64 depth : 6; ++ u64 reserved_14_15 : 2; ++ u64 en : 1; ++ u64 reserved_17_63 : 47; ++ } s; ++ /* struct cgxx_smux_ext_loopback_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_EXT_LOOPBACK(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_EXT_LOOPBACK(u64 a) ++{ ++ return 0x20208 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_hg2_control ++ * ++ * CGX SMU HiGig2 Control Registers HiGig2 TX- and RX-enable are normally ++ * set together for HiGig2 messaging. Setting just the TX or RX bit ++ * results in only the HG2 message transmit or receive capability. ++ * Setting [PHYS_EN] and [LOGL_EN] to 1 allows link PAUSE or backpressure ++ * to NIX as per the received HiGig2 message. Setting these fields to 0 ++ * disables link PAUSE and backpressure to NIX in response to received ++ * messages. CGX()_SMU()_TX_CTL[HG_EN] must be set (to enable HiGig) ++ * whenever either [HG2TX_EN] or [HG2RX_EN] are set. ++ * CGX()_SMU()_RX_UDD_SKP[LEN] must be set to 16 (to select HiGig2) ++ * whenever either [HG2TX_EN] or [HG2RX_EN] are set. ++ * CGX()_CMR_RX_OVR_BP[EN]\<0\> must be set and ++ * CGX()_CMR_RX_OVR_BP[BP]\<0\> must be cleared to 0 (to forcibly disable ++ * hardware-automatic 802.3 PAUSE packet generation) with the HiGig2 ++ * Protocol when [HG2TX_EN] = 0. (The HiGig2 protocol is indicated by ++ * CGX()_SMU()_TX_CTL[HG_EN] = 1 and CGX()_SMU()_RX_UDD_SKP[LEN]=16.) ++ * Hardware can only autogenerate backpressure via HiGig2 messages ++ * (optionally, when [HG2TX_EN] = 1) with the HiGig2 protocol. ++ */ ++union cgxx_smux_hg2_control { ++ u64 u; ++ struct cgxx_smux_hg2_control_s { ++ u64 logl_en : 16; ++ u64 phys_en : 1; ++ u64 hg2rx_en : 1; ++ u64 hg2tx_en : 1; ++ u64 reserved_19_63 : 45; ++ } s; ++ /* struct cgxx_smux_hg2_control_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_HG2_CONTROL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_HG2_CONTROL(u64 a) ++{ ++ return 0x20210 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_mmsi_ctl_sta ++ * ++ * CGX SMU MAC Merge Service Interface (MMSI) Control/Status Registers ++ * MMSI control and status registers for frame preemption mode. Refer to ++ * IEEE 802.3br, Clause 99. ++ */ ++union cgxx_smux_mmsi_ctl_sta { ++ u64 u; ++ struct cgxx_smux_mmsi_ctl_sta_s { ++ u64 p_en : 1; ++ u64 dis_v : 1; ++ u64 afs : 2; ++ u64 v_sta : 3; ++ u64 tx_pactive : 1; ++ u64 reserved_8_31 : 24; ++ u64 v_time : 24; ++ u64 reserved_56_63 : 8; ++ } s; ++ /* struct cgxx_smux_mmsi_ctl_sta_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_MMSI_CTL_STA(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_MMSI_CTL_STA(u64 a) ++{ ++ return 0x20220 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_bad_col_ctrl ++ * ++ * CGX SMU RX Bad Column High Registers ++ */ ++union cgxx_smux_rx_bad_col_ctrl { ++ u64 u; ++ struct cgxx_smux_rx_bad_col_ctrl_s { ++ u64 lane_rxc : 16; ++ u64 state : 3; ++ u64 val : 1; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct cgxx_smux_rx_bad_col_ctrl_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_BAD_COL_CTRL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_BAD_COL_CTRL(u64 a) ++{ ++ return 0x20060 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_bad_col_data_hi ++ * ++ * CGX SMU RX Bad Column Low Registers ++ */ ++union cgxx_smux_rx_bad_col_data_hi { ++ u64 u; ++ struct cgxx_smux_rx_bad_col_data_hi_s { ++ u64 lane_rxd : 64; ++ } s; ++ /* struct cgxx_smux_rx_bad_col_data_hi_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_BAD_COL_DATA_HI(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_BAD_COL_DATA_HI(u64 a) ++{ ++ return 0x20058 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_bad_col_data_lo ++ * ++ * CGX SMU RX Bad Column Low Registers ++ */ ++union cgxx_smux_rx_bad_col_data_lo { ++ u64 u; ++ struct cgxx_smux_rx_bad_col_data_lo_s { ++ u64 lane_rxd : 64; ++ } s; ++ /* struct cgxx_smux_rx_bad_col_data_lo_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_BAD_COL_DATA_LO(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_BAD_COL_DATA_LO(u64 a) ++{ ++ return 0x20050 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_ctl ++ * ++ * CGX SMU RX Control Registers ++ */ ++union cgxx_smux_rx_ctl { ++ u64 u; ++ struct cgxx_smux_rx_ctl_s { ++ u64 status : 2; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct cgxx_smux_rx_ctl_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_CTL(u64 a) ++{ ++ return 0x20048 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_decision ++ * ++ * CGX SMU Packet Decision Registers This register specifies the byte ++ * count used to determine when to accept or to filter a packet. As each ++ * byte in a packet is received by CGX, the L2 byte count (i.e. the ++ * number of bytes from the beginning of the L2 header (DMAC)) is ++ * compared against CNT. In normal operation, the L2 header begins after ++ * the PREAMBLE + SFD (CGX()_SMU()_RX_FRM_CTL[PRE_CHK] = 1) and any ++ * optional UDD skip data (CGX()_SMU()_RX_UDD_SKP[LEN]). ++ */ ++union cgxx_smux_rx_decision { ++ u64 u; ++ struct cgxx_smux_rx_decision_s { ++ u64 cnt : 5; ++ u64 reserved_5_63 : 59; ++ } s; ++ /* struct cgxx_smux_rx_decision_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_DECISION(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_DECISION(u64 a) ++{ ++ return 0x20038 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_frm_chk ++ * ++ * CGX SMU RX Frame Check Registers The CSRs provide the enable bits for ++ * a subset of errors passed to CMR encoded. ++ */ ++union cgxx_smux_rx_frm_chk { ++ u64 u; ++ struct cgxx_smux_rx_frm_chk_s { ++ u64 reserved_0_2 : 3; ++ u64 jabber : 1; ++ u64 fcserr_d : 1; ++ u64 fcserr_c : 1; ++ u64 reserved_6 : 1; ++ u64 rcverr : 1; ++ u64 skperr : 1; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct cgxx_smux_rx_frm_chk_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_FRM_CHK(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_FRM_CHK(u64 a) ++{ ++ return 0x20028 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_frm_ctl ++ * ++ * CGX SMU RX Frame Control Registers This register controls the handling ++ * of the frames. The [CTL_BCK] and [CTL_DRP] bits control how the ++ * hardware handles incoming PAUSE packets. The most common modes of ++ * operation: _ [CTL_BCK] = 1, [CTL_DRP] = 1: hardware handles everything ++ * _ [CTL_BCK] = 0, [CTL_DRP] = 0: software sees all PAUSE frames _ ++ * [CTL_BCK] = 0, [CTL_DRP] = 1: all PAUSE frames are completely ignored ++ * These control bits should be set to [CTL_BCK] = 0, [CTL_DRP] = 0 in ++ * half-duplex mode. Since PAUSE packets only apply to full duplex ++ * operation, any PAUSE packet would constitute an exception which should ++ * be handled by the processing cores. PAUSE packets should not be ++ * forwarded. ++ */ ++union cgxx_smux_rx_frm_ctl { ++ u64 u; ++ struct cgxx_smux_rx_frm_ctl_s { ++ u64 pre_chk : 1; ++ u64 pre_strp : 1; ++ u64 ctl_drp : 1; ++ u64 ctl_bck : 1; ++ u64 ctl_mcst : 1; ++ u64 ctl_smac : 1; ++ u64 reserved_6_11 : 6; ++ u64 ptp_mode : 1; ++ u64 reserved_13_63 : 51; ++ } s; ++ /* struct cgxx_smux_rx_frm_ctl_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_FRM_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_FRM_CTL(u64 a) ++{ ++ return 0x20020 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_int ++ * ++ * CGX SMU Receive Interrupt Registers SMU Interrupt Register. Internal: ++ * Exception conditions \<9\> and \<4:0\> can also set the rcv/opcode in ++ * the received packet's work queue entry. CGX()_SMU()_RX_FRM_CHK ++ * provides a bit mask for configuring which conditions set the error. ++ */ ++union cgxx_smux_rx_int { ++ u64 u; ++ struct cgxx_smux_rx_int_s { ++ u64 jabber : 1; ++ u64 fcserr : 1; ++ u64 rcverr : 1; ++ u64 skperr : 1; ++ u64 pcterr : 1; ++ u64 rsverr : 1; ++ u64 loc_fault : 1; ++ u64 rem_fault : 1; ++ u64 bad_seq : 1; ++ u64 bad_term : 1; ++ u64 hg2fld : 1; ++ u64 hg2cc : 1; ++ u64 badver : 1; ++ u64 badrsp : 1; ++ u64 reserved_14_63 : 50; ++ } s; ++ /* struct cgxx_smux_rx_int_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_INT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_INT(u64 a) ++{ ++ return 0x20000 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_int_ena_w1c ++ * ++ * CGX SMU Receive Interrupt Enable Clear Registers This register clears ++ * interrupt enable bits. ++ */ ++union cgxx_smux_rx_int_ena_w1c { ++ u64 u; ++ struct cgxx_smux_rx_int_ena_w1c_s { ++ u64 jabber : 1; ++ u64 fcserr : 1; ++ u64 rcverr : 1; ++ u64 skperr : 1; ++ u64 pcterr : 1; ++ u64 rsverr : 1; ++ u64 loc_fault : 1; ++ u64 rem_fault : 1; ++ u64 bad_seq : 1; ++ u64 bad_term : 1; ++ u64 hg2fld : 1; ++ u64 hg2cc : 1; ++ u64 badver : 1; ++ u64 badrsp : 1; ++ u64 reserved_14_63 : 50; ++ } s; ++ /* struct cgxx_smux_rx_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_INT_ENA_W1C(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_INT_ENA_W1C(u64 a) ++{ ++ return 0x20010 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_int_ena_w1s ++ * ++ * CGX SMU Receive Interrupt Enable Set Registers This register sets ++ * interrupt enable bits. ++ */ ++union cgxx_smux_rx_int_ena_w1s { ++ u64 u; ++ struct cgxx_smux_rx_int_ena_w1s_s { ++ u64 jabber : 1; ++ u64 fcserr : 1; ++ u64 rcverr : 1; ++ u64 skperr : 1; ++ u64 pcterr : 1; ++ u64 rsverr : 1; ++ u64 loc_fault : 1; ++ u64 rem_fault : 1; ++ u64 bad_seq : 1; ++ u64 bad_term : 1; ++ u64 hg2fld : 1; ++ u64 hg2cc : 1; ++ u64 badver : 1; ++ u64 badrsp : 1; ++ u64 reserved_14_63 : 50; ++ } s; ++ /* struct cgxx_smux_rx_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_INT_ENA_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_INT_ENA_W1S(u64 a) ++{ ++ return 0x20018 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_int_w1s ++ * ++ * CGX SMU Receive Interrupt Set Registers This register sets interrupt ++ * bits. ++ */ ++union cgxx_smux_rx_int_w1s { ++ u64 u; ++ struct cgxx_smux_rx_int_w1s_s { ++ u64 jabber : 1; ++ u64 fcserr : 1; ++ u64 rcverr : 1; ++ u64 skperr : 1; ++ u64 pcterr : 1; ++ u64 rsverr : 1; ++ u64 loc_fault : 1; ++ u64 rem_fault : 1; ++ u64 bad_seq : 1; ++ u64 bad_term : 1; ++ u64 hg2fld : 1; ++ u64 hg2cc : 1; ++ u64 badver : 1; ++ u64 badrsp : 1; ++ u64 reserved_14_63 : 50; ++ } s; ++ /* struct cgxx_smux_rx_int_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_INT_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_INT_W1S(u64 a) ++{ ++ return 0x20008 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_jabber ++ * ++ * CGX SMU Maximum Packet-Size Registers This register specifies the ++ * maximum size for packets, beyond which the SMU truncates. Internal: ++ * JABBER[CNT] is checked against the packet that arrives from SPU. The ++ * checking is performed before preamble is stripped or PTP is inserted. ++ * If present, preamble is counted as eight bytes of the incoming packet. ++ */ ++union cgxx_smux_rx_jabber { ++ u64 u; ++ struct cgxx_smux_rx_jabber_s { ++ u64 cnt : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_smux_rx_jabber_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_JABBER(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_JABBER(u64 a) ++{ ++ return 0x20030 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_udd_skp ++ * ++ * CGX SMU User-Defined Data Skip Registers Internal: (1) The skip bytes ++ * are part of the packet and will be sent down the NCB packet interface ++ * and will be handled by NIX. (2) The system can determine if the UDD ++ * bytes are included in the FCS check by using the FCSSEL field if the ++ * FCS check is enabled. (3) Assume that the preamble/sfd is always at ++ * the start of the frame even before UDD bytes. In most cases, there ++ * will be no preamble in these cases since it will be packet interface ++ * in direct communication to another packet interface (MAC to MAC) ++ * without a PHY involved. (4) We can still do address filtering and ++ * control packet filtering if the user desires. (5) In all cases, the ++ * UDD bytes will be sent down the packet interface as part of the ++ * packet. The UDD bytes are never stripped from the actual packet. ++ */ ++union cgxx_smux_rx_udd_skp { ++ u64 u; ++ struct cgxx_smux_rx_udd_skp_s { ++ u64 len : 7; ++ u64 reserved_7 : 1; ++ u64 fcssel : 1; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct cgxx_smux_rx_udd_skp_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_UDD_SKP(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_UDD_SKP(u64 a) ++{ ++ return 0x20040 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_wol_ctrl0 ++ * ++ * CGX SMU RX Wake-on-LAN Control 0 Registers ++ */ ++union cgxx_smux_rx_wol_ctrl0 { ++ u64 u; ++ struct cgxx_smux_rx_wol_ctrl0_s { ++ u64 dmac : 48; ++ u64 pswd_len : 4; ++ u64 reserved_52_63 : 12; ++ } s; ++ /* struct cgxx_smux_rx_wol_ctrl0_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_WOL_CTRL0(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_WOL_CTRL0(u64 a) ++{ ++ return 0x20068 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_wol_ctrl1 ++ * ++ * CGX SMU RX Wake-on-LAN Control 1 Registers ++ */ ++union cgxx_smux_rx_wol_ctrl1 { ++ u64 u; ++ struct cgxx_smux_rx_wol_ctrl1_s { ++ u64 pswd : 64; ++ } s; ++ /* struct cgxx_smux_rx_wol_ctrl1_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_WOL_CTRL1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_WOL_CTRL1(u64 a) ++{ ++ return 0x20070 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_wol_int ++ * ++ * CGX SMU RX WOL Interrupt Registers These registers allow WOL ++ * interrupts to be sent to the control processor. ++ */ ++union cgxx_smux_rx_wol_int { ++ u64 u; ++ struct cgxx_smux_rx_wol_int_s { ++ u64 wol_rcvd : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_smux_rx_wol_int_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_WOL_INT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_WOL_INT(u64 a) ++{ ++ return 0x20078 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_wol_int_ena_w1c ++ * ++ * CGX SMU RX WOL Interrupt Enable Clear Registers This register clears ++ * interrupt enable bits. ++ */ ++union cgxx_smux_rx_wol_int_ena_w1c { ++ u64 u; ++ struct cgxx_smux_rx_wol_int_ena_w1c_s { ++ u64 wol_rcvd : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_smux_rx_wol_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_WOL_INT_ENA_W1C(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_WOL_INT_ENA_W1C(u64 a) ++{ ++ return 0x20088 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_wol_int_ena_w1s ++ * ++ * CGX SMU RX WOL Interrupt Enable Set Registers This register sets ++ * interrupt enable bits. ++ */ ++union cgxx_smux_rx_wol_int_ena_w1s { ++ u64 u; ++ struct cgxx_smux_rx_wol_int_ena_w1s_s { ++ u64 wol_rcvd : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_smux_rx_wol_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_WOL_INT_ENA_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_WOL_INT_ENA_W1S(u64 a) ++{ ++ return 0x20090 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_rx_wol_int_w1s ++ * ++ * CGX SMU RX WOL Interrupt Set Registers This register sets interrupt ++ * bits. ++ */ ++union cgxx_smux_rx_wol_int_w1s { ++ u64 u; ++ struct cgxx_smux_rx_wol_int_w1s_s { ++ u64 wol_rcvd : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_smux_rx_wol_int_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_RX_WOL_INT_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_RX_WOL_INT_W1S(u64 a) ++{ ++ return 0x20080 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_smac ++ * ++ * CGX SMU SMAC Registers ++ */ ++union cgxx_smux_smac { ++ u64 u; ++ struct cgxx_smux_smac_s { ++ u64 smac : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_smux_smac_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_SMAC(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_SMAC(u64 a) ++{ ++ return 0x20108 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_append ++ * ++ * CGX SMU TX Append Control Registers For more details on the ++ * interactions between FCS and PAD, see also the description of ++ * CGX()_SMU()_TX_MIN_PKT[MIN_SIZE]. ++ */ ++union cgxx_smux_tx_append { ++ u64 u; ++ struct cgxx_smux_tx_append_s { ++ u64 preamble : 1; ++ u64 pad : 1; ++ u64 fcs_d : 1; ++ u64 fcs_c : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct cgxx_smux_tx_append_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_APPEND(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_APPEND(u64 a) ++{ ++ return 0x20100 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_ctl ++ * ++ * CGX SMU Transmit Control Registers ++ */ ++union cgxx_smux_tx_ctl { ++ u64 u; ++ struct cgxx_smux_tx_ctl_s { ++ u64 dic_en : 1; ++ u64 uni_en : 1; ++ u64 x4a_dis : 1; ++ u64 mia_en : 1; ++ u64 ls : 2; ++ u64 ls_byp : 1; ++ u64 l2p_bp_conv : 1; ++ u64 hg_en : 1; ++ u64 hg_pause_hgi : 2; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct cgxx_smux_tx_ctl_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_CTL(u64 a) ++{ ++ return 0x20178 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_dack ++ * ++ * CGX SMU TX Drop Counters Registers ++ */ ++union cgxx_smux_tx_dack { ++ u64 u; ++ struct cgxx_smux_tx_dack_s { ++ u64 dpi_sdrop_ack : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_smux_tx_dack_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_DACK(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_DACK(u64 a) ++{ ++ return 0x201b0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_dcnt ++ * ++ * CGX SMU TX Drop Counters Registers ++ */ ++union cgxx_smux_tx_dcnt { ++ u64 u; ++ struct cgxx_smux_tx_dcnt_s { ++ u64 dpi_sdrop_cnt : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_smux_tx_dcnt_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_DCNT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_DCNT(u64 a) ++{ ++ return 0x201a8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_eee ++ * ++ * INTERNAL: CGX SMU TX EEE Configure Registers Resvered. Internal: ++ * These registers control when SMU TX requests to enter or exist LPI. ++ * Those registers take effect only when EEE is supported and enabled for ++ * a given LMAC. ++ */ ++union cgxx_smux_tx_eee { ++ u64 u; ++ struct cgxx_smux_tx_eee_s { ++ u64 idle_thresh : 28; ++ u64 reserved_28 : 1; ++ u64 force_lpi : 1; ++ u64 wakeup : 1; ++ u64 auto_lpi : 1; ++ u64 idle_cnt : 28; ++ u64 reserved_60_61 : 2; ++ u64 tx_lpi_wake : 1; ++ u64 tx_lpi : 1; ++ } s; ++ /* struct cgxx_smux_tx_eee_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_EEE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_EEE(u64 a) ++{ ++ return 0x20190 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_eee_timer_status ++ * ++ * INTERNAL: CGX SMU TX EEE TIMER STATUS Registers Reserved. Internal: ++ * These registers configure SMU TX EEE timing parameters. ++ */ ++union cgxx_smux_tx_eee_timer_status { ++ u64 u; ++ struct cgxx_smux_tx_eee_timer_status_s { ++ u64 lpi_wake_cnt : 16; ++ u64 reserved_16_30 : 15; ++ u64 wake_timer_done : 1; ++ u64 link_ok_cnt : 30; ++ u64 reserved_62 : 1; ++ u64 link_timer_done : 1; ++ } s; ++ /* struct cgxx_smux_tx_eee_timer_status_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_EEE_TIMER_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_EEE_TIMER_STATUS(u64 a) ++{ ++ return 0x201a0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_eee_timing ++ * ++ * INTERNAL: CGX SMU TX EEE TIMING Parameter Registers Reserved. ++ * Internal: These registers configure SMU TX EEE timing parameters. ++ */ ++union cgxx_smux_tx_eee_timing { ++ u64 u; ++ struct cgxx_smux_tx_eee_timing_s { ++ u64 w_sys_tx_min : 16; ++ u64 reserved_16_31 : 16; ++ u64 link_ok_min : 30; ++ u64 reserved_62_63 : 2; ++ } s; ++ /* struct cgxx_smux_tx_eee_timing_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_EEE_TIMING(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_EEE_TIMING(u64 a) ++{ ++ return 0x20198 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_ifg ++ * ++ * CGX SMU TX Interframe-Gap Cycles Registers Programming IFG1 and IFG2: ++ * * For XAUI/RXAUI/10G/25G/40G/50G/100G systems that require IEEE 802.3 ++ * compatibility, the [IFG1]+[IFG2] sum must be 12. * In loopback mode, ++ * the [IFG1]+[IFG2] of local and remote parties must match exactly; ++ * otherwise loopback FIFO will overrun: CGX()_SMU()_TX_INT[LB_OVRFLW]. * ++ * When CGX()_SMU()_TX_CTL[DIC_EN] is set, [IFG1]+[IFG2] sum must be at ++ * least 8. The behavior of smaller values is un-determined. * When ++ * CGX()_SMU()_TX_CTL[DIC_EN] is cleared, the minimum value of ++ * [IFG1]+[IFG2] is 1 for 40G/50G/100G LMAC_TYPE configurations and 5 for ++ * all other values. The behavior of smaller values is un-determined. ++ * Internal: When CGX()_SMU()_TX_CTL[DIC_EN] is set, SMU TX treats ++ * ([IFG1]+[IFG2]) \< 8 as 8 for 40G/50G/100G MACs and ([IFG1]+[IFG2]) \< ++ * 8 as 8 for other MACs. When CGX()_SMU()_TX_CTL[DIC_EN] is cleared, SMU ++ * TX can work correctly with any IFG1 and IFG2. ++ */ ++union cgxx_smux_tx_ifg { ++ u64 u; ++ struct cgxx_smux_tx_ifg_s { ++ u64 ifg1 : 4; ++ u64 ifg2 : 4; ++ u64 mia_amt : 2; ++ u64 reserved_10_15 : 6; ++ u64 mia_cnt : 8; ++ u64 reserved_24_63 : 40; ++ } s; ++ /* struct cgxx_smux_tx_ifg_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_IFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_IFG(u64 a) ++{ ++ return 0x20160 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_int ++ * ++ * CGX SMU TX Interrupt Registers ++ */ ++union cgxx_smux_tx_int { ++ u64 u; ++ struct cgxx_smux_tx_int_s { ++ u64 undflw : 1; ++ u64 xchange : 1; ++ u64 fake_commit : 1; ++ u64 lb_undflw : 1; ++ u64 lb_ovrflw : 1; ++ u64 dpi_sdrop : 1; ++ u64 reserved_6_63 : 58; ++ } s; ++ /* struct cgxx_smux_tx_int_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_INT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_INT(u64 a) ++{ ++ return 0x20140 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_int_ena_w1c ++ * ++ * CGX SMU TX Interrupt Enable Clear Registers This register clears ++ * interrupt enable bits. ++ */ ++union cgxx_smux_tx_int_ena_w1c { ++ u64 u; ++ struct cgxx_smux_tx_int_ena_w1c_s { ++ u64 undflw : 1; ++ u64 xchange : 1; ++ u64 fake_commit : 1; ++ u64 lb_undflw : 1; ++ u64 lb_ovrflw : 1; ++ u64 dpi_sdrop : 1; ++ u64 reserved_6_63 : 58; ++ } s; ++ /* struct cgxx_smux_tx_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_INT_ENA_W1C(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_INT_ENA_W1C(u64 a) ++{ ++ return 0x20150 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_int_ena_w1s ++ * ++ * CGX SMU TX Interrupt Enable Set Registers This register sets interrupt ++ * enable bits. ++ */ ++union cgxx_smux_tx_int_ena_w1s { ++ u64 u; ++ struct cgxx_smux_tx_int_ena_w1s_s { ++ u64 undflw : 1; ++ u64 xchange : 1; ++ u64 fake_commit : 1; ++ u64 lb_undflw : 1; ++ u64 lb_ovrflw : 1; ++ u64 dpi_sdrop : 1; ++ u64 reserved_6_63 : 58; ++ } s; ++ /* struct cgxx_smux_tx_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_INT_ENA_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_INT_ENA_W1S(u64 a) ++{ ++ return 0x20158 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_int_w1s ++ * ++ * CGX SMU TX Interrupt Set Registers This register sets interrupt bits. ++ */ ++union cgxx_smux_tx_int_w1s { ++ u64 u; ++ struct cgxx_smux_tx_int_w1s_s { ++ u64 undflw : 1; ++ u64 xchange : 1; ++ u64 fake_commit : 1; ++ u64 lb_undflw : 1; ++ u64 lb_ovrflw : 1; ++ u64 dpi_sdrop : 1; ++ u64 reserved_6_63 : 58; ++ } s; ++ /* struct cgxx_smux_tx_int_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_INT_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_INT_W1S(u64 a) ++{ ++ return 0x20148 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_min_pkt ++ * ++ * CGX SMU TX Minimum-Size-Packet Registers Internal: [MIN_SIZE] less ++ * than 16 will be ignored by hardware which will use 16 instead. ++ */ ++union cgxx_smux_tx_min_pkt { ++ u64 u; ++ struct cgxx_smux_tx_min_pkt_s { ++ u64 min_size : 8; ++ u64 reserved_8_63 : 56; ++ } s; ++ /* struct cgxx_smux_tx_min_pkt_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_MIN_PKT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_MIN_PKT(u64 a) ++{ ++ return 0x20118 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_pause_pkt_dmac ++ * ++ * CGX SMU TX PAUSE-Packet DMAC-Field Registers This register provides ++ * the DMAC value that is placed in outbound PAUSE packets. ++ */ ++union cgxx_smux_tx_pause_pkt_dmac { ++ u64 u; ++ struct cgxx_smux_tx_pause_pkt_dmac_s { ++ u64 dmac : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_smux_tx_pause_pkt_dmac_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_PAUSE_PKT_DMAC(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_PAUSE_PKT_DMAC(u64 a) ++{ ++ return 0x20168 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_pause_pkt_interval ++ * ++ * CGX SMU TX PAUSE-Packet Transmission-Interval Registers This register ++ * specifies how often PAUSE packets are sent. ++ */ ++union cgxx_smux_tx_pause_pkt_interval { ++ u64 u; ++ struct cgxx_smux_tx_pause_pkt_interval_s { ++ u64 interval : 16; ++ u64 hg2_intra_interval : 16; ++ u64 hg2_intra_en : 1; ++ u64 reserved_33_63 : 31; ++ } s; ++ /* struct cgxx_smux_tx_pause_pkt_interval_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_PAUSE_PKT_INTERVAL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_PAUSE_PKT_INTERVAL(u64 a) ++{ ++ return 0x20120 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_pause_pkt_time ++ * ++ * CGX SMU TX PAUSE Packet Time Registers ++ */ ++union cgxx_smux_tx_pause_pkt_time { ++ u64 u; ++ struct cgxx_smux_tx_pause_pkt_time_s { ++ u64 p_time : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_smux_tx_pause_pkt_time_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_PAUSE_PKT_TIME(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_PAUSE_PKT_TIME(u64 a) ++{ ++ return 0x20110 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_pause_pkt_type ++ * ++ * CGX SMU TX PAUSE-Packet P_TYPE-Field Registers This register provides ++ * the P_TYPE field that is placed in outbound PAUSE packets. ++ */ ++union cgxx_smux_tx_pause_pkt_type { ++ u64 u; ++ struct cgxx_smux_tx_pause_pkt_type_s { ++ u64 p_type : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_smux_tx_pause_pkt_type_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_PAUSE_PKT_TYPE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_PAUSE_PKT_TYPE(u64 a) ++{ ++ return 0x20170 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_pause_togo ++ * ++ * CGX SMU TX Time-to-Backpressure Registers ++ */ ++union cgxx_smux_tx_pause_togo { ++ u64 u; ++ struct cgxx_smux_tx_pause_togo_s { ++ u64 p_time : 16; ++ u64 msg_time : 16; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct cgxx_smux_tx_pause_togo_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_PAUSE_TOGO(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_PAUSE_TOGO(u64 a) ++{ ++ return 0x20130 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_pause_zero ++ * ++ * CGX SMU TX PAUSE Zero Registers ++ */ ++union cgxx_smux_tx_pause_zero { ++ u64 u; ++ struct cgxx_smux_tx_pause_zero_s { ++ u64 send : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_smux_tx_pause_zero_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_PAUSE_ZERO(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_PAUSE_ZERO(u64 a) ++{ ++ return 0x20138 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_soft_pause ++ * ++ * CGX SMU TX Soft PAUSE Registers ++ */ ++union cgxx_smux_tx_soft_pause { ++ u64 u; ++ struct cgxx_smux_tx_soft_pause_s { ++ u64 p_time : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_smux_tx_soft_pause_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_SOFT_PAUSE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_SOFT_PAUSE(u64 a) ++{ ++ return 0x20128 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_smu#_tx_thresh ++ * ++ * CGX SMU TX Threshold Registers ++ */ ++union cgxx_smux_tx_thresh { ++ u64 u; ++ struct cgxx_smux_tx_thresh_s { ++ u64 cnt : 12; ++ u64 reserved_12_15 : 4; ++ u64 dpi_thresh : 5; ++ u64 reserved_21_23 : 3; ++ u64 dpi_depth : 5; ++ u64 reserved_29_31 : 3; ++ u64 ecnt : 12; ++ u64 reserved_44_63 : 20; ++ } s; ++ /* struct cgxx_smux_tx_thresh_s cn; */ ++}; ++ ++static inline u64 CGXX_SMUX_TX_THRESH(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SMUX_TX_THRESH(u64 a) ++{ ++ return 0x20180 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_an_adv ++ * ++ * CGX SPU Autonegotiation Advertisement Registers Software programs this ++ * register with the contents of the AN-link code word base page to be ++ * transmitted during autonegotiation. (See IEEE 802.3 section 73.6 for ++ * details.) Any write operations to this register prior to completion of ++ * autonegotiation, as indicated by CGX()_SPU()_AN_STATUS[AN_COMPLETE], ++ * should be followed by a renegotiation in order for the new values to ++ * take effect. Renegotiation is initiated by setting ++ * CGX()_SPU()_AN_CONTROL[AN_RESTART]. Once autonegotiation has ++ * completed, software can examine this register along with ++ * CGX()_SPU()_AN_LP_BASE to determine the highest common denominator ++ * technology. ++ */ ++union cgxx_spux_an_adv { ++ u64 u; ++ struct cgxx_spux_an_adv_s { ++ u64 s : 5; ++ u64 e : 5; ++ u64 pause : 1; ++ u64 asm_dir : 1; ++ u64 xnp_able : 1; ++ u64 rf : 1; ++ u64 ack : 1; ++ u64 np : 1; ++ u64 t : 5; ++ u64 a1g_kx : 1; ++ u64 a10g_kx4 : 1; ++ u64 a10g_kr : 1; ++ u64 a40g_kr4 : 1; ++ u64 a40g_cr4 : 1; ++ u64 a100g_cr10 : 1; ++ u64 a100g_kp4 : 1; ++ u64 a100g_kr4 : 1; ++ u64 a100g_cr4 : 1; ++ u64 a25g_krs_crs : 1; ++ u64 a25g_kr_cr : 1; ++ u64 arsv : 12; ++ u64 a25g_rs_fec_req : 1; ++ u64 a25g_br_fec_req : 1; ++ u64 fec_able : 1; ++ u64 fec_req : 1; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_spux_an_adv_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_AN_ADV(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_AN_ADV(u64 a) ++{ ++ return 0x10198 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_an_bp_status ++ * ++ * CGX SPU Autonegotiation Backplane Ethernet & BASE-R Copper Status ++ * Registers The contents of this register are updated during ++ * autonegotiation and are valid when CGX()_SPU()_AN_STATUS[AN_COMPLETE] ++ * is set. At that time, one of the port type bits will be set depending ++ * on the AN priority resolution. The port types are listed in order of ++ * decreasing priority. If a BASE-R type is negotiated then [FEC] or ++ * [RS_FEC] will be set to indicate whether/which FEC operation has been ++ * negotiated and will be clear otherwise. ++ */ ++union cgxx_spux_an_bp_status { ++ u64 u; ++ struct cgxx_spux_an_bp_status_s { ++ u64 bp_an_able : 1; ++ u64 n1g_kx : 1; ++ u64 n10g_kx4 : 1; ++ u64 n10g_kr : 1; ++ u64 n25g_kr1 : 1; ++ u64 n25g_cr1 : 1; ++ u64 n25g_krs_crs : 1; ++ u64 n25g_kr_cr : 1; ++ u64 n40g_kr4 : 1; ++ u64 n40g_cr4 : 1; ++ u64 n50g_kr2 : 1; ++ u64 n50g_cr2 : 1; ++ u64 n100g_cr10 : 1; ++ u64 n100g_kp4 : 1; ++ u64 n100g_kr4 : 1; ++ u64 n100g_cr4 : 1; ++ u64 fec : 1; ++ u64 rs_fec : 1; ++ u64 reserved_18_63 : 46; ++ } s; ++ /* struct cgxx_spux_an_bp_status_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_AN_BP_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_AN_BP_STATUS(u64 a) ++{ ++ return 0x101b8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_an_control ++ * ++ * CGX SPU Autonegotiation Control Registers ++ */ ++union cgxx_spux_an_control { ++ u64 u; ++ struct cgxx_spux_an_control_s { ++ u64 reserved_0_8 : 9; ++ u64 an_restart : 1; ++ u64 reserved_10_11 : 2; ++ u64 an_en : 1; ++ u64 xnp_en : 1; ++ u64 reserved_14 : 1; ++ u64 an_reset : 1; ++ u64 an_arb_link_chk_en : 1; ++ u64 usx_an_arb_link_chk_en : 1; ++ u64 reserved_18_63 : 46; ++ } s; ++ /* struct cgxx_spux_an_control_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_AN_CONTROL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_AN_CONTROL(u64 a) ++{ ++ return 0x10188 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_an_lp_base ++ * ++ * CGX SPU Autonegotiation Link-Partner Base-Page Ability Registers This ++ * register captures the contents of the latest AN link code word base ++ * page received from the link partner during autonegotiation. (See IEEE ++ * 802.3 section 73.6 for details.) CGX()_SPU()_AN_STATUS[PAGE_RX] is set ++ * when this register is updated by hardware. ++ */ ++union cgxx_spux_an_lp_base { ++ u64 u; ++ struct cgxx_spux_an_lp_base_s { ++ u64 s : 5; ++ u64 e : 5; ++ u64 pause : 1; ++ u64 asm_dir : 1; ++ u64 xnp_able : 1; ++ u64 rf : 1; ++ u64 ack : 1; ++ u64 np : 1; ++ u64 t : 5; ++ u64 a1g_kx : 1; ++ u64 a10g_kx4 : 1; ++ u64 a10g_kr : 1; ++ u64 a40g_kr4 : 1; ++ u64 a40g_cr4 : 1; ++ u64 a100g_cr10 : 1; ++ u64 a100g_kp4 : 1; ++ u64 a100g_kr4 : 1; ++ u64 a100g_cr4 : 1; ++ u64 a25g_krs_crs : 1; ++ u64 a25g_kr_cr : 1; ++ u64 arsv : 12; ++ u64 a25g_rs_fec_req : 1; ++ u64 a25g_br_fec_req : 1; ++ u64 fec_able : 1; ++ u64 fec_req : 1; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_spux_an_lp_base_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_AN_LP_BASE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_AN_LP_BASE(u64 a) ++{ ++ return 0x101a0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_an_lp_xnp ++ * ++ * CGX SPU Autonegotiation Link Partner Extended Next Page Ability ++ * Registers This register captures the contents of the latest next page ++ * code word received from the link partner during autonegotiation, if ++ * any. See IEEE 802.3 section 73.7.7 for details. ++ */ ++union cgxx_spux_an_lp_xnp { ++ u64 u; ++ struct cgxx_spux_an_lp_xnp_s { ++ u64 m_u : 11; ++ u64 toggle : 1; ++ u64 ack2 : 1; ++ u64 mp : 1; ++ u64 ack : 1; ++ u64 np : 1; ++ u64 u : 32; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_spux_an_lp_xnp_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_AN_LP_XNP(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_AN_LP_XNP(u64 a) ++{ ++ return 0x101b0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_an_status ++ * ++ * CGX SPU Autonegotiation Status Registers ++ */ ++union cgxx_spux_an_status { ++ u64 u; ++ struct cgxx_spux_an_status_s { ++ u64 lp_an_able : 1; ++ u64 reserved_1 : 1; ++ u64 link_status : 1; ++ u64 an_able : 1; ++ u64 rmt_flt : 1; ++ u64 an_complete : 1; ++ u64 page_rx : 1; ++ u64 xnp_stat : 1; ++ u64 reserved_8 : 1; ++ u64 prl_flt : 1; ++ u64 reserved_10_63 : 54; ++ } s; ++ /* struct cgxx_spux_an_status_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_AN_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_AN_STATUS(u64 a) ++{ ++ return 0x10190 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_an_xnp_tx ++ * ++ * CGX SPU Autonegotiation Extended Next Page Transmit Registers Software ++ * programs this register with the contents of the AN message next page ++ * or unformatted next page link code word to be transmitted during ++ * autonegotiation. Next page exchange occurs after the base link code ++ * words have been exchanged if either end of the link segment sets the ++ * NP bit to 1, indicating that it has at least one next page to send. ++ * Once initiated, next page exchange continues until both ends of the ++ * link segment set their NP bits to 0. See IEEE 802.3 section 73.7.7 for ++ * details. ++ */ ++union cgxx_spux_an_xnp_tx { ++ u64 u; ++ struct cgxx_spux_an_xnp_tx_s { ++ u64 m_u : 11; ++ u64 toggle : 1; ++ u64 ack2 : 1; ++ u64 mp : 1; ++ u64 ack : 1; ++ u64 np : 1; ++ u64 u : 32; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct cgxx_spux_an_xnp_tx_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_AN_XNP_TX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_AN_XNP_TX(u64 a) ++{ ++ return 0x101a8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_br_algn_status ++ * ++ * CGX SPU Multilane BASE-R PCS Alignment-Status Registers This register ++ * implements the IEEE 802.3 multilane BASE-R PCS alignment status 1-4 ++ * registers (3.50-3.53). It is valid only when the LPCS type is ++ * 40GBASE-R, 50GBASE-R, 100GBASE-R, (CGX()_CMR()_CONFIG[LMAC_TYPE] = ++ * CGX_LMAC_TYPES_E::FORTYG_R,FIFTYG_R,HUNDREDG_R), and always returns ++ * 0x0 for all other LPCS types. Service interfaces (lanes) 19-0 (100G) ++ * and 3-0 (all others) are mapped to PCS lanes 19-0 or 3-0 via ++ * CGX()_SPU()_BR_LANE_MAP()[LN_MAPPING]. For 100G, logical lane 0 fans ++ * out to service interfaces 0-4, logical lane 1 fans out to service ++ * interfaces 5-9, ... etc. For all other modes, logical lanes and ++ * service interfaces are identical. Logical interfaces (lanes) map to ++ * SerDes lanes via CGX()_CMR()_CONFIG[LANE_TO_SDS] (programmable). ++ */ ++union cgxx_spux_br_algn_status { ++ u64 u; ++ struct cgxx_spux_br_algn_status_s { ++ u64 block_lock : 20; ++ u64 reserved_20_29 : 10; ++ u64 alignd : 1; ++ u64 reserved_31_40 : 10; ++ u64 marker_lock : 20; ++ u64 reserved_61_63 : 3; ++ } s; ++ /* struct cgxx_spux_br_algn_status_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_BR_ALGN_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_BR_ALGN_STATUS(u64 a) ++{ ++ return 0x10050 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_br_lane_map# ++ * ++ * CGX SPU 40,50,100GBASE-R Lane-Mapping Registers This register ++ * implements the IEEE 802.3 lane 0-19 mapping registers (3.400-3.403). ++ * It is valid only when the LPCS type is 40GBASE-R, 50GBASE-R, ++ * 100GBASE-R, USXGMII (CGX()_CMR()_CONFIG[LMAC_TYPE]), and always ++ * returns 0x0 for all other LPCS types. The LNx_MAPPING field for each ++ * programmed PCS lane (called service interface in 802.3) is valid when ++ * that lane has achieved alignment marker lock on the receive side (i.e. ++ * the associated CGX()_SPU()_BR_ALGN_STATUS[MARKER_LOCK] = 1), and is ++ * invalid otherwise. When valid, it returns the actual detected receive ++ * PCS lane number based on the received alignment marker contents ++ * received on that service interface. In RS-FEC mode the LNx_MAPPING ++ * field is valid when that lane has achieved alignment marker lock on ++ * the receive side (i.e. the associated ++ * CGX(0..3)_SPU(0..3)_RSFEC_STATUS[AMPS_LOCK] = 1), and is invalid ++ * otherwise. When valid, it returns the actual detected receive FEC lane ++ * number based on the received alignment marker contents received on ++ * that logical lane therefore expect for RS-FEC that LNx_MAPPING = x. ++ * The mapping is flexible because IEEE 802.3 allows multilane BASE-R ++ * receive lanes to be re-ordered. Note that for the transmit side, each ++ * logical lane is mapped to a physical SerDes lane based on the ++ * programming of CGX()_CMR()_CONFIG[LANE_TO_SDS]. For the receive side, ++ * CGX()_CMR()_CONFIG[LANE_TO_SDS] specifies the logical lane to physical ++ * SerDes lane mapping, and this register specifies the service interface ++ * (or lane) to PCS lane mapping. ++ */ ++union cgxx_spux_br_lane_mapx { ++ u64 u; ++ struct cgxx_spux_br_lane_mapx_s { ++ u64 ln_mapping : 6; ++ u64 reserved_6_63 : 58; ++ } s; ++ /* struct cgxx_spux_br_lane_mapx_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_BR_LANE_MAPX(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_BR_LANE_MAPX(u64 a, u64 b) ++{ ++ return 0x10600 + 0x40000 * a + 8 * b; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_br_pmd_control ++ * ++ * CGX SPU BASE-R PMD Control Registers ++ */ ++union cgxx_spux_br_pmd_control { ++ u64 u; ++ struct cgxx_spux_br_pmd_control_s { ++ u64 train_restart : 1; ++ u64 train_en : 1; ++ u64 use_lane_poly : 1; ++ u64 max_wait_disable : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ struct cgxx_spux_br_pmd_control_cn96xx { ++ u64 train_restart : 1; ++ u64 train_en : 1; ++ u64 use_lane_poly : 1; ++ u64 reserved_3_63 : 61; ++ } cn96xx; ++ /* struct cgxx_spux_br_pmd_control_cn96xx cn98xx; */ ++ /* struct cgxx_spux_br_pmd_control_s cnf95xxp1; */ ++ /* struct cgxx_spux_br_pmd_control_cn96xx cnf95xxp2; */ ++ /* struct cgxx_spux_br_pmd_control_cn96xx loki; */ ++}; ++ ++static inline u64 CGXX_SPUX_BR_PMD_CONTROL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_BR_PMD_CONTROL(u64 a) ++{ ++ return 0x100a8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_br_pmd_ld_cup ++ * ++ * CGX SPU BASE-R PMD Local Device Coefficient Update Registers This ++ * register implements MDIO register 1.154 of 802.3-2012 Section 5 CL45 ++ * for 10GBASE-R and and of 802.3by-2016 CL45 for 25GBASE-R. Note that ++ * for 10G, 25G LN0_ only is used. It implements MDIO registers ++ * 1.1300-1.1303 for all other BASE-R modes (40G, 50G, 100G) per ++ * 802.3bj-2014 CL45. Note that for 50G LN0_ and LN1_ only are used. The ++ * fields in this register are read/write even though they are specified ++ * as read-only in 802.3. The register is automatically cleared at the ++ * start of training. When link training is in progress, each field ++ * reflects the contents of the coefficient update field in the ++ * associated lane's outgoing training frame. If ++ * CGX()_SPU_DBG_CONTROL[BR_PMD_TRAIN_SOFT_EN] is set, then this register ++ * must be updated by software during link training and hardware updates ++ * are disabled. If CGX()_SPU_DBG_CONTROL[BR_PMD_TRAIN_SOFT_EN] is clear, ++ * this register is automatically updated by hardware, and it should not ++ * be written by software. The lane fields in this register are indexed ++ * by logical PCS lane ID. ++ */ ++union cgxx_spux_br_pmd_ld_cup { ++ u64 u; ++ struct cgxx_spux_br_pmd_ld_cup_s { ++ u64 ln0_cup : 16; ++ u64 ln1_cup : 16; ++ u64 ln2_cup : 16; ++ u64 ln3_cup : 16; ++ } s; ++ /* struct cgxx_spux_br_pmd_ld_cup_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_BR_PMD_LD_CUP(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_BR_PMD_LD_CUP(u64 a) ++{ ++ return 0x100c8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_br_pmd_ld_rep ++ * ++ * CGX SPU BASE-R PMD Local Device Status Report Registers This register ++ * implements MDIO register 1.155 of 802.3-2012 Section 5 CL45 for ++ * 10GBASE-R and and of 802.3by-2016 CL45 for 25GBASE-R. Note that for ++ * 10G, 25G LN0_ only is used. It implements MDIO registers ++ * 1.1400-1.1403 for all other BASE-R modes (40G, 50G, 100G) per ++ * 802.3bj-2014 CL45. Note that for 50G LN0_ and LN1_ only are used. The ++ * fields in this register are read/write even though they are specified ++ * as read-only in 802.3. The register is automatically cleared at the ++ * start of training. Each field reflects the contents of the status ++ * report field in the associated lane's outgoing training frame. If ++ * CGX()_SPU_DBG_CONTROL[BR_PMD_TRAIN_SOFT_EN] is set, then this register ++ * must be updated by software during link training and hardware updates ++ * are disabled. If CGX()_SPU_DBG_CONTROL[BR_PMD_TRAIN_SOFT_EN] is clear, ++ * this register is automatically updated by hardware, and it should not ++ * be written by software. The lane fields in this register are indexed ++ * by logical PCS lane ID. ++ */ ++union cgxx_spux_br_pmd_ld_rep { ++ u64 u; ++ struct cgxx_spux_br_pmd_ld_rep_s { ++ u64 ln0_rep : 16; ++ u64 ln1_rep : 16; ++ u64 ln2_rep : 16; ++ u64 ln3_rep : 16; ++ } s; ++ /* struct cgxx_spux_br_pmd_ld_rep_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_BR_PMD_LD_REP(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_BR_PMD_LD_REP(u64 a) ++{ ++ return 0x100d0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_br_pmd_lp_cup ++ * ++ * CGX SPU BASE-R PMD Link Partner Coefficient Update Registers This ++ * register implements MDIO register 1.152 of 802.3-2012 Section 5 CL45 ++ * for 10GBASE-R and and of 802.3by-2016 CL45 for 25GBASE-R. Note that ++ * for 10G, 25G LN0_ only is used. It implements MDIO registers ++ * 1.1100-1.1103 for all other BASE-R modes (40G, 50G, 100G) per ++ * 802.3bj-2014 CL45. Note that for 50G LN0_ and LN1_ only are used. The ++ * register is automatically cleared at the start of training. Each field ++ * reflects the contents of the coefficient update field in the lane's ++ * most recently received training frame. This register should not be ++ * written when link training is enabled, i.e. when ++ * CGX()_SPU()_BR_PMD_CONTROL[TRAIN_EN] is set. The lane fields in this ++ * register are indexed by logical PCS lane ID. ++ */ ++union cgxx_spux_br_pmd_lp_cup { ++ u64 u; ++ struct cgxx_spux_br_pmd_lp_cup_s { ++ u64 ln0_cup : 16; ++ u64 ln1_cup : 16; ++ u64 ln2_cup : 16; ++ u64 ln3_cup : 16; ++ } s; ++ /* struct cgxx_spux_br_pmd_lp_cup_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_BR_PMD_LP_CUP(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_BR_PMD_LP_CUP(u64 a) ++{ ++ return 0x100b8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_br_pmd_lp_rep ++ * ++ * CGX SPU BASE-R PMD Link Partner Status Report Registers This register ++ * implements MDIO register 1.153 of 802.3-2012 Section 5 CL45 for ++ * 10GBASE-R and and of 802.3by-2016 CL45 for 25GBASE-R. Note that for ++ * 10G, 25G LN0_ only is used. It implements MDIO registers ++ * 1.1200-1.1203 for all other BASE-R modes (40G, 50G, 100G) per ++ * 802.3bj-2014 CL45. Note that for 50G LN0_ and LN1_ only are used. The ++ * register is automatically cleared at the start of training. Each field ++ * reflects the contents of the coefficient update field in the lane's ++ * most recently received training frame. This register should not be ++ * written when link training is enabled, i.e. when ++ * CGX()_SPU()_BR_PMD_CONTROL[TRAIN_EN] is set. The lane fields in this ++ * register are indexed by logical PCS lane ID. ++ */ ++union cgxx_spux_br_pmd_lp_rep { ++ u64 u; ++ struct cgxx_spux_br_pmd_lp_rep_s { ++ u64 ln0_rep : 16; ++ u64 ln1_rep : 16; ++ u64 ln2_rep : 16; ++ u64 ln3_rep : 16; ++ } s; ++ /* struct cgxx_spux_br_pmd_lp_rep_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_BR_PMD_LP_REP(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_BR_PMD_LP_REP(u64 a) ++{ ++ return 0x100c0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_br_pmd_status ++ * ++ * CGX SPU BASE-R PMD Status Registers The lane fields in this register ++ * are indexed by logical PCS lane ID. The lane 0 field (LN0_*) is valid ++ * for 10GBASE-R, 25GBASE-R, 40GBASE-R, 50GBASE-R and 100GBASE-R. The ++ * lane 1 field (LN1_*) is valid for 40GBASE-R, 50GBASE-R and 100GBASE-R. ++ * The remaining fields (LN2_*, LN3_*) are only valid for 40GBASE-R and ++ * 100GBASE-R. ++ */ ++union cgxx_spux_br_pmd_status { ++ u64 u; ++ struct cgxx_spux_br_pmd_status_s { ++ u64 ln0_train_status : 4; ++ u64 ln1_train_status : 4; ++ u64 ln2_train_status : 4; ++ u64 ln3_train_status : 4; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_spux_br_pmd_status_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_BR_PMD_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_BR_PMD_STATUS(u64 a) ++{ ++ return 0x100b0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_br_status1 ++ * ++ * CGX SPU BASE-R Status 1 Registers ++ */ ++union cgxx_spux_br_status1 { ++ u64 u; ++ struct cgxx_spux_br_status1_s { ++ u64 blk_lock : 1; ++ u64 hi_ber : 1; ++ u64 prbs31 : 1; ++ u64 prbs9 : 1; ++ u64 reserved_4_11 : 8; ++ u64 rcv_lnk : 1; ++ u64 reserved_13_63 : 51; ++ } s; ++ /* struct cgxx_spux_br_status1_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_BR_STATUS1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_BR_STATUS1(u64 a) ++{ ++ return 0x10030 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_br_status2 ++ * ++ * CGX SPU BASE-R Status 2 Registers This register implements a ++ * combination of the following IEEE 802.3 registers: * BASE-R PCS status ++ * 2 (MDIO address 3.33). * BASE-R BER high-order counter (MDIO address ++ * 3.44). * Errored-blocks high-order counter (MDIO address 3.45). Note ++ * that the relative locations of some fields have been moved from IEEE ++ * 802.3 in order to make the register layout more software friendly: the ++ * BER counter high-order and low-order bits from sections 3.44 and 3.33 ++ * have been combined into the contiguous, 22-bit [BER_CNT] field; ++ * likewise, the errored-blocks counter high-order and low-order bits ++ * from section 3.45 have been combined into the contiguous, 22-bit ++ * [ERR_BLKS] field. ++ */ ++union cgxx_spux_br_status2 { ++ u64 u; ++ struct cgxx_spux_br_status2_s { ++ u64 reserved_0_13 : 14; ++ u64 latched_ber : 1; ++ u64 latched_lock : 1; ++ u64 ber_cnt : 22; ++ u64 reserved_38_39 : 2; ++ u64 err_blks : 22; ++ u64 reserved_62_63 : 2; ++ } s; ++ /* struct cgxx_spux_br_status2_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_BR_STATUS2(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_BR_STATUS2(u64 a) ++{ ++ return 0x10038 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_br_tp_control ++ * ++ * CGX SPU BASE-R Test-Pattern Control Registers Refer to the test ++ * pattern methodology described in 802.3 sections 49.2.8 and 82.2.10. ++ */ ++union cgxx_spux_br_tp_control { ++ u64 u; ++ struct cgxx_spux_br_tp_control_s { ++ u64 dp_sel : 1; ++ u64 tp_sel : 1; ++ u64 rx_tp_en : 1; ++ u64 tx_tp_en : 1; ++ u64 prbs31_tx : 1; ++ u64 prbs31_rx : 1; ++ u64 prbs9_tx : 1; ++ u64 scramble_tp : 2; ++ u64 pr_tp_data_type : 1; ++ u64 reserved_10_63 : 54; ++ } s; ++ /* struct cgxx_spux_br_tp_control_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_BR_TP_CONTROL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_BR_TP_CONTROL(u64 a) ++{ ++ return 0x10040 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_br_tp_err_cnt ++ * ++ * CGX SPU BASE-R Test-Pattern Error-Count Registers This register ++ * provides the BASE-R PCS test-pattern error counter. ++ */ ++union cgxx_spux_br_tp_err_cnt { ++ u64 u; ++ struct cgxx_spux_br_tp_err_cnt_s { ++ u64 err_cnt : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_spux_br_tp_err_cnt_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_BR_TP_ERR_CNT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_BR_TP_ERR_CNT(u64 a) ++{ ++ return 0x10048 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_br_tp_seed_a ++ * ++ * CGX SPU BASE-R Test-Pattern Seed A Registers Refer to the test pattern ++ * methodology described in 802.3 sections 49.2.8 and 82.2.10. ++ */ ++union cgxx_spux_br_tp_seed_a { ++ u64 u; ++ struct cgxx_spux_br_tp_seed_a_s { ++ u64 tp_seed_a : 58; ++ u64 reserved_58_63 : 6; ++ } s; ++ /* struct cgxx_spux_br_tp_seed_a_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_BR_TP_SEED_A(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_BR_TP_SEED_A(u64 a) ++{ ++ return 0x10060 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_br_tp_seed_b ++ * ++ * CGX SPU BASE-R Test-Pattern Seed B Registers Refer to the test pattern ++ * methodology described in 802.3 sections 49.2.8 and 82.2.10. ++ */ ++union cgxx_spux_br_tp_seed_b { ++ u64 u; ++ struct cgxx_spux_br_tp_seed_b_s { ++ u64 tp_seed_b : 58; ++ u64 reserved_58_63 : 6; ++ } s; ++ /* struct cgxx_spux_br_tp_seed_b_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_BR_TP_SEED_B(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_BR_TP_SEED_B(u64 a) ++{ ++ return 0x10068 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_bx_status ++ * ++ * CGX SPU BASE-X Status Registers ++ */ ++union cgxx_spux_bx_status { ++ u64 u; ++ struct cgxx_spux_bx_status_s { ++ u64 lsync : 4; ++ u64 reserved_4_10 : 7; ++ u64 pattst : 1; ++ u64 alignd : 1; ++ u64 reserved_13_63 : 51; ++ } s; ++ /* struct cgxx_spux_bx_status_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_BX_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_BX_STATUS(u64 a) ++{ ++ return 0x10028 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_control1 ++ * ++ * CGX SPU Control 1 Registers ++ */ ++union cgxx_spux_control1 { ++ u64 u; ++ struct cgxx_spux_control1_s { ++ u64 reserved_0_1 : 2; ++ u64 spd : 4; ++ u64 spdsel0 : 1; ++ u64 reserved_7_10 : 4; ++ u64 lo_pwr : 1; ++ u64 reserved_12 : 1; ++ u64 spdsel1 : 1; ++ u64 loopbck : 1; ++ u64 reset : 1; ++ u64 usxgmii_type : 3; ++ u64 usxgmii_rate : 3; ++ u64 disable_am : 1; ++ u64 reserved_23_63 : 41; ++ } s; ++ struct cgxx_spux_control1_cn96xxp1 { ++ u64 reserved_0_1 : 2; ++ u64 spd : 4; ++ u64 spdsel0 : 1; ++ u64 reserved_7_10 : 4; ++ u64 lo_pwr : 1; ++ u64 reserved_12 : 1; ++ u64 spdsel1 : 1; ++ u64 loopbck : 1; ++ u64 reset : 1; ++ u64 usxgmii_type : 3; ++ u64 usxgmii_rate : 3; ++ u64 reserved_22_63 : 42; ++ } cn96xxp1; ++ /* struct cgxx_spux_control1_s cn96xxp3; */ ++ /* struct cgxx_spux_control1_cn96xxp1 cn98xx; */ ++ /* struct cgxx_spux_control1_cn96xxp1 cnf95xx; */ ++ /* struct cgxx_spux_control1_cn96xxp1 loki; */ ++}; ++ ++static inline u64 CGXX_SPUX_CONTROL1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_CONTROL1(u64 a) ++{ ++ return 0x10000 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_control2 ++ * ++ * CGX SPU Control 2 Registers ++ */ ++union cgxx_spux_control2 { ++ u64 u; ++ struct cgxx_spux_control2_s { ++ u64 pcs_type : 4; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct cgxx_spux_control2_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_CONTROL2(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_CONTROL2(u64 a) ++{ ++ return 0x10018 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_fec_abil ++ * ++ * CGX SPU Forward Error Correction Ability Registers ++ */ ++union cgxx_spux_fec_abil { ++ u64 u; ++ struct cgxx_spux_fec_abil_s { ++ u64 fec_abil : 1; ++ u64 err_abil : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct cgxx_spux_fec_abil_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_FEC_ABIL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_FEC_ABIL(u64 a) ++{ ++ return 0x100d8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_fec_control ++ * ++ * CGX SPU Forward Error Correction Control Registers ++ */ ++union cgxx_spux_fec_control { ++ u64 u; ++ struct cgxx_spux_fec_control_s { ++ u64 fec_en : 2; ++ u64 err_en : 1; ++ u64 fec_byp_ind_en : 1; ++ u64 fec_byp_cor_en : 1; ++ u64 reserved_5_63 : 59; ++ } s; ++ /* struct cgxx_spux_fec_control_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_FEC_CONTROL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_FEC_CONTROL(u64 a) ++{ ++ return 0x100e0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_fec_ln#_rsfec_err ++ * ++ * CGX SPU Reed-Solomon FEC Symbol Error Counter for FEC Lanes 0-3 ++ * Registers This register is valid only when Reed-Solomon FEC is ++ * enabled. The symbol error counters are defined in 802.3 section ++ * 91.6.11 (for 100G and extended to 50G) and 802.3by-2016 section ++ * 108.6.9 (for 25G and extended to USXGMII). The counter is reset to all ++ * zeros when the register is read, and held at all ones in case of ++ * overflow. The reset operation takes precedence over the increment ++ * operation; if the register is read on the same clock cycle as an ++ * increment operation, the counter is reset to all zeros and the ++ * increment operation is lost. The counters are writable for test ++ * purposes, rather than read-only as specified in IEEE 802.3. ++ */ ++union cgxx_spux_fec_lnx_rsfec_err { ++ u64 u; ++ struct cgxx_spux_fec_lnx_rsfec_err_s { ++ u64 symb_err_cnt : 32; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct cgxx_spux_fec_lnx_rsfec_err_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_FEC_LNX_RSFEC_ERR(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_FEC_LNX_RSFEC_ERR(u64 a, u64 b) ++{ ++ return 0x10900 + 0x40000 * a + 8 * b; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_int ++ * ++ * CGX SPU Interrupt Registers ++ */ ++union cgxx_spux_int { ++ u64 u; ++ struct cgxx_spux_int_s { ++ u64 rx_link_up : 1; ++ u64 rx_link_down : 1; ++ u64 err_blk : 1; ++ u64 bitlckls : 1; ++ u64 synlos : 1; ++ u64 algnlos : 1; ++ u64 dbg_sync : 1; ++ u64 bip_err : 1; ++ u64 fec_corr : 1; ++ u64 fec_uncorr : 1; ++ u64 an_page_rx : 1; ++ u64 an_link_good : 1; ++ u64 an_complete : 1; ++ u64 training_done : 1; ++ u64 training_failure : 1; ++ u64 fec_align_status : 1; ++ u64 rsfec_corr : 1; ++ u64 rsfec_uncorr : 1; ++ u64 hi_ser : 1; ++ u64 usx_an_lnk_st : 1; ++ u64 usx_an_cpt : 1; ++ u64 reserved_21_63 : 43; ++ } s; ++ /* struct cgxx_spux_int_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_INT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_INT(u64 a) ++{ ++ return 0x10220 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_int_ena_w1c ++ * ++ * CGX SPU Interrupt Enable Clear Registers This register clears ++ * interrupt enable bits. ++ */ ++union cgxx_spux_int_ena_w1c { ++ u64 u; ++ struct cgxx_spux_int_ena_w1c_s { ++ u64 rx_link_up : 1; ++ u64 rx_link_down : 1; ++ u64 err_blk : 1; ++ u64 bitlckls : 1; ++ u64 synlos : 1; ++ u64 algnlos : 1; ++ u64 dbg_sync : 1; ++ u64 bip_err : 1; ++ u64 fec_corr : 1; ++ u64 fec_uncorr : 1; ++ u64 an_page_rx : 1; ++ u64 an_link_good : 1; ++ u64 an_complete : 1; ++ u64 training_done : 1; ++ u64 training_failure : 1; ++ u64 fec_align_status : 1; ++ u64 rsfec_corr : 1; ++ u64 rsfec_uncorr : 1; ++ u64 hi_ser : 1; ++ u64 usx_an_lnk_st : 1; ++ u64 usx_an_cpt : 1; ++ u64 reserved_21_63 : 43; ++ } s; ++ /* struct cgxx_spux_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_INT_ENA_W1C(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_INT_ENA_W1C(u64 a) ++{ ++ return 0x10230 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_int_ena_w1s ++ * ++ * CGX SPU Interrupt Enable Set Registers This register sets interrupt ++ * enable bits. ++ */ ++union cgxx_spux_int_ena_w1s { ++ u64 u; ++ struct cgxx_spux_int_ena_w1s_s { ++ u64 rx_link_up : 1; ++ u64 rx_link_down : 1; ++ u64 err_blk : 1; ++ u64 bitlckls : 1; ++ u64 synlos : 1; ++ u64 algnlos : 1; ++ u64 dbg_sync : 1; ++ u64 bip_err : 1; ++ u64 fec_corr : 1; ++ u64 fec_uncorr : 1; ++ u64 an_page_rx : 1; ++ u64 an_link_good : 1; ++ u64 an_complete : 1; ++ u64 training_done : 1; ++ u64 training_failure : 1; ++ u64 fec_align_status : 1; ++ u64 rsfec_corr : 1; ++ u64 rsfec_uncorr : 1; ++ u64 hi_ser : 1; ++ u64 usx_an_lnk_st : 1; ++ u64 usx_an_cpt : 1; ++ u64 reserved_21_63 : 43; ++ } s; ++ /* struct cgxx_spux_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_INT_ENA_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_INT_ENA_W1S(u64 a) ++{ ++ return 0x10238 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_int_w1s ++ * ++ * CGX SPU Interrupt Set Registers This register sets interrupt bits. ++ */ ++union cgxx_spux_int_w1s { ++ u64 u; ++ struct cgxx_spux_int_w1s_s { ++ u64 rx_link_up : 1; ++ u64 rx_link_down : 1; ++ u64 err_blk : 1; ++ u64 bitlckls : 1; ++ u64 synlos : 1; ++ u64 algnlos : 1; ++ u64 dbg_sync : 1; ++ u64 bip_err : 1; ++ u64 fec_corr : 1; ++ u64 fec_uncorr : 1; ++ u64 an_page_rx : 1; ++ u64 an_link_good : 1; ++ u64 an_complete : 1; ++ u64 training_done : 1; ++ u64 training_failure : 1; ++ u64 fec_align_status : 1; ++ u64 rsfec_corr : 1; ++ u64 rsfec_uncorr : 1; ++ u64 hi_ser : 1; ++ u64 usx_an_lnk_st : 1; ++ u64 usx_an_cpt : 1; ++ u64 reserved_21_63 : 43; ++ } s; ++ /* struct cgxx_spux_int_w1s_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_INT_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_INT_W1S(u64 a) ++{ ++ return 0x10228 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_ln#_br_bip_err_cnt ++ * ++ * CGX SPU 40,50,100GBASE-R BIP Error-Counter Registers This register ++ * implements the IEEE 802.3 BIP error-counter registers for PCS lanes ++ * 0-19 (3.200-3.203). It is valid only when the LPCS type is 40GBASE-R, ++ * 50GBASE-R, 100GBASE-R, (CGX()_CMR()_CONFIG[LMAC_TYPE]), and always ++ * returns 0x0 for all other LPCS types. The counters are indexed by the ++ * RX PCS lane number based on the alignment marker detected on each lane ++ * and captured in CGX()_SPU()_BR_LANE_MAP(). Each counter counts the BIP ++ * errors for its PCS lane, and is held at all ones in case of overflow. ++ * The counters are reset to all zeros when this register is read by ++ * software. The reset operation takes precedence over the increment ++ * operation; if the register is read on the same clock cycle as an ++ * increment operation, the counter is reset to all zeros and the ++ * increment operation is lost. The counters are writable for test ++ * purposes, rather than read-only as specified in IEEE 802.3. ++ */ ++union cgxx_spux_lnx_br_bip_err_cnt { ++ u64 u; ++ struct cgxx_spux_lnx_br_bip_err_cnt_s { ++ u64 bip_err_cnt : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_spux_lnx_br_bip_err_cnt_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_LNX_BR_BIP_ERR_CNT(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_LNX_BR_BIP_ERR_CNT(u64 a, u64 b) ++{ ++ return 0x10500 + 0x40000 * a + 8 * b; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_ln#_fec_corr_blks ++ * ++ * CGX SPU FEC Corrected-Blocks Counters 0-19 Registers This register is ++ * valid only when the LPCS type is BASE-R ++ * (CGX()_CMR()_CONFIG[LMAC_TYPE]) and applies to BASE-R FEC and Reed- ++ * Solomon FEC (RS-FEC). When BASE-R FEC is enabled, the FEC corrected- ++ * block counters are defined in IEEE 802.3 section 74.8.4.1. Each ++ * corrected-blocks counter increments by one for a corrected FEC block, ++ * i.e. an FEC block that has been received with invalid parity on the ++ * associated PCS lane and has been corrected by the FEC decoder. The ++ * counter is reset to all zeros when the register is read, and held at ++ * all ones in case of overflow. The reset operation takes precedence ++ * over the increment operation; if the register is read on the same ++ * clock cycle as an increment operation, the counter is reset to all ++ * zeros and the increment operation is lost. The counters are writable ++ * for test purposes, rather than read-only as specified in IEEE 802.3. ++ */ ++union cgxx_spux_lnx_fec_corr_blks { ++ u64 u; ++ struct cgxx_spux_lnx_fec_corr_blks_s { ++ u64 ln_corr_blks : 32; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct cgxx_spux_lnx_fec_corr_blks_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_LNX_FEC_CORR_BLKS(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_LNX_FEC_CORR_BLKS(u64 a, u64 b) ++{ ++ return 0x10700 + 0x40000 * a + 8 * b; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_ln#_fec_uncorr_blks ++ * ++ * CGX SPU FEC Uncorrected-Blocks Counters 0-19 Registers This register ++ * is valid only when the LPCS type is BASE-R ++ * (CGX()_CMR()_CONFIG[LMAC_TYPE]) and applies to BASE-R FEC and Reed- ++ * Solomon FEC (RS-FEC). When BASE-R FEC is enabled, the FEC corrected- ++ * block counters are defined in IEEE 802.3 section 74.8.4.2. Each ++ * uncorrected-blocks counter increments by one for an uncorrected FEC ++ * block, i.e. an FEC block that has been received with invalid parity on ++ * the associated PCS lane and has not been corrected by the FEC decoder. ++ * The counter is reset to all zeros when the register is read, and held ++ * at all ones in case of overflow. The reset operation takes precedence ++ * over the increment operation; if the register is read on the same ++ * clock cycle as an increment operation, the counter is reset to all ++ * zeros and the increment operation is lost. The counters are writable ++ * for test purposes, rather than read-only as specified in IEEE 802.3. ++ */ ++union cgxx_spux_lnx_fec_uncorr_blks { ++ u64 u; ++ struct cgxx_spux_lnx_fec_uncorr_blks_s { ++ u64 ln_uncorr_blks : 32; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct cgxx_spux_lnx_fec_uncorr_blks_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_LNX_FEC_UNCORR_BLKS(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_LNX_FEC_UNCORR_BLKS(u64 a, u64 b) ++{ ++ return 0x10800 + 0x40000 * a + 8 * b; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_lpcs_states ++ * ++ * CGX SPU BASE-X Transmit/Receive States Registers ++ */ ++union cgxx_spux_lpcs_states { ++ u64 u; ++ struct cgxx_spux_lpcs_states_s { ++ u64 deskew_sm : 3; ++ u64 reserved_3 : 1; ++ u64 deskew_am_found : 20; ++ u64 bx_rx_sm : 2; ++ u64 reserved_26_27 : 2; ++ u64 br_rx_sm : 3; ++ u64 reserved_31_63 : 33; ++ } s; ++ /* struct cgxx_spux_lpcs_states_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_LPCS_STATES(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_LPCS_STATES(u64 a) ++{ ++ return 0x10208 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_misc_control ++ * ++ * CGX SPU Miscellaneous Control Registers "* RX logical PCS lane ++ * polarity vector \<3:0\> = [XOR_RXPLRT]\<3:0\> ^ {4{[RXPLRT]}}. * TX ++ * logical PCS lane polarity vector \<3:0\> = [XOR_TXPLRT]\<3:0\> ^ ++ * {4{[TXPLRT]}}. In short, keep [RXPLRT] and [TXPLRT] cleared, and use ++ * [XOR_RXPLRT] and [XOR_TXPLRT] fields to define the polarity per ++ * logical PCS lane. Only bit 0 of vector is used for 10GBASE-R, and only ++ * bits 1:0 of vector are used for RXAUI." ++ */ ++union cgxx_spux_misc_control { ++ u64 u; ++ struct cgxx_spux_misc_control_s { ++ u64 txplrt : 1; ++ u64 rxplrt : 1; ++ u64 xor_txplrt : 4; ++ u64 xor_rxplrt : 4; ++ u64 intlv_rdisp : 1; ++ u64 skip_after_term : 1; ++ u64 rx_packet_dis : 1; ++ u64 rx_edet_signal_ok : 1; ++ u64 reserved_14_63 : 50; ++ } s; ++ /* struct cgxx_spux_misc_control_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_MISC_CONTROL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_MISC_CONTROL(u64 a) ++{ ++ return 0x10218 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_rsfec_corr ++ * ++ * CGX SPU Reed-Solomon FEC Corrected Codeword Counter Register This ++ * register implements the IEEE 802.3 RS-FEC corrected codewords counter ++ * described in 802.3 section 91.6.8 (for 100G and extended to 50G) and ++ * 802.3by-2016 section 108.6.7 (for 25G and extended to USXGMII). ++ */ ++union cgxx_spux_rsfec_corr { ++ u64 u; ++ struct cgxx_spux_rsfec_corr_s { ++ u64 cw_cnt : 32; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct cgxx_spux_rsfec_corr_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_RSFEC_CORR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_RSFEC_CORR(u64 a) ++{ ++ return 0x10088 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_rsfec_status ++ * ++ * CGX SPU Reed-Solomon FEC Status Registers This register implements the ++ * IEEE 802.3 RS-FEC status and lane mapping registers as described in ++ * 802.3 section 91.6 (for 100G and extended to 50G) and 802.3by-2016 ++ * section 108-6 (for 25G and extended to USXGMII). ++ */ ++union cgxx_spux_rsfec_status { ++ u64 u; ++ struct cgxx_spux_rsfec_status_s { ++ u64 fec_lane_mapping : 8; ++ u64 fec_align_status : 1; ++ u64 amps_lock : 4; ++ u64 hi_ser : 1; ++ u64 fec_byp_ind_abil : 1; ++ u64 fec_byp_cor_abil : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_spux_rsfec_status_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_RSFEC_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_RSFEC_STATUS(u64 a) ++{ ++ return 0x10080 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_rsfec_uncorr ++ * ++ * CGX SPU Reed-Solomon FEC Uncorrected Codeword Counter Register This ++ * register implements the IEEE 802.3 RS-FEC uncorrected codewords ++ * counter described in 802.3 section 91.6.9 (for 100G and extended to ++ * 50G) and 802.3by-2016 section 108.6.8 (for 25G and extended to ++ * USXGMII). ++ */ ++union cgxx_spux_rsfec_uncorr { ++ u64 u; ++ struct cgxx_spux_rsfec_uncorr_s { ++ u64 cw_cnt : 32; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct cgxx_spux_rsfec_uncorr_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_RSFEC_UNCORR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_RSFEC_UNCORR(u64 a) ++{ ++ return 0x10090 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_rx_eee_wake ++ * ++ * INTERNAL: CGX SPU RX EEE Wake Error Counter Registers Reserved. ++ * Internal: A counter that is incremented each time that the LPI receive ++ * state diagram enters the RX_WTF state indicating that a wake time ++ * fault has been detected. ++ */ ++union cgxx_spux_rx_eee_wake { ++ u64 u; ++ struct cgxx_spux_rx_eee_wake_s { ++ u64 wtf_error_counter : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_spux_rx_eee_wake_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_RX_EEE_WAKE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_RX_EEE_WAKE(u64 a) ++{ ++ return 0x103e0 + 8 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_rx_lpi_timing ++ * ++ * INTERNAL: CGX SPU RX EEE LPI Timing Parameters Registers Reserved. ++ * Internal: This register specifies receiver LPI timing parameters Tqr, ++ * Twr and Twtf. ++ */ ++union cgxx_spux_rx_lpi_timing { ++ u64 u; ++ struct cgxx_spux_rx_lpi_timing_s { ++ u64 twtf : 20; ++ u64 twr : 20; ++ u64 tqr : 20; ++ u64 reserved_60_61 : 2; ++ u64 rx_lpi_fw : 1; ++ u64 rx_lpi_en : 1; ++ } s; ++ /* struct cgxx_spux_rx_lpi_timing_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_RX_LPI_TIMING(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_RX_LPI_TIMING(u64 a) ++{ ++ return 0x103c0 + 8 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_rx_lpi_timing2 ++ * ++ * INTERNAL: CGX SPU RX EEE LPI Timing2 Parameters Registers Reserved. ++ * Internal: This register specifies receiver LPI timing parameters ++ * hold_off_timer. ++ */ ++union cgxx_spux_rx_lpi_timing2 { ++ u64 u; ++ struct cgxx_spux_rx_lpi_timing2_s { ++ u64 hold_off_timer : 20; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct cgxx_spux_rx_lpi_timing2_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_RX_LPI_TIMING2(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_RX_LPI_TIMING2(u64 a) ++{ ++ return 0x10420 + 8 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_rx_mrk_cnt ++ * ++ * CGX SPU Receiver Marker Interval Count Control Registers ++ */ ++union cgxx_spux_rx_mrk_cnt { ++ u64 u; ++ struct cgxx_spux_rx_mrk_cnt_s { ++ u64 mrk_cnt : 20; ++ u64 reserved_20_43 : 24; ++ u64 by_mrk_100g : 1; ++ u64 reserved_45_47 : 3; ++ u64 ram_mrk_cnt : 8; ++ u64 reserved_56_63 : 8; ++ } s; ++ /* struct cgxx_spux_rx_mrk_cnt_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_RX_MRK_CNT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_RX_MRK_CNT(u64 a) ++{ ++ return 0x103a0 + 8 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_spd_abil ++ * ++ * CGX SPU PCS Speed Ability Registers ++ */ ++union cgxx_spux_spd_abil { ++ u64 u; ++ struct cgxx_spux_spd_abil_s { ++ u64 tengb : 1; ++ u64 tenpasst : 1; ++ u64 usxgmii : 1; ++ u64 twentyfivegb : 1; ++ u64 fortygb : 1; ++ u64 fiftygb : 1; ++ u64 hundredgb : 1; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct cgxx_spux_spd_abil_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_SPD_ABIL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_SPD_ABIL(u64 a) ++{ ++ return 0x10010 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_status1 ++ * ++ * CGX SPU Status 1 Registers ++ */ ++union cgxx_spux_status1 { ++ u64 u; ++ struct cgxx_spux_status1_s { ++ u64 reserved_0 : 1; ++ u64 lpable : 1; ++ u64 rcv_lnk : 1; ++ u64 reserved_3_6 : 4; ++ u64 flt : 1; ++ u64 rx_lpi_indication : 1; ++ u64 tx_lpi_indication : 1; ++ u64 rx_lpi_received : 1; ++ u64 tx_lpi_received : 1; ++ u64 reserved_12_63 : 52; ++ } s; ++ /* struct cgxx_spux_status1_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_STATUS1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_STATUS1(u64 a) ++{ ++ return 0x10008 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_status2 ++ * ++ * CGX SPU Status 2 Registers ++ */ ++union cgxx_spux_status2 { ++ u64 u; ++ struct cgxx_spux_status2_s { ++ u64 tengb_r : 1; ++ u64 tengb_x : 1; ++ u64 tengb_w : 1; ++ u64 tengb_t : 1; ++ u64 usxgmii_r : 1; ++ u64 twentyfivegb_r : 1; ++ u64 fortygb_r : 1; ++ u64 fiftygb_r : 1; ++ u64 hundredgb_r : 1; ++ u64 reserved_9 : 1; ++ u64 rcvflt : 1; ++ u64 xmtflt : 1; ++ u64 reserved_12_13 : 2; ++ u64 dev : 2; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_spux_status2_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_STATUS2(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_STATUS2(u64 a) ++{ ++ return 0x10020 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_tx_lpi_timing ++ * ++ * INTERNAL: CGX SPU TX EEE LPI Timing Parameters Registers Reserved. ++ * Internal: Transmit LPI timing parameters Tsl, Tql and Tul ++ */ ++union cgxx_spux_tx_lpi_timing { ++ u64 u; ++ struct cgxx_spux_tx_lpi_timing_s { ++ u64 tql : 19; ++ u64 reserved_19_31 : 13; ++ u64 tul : 12; ++ u64 reserved_44_47 : 4; ++ u64 tsl : 12; ++ u64 reserved_60 : 1; ++ u64 tx_lpi_ignore_twl : 1; ++ u64 tx_lpi_fw : 1; ++ u64 tx_lpi_en : 1; ++ } s; ++ /* struct cgxx_spux_tx_lpi_timing_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_TX_LPI_TIMING(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_TX_LPI_TIMING(u64 a) ++{ ++ return 0x10400 + 8 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_tx_lpi_timing2 ++ * ++ * INTERNAL: CGX SPU TX EEE LPI Timing2 Parameters Registers Reserved. ++ * Internal: This register specifies transmit LPI timer parameters. ++ */ ++union cgxx_spux_tx_lpi_timing2 { ++ u64 u; ++ struct cgxx_spux_tx_lpi_timing2_s { ++ u64 t1u : 8; ++ u64 reserved_8_11 : 4; ++ u64 twl : 12; ++ u64 reserved_24_31 : 8; ++ u64 twl2 : 12; ++ u64 reserved_44_47 : 4; ++ u64 tbyp : 12; ++ u64 reserved_60_63 : 4; ++ } s; ++ /* struct cgxx_spux_tx_lpi_timing2_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_TX_LPI_TIMING2(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_TX_LPI_TIMING2(u64 a) ++{ ++ return 0x10440 + 8 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_tx_mrk_cnt ++ * ++ * CGX SPU Transmitter Marker Interval Count Control Registers ++ */ ++union cgxx_spux_tx_mrk_cnt { ++ u64 u; ++ struct cgxx_spux_tx_mrk_cnt_s { ++ u64 mrk_cnt : 20; ++ u64 reserved_20_43 : 24; ++ u64 by_mrk_100g : 1; ++ u64 reserved_45_47 : 3; ++ u64 ram_mrk_cnt : 8; ++ u64 reserved_56_63 : 8; ++ } s; ++ /* struct cgxx_spux_tx_mrk_cnt_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_TX_MRK_CNT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_TX_MRK_CNT(u64 a) ++{ ++ return 0x10380 + 8 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_usx_an_adv ++ * ++ * CGX SPU USXGMII Autonegotiation Advertisement Registers Software ++ * programs this register with the contents of the AN-link code word base ++ * page to be transmitted during autonegotiation. Any write operations to ++ * this register prior to completion of autonegotiation should be ++ * followed by a renegotiation in order for the new values to take ++ * effect. Once autonegotiation has completed, software can examine this ++ * register along with CGX()_SPU()_USX_AN_ADV to determine the highest ++ * common denominator technology. The format for this register is from ++ * USXGMII Multiport specification section 1.1.2 Table 2. ++ */ ++union cgxx_spux_usx_an_adv { ++ u64 u; ++ struct cgxx_spux_usx_an_adv_s { ++ u64 set : 1; ++ u64 reserved_1_6 : 6; ++ u64 eee_clk_stop_abil : 1; ++ u64 eee_abil : 1; ++ u64 spd : 3; ++ u64 dplx : 1; ++ u64 reserved_13_14 : 2; ++ u64 lnk_st : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_spux_usx_an_adv_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_USX_AN_ADV(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_USX_AN_ADV(u64 a) ++{ ++ return 0x101d0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_usx_an_control ++ * ++ * CGX SPU USXGMII Autonegotiation Control Register ++ */ ++union cgxx_spux_usx_an_control { ++ u64 u; ++ struct cgxx_spux_usx_an_control_s { ++ u64 reserved_0_8 : 9; ++ u64 rst_an : 1; ++ u64 reserved_10_11 : 2; ++ u64 an_en : 1; ++ u64 reserved_13_14 : 2; ++ u64 an_reset : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_spux_usx_an_control_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_USX_AN_CONTROL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_USX_AN_CONTROL(u64 a) ++{ ++ return 0x101c0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_usx_an_expansion ++ * ++ * CGX SPU USXGMII Autonegotiation Expansion Register This register is ++ * only used to signal page reception. ++ */ ++union cgxx_spux_usx_an_expansion { ++ u64 u; ++ struct cgxx_spux_usx_an_expansion_s { ++ u64 reserved_0 : 1; ++ u64 an_page_received : 1; ++ u64 next_page_able : 1; ++ u64 reserved_3_63 : 61; ++ } s; ++ /* struct cgxx_spux_usx_an_expansion_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_USX_AN_EXPANSION(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_USX_AN_EXPANSION(u64 a) ++{ ++ return 0x101e0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_usx_an_flow_ctrl ++ * ++ * CGX SPU USXGMII Flow Control Registers This register is used by ++ * software to affect USXGMII AN hardware behavior. ++ */ ++union cgxx_spux_usx_an_flow_ctrl { ++ u64 u; ++ struct cgxx_spux_usx_an_flow_ctrl_s { ++ u64 start_idle_detect : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct cgxx_spux_usx_an_flow_ctrl_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_USX_AN_FLOW_CTRL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_USX_AN_FLOW_CTRL(u64 a) ++{ ++ return 0x101e8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_usx_an_link_timer ++ * ++ * CGX SPU USXGMII Link Timer Registers This is the link timer register. ++ */ ++union cgxx_spux_usx_an_link_timer { ++ u64 u; ++ struct cgxx_spux_usx_an_link_timer_s { ++ u64 count : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_spux_usx_an_link_timer_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_USX_AN_LINK_TIMER(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_USX_AN_LINK_TIMER(u64 a) ++{ ++ return 0x101f0 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_usx_an_lp_abil ++ * ++ * CGX SPU USXGMII Autonegotiation Link-Partner Advertisement Registers ++ * This register captures the contents of the latest AN link code word ++ * base page received from the link partner during autonegotiation. This ++ * is register 5 per IEEE 802.3, Clause 37. ++ * CGX()_SPU()_USX_AN_EXPANSION[AN_PAGE_RECEIVED] is set when this ++ * register is updated by hardware. ++ */ ++union cgxx_spux_usx_an_lp_abil { ++ u64 u; ++ struct cgxx_spux_usx_an_lp_abil_s { ++ u64 set : 1; ++ u64 reserved_1_6 : 6; ++ u64 eee_clk_stop_abil : 1; ++ u64 eee_abil : 1; ++ u64 spd : 3; ++ u64 dplx : 1; ++ u64 reserved_13_14 : 2; ++ u64 lnk_st : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct cgxx_spux_usx_an_lp_abil_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_USX_AN_LP_ABIL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_USX_AN_LP_ABIL(u64 a) ++{ ++ return 0x101d8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu#_usx_an_status ++ * ++ * CGX SPU USXGMII Autonegotiation Status Register ++ */ ++union cgxx_spux_usx_an_status { ++ u64 u; ++ struct cgxx_spux_usx_an_status_s { ++ u64 extnd : 1; ++ u64 reserved_1 : 1; ++ u64 lnk_st : 1; ++ u64 an_abil : 1; ++ u64 rmt_flt : 1; ++ u64 an_cpt : 1; ++ u64 reserved_6_63 : 58; ++ } s; ++ /* struct cgxx_spux_usx_an_status_s cn; */ ++}; ++ ++static inline u64 CGXX_SPUX_USX_AN_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPUX_USX_AN_STATUS(u64 a) ++{ ++ return 0x101c8 + 0x40000 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu_dbg_control ++ * ++ * CGX SPU Debug Control Registers ++ */ ++union cgxx_spu_dbg_control { ++ u64 u; ++ struct cgxx_spu_dbg_control_s { ++ u64 marker_rxp : 15; ++ u64 reserved_15 : 1; ++ u64 scramble_dis : 1; ++ u64 reserved_17_18 : 2; ++ u64 br_pmd_train_soft_en : 1; ++ u64 reserved_20_27 : 8; ++ u64 timestamp_norm_dis : 1; ++ u64 an_nonce_match_dis : 1; ++ u64 br_ber_mon_dis : 1; ++ u64 rf_cw_mon_erly_restart_dis : 1; ++ u64 us_clk_period : 12; ++ u64 ms_clk_period : 12; ++ u64 reserved_56_63 : 8; ++ } s; ++ struct cgxx_spu_dbg_control_cn96xxp1 { ++ u64 marker_rxp : 15; ++ u64 reserved_15 : 1; ++ u64 scramble_dis : 1; ++ u64 reserved_17_18 : 2; ++ u64 br_pmd_train_soft_en : 1; ++ u64 reserved_20_27 : 8; ++ u64 timestamp_norm_dis : 1; ++ u64 an_nonce_match_dis : 1; ++ u64 br_ber_mon_dis : 1; ++ u64 reserved_31 : 1; ++ u64 us_clk_period : 12; ++ u64 ms_clk_period : 12; ++ u64 reserved_56_63 : 8; ++ } cn96xxp1; ++ /* struct cgxx_spu_dbg_control_s cn96xxp3; */ ++ /* struct cgxx_spu_dbg_control_s cn98xx; */ ++ /* struct cgxx_spu_dbg_control_cn96xxp1 cnf95xxp1; */ ++ /* struct cgxx_spu_dbg_control_s cnf95xxp2; */ ++ /* struct cgxx_spu_dbg_control_s loki; */ ++}; ++ ++static inline u64 CGXX_SPU_DBG_CONTROL(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPU_DBG_CONTROL(void) ++{ ++ return 0x10300; ++} ++ ++/** ++ * Register (RSL) cgx#_spu_sds#_skew_status ++ * ++ * CGX SPU SerDes Lane Skew Status Registers This register provides ++ * SerDes lane skew status. One register per physical SerDes lane. ++ */ ++union cgxx_spu_sdsx_skew_status { ++ u64 u; ++ struct cgxx_spu_sdsx_skew_status_s { ++ u64 skew_status : 32; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct cgxx_spu_sdsx_skew_status_s cn; */ ++}; ++ ++static inline u64 CGXX_SPU_SDSX_SKEW_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPU_SDSX_SKEW_STATUS(u64 a) ++{ ++ return 0x10340 + 8 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu_sds#_states ++ * ++ * CGX SPU SerDes States Registers This register provides SerDes lane ++ * states. One register per physical SerDes lane. ++ */ ++union cgxx_spu_sdsx_states { ++ u64 u; ++ struct cgxx_spu_sdsx_states_s { ++ u64 bx_sync_sm : 4; ++ u64 br_sh_cnt : 11; ++ u64 br_block_lock : 1; ++ u64 br_sh_invld_cnt : 7; ++ u64 reserved_23 : 1; ++ u64 fec_sync_cnt : 4; ++ u64 fec_block_sync : 1; ++ u64 reserved_29 : 1; ++ u64 an_rx_sm : 2; ++ u64 an_arb_sm : 3; ++ u64 reserved_35 : 1; ++ u64 train_lock_bad_markers : 3; ++ u64 train_lock_found_1st_marker : 1; ++ u64 train_frame_lock : 1; ++ u64 train_code_viol : 1; ++ u64 train_sm : 3; ++ u64 reserved_45_47 : 3; ++ u64 am_lock_sm : 2; ++ u64 am_lock_invld_cnt : 2; ++ u64 reserved_52_63 : 12; ++ } s; ++ /* struct cgxx_spu_sdsx_states_s cn; */ ++}; ++ ++static inline u64 CGXX_SPU_SDSX_STATES(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPU_SDSX_STATES(u64 a) ++{ ++ return 0x10360 + 8 * a; ++} ++ ++/** ++ * Register (RSL) cgx#_spu_usxgmii_control ++ * ++ * CGX SPU Common USXGMII Control Register This register is the common ++ * control register that enables USXGMII Mode. The fields in this ++ * register are preserved across any LMAC soft-resets. For an LMAC in ++ * soft- reset state in USXGMII mode, the CGX will transmit Remote Fault ++ * BASE-R blocks. ++ */ ++union cgxx_spu_usxgmii_control { ++ u64 u; ++ struct cgxx_spu_usxgmii_control_s { ++ u64 enable : 1; ++ u64 usxgmii_type : 3; ++ u64 sds_id : 2; ++ u64 reserved_6_63 : 58; ++ } s; ++ /* struct cgxx_spu_usxgmii_control_s cn; */ ++}; ++ ++static inline u64 CGXX_SPU_USXGMII_CONTROL(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 CGXX_SPU_USXGMII_CONTROL(void) ++{ ++ return 0x10920; ++} ++ ++#endif /* __CSRS_CGX_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx2/csrs/csrs-lmt.h b/arch/arm/include/asm/arch-octeontx2/csrs/csrs-lmt.h +new file mode 100644 +index 0000000000..72a5956c60 +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx2/csrs/csrs-lmt.h +@@ -0,0 +1,60 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++#ifndef __CSRS_LMT_H__ ++#define __CSRS_LMT_H__ ++ ++/** ++ * @file ++ * ++ * Configuration and status register (CSR) address and type definitions for ++ * LMT. ++ * ++ * This file is auto generated. Do not edit. ++ * ++ */ ++ ++/** ++ * Register (RVU_PFVF_BAR2) lmt_lf_lmtcancel ++ * ++ * RVU VF LMT Cancel Register ++ */ ++union lmt_lf_lmtcancel { ++ u64 u; ++ struct lmt_lf_lmtcancel_s { ++ u64 data : 64; ++ } s; ++ /* struct lmt_lf_lmtcancel_s cn; */ ++}; ++ ++static inline u64 LMT_LF_LMTCANCEL(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 LMT_LF_LMTCANCEL(void) ++{ ++ return 0x400; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) lmt_lf_lmtline# ++ * ++ * RVU VF LMT Line Registers ++ */ ++union lmt_lf_lmtlinex { ++ u64 u; ++ struct lmt_lf_lmtlinex_s { ++ u64 data : 64; ++ } s; ++ /* struct lmt_lf_lmtlinex_s cn; */ ++}; ++ ++static inline u64 LMT_LF_LMTLINEX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 LMT_LF_LMTLINEX(u64 a) ++{ ++ return 0 + 8 * a; ++} ++ ++#endif /* __CSRS_LMT_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx2/csrs/csrs-mio_emm.h b/arch/arm/include/asm/arch-octeontx2/csrs/csrs-mio_emm.h +new file mode 100644 +index 0000000000..4dd8958d2f +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx2/csrs/csrs-mio_emm.h +@@ -0,0 +1,1199 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++#ifndef __CSRS_MIO_EMM_H__ ++#define __CSRS_MIO_EMM_H__ ++ ++/** ++ * @file ++ * ++ * Configuration and status register (CSR) address and type definitions for ++ * MIO_EMM. ++ * ++ * This file is auto generated. Do not edit. ++ * ++ */ ++ ++/** ++ * Enumeration mio_emm_bar_e ++ * ++ * eMMC Base Address Register Enumeration Enumerates the base address ++ * registers. ++ */ ++#define MIO_EMM_BAR_E_MIO_EMM_PF_BAR0_CN8 (0x87e009000000ll) ++#define MIO_EMM_BAR_E_MIO_EMM_PF_BAR0_CN8_SIZE 0x800000ull ++#define MIO_EMM_BAR_E_MIO_EMM_PF_BAR0_CN9 (0x87e009000000ll) ++#define MIO_EMM_BAR_E_MIO_EMM_PF_BAR0_CN9_SIZE 0x10000ull ++#define MIO_EMM_BAR_E_MIO_EMM_PF_BAR4 (0x87e009f00000ll) ++#define MIO_EMM_BAR_E_MIO_EMM_PF_BAR4_SIZE 0x100000ull ++ ++/** ++ * Enumeration mio_emm_int_vec_e ++ * ++ * eMMC MSI-X Vector Enumeration Enumerates the MSI-X interrupt vectors. ++ */ ++#define MIO_EMM_INT_VEC_E_DMA_INT_DONE (8) ++#define MIO_EMM_INT_VEC_E_DMA_INT_FIFO (7) ++#define MIO_EMM_INT_VEC_E_EMM_BUF_DONE (0) ++#define MIO_EMM_INT_VEC_E_EMM_CMD_DONE (1) ++#define MIO_EMM_INT_VEC_E_EMM_CMD_ERR (3) ++#define MIO_EMM_INT_VEC_E_EMM_DMA_DONE (2) ++#define MIO_EMM_INT_VEC_E_EMM_DMA_ERR (4) ++#define MIO_EMM_INT_VEC_E_EMM_SWITCH_DONE (5) ++#define MIO_EMM_INT_VEC_E_EMM_SWITCH_ERR (6) ++#define MIO_EMM_INT_VEC_E_NCB_FLT (9) ++#define MIO_EMM_INT_VEC_E_NCB_RAS (0xa) ++ ++/** ++ * Register (RSL) mio_emm_access_wdog ++ * ++ * eMMC Access Watchdog Register ++ */ ++union mio_emm_access_wdog { ++ u64 u; ++ struct mio_emm_access_wdog_s { ++ u64 clk_cnt : 32; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct mio_emm_access_wdog_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_ACCESS_WDOG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_ACCESS_WDOG(void) ++{ ++ return 0x20f0; ++} ++ ++/** ++ * Register (RSL) mio_emm_buf_dat ++ * ++ * eMMC Data Buffer Access Register ++ */ ++union mio_emm_buf_dat { ++ u64 u; ++ struct mio_emm_buf_dat_s { ++ u64 dat : 64; ++ } s; ++ /* struct mio_emm_buf_dat_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_BUF_DAT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_BUF_DAT(void) ++{ ++ return 0x20e8; ++} ++ ++/** ++ * Register (RSL) mio_emm_buf_idx ++ * ++ * eMMC Data Buffer Address Register ++ */ ++union mio_emm_buf_idx { ++ u64 u; ++ struct mio_emm_buf_idx_s { ++ u64 offset : 6; ++ u64 buf_num : 1; ++ u64 reserved_7_15 : 9; ++ u64 inc : 1; ++ u64 reserved_17_63 : 47; ++ } s; ++ /* struct mio_emm_buf_idx_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_BUF_IDX(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_BUF_IDX(void) ++{ ++ return 0x20e0; ++} ++ ++/** ++ * Register (RSL) mio_emm_calb ++ * ++ * eMMC Calbration Register This register initiates delay line ++ * characterization. ++ */ ++union mio_emm_calb { ++ u64 u; ++ struct mio_emm_calb_s { ++ u64 start : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct mio_emm_calb_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_CALB(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_CALB(void) ++{ ++ return 0x20c0; ++} ++ ++/** ++ * Register (RSL) mio_emm_cfg ++ * ++ * eMMC Configuration Register ++ */ ++union mio_emm_cfg { ++ u64 u; ++ struct mio_emm_cfg_s { ++ u64 bus_ena : 4; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct mio_emm_cfg_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_CFG(void) ++{ ++ return 0x2000; ++} ++ ++/** ++ * Register (RSL) mio_emm_cmd ++ * ++ * eMMC Command Register ++ */ ++union mio_emm_cmd { ++ u64 u; ++ struct mio_emm_cmd_s { ++ u64 arg : 32; ++ u64 cmd_idx : 6; ++ u64 rtype_xor : 3; ++ u64 ctype_xor : 2; ++ u64 reserved_43_48 : 6; ++ u64 offset : 6; ++ u64 dbuf : 1; ++ u64 reserved_56_58 : 3; ++ u64 cmd_val : 1; ++ u64 bus_id : 2; ++ u64 skip_busy : 1; ++ u64 reserved_63 : 1; ++ } s; ++ /* struct mio_emm_cmd_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_CMD(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_CMD(void) ++{ ++ return 0x2058; ++} ++ ++/** ++ * Register (RSL) mio_emm_comp ++ * ++ * eMMC Compensation Register ++ */ ++union mio_emm_comp { ++ u64 u; ++ struct mio_emm_comp_s { ++ u64 nctl : 3; ++ u64 reserved_3_7 : 5; ++ u64 pctl : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct mio_emm_comp_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_COMP(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_COMP(void) ++{ ++ return 0x2040; ++} ++ ++/** ++ * Register (RSL) mio_emm_debug ++ * ++ * eMMC Debug Register ++ */ ++union mio_emm_debug { ++ u64 u; ++ struct mio_emm_debug_s { ++ u64 clk_on : 1; ++ u64 reserved_1_7 : 7; ++ u64 cmd_sm : 4; ++ u64 data_sm : 4; ++ u64 dma_sm : 4; ++ u64 emmc_clk_disable : 1; ++ u64 rdsync_rst : 1; ++ u64 reserved_22_63 : 42; ++ } s; ++ struct mio_emm_debug_cn96xxp1 { ++ u64 clk_on : 1; ++ u64 reserved_1_7 : 7; ++ u64 cmd_sm : 4; ++ u64 data_sm : 4; ++ u64 dma_sm : 4; ++ u64 reserved_20_63 : 44; ++ } cn96xxp1; ++ /* struct mio_emm_debug_s cn96xxp3; */ ++ /* struct mio_emm_debug_s cn98xx; */ ++ /* struct mio_emm_debug_cn96xxp1 cnf95xx; */ ++ /* struct mio_emm_debug_s loki; */ ++}; ++ ++static inline u64 MIO_EMM_DEBUG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DEBUG(void) ++{ ++ return 0x20f8; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma ++ * ++ * eMMC External DMA Configuration Register ++ */ ++union mio_emm_dma { ++ u64 u; ++ struct mio_emm_dma_s { ++ u64 card_addr : 32; ++ u64 block_cnt : 16; ++ u64 multi : 1; ++ u64 rw : 1; ++ u64 rel_wr : 1; ++ u64 thres : 6; ++ u64 dat_null : 1; ++ u64 sector : 1; ++ u64 dma_val : 1; ++ u64 bus_id : 2; ++ u64 skip_busy : 1; ++ u64 extra_args : 1; ++ } s; ++ struct mio_emm_dma_cn8 { ++ u64 card_addr : 32; ++ u64 block_cnt : 16; ++ u64 multi : 1; ++ u64 rw : 1; ++ u64 rel_wr : 1; ++ u64 thres : 6; ++ u64 dat_null : 1; ++ u64 sector : 1; ++ u64 dma_val : 1; ++ u64 bus_id : 2; ++ u64 skip_busy : 1; ++ u64 reserved_63 : 1; ++ } cn8; ++ struct mio_emm_dma_cn9 { ++ u64 card_addr : 32; ++ u64 block_cnt : 16; ++ u64 multi : 1; ++ u64 rw : 1; ++ u64 reserved_50 : 1; ++ u64 thres : 6; ++ u64 dat_null : 1; ++ u64 sector : 1; ++ u64 dma_val : 1; ++ u64 bus_id : 2; ++ u64 skip_busy : 1; ++ u64 extra_args : 1; ++ } cn9; ++}; ++ ++static inline u64 MIO_EMM_DMA(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA(void) ++{ ++ return 0x2050; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_adr ++ * ++ * eMMC DMA Address Register This register sets the address for eMMC/SD ++ * flash transfers to/from memory. Sixty-four-bit operations must be used ++ * to access this register. This register is updated by the DMA hardware ++ * and can be reloaded by the values placed in the MIO_EMM_DMA_FIFO_ADR. ++ */ ++union mio_emm_dma_adr { ++ u64 u; ++ struct mio_emm_dma_adr_s { ++ u64 adr : 53; ++ u64 reserved_53_63 : 11; ++ } s; ++ struct mio_emm_dma_adr_cn8 { ++ u64 adr : 49; ++ u64 reserved_49_63 : 15; ++ } cn8; ++ /* struct mio_emm_dma_adr_s cn9; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_ADR(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_ADR(void) ++{ ++ return 0x188; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_arg ++ * ++ * eMMC External DMA Extra Arguments Register ++ */ ++union mio_emm_dma_arg { ++ u64 u; ++ struct mio_emm_dma_arg_s { ++ u64 cmd23_args : 8; ++ u64 force_pgm : 1; ++ u64 context_id : 4; ++ u64 tag_req : 1; ++ u64 pack_cmd : 1; ++ u64 rel_wr : 1; ++ u64 alt_cmd : 6; ++ u64 skip_blk_cmd : 1; ++ u64 reserved_23_31 : 9; ++ u64 alt_cmd_arg : 32; ++ } s; ++ /* struct mio_emm_dma_arg_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_ARG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_ARG(void) ++{ ++ return 0x2090; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_cfg ++ * ++ * eMMC DMA Configuration Register This register controls the internal ++ * DMA engine used with the eMMC/SD flash controller. Sixty- four-bit ++ * operations must be used to access this register. This register is ++ * updated by the hardware DMA engine and can also be reloaded by writes ++ * to the MIO_EMM_DMA_FIFO_CMD register. ++ */ ++union mio_emm_dma_cfg { ++ u64 u; ++ struct mio_emm_dma_cfg_s { ++ u64 reserved_0_35 : 36; ++ u64 size : 20; ++ u64 endian : 1; ++ u64 swap8 : 1; ++ u64 swap16 : 1; ++ u64 swap32 : 1; ++ u64 reserved_60 : 1; ++ u64 clr : 1; ++ u64 rw : 1; ++ u64 en : 1; ++ } s; ++ /* struct mio_emm_dma_cfg_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_CFG(void) ++{ ++ return 0x180; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_fifo_adr ++ * ++ * eMMC Internal DMA FIFO Address Register This register specifies the ++ * internal address that is loaded into the eMMC internal DMA FIFO. The ++ * FIFO is used to queue up operations for the ++ * MIO_EMM_DMA_CFG/MIO_EMM_DMA_ADR when the DMA completes successfully. ++ */ ++union mio_emm_dma_fifo_adr { ++ u64 u; ++ struct mio_emm_dma_fifo_adr_s { ++ u64 reserved_0_2 : 3; ++ u64 adr : 50; ++ u64 reserved_53_63 : 11; ++ } s; ++ struct mio_emm_dma_fifo_adr_cn8 { ++ u64 reserved_0_2 : 3; ++ u64 adr : 46; ++ u64 reserved_49_63 : 15; ++ } cn8; ++ /* struct mio_emm_dma_fifo_adr_s cn9; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_FIFO_ADR(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_FIFO_ADR(void) ++{ ++ return 0x170; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_fifo_cfg ++ * ++ * eMMC Internal DMA FIFO Configuration Register This register controls ++ * DMA FIFO operations. ++ */ ++union mio_emm_dma_fifo_cfg { ++ u64 u; ++ struct mio_emm_dma_fifo_cfg_s { ++ u64 count : 5; ++ u64 reserved_5_7 : 3; ++ u64 int_lvl : 5; ++ u64 reserved_13_15 : 3; ++ u64 clr : 1; ++ u64 reserved_17_63 : 47; ++ } s; ++ /* struct mio_emm_dma_fifo_cfg_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_FIFO_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_FIFO_CFG(void) ++{ ++ return 0x160; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_fifo_cmd ++ * ++ * eMMC Internal DMA FIFO Command Register This register specifies a ++ * command that is loaded into the eMMC internal DMA FIFO. The FIFO is ++ * used to queue up operations for the MIO_EMM_DMA_CFG/MIO_EMM_DMA_ADR ++ * when the DMA completes successfully. Writes to this register store ++ * both the MIO_EMM_DMA_FIFO_CMD and the MIO_EMM_DMA_FIFO_ADR contents ++ * into the FIFO and increment the MIO_EMM_DMA_FIFO_CFG[COUNT] field. ++ * Note: This register has a similar format to MIO_EMM_DMA_CFG with the ++ * exception that the EN and CLR fields are absent. These are supported ++ * in MIO_EMM_DMA_FIFO_CFG. ++ */ ++union mio_emm_dma_fifo_cmd { ++ u64 u; ++ struct mio_emm_dma_fifo_cmd_s { ++ u64 reserved_0_35 : 36; ++ u64 size : 20; ++ u64 endian : 1; ++ u64 swap8 : 1; ++ u64 swap16 : 1; ++ u64 swap32 : 1; ++ u64 intdis : 1; ++ u64 reserved_61 : 1; ++ u64 rw : 1; ++ u64 reserved_63 : 1; ++ } s; ++ /* struct mio_emm_dma_fifo_cmd_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_FIFO_CMD(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_FIFO_CMD(void) ++{ ++ return 0x178; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_int ++ * ++ * eMMC DMA Interrupt Register Sixty-four-bit operations must be used to ++ * access this register. ++ */ ++union mio_emm_dma_int { ++ u64 u; ++ struct mio_emm_dma_int_s { ++ u64 done : 1; ++ u64 fifo : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct mio_emm_dma_int_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_INT(void) ++{ ++ return 0x190; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_int_ena_w1c ++ * ++ * eMMC DMA Interrupt Enable Clear Register This register clears ++ * interrupt enable bits. ++ */ ++union mio_emm_dma_int_ena_w1c { ++ u64 u; ++ struct mio_emm_dma_int_ena_w1c_s { ++ u64 done : 1; ++ u64 fifo : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct mio_emm_dma_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_INT_ENA_W1C(void) ++{ ++ return 0x1a8; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_int_ena_w1s ++ * ++ * eMMC DMA Interrupt Enable Set Register This register sets interrupt ++ * enable bits. ++ */ ++union mio_emm_dma_int_ena_w1s { ++ u64 u; ++ struct mio_emm_dma_int_ena_w1s_s { ++ u64 done : 1; ++ u64 fifo : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct mio_emm_dma_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_INT_ENA_W1S(void) ++{ ++ return 0x1a0; ++} ++ ++/** ++ * Register (RSL) mio_emm_dma_int_w1s ++ * ++ * eMMC DMA Interrupt Set Register This register sets interrupt bits. ++ */ ++union mio_emm_dma_int_w1s { ++ u64 u; ++ struct mio_emm_dma_int_w1s_s { ++ u64 done : 1; ++ u64 fifo : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct mio_emm_dma_int_w1s_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_DMA_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_DMA_INT_W1S(void) ++{ ++ return 0x198; ++} ++ ++/** ++ * Register (RSL) mio_emm_int ++ * ++ * eMMC Interrupt Register ++ */ ++union mio_emm_int { ++ u64 u; ++ struct mio_emm_int_s { ++ u64 buf_done : 1; ++ u64 cmd_done : 1; ++ u64 dma_done : 1; ++ u64 cmd_err : 1; ++ u64 dma_err : 1; ++ u64 switch_done : 1; ++ u64 switch_err : 1; ++ u64 ncb_flt : 1; ++ u64 ncb_ras : 1; ++ u64 reserved_9_63 : 55; ++ } s; ++ struct mio_emm_int_cn8 { ++ u64 buf_done : 1; ++ u64 cmd_done : 1; ++ u64 dma_done : 1; ++ u64 cmd_err : 1; ++ u64 dma_err : 1; ++ u64 switch_done : 1; ++ u64 switch_err : 1; ++ u64 reserved_7_63 : 57; ++ } cn8; ++ /* struct mio_emm_int_s cn9; */ ++}; ++ ++static inline u64 MIO_EMM_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_INT(void) ++{ ++ return 0x2078; ++} ++ ++/** ++ * Register (RSL) mio_emm_int_ena_w1c ++ * ++ * eMMC Interrupt Enable Clear Register This register clears interrupt ++ * enable bits. ++ */ ++union mio_emm_int_ena_w1c { ++ u64 u; ++ struct mio_emm_int_ena_w1c_s { ++ u64 buf_done : 1; ++ u64 cmd_done : 1; ++ u64 dma_done : 1; ++ u64 cmd_err : 1; ++ u64 dma_err : 1; ++ u64 switch_done : 1; ++ u64 switch_err : 1; ++ u64 ncb_flt : 1; ++ u64 ncb_ras : 1; ++ u64 reserved_9_63 : 55; ++ } s; ++ struct mio_emm_int_ena_w1c_cn8 { ++ u64 buf_done : 1; ++ u64 cmd_done : 1; ++ u64 dma_done : 1; ++ u64 cmd_err : 1; ++ u64 dma_err : 1; ++ u64 switch_done : 1; ++ u64 switch_err : 1; ++ u64 reserved_7_63 : 57; ++ } cn8; ++ /* struct mio_emm_int_ena_w1c_s cn9; */ ++}; ++ ++static inline u64 MIO_EMM_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_INT_ENA_W1C(void) ++{ ++ return 0x20b8; ++} ++ ++/** ++ * Register (RSL) mio_emm_int_ena_w1s ++ * ++ * eMMC Interrupt Enable Set Register This register sets interrupt enable ++ * bits. ++ */ ++union mio_emm_int_ena_w1s { ++ u64 u; ++ struct mio_emm_int_ena_w1s_s { ++ u64 buf_done : 1; ++ u64 cmd_done : 1; ++ u64 dma_done : 1; ++ u64 cmd_err : 1; ++ u64 dma_err : 1; ++ u64 switch_done : 1; ++ u64 switch_err : 1; ++ u64 ncb_flt : 1; ++ u64 ncb_ras : 1; ++ u64 reserved_9_63 : 55; ++ } s; ++ struct mio_emm_int_ena_w1s_cn8 { ++ u64 buf_done : 1; ++ u64 cmd_done : 1; ++ u64 dma_done : 1; ++ u64 cmd_err : 1; ++ u64 dma_err : 1; ++ u64 switch_done : 1; ++ u64 switch_err : 1; ++ u64 reserved_7_63 : 57; ++ } cn8; ++ /* struct mio_emm_int_ena_w1s_s cn9; */ ++}; ++ ++static inline u64 MIO_EMM_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_INT_ENA_W1S(void) ++{ ++ return 0x20b0; ++} ++ ++/** ++ * Register (RSL) mio_emm_int_w1s ++ * ++ * eMMC Interrupt Set Register This register sets interrupt bits. ++ */ ++union mio_emm_int_w1s { ++ u64 u; ++ struct mio_emm_int_w1s_s { ++ u64 buf_done : 1; ++ u64 cmd_done : 1; ++ u64 dma_done : 1; ++ u64 cmd_err : 1; ++ u64 dma_err : 1; ++ u64 switch_done : 1; ++ u64 switch_err : 1; ++ u64 ncb_flt : 1; ++ u64 ncb_ras : 1; ++ u64 reserved_9_63 : 55; ++ } s; ++ struct mio_emm_int_w1s_cn8 { ++ u64 buf_done : 1; ++ u64 cmd_done : 1; ++ u64 dma_done : 1; ++ u64 cmd_err : 1; ++ u64 dma_err : 1; ++ u64 switch_done : 1; ++ u64 switch_err : 1; ++ u64 reserved_7_63 : 57; ++ } cn8; ++ /* struct mio_emm_int_w1s_s cn9; */ ++}; ++ ++static inline u64 MIO_EMM_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_INT_W1S(void) ++{ ++ return 0x2080; ++} ++ ++/** ++ * Register (RSL) mio_emm_io_ctl ++ * ++ * eMMC I/O Control Register ++ */ ++union mio_emm_io_ctl { ++ u64 u; ++ struct mio_emm_io_ctl_s { ++ u64 slew : 1; ++ u64 reserved_1 : 1; ++ u64 drive : 2; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct mio_emm_io_ctl_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_IO_CTL(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_IO_CTL(void) ++{ ++ return 0x2040; ++} ++ ++/** ++ * Register (RSL) mio_emm_mode# ++ * ++ * eMMC Operating Mode Register ++ */ ++union mio_emm_modex { ++ u64 u; ++ struct mio_emm_modex_s { ++ u64 clk_lo : 16; ++ u64 clk_hi : 16; ++ u64 power_class : 4; ++ u64 clk_swap : 1; ++ u64 reserved_37_39 : 3; ++ u64 bus_width : 3; ++ u64 reserved_43_47 : 5; ++ u64 hs_timing : 1; ++ u64 hs200_timing : 1; ++ u64 hs400_timing : 1; ++ u64 reserved_51_63 : 13; ++ } s; ++ struct mio_emm_modex_cn8 { ++ u64 clk_lo : 16; ++ u64 clk_hi : 16; ++ u64 power_class : 4; ++ u64 reserved_36_39 : 4; ++ u64 bus_width : 3; ++ u64 reserved_43_47 : 5; ++ u64 hs_timing : 1; ++ u64 reserved_49_63 : 15; ++ } cn8; ++ struct mio_emm_modex_cn96xxp1 { ++ u64 clk_lo : 16; ++ u64 clk_hi : 16; ++ u64 power_class : 4; ++ u64 reserved_36_39 : 4; ++ u64 bus_width : 3; ++ u64 reserved_43_47 : 5; ++ u64 hs_timing : 1; ++ u64 hs200_timing : 1; ++ u64 hs400_timing : 1; ++ u64 reserved_51_63 : 13; ++ } cn96xxp1; ++ /* struct mio_emm_modex_s cn96xxp3; */ ++ /* struct mio_emm_modex_s cn98xx; */ ++ /* struct mio_emm_modex_s cnf95xx; */ ++ /* struct mio_emm_modex_s loki; */ ++}; ++ ++static inline u64 MIO_EMM_MODEX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_MODEX(u64 a) ++{ ++ return 0x2008 + 8 * a; ++} ++ ++/** ++ * Register (RSL) mio_emm_msix_pba# ++ * ++ * eMMC MSI-X Pending Bit Array Registers This register is the MSI-X PBA ++ * table; the bit number is indexed by the MIO_EMM_INT_VEC_E enumeration. ++ */ ++union mio_emm_msix_pbax { ++ u64 u; ++ struct mio_emm_msix_pbax_s { ++ u64 pend : 64; ++ } s; ++ /* struct mio_emm_msix_pbax_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_MSIX_PBAX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_MSIX_PBAX(u64 a) ++{ ++ return 0xf0000 + 8 * a; ++} ++ ++/** ++ * Register (RSL) mio_emm_msix_vec#_addr ++ * ++ * eMMC MSI-X Vector-Table Address Register This register is the MSI-X ++ * vector table, indexed by the MIO_EMM_INT_VEC_E enumeration. ++ */ ++union mio_emm_msix_vecx_addr { ++ u64 u; ++ struct mio_emm_msix_vecx_addr_s { ++ u64 secvec : 1; ++ u64 reserved_1 : 1; ++ u64 addr : 51; ++ u64 reserved_53_63 : 11; ++ } s; ++ struct mio_emm_msix_vecx_addr_cn8 { ++ u64 secvec : 1; ++ u64 reserved_1 : 1; ++ u64 addr : 47; ++ u64 reserved_49_63 : 15; ++ } cn8; ++ /* struct mio_emm_msix_vecx_addr_s cn9; */ ++}; ++ ++static inline u64 MIO_EMM_MSIX_VECX_ADDR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_MSIX_VECX_ADDR(u64 a) ++{ ++ return 0 + 0x10 * a; ++} ++ ++/** ++ * Register (RSL) mio_emm_msix_vec#_ctl ++ * ++ * eMMC MSI-X Vector-Table Control and Data Register This register is the ++ * MSI-X vector table, indexed by the MIO_EMM_INT_VEC_E enumeration. ++ */ ++union mio_emm_msix_vecx_ctl { ++ u64 u; ++ struct mio_emm_msix_vecx_ctl_s { ++ u64 data : 32; ++ u64 mask : 1; ++ u64 reserved_33_63 : 31; ++ } s; ++ struct mio_emm_msix_vecx_ctl_cn8 { ++ u64 data : 20; ++ u64 reserved_20_31 : 12; ++ u64 mask : 1; ++ u64 reserved_33_63 : 31; ++ } cn8; ++ /* struct mio_emm_msix_vecx_ctl_s cn9; */ ++}; ++ ++static inline u64 MIO_EMM_MSIX_VECX_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_MSIX_VECX_CTL(u64 a) ++{ ++ return 8 + 0x10 * a; ++} ++ ++/** ++ * Register (RSL) mio_emm_rca ++ * ++ * eMMC Relative Card Address Register ++ */ ++union mio_emm_rca { ++ u64 u; ++ struct mio_emm_rca_s { ++ u64 card_rca : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct mio_emm_rca_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_RCA(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_RCA(void) ++{ ++ return 0x20a0; ++} ++ ++/** ++ * Register (RSL) mio_emm_rsp_hi ++ * ++ * eMMC Response Data High Register ++ */ ++union mio_emm_rsp_hi { ++ u64 u; ++ struct mio_emm_rsp_hi_s { ++ u64 dat : 64; ++ } s; ++ /* struct mio_emm_rsp_hi_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_RSP_HI(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_RSP_HI(void) ++{ ++ return 0x2070; ++} ++ ++/** ++ * Register (RSL) mio_emm_rsp_lo ++ * ++ * eMMC Response Data Low Register ++ */ ++union mio_emm_rsp_lo { ++ u64 u; ++ struct mio_emm_rsp_lo_s { ++ u64 dat : 64; ++ } s; ++ /* struct mio_emm_rsp_lo_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_RSP_LO(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_RSP_LO(void) ++{ ++ return 0x2068; ++} ++ ++/** ++ * Register (RSL) mio_emm_rsp_sts ++ * ++ * eMMC Response Status Register ++ */ ++union mio_emm_rsp_sts { ++ u64 u; ++ struct mio_emm_rsp_sts_s { ++ u64 cmd_done : 1; ++ u64 cmd_idx : 6; ++ u64 cmd_type : 2; ++ u64 rsp_type : 3; ++ u64 rsp_val : 1; ++ u64 rsp_bad_sts : 1; ++ u64 rsp_crc_err : 1; ++ u64 rsp_timeout : 1; ++ u64 stp_val : 1; ++ u64 stp_bad_sts : 1; ++ u64 stp_crc_err : 1; ++ u64 stp_timeout : 1; ++ u64 rsp_busybit : 1; ++ u64 blk_crc_err : 1; ++ u64 blk_timeout : 1; ++ u64 dbuf : 1; ++ u64 reserved_24_27 : 4; ++ u64 dbuf_err : 1; ++ u64 reserved_29_54 : 26; ++ u64 acc_timeout : 1; ++ u64 dma_pend : 1; ++ u64 dma_val : 1; ++ u64 switch_val : 1; ++ u64 cmd_val : 1; ++ u64 bus_id : 2; ++ u64 reserved_62_63 : 2; ++ } s; ++ /* struct mio_emm_rsp_sts_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_RSP_STS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_RSP_STS(void) ++{ ++ return 0x2060; ++} ++ ++/** ++ * Register (RSL) mio_emm_sample ++ * ++ * eMMC Sampling Register ++ */ ++union mio_emm_sample { ++ u64 u; ++ struct mio_emm_sample_s { ++ u64 dat_cnt : 10; ++ u64 reserved_10_15 : 6; ++ u64 cmd_cnt : 10; ++ u64 reserved_26_63 : 38; ++ } s; ++ /* struct mio_emm_sample_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_SAMPLE(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_SAMPLE(void) ++{ ++ return 0x2090; ++} ++ ++/** ++ * Register (RSL) mio_emm_sts_mask ++ * ++ * eMMC Status Mask Register ++ */ ++union mio_emm_sts_mask { ++ u64 u; ++ struct mio_emm_sts_mask_s { ++ u64 sts_msk : 32; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct mio_emm_sts_mask_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_STS_MASK(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_STS_MASK(void) ++{ ++ return 0x2098; ++} ++ ++/** ++ * Register (RSL) mio_emm_switch ++ * ++ * eMMC Operating Mode Switch Register This register allows software to ++ * change eMMC related parameters associated with a specific BUS_ID. The ++ * MIO_EMM_MODE() registers contain the current setting for each BUS. ++ * This register is also used to switch the [CLK_HI] and [CLK_LO] ++ * settings associated with the common EMMC_CLK. These settings can only ++ * be changed when [BUS_ID] = 0. ++ */ ++union mio_emm_switch { ++ u64 u; ++ struct mio_emm_switch_s { ++ u64 clk_lo : 16; ++ u64 clk_hi : 16; ++ u64 power_class : 4; ++ u64 clk_swap : 1; ++ u64 reserved_37_39 : 3; ++ u64 bus_width : 3; ++ u64 reserved_43_47 : 5; ++ u64 hs_timing : 1; ++ u64 hs200_timing : 1; ++ u64 hs400_timing : 1; ++ u64 reserved_51_55 : 5; ++ u64 switch_err2 : 1; ++ u64 switch_err1 : 1; ++ u64 switch_err0 : 1; ++ u64 switch_exe : 1; ++ u64 bus_id : 2; ++ u64 reserved_62_63 : 2; ++ } s; ++ struct mio_emm_switch_cn8 { ++ u64 clk_lo : 16; ++ u64 clk_hi : 16; ++ u64 power_class : 4; ++ u64 reserved_36_39 : 4; ++ u64 bus_width : 3; ++ u64 reserved_43_47 : 5; ++ u64 hs_timing : 1; ++ u64 reserved_49_55 : 7; ++ u64 switch_err2 : 1; ++ u64 switch_err1 : 1; ++ u64 switch_err0 : 1; ++ u64 switch_exe : 1; ++ u64 bus_id : 2; ++ u64 reserved_62_63 : 2; ++ } cn8; ++ struct mio_emm_switch_cn96xxp1 { ++ u64 clk_lo : 16; ++ u64 clk_hi : 16; ++ u64 power_class : 4; ++ u64 reserved_36_39 : 4; ++ u64 bus_width : 3; ++ u64 reserved_43_47 : 5; ++ u64 hs_timing : 1; ++ u64 hs200_timing : 1; ++ u64 hs400_timing : 1; ++ u64 reserved_51_55 : 5; ++ u64 switch_err2 : 1; ++ u64 switch_err1 : 1; ++ u64 switch_err0 : 1; ++ u64 switch_exe : 1; ++ u64 bus_id : 2; ++ u64 reserved_62_63 : 2; ++ } cn96xxp1; ++ /* struct mio_emm_switch_s cn96xxp3; */ ++ /* struct mio_emm_switch_s cn98xx; */ ++ /* struct mio_emm_switch_s cnf95xx; */ ++ /* struct mio_emm_switch_s loki; */ ++}; ++ ++static inline u64 MIO_EMM_SWITCH(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_SWITCH(void) ++{ ++ return 0x2048; ++} ++ ++/** ++ * Register (RSL) mio_emm_tap ++ * ++ * eMMC TAP Delay Register This register indicates the delay line ++ * characteristics. ++ */ ++union mio_emm_tap { ++ u64 u; ++ struct mio_emm_tap_s { ++ u64 delay : 8; ++ u64 reserved_8_63 : 56; ++ } s; ++ /* struct mio_emm_tap_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_TAP(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_TAP(void) ++{ ++ return 0x20c8; ++} ++ ++/** ++ * Register (RSL) mio_emm_timing ++ * ++ * eMMC Timing Register This register determines the number of tap delays ++ * the EMM_DAT, EMM_DS, and EMM_CMD lines are transmitted or received in ++ * relation to EMM_CLK. These values should only be changed when the eMMC ++ * bus is idle. ++ */ ++union mio_emm_timing { ++ u64 u; ++ struct mio_emm_timing_s { ++ u64 data_out_tap : 6; ++ u64 reserved_6_15 : 10; ++ u64 data_in_tap : 6; ++ u64 reserved_22_31 : 10; ++ u64 cmd_out_tap : 6; ++ u64 reserved_38_47 : 10; ++ u64 cmd_in_tap : 6; ++ u64 reserved_54_63 : 10; ++ } s; ++ /* struct mio_emm_timing_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_TIMING(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_TIMING(void) ++{ ++ return 0x20d0; ++} ++ ++/** ++ * Register (RSL) mio_emm_wdog ++ * ++ * eMMC Watchdog Register ++ */ ++union mio_emm_wdog { ++ u64 u; ++ struct mio_emm_wdog_s { ++ u64 clk_cnt : 26; ++ u64 reserved_26_63 : 38; ++ } s; ++ /* struct mio_emm_wdog_s cn; */ ++}; ++ ++static inline u64 MIO_EMM_WDOG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 MIO_EMM_WDOG(void) ++{ ++ return 0x2088; ++} ++ ++#endif /* __CSRS_MIO_EMM_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx2/csrs/csrs-nix.h b/arch/arm/include/asm/arch-octeontx2/csrs/csrs-nix.h +new file mode 100644 +index 0000000000..81b9235365 +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx2/csrs/csrs-nix.h +@@ -0,0 +1,10548 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++#ifndef __CSRS_NIX_H__ ++#define __CSRS_NIX_H__ ++ ++/** ++ * @file ++ * ++ * Configuration and status register (CSR) address and type definitions for ++ * NIX. ++ * ++ * This file is auto generated. Do not edit. ++ * ++ */ ++ ++/** ++ * Enumeration nix_af_int_vec_e ++ * ++ * NIX Admin Function Interrupt Vector Enumeration Enumerates the NIX AF ++ * MSI-X interrupt vectors. ++ */ ++#define NIX_AF_INT_VEC_E_AF_ERR (3) ++#define NIX_AF_INT_VEC_E_AQ_DONE (2) ++#define NIX_AF_INT_VEC_E_GEN (1) ++#define NIX_AF_INT_VEC_E_POISON (4) ++#define NIX_AF_INT_VEC_E_RVU (0) ++ ++/** ++ * Enumeration nix_aq_comp_e ++ * ++ * NIX Completion Enumeration Enumerates the values of ++ * NIX_AQ_RES_S[COMPCODE]. ++ */ ++#define NIX_AQ_COMP_E_CTX_FAULT (4) ++#define NIX_AQ_COMP_E_CTX_POISON (3) ++#define NIX_AQ_COMP_E_GOOD (1) ++#define NIX_AQ_COMP_E_LOCKERR (5) ++#define NIX_AQ_COMP_E_NOTDONE (0) ++#define NIX_AQ_COMP_E_SQB_ALLOC_FAIL (6) ++#define NIX_AQ_COMP_E_SWERR (2) ++ ++/** ++ * Enumeration nix_aq_ctype_e ++ * ++ * NIX Context Type Enumeration Enumerates NIX_AQ_INST_S[CTYPE] values. ++ */ ++#define NIX_AQ_CTYPE_E_CQ (2) ++#define NIX_AQ_CTYPE_E_DYNO (5) ++#define NIX_AQ_CTYPE_E_MCE (3) ++#define NIX_AQ_CTYPE_E_RQ (0) ++#define NIX_AQ_CTYPE_E_RSS (4) ++#define NIX_AQ_CTYPE_E_SQ (1) ++ ++/** ++ * Enumeration nix_aq_instop_e ++ * ++ * NIX Admin Queue Opcode Enumeration Enumerates NIX_AQ_INST_S[OP] ++ * values. ++ */ ++#define NIX_AQ_INSTOP_E_INIT (1) ++#define NIX_AQ_INSTOP_E_LOCK (4) ++#define NIX_AQ_INSTOP_E_NOP (0) ++#define NIX_AQ_INSTOP_E_READ (3) ++#define NIX_AQ_INSTOP_E_UNLOCK (5) ++#define NIX_AQ_INSTOP_E_WRITE (2) ++ ++/** ++ * Enumeration nix_chan_e ++ * ++ * NIX Channel Number Enumeration Enumerates the receive and transmit ++ * channels, and values of NIX_RX_PARSE_S[CHAN], ++ * NIX_SQ_CTX_S[DEFAULT_CHAN]. CNXXXX implements a subset of these ++ * channels. Specifically, only channels for links enumerated by ++ * NIX_LINK_E are implemented. Internal: P2X/X2P channel enumeration for ++ * t9x. ++ */ ++#define NIX_CHAN_E_CGXX_LMACX_CHX(a, b, c) \ ++ (0x800 + 0x100 * (a) + 0x10 * (b) + (c)) ++#define NIX_CHAN_E_LBKX_CHX(a, b) (0 + 0x100 * (a) + (b)) ++#define NIX_CHAN_E_RX(a) (0 + 0x100 * (a)) ++#define NIX_CHAN_E_SDP_CHX(a) (0x700 + (a)) ++ ++/** ++ * Enumeration nix_colorresult_e ++ * ++ * NIX Color Result Enumeration Enumerates the values of ++ * NIX_MEM_RESULT_S[COLOR], NIX_AF_TL1()_MD_DEBUG1[COLOR] and ++ * NIX_AF_TL1()_MD_DEBUG1[COLOR]. ++ */ ++#define NIX_COLORRESULT_E_GREEN (0) ++#define NIX_COLORRESULT_E_RED_DROP (3) ++#define NIX_COLORRESULT_E_RED_SEND (2) ++#define NIX_COLORRESULT_E_YELLOW (1) ++ ++/** ++ * Enumeration nix_cqerrint_e ++ * ++ * NIX Completion Queue Interrupt Enumeration Enumerates the bit index of ++ * NIX_CQ_CTX_S[CQ_ERR_INT,CQ_ERR_INT_ENA]. ++ */ ++#define NIX_CQERRINT_E_CQE_FAULT (2) ++#define NIX_CQERRINT_E_DOOR_ERR (0) ++#define NIX_CQERRINT_E_WR_FULL (1) ++ ++/** ++ * Enumeration nix_intf_e ++ * ++ * NIX Interface Number Enumeration Enumerates the bit index of ++ * NIX_AF_STATUS[CALIBRATE_STATUS]. ++ */ ++#define NIX_INTF_E_CGXX(a) (0 + (a)) ++#define NIX_INTF_E_LBKX_CN96XX(a) (3 + (a)) ++#define NIX_INTF_E_LBKX_CN98XX(a) (5 + (a)) ++#define NIX_INTF_E_LBKX_CNF95XX(a) (3 + (a)) ++#define NIX_INTF_E_LBKX_LOKI(a) (3 + (a)) ++#define NIX_INTF_E_SDP_CN96XX (4) ++#define NIX_INTF_E_SDP_CN98XX (7) ++#define NIX_INTF_E_SDP_CNF95XX (4) ++#define NIX_INTF_E_SDP_LOKI (4) ++ ++/** ++ * Enumeration nix_lf_int_vec_e ++ * ++ * NIX Local Function Interrupt Vector Enumeration Enumerates the NIX ++ * MSI-X interrupt vectors per LF. ++ */ ++#define NIX_LF_INT_VEC_E_CINTX(a) (0x40 + (a)) ++#define NIX_LF_INT_VEC_E_ERR_INT (0x81) ++#define NIX_LF_INT_VEC_E_GINT (0x80) ++#define NIX_LF_INT_VEC_E_POISON (0x82) ++#define NIX_LF_INT_VEC_E_QINTX(a) (0 + (a)) ++ ++/** ++ * Enumeration nix_link_e ++ * ++ * NIX Link Number Enumeration Enumerates the receive and transmit links, ++ * and LINK index of NIX_AF_RX_LINK()_CFG, NIX_AF_RX_LINK()_WRR_CFG, ++ * NIX_AF_TX_LINK()_NORM_CREDIT, NIX_AF_TX_LINK()_HW_XOFF and ++ * NIX_AF_TL3_TL2()_LINK()_CFG. ++ */ ++#define NIX_LINK_E_CGXX_LMACX(a, b) (0 + 4 * (a) + (b)) ++#define NIX_LINK_E_LBKX_CN96XX(a) (0xc + (a)) ++#define NIX_LINK_E_LBKX_CN98XX(a) (0x14 + (a)) ++#define NIX_LINK_E_LBKX_CNF95XX(a) (0xc + (a)) ++#define NIX_LINK_E_LBKX_LOKI(a) (0xc + (a)) ++#define NIX_LINK_E_MC_CN96XX (0xe) ++#define NIX_LINK_E_MC_CN98XX (0x17) ++#define NIX_LINK_E_MC_CNF95XX (0xe) ++#define NIX_LINK_E_MC_LOKI (0xe) ++#define NIX_LINK_E_SDP_CN96XX (0xd) ++#define NIX_LINK_E_SDP_CN98XX (0x16) ++#define NIX_LINK_E_SDP_CNF95XX (0xd) ++#define NIX_LINK_E_SDP_LOKI (0xd) ++ ++/** ++ * Enumeration nix_lsoalg_e ++ * ++ * NIX Large Send Offload Algorithm Enumeration Enumerates ++ * NIX_AF_LSO_FORMAT()_FIELD()[ALG] values. Specifies algorithm for ++ * modifying the associated LSO packet field. ++ */ ++#define NIX_LSOALG_E_ADD_OFFSET (3) ++#define NIX_LSOALG_E_ADD_PAYLEN (2) ++#define NIX_LSOALG_E_ADD_SEGNUM (1) ++#define NIX_LSOALG_E_NOP (0) ++#define NIX_LSOALG_E_TCP_FLAGS (4) ++ ++/** ++ * Enumeration nix_maxsqesz_e ++ * ++ * NIX Maximum SQE Size Enumeration Enumerates the values of ++ * NIX_SQ_CTX_S[MAX_SQE_SIZE]. ++ */ ++#define NIX_MAXSQESZ_E_W16 (0) ++#define NIX_MAXSQESZ_E_W8 (1) ++ ++/** ++ * Enumeration nix_mdtype_e ++ * ++ * NIX Meta Descriptor Type Enumeration Enumerates values of ++ * NIX_AF_MDQ()_MD_DEBUG[MD_TYPE]. ++ */ ++#define NIX_MDTYPE_E_FLUSH (1) ++#define NIX_MDTYPE_E_PMD (2) ++#define NIX_MDTYPE_E_RSVD (0) ++ ++/** ++ * Enumeration nix_mnqerr_e ++ * ++ * NIX Meta-Descriptor Enqueue Error Enumeration Enumerates ++ * NIX_LF_MNQ_ERR_DBG[ERRCODE] values. ++ */ ++#define NIX_MNQERR_E_CQ_QUERY_ERR (6) ++#define NIX_MNQERR_E_LSO_ERR (5) ++#define NIX_MNQERR_E_MAXLEN_ERR (8) ++#define NIX_MNQERR_E_MAX_SQE_SIZE_ERR (7) ++#define NIX_MNQERR_E_SQB_FAULT (2) ++#define NIX_MNQERR_E_SQB_POISON (3) ++#define NIX_MNQERR_E_SQE_SIZEM1_ZERO (9) ++#define NIX_MNQERR_E_SQ_CTX_FAULT (0) ++#define NIX_MNQERR_E_SQ_CTX_POISON (1) ++#define NIX_MNQERR_E_TOTAL_ERR (4) ++ ++/** ++ * Enumeration nix_ndc_rx_port_e ++ * ++ * NIX Receive NDC Port Enumeration Enumerates NIX receive NDC ++ * (NDC_IDX_E::NIX()_RX) ports and the PORT index of ++ * NDC_AF_PORT()_RT()_RW()_REQ_PC and NDC_AF_PORT()_RT()_RW()_LAT_PC. ++ */ ++#define NIX_NDC_RX_PORT_E_AQ (0) ++#define NIX_NDC_RX_PORT_E_CINT (2) ++#define NIX_NDC_RX_PORT_E_CQ (1) ++#define NIX_NDC_RX_PORT_E_MC (3) ++#define NIX_NDC_RX_PORT_E_PKT (4) ++#define NIX_NDC_RX_PORT_E_RQ (5) ++ ++/** ++ * Enumeration nix_ndc_tx_port_e ++ * ++ * NIX Transmit NDC Port Enumeration Enumerates NIX transmit NDC ++ * (NDC_IDX_E::NIX()_TX) ports and the PORT index of ++ * NDC_AF_PORT()_RT()_RW()_REQ_PC and NDC_AF_PORT()_RT()_RW()_LAT_PC. ++ */ ++#define NIX_NDC_TX_PORT_E_DEQ (3) ++#define NIX_NDC_TX_PORT_E_DMA (4) ++#define NIX_NDC_TX_PORT_E_ENQ (1) ++#define NIX_NDC_TX_PORT_E_LMT (0) ++#define NIX_NDC_TX_PORT_E_MNQ (2) ++#define NIX_NDC_TX_PORT_E_XQE (5) ++ ++/** ++ * Enumeration nix_re_opcode_e ++ * ++ * NIX Receive Error Opcode Enumeration Enumerates ++ * NIX_RX_PARSE_S[ERRCODE] values when NIX_RX_PARSE_S[ERRLEV] = ++ * NPC_ERRLEV_E::RE. ++ */ ++#define NIX_RE_OPCODE_E_OL2_LENMISM (0x12) ++#define NIX_RE_OPCODE_E_OVERSIZE (0x11) ++#define NIX_RE_OPCODE_E_RE_DMAPKT (0xf) ++#define NIX_RE_OPCODE_E_RE_FCS (7) ++#define NIX_RE_OPCODE_E_RE_FCS_RCV (8) ++#define NIX_RE_OPCODE_E_RE_JABBER (2) ++#define NIX_RE_OPCODE_E_RE_NONE (0) ++#define NIX_RE_OPCODE_E_RE_PARTIAL (1) ++#define NIX_RE_OPCODE_E_RE_RX_CTL (0xb) ++#define NIX_RE_OPCODE_E_RE_SKIP (0xc) ++#define NIX_RE_OPCODE_E_RE_TERMINATE (9) ++#define NIX_RE_OPCODE_E_UNDERSIZE (0x10) ++ ++/** ++ * Enumeration nix_redalg_e ++ * ++ * NIX Red Algorithm Enumeration Enumerates the different algorithms of ++ * NIX_SEND_EXT_S[SHP_RA]. ++ */ ++#define NIX_REDALG_E_DISCARD (3) ++#define NIX_REDALG_E_SEND (1) ++#define NIX_REDALG_E_STALL (2) ++#define NIX_REDALG_E_STD (0) ++ ++/** ++ * Enumeration nix_rqint_e ++ * ++ * NIX Receive Queue Interrupt Enumeration Enumerates the bit index of ++ * NIX_RQ_CTX_S[RQ_INT,RQ_INT_ENA]. ++ */ ++#define NIX_RQINT_E_DROP (0) ++#define NIX_RQINT_E_RX(a) (0 + (a)) ++#define NIX_RQINT_E_RED (1) ++ ++/** ++ * Enumeration nix_rx_actionop_e ++ * ++ * NIX Receive Action Opcode Enumeration Enumerates the values of ++ * NIX_RX_ACTION_S[OP]. ++ */ ++#define NIX_RX_ACTIONOP_E_DROP (0) ++#define NIX_RX_ACTIONOP_E_MCAST (3) ++#define NIX_RX_ACTIONOP_E_MIRROR (6) ++#define NIX_RX_ACTIONOP_E_PF_FUNC_DROP (5) ++#define NIX_RX_ACTIONOP_E_RSS (4) ++#define NIX_RX_ACTIONOP_E_UCAST (1) ++#define NIX_RX_ACTIONOP_E_UCAST_IPSEC (2) ++ ++/** ++ * Enumeration nix_rx_mcop_e ++ * ++ * NIX Receive Multicast/Mirror Opcode Enumeration Enumerates the values ++ * of NIX_RX_MCE_S[OP]. ++ */ ++#define NIX_RX_MCOP_E_RQ (0) ++#define NIX_RX_MCOP_E_RSS (1) ++ ++/** ++ * Enumeration nix_rx_perrcode_e ++ * ++ * NIX Receive Protocol Error Code Enumeration Enumerates ++ * NIX_RX_PARSE_S[ERRCODE] values when NIX_RX_PARSE_S[ERRLEV] = ++ * NPC_ERRLEV_E::NIX. ++ */ ++#define NIX_RX_PERRCODE_E_BUFS_OFLOW (0xa) ++#define NIX_RX_PERRCODE_E_DATA_FAULT (8) ++#define NIX_RX_PERRCODE_E_IL3_LEN (0x20) ++#define NIX_RX_PERRCODE_E_IL4_CHK (0x22) ++#define NIX_RX_PERRCODE_E_IL4_LEN (0x21) ++#define NIX_RX_PERRCODE_E_IL4_PORT (0x23) ++#define NIX_RX_PERRCODE_E_MCAST_FAULT (4) ++#define NIX_RX_PERRCODE_E_MCAST_POISON (6) ++#define NIX_RX_PERRCODE_E_MEMOUT (9) ++#define NIX_RX_PERRCODE_E_MIRROR_FAULT (5) ++#define NIX_RX_PERRCODE_E_MIRROR_POISON (7) ++#define NIX_RX_PERRCODE_E_NPC_RESULT_ERR (2) ++#define NIX_RX_PERRCODE_E_OL3_LEN (0x10) ++#define NIX_RX_PERRCODE_E_OL4_CHK (0x12) ++#define NIX_RX_PERRCODE_E_OL4_LEN (0x11) ++#define NIX_RX_PERRCODE_E_OL4_PORT (0x13) ++ ++/** ++ * Enumeration nix_send_status_e ++ * ++ * NIX Send Completion Status Enumeration Enumerates values of ++ * NIX_SEND_COMP_S[STATUS] and NIX_LF_SEND_ERR_DBG[ERRCODE]. ++ */ ++#define NIX_SEND_STATUS_E_DATA_FAULT (0x16) ++#define NIX_SEND_STATUS_E_DATA_POISON (0x17) ++#define NIX_SEND_STATUS_E_GOOD (0) ++#define NIX_SEND_STATUS_E_INVALID_SUBDC (0x14) ++#define NIX_SEND_STATUS_E_JUMP_FAULT (7) ++#define NIX_SEND_STATUS_E_JUMP_POISON (8) ++#define NIX_SEND_STATUS_E_LOCK_VIOL (0x21) ++#define NIX_SEND_STATUS_E_NPC_DROP_ACTION (0x20) ++#define NIX_SEND_STATUS_E_NPC_MCAST_ABORT (0x24) ++#define NIX_SEND_STATUS_E_NPC_MCAST_CHAN_ERR (0x23) ++#define NIX_SEND_STATUS_E_NPC_UCAST_CHAN_ERR (0x22) ++#define NIX_SEND_STATUS_E_NPC_VTAG_PTR_ERR (0x25) ++#define NIX_SEND_STATUS_E_NPC_VTAG_SIZE_ERR (0x26) ++#define NIX_SEND_STATUS_E_SEND_CRC_ERR (0x10) ++#define NIX_SEND_STATUS_E_SEND_EXT_ERR (6) ++#define NIX_SEND_STATUS_E_SEND_HDR_ERR (5) ++#define NIX_SEND_STATUS_E_SEND_IMM_ERR (0x11) ++#define NIX_SEND_STATUS_E_SEND_MEM_ERR (0x13) ++#define NIX_SEND_STATUS_E_SEND_MEM_FAULT (0x27) ++#define NIX_SEND_STATUS_E_SEND_SG_ERR (0x12) ++#define NIX_SEND_STATUS_E_SQB_FAULT (3) ++#define NIX_SEND_STATUS_E_SQB_POISON (4) ++#define NIX_SEND_STATUS_E_SQ_CTX_FAULT (1) ++#define NIX_SEND_STATUS_E_SQ_CTX_POISON (2) ++#define NIX_SEND_STATUS_E_SUBDC_ORDER_ERR (0x15) ++ ++/** ++ * Enumeration nix_sendcrcalg_e ++ * ++ * NIX Send CRC Algorithm Enumeration Enumerates the CRC algorithm used, ++ * see NIX_SEND_CRC_S[ALG]. ++ */ ++#define NIX_SENDCRCALG_E_CRC32 (0) ++#define NIX_SENDCRCALG_E_CRC32C (1) ++#define NIX_SENDCRCALG_E_ONES16 (2) ++ ++/** ++ * Enumeration nix_sendl3type_e ++ * ++ * NIX Send Layer 3 Header Type Enumeration Enumerates values of ++ * NIX_SEND_HDR_S[OL3TYPE], NIX_SEND_HDR_S[IL3TYPE]. Internal: Encoding ++ * matches DPDK TX IP types: \ PKT_TX_IP_CKSUM (1ULL \<\< 54) ++ * PKT_TX_IPV4 (1ULL \<\< 55) PKT_TX_IPV6 (1ULL \<\< ++ * 56) PKT_TX_OUTER_IP_CKSUM(1ULL \<\< 58) PKT_TX_OUTER_IPV4 (1ULL ++ * \<\< 59) PKT_TX_OUTER_IPV6 (1ULL \<\< 60) \ ++ */ ++#define NIX_SENDL3TYPE_E_IP4 (2) ++#define NIX_SENDL3TYPE_E_IP4_CKSUM (3) ++#define NIX_SENDL3TYPE_E_IP6 (4) ++#define NIX_SENDL3TYPE_E_NONE (0) ++ ++/** ++ * Enumeration nix_sendl4type_e ++ * ++ * NIX Send Layer 4 Header Type Enumeration Enumerates values of ++ * NIX_SEND_HDR_S[OL4TYPE], NIX_SEND_HDR_S[IL4TYPE]. Internal: Encoding ++ * matches DPDK TX L4 types. \ PKT_TX_L4_NO_CKSUM (0ULL \<\< 52) ++ * // Disable L4 cksum of TX pkt. PKT_TX_TCP_CKSUM (1ULL \<\< 52) // ++ * TCP cksum of TX pkt. computed by nic. PKT_TX_SCTP_CKSUM (2ULL \<\< ++ * 52) // SCTP cksum of TX pkt. computed by nic. PKT_TX_UDP_CKSUM ++ * (3ULL \<\< 52) // UDP cksum of TX pkt. computed by nic. \ ++ */ ++#define NIX_SENDL4TYPE_E_NONE (0) ++#define NIX_SENDL4TYPE_E_SCTP_CKSUM (2) ++#define NIX_SENDL4TYPE_E_TCP_CKSUM (1) ++#define NIX_SENDL4TYPE_E_UDP_CKSUM (3) ++ ++/** ++ * Enumeration nix_sendldtype_e ++ * ++ * NIX Send Load Type Enumeration Enumerates the load transaction types ++ * for reading segment bytes specified by NIX_SEND_SG_S[LD_TYPE] and ++ * NIX_SEND_JUMP_S[LD_TYPE]. Internal: The hardware implementation ++ * treats undefined encodings as LDD load type. ++ */ ++#define NIX_SENDLDTYPE_E_LDD (0) ++#define NIX_SENDLDTYPE_E_LDT (1) ++#define NIX_SENDLDTYPE_E_LDWB (2) ++ ++/** ++ * Enumeration nix_sendmemalg_e ++ * ++ * NIX Memory Modify Algorithm Enumeration Enumerates the different ++ * algorithms for modifying memory; see NIX_SEND_MEM_S[ALG]. mbufs_freed ++ * is the number of gather buffers freed to NPA for the send descriptor. ++ * See NIX_SEND_HDR_S[DF] and NIX_SEND_SG_S[I*]. ++ */ ++#define NIX_SENDMEMALG_E_ADD (8) ++#define NIX_SENDMEMALG_E_ADDLEN (0xa) ++#define NIX_SENDMEMALG_E_ADDMBUF (0xc) ++#define NIX_SENDMEMALG_E_SET (0) ++#define NIX_SENDMEMALG_E_SETRSLT (2) ++#define NIX_SENDMEMALG_E_SETTSTMP (1) ++#define NIX_SENDMEMALG_E_SUB (9) ++#define NIX_SENDMEMALG_E_SUBLEN (0xb) ++#define NIX_SENDMEMALG_E_SUBMBUF (0xd) ++ ++/** ++ * Enumeration nix_sendmemdsz_e ++ * ++ * NIX Memory Data Size Enumeration Enumerates the datum size for ++ * modifying memory; see NIX_SEND_MEM_S[DSZ]. ++ */ ++#define NIX_SENDMEMDSZ_E_B16 (2) ++#define NIX_SENDMEMDSZ_E_B32 (1) ++#define NIX_SENDMEMDSZ_E_B64 (0) ++#define NIX_SENDMEMDSZ_E_B8 (3) ++ ++/** ++ * Enumeration nix_sqint_e ++ * ++ * NIX Send Queue Interrupt Enumeration Enumerates the bit index of ++ * NIX_SQ_CTX_S[SQ_INT,SQ_INT_ENA]. ++ */ ++#define NIX_SQINT_E_LMT_ERR (0) ++#define NIX_SQINT_E_MNQ_ERR (1) ++#define NIX_SQINT_E_SEND_ERR (2) ++#define NIX_SQINT_E_SQB_ALLOC_FAIL (3) ++ ++/** ++ * Enumeration nix_sqoperr_e ++ * ++ * NIX SQ Operation Error Enumeration Enumerates ++ * NIX_LF_SQ_OP_ERR_DBG[ERRCODE] values. ++ */ ++#define NIX_SQOPERR_E_MAX_SQE_SIZE_ERR (4) ++#define NIX_SQOPERR_E_SQB_FAULT (7) ++#define NIX_SQOPERR_E_SQB_NULL (6) ++#define NIX_SQOPERR_E_SQE_OFLOW (5) ++#define NIX_SQOPERR_E_SQE_SIZEM1_ZERO (8) ++#define NIX_SQOPERR_E_SQ_CTX_FAULT (1) ++#define NIX_SQOPERR_E_SQ_CTX_POISON (2) ++#define NIX_SQOPERR_E_SQ_DISABLED (3) ++#define NIX_SQOPERR_E_SQ_OOR (0) ++ ++/** ++ * Enumeration nix_stat_lf_rx_e ++ * ++ * NIX Local Function Receive Statistics Enumeration Enumerates the last ++ * index of NIX_AF_LF()_RX_STAT() and NIX_LF_RX_STAT(). ++ */ ++#define NIX_STAT_LF_RX_E_RX_BCAST (2) ++#define NIX_STAT_LF_RX_E_RX_DROP (4) ++#define NIX_STAT_LF_RX_E_RX_DROP_OCTS (5) ++#define NIX_STAT_LF_RX_E_RX_DRP_BCAST (8) ++#define NIX_STAT_LF_RX_E_RX_DRP_L3BCAST (0xa) ++#define NIX_STAT_LF_RX_E_RX_DRP_L3MCAST (0xb) ++#define NIX_STAT_LF_RX_E_RX_DRP_MCAST (9) ++#define NIX_STAT_LF_RX_E_RX_ERR (7) ++#define NIX_STAT_LF_RX_E_RX_FCS (6) ++#define NIX_STAT_LF_RX_E_RX_MCAST (3) ++#define NIX_STAT_LF_RX_E_RX_OCTS (0) ++#define NIX_STAT_LF_RX_E_RX_UCAST (1) ++ ++/** ++ * Enumeration nix_stat_lf_tx_e ++ * ++ * NIX Local Function Transmit Statistics Enumeration Enumerates the ++ * index of NIX_AF_LF()_TX_STAT() and NIX_LF_TX_STAT(). These statistics ++ * do not account for packet replication due to NIX_TX_ACTION_S[OP] = ++ * NIX_TX_ACTIONOP_E::MCAST. ++ */ ++#define NIX_STAT_LF_TX_E_TX_BCAST (1) ++#define NIX_STAT_LF_TX_E_TX_DROP (3) ++#define NIX_STAT_LF_TX_E_TX_MCAST (2) ++#define NIX_STAT_LF_TX_E_TX_OCTS (4) ++#define NIX_STAT_LF_TX_E_TX_UCAST (0) ++ ++/** ++ * Enumeration nix_stype_e ++ * ++ * NIX SQB Caching Type Enumeration Enumerates the values of ++ * NIX_SQ_CTX_S[SQE_STYPE]. ++ */ ++#define NIX_STYPE_E_STF (0) ++#define NIX_STYPE_E_STP (2) ++#define NIX_STYPE_E_STT (1) ++ ++/** ++ * Enumeration nix_subdc_e ++ * ++ * NIX Subdescriptor Operation Enumeration Enumerates send and receive ++ * subdescriptor codes. The codes differentiate subdescriptors within a ++ * NIX send or receive descriptor, excluding NIX_SEND_HDR_S for send and ++ * NIX_CQE_HDR_S/NIX_WQE_HDR_S for receive, which are determined by their ++ * position as the first subdescriptor, and NIX_RX_PARSE_S, which is ++ * determined by its position as the second subdescriptor. ++ */ ++#define NIX_SUBDC_E_CRC (2) ++#define NIX_SUBDC_E_EXT (1) ++#define NIX_SUBDC_E_IMM (3) ++#define NIX_SUBDC_E_JUMP (6) ++#define NIX_SUBDC_E_MEM (5) ++#define NIX_SUBDC_E_NOP (0) ++#define NIX_SUBDC_E_SG (4) ++#define NIX_SUBDC_E_SOD (0xf) ++#define NIX_SUBDC_E_WORK (7) ++ ++/** ++ * Enumeration nix_tx_actionop_e ++ * ++ * NIX Transmit Action Opcode Enumeration Enumerates the values of ++ * NIX_TX_ACTION_S[OP]. ++ */ ++#define NIX_TX_ACTIONOP_E_DROP (0) ++#define NIX_TX_ACTIONOP_E_DROP_VIOL (5) ++#define NIX_TX_ACTIONOP_E_MCAST (3) ++#define NIX_TX_ACTIONOP_E_UCAST_CHAN (2) ++#define NIX_TX_ACTIONOP_E_UCAST_DEFAULT (1) ++ ++/** ++ * Enumeration nix_tx_vtagop_e ++ * ++ * NIX Transmit Vtag Opcode Enumeration Enumerates the values of ++ * NIX_TX_VTAG_ACTION_S[VTAG0_OP,VTAG1_OP]. ++ */ ++#define NIX_TX_VTAGOP_E_INSERT (1) ++#define NIX_TX_VTAGOP_E_NOP (0) ++#define NIX_TX_VTAGOP_E_REPLACE (2) ++ ++/** ++ * Enumeration nix_txlayer_e ++ * ++ * NIX Transmit Layer Enumeration Enumerates the values of ++ * NIX_AF_LSO_FORMAT()_FIELD()[LAYER]. ++ */ ++#define NIX_TXLAYER_E_IL3 (2) ++#define NIX_TXLAYER_E_IL4 (3) ++#define NIX_TXLAYER_E_OL3 (0) ++#define NIX_TXLAYER_E_OL4 (1) ++ ++/** ++ * Enumeration nix_vtagsize_e ++ * ++ * NIX Vtag Size Enumeration Enumerates the values of ++ * NIX_AF_TX_VTAG_DEF()_CTL[SIZE] and NIX_AF_LF()_RX_VTAG_TYPE()[SIZE]. ++ */ ++#define NIX_VTAGSIZE_E_T4 (0) ++#define NIX_VTAGSIZE_E_T8 (1) ++ ++/** ++ * Enumeration nix_xqe_type_e ++ * ++ * NIX WQE/CQE Type Enumeration Enumerates the values of ++ * NIX_WQE_HDR_S[WQE_TYPE], NIX_CQE_HDR_S[CQE_TYPE]. ++ */ ++#define NIX_XQE_TYPE_E_INVALID (0) ++#define NIX_XQE_TYPE_E_RX (1) ++#define NIX_XQE_TYPE_E_RX_IPSECD (4) ++#define NIX_XQE_TYPE_E_RX_IPSECH (3) ++#define NIX_XQE_TYPE_E_RX_IPSECS (2) ++#define NIX_XQE_TYPE_E_SEND (8) ++ ++/** ++ * Enumeration nix_xqesz_e ++ * ++ * NIX WQE/CQE Size Enumeration Enumerates the values of ++ * NIX_AF_LF()_CFG[XQE_SIZE]. ++ */ ++#define NIX_XQESZ_E_W16 (1) ++#define NIX_XQESZ_E_W64 (0) ++ ++/** ++ * Structure nix_aq_inst_s ++ * ++ * NIX Admin Queue Instruction Structure This structure specifies the AQ ++ * instruction. Instructions and associated software structures are ++ * stored in memory as little-endian unless NIX_AF_CFG[AF_BE] is set. ++ * Hardware reads of NIX_AQ_INST_S do not allocate into LLC. Hardware ++ * reads and writes of the context structure selected by [CTYPE], [LF] ++ * and [CINDEX] use the NDC and LLC caching style configured for that ++ * context. For example: * When [CTYPE] = NIX_AQ_CTYPE_E::RQ: use ++ * NIX_AF_LF()_RSS_CFG[CACHING] and NIX_AF_LF()_RSS_CFG[WAY_MASK]. * When ++ * [CTYPE] = NIX_AQ_CTYPE_E::MCE: use NIX_AF_RX_MCAST_CFG[CACHING] and ++ * NIX_AF_RX_MCAST_CFG[WAY_MASK]. ++ */ ++union nix_aq_inst_s { ++ u64 u[2]; ++ struct nix_aq_inst_s_s { ++ u64 op : 4; ++ u64 ctype : 4; ++ u64 lf : 7; ++ u64 reserved_15_23 : 9; ++ u64 cindex : 20; ++ u64 reserved_44_62 : 19; ++ u64 doneint : 1; ++ u64 res_addr : 64; ++ } s; ++ /* struct nix_aq_inst_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_aq_res_s ++ * ++ * NIX Admin Queue Result Structure NIX writes this structure after it ++ * completes the NIX_AQ_INST_S instruction. The result structure is ++ * exactly 16 bytes, and each instruction completion produces exactly one ++ * result structure. Results and associated software structures are ++ * stored in memory as little-endian unless NIX_AF_CFG[AF_BE] is set. ++ * When [OP] = NIX_AQ_INSTOP_E::INIT, WRITE or READ, this structure is ++ * immediately followed by context read or write data. See ++ * NIX_AQ_INSTOP_E. Hardware writes of NIX_AQ_RES_S and context data ++ * always allocate into LLC. Hardware reads of context data do not ++ * allocate into LLC. ++ */ ++union nix_aq_res_s { ++ u64 u[2]; ++ struct nix_aq_res_s_s { ++ u64 op : 4; ++ u64 ctype : 4; ++ u64 compcode : 8; ++ u64 doneint : 1; ++ u64 reserved_17_63 : 47; ++ u64 reserved_64_127 : 64; ++ } s; ++ /* struct nix_aq_res_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_cint_hw_s ++ * ++ * NIX Completion Interrupt Context Hardware Structure This structure ++ * contains context state maintained by hardware for each completion ++ * interrupt (CINT) in NDC/LLC/DRAM. Software accesses this structure ++ * with the NIX_LF_CINT()* registers. Hardware maintains a table of ++ * NIX_AF_CONST2[CINTS] contiguous NIX_CINT_HW_S structures per LF ++ * starting at AF IOVA NIX_AF_LF()_CINTS_BASE. Always stored in byte ++ * invariant little-endian format (LE8). ++ */ ++union nix_cint_hw_s { ++ u64 u[2]; ++ struct nix_cint_hw_s_s { ++ u64 ecount : 32; ++ u64 qcount : 16; ++ u64 intr : 1; ++ u64 ena : 1; ++ u64 timer_idx : 8; ++ u64 reserved_58_63 : 6; ++ u64 ecount_wait : 32; ++ u64 qcount_wait : 16; ++ u64 time_wait : 8; ++ u64 reserved_120_127 : 8; ++ } s; ++ /* struct nix_cint_hw_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_cq_ctx_s ++ * ++ * NIX Completion Queue Context Structure This structure contains context ++ * state maintained by hardware for each CQ in NDC/LLC/DRAM. Software ++ * uses the same structure format to read and write an CQ context with ++ * the NIX admin queue. ++ */ ++union nix_cq_ctx_s { ++ u64 u[4]; ++ struct nix_cq_ctx_s_s { ++ u64 base : 64; ++ u64 reserved_64_67 : 4; ++ u64 bp_ena : 1; ++ u64 reserved_69_71 : 3; ++ u64 bpid : 9; ++ u64 reserved_81_83 : 3; ++ u64 qint_idx : 7; ++ u64 cq_err : 1; ++ u64 cint_idx : 7; ++ u64 avg_con : 9; ++ u64 wrptr : 20; ++ u64 tail : 20; ++ u64 head : 20; ++ u64 avg_level : 8; ++ u64 update_time : 16; ++ u64 bp : 8; ++ u64 drop : 8; ++ u64 drop_ena : 1; ++ u64 ena : 1; ++ u64 reserved_210_211 : 2; ++ u64 substream : 20; ++ u64 caching : 1; ++ u64 reserved_233_235 : 3; ++ u64 qsize : 4; ++ u64 cq_err_int : 8; ++ u64 cq_err_int_ena : 8; ++ } s; ++ /* struct nix_cq_ctx_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_cqe_hdr_s ++ * ++ * NIX Completion Queue Entry Header Structure This 64-bit structure ++ * defines the first word of every CQE. It is immediately followed by ++ * NIX_RX_PARSE_S in a receive CQE, and by NIX_SEND_COMP_S in a send ++ * completion CQE. Stored in memory as little-endian unless ++ * NIX_AF_LF()_CFG[BE] is set. ++ */ ++union nix_cqe_hdr_s { ++ u64 u; ++ struct nix_cqe_hdr_s_s { ++ u64 tag : 32; ++ u64 q : 20; ++ u64 reserved_52_57 : 6; ++ u64 node : 2; ++ u64 cqe_type : 4; ++ } s; ++ /* struct nix_cqe_hdr_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_inst_hdr_s ++ * ++ * NIX Instruction Header Structure This structure defines the ++ * instruction header that precedes the packet header supplied to NPC for ++ * packets to be transmitted by NIX. ++ */ ++union nix_inst_hdr_s { ++ u64 u; ++ struct nix_inst_hdr_s_s { ++ u64 pf_func : 16; ++ u64 sq : 20; ++ u64 reserved_36_63 : 28; ++ } s; ++ /* struct nix_inst_hdr_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_iova_s ++ * ++ * NIX I/O Virtual Address Structure ++ */ ++union nix_iova_s { ++ u64 u; ++ struct nix_iova_s_s { ++ u64 addr : 64; ++ } s; ++ /* struct nix_iova_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_ipsec_dyno_s ++ * ++ * INTERNAL: NIX IPSEC Dynamic Ordering Counter Structure Internal: Not ++ * used; no IPSEC fast-path. ++ */ ++union nix_ipsec_dyno_s { ++ u32 u; ++ struct nix_ipsec_dyno_s_s { ++ u32 count : 32; ++ } s; ++ /* struct nix_ipsec_dyno_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_mem_result_s ++ * ++ * NIX Memory Value Structure When ++ * NIX_SEND_MEM_S[ALG]=NIX_SENDMEMALG_E::SETRSLT, the value written to ++ * memory is formed with this structure. ++ */ ++union nix_mem_result_s { ++ u64 u; ++ struct nix_mem_result_s_s { ++ u64 v : 1; ++ u64 color : 2; ++ u64 reserved_3_63 : 61; ++ } s; ++ /* struct nix_mem_result_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_op_q_wdata_s ++ * ++ * NIX Statistics Operation Write Data Structure This structure specifies ++ * the write data format of an atomic 64-bit load-and-add of some ++ * NIX_LF_RQ_OP_*, NIX_LF_SQ_OP* and NIX_LF_CQ_OP* registers. ++ */ ++union nix_op_q_wdata_s { ++ u64 u; ++ struct nix_op_q_wdata_s_s { ++ u64 reserved_0_31 : 32; ++ u64 q : 20; ++ u64 reserved_52_63 : 12; ++ } s; ++ /* struct nix_op_q_wdata_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_qint_hw_s ++ * ++ * NIX Queue Interrupt Context Hardware Structure This structure contains ++ * context state maintained by hardware for each queue interrupt (QINT) ++ * in NDC/LLC/DRAM. Software accesses this structure with the ++ * NIX_LF_QINT()* registers. Hardware maintains a table of ++ * NIX_AF_CONST2[QINTS] contiguous NIX_QINT_HW_S structures per LF ++ * starting at IOVA NIX_AF_LF()_QINTS_BASE. Always stored in byte ++ * invariant little-endian format (LE8). ++ */ ++union nix_qint_hw_s { ++ u32 u; ++ struct nix_qint_hw_s_s { ++ u32 count : 22; ++ u32 reserved_22_30 : 9; ++ u32 ena : 1; ++ } s; ++ /* struct nix_qint_hw_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_rq_ctx_hw_s ++ * ++ * NIX Receive Queue Context Structure This structure contains context ++ * state maintained by hardware for each RQ in NDC/LLC/DRAM. Software ++ * uses the equivalent NIX_RQ_CTX_S structure format to read and write an ++ * RQ context with the NIX admin queue. Always stored in byte invariant ++ * little-endian format (LE8). ++ */ ++union nix_rq_ctx_hw_s { ++ u64 u[16]; ++ struct nix_rq_ctx_hw_s_s { ++ u64 ena : 1; ++ u64 sso_ena : 1; ++ u64 ipsech_ena : 1; ++ u64 ena_wqwd : 1; ++ u64 cq : 20; ++ u64 substream : 20; ++ u64 wqe_aura : 20; ++ u64 spb_aura : 20; ++ u64 lpb_aura : 20; ++ u64 sso_grp : 10; ++ u64 sso_tt : 2; ++ u64 pb_caching : 2; ++ u64 wqe_caching : 1; ++ u64 xqe_drop_ena : 1; ++ u64 spb_drop_ena : 1; ++ u64 lpb_drop_ena : 1; ++ u64 wqe_skip : 2; ++ u64 reserved_124_127 : 4; ++ u64 reserved_128_139 : 12; ++ u64 spb_sizem1 : 6; ++ u64 reserved_146_150 : 5; ++ u64 spb_ena : 1; ++ u64 lpb_sizem1 : 12; ++ u64 first_skip : 7; ++ u64 reserved_171 : 1; ++ u64 later_skip : 6; ++ u64 xqe_imm_size : 6; ++ u64 reserved_184_189 : 6; ++ u64 xqe_imm_copy : 1; ++ u64 xqe_hdr_split : 1; ++ u64 xqe_drop : 8; ++ u64 xqe_pass : 8; ++ u64 wqe_pool_drop : 8; ++ u64 wqe_pool_pass : 8; ++ u64 spb_aura_drop : 8; ++ u64 spb_aura_pass : 8; ++ u64 spb_pool_drop : 8; ++ u64 spb_pool_pass : 8; ++ u64 lpb_aura_drop : 8; ++ u64 lpb_aura_pass : 8; ++ u64 lpb_pool_drop : 8; ++ u64 lpb_pool_pass : 8; ++ u64 reserved_288_319 : 32; ++ u64 ltag : 24; ++ u64 good_utag : 8; ++ u64 bad_utag : 8; ++ u64 flow_tagw : 6; ++ u64 reserved_366_383 : 18; ++ u64 octs : 48; ++ u64 reserved_432_447 : 16; ++ u64 pkts : 48; ++ u64 reserved_496_511 : 16; ++ u64 drop_octs : 48; ++ u64 reserved_560_575 : 16; ++ u64 drop_pkts : 48; ++ u64 reserved_624_639 : 16; ++ u64 re_pkts : 48; ++ u64 reserved_688_702 : 15; ++ u64 ena_copy : 1; ++ u64 reserved_704_739 : 36; ++ u64 rq_int : 8; ++ u64 rq_int_ena : 8; ++ u64 qint_idx : 7; ++ u64 reserved_763_767 : 5; ++ u64 reserved_768_831 : 64; ++ u64 reserved_832_895 : 64; ++ u64 reserved_896_959 : 64; ++ u64 reserved_960_1023 : 64; ++ } s; ++ /* struct nix_rq_ctx_hw_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_rq_ctx_s ++ * ++ * NIX Receive Queue Context Structure This structure specifies the ++ * format used by software to read and write an RQ context with the NIX ++ * admin queue. ++ */ ++union nix_rq_ctx_s { ++ u64 u[16]; ++ struct nix_rq_ctx_s_s { ++ u64 ena : 1; ++ u64 sso_ena : 1; ++ u64 ipsech_ena : 1; ++ u64 ena_wqwd : 1; ++ u64 cq : 20; ++ u64 substream : 20; ++ u64 wqe_aura : 20; ++ u64 spb_aura : 20; ++ u64 lpb_aura : 20; ++ u64 sso_grp : 10; ++ u64 sso_tt : 2; ++ u64 pb_caching : 2; ++ u64 wqe_caching : 1; ++ u64 xqe_drop_ena : 1; ++ u64 spb_drop_ena : 1; ++ u64 lpb_drop_ena : 1; ++ u64 reserved_122_127 : 6; ++ u64 reserved_128_139 : 12; ++ u64 spb_sizem1 : 6; ++ u64 wqe_skip : 2; ++ u64 reserved_148_150 : 3; ++ u64 spb_ena : 1; ++ u64 lpb_sizem1 : 12; ++ u64 first_skip : 7; ++ u64 reserved_171 : 1; ++ u64 later_skip : 6; ++ u64 xqe_imm_size : 6; ++ u64 reserved_184_189 : 6; ++ u64 xqe_imm_copy : 1; ++ u64 xqe_hdr_split : 1; ++ u64 xqe_drop : 8; ++ u64 xqe_pass : 8; ++ u64 wqe_pool_drop : 8; ++ u64 wqe_pool_pass : 8; ++ u64 spb_aura_drop : 8; ++ u64 spb_aura_pass : 8; ++ u64 spb_pool_drop : 8; ++ u64 spb_pool_pass : 8; ++ u64 lpb_aura_drop : 8; ++ u64 lpb_aura_pass : 8; ++ u64 lpb_pool_drop : 8; ++ u64 lpb_pool_pass : 8; ++ u64 reserved_288_291 : 4; ++ u64 rq_int : 8; ++ u64 rq_int_ena : 8; ++ u64 qint_idx : 7; ++ u64 reserved_315_319 : 5; ++ u64 ltag : 24; ++ u64 good_utag : 8; ++ u64 bad_utag : 8; ++ u64 flow_tagw : 6; ++ u64 reserved_366_383 : 18; ++ u64 octs : 48; ++ u64 reserved_432_447 : 16; ++ u64 pkts : 48; ++ u64 reserved_496_511 : 16; ++ u64 drop_octs : 48; ++ u64 reserved_560_575 : 16; ++ u64 drop_pkts : 48; ++ u64 reserved_624_639 : 16; ++ u64 re_pkts : 48; ++ u64 reserved_688_703 : 16; ++ u64 reserved_704_767 : 64; ++ u64 reserved_768_831 : 64; ++ u64 reserved_832_895 : 64; ++ u64 reserved_896_959 : 64; ++ u64 reserved_960_1023 : 64; ++ } s; ++ /* struct nix_rq_ctx_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_rsse_s ++ * ++ * NIX Receive Side Scaling Entry Structure This structure specifies the ++ * format of each hardware entry in the NIX RSS tables in NDC/LLC/DRAM. ++ * See NIX_AF_LF()_RSS_BASE and NIX_AF_LF()_RSS_GRP(). Software uses the ++ * same structure format to read and write an RSS table entry with the ++ * NIX admin queue. ++ */ ++union nix_rsse_s { ++ u32 u; ++ struct nix_rsse_s_s { ++ u32 rq : 20; ++ u32 reserved_20_31 : 12; ++ } s; ++ /* struct nix_rsse_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_rx_action_s ++ * ++ * NIX Receive Action Structure This structure defines the format of ++ * NPC_RESULT_S[ACTION] for a receive packet. ++ */ ++union nix_rx_action_s { ++ u64 u; ++ struct nix_rx_action_s_s { ++ u64 op : 4; ++ u64 pf_func : 16; ++ u64 index : 20; ++ u64 match_id : 16; ++ u64 flow_key_alg : 5; ++ u64 reserved_61_63 : 3; ++ } s; ++ /* struct nix_rx_action_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_rx_imm_s ++ * ++ * NIX Receive Immediate Subdescriptor Structure The receive immediate ++ * subdescriptor indicates that bytes immediately following this ++ * NIX_RX_IMM_S (after skipping [APAD] bytes) were saved from the ++ * received packet. The next subdescriptor following this NIX_RX_IMM_S ++ * (when one exists) will follow the immediate bytes, after rounding up ++ * the address to a multiple of 16 bytes. ++ */ ++union nix_rx_imm_s { ++ u64 u; ++ struct nix_rx_imm_s_s { ++ u64 size : 16; ++ u64 apad : 3; ++ u64 reserved_19_59 : 41; ++ u64 subdc : 4; ++ } s; ++ /* struct nix_rx_imm_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_rx_mce_s ++ * ++ * NIX Receive Multicast/Mirror Entry Structure This structure specifies ++ * the format of entries in the NIX receive multicast/mirror table ++ * maintained by hardware in NDC/LLC/DRAM. See NIX_AF_RX_MCAST_BASE and ++ * NIX_AF_RX_MCAST_CFG. Note the table may contain both multicast and ++ * mirror replication lists. Software uses the same structure format to ++ * read and write a multicast/mirror table entry with the NIX admin ++ * queue. ++ */ ++union nix_rx_mce_s { ++ u64 u; ++ struct nix_rx_mce_s_s { ++ u64 op : 2; ++ u64 reserved_2 : 1; ++ u64 eol : 1; ++ u64 index : 20; ++ u64 reserved_24_31 : 8; ++ u64 pf_func : 16; ++ u64 next : 16; ++ } s; ++ /* struct nix_rx_mce_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_rx_parse_s ++ * ++ * NIX Receive Parse Structure This structure contains the receive packet ++ * parse result. It immediately follows NIX_CQE_HDR_S in a receive CQE, ++ * or NIX_WQE_HDR_S in a receive WQE. Stored in memory as little-endian ++ * unless NIX_AF_LF()_CFG[BE] is set. Header layers are always 2-byte ++ * aligned, so all header pointers in this structure ([EOH_PTR], [LAPTR] ++ * through [LHPTR], [VTAG*_PTR]) are even. ++ */ ++union nix_rx_parse_s { ++ u64 u[7]; ++ struct nix_rx_parse_s_s { ++ u64 chan : 12; ++ u64 desc_sizem1 : 5; ++ u64 imm_copy : 1; ++ u64 express : 1; ++ u64 wqwd : 1; ++ u64 errlev : 4; ++ u64 errcode : 8; ++ u64 latype : 4; ++ u64 lbtype : 4; ++ u64 lctype : 4; ++ u64 ldtype : 4; ++ u64 letype : 4; ++ u64 lftype : 4; ++ u64 lgtype : 4; ++ u64 lhtype : 4; ++ u64 pkt_lenm1 : 16; ++ u64 l2m : 1; ++ u64 l2b : 1; ++ u64 l3m : 1; ++ u64 l3b : 1; ++ u64 vtag0_valid : 1; ++ u64 vtag0_gone : 1; ++ u64 vtag1_valid : 1; ++ u64 vtag1_gone : 1; ++ u64 pkind : 6; ++ u64 nix_idx : 2; ++ u64 vtag0_tci : 16; ++ u64 vtag1_tci : 16; ++ u64 laflags : 8; ++ u64 lbflags : 8; ++ u64 lcflags : 8; ++ u64 ldflags : 8; ++ u64 leflags : 8; ++ u64 lfflags : 8; ++ u64 lgflags : 8; ++ u64 lhflags : 8; ++ u64 eoh_ptr : 8; ++ u64 wqe_aura : 20; ++ u64 pb_aura : 20; ++ u64 match_id : 16; ++ u64 laptr : 8; ++ u64 lbptr : 8; ++ u64 lcptr : 8; ++ u64 ldptr : 8; ++ u64 leptr : 8; ++ u64 lfptr : 8; ++ u64 lgptr : 8; ++ u64 lhptr : 8; ++ u64 vtag0_ptr : 8; ++ u64 vtag1_ptr : 8; ++ u64 flow_key_alg : 5; ++ u64 reserved_341_383 : 43; ++ u64 reserved_384_447 : 64; ++ } s; ++ struct nix_rx_parse_s_cn96xx { ++ u64 chan : 12; ++ u64 desc_sizem1 : 5; ++ u64 imm_copy : 1; ++ u64 express : 1; ++ u64 wqwd : 1; ++ u64 errlev : 4; ++ u64 errcode : 8; ++ u64 latype : 4; ++ u64 lbtype : 4; ++ u64 lctype : 4; ++ u64 ldtype : 4; ++ u64 letype : 4; ++ u64 lftype : 4; ++ u64 lgtype : 4; ++ u64 lhtype : 4; ++ u64 pkt_lenm1 : 16; ++ u64 l2m : 1; ++ u64 l2b : 1; ++ u64 l3m : 1; ++ u64 l3b : 1; ++ u64 vtag0_valid : 1; ++ u64 vtag0_gone : 1; ++ u64 vtag1_valid : 1; ++ u64 vtag1_gone : 1; ++ u64 pkind : 6; ++ u64 reserved_94_95 : 2; ++ u64 vtag0_tci : 16; ++ u64 vtag1_tci : 16; ++ u64 laflags : 8; ++ u64 lbflags : 8; ++ u64 lcflags : 8; ++ u64 ldflags : 8; ++ u64 leflags : 8; ++ u64 lfflags : 8; ++ u64 lgflags : 8; ++ u64 lhflags : 8; ++ u64 eoh_ptr : 8; ++ u64 wqe_aura : 20; ++ u64 pb_aura : 20; ++ u64 match_id : 16; ++ u64 laptr : 8; ++ u64 lbptr : 8; ++ u64 lcptr : 8; ++ u64 ldptr : 8; ++ u64 leptr : 8; ++ u64 lfptr : 8; ++ u64 lgptr : 8; ++ u64 lhptr : 8; ++ u64 vtag0_ptr : 8; ++ u64 vtag1_ptr : 8; ++ u64 flow_key_alg : 5; ++ u64 reserved_341_383 : 43; ++ u64 reserved_384_447 : 64; ++ } cn96xx; ++ /* struct nix_rx_parse_s_s cn98xx; */ ++ /* struct nix_rx_parse_s_cn96xx cnf95xx; */ ++ /* struct nix_rx_parse_s_cn96xx loki; */ ++}; ++ ++/** ++ * Structure nix_rx_sg_s ++ * ++ * NIX Receive Scatter/Gather Subdescriptor Structure The receive ++ * scatter/gather subdescriptor specifies one to three segments of packet ++ * data bytes. There may be multiple NIX_RX_SG_Ss in each NIX receive ++ * descriptor. NIX_RX_SG_S is immediately followed by one NIX_IOVA_S ++ * word when [SEGS] = 1, three NIX_IOVA_S words when [SEGS] \>= 2. Each ++ * NIX_IOVA_S word specifies the LF IOVA of first packet data byte in the ++ * corresponding segment; first NIX_IOVA_S word for segment 1, second ++ * word for segment 2, third word for segment 3. Note the third word is ++ * present when [SEGS] \>= 2 but only valid when [SEGS] = 3. ++ */ ++union nix_rx_sg_s { ++ u64 u; ++ struct nix_rx_sg_s_s { ++ u64 seg1_size : 16; ++ u64 seg2_size : 16; ++ u64 seg3_size : 16; ++ u64 segs : 2; ++ u64 reserved_50_59 : 10; ++ u64 subdc : 4; ++ } s; ++ /* struct nix_rx_sg_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_rx_vtag_action_s ++ * ++ * NIX Receive Vtag Action Structure This structure defines the format of ++ * NPC_RESULT_S[VTAG_ACTION] for a receive packet. It specifies up to two ++ * Vtags (e.g. C-VLAN/S-VLAN tags, 802.1BR E-TAG) for optional capture ++ * and/or stripping. ++ */ ++union nix_rx_vtag_action_s { ++ u64 u; ++ struct nix_rx_vtag_action_s_s { ++ u64 vtag0_relptr : 8; ++ u64 vtag0_lid : 3; ++ u64 reserved_11 : 1; ++ u64 vtag0_type : 3; ++ u64 vtag0_valid : 1; ++ u64 reserved_16_31 : 16; ++ u64 vtag1_relptr : 8; ++ u64 vtag1_lid : 3; ++ u64 reserved_43 : 1; ++ u64 vtag1_type : 3; ++ u64 vtag1_valid : 1; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nix_rx_vtag_action_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_send_comp_s ++ * ++ * NIX Send Completion Structure This structure immediately follows ++ * NIX_CQE_HDR_S in a send completion CQE. ++ */ ++union nix_send_comp_s { ++ u64 u; ++ struct nix_send_comp_s_s { ++ u64 status : 8; ++ u64 sqe_id : 16; ++ u64 reserved_24_63 : 40; ++ } s; ++ /* struct nix_send_comp_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_send_crc_s ++ * ++ * NIX Send CRC Subdescriptor Structure The send CRC subdescriptor ++ * specifies a CRC calculation be performed during transmission. Ignored ++ * when present in a send descriptor with NIX_SEND_EXT_S[LSO] set. There ++ * may be up to two NIX_SEND_CRC_Ss per send descriptor. NIX_SEND_CRC_S ++ * constraints: * When present, NIX_SEND_CRC_S subdescriptors must ++ * precede all NIX_SEND_SG_S, NIX_SEND_IMM_S and NIX_SEND_MEM_S ++ * subdescriptors in the send descriptor. * NIX_SEND_CRC_S subdescriptors ++ * must follow the same order as their checksum and insert regions in the ++ * packet, i.e. the checksum and insert regions of a NIX_SEND_CRC_S must ++ * come after the checksum and insert regions of a preceding ++ * NIX_SEND_CRC_S. There must be no overlap between any NIX_SEND_CRC_S ++ * checksum and insert regions. * If either ++ * NIX_SEND_HDR_S[OL4TYPE,IL4TYPE] = NIX_SENDL4TYPE_E::SCTP_CKSUM, the ++ * SCTP checksum region and NIX_SEND_CRC_S insert region must not ++ * overlap, and likewise the NIX_SEND_CRC_S checksum region and SCTP ++ * insert region must not overlap. * If either ++ * NIX_SEND_HDR_S[OL3TYPE,IL3TYPE] = NIX_SENDL3TYPE_E::IP4_CKSUM, the ++ * IPv4 header checksum region and NIX_SEND_CRC_S insert region must not ++ * overlap. * Any checksums inserted by ++ * NIX_SEND_HDR_S[OL3TYPE,OL4TYPE,IL3TYPE,IL4TYPE] must be outside of the ++ * NIX_SEND_CRC_S checksum and insert regions. Hardware adjusts [START], ++ * [SIZE] and [INSERT] as needed to account for any VLAN inserted by ++ * NIX_SEND_EXT_S[VLAN*] or Vtag inserted by NIX_TX_VTAG_ACTION_S. ++ */ ++union nix_send_crc_s { ++ u64 u[2]; ++ struct nix_send_crc_s_s { ++ u64 size : 16; ++ u64 start : 16; ++ u64 insert : 16; ++ u64 reserved_48_57 : 10; ++ u64 alg : 2; ++ u64 subdc : 4; ++ u64 iv : 32; ++ u64 reserved_96_127 : 32; ++ } s; ++ /* struct nix_send_crc_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_send_ext_s ++ * ++ * NIX Send Extended Header Subdescriptor Structure The send extended ++ * header specifies LSO, VLAN insertion, timestamp and/or scheduling ++ * services on the packet. If present, it must immediately follow ++ * NIX_SEND_HDR_S. All fields are assumed to be zero when this ++ * subdescriptor is not present. ++ */ ++union nix_send_ext_s { ++ u64 u[2]; ++ struct nix_send_ext_s_s { ++ u64 lso_mps : 14; ++ u64 lso : 1; ++ u64 tstmp : 1; ++ u64 lso_sb : 8; ++ u64 lso_format : 5; ++ u64 reserved_29_31 : 3; ++ u64 shp_chg : 9; ++ u64 shp_dis : 1; ++ u64 shp_ra : 2; ++ u64 markptr : 8; ++ u64 markform : 7; ++ u64 mark_en : 1; ++ u64 subdc : 4; ++ u64 vlan0_ins_ptr : 8; ++ u64 vlan0_ins_tci : 16; ++ u64 vlan1_ins_ptr : 8; ++ u64 vlan1_ins_tci : 16; ++ u64 vlan0_ins_ena : 1; ++ u64 vlan1_ins_ena : 1; ++ u64 reserved_114_127 : 14; ++ } s; ++ /* struct nix_send_ext_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_send_hdr_s ++ * ++ * NIX Send Header Subdescriptor Structure The send header is the first ++ * subdescriptor of every send descriptor. ++ */ ++union nix_send_hdr_s { ++ u64 u[2]; ++ struct nix_send_hdr_s_s { ++ u64 total : 18; ++ u64 reserved_18 : 1; ++ u64 df : 1; ++ u64 aura : 20; ++ u64 sizem1 : 3; ++ u64 pnc : 1; ++ u64 sq : 20; ++ u64 ol3ptr : 8; ++ u64 ol4ptr : 8; ++ u64 il3ptr : 8; ++ u64 il4ptr : 8; ++ u64 ol3type : 4; ++ u64 ol4type : 4; ++ u64 il3type : 4; ++ u64 il4type : 4; ++ u64 sqe_id : 16; ++ } s; ++ /* struct nix_send_hdr_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_send_imm_s ++ * ++ * NIX Send Immediate Subdescriptor Structure The send immediate ++ * subdescriptor requests that bytes immediately following this ++ * NIX_SEND_IMM_S (after skipping [APAD] bytes) are to be included in the ++ * packet data. The next subdescriptor following this NIX_SEND_IMM_S ++ * (when one exists) will follow the immediate bytes, after rounding up ++ * the address to a multiple of 16 bytes. There may be multiple ++ * NIX_SEND_IMM_S in one NIX send descriptor. A NIX_SEND_IMM_S is ignored ++ * in a NIX send descriptor if the sum of all prior ++ * NIX_SEND_SG_S[SEG*_SIZE]s and NIX_SEND_IMM_S[SIZE]s meets or exceeds ++ * NIX_SEND_HDR_S[TOTAL]. When NIX_SEND_EXT_S[LSO] is set in the ++ * descriptor, all NIX_SEND_IMM_S bytes must be included in the first ++ * NIX_SEND_EXT_S[LSO_SB] bytes of the source packet. ++ */ ++union nix_send_imm_s { ++ u64 u; ++ struct nix_send_imm_s_s { ++ u64 size : 16; ++ u64 apad : 3; ++ u64 reserved_19_59 : 41; ++ u64 subdc : 4; ++ } s; ++ /* struct nix_send_imm_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_send_jump_s ++ * ++ * NIX Send Jump Subdescriptor Structure The send jump subdescriptor ++ * selects a new address for fetching the remaining subdescriptors of a ++ * send descriptor. This allows software to create a send descriptor ++ * longer than SQE size selected by NIX_SQ_CTX_S[MAX_SQE_SIZE]. There ++ * can be only one NIX_SEND_JUMP_S subdescriptor in a send descriptor. If ++ * present, it must immediately follow NIX_SEND_HDR_S if NIX_SEND_EXT_S ++ * is not present, else it must immediately follow NIX_SEND_EXT_S. In ++ * either case, it must terminate the SQE enqueued by software. ++ */ ++union nix_send_jump_s { ++ u64 u[2]; ++ struct nix_send_jump_s_s { ++ u64 sizem1 : 7; ++ u64 reserved_7_13 : 7; ++ u64 ld_type : 2; ++ u64 aura : 20; ++ u64 reserved_36_58 : 23; ++ u64 f : 1; ++ u64 subdc : 4; ++ u64 addr : 64; ++ } s; ++ /* struct nix_send_jump_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_send_mem_s ++ * ++ * NIX Send Memory Subdescriptor Structure The send memory subdescriptor ++ * atomically sets, increments or decrements a memory location. ++ * NIX_SEND_MEM_S subdescriptors must follow all NIX_SEND_SG_S and ++ * NIX_SEND_IMM_S subdescriptors in the NIX send descriptor. NIX will not ++ * initiate the memory update for this subdescriptor until after it has ++ * completed all LLC/DRAM fetches that service all prior NIX_SEND_SG_S ++ * subdescriptors. The memory update is executed once, even if the packet ++ * is replicated due to NIX_TX_ACTION_S[OP] = NIX_TX_ACTIONOP_E::MCAST. ++ * Performance is best if a memory decrement by one is used rather than ++ * any other memory set/increment/decrement. (Less internal bus bandwidth ++ * is used with memory decrements by one.) When NIX_SEND_EXT_S[LSO] is ++ * set in the descriptor, NIX executes the memory update only while ++ * processing the last LSO segment, after processing prior segments. ++ */ ++union nix_send_mem_s { ++ u64 u[2]; ++ struct nix_send_mem_s_s { ++ u64 offset : 16; ++ u64 reserved_16_52 : 37; ++ u64 wmem : 1; ++ u64 dsz : 2; ++ u64 alg : 4; ++ u64 subdc : 4; ++ u64 addr : 64; ++ } s; ++ /* struct nix_send_mem_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_send_sg_s ++ * ++ * NIX Send Scatter/Gather Subdescriptor Structure The send ++ * scatter/gather subdescriptor requests one to three segments of packet ++ * data bytes to be transmitted. There may be multiple NIX_SEND_SG_Ss in ++ * each NIX send descriptor. NIX_SEND_SG_S is immediately followed by ++ * one NIX_IOVA_S word when [SEGS] = 1, three NIX_IOVA_S words when ++ * [SEGS] \>= 2. Each NIX_IOVA_S word specifies the LF IOVA of first ++ * packet data byte in the corresponding segment; first NIX_IOVA_S word ++ * for segment 1, second word for segment 2, third word for segment 3. ++ * Note the third word is present when [SEGS] \>= 2 but only valid when ++ * [SEGS] = 3. If the sum of all prior NIX_SEND_SG_S[SEG*_SIZE]s and ++ * NIX_SEND_IMM_S[SIZE]s meets or exceeds NIX_SEND_HDR_S[TOTAL], this ++ * subdescriptor will not contribute any packet data but may free buffers ++ * to NPA (see [I1]). ++ */ ++union nix_send_sg_s { ++ u64 u; ++ struct nix_send_sg_s_s { ++ u64 seg1_size : 16; ++ u64 seg2_size : 16; ++ u64 seg3_size : 16; ++ u64 segs : 2; ++ u64 reserved_50_54 : 5; ++ u64 i1 : 1; ++ u64 i2 : 1; ++ u64 i3 : 1; ++ u64 ld_type : 2; ++ u64 subdc : 4; ++ } s; ++ /* struct nix_send_sg_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_send_work_s ++ * ++ * NIX Send Work Subdescriptor Structure This subdescriptor adds work to ++ * the SSO. At most one NIX_SEND_WORK_S subdescriptor can exist in the ++ * NIX send descriptor. If a NIX_SEND_WORK_S exists in the descriptor, it ++ * must be the last subdescriptor. NIX will not initiate the work add for ++ * this subdescriptor until after (1) it has completed all LLC/DRAM ++ * fetches that service all prior NIX_SEND_SG_S subdescriptors, (2) it ++ * has fetched all subdescriptors in the descriptor, and (3) all ++ * NIX_SEND_MEM_S[WMEM]=1 LLC/DRAM updates have completed. Provided the ++ * path of descriptors from the SQ through NIX to an output FIFO is ++ * unmodified between the descriptors (as should normally be the case, ++ * but it is possible for software to change the path), NIX also (1) will ++ * submit the SSO add works from all descriptors in the SQ in order, and ++ * (2) will not submit an SSO work add until after all prior descriptors ++ * in the SQ have completed their NIX_SEND_SG_S processing, and (3) will ++ * not submit an SSO work add until after it has fetched all ++ * subdescriptors from prior descriptors in the SQ. When ++ * NIX_SEND_EXT_S[LSO] is set in the descriptor, NIX executes the ++ * NIX_SEND_WORK_S work add only while processing the last LSO segment, ++ * after processing prior segments. Hardware ignores NIX_SEND_WORK_S ++ * when NIX_SQ_CTX_S[SSO_ENA] is clear. ++ */ ++union nix_send_work_s { ++ u64 u[2]; ++ struct nix_send_work_s_s { ++ u64 tag : 32; ++ u64 tt : 2; ++ u64 grp : 10; ++ u64 reserved_44_59 : 16; ++ u64 subdc : 4; ++ u64 addr : 64; ++ } s; ++ /* struct nix_send_work_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_sq_ctx_hw_s ++ * ++ * NIX SQ Context Hardware Structure This structure contains context ++ * state maintained by hardware for each SQ in NDC/LLC/DRAM. Software ++ * uses the equivalent NIX_SQ_CTX_S structure format to read and write an ++ * SQ context with the NIX admin queue. Always stored in byte invariant ++ * little-endian format (LE8). ++ */ ++union nix_sq_ctx_hw_s { ++ u64 u[16]; ++ struct nix_sq_ctx_hw_s_s { ++ u64 ena : 1; ++ u64 substream : 20; ++ u64 max_sqe_size : 2; ++ u64 sqe_way_mask : 16; ++ u64 sqb_aura : 20; ++ u64 gbl_rsvd1 : 5; ++ u64 cq_id : 20; ++ u64 cq_ena : 1; ++ u64 qint_idx : 6; ++ u64 gbl_rsvd2 : 1; ++ u64 sq_int : 8; ++ u64 sq_int_ena : 8; ++ u64 xoff : 1; ++ u64 sqe_stype : 2; ++ u64 gbl_rsvd : 17; ++ u64 head_sqb : 64; ++ u64 head_offset : 6; ++ u64 sqb_dequeue_count : 16; ++ u64 default_chan : 12; ++ u64 sdp_mcast : 1; ++ u64 sso_ena : 1; ++ u64 dse_rsvd1 : 28; ++ u64 sqb_enqueue_count : 16; ++ u64 tail_offset : 6; ++ u64 lmt_dis : 1; ++ u64 smq_rr_quantum : 24; ++ u64 dnq_rsvd1 : 17; ++ u64 tail_sqb : 64; ++ u64 next_sqb : 64; ++ u64 mnq_dis : 1; ++ u64 smq : 9; ++ u64 smq_pend : 1; ++ u64 smq_next_sq : 20; ++ u64 smq_next_sq_vld : 1; ++ u64 scm1_rsvd2 : 32; ++ u64 smenq_sqb : 64; ++ u64 smenq_offset : 6; ++ u64 cq_limit : 8; ++ u64 smq_rr_count : 25; ++ u64 scm_lso_rem : 18; ++ u64 scm_dq_rsvd0 : 7; ++ u64 smq_lso_segnum : 8; ++ u64 vfi_lso_total : 18; ++ u64 vfi_lso_sizem1 : 3; ++ u64 vfi_lso_sb : 8; ++ u64 vfi_lso_mps : 14; ++ u64 vfi_lso_vlan0_ins_ena : 1; ++ u64 vfi_lso_vlan1_ins_ena : 1; ++ u64 vfi_lso_vld : 1; ++ u64 smenq_next_sqb_vld : 1; ++ u64 scm_dq_rsvd1 : 9; ++ u64 smenq_next_sqb : 64; ++ u64 seb_rsvd1 : 64; ++ u64 drop_pkts : 48; ++ u64 drop_octs_lsw : 16; ++ u64 drop_octs_msw : 32; ++ u64 pkts_lsw : 32; ++ u64 pkts_msw : 16; ++ u64 octs : 48; ++ } s; ++ /* struct nix_sq_ctx_hw_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_sq_ctx_s ++ * ++ * NIX Send Queue Context Structure This structure specifies the format ++ * used by software with the NIX admin queue to read and write a send ++ * queue's NIX_SQ_CTX_HW_S structure maintained by hardware in ++ * NDC/LLC/DRAM. The SQ statistics ([OCTS], [PKTS], [DROP_OCTS], ++ * [DROP_PKTS]) do not account for packet replication due to ++ * NIX_TX_ACTION_S[OP] = NIX_TX_ACTIONOP_E::MCAST. ++ */ ++union nix_sq_ctx_s { ++ u64 u[16]; ++ struct nix_sq_ctx_s_s { ++ u64 ena : 1; ++ u64 qint_idx : 6; ++ u64 substream : 20; ++ u64 sdp_mcast : 1; ++ u64 cq : 20; ++ u64 sqe_way_mask : 16; ++ u64 smq : 9; ++ u64 cq_ena : 1; ++ u64 xoff : 1; ++ u64 sso_ena : 1; ++ u64 smq_rr_quantum : 24; ++ u64 default_chan : 12; ++ u64 sqb_count : 16; ++ u64 smq_rr_count : 25; ++ u64 sqb_aura : 20; ++ u64 sq_int : 8; ++ u64 sq_int_ena : 8; ++ u64 sqe_stype : 2; ++ u64 reserved_191 : 1; ++ u64 max_sqe_size : 2; ++ u64 cq_limit : 8; ++ u64 lmt_dis : 1; ++ u64 mnq_dis : 1; ++ u64 smq_next_sq : 20; ++ u64 smq_lso_segnum : 8; ++ u64 tail_offset : 6; ++ u64 smenq_offset : 6; ++ u64 head_offset : 6; ++ u64 smenq_next_sqb_vld : 1; ++ u64 smq_pend : 1; ++ u64 smq_next_sq_vld : 1; ++ u64 reserved_253_255 : 3; ++ u64 next_sqb : 64; ++ u64 tail_sqb : 64; ++ u64 smenq_sqb : 64; ++ u64 smenq_next_sqb : 64; ++ u64 head_sqb : 64; ++ u64 reserved_576_583 : 8; ++ u64 vfi_lso_total : 18; ++ u64 vfi_lso_sizem1 : 3; ++ u64 vfi_lso_sb : 8; ++ u64 vfi_lso_mps : 14; ++ u64 vfi_lso_vlan0_ins_ena : 1; ++ u64 vfi_lso_vlan1_ins_ena : 1; ++ u64 vfi_lso_vld : 1; ++ u64 reserved_630_639 : 10; ++ u64 scm_lso_rem : 18; ++ u64 reserved_658_703 : 46; ++ u64 octs : 48; ++ u64 reserved_752_767 : 16; ++ u64 pkts : 48; ++ u64 reserved_816_831 : 16; ++ u64 reserved_832_895 : 64; ++ u64 drop_octs : 48; ++ u64 reserved_944_959 : 16; ++ u64 drop_pkts : 48; ++ u64 reserved_1008_1023 : 16; ++ } s; ++ /* struct nix_sq_ctx_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_tx_action_s ++ * ++ * NIX Transmit Action Structure This structure defines the format of ++ * NPC_RESULT_S[ACTION] for a transmit packet. ++ */ ++union nix_tx_action_s { ++ u64 u; ++ struct nix_tx_action_s_s { ++ u64 op : 4; ++ u64 reserved_4_11 : 8; ++ u64 index : 20; ++ u64 match_id : 16; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nix_tx_action_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_tx_vtag_action_s ++ * ++ * NIX Transmit Vtag Action Structure This structure defines the format ++ * of NPC_RESULT_S[VTAG_ACTION] for a transmit packet. It specifies the ++ * optional insertion or replacement of up to two Vtags (e.g. ++ * C-VLAN/S-VLAN tags, 802.1BR E-TAG). If two Vtags are specified: * The ++ * Vtag 0 byte offset from packet start (see [VTAG0_RELPTR]) must be less ++ * than or equal to the Vtag 1 byte offset. * Hardware executes the Vtag ++ * 0 action first, Vtag 1 action second. * If Vtag 0 is inserted, ++ * hardware adjusts the Vtag 1 byte offset accordingly. Thus, if the two ++ * offsets are equal in the structure, hardware inserts Vtag 1 ++ * immediately after Vtag 0 in the packet. A Vtag must not be inserted ++ * or replaced within an outer or inner L3/L4 header, but may be inserted ++ * or replaced within an outer L4 payload. ++ */ ++union nix_tx_vtag_action_s { ++ u64 u; ++ struct nix_tx_vtag_action_s_s { ++ u64 vtag0_relptr : 8; ++ u64 vtag0_lid : 3; ++ u64 reserved_11 : 1; ++ u64 vtag0_op : 2; ++ u64 reserved_14_15 : 2; ++ u64 vtag0_def : 10; ++ u64 reserved_26_31 : 6; ++ u64 vtag1_relptr : 8; ++ u64 vtag1_lid : 3; ++ u64 reserved_43 : 1; ++ u64 vtag1_op : 2; ++ u64 reserved_46_47 : 2; ++ u64 vtag1_def : 10; ++ u64 reserved_58_63 : 6; ++ } s; ++ /* struct nix_tx_vtag_action_s_s cn; */ ++}; ++ ++/** ++ * Structure nix_wqe_hdr_s ++ * ++ * NIX Work Queue Entry Header Structure This 64-bit structure defines ++ * the first word of every receive WQE generated by NIX. It is ++ * immediately followed by NIX_RX_PARSE_S. Stored in memory as little- ++ * endian unless NIX_AF_LF()_CFG[BE] is set. ++ */ ++union nix_wqe_hdr_s { ++ u64 u; ++ struct nix_wqe_hdr_s_s { ++ u64 tag : 32; ++ u64 tt : 2; ++ u64 grp : 10; ++ u64 node : 2; ++ u64 q : 14; ++ u64 wqe_type : 4; ++ } s; ++ /* struct nix_wqe_hdr_s_s cn; */ ++}; ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_aq_base ++ * ++ * NIX AF Admin Queue Base Address Register ++ */ ++union nixx_af_aq_base { ++ u64 u; ++ struct nixx_af_aq_base_s { ++ u64 reserved_0_6 : 7; ++ u64 base_addr : 46; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct nixx_af_aq_base_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_AQ_BASE(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_AQ_BASE(void) ++{ ++ return 0x410; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_aq_cfg ++ * ++ * NIX AF Admin Queue Configuration Register ++ */ ++union nixx_af_aq_cfg { ++ u64 u; ++ struct nixx_af_aq_cfg_s { ++ u64 qsize : 4; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct nixx_af_aq_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_AQ_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_AQ_CFG(void) ++{ ++ return 0x400; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_aq_done ++ * ++ * NIX AF Admin Queue Done Count Register ++ */ ++union nixx_af_aq_done { ++ u64 u; ++ struct nixx_af_aq_done_s { ++ u64 done : 20; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct nixx_af_aq_done_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_AQ_DONE(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_AQ_DONE(void) ++{ ++ return 0x450; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_aq_done_ack ++ * ++ * NIX AF Admin Queue Done Count Ack Register This register is written by ++ * software to acknowledge interrupts. ++ */ ++union nixx_af_aq_done_ack { ++ u64 u; ++ struct nixx_af_aq_done_ack_s { ++ u64 done_ack : 20; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct nixx_af_aq_done_ack_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_AQ_DONE_ACK(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_AQ_DONE_ACK(void) ++{ ++ return 0x460; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_aq_done_ena_w1c ++ * ++ * NIX AF Admin Queue Done Interrupt Enable Clear Register ++ */ ++union nixx_af_aq_done_ena_w1c { ++ u64 u; ++ struct nixx_af_aq_done_ena_w1c_s { ++ u64 done : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_aq_done_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_AQ_DONE_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_AQ_DONE_ENA_W1C(void) ++{ ++ return 0x498; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_aq_done_ena_w1s ++ * ++ * NIX AF Admin Queue Done Interrupt Enable Set Register ++ */ ++union nixx_af_aq_done_ena_w1s { ++ u64 u; ++ struct nixx_af_aq_done_ena_w1s_s { ++ u64 done : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_aq_done_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_AQ_DONE_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_AQ_DONE_ENA_W1S(void) ++{ ++ return 0x490; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_aq_done_int ++ * ++ * INTERNAL: NIX AF Admin Queue Done Interrupt Register ++ */ ++union nixx_af_aq_done_int { ++ u64 u; ++ struct nixx_af_aq_done_int_s { ++ u64 done : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_aq_done_int_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_AQ_DONE_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_AQ_DONE_INT(void) ++{ ++ return 0x480; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_aq_done_int_w1s ++ * ++ * INTERNAL: NIX AF Admin Queue Done Interrupt Set Register ++ */ ++union nixx_af_aq_done_int_w1s { ++ u64 u; ++ struct nixx_af_aq_done_int_w1s_s { ++ u64 done : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_aq_done_int_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_AQ_DONE_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_AQ_DONE_INT_W1S(void) ++{ ++ return 0x488; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_aq_done_timer ++ * ++ * NIX AF Admin Queue Done Interrupt Timer Register ++ */ ++union nixx_af_aq_done_timer { ++ u64 u; ++ struct nixx_af_aq_done_timer_s { ++ u64 count : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct nixx_af_aq_done_timer_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_AQ_DONE_TIMER(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_AQ_DONE_TIMER(void) ++{ ++ return 0x470; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_aq_done_wait ++ * ++ * NIX AF Admin Queue Done Interrupt Coalescing Wait Register Specifies ++ * the queue interrupt coalescing settings. ++ */ ++union nixx_af_aq_done_wait { ++ u64 u; ++ struct nixx_af_aq_done_wait_s { ++ u64 num_wait : 20; ++ u64 reserved_20_31 : 12; ++ u64 time_wait : 16; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nixx_af_aq_done_wait_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_AQ_DONE_WAIT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_AQ_DONE_WAIT(void) ++{ ++ return 0x440; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_aq_door ++ * ++ * NIX AF Admin Queue Doorbell Register Software writes to this register ++ * to enqueue entries to AQ. ++ */ ++union nixx_af_aq_door { ++ u64 u; ++ struct nixx_af_aq_door_s { ++ u64 count : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct nixx_af_aq_door_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_AQ_DOOR(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_AQ_DOOR(void) ++{ ++ return 0x430; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_aq_status ++ * ++ * NIX AF Admin Queue Status Register ++ */ ++union nixx_af_aq_status { ++ u64 u; ++ struct nixx_af_aq_status_s { ++ u64 reserved_0_3 : 4; ++ u64 head_ptr : 20; ++ u64 reserved_24_35 : 12; ++ u64 tail_ptr : 20; ++ u64 reserved_56_61 : 6; ++ u64 aq_busy : 1; ++ u64 aq_err : 1; ++ } s; ++ struct nixx_af_aq_status_cn { ++ u64 reserved_0_3 : 4; ++ u64 head_ptr : 20; ++ u64 reserved_24_31 : 8; ++ u64 reserved_32_35 : 4; ++ u64 tail_ptr : 20; ++ u64 reserved_56_61 : 6; ++ u64 aq_busy : 1; ++ u64 aq_err : 1; ++ } cn; ++}; ++ ++static inline u64 NIXX_AF_AQ_STATUS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_AQ_STATUS(void) ++{ ++ return 0x420; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_avg_delay ++ * ++ * NIX AF Queue Average Delay Register ++ */ ++union nixx_af_avg_delay { ++ u64 u; ++ struct nixx_af_avg_delay_s { ++ u64 avg_dly : 19; ++ u64 reserved_19_23 : 5; ++ u64 avg_timer : 16; ++ u64 reserved_40_63 : 24; ++ } s; ++ /* struct nixx_af_avg_delay_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_AVG_DELAY(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_AVG_DELAY(void) ++{ ++ return 0xe0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_bar2_alias# ++ * ++ * NIX Admin Function BAR2 Alias Registers These registers alias to the ++ * NIX BAR2 registers for the PF and function selected by ++ * NIX_AF_BAR2_SEL[PF_FUNC]. Internal: Not implemented. Placeholder for ++ * bug33464. ++ */ ++union nixx_af_bar2_aliasx { ++ u64 u; ++ struct nixx_af_bar2_aliasx_s { ++ u64 data : 64; ++ } s; ++ /* struct nixx_af_bar2_aliasx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_BAR2_ALIASX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_BAR2_ALIASX(u64 a) ++{ ++ return 0x9100000 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_bar2_sel ++ * ++ * NIX Admin Function BAR2 Select Register This register configures BAR2 ++ * accesses from the NIX_AF_BAR2_ALIAS() registers in BAR0. Internal: Not ++ * implemented. Placeholder for bug33464. ++ */ ++union nixx_af_bar2_sel { ++ u64 u; ++ struct nixx_af_bar2_sel_s { ++ u64 alias_pf_func : 16; ++ u64 alias_ena : 1; ++ u64 reserved_17_63 : 47; ++ } s; ++ /* struct nixx_af_bar2_sel_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_BAR2_SEL(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_BAR2_SEL(void) ++{ ++ return 0x9000000; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_blk_rst ++ * ++ * NIX AF Block Reset Register ++ */ ++union nixx_af_blk_rst { ++ u64 u; ++ struct nixx_af_blk_rst_s { ++ u64 rst : 1; ++ u64 reserved_1_62 : 62; ++ u64 busy : 1; ++ } s; ++ /* struct nixx_af_blk_rst_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_BLK_RST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_BLK_RST(void) ++{ ++ return 0xb0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_cfg ++ * ++ * NIX AF General Configuration Register ++ */ ++union nixx_af_cfg { ++ u64 u; ++ struct nixx_af_cfg_s { ++ u64 force_cond_clk_en : 1; ++ u64 force_rx_gbl_clk_en : 1; ++ u64 force_rx_strm_clk_en : 1; ++ u64 force_cqm_clk_en : 1; ++ u64 force_seb_clk_en : 1; ++ u64 force_sqm_clk_en : 1; ++ u64 force_pse_clk_en : 1; ++ u64 reserved_7 : 1; ++ u64 af_be : 1; ++ u64 calibrate_x2p : 1; ++ u64 force_intf_clk_en : 1; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct nixx_af_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_CFG(void) ++{ ++ return 0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_cint_delay ++ * ++ * NIX AF Completion Interrupt Delay Register ++ */ ++union nixx_af_cint_delay { ++ u64 u; ++ struct nixx_af_cint_delay_s { ++ u64 cint_dly : 10; ++ u64 reserved_10_15 : 6; ++ u64 cint_timer : 16; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct nixx_af_cint_delay_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_CINT_DELAY(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_CINT_DELAY(void) ++{ ++ return 0xf0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_cint_timer# ++ * ++ * NIX AF Completion Interrupt Timer Registers ++ */ ++union nixx_af_cint_timerx { ++ u64 u; ++ struct nixx_af_cint_timerx_s { ++ u64 expir_time : 16; ++ u64 cint : 7; ++ u64 reserved_23 : 1; ++ u64 lf : 8; ++ u64 active : 1; ++ u64 reserved_33_63 : 31; ++ } s; ++ /* struct nixx_af_cint_timerx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_CINT_TIMERX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_CINT_TIMERX(u64 a) ++{ ++ return 0x1a40 + 0x40000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_const ++ * ++ * NIX AF Constants Register This register contains constants for ++ * software discovery. ++ */ ++union nixx_af_const { ++ u64 u; ++ struct nixx_af_const_s { ++ u64 cgx_lmac_channels : 8; ++ u64 cgx_lmacs : 4; ++ u64 num_cgx : 4; ++ u64 lbk_channels : 8; ++ u64 num_lbk : 4; ++ u64 num_sdp : 4; ++ u64 reserved_32_47 : 16; ++ u64 links : 8; ++ u64 intfs : 4; ++ u64 reserved_60_63 : 4; ++ } s; ++ /* struct nixx_af_const_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_CONST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_CONST(void) ++{ ++ return 0x20; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_const1 ++ * ++ * NIX AF Constants 1 Register This register contains constants for ++ * software discovery. ++ */ ++union nixx_af_const1 { ++ u64 u; ++ struct nixx_af_const1_s { ++ u64 sdp_channels : 12; ++ u64 rx_bpids : 12; ++ u64 lf_tx_stats : 8; ++ u64 lf_rx_stats : 8; ++ u64 lso_format_fields : 8; ++ u64 lso_formats : 8; ++ u64 reserved_56_63 : 8; ++ } s; ++ /* struct nixx_af_const1_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_CONST1(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_CONST1(void) ++{ ++ return 0x28; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_const2 ++ * ++ * NIX AF Constants 2 Register This register contains constants for ++ * software discovery. ++ */ ++union nixx_af_const2 { ++ u64 u; ++ struct nixx_af_const2_s { ++ u64 lfs : 12; ++ u64 qints : 12; ++ u64 cints : 12; ++ u64 reserved_36_63 : 28; ++ } s; ++ /* struct nixx_af_const2_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_CONST2(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_CONST2(void) ++{ ++ return 0x30; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_const3 ++ * ++ * NIX AF Constants 2 Register This register contains constants for ++ * software discovery. ++ */ ++union nixx_af_const3 { ++ u64 u; ++ struct nixx_af_const3_s { ++ u64 sq_ctx_log2bytes : 4; ++ u64 rq_ctx_log2bytes : 4; ++ u64 cq_ctx_log2bytes : 4; ++ u64 rsse_log2bytes : 4; ++ u64 mce_log2bytes : 4; ++ u64 qint_log2bytes : 4; ++ u64 cint_log2bytes : 4; ++ u64 dyno_log2bytes : 4; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct nixx_af_const3_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_CONST3(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_CONST3(void) ++{ ++ return 0x38; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_cq_const ++ * ++ * NIX AF CQ Constants Register This register contains constants for ++ * software discovery. ++ */ ++union nixx_af_cq_const { ++ u64 u; ++ struct nixx_af_cq_const_s { ++ u64 queues_per_lf : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ /* struct nixx_af_cq_const_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_CQ_CONST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_CQ_CONST(void) ++{ ++ return 0x48; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_cqm_bp_test ++ * ++ * INTERNAL: NIX AF CQM Backpressure Test Registers ++ */ ++union nixx_af_cqm_bp_test { ++ u64 u; ++ struct nixx_af_cqm_bp_test_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 24; ++ u64 enable : 12; ++ u64 reserved_52_63 : 12; ++ } s; ++ /* struct nixx_af_cqm_bp_test_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_CQM_BP_TEST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_CQM_BP_TEST(void) ++{ ++ return 0x48c0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_cqm_eco ++ * ++ * INTERNAL: AF CQM ECO Register ++ */ ++union nixx_af_cqm_eco { ++ u64 u; ++ struct nixx_af_cqm_eco_s { ++ u64 eco_rw : 64; ++ } s; ++ /* struct nixx_af_cqm_eco_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_CQM_ECO(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_CQM_ECO(void) ++{ ++ return 0x590; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_csi_eco ++ * ++ * INTERNAL: AF CSI ECO Register ++ */ ++union nixx_af_csi_eco { ++ u64 u; ++ struct nixx_af_csi_eco_s { ++ u64 eco_rw : 64; ++ } s; ++ /* struct nixx_af_csi_eco_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_CSI_ECO(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_CSI_ECO(void) ++{ ++ return 0x580; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_err_int ++ * ++ * NIX Admin Function Error Interrupt Register ++ */ ++union nixx_af_err_int { ++ u64 u; ++ struct nixx_af_err_int_s { ++ u64 rx_mcast_data_fault : 1; ++ u64 rx_mirror_data_fault : 1; ++ u64 rx_mcast_wqe_fault : 1; ++ u64 rx_mirror_wqe_fault : 1; ++ u64 rx_mce_fault : 1; ++ u64 rx_mce_list_err : 1; ++ u64 rx_unmapped_pf_func : 1; ++ u64 reserved_7_11 : 5; ++ u64 aq_door_err : 1; ++ u64 aq_res_fault : 1; ++ u64 aq_inst_fault : 1; ++ u64 reserved_15_63 : 49; ++ } s; ++ /* struct nixx_af_err_int_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_ERR_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_ERR_INT(void) ++{ ++ return 0x180; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_err_int_ena_w1c ++ * ++ * NIX Admin Function Error Interrupt Enable Clear Register This register ++ * clears interrupt enable bits. ++ */ ++union nixx_af_err_int_ena_w1c { ++ u64 u; ++ struct nixx_af_err_int_ena_w1c_s { ++ u64 rx_mcast_data_fault : 1; ++ u64 rx_mirror_data_fault : 1; ++ u64 rx_mcast_wqe_fault : 1; ++ u64 rx_mirror_wqe_fault : 1; ++ u64 rx_mce_fault : 1; ++ u64 rx_mce_list_err : 1; ++ u64 rx_unmapped_pf_func : 1; ++ u64 reserved_7_11 : 5; ++ u64 aq_door_err : 1; ++ u64 aq_res_fault : 1; ++ u64 aq_inst_fault : 1; ++ u64 reserved_15_63 : 49; ++ } s; ++ /* struct nixx_af_err_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_ERR_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_ERR_INT_ENA_W1C(void) ++{ ++ return 0x198; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_err_int_ena_w1s ++ * ++ * NIX Admin Function Error Interrupt Enable Set Register This register ++ * sets interrupt enable bits. ++ */ ++union nixx_af_err_int_ena_w1s { ++ u64 u; ++ struct nixx_af_err_int_ena_w1s_s { ++ u64 rx_mcast_data_fault : 1; ++ u64 rx_mirror_data_fault : 1; ++ u64 rx_mcast_wqe_fault : 1; ++ u64 rx_mirror_wqe_fault : 1; ++ u64 rx_mce_fault : 1; ++ u64 rx_mce_list_err : 1; ++ u64 rx_unmapped_pf_func : 1; ++ u64 reserved_7_11 : 5; ++ u64 aq_door_err : 1; ++ u64 aq_res_fault : 1; ++ u64 aq_inst_fault : 1; ++ u64 reserved_15_63 : 49; ++ } s; ++ /* struct nixx_af_err_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_ERR_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_ERR_INT_ENA_W1S(void) ++{ ++ return 0x190; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_err_int_w1s ++ * ++ * NIX Admin Function Error Interrupt Set Register This register sets ++ * interrupt bits. ++ */ ++union nixx_af_err_int_w1s { ++ u64 u; ++ struct nixx_af_err_int_w1s_s { ++ u64 rx_mcast_data_fault : 1; ++ u64 rx_mirror_data_fault : 1; ++ u64 rx_mcast_wqe_fault : 1; ++ u64 rx_mirror_wqe_fault : 1; ++ u64 rx_mce_fault : 1; ++ u64 rx_mce_list_err : 1; ++ u64 rx_unmapped_pf_func : 1; ++ u64 reserved_7_11 : 5; ++ u64 aq_door_err : 1; ++ u64 aq_res_fault : 1; ++ u64 aq_inst_fault : 1; ++ u64 reserved_15_63 : 49; ++ } s; ++ /* struct nixx_af_err_int_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_ERR_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_ERR_INT_W1S(void) ++{ ++ return 0x188; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_expr_tx_fifo_status ++ * ++ * INTERNAL: NIX AF Express Transmit FIFO Status Register Internal: ++ * 802.3br frame preemption/express path is defeatured. Old definition: ++ * Status of FIFO which transmits express packets to CGX and LBK. ++ */ ++union nixx_af_expr_tx_fifo_status { ++ u64 u; ++ struct nixx_af_expr_tx_fifo_status_s { ++ u64 count : 12; ++ u64 reserved_12_63 : 52; ++ } s; ++ /* struct nixx_af_expr_tx_fifo_status_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_EXPR_TX_FIFO_STATUS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_EXPR_TX_FIFO_STATUS(void) ++{ ++ return 0x640; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_gen_int ++ * ++ * NIX AF General Interrupt Register ++ */ ++union nixx_af_gen_int { ++ u64 u; ++ struct nixx_af_gen_int_s { ++ u64 rx_mcast_drop : 1; ++ u64 rx_mirror_drop : 1; ++ u64 reserved_2 : 1; ++ u64 tl1_drain : 1; ++ u64 smq_flush_done : 1; ++ u64 reserved_5_63 : 59; ++ } s; ++ /* struct nixx_af_gen_int_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_GEN_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_GEN_INT(void) ++{ ++ return 0x160; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_gen_int_ena_w1c ++ * ++ * NIX AF General Interrupt Enable Clear Register This register clears ++ * interrupt enable bits. ++ */ ++union nixx_af_gen_int_ena_w1c { ++ u64 u; ++ struct nixx_af_gen_int_ena_w1c_s { ++ u64 rx_mcast_drop : 1; ++ u64 rx_mirror_drop : 1; ++ u64 reserved_2 : 1; ++ u64 tl1_drain : 1; ++ u64 smq_flush_done : 1; ++ u64 reserved_5_63 : 59; ++ } s; ++ /* struct nixx_af_gen_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_GEN_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_GEN_INT_ENA_W1C(void) ++{ ++ return 0x178; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_gen_int_ena_w1s ++ * ++ * NIX AF General Interrupt Enable Set Register This register sets ++ * interrupt enable bits. ++ */ ++union nixx_af_gen_int_ena_w1s { ++ u64 u; ++ struct nixx_af_gen_int_ena_w1s_s { ++ u64 rx_mcast_drop : 1; ++ u64 rx_mirror_drop : 1; ++ u64 reserved_2 : 1; ++ u64 tl1_drain : 1; ++ u64 smq_flush_done : 1; ++ u64 reserved_5_63 : 59; ++ } s; ++ /* struct nixx_af_gen_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_GEN_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_GEN_INT_ENA_W1S(void) ++{ ++ return 0x170; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_gen_int_w1s ++ * ++ * NIX AF General Interrupt Set Register This register sets interrupt ++ * bits. ++ */ ++union nixx_af_gen_int_w1s { ++ u64 u; ++ struct nixx_af_gen_int_w1s_s { ++ u64 rx_mcast_drop : 1; ++ u64 rx_mirror_drop : 1; ++ u64 reserved_2 : 1; ++ u64 tl1_drain : 1; ++ u64 smq_flush_done : 1; ++ u64 reserved_5_63 : 59; ++ } s; ++ /* struct nixx_af_gen_int_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_GEN_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_GEN_INT_W1S(void) ++{ ++ return 0x168; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_cfg ++ * ++ * NIX AF Local Function Configuration Registers ++ */ ++union nixx_af_lfx_cfg { ++ u64 u; ++ struct nixx_af_lfx_cfg_s { ++ u64 npa_pf_func : 16; ++ u64 sso_pf_func : 16; ++ u64 be : 1; ++ u64 xqe_size : 2; ++ u64 reserved_35_63 : 29; ++ } s; ++ /* struct nixx_af_lfx_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_CFG(u64 a) ++{ ++ return 0x4000 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_cints_base ++ * ++ * NIX AF Local Function Completion Interrupts Base Address Registers ++ * This register specifies the base AF IOVA of LF's completion interrupt ++ * context table in NDC/LLC/DRAM. The table consists of ++ * NIX_AF_CONST2[CINTS] contiguous NIX_CINT_HW_S structures. ++ */ ++union nixx_af_lfx_cints_base { ++ u64 u; ++ struct nixx_af_lfx_cints_base_s { ++ u64 reserved_0_6 : 7; ++ u64 addr : 46; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct nixx_af_lfx_cints_base_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_CINTS_BASE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_CINTS_BASE(u64 a) ++{ ++ return 0x4130 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_cints_cfg ++ * ++ * NIX AF Local Function Completion Interrupts Configuration Registers ++ * This register controls access to the LF's completion interrupt context ++ * table in NDC/LLC/DRAM. The table consists of NIX_AF_CONST2[CINTS] ++ * contiguous NIX_CINT_HW_S structures. The size of each structure is 1 ++ * \<\< NIX_AF_CONST3[CINT_LOG2BYTES]. ++ */ ++union nixx_af_lfx_cints_cfg { ++ u64 u; ++ struct nixx_af_lfx_cints_cfg_s { ++ u64 reserved_0_19 : 20; ++ u64 way_mask : 16; ++ u64 caching : 1; ++ u64 reserved_37_63 : 27; ++ } s; ++ /* struct nixx_af_lfx_cints_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_CINTS_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_CINTS_CFG(u64 a) ++{ ++ return 0x4120 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_cqs_base ++ * ++ * NIX AF Local Function Completion Queues Base Address Register This ++ * register specifies the base AF IOVA of the LF's CQ context table. The ++ * table consists of NIX_AF_LF()_CQS_CFG[MAX_QUEUESM1]+1 contiguous ++ * NIX_CQ_CTX_S structures. ++ */ ++union nixx_af_lfx_cqs_base { ++ u64 u; ++ struct nixx_af_lfx_cqs_base_s { ++ u64 reserved_0_6 : 7; ++ u64 addr : 46; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct nixx_af_lfx_cqs_base_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_CQS_BASE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_CQS_BASE(u64 a) ++{ ++ return 0x4070 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_cqs_cfg ++ * ++ * NIX AF Local Function Completion Queues Configuration Register This ++ * register configures completion queues in the LF. ++ */ ++union nixx_af_lfx_cqs_cfg { ++ u64 u; ++ struct nixx_af_lfx_cqs_cfg_s { ++ u64 max_queuesm1 : 20; ++ u64 way_mask : 16; ++ u64 caching : 1; ++ u64 reserved_37_63 : 27; ++ } s; ++ /* struct nixx_af_lfx_cqs_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_CQS_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_CQS_CFG(u64 a) ++{ ++ return 0x4060 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_lock# ++ * ++ * NIX AF Local Function Lockdown Registers Internal: The NIX lockdown ++ * depth of 32 bytes is shallow compared to 96 bytes for NIC and meant ++ * for outer MAC and/or VLAN (optionally preceded by a small number of ++ * skip bytes). NPC's MCAM can be used for deeper protocol-aware ++ * lockdown. ++ */ ++union nixx_af_lfx_lockx { ++ u64 u; ++ struct nixx_af_lfx_lockx_s { ++ u64 data : 32; ++ u64 bit_ena : 32; ++ } s; ++ /* struct nixx_af_lfx_lockx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_LOCKX(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_LOCKX(u64 a, u64 b) ++{ ++ return 0x4300 + 0x20000 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_qints_base ++ * ++ * NIX AF Local Function Queue Interrupts Base Address Registers This ++ * register specifies the base AF IOVA of LF's queue interrupt context ++ * table in NDC/LLC/DRAM. The table consists of NIX_AF_CONST2[QINTS] ++ * contiguous NIX_QINT_HW_S structures. ++ */ ++union nixx_af_lfx_qints_base { ++ u64 u; ++ struct nixx_af_lfx_qints_base_s { ++ u64 reserved_0_6 : 7; ++ u64 addr : 46; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct nixx_af_lfx_qints_base_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_QINTS_BASE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_QINTS_BASE(u64 a) ++{ ++ return 0x4110 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_qints_cfg ++ * ++ * NIX AF Local Function Queue Interrupts Configuration Registers This ++ * register controls access to the LF's queue interrupt context table in ++ * NDC/LLC/DRAM. The table consists of NIX_AF_CONST2[QINTS] contiguous ++ * NIX_QINT_HW_S structures. The size of each structure is 1 \<\< ++ * NIX_AF_CONST3[QINT_LOG2BYTES]. ++ */ ++union nixx_af_lfx_qints_cfg { ++ u64 u; ++ struct nixx_af_lfx_qints_cfg_s { ++ u64 reserved_0_19 : 20; ++ u64 way_mask : 16; ++ u64 caching : 1; ++ u64 reserved_37_63 : 27; ++ } s; ++ /* struct nixx_af_lfx_qints_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_QINTS_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_QINTS_CFG(u64 a) ++{ ++ return 0x4100 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_rqs_base ++ * ++ * NIX AF Local Function Receive Queues Base Address Register This ++ * register specifies the base AF IOVA of the LF's RQ context table. The ++ * table consists of NIX_AF_LF()_RQS_CFG[MAX_QUEUESM1]+1 contiguous ++ * NIX_RQ_CTX_S structures. ++ */ ++union nixx_af_lfx_rqs_base { ++ u64 u; ++ struct nixx_af_lfx_rqs_base_s { ++ u64 reserved_0_6 : 7; ++ u64 addr : 46; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct nixx_af_lfx_rqs_base_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_RQS_BASE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_RQS_BASE(u64 a) ++{ ++ return 0x4050 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_rqs_cfg ++ * ++ * NIX AF Local Function Receive Queues Configuration Register This ++ * register configures receive queues in the LF. ++ */ ++union nixx_af_lfx_rqs_cfg { ++ u64 u; ++ struct nixx_af_lfx_rqs_cfg_s { ++ u64 max_queuesm1 : 20; ++ u64 way_mask : 16; ++ u64 caching : 1; ++ u64 reserved_37_63 : 27; ++ } s; ++ /* struct nixx_af_lfx_rqs_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_RQS_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_RQS_CFG(u64 a) ++{ ++ return 0x4040 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_rss_base ++ * ++ * NIX AF Local Function Receive Size Scaling Table Base Address Register ++ * This register specifies the base AF IOVA of the RSS table per LF. The ++ * table is present when NIX_AF_LF()_RSS_CFG[ENA] is set and consists of ++ * 1 \<\< (NIX_AF_LF()_RSS_CFG[SIZE] + 8) contiguous NIX_RSSE_S ++ * structures, where the size of each structure is 1 \<\< ++ * NIX_AF_CONST3[RSSE_LOG2BYTES]. See NIX_AF_LF()_RSS_GRP(). ++ */ ++union nixx_af_lfx_rss_base { ++ u64 u; ++ struct nixx_af_lfx_rss_base_s { ++ u64 reserved_0_6 : 7; ++ u64 addr : 46; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct nixx_af_lfx_rss_base_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_RSS_BASE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_RSS_BASE(u64 a) ++{ ++ return 0x40d0 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_rss_cfg ++ * ++ * NIX AF Local Function Receive Size Scaling Table Configuration ++ * Register See NIX_AF_LF()_RSS_BASE and NIX_AF_LF()_RSS_GRP(). ++ */ ++union nixx_af_lfx_rss_cfg { ++ u64 u; ++ struct nixx_af_lfx_rss_cfg_s { ++ u64 size : 4; ++ u64 ena : 1; ++ u64 adder_is_tag_lsb : 1; ++ u64 reserved_6_19 : 14; ++ u64 way_mask : 16; ++ u64 caching : 1; ++ u64 reserved_37_63 : 27; ++ } s; ++ struct nixx_af_lfx_rss_cfg_cn96xxp1 { ++ u64 size : 4; ++ u64 ena : 1; ++ u64 reserved_5_19 : 15; ++ u64 way_mask : 16; ++ u64 caching : 1; ++ u64 reserved_37_63 : 27; ++ } cn96xxp1; ++ /* struct nixx_af_lfx_rss_cfg_s cn96xxp3; */ ++ /* struct nixx_af_lfx_rss_cfg_s cn98xx; */ ++ /* struct nixx_af_lfx_rss_cfg_cn96xxp1 cnf95xx; */ ++ /* struct nixx_af_lfx_rss_cfg_s loki; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_RSS_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_RSS_CFG(u64 a) ++{ ++ return 0x40c0 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_rss_grp# ++ * ++ * NIX AF Local Function Receive Side Scaling Group Registers A receive ++ * packet targets a LF's RSS group when its NIX_RX_ACTION_S[OP] = ++ * NIX_RX_ACTIONOP_E::RSS, or its target multicast list has an entry with ++ * NIX_RX_MCE_S[OP] = NIX_RX_MCOP_E::RSS. The RSS group index (this ++ * register's last index) is NIX_RX_ACTION_S[INDEX] or ++ * NIX_RX_MCE_S[INDEX]. The RSS computation is as follows: * The ++ * packet's flow_tag (see NIX_LF_RX_SECRET()) and RSS group are used to ++ * select a NIX_RSSE_S entry in the LF's RSS table (see [SIZEM1]). * ++ * NIX_RSSE_S selects the packet's destination RQ. ++ */ ++union nixx_af_lfx_rss_grpx { ++ u64 u; ++ struct nixx_af_lfx_rss_grpx_s { ++ u64 offset : 11; ++ u64 reserved_11_15 : 5; ++ u64 sizem1 : 3; ++ u64 reserved_19_63 : 45; ++ } s; ++ /* struct nixx_af_lfx_rss_grpx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_RSS_GRPX(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_RSS_GRPX(u64 a, u64 b) ++{ ++ return 0x4600 + 0x20000 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_rx_cfg ++ * ++ * NIX AF Local Function Receive Configuration Register ++ */ ++union nixx_af_lfx_rx_cfg { ++ u64 u; ++ struct nixx_af_lfx_rx_cfg_s { ++ u64 reserved_0_31 : 32; ++ u64 drop_re : 1; ++ u64 lenerr_en : 1; ++ u64 ip6_udp_opt : 1; ++ u64 dis_apad : 1; ++ u64 csum_il4 : 1; ++ u64 csum_ol4 : 1; ++ u64 len_il4 : 1; ++ u64 len_il3 : 1; ++ u64 len_ol4 : 1; ++ u64 len_ol3 : 1; ++ u64 reserved_42_63 : 22; ++ } s; ++ struct nixx_af_lfx_rx_cfg_cn96xxp1 { ++ u64 reserved_0_31 : 32; ++ u64 reserved_32 : 1; ++ u64 lenerr_en : 1; ++ u64 ip6_udp_opt : 1; ++ u64 dis_apad : 1; ++ u64 csum_il4 : 1; ++ u64 csum_ol4 : 1; ++ u64 len_il4 : 1; ++ u64 len_il3 : 1; ++ u64 len_ol4 : 1; ++ u64 len_ol3 : 1; ++ u64 reserved_42_63 : 22; ++ } cn96xxp1; ++ /* struct nixx_af_lfx_rx_cfg_s cn96xxp3; */ ++ /* struct nixx_af_lfx_rx_cfg_s cn98xx; */ ++ /* struct nixx_af_lfx_rx_cfg_s cnf95xx; */ ++ /* struct nixx_af_lfx_rx_cfg_s loki; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_RX_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_RX_CFG(u64 a) ++{ ++ return 0x40a0 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_rx_ipsec_cfg0 ++ * ++ * INTERNAL: NIX AF LF Receive IPSEC Configuration Registers Internal: ++ * Not used; no IPSEC fast-path. ++ */ ++union nixx_af_lfx_rx_ipsec_cfg0 { ++ u64 u; ++ struct nixx_af_lfx_rx_ipsec_cfg0_s { ++ u64 lenm1_max : 14; ++ u64 reserved_14_15 : 2; ++ u64 sa_pow2_size : 4; ++ u64 tag_const : 24; ++ u64 tt : 2; ++ u64 defcpt : 1; ++ u64 hshcpt : 1; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nixx_af_lfx_rx_ipsec_cfg0_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_RX_IPSEC_CFG0(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_RX_IPSEC_CFG0(u64 a) ++{ ++ return 0x4140 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_rx_ipsec_cfg1 ++ * ++ * INTERNAL: NIX AF LF Receive IPSEC Security Association Configuration ++ * Register Internal: Not used; no IPSEC fast-path. ++ */ ++union nixx_af_lfx_rx_ipsec_cfg1 { ++ u64 u; ++ struct nixx_af_lfx_rx_ipsec_cfg1_s { ++ u64 sa_idx_max : 32; ++ u64 sa_idx_w : 5; ++ u64 reserved_37_63 : 27; ++ } s; ++ /* struct nixx_af_lfx_rx_ipsec_cfg1_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_RX_IPSEC_CFG1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_RX_IPSEC_CFG1(u64 a) ++{ ++ return 0x4148 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_rx_ipsec_dyno_base ++ * ++ * INTERNAL: NIX AF LF Receive IPSEC Dynamic Ordering Base Address ++ * Registers Internal: Not used; no IPSEC fast-path. ++ */ ++union nixx_af_lfx_rx_ipsec_dyno_base { ++ u64 u; ++ struct nixx_af_lfx_rx_ipsec_dyno_base_s { ++ u64 reserved_0_6 : 7; ++ u64 addr : 46; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct nixx_af_lfx_rx_ipsec_dyno_base_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_RX_IPSEC_DYNO_BASE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_RX_IPSEC_DYNO_BASE(u64 a) ++{ ++ return 0x4158 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_rx_ipsec_dyno_cfg ++ * ++ * INTERNAL: NIX AF LF Receive IPSEC Dynamic Ordering Base Address ++ * Registers Internal: Not used; no IPSEC fast-path. ++ */ ++union nixx_af_lfx_rx_ipsec_dyno_cfg { ++ u64 u; ++ struct nixx_af_lfx_rx_ipsec_dyno_cfg_s { ++ u64 dyno_idx_w : 4; ++ u64 dyno_ena : 1; ++ u64 reserved_5_19 : 15; ++ u64 way_mask : 16; ++ u64 caching : 1; ++ u64 reserved_37_63 : 27; ++ } s; ++ /* struct nixx_af_lfx_rx_ipsec_dyno_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_RX_IPSEC_DYNO_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_RX_IPSEC_DYNO_CFG(u64 a) ++{ ++ return 0x4150 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_rx_ipsec_sa_base ++ * ++ * INTERNAL: NIX AF LF Receive IPSEC Security Association Base Address ++ * Register Internal: Not used; no IPSEC fast-path. ++ */ ++union nixx_af_lfx_rx_ipsec_sa_base { ++ u64 u; ++ struct nixx_af_lfx_rx_ipsec_sa_base_s { ++ u64 reserved_0_6 : 7; ++ u64 addr : 46; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct nixx_af_lfx_rx_ipsec_sa_base_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_RX_IPSEC_SA_BASE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_RX_IPSEC_SA_BASE(u64 a) ++{ ++ return 0x4170 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_rx_stat# ++ * ++ * NIX AF Local Function Receive Statistics Registers The last dimension ++ * indicates which statistic, and is enumerated by NIX_STAT_LF_RX_E. ++ */ ++union nixx_af_lfx_rx_statx { ++ u64 u; ++ struct nixx_af_lfx_rx_statx_s { ++ u64 stat : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nixx_af_lfx_rx_statx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_RX_STATX(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_RX_STATX(u64 a, u64 b) ++{ ++ return 0x4500 + 0x20000 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_rx_vtag_type# ++ * ++ * NIX AF Local Function Receive Vtag Type Registers These registers ++ * specify optional Vtag (e.g. VLAN, E-TAG) actions for received packets. ++ * Indexed by NIX_RX_VTAG_ACTION_S[VTAG*_TYPE]. ++ */ ++union nixx_af_lfx_rx_vtag_typex { ++ u64 u; ++ struct nixx_af_lfx_rx_vtag_typex_s { ++ u64 size : 1; ++ u64 reserved_1_3 : 3; ++ u64 strip : 1; ++ u64 capture : 1; ++ u64 reserved_6_63 : 58; ++ } s; ++ /* struct nixx_af_lfx_rx_vtag_typex_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_RX_VTAG_TYPEX(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_RX_VTAG_TYPEX(u64 a, u64 b) ++{ ++ return 0x4200 + 0x20000 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_sqs_base ++ * ++ * NIX AF Local Function Send Queues Base Address Register This register ++ * specifies the base AF IOVA of the LF's SQ context table. The table ++ * consists of NIX_AF_LF()_SQS_CFG[MAX_QUEUESM1]+1 contiguous ++ * NIX_SQ_CTX_HW_S structures. ++ */ ++union nixx_af_lfx_sqs_base { ++ u64 u; ++ struct nixx_af_lfx_sqs_base_s { ++ u64 reserved_0_6 : 7; ++ u64 addr : 46; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct nixx_af_lfx_sqs_base_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_SQS_BASE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_SQS_BASE(u64 a) ++{ ++ return 0x4030 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_sqs_cfg ++ * ++ * NIX AF Local Function Send Queues Configuration Register This register ++ * configures send queues in the LF. ++ */ ++union nixx_af_lfx_sqs_cfg { ++ u64 u; ++ struct nixx_af_lfx_sqs_cfg_s { ++ u64 max_queuesm1 : 20; ++ u64 way_mask : 16; ++ u64 caching : 1; ++ u64 reserved_37_63 : 27; ++ } s; ++ /* struct nixx_af_lfx_sqs_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_SQS_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_SQS_CFG(u64 a) ++{ ++ return 0x4020 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_tx_cfg ++ * ++ * NIX AF Local Function Transmit Configuration Register ++ */ ++union nixx_af_lfx_tx_cfg { ++ u64 u; ++ struct nixx_af_lfx_tx_cfg_s { ++ u64 vlan0_ins_etype : 16; ++ u64 vlan1_ins_etype : 16; ++ u64 send_tstmp_ena : 1; ++ u64 lock_viol_cqe_ena : 1; ++ u64 lock_ena : 1; ++ u64 reserved_35_63 : 29; ++ } s; ++ /* struct nixx_af_lfx_tx_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_TX_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_TX_CFG(u64 a) ++{ ++ return 0x4080 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_tx_cfg2 ++ * ++ * NIX AF Local Function Transmit Configuration Register ++ */ ++union nixx_af_lfx_tx_cfg2 { ++ u64 u; ++ struct nixx_af_lfx_tx_cfg2_s { ++ u64 lmt_ena : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_lfx_tx_cfg2_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_TX_CFG2(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_TX_CFG2(u64 a) ++{ ++ return 0x4028 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_tx_parse_cfg ++ * ++ * NIX AF Local Function Transmit Parse Configuration Register ++ */ ++union nixx_af_lfx_tx_parse_cfg { ++ u64 u; ++ struct nixx_af_lfx_tx_parse_cfg_s { ++ u64 pkind : 6; ++ u64 reserved_6_63 : 58; ++ } s; ++ /* struct nixx_af_lfx_tx_parse_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_TX_PARSE_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_TX_PARSE_CFG(u64 a) ++{ ++ return 0x4090 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_tx_stat# ++ * ++ * NIX AF Local Function Transmit Statistics Registers The last dimension ++ * indicates which statistic, and is enumerated by NIX_STAT_LF_TX_E. ++ */ ++union nixx_af_lfx_tx_statx { ++ u64 u; ++ struct nixx_af_lfx_tx_statx_s { ++ u64 stat : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nixx_af_lfx_tx_statx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_TX_STATX(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_TX_STATX(u64 a, u64 b) ++{ ++ return 0x4400 + 0x20000 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf#_tx_status ++ * ++ * NIX AF LF Transmit Status Register ++ */ ++union nixx_af_lfx_tx_status { ++ u64 u; ++ struct nixx_af_lfx_tx_status_s { ++ u64 sq_ctx_err : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_lfx_tx_status_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LFX_TX_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LFX_TX_STATUS(u64 a) ++{ ++ return 0x4180 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lf_rst ++ * ++ * NIX Admin Function LF Reset Register ++ */ ++union nixx_af_lf_rst { ++ u64 u; ++ struct nixx_af_lf_rst_s { ++ u64 lf : 8; ++ u64 reserved_8_11 : 4; ++ u64 exec : 1; ++ u64 reserved_13_63 : 51; ++ } s; ++ /* struct nixx_af_lf_rst_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LF_RST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LF_RST(void) ++{ ++ return 0x150; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lso_cfg ++ * ++ * NIX AF Large Send Offload Configuration Register ++ */ ++union nixx_af_lso_cfg { ++ u64 u; ++ struct nixx_af_lso_cfg_s { ++ u64 tcp_lsf : 16; ++ u64 tcp_msf : 16; ++ u64 tcp_fsf : 16; ++ u64 reserved_48_62 : 15; ++ u64 enable : 1; ++ } s; ++ /* struct nixx_af_lso_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LSO_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LSO_CFG(void) ++{ ++ return 0xa8; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_lso_format#_field# ++ * ++ * NIX AF Large Send Offload Format Field Registers These registers ++ * specify LSO packet modification formats. Each format may modify up to ++ * eight packet fields with the following constraints: * If fewer than ++ * eight fields are modified, [ALG] must be NIX_LSOALG_E::NOP in the ++ * unused field registers. * Modified fields must be specified in ++ * contiguous field registers starting with NIX_AF_LSO_FORMAT()_FIELD(0). ++ * * Modified fields cannot overlap. * Multiple fields with the same ++ * [LAYER] value must be specified in ascending [OFFSET] order. * Fields ++ * in different layers must be specified in ascending [LAYER] order. ++ */ ++union nixx_af_lso_formatx_fieldx { ++ u64 u; ++ struct nixx_af_lso_formatx_fieldx_s { ++ u64 offset : 8; ++ u64 layer : 2; ++ u64 reserved_10_11 : 2; ++ u64 sizem1 : 2; ++ u64 reserved_14_15 : 2; ++ u64 alg : 3; ++ u64 reserved_19_63 : 45; ++ } s; ++ /* struct nixx_af_lso_formatx_fieldx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_LSO_FORMATX_FIELDX(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_LSO_FORMATX_FIELDX(u64 a, u64 b) ++{ ++ return 0x1b00 + 0x10000 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_mark_format#_ctl ++ * ++ * NIX AF Packet Marking Format Registers Describes packet marking ++ * calculations for YELLOW and for NIX_COLORRESULT_E::RED_SEND packets. ++ * NIX_SEND_EXT_S[MARKFORM] selects the CSR used for the packet ++ * descriptor. All the packet marking offset calculations assume big- ++ * endian bits within a byte. For example, if NIX_SEND_EXT_S[MARKPTR] is ++ * 3 and [OFFSET] is 5 and the packet is YELLOW, the NIX marking hardware ++ * would do this: _ byte[3]\<2:0\> |= [Y_VAL]\<3:1\> _ ++ * byte[3]\<2:0\> &= ~[Y_MASK]\<3:1\> _ byte[4]\<7\> |= [Y_VAL]\<0\> ++ * _ byte[4]\<7\> &= ~[Y_MASK]\<0\> where byte[3] is the third byte ++ * in the packet, and byte[4] the fourth. For another example, if ++ * NIX_SEND_EXT_S[MARKPTR] is 3 and [OFFSET] is 0 and the packet is ++ * NIX_COLORRESULT_E::RED_SEND, _ byte[3]\<7:4\> |= [R_VAL]\<3:0\> _ ++ * byte[3]\<7:4\> &= ~[R_MASK]\<3:0\> ++ */ ++union nixx_af_mark_formatx_ctl { ++ u64 u; ++ struct nixx_af_mark_formatx_ctl_s { ++ u64 r_val : 4; ++ u64 r_mask : 4; ++ u64 y_val : 4; ++ u64 y_mask : 4; ++ u64 offset : 3; ++ u64 reserved_19_63 : 45; ++ } s; ++ /* struct nixx_af_mark_formatx_ctl_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_MARK_FORMATX_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_MARK_FORMATX_CTL(u64 a) ++{ ++ return 0x900 + 0x40000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_mc_mirror_const ++ * ++ * NIX AF Multicast/Mirror Constants Register This register contains ++ * constants for software discovery. ++ */ ++union nixx_af_mc_mirror_const { ++ u64 u; ++ struct nixx_af_mc_mirror_const_s { ++ u64 buf_size : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct nixx_af_mc_mirror_const_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_MC_MIRROR_CONST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_MC_MIRROR_CONST(void) ++{ ++ return 0x98; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_mdq#_cir ++ * ++ * NIX AF Meta Descriptor Queue Committed Information Rate Registers This ++ * register has the same bit fields as NIX_AF_TL1()_CIR. ++ */ ++union nixx_af_mdqx_cir { ++ u64 u; ++ struct nixx_af_mdqx_cir_s { ++ u64 enable : 1; ++ u64 rate_mantissa : 8; ++ u64 rate_exponent : 4; ++ u64 rate_divider_exponent : 4; ++ u64 reserved_17_28 : 12; ++ u64 burst_mantissa : 8; ++ u64 burst_exponent : 4; ++ u64 reserved_41_63 : 23; ++ } s; ++ /* struct nixx_af_mdqx_cir_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_MDQX_CIR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_MDQX_CIR(u64 a) ++{ ++ return 0x1420 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_mdq#_md_debug ++ * ++ * NIX AF Meta Descriptor Queue Meta Descriptor State Debug Registers ++ * This register provides access to the meta descriptor at the front of ++ * the MDQ. An MDQ can hold up to 8 packet meta descriptors (PMD) and one ++ * flush meta descriptor (FMD). ++ */ ++union nixx_af_mdqx_md_debug { ++ u64 u; ++ struct nixx_af_mdqx_md_debug_s { ++ u64 pkt_len : 16; ++ u64 red_algo_override : 2; ++ u64 shp_dis : 1; ++ u64 reserved_19 : 1; ++ u64 shp_chg : 9; ++ u64 reserved_29_31 : 3; ++ u64 sqm_pkt_id : 13; ++ u64 reserved_45_60 : 16; ++ u64 md_type : 2; ++ u64 reserved_63 : 1; ++ } s; ++ /* struct nixx_af_mdqx_md_debug_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_MDQX_MD_DEBUG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_MDQX_MD_DEBUG(u64 a) ++{ ++ return 0x14c0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_mdq#_parent ++ * ++ * NIX AF Meta Descriptor Queue Topology Registers ++ */ ++union nixx_af_mdqx_parent { ++ u64 u; ++ struct nixx_af_mdqx_parent_s { ++ u64 reserved_0_15 : 16; ++ u64 parent : 9; ++ u64 reserved_25_63 : 39; ++ } s; ++ /* struct nixx_af_mdqx_parent_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_MDQX_PARENT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_MDQX_PARENT(u64 a) ++{ ++ return 0x1480 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_mdq#_pir ++ * ++ * NIX AF Meta Descriptor Queue Peak Information Rate Registers This ++ * register has the same bit fields as NIX_AF_TL1()_CIR. ++ */ ++union nixx_af_mdqx_pir { ++ u64 u; ++ struct nixx_af_mdqx_pir_s { ++ u64 enable : 1; ++ u64 rate_mantissa : 8; ++ u64 rate_exponent : 4; ++ u64 rate_divider_exponent : 4; ++ u64 reserved_17_28 : 12; ++ u64 burst_mantissa : 8; ++ u64 burst_exponent : 4; ++ u64 reserved_41_63 : 23; ++ } s; ++ /* struct nixx_af_mdqx_pir_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_MDQX_PIR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_MDQX_PIR(u64 a) ++{ ++ return 0x1430 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_mdq#_pointers ++ * ++ * INTERNAL: NIX AF Meta Descriptor 4 Linked List Pointers Debug Register ++ * This register has the same bit fields as NIX_AF_TL4()_POINTERS. ++ */ ++union nixx_af_mdqx_pointers { ++ u64 u; ++ struct nixx_af_mdqx_pointers_s { ++ u64 next : 9; ++ u64 reserved_9_15 : 7; ++ u64 prev : 9; ++ u64 reserved_25_63 : 39; ++ } s; ++ /* struct nixx_af_mdqx_pointers_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_MDQX_POINTERS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_MDQX_POINTERS(u64 a) ++{ ++ return 0x1460 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_mdq#_ptr_fifo ++ * ++ * INTERNAL: NIX Meta Descriptor Queue Pointer FIFO State Debug Registers ++ */ ++union nixx_af_mdqx_ptr_fifo { ++ u64 u; ++ struct nixx_af_mdqx_ptr_fifo_s { ++ u64 tail : 4; ++ u64 head : 4; ++ u64 p_con : 1; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct nixx_af_mdqx_ptr_fifo_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_MDQX_PTR_FIFO(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_MDQX_PTR_FIFO(u64 a) ++{ ++ return 0x14d0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_mdq#_sched_state ++ * ++ * NIX AF Meta Descriptor Queue Scheduling Control State Registers This ++ * register has the same bit fields as NIX_AF_TL2()_SCHED_STATE. ++ */ ++union nixx_af_mdqx_sched_state { ++ u64 u; ++ struct nixx_af_mdqx_sched_state_s { ++ u64 rr_count : 25; ++ u64 reserved_25_63 : 39; ++ } s; ++ /* struct nixx_af_mdqx_sched_state_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_MDQX_SCHED_STATE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_MDQX_SCHED_STATE(u64 a) ++{ ++ return 0x1440 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_mdq#_schedule ++ * ++ * NIX AF Meta Descriptor Queue Scheduling Control Registers This ++ * register has the same bit fields as NIX_AF_TL2()_SCHEDULE. ++ */ ++union nixx_af_mdqx_schedule { ++ u64 u; ++ struct nixx_af_mdqx_schedule_s { ++ u64 rr_quantum : 24; ++ u64 prio : 4; ++ u64 reserved_28_63 : 36; ++ } s; ++ /* struct nixx_af_mdqx_schedule_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_MDQX_SCHEDULE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_MDQX_SCHEDULE(u64 a) ++{ ++ return 0x1400 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_mdq#_shape ++ * ++ * NIX AF Meta Descriptor Queue Shaping Control Registers This register ++ * has the same bit fields as NIX_AF_TL3()_SHAPE. ++ */ ++union nixx_af_mdqx_shape { ++ u64 u; ++ struct nixx_af_mdqx_shape_s { ++ u64 adjust : 9; ++ u64 red_algo : 2; ++ u64 red_disable : 1; ++ u64 yellow_disable : 1; ++ u64 reserved_13_23 : 11; ++ u64 length_disable : 1; ++ u64 schedule_list : 2; ++ u64 reserved_27_63 : 37; ++ } s; ++ /* struct nixx_af_mdqx_shape_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_MDQX_SHAPE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_MDQX_SHAPE(u64 a) ++{ ++ return 0x1410 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_mdq#_shape_state ++ * ++ * NIX AF Meta Descriptor Queue Shaping State Registers This register has ++ * the same bit fields as NIX_AF_TL2()_SHAPE_STATE. This register must ++ * not be written during normal operation. ++ */ ++union nixx_af_mdqx_shape_state { ++ u64 u; ++ struct nixx_af_mdqx_shape_state_s { ++ u64 cir_accum : 26; ++ u64 pir_accum : 26; ++ u64 color : 2; ++ u64 reserved_54_63 : 10; ++ } s; ++ /* struct nixx_af_mdqx_shape_state_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_MDQX_SHAPE_STATE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_MDQX_SHAPE_STATE(u64 a) ++{ ++ return 0x1450 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_mdq#_sw_xoff ++ * ++ * NIX AF Meta Descriptor Controlled XOFF Registers This register has the ++ * same bit fields as NIX_AF_TL1()_SW_XOFF ++ */ ++union nixx_af_mdqx_sw_xoff { ++ u64 u; ++ struct nixx_af_mdqx_sw_xoff_s { ++ u64 xoff : 1; ++ u64 drain : 1; ++ u64 reserved_2 : 1; ++ u64 drain_irq : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct nixx_af_mdqx_sw_xoff_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_MDQX_SW_XOFF(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_MDQX_SW_XOFF(u64 a) ++{ ++ return 0x1470 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_mdq_const ++ * ++ * NIX AF Meta Descriptor Queue Constants Register This register contains ++ * constants for software discovery. ++ */ ++union nixx_af_mdq_const { ++ u64 u; ++ struct nixx_af_mdq_const_s { ++ u64 count : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct nixx_af_mdq_const_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_MDQ_CONST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_MDQ_CONST(void) ++{ ++ return 0x90; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_mdq_md_count ++ * ++ * NIX AF MDQ MD COUNT Registers ++ */ ++union nixx_af_mdq_md_count { ++ u64 u; ++ struct nixx_af_mdq_md_count_s { ++ u64 count : 64; ++ } s; ++ /* struct nixx_af_mdq_md_count_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_MDQ_MD_COUNT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_MDQ_MD_COUNT(void) ++{ ++ return 0xda0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_ndc_cfg ++ * ++ * NIX AF General Configuration Register ++ */ ++union nixx_af_ndc_cfg { ++ u64 u; ++ struct nixx_af_ndc_cfg_s { ++ u64 ndc_ign_pois : 1; ++ u64 byp_sq : 1; ++ u64 byp_sqb : 1; ++ u64 byp_cqs : 1; ++ u64 byp_cints : 1; ++ u64 byp_dyno : 1; ++ u64 byp_mce : 1; ++ u64 byp_rqc : 1; ++ u64 byp_rsse : 1; ++ u64 byp_mc_data : 1; ++ u64 byp_mc_wqe : 1; ++ u64 byp_mr_data : 1; ++ u64 byp_mr_wqe : 1; ++ u64 byp_qints : 1; ++ u64 reserved_14_63 : 50; ++ } s; ++ /* struct nixx_af_ndc_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_NDC_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_NDC_CFG(void) ++{ ++ return 0x18; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_ndc_rx_sync ++ * ++ * NIX AF Receive NDC Sync Register Used to synchronize the NIX receive ++ * NDC (NDC_IDX_E::NIX()_RX). ++ */ ++union nixx_af_ndc_rx_sync { ++ u64 u; ++ struct nixx_af_ndc_rx_sync_s { ++ u64 lf : 8; ++ u64 reserved_8_11 : 4; ++ u64 exec : 1; ++ u64 reserved_13_63 : 51; ++ } s; ++ /* struct nixx_af_ndc_rx_sync_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_NDC_RX_SYNC(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_NDC_RX_SYNC(void) ++{ ++ return 0x3e0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_ndc_tx_sync ++ * ++ * NIX AF NDC_TX Sync Register Used to synchronize the NIX transmit NDC ++ * (NDC_IDX_E::NIX()_TX). ++ */ ++union nixx_af_ndc_tx_sync { ++ u64 u; ++ struct nixx_af_ndc_tx_sync_s { ++ u64 lf : 8; ++ u64 reserved_8_11 : 4; ++ u64 exec : 1; ++ u64 reserved_13_63 : 51; ++ } s; ++ /* struct nixx_af_ndc_tx_sync_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_NDC_TX_SYNC(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_NDC_TX_SYNC(void) ++{ ++ return 0x3f0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_norm_tx_fifo_status ++ * ++ * NIX AF Normal Transmit FIFO Status Register Status of FIFO which ++ * transmits normal packets to CGX and LBK. ++ */ ++union nixx_af_norm_tx_fifo_status { ++ u64 u; ++ struct nixx_af_norm_tx_fifo_status_s { ++ u64 count : 12; ++ u64 reserved_12_63 : 52; ++ } s; ++ /* struct nixx_af_norm_tx_fifo_status_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_NORM_TX_FIFO_STATUS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_NORM_TX_FIFO_STATUS(void) ++{ ++ return 0x648; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pq#_dbg_arb_link_exp ++ * ++ * INTERNAL: NIX AF PQ Arb Link EXPRESS Debug Register ++ */ ++union nixx_af_pqx_dbg_arb_link_exp { ++ u64 u; ++ struct nixx_af_pqx_dbg_arb_link_exp_s { ++ u64 req : 1; ++ u64 act_c_con : 1; ++ u64 cnt : 2; ++ u64 reserved_4_5 : 2; ++ u64 rr_mask : 1; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct nixx_af_pqx_dbg_arb_link_exp_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PQX_DBG_ARB_LINK_EXP(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PQX_DBG_ARB_LINK_EXP(u64 a) ++{ ++ return 0xce8 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pq#_dbg_arb_link_nrm ++ * ++ * INTERNAL: NIX AF PQ Arb Link NORMAL Debug Register ++ */ ++union nixx_af_pqx_dbg_arb_link_nrm { ++ u64 u; ++ struct nixx_af_pqx_dbg_arb_link_nrm_s { ++ u64 req : 1; ++ u64 act_c_con : 1; ++ u64 cnt : 2; ++ u64 reserved_4_5 : 2; ++ u64 rr_mask : 1; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct nixx_af_pqx_dbg_arb_link_nrm_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PQX_DBG_ARB_LINK_NRM(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PQX_DBG_ARB_LINK_NRM(u64 a) ++{ ++ return 0xce0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pq#_dbg_arb_link_sdp ++ * ++ * INTERNAL: NIX AF PQ Arb Link SDP Debug Register ++ */ ++union nixx_af_pqx_dbg_arb_link_sdp { ++ u64 u; ++ struct nixx_af_pqx_dbg_arb_link_sdp_s { ++ u64 req : 1; ++ u64 act_c_con : 1; ++ u64 cnt : 2; ++ u64 reserved_4_5 : 2; ++ u64 rr_mask : 1; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct nixx_af_pqx_dbg_arb_link_sdp_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PQX_DBG_ARB_LINK_SDP(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PQX_DBG_ARB_LINK_SDP(u64 a) ++{ ++ return 0xcf0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pq_arb_crd_rdy_debug ++ * ++ * INTERNAL: NIX AF PQ_ARB Node Credit Ready Registers NIX AF PQ ARB ++ * Credit ready register ++ */ ++union nixx_af_pq_arb_crd_rdy_debug { ++ u64 u; ++ struct nixx_af_pq_arb_crd_rdy_debug_s { ++ u64 node_crd_rdy : 28; ++ u64 reserved_28_63 : 36; ++ } s; ++ /* struct nixx_af_pq_arb_crd_rdy_debug_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PQ_ARB_CRD_RDY_DEBUG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PQ_ARB_CRD_RDY_DEBUG(void) ++{ ++ return 0xf10; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pq_arb_dwrr_msk_debug ++ * ++ * INTERNAL: NIX AF PQ_ARB DWRR mask set read only debug Registers ++ */ ++union nixx_af_pq_arb_dwrr_msk_debug { ++ u64 u; ++ struct nixx_af_pq_arb_dwrr_msk_debug_s { ++ u64 node_dwrr_mask_set : 28; ++ u64 reserved_28_63 : 36; ++ } s; ++ /* struct nixx_af_pq_arb_dwrr_msk_debug_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PQ_ARB_DWRR_MSK_DEBUG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PQ_ARB_DWRR_MSK_DEBUG(void) ++{ ++ return 0xf30; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pq_arb_node_gnt_debug ++ * ++ * INTERNAL: NIX AF PQ_ARB Node Grant vector Registers ++ */ ++union nixx_af_pq_arb_node_gnt_debug { ++ u64 u; ++ struct nixx_af_pq_arb_node_gnt_debug_s { ++ u64 node_grant_vec : 28; ++ u64 reserved_28_63 : 36; ++ } s; ++ /* struct nixx_af_pq_arb_node_gnt_debug_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PQ_ARB_NODE_GNT_DEBUG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PQ_ARB_NODE_GNT_DEBUG(void) ++{ ++ return 0xf20; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pq_arb_node_req_debug ++ * ++ * INTERNAL: NIX AF PQ_ARB Node Request Debug Registers NIX AF PQ ARB ++ * Node Request Debug register ++ */ ++union nixx_af_pq_arb_node_req_debug { ++ u64 u; ++ struct nixx_af_pq_arb_node_req_debug_s { ++ u64 node_req : 28; ++ u64 reserved_28_63 : 36; ++ } s; ++ /* struct nixx_af_pq_arb_node_req_debug_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PQ_ARB_NODE_REQ_DEBUG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PQ_ARB_NODE_REQ_DEBUG(void) ++{ ++ return 0xf00; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pq_arb_shape_vld_dbg ++ * ++ * INTERNAL: NIX AF PQ_ARB shape valid set Register ++ */ ++union nixx_af_pq_arb_shape_vld_dbg { ++ u64 u; ++ struct nixx_af_pq_arb_shape_vld_dbg_s { ++ u64 node_shape_vld_set : 28; ++ u64 reserved_28_63 : 36; ++ } s; ++ /* struct nixx_af_pq_arb_shape_vld_dbg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PQ_ARB_SHAPE_VLD_DBG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PQ_ARB_SHAPE_VLD_DBG(void) ++{ ++ return 0xf40; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pq_dbg_arb_0 ++ * ++ * INTERNAL: NIX AF PQ Arb Debug 0 Register ++ */ ++union nixx_af_pq_dbg_arb_0 { ++ u64 u; ++ struct nixx_af_pq_dbg_arb_0_s { ++ u64 rr_mask_clr : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_pq_dbg_arb_0_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PQ_DBG_ARB_0(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PQ_DBG_ARB_0(void) ++{ ++ return 0xcf8; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pq_lnk_#_dwrr_msk_dbg ++ * ++ * INTERNAL: NIX AF PQ_ARB Physical Link DWRR MASK Registers ++ */ ++union nixx_af_pq_lnk_x_dwrr_msk_dbg { ++ u64 u; ++ struct nixx_af_pq_lnk_x_dwrr_msk_dbg_s { ++ u64 link_dwrr_mask_set : 28; ++ u64 reserved_28_63 : 36; ++ } s; ++ /* struct nixx_af_pq_lnk_x_dwrr_msk_dbg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PQ_LNK_X_DWRR_MSK_DBG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PQ_LNK_X_DWRR_MSK_DBG(u64 a) ++{ ++ return 0x1100 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pse_400_rate_divider ++ * ++ * INTERNAL: NIX AF PSE 400 Rate Divider Register ++ */ ++union nixx_af_pse_400_rate_divider { ++ u64 u; ++ struct nixx_af_pse_400_rate_divider_s { ++ u64 rate_div_cfg : 9; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct nixx_af_pse_400_rate_divider_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PSE_400_RATE_DIVIDER(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PSE_400_RATE_DIVIDER(void) ++{ ++ return 0x830; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pse_active_cycles_pc ++ * ++ * NIX AF Active Cycles Register These registers are indexed by the ++ * conditional clock domain number. ++ */ ++union nixx_af_pse_active_cycles_pc { ++ u64 u; ++ struct nixx_af_pse_active_cycles_pc_s { ++ u64 act_cyc : 64; ++ } s; ++ /* struct nixx_af_pse_active_cycles_pc_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PSE_ACTIVE_CYCLES_PC(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PSE_ACTIVE_CYCLES_PC(void) ++{ ++ return 0x8c0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pse_bp_test0 ++ * ++ * INTERNAL: NIX AF PSE Backpressure Test 0 Register ++ */ ++union nixx_af_pse_bp_test0 { ++ u64 u; ++ struct nixx_af_pse_bp_test0_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_63 : 52; ++ } s; ++ struct nixx_af_pse_bp_test0_cn96xxp1 { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 8; ++ u64 reserved_24_59 : 36; ++ u64 enable : 4; ++ } cn96xxp1; ++ struct nixx_af_pse_bp_test0_cn96xxp3 { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 reserved_16_19 : 4; ++ u64 bp_cfg : 12; ++ u64 reserved_32_55 : 24; ++ u64 reserved_56_57 : 2; ++ u64 enable : 6; ++ } cn96xxp3; ++ /* struct nixx_af_pse_bp_test0_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_pse_bp_test0_cn96xxp1 cnf95xxp1; */ ++ struct nixx_af_pse_bp_test0_cnf95xxp2 { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 8; ++ u64 reserved_24_31 : 8; ++ u64 reserved_32_55 : 24; ++ u64 reserved_56_59 : 4; ++ u64 enable : 4; ++ } cnf95xxp2; ++ /* struct nixx_af_pse_bp_test0_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_PSE_BP_TEST0(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PSE_BP_TEST0(void) ++{ ++ return 0x840; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pse_bp_test1 ++ * ++ * INTERNAL: NIX AF PSE Backpressure Test 1 Register ++ */ ++union nixx_af_pse_bp_test1 { ++ u64 u; ++ struct nixx_af_pse_bp_test1_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 10; ++ u64 reserved_26_63 : 38; ++ } s; ++ struct nixx_af_pse_bp_test1_cn96xxp1 { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 8; ++ u64 reserved_24_59 : 36; ++ u64 enable : 4; ++ } cn96xxp1; ++ struct nixx_af_pse_bp_test1_cn96xxp3 { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 10; ++ u64 reserved_26_31 : 6; ++ u64 reserved_32_55 : 24; ++ u64 reserved_56_58 : 3; ++ u64 enable : 5; ++ } cn96xxp3; ++ /* struct nixx_af_pse_bp_test1_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_pse_bp_test1_cn96xxp1 cnf95xxp1; */ ++ struct nixx_af_pse_bp_test1_cnf95xxp2 { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 8; ++ u64 reserved_24_31 : 8; ++ u64 reserved_32_55 : 24; ++ u64 reserved_56_59 : 4; ++ u64 enable : 4; ++ } cnf95xxp2; ++ /* struct nixx_af_pse_bp_test1_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_PSE_BP_TEST1(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PSE_BP_TEST1(void) ++{ ++ return 0x850; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pse_bp_test2 ++ * ++ * INTERNAL: NIX AF PSE Backpressure Test 2 Register ++ */ ++union nixx_af_pse_bp_test2 { ++ u64 u; ++ struct nixx_af_pse_bp_test2_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 10; ++ u64 reserved_26_63 : 38; ++ } s; ++ struct nixx_af_pse_bp_test2_cn96xxp1 { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 8; ++ u64 reserved_24_59 : 36; ++ u64 enable : 4; ++ } cn96xxp1; ++ struct nixx_af_pse_bp_test2_cn96xxp3 { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 10; ++ u64 reserved_26_31 : 6; ++ u64 reserved_32_55 : 24; ++ u64 reserved_56_58 : 3; ++ u64 enable : 5; ++ } cn96xxp3; ++ /* struct nixx_af_pse_bp_test2_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_pse_bp_test2_cn96xxp1 cnf95xxp1; */ ++ struct nixx_af_pse_bp_test2_cnf95xxp2 { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 8; ++ u64 reserved_24_31 : 8; ++ u64 reserved_32_55 : 24; ++ u64 reserved_56_59 : 4; ++ u64 enable : 4; ++ } cnf95xxp2; ++ /* struct nixx_af_pse_bp_test2_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_PSE_BP_TEST2(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PSE_BP_TEST2(void) ++{ ++ return 0x860; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pse_bp_test3 ++ * ++ * INTERNAL: NIX AF PSE Backpressure Test 3 Register ++ */ ++union nixx_af_pse_bp_test3 { ++ u64 u; ++ struct nixx_af_pse_bp_test3_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 10; ++ u64 reserved_26_63 : 38; ++ } s; ++ struct nixx_af_pse_bp_test3_cn96xxp1 { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 8; ++ u64 reserved_24_59 : 36; ++ u64 enable : 4; ++ } cn96xxp1; ++ struct nixx_af_pse_bp_test3_cn96xxp3 { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 10; ++ u64 reserved_26_31 : 6; ++ u64 reserved_32_55 : 24; ++ u64 reserved_56_58 : 3; ++ u64 enable : 5; ++ } cn96xxp3; ++ /* struct nixx_af_pse_bp_test3_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_pse_bp_test3_cn96xxp1 cnf95xxp1; */ ++ struct nixx_af_pse_bp_test3_cnf95xxp2 { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 8; ++ u64 reserved_24_31 : 8; ++ u64 reserved_32_55 : 24; ++ u64 reserved_56_59 : 4; ++ u64 enable : 4; ++ } cnf95xxp2; ++ /* struct nixx_af_pse_bp_test3_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_PSE_BP_TEST3(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PSE_BP_TEST3(void) ++{ ++ return 0x870; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pse_channel_level ++ * ++ * NIX AF PSE Channel Level Register ++ */ ++union nixx_af_pse_channel_level { ++ u64 u; ++ struct nixx_af_pse_channel_level_s { ++ u64 bp_level : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_pse_channel_level_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PSE_CHANNEL_LEVEL(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PSE_CHANNEL_LEVEL(void) ++{ ++ return 0x800; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pse_const ++ * ++ * NIX AF PSE Constants Register This register contains constants for ++ * software discovery. ++ */ ++union nixx_af_pse_const { ++ u64 u; ++ struct nixx_af_pse_const_s { ++ u64 levels : 4; ++ u64 reserved_4_7 : 4; ++ u64 mark_formats : 8; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct nixx_af_pse_const_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PSE_CONST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PSE_CONST(void) ++{ ++ return 0x60; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pse_eco ++ * ++ * INTERNAL: AF PSE ECO Register ++ */ ++union nixx_af_pse_eco { ++ u64 u; ++ struct nixx_af_pse_eco_s { ++ u64 eco_rw : 64; ++ } s; ++ /* struct nixx_af_pse_eco_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PSE_ECO(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PSE_ECO(void) ++{ ++ return 0x5d0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pse_expr_bp_test ++ * ++ * INTERNAL: NIX AF PSE Express Backpressure Test Register Internal: ++ * 802.3br frame preemption/express path is defeatured. ++ */ ++union nixx_af_pse_expr_bp_test { ++ u64 u; ++ struct nixx_af_pse_expr_bp_test_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 32; ++ u64 enable : 16; ++ } s; ++ /* struct nixx_af_pse_expr_bp_test_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PSE_EXPR_BP_TEST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PSE_EXPR_BP_TEST(void) ++{ ++ return 0x890; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pse_norm_bp_test ++ * ++ * INTERNAL: NIX AF PSE Normal Backpressure Test Register ++ */ ++union nixx_af_pse_norm_bp_test { ++ u64 u; ++ struct nixx_af_pse_norm_bp_test_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 32; ++ u64 reserved_48_63 : 16; ++ } s; ++ struct nixx_af_pse_norm_bp_test_cn96xxp1 { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 32; ++ u64 enable : 16; ++ } cn96xxp1; ++ struct nixx_af_pse_norm_bp_test_cn96xxp3 { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 12; ++ u64 reserved_28_57 : 30; ++ u64 enable : 6; ++ } cn96xxp3; ++ /* struct nixx_af_pse_norm_bp_test_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_pse_norm_bp_test_cn96xxp1 cnf95xx; */ ++ /* struct nixx_af_pse_norm_bp_test_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_PSE_NORM_BP_TEST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PSE_NORM_BP_TEST(void) ++{ ++ return 0x880; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_pse_shaper_cfg ++ * ++ * NIX AF PSE Shaper Configuration Register ++ */ ++union nixx_af_pse_shaper_cfg { ++ u64 u; ++ struct nixx_af_pse_shaper_cfg_s { ++ u64 red_send_as_yellow : 1; ++ u64 color_aware : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct nixx_af_pse_shaper_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_PSE_SHAPER_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_PSE_SHAPER_CFG(void) ++{ ++ return 0x810; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_ras ++ * ++ * NIX AF RAS Interrupt Register This register is intended for delivery ++ * of RAS events to the SCP, so should be ignored by OS drivers. ++ */ ++union nixx_af_ras { ++ u64 u; ++ struct nixx_af_ras_s { ++ u64 rx_mce_poison : 1; ++ u64 rx_mcast_wqe_poison : 1; ++ u64 rx_mirror_wqe_poison : 1; ++ u64 rx_mcast_data_poison : 1; ++ u64 rx_mirror_data_poison : 1; ++ u64 reserved_5_31 : 27; ++ u64 aq_ctx_poison : 1; ++ u64 aq_res_poison : 1; ++ u64 aq_inst_poison : 1; ++ u64 reserved_35_63 : 29; ++ } s; ++ /* struct nixx_af_ras_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RAS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RAS(void) ++{ ++ return 0x1a0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_ras_ena_w1c ++ * ++ * NIX AF RAS Interrupt Enable Clear Register This register clears ++ * interrupt enable bits. ++ */ ++union nixx_af_ras_ena_w1c { ++ u64 u; ++ struct nixx_af_ras_ena_w1c_s { ++ u64 rx_mce_poison : 1; ++ u64 rx_mcast_wqe_poison : 1; ++ u64 rx_mirror_wqe_poison : 1; ++ u64 rx_mcast_data_poison : 1; ++ u64 rx_mirror_data_poison : 1; ++ u64 reserved_5_31 : 27; ++ u64 aq_ctx_poison : 1; ++ u64 aq_res_poison : 1; ++ u64 aq_inst_poison : 1; ++ u64 reserved_35_63 : 29; ++ } s; ++ /* struct nixx_af_ras_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RAS_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RAS_ENA_W1C(void) ++{ ++ return 0x1b8; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_ras_ena_w1s ++ * ++ * NIX AF RAS Interrupt Enable Set Register This register sets interrupt ++ * enable bits. ++ */ ++union nixx_af_ras_ena_w1s { ++ u64 u; ++ struct nixx_af_ras_ena_w1s_s { ++ u64 rx_mce_poison : 1; ++ u64 rx_mcast_wqe_poison : 1; ++ u64 rx_mirror_wqe_poison : 1; ++ u64 rx_mcast_data_poison : 1; ++ u64 rx_mirror_data_poison : 1; ++ u64 reserved_5_31 : 27; ++ u64 aq_ctx_poison : 1; ++ u64 aq_res_poison : 1; ++ u64 aq_inst_poison : 1; ++ u64 reserved_35_63 : 29; ++ } s; ++ /* struct nixx_af_ras_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RAS_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RAS_ENA_W1S(void) ++{ ++ return 0x1b0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_ras_w1s ++ * ++ * NIX AF RAS Interrupt Set Register This register sets interrupt bits. ++ */ ++union nixx_af_ras_w1s { ++ u64 u; ++ struct nixx_af_ras_w1s_s { ++ u64 rx_mce_poison : 1; ++ u64 rx_mcast_wqe_poison : 1; ++ u64 rx_mirror_wqe_poison : 1; ++ u64 rx_mcast_data_poison : 1; ++ u64 rx_mirror_data_poison : 1; ++ u64 reserved_5_31 : 27; ++ u64 aq_ctx_poison : 1; ++ u64 aq_res_poison : 1; ++ u64 aq_inst_poison : 1; ++ u64 reserved_35_63 : 29; ++ } s; ++ /* struct nixx_af_ras_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RAS_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RAS_W1S(void) ++{ ++ return 0x1a8; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_reb_bp_test# ++ * ++ * INTERNAL: NIX AF REB Backpressure Test Registers ++ */ ++union nixx_af_reb_bp_testx { ++ u64 u; ++ struct nixx_af_reb_bp_testx_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 8; ++ u64 reserved_24_47 : 24; ++ u64 enable : 4; ++ u64 reserved_52_63 : 12; ++ } s; ++ /* struct nixx_af_reb_bp_testx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_REB_BP_TESTX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_REB_BP_TESTX(u64 a) ++{ ++ return 0x4840 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rq_const ++ * ++ * NIX AF RQ Constants Register This register contains constants for ++ * software discovery. ++ */ ++union nixx_af_rq_const { ++ u64 u; ++ struct nixx_af_rq_const_s { ++ u64 queues_per_lf : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ /* struct nixx_af_rq_const_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RQ_CONST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RQ_CONST(void) ++{ ++ return 0x50; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rqm_bp_test ++ * ++ * INTERNAL: NIX AF REB Backpressure Test Registers ++ */ ++union nixx_af_rqm_bp_test { ++ u64 u; ++ struct nixx_af_rqm_bp_test_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 16; ++ u64 reserved_32_47 : 16; ++ u64 enable : 8; ++ u64 reserved_56_63 : 8; ++ } s; ++ /* struct nixx_af_rqm_bp_test_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RQM_BP_TEST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RQM_BP_TEST(void) ++{ ++ return 0x4880; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rqm_eco ++ * ++ * INTERNAL: AF RQM ECO Register ++ */ ++union nixx_af_rqm_eco { ++ u64 u; ++ struct nixx_af_rqm_eco_s { ++ u64 eco_rw : 64; ++ } s; ++ /* struct nixx_af_rqm_eco_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RQM_ECO(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RQM_ECO(void) ++{ ++ return 0x5a0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rvu_int ++ * ++ * NIX AF RVU Interrupt Register This register contains RVU error ++ * interrupt summary bits. ++ */ ++union nixx_af_rvu_int { ++ u64 u; ++ struct nixx_af_rvu_int_s { ++ u64 unmapped_slot : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_rvu_int_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RVU_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RVU_INT(void) ++{ ++ return 0x1c0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rvu_int_ena_w1c ++ * ++ * NIX AF RVU Interrupt Enable Clear Register This register clears ++ * interrupt enable bits. ++ */ ++union nixx_af_rvu_int_ena_w1c { ++ u64 u; ++ struct nixx_af_rvu_int_ena_w1c_s { ++ u64 unmapped_slot : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_rvu_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RVU_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RVU_INT_ENA_W1C(void) ++{ ++ return 0x1d8; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rvu_int_ena_w1s ++ * ++ * NIX AF RVU Interrupt Enable Set Register This register sets interrupt ++ * enable bits. ++ */ ++union nixx_af_rvu_int_ena_w1s { ++ u64 u; ++ struct nixx_af_rvu_int_ena_w1s_s { ++ u64 unmapped_slot : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_rvu_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RVU_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RVU_INT_ENA_W1S(void) ++{ ++ return 0x1d0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rvu_int_w1s ++ * ++ * NIX AF RVU Interrupt Set Register This register sets interrupt bits. ++ */ ++union nixx_af_rvu_int_w1s { ++ u64 u; ++ struct nixx_af_rvu_int_w1s_s { ++ u64 unmapped_slot : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_rvu_int_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RVU_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RVU_INT_W1S(void) ++{ ++ return 0x1c8; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rvu_lf_cfg_debug ++ * ++ * NIX Privileged LF Configuration Debug Register This debug register ++ * allows software to lookup the reverse mapping from VF/PF slot to LF. ++ * The forward mapping is programmed with NIX_PRIV_LF()_CFG. ++ */ ++union nixx_af_rvu_lf_cfg_debug { ++ u64 u; ++ struct nixx_af_rvu_lf_cfg_debug_s { ++ u64 lf : 12; ++ u64 lf_valid : 1; ++ u64 exec : 1; ++ u64 reserved_14_15 : 2; ++ u64 slot : 8; ++ u64 pf_func : 16; ++ u64 reserved_40_63 : 24; ++ } s; ++ /* struct nixx_af_rvu_lf_cfg_debug_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RVU_LF_CFG_DEBUG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RVU_LF_CFG_DEBUG(void) ++{ ++ return 0x8000030; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_active_cycles_pc# ++ * ++ * NIX AF Active Cycles Register These registers are indexed by the ++ * conditional clock domain number. ++ */ ++union nixx_af_rx_active_cycles_pcx { ++ u64 u; ++ struct nixx_af_rx_active_cycles_pcx_s { ++ u64 act_cyc : 64; ++ } s; ++ /* struct nixx_af_rx_active_cycles_pcx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_ACTIVE_CYCLES_PCX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_ACTIVE_CYCLES_PCX(u64 a) ++{ ++ return 0x4800 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_bpid#_status ++ * ++ * NIX AF Receive Backpressure ID Status Registers ++ */ ++union nixx_af_rx_bpidx_status { ++ u64 u; ++ struct nixx_af_rx_bpidx_status_s { ++ u64 aura_cnt : 32; ++ u64 cq_cnt : 32; ++ } s; ++ /* struct nixx_af_rx_bpidx_status_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_BPIDX_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_BPIDX_STATUS(u64 a) ++{ ++ return 0x1a20 + 0x20000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_cfg ++ * ++ * NIX AF Receive Configuration Register ++ */ ++union nixx_af_rx_cfg { ++ u64 u; ++ struct nixx_af_rx_cfg_s { ++ u64 cbp_ena : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_rx_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_CFG(void) ++{ ++ return 0xd0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_chan#_cfg ++ * ++ * NIX AF Receive Channel Configuration Registers ++ */ ++union nixx_af_rx_chanx_cfg { ++ u64 u; ++ struct nixx_af_rx_chanx_cfg_s { ++ u64 bpid : 9; ++ u64 reserved_9_15 : 7; ++ u64 bp_ena : 1; ++ u64 sw_xoff : 1; ++ u64 imp : 1; ++ u64 reserved_19_63 : 45; ++ } s; ++ /* struct nixx_af_rx_chanx_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_CHANX_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_CHANX_CFG(u64 a) ++{ ++ return 0x1a30 + 0x8000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_cpt#_credit ++ * ++ * NIX AF Receive CPT Credit Register ++ */ ++union nixx_af_rx_cptx_credit { ++ u64 u; ++ struct nixx_af_rx_cptx_credit_s { ++ u64 inst_cred_cnt : 22; ++ u64 reserved_22_63 : 42; ++ } s; ++ /* struct nixx_af_rx_cptx_credit_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_CPTX_CREDIT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_CPTX_CREDIT(u64 a) ++{ ++ return 0x360 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_cpt#_inst_qsel ++ * ++ * NIX AF Receive CPT Instruction Queue Select Register Selects the CPT ++ * queue to which instructions (CPT_INST_S) are sent. Internal: NIX sends ++ * CPT_INST_S to the CPT_LF_NQ() physical address for [PF_FUNC] and ++ * [SLOT]: \ // CPT_LF_NQ() physical address: ++ * chip_pa_defs::io_rvu2a_t cpt_addr; cpt_addr = ++ * RVU_BAR_E::RVU_PF()_FUNC()_BAR2(pf, func); cpt_addr.block = ++ * RVU_BLOCK_ADDR_E::CPT()({a}); // {a} = CPT index cpt_addr.slot = ++ * [SLOT]; cpt_addr.offset = `CPT_LF_NQX__BASE; // NDC/NCBI command: ++ * ncbi_cmd.paddr = 1; // Physical address ncbi_cmd.addr = cpt_addr; ++ * \ ++ */ ++union nixx_af_rx_cptx_inst_qsel { ++ u64 u; ++ struct nixx_af_rx_cptx_inst_qsel_s { ++ u64 slot : 8; ++ u64 pf_func : 16; ++ u64 reserved_24_63 : 40; ++ } s; ++ /* struct nixx_af_rx_cptx_inst_qsel_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_CPTX_INST_QSEL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_CPTX_INST_QSEL(u64 a) ++{ ++ return 0x320 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_def_iip4 ++ * ++ * NIX AF Receive Inner IPv4 Header Definition Register Defines layer ++ * information in NPC_RESULT_S to identify an inner IPv4 header. ++ * Typically the same as NPC_PCK_DEF_IIP4. ++ */ ++union nixx_af_rx_def_iip4 { ++ u64 u; ++ struct nixx_af_rx_def_iip4_s { ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct nixx_af_rx_def_iip4_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_DEF_IIP4(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_DEF_IIP4(void) ++{ ++ return 0x220; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_def_iip6 ++ * ++ * NIX AF Receive Inner IPv6 Header Definition Register Defines layer ++ * information in NPC_RESULT_S to identify an inner IPv6 header. ++ */ ++union nixx_af_rx_def_iip6 { ++ u64 u; ++ struct nixx_af_rx_def_iip6_s { ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct nixx_af_rx_def_iip6_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_DEF_IIP6(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_DEF_IIP6(void) ++{ ++ return 0x240; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_def_ipsec# ++ * ++ * INTERNAL: NIX AF Receive IPSEC Header Definition Registers Internal: ++ * Not used; no IPSEC fast-path. ++ */ ++union nixx_af_rx_def_ipsecx { ++ u64 u; ++ struct nixx_af_rx_def_ipsecx_s { ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_11 : 1; ++ u64 spi_offset : 4; ++ u64 spi_nz : 1; ++ u64 reserved_17_63 : 47; ++ } s; ++ /* struct nixx_af_rx_def_ipsecx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_DEF_IPSECX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_DEF_IPSECX(u64 a) ++{ ++ return 0x2b0 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_def_isctp ++ * ++ * NIX AF Receive Inner SCTP Header Definition Register Defines layer ++ * information in NPC_RESULT_S to identify an inner SCTP header. ++ */ ++union nixx_af_rx_def_isctp { ++ u64 u; ++ struct nixx_af_rx_def_isctp_s { ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct nixx_af_rx_def_isctp_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_DEF_ISCTP(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_DEF_ISCTP(void) ++{ ++ return 0x2a0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_def_itcp ++ * ++ * NIX AF Receive Inner TCP Header Definition Register Defines layer ++ * information in NPC_RESULT_S to identify an inner TCP header. ++ */ ++union nixx_af_rx_def_itcp { ++ u64 u; ++ struct nixx_af_rx_def_itcp_s { ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct nixx_af_rx_def_itcp_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_DEF_ITCP(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_DEF_ITCP(void) ++{ ++ return 0x260; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_def_iudp ++ * ++ * NIX AF Receive Inner UDP Header Definition Register Defines layer ++ * information in NPC_RESULT_S to identify an inner UDP header. ++ */ ++union nixx_af_rx_def_iudp { ++ u64 u; ++ struct nixx_af_rx_def_iudp_s { ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct nixx_af_rx_def_iudp_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_DEF_IUDP(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_DEF_IUDP(void) ++{ ++ return 0x280; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_def_oip4 ++ * ++ * NIX AF Receive Outer IPv4 Header Definition Register Defines layer ++ * information in NPC_RESULT_S to identify an outer IPv4 L3 header. ++ * Typically the same as NPC_PCK_DEF_OIP4. ++ */ ++union nixx_af_rx_def_oip4 { ++ u64 u; ++ struct nixx_af_rx_def_oip4_s { ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct nixx_af_rx_def_oip4_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_DEF_OIP4(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_DEF_OIP4(void) ++{ ++ return 0x210; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_def_oip6 ++ * ++ * NIX AF Receive Outer IPv6 Header Definition Register Defines layer ++ * information in NPC_RESULT_S to identify an outer IPv6 header. ++ * Typically the same as NPC_PCK_DEF_OIP6. ++ */ ++union nixx_af_rx_def_oip6 { ++ u64 u; ++ struct nixx_af_rx_def_oip6_s { ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct nixx_af_rx_def_oip6_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_DEF_OIP6(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_DEF_OIP6(void) ++{ ++ return 0x230; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_def_ol2 ++ * ++ * NIX AF Receive Outer L2 Header Definition Register Defines layer ++ * information in NPC_RESULT_S to identify an outer L2/Ethernet header. ++ * Typically the same as NPC_PCK_DEF_OL2. ++ */ ++union nixx_af_rx_def_ol2 { ++ u64 u; ++ struct nixx_af_rx_def_ol2_s { ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct nixx_af_rx_def_ol2_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_DEF_OL2(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_DEF_OL2(void) ++{ ++ return 0x200; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_def_osctp ++ * ++ * NIX AF Receive Outer SCTP Header Definition Register Defines layer ++ * information in NPC_RESULT_S to identify an outer SCTP header. ++ */ ++union nixx_af_rx_def_osctp { ++ u64 u; ++ struct nixx_af_rx_def_osctp_s { ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct nixx_af_rx_def_osctp_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_DEF_OSCTP(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_DEF_OSCTP(void) ++{ ++ return 0x290; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_def_otcp ++ * ++ * NIX AF Receive Outer TCP Header Definition Register Defines layer ++ * information in NPC_RESULT_S to identify an outer TCP header. ++ */ ++union nixx_af_rx_def_otcp { ++ u64 u; ++ struct nixx_af_rx_def_otcp_s { ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct nixx_af_rx_def_otcp_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_DEF_OTCP(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_DEF_OTCP(void) ++{ ++ return 0x250; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_def_oudp ++ * ++ * NIX AF Receive Outer UDP Header Definition Register Defines layer ++ * information in NPC_RESULT_S to identify an outer UDP header. ++ */ ++union nixx_af_rx_def_oudp { ++ u64 u; ++ struct nixx_af_rx_def_oudp_s { ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct nixx_af_rx_def_oudp_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_DEF_OUDP(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_DEF_OUDP(void) ++{ ++ return 0x270; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_flow_key_alg#_field# ++ * ++ * NIX AF Receive Flow Key Algorithm Field Registers A flow key algorithm ++ * defines how the 40-byte FLOW_KEY is formed from the received packet ++ * header. FLOW_KEY is formed using up to five header fields (this ++ * register's last index) with up to 16 bytes per field. The algorithm ++ * (index {a} (ALG) of these registers) is selected by ++ * NIX_RX_ACTION_S[FLOW_KEY_ALG] from the packet's NPC_RESULT_S[ACTION]. ++ * Internal: 40-byte FLOW_KEY is wide enough to support an IPv6 5-tuple ++ * that includes a VXLAN/GENEVE/NVGRE tunnel ID, e.g: _ Source IP: 16B. _ ++ * Dest IP: 16B. _ Source port: 2B. _ Dest port: 2B. _ Tunnel VNI/VSI: ++ * 3B. _ Total: 39B. ++ */ ++union nixx_af_rx_flow_key_algx_fieldx { ++ u64 u; ++ struct nixx_af_rx_flow_key_algx_fieldx_s { ++ u64 key_offset : 6; ++ u64 ln_mask : 1; ++ u64 fn_mask : 1; ++ u64 hdr_offset : 8; ++ u64 bytesm1 : 5; ++ u64 lid : 3; ++ u64 reserved_24 : 1; ++ u64 ena : 1; ++ u64 sel_chan : 1; ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 reserved_35_63 : 29; ++ } s; ++ /* struct nixx_af_rx_flow_key_algx_fieldx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_FLOW_KEY_ALGX_FIELDX(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_FLOW_KEY_ALGX_FIELDX(u64 a, u64 b) ++{ ++ return 0x1800 + 0x40000 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_ipsec_gen_cfg ++ * ++ * INTERNAL: NIX AF Receive IPSEC General Configuration Register ++ * Internal: Not used; no IPSEC fast-path. ++ */ ++union nixx_af_rx_ipsec_gen_cfg { ++ u64 u; ++ struct nixx_af_rx_ipsec_gen_cfg_s { ++ u64 param2 : 16; ++ u64 param1 : 16; ++ u64 opcode : 16; ++ u64 egrp : 3; ++ u64 reserved_51_63 : 13; ++ } s; ++ /* struct nixx_af_rx_ipsec_gen_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_IPSEC_GEN_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_IPSEC_GEN_CFG(void) ++{ ++ return 0x300; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_link#_cfg ++ * ++ * NIX AF Receive Link Configuration Registers Index enumerated by ++ * NIX_LINK_E. ++ */ ++union nixx_af_rx_linkx_cfg { ++ u64 u; ++ struct nixx_af_rx_linkx_cfg_s { ++ u64 minlen : 16; ++ u64 maxlen : 16; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct nixx_af_rx_linkx_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_LINKX_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_LINKX_CFG(u64 a) ++{ ++ return 0x540 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_link#_sl#_spkt_cnt ++ * ++ * INTERNAL: NIX Receive Software Sync Link Packet Count Registers For ++ * diagnostic use only for debug of NIX_AF_RX_SW_SYNC[ENA] function. LINK ++ * index is enumerated by NIX_LINK_E. For the internal multicast/mirror ++ * link (NIX_LINK_E::MC), SL index is zero for multicast replay, one for ++ * mirror replay. SL index one is reserved for all other links. ++ * Internal: 802.3br frame preemption/express path is defeatured. Old ++ * definition of SL index: SL index is zero for non-express packets, one ++ * for express packets. For the internal NIX_LINK_E::MC, SL index is zero ++ * for multicast replay, one for mirror replay. ++ */ ++union nixx_af_rx_linkx_slx_spkt_cnt { ++ u64 u; ++ struct nixx_af_rx_linkx_slx_spkt_cnt_s { ++ u64 in_cnt : 20; ++ u64 reserved_20_31 : 12; ++ u64 out_cnt : 20; ++ u64 reserved_52_63 : 12; ++ } s; ++ /* struct nixx_af_rx_linkx_slx_spkt_cnt_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_LINKX_SLX_SPKT_CNT(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_LINKX_SLX_SPKT_CNT(u64 a, u64 b) ++{ ++ return 0x500 + 0x10000 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_link#_wrr_cfg ++ * ++ * NIX AF Receive Link Weighted Round Robin Configuration Registers Index ++ * enumerated by NIX_LINK_E. ++ */ ++union nixx_af_rx_linkx_wrr_cfg { ++ u64 u; ++ struct nixx_af_rx_linkx_wrr_cfg_s { ++ u64 weight : 8; ++ u64 reserved_8_63 : 56; ++ } s; ++ /* struct nixx_af_rx_linkx_wrr_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_LINKX_WRR_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_LINKX_WRR_CFG(u64 a) ++{ ++ return 0x560 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_mcast_base ++ * ++ * NIX AF Receive Multicast/Mirror Table Base Address Register This ++ * register specifies the base AF IOVA of the receive multicast/mirror ++ * table in NDC/LLC/DRAM. The table consists of 1 \<\< ++ * (NIX_AF_RX_MCAST_CFG[SIZE] + 8) contiguous NIX_RX_MCE_S structures. ++ * The size of each structure is 1 \<\< NIX_AF_CONST3[MCE_LOG2BYTES]. ++ * The table contains multicast/mirror replication lists. Each list ++ * consists of linked entries with NIX_RX_MCE_S[EOL] = 1 in the last ++ * entry. All lists must reside within the table size specified by ++ * NIX_AF_RX_MCAST_CFG[SIZE]. A mirror replication list will typically ++ * consist of two entries, but that is not checked or enforced by ++ * hardware. A receive packet is multicast when the action returned by ++ * NPC has NIX_RX_ACTION_S[OP] = NIX_RX_ACTIONOP_E::MCAST. A receive ++ * packet is mirrored when the action returned by NPC has ++ * NIX_RX_ACTION_S[OP] = NIX_RX_ACTIONOP_E::MIRROR. In both cases, ++ * NIX_RX_ACTION_S[INDEX] specifies the index of the replication list's ++ * first NIX_RX_MCE_S in the table, and a linked entry with ++ * NIX_RX_MCE_S[EOL] = 1 indicates the end of list. If a mirrored flow ++ * is part of a multicast replication list, software should include the ++ * two mirror entries in that list. Internal: A multicast list may have ++ * multiple entries for the same LF (e.g. for future RoCE/IB multicast). ++ */ ++union nixx_af_rx_mcast_base { ++ u64 u; ++ struct nixx_af_rx_mcast_base_s { ++ u64 reserved_0_6 : 7; ++ u64 addr : 46; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct nixx_af_rx_mcast_base_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_MCAST_BASE(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_MCAST_BASE(void) ++{ ++ return 0x100; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_mcast_buf_base ++ * ++ * NIX AF Receive Multicast Buffer Base Address Register This register ++ * specifies the base AF IOVA of the receive multicast buffers in ++ * NDC/LLC/DRAM. These buffers are used to temporarily store packets ++ * whose action returned by NPC has NIX_RX_ACTION_S[OP] = ++ * NIX_RX_ACTIONOP_E::MCAST. The number of buffers is configured by ++ * NIX_AF_RX_MCAST_BUF_CFG[SIZE]. If the number of free buffers is ++ * insufficient for a received multicast packet, hardware tail drops the ++ * packet and sets NIX_AF_GEN_INT[RX_MCAST_DROP]. Hardware prioritizes ++ * the processing of RX mirror packets over RX multicast packets. ++ */ ++union nixx_af_rx_mcast_buf_base { ++ u64 u; ++ struct nixx_af_rx_mcast_buf_base_s { ++ u64 reserved_0_6 : 7; ++ u64 addr : 46; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct nixx_af_rx_mcast_buf_base_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_MCAST_BUF_BASE(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_MCAST_BUF_BASE(void) ++{ ++ return 0x120; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_mcast_buf_cfg ++ * ++ * NIX AF Receive Multicast Buffer Configuration Register See ++ * NIX_AF_RX_MCAST_BUF_BASE. ++ */ ++union nixx_af_rx_mcast_buf_cfg { ++ u64 u; ++ struct nixx_af_rx_mcast_buf_cfg_s { ++ u64 size : 4; ++ u64 way_mask : 16; ++ u64 caching : 1; ++ u64 reserved_21_23 : 3; ++ u64 npc_replay_pkind : 6; ++ u64 reserved_30_31 : 2; ++ u64 free_buf_level : 11; ++ u64 reserved_43_61 : 19; ++ u64 busy : 1; ++ u64 ena : 1; ++ } s; ++ struct nixx_af_rx_mcast_buf_cfg_cn96xxp1 { ++ u64 size : 4; ++ u64 way_mask : 16; ++ u64 caching : 1; ++ u64 reserved_21_23 : 3; ++ u64 npc_replay_pkind : 6; ++ u64 reserved_30_31 : 2; ++ u64 free_buf_level : 11; ++ u64 reserved_43_61 : 19; ++ u64 reserved_62 : 1; ++ u64 ena : 1; ++ } cn96xxp1; ++ /* struct nixx_af_rx_mcast_buf_cfg_s cn96xxp3; */ ++ /* struct nixx_af_rx_mcast_buf_cfg_s cn98xx; */ ++ struct nixx_af_rx_mcast_buf_cfg_cnf95xxp1 { ++ u64 size : 4; ++ u64 way_mask : 16; ++ u64 caching : 1; ++ u64 reserved_21_23 : 3; ++ u64 npc_replay_pkind : 6; ++ u64 reserved_30_31 : 2; ++ u64 free_buf_level : 11; ++ u64 reserved_43_62 : 20; ++ u64 ena : 1; ++ } cnf95xxp1; ++ /* struct nixx_af_rx_mcast_buf_cfg_s cnf95xxp2; */ ++ /* struct nixx_af_rx_mcast_buf_cfg_s loki; */ ++}; ++ ++static inline u64 NIXX_AF_RX_MCAST_BUF_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_MCAST_BUF_CFG(void) ++{ ++ return 0x130; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_mcast_cfg ++ * ++ * NIX AF Receive Multicast/Mirror Table Configuration Register See ++ * NIX_AF_RX_MCAST_BASE. ++ */ ++union nixx_af_rx_mcast_cfg { ++ u64 u; ++ struct nixx_af_rx_mcast_cfg_s { ++ u64 size : 4; ++ u64 max_list_lenm1 : 8; ++ u64 reserved_12_19 : 8; ++ u64 way_mask : 16; ++ u64 caching : 1; ++ u64 reserved_37_63 : 27; ++ } s; ++ /* struct nixx_af_rx_mcast_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_MCAST_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_MCAST_CFG(void) ++{ ++ return 0x110; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_mirror_buf_base ++ * ++ * NIX AF Receive Mirror Buffer Base Address Register This register ++ * specifies the base AF IOVA of the receive mirror buffers in ++ * NDC/LLC/DRAM. These buffers are used to temporarily store packets ++ * whose action returned by NPC has NIX_RX_ACTION_S[OP] = ++ * NIX_RX_ACTIONOP_E::MIRROR. The number of buffers is configured by ++ * NIX_AF_RX_MIRROR_BUF_CFG[SIZE]. If the number of free buffers is ++ * insufficient for a received multicast packet, hardware tail drops the ++ * packet and sets NIX_AF_GEN_INT[RX_MIRROR_DROP]. Hardware prioritizes ++ * the processing of RX mirror packets over RX multicast packets. ++ */ ++union nixx_af_rx_mirror_buf_base { ++ u64 u; ++ struct nixx_af_rx_mirror_buf_base_s { ++ u64 reserved_0_6 : 7; ++ u64 addr : 46; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct nixx_af_rx_mirror_buf_base_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_MIRROR_BUF_BASE(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_MIRROR_BUF_BASE(void) ++{ ++ return 0x140; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_mirror_buf_cfg ++ * ++ * NIX AF Receive Mirror Buffer Configuration Register See ++ * NIX_AF_RX_MIRROR_BUF_BASE. ++ */ ++union nixx_af_rx_mirror_buf_cfg { ++ u64 u; ++ struct nixx_af_rx_mirror_buf_cfg_s { ++ u64 size : 4; ++ u64 way_mask : 16; ++ u64 caching : 1; ++ u64 reserved_21_23 : 3; ++ u64 npc_replay_pkind : 6; ++ u64 reserved_30_31 : 2; ++ u64 free_buf_level : 11; ++ u64 reserved_43_61 : 19; ++ u64 busy : 1; ++ u64 ena : 1; ++ } s; ++ struct nixx_af_rx_mirror_buf_cfg_cn96xxp1 { ++ u64 size : 4; ++ u64 way_mask : 16; ++ u64 caching : 1; ++ u64 reserved_21_23 : 3; ++ u64 npc_replay_pkind : 6; ++ u64 reserved_30_31 : 2; ++ u64 free_buf_level : 11; ++ u64 reserved_43_61 : 19; ++ u64 reserved_62 : 1; ++ u64 ena : 1; ++ } cn96xxp1; ++ /* struct nixx_af_rx_mirror_buf_cfg_s cn96xxp3; */ ++ /* struct nixx_af_rx_mirror_buf_cfg_s cn98xx; */ ++ struct nixx_af_rx_mirror_buf_cfg_cnf95xxp1 { ++ u64 size : 4; ++ u64 way_mask : 16; ++ u64 caching : 1; ++ u64 reserved_21_23 : 3; ++ u64 npc_replay_pkind : 6; ++ u64 reserved_30_31 : 2; ++ u64 free_buf_level : 11; ++ u64 reserved_43_62 : 20; ++ u64 ena : 1; ++ } cnf95xxp1; ++ /* struct nixx_af_rx_mirror_buf_cfg_s cnf95xxp2; */ ++ /* struct nixx_af_rx_mirror_buf_cfg_s loki; */ ++}; ++ ++static inline u64 NIXX_AF_RX_MIRROR_BUF_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_MIRROR_BUF_CFG(void) ++{ ++ return 0x148; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_npc_mc_drop ++ * ++ * NIX AF Multicast Drop Statistics Register The counter increments for ++ * every dropped MC packet marked by the NPC. ++ */ ++union nixx_af_rx_npc_mc_drop { ++ u64 u; ++ struct nixx_af_rx_npc_mc_drop_s { ++ u64 stat : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nixx_af_rx_npc_mc_drop_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_NPC_MC_DROP(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_NPC_MC_DROP(void) ++{ ++ return 0x4710; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_npc_mc_rcv ++ * ++ * NIX AF Multicast Receive Statistics Register The counter increments ++ * for every received MC packet marked by the NPC. ++ */ ++union nixx_af_rx_npc_mc_rcv { ++ u64 u; ++ struct nixx_af_rx_npc_mc_rcv_s { ++ u64 stat : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nixx_af_rx_npc_mc_rcv_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_NPC_MC_RCV(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_NPC_MC_RCV(void) ++{ ++ return 0x4700; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_npc_mirror_drop ++ * ++ * NIX AF Mirror Drop Statistics Register The counter increments for ++ * every dropped MIRROR packet marked by the NPC. ++ */ ++union nixx_af_rx_npc_mirror_drop { ++ u64 u; ++ struct nixx_af_rx_npc_mirror_drop_s { ++ u64 stat : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nixx_af_rx_npc_mirror_drop_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_NPC_MIRROR_DROP(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_NPC_MIRROR_DROP(void) ++{ ++ return 0x4730; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_npc_mirror_rcv ++ * ++ * NIX AF Mirror Receive Statistics Register The counter increments for ++ * every received MIRROR packet marked by the NPC. ++ */ ++union nixx_af_rx_npc_mirror_rcv { ++ u64 u; ++ struct nixx_af_rx_npc_mirror_rcv_s { ++ u64 stat : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nixx_af_rx_npc_mirror_rcv_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_NPC_MIRROR_RCV(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_NPC_MIRROR_RCV(void) ++{ ++ return 0x4720; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_rx_sw_sync ++ * ++ * NIX AF Receive Software Sync Register ++ */ ++union nixx_af_rx_sw_sync { ++ u64 u; ++ struct nixx_af_rx_sw_sync_s { ++ u64 ena : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_rx_sw_sync_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_RX_SW_SYNC(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_RX_SW_SYNC(void) ++{ ++ return 0x550; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_sdp_hw_xoff# ++ * ++ * NIX AF SDP Transmit Link Hardware Controlled XOFF Registers . ++ */ ++union nixx_af_sdp_hw_xoffx { ++ u64 u; ++ struct nixx_af_sdp_hw_xoffx_s { ++ u64 chan_xoff : 64; ++ } s; ++ /* struct nixx_af_sdp_hw_xoffx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SDP_HW_XOFFX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SDP_HW_XOFFX(u64 a) ++{ ++ return 0xac0 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_sdp_link_credit ++ * ++ * NIX AF Transmit Link SDP Credit Register This register tracks SDP link ++ * credits. ++ */ ++union nixx_af_sdp_link_credit { ++ u64 u; ++ struct nixx_af_sdp_link_credit_s { ++ u64 reserved_0 : 1; ++ u64 cc_enable : 1; ++ u64 cc_packet_cnt : 10; ++ u64 cc_unit_cnt : 20; ++ u64 reserved_32_62 : 31; ++ u64 pse_pkt_id_lmt : 1; ++ } s; ++ struct nixx_af_sdp_link_credit_cn96xx { ++ u64 reserved_0 : 1; ++ u64 cc_enable : 1; ++ u64 cc_packet_cnt : 10; ++ u64 cc_unit_cnt : 20; ++ u64 reserved_32_62 : 31; ++ u64 reserved_63 : 1; ++ } cn96xx; ++ /* struct nixx_af_sdp_link_credit_cn96xx cn98xx; */ ++ /* struct nixx_af_sdp_link_credit_s cnf95xx; */ ++ /* struct nixx_af_sdp_link_credit_cn96xx loki; */ ++}; ++ ++static inline u64 NIXX_AF_SDP_LINK_CREDIT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SDP_LINK_CREDIT(void) ++{ ++ return 0xa40; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_sdp_sw_xoff# ++ * ++ * INTERNAL: NIX AF SDP Transmit Link Software Controlled XOFF Registers ++ * Internal: Defeatured registers. Software should use ++ * NIX_AF_TL4()_SW_XOFF registers instead. ++ */ ++union nixx_af_sdp_sw_xoffx { ++ u64 u; ++ struct nixx_af_sdp_sw_xoffx_s { ++ u64 chan_xoff : 64; ++ } s; ++ /* struct nixx_af_sdp_sw_xoffx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SDP_SW_XOFFX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SDP_SW_XOFFX(u64 a) ++{ ++ return 0xa60 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_sdp_tx_fifo_status ++ * ++ * NIX AF SDP Transmit FIFO Status Register Status of FIFO which ++ * transmits packets to SDP. ++ */ ++union nixx_af_sdp_tx_fifo_status { ++ u64 u; ++ struct nixx_af_sdp_tx_fifo_status_s { ++ u64 count : 12; ++ u64 reserved_12_63 : 52; ++ } s; ++ /* struct nixx_af_sdp_tx_fifo_status_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SDP_TX_FIFO_STATUS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SDP_TX_FIFO_STATUS(void) ++{ ++ return 0x650; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_seb_active_cycles_pc# ++ * ++ * NIX AF Active Cycles Register These registers are indexed by the ++ * conditional clock domain number. ++ */ ++union nixx_af_seb_active_cycles_pcx { ++ u64 u; ++ struct nixx_af_seb_active_cycles_pcx_s { ++ u64 act_cyc : 64; ++ } s; ++ /* struct nixx_af_seb_active_cycles_pcx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SEB_ACTIVE_CYCLES_PCX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SEB_ACTIVE_CYCLES_PCX(u64 a) ++{ ++ return 0x6c0 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_seb_bp_test ++ * ++ * INTERNAL: NIX AF SEB Backpressure Test Register ++ */ ++union nixx_af_seb_bp_test { ++ u64 u; ++ struct nixx_af_seb_bp_test_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 14; ++ u64 reserved_30_47 : 18; ++ u64 enable : 7; ++ u64 reserved_55_63 : 9; ++ } s; ++ /* struct nixx_af_seb_bp_test_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SEB_BP_TEST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SEB_BP_TEST(void) ++{ ++ return 0x630; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_seb_cfg ++ * ++ * NIX SEB Configuration Register ++ */ ++union nixx_af_seb_cfg { ++ u64 u; ++ struct nixx_af_seb_cfg_s { ++ u64 sg_ndc_sel : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_seb_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SEB_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SEB_CFG(void) ++{ ++ return 0x5f0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_seb_eco ++ * ++ * INTERNAL: AF SEB ECO Register ++ */ ++union nixx_af_seb_eco { ++ u64 u; ++ struct nixx_af_seb_eco_s { ++ u64 eco_rw : 64; ++ } s; ++ /* struct nixx_af_seb_eco_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SEB_ECO(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SEB_ECO(void) ++{ ++ return 0x5c0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_seb_pipe_bp_test# ++ * ++ * INTERNAL: NIX AF SEB Pipe Backpressure Test Registers ++ */ ++union nixx_af_seb_pipe_bp_testx { ++ u64 u; ++ struct nixx_af_seb_pipe_bp_testx_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 24; ++ u64 reserved_40_47 : 8; ++ u64 enable : 12; ++ u64 reserved_60_63 : 4; ++ } s; ++ /* struct nixx_af_seb_pipe_bp_testx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SEB_PIPE_BP_TESTX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SEB_PIPE_BP_TESTX(u64 a) ++{ ++ return 0x600 + 0x10 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_seb_pipeb_bp_test# ++ * ++ * INTERNAL: NIX AF SEB Pipe Backpressure Test Registers ++ */ ++union nixx_af_seb_pipeb_bp_testx { ++ u64 u; ++ struct nixx_af_seb_pipeb_bp_testx_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 18; ++ u64 reserved_34_47 : 14; ++ u64 enable : 9; ++ u64 reserved_57_63 : 7; ++ } s; ++ /* struct nixx_af_seb_pipeb_bp_testx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SEB_PIPEB_BP_TESTX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SEB_PIPEB_BP_TESTX(u64 a) ++{ ++ return 0x608 + 0x10 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_seb_wd_tick_divider ++ * ++ * INTERNAL: NIX AF SEB TSTMP Watchdog Tick Divider Register ++ */ ++union nixx_af_seb_wd_tick_divider { ++ u64 u; ++ struct nixx_af_seb_wd_tick_divider_s { ++ u64 tick_div_cfg : 7; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct nixx_af_seb_wd_tick_divider_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SEB_WD_TICK_DIVIDER(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SEB_WD_TICK_DIVIDER(void) ++{ ++ return 0x6f0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_smq#_cfg ++ * ++ * NIX AF SQM PSE Queue Configuration Registers ++ */ ++union nixx_af_smqx_cfg { ++ u64 u; ++ struct nixx_af_smqx_cfg_s { ++ u64 minlen : 7; ++ u64 desc_shp_ctl_dis : 1; ++ u64 maxlen : 16; ++ u64 lf : 7; ++ u64 reserved_31_35 : 5; ++ u64 max_vtag_ins : 3; ++ u64 rr_minlen : 9; ++ u64 express : 1; ++ u64 flush : 1; ++ u64 enq_xoff : 1; ++ u64 pri_thr : 6; ++ u64 reserved_57_63 : 7; ++ } s; ++ /* struct nixx_af_smqx_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SMQX_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SMQX_CFG(u64 a) ++{ ++ return 0x700 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_smq#_head ++ * ++ * NIX AF SQM SMQ Head Register These registers track the head of the SMQ ++ * linked list. ++ */ ++union nixx_af_smqx_head { ++ u64 u; ++ struct nixx_af_smqx_head_s { ++ u64 sq_idx : 20; ++ u64 valid : 1; ++ u64 reserved_21_63 : 43; ++ } s; ++ /* struct nixx_af_smqx_head_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SMQX_HEAD(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SMQX_HEAD(u64 a) ++{ ++ return 0x710 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_smq#_nxt_head ++ * ++ * NIX AF SQM SMQ Next Head Register These registers track the next head ++ * of the SMQ linked list. ++ */ ++union nixx_af_smqx_nxt_head { ++ u64 u; ++ struct nixx_af_smqx_nxt_head_s { ++ u64 sq_idx : 20; ++ u64 valid : 1; ++ u64 reserved_21_63 : 43; ++ } s; ++ /* struct nixx_af_smqx_nxt_head_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SMQX_NXT_HEAD(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SMQX_NXT_HEAD(u64 a) ++{ ++ return 0x740 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_smq#_status ++ * ++ * NIX AF SQM SMQ Status Register These registers track the status of the ++ * SMQ FIFO. ++ */ ++union nixx_af_smqx_status { ++ u64 u; ++ struct nixx_af_smqx_status_s { ++ u64 level : 7; ++ u64 reserved_7_63 : 57; ++ } s; ++ /* struct nixx_af_smqx_status_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SMQX_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SMQX_STATUS(u64 a) ++{ ++ return 0x730 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_smq#_tail ++ * ++ * NIX AF SQM SMQ Head Register These registers track the tail of SMQ ++ * linked list. ++ */ ++union nixx_af_smqx_tail { ++ u64 u; ++ struct nixx_af_smqx_tail_s { ++ u64 sq_idx : 20; ++ u64 valid : 1; ++ u64 reserved_21_63 : 43; ++ } s; ++ /* struct nixx_af_smqx_tail_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SMQX_TAIL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SMQX_TAIL(u64 a) ++{ ++ return 0x720 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_sq_const ++ * ++ * NIX AF SQ Constants Register This register contains constants for ++ * software discovery. ++ */ ++union nixx_af_sq_const { ++ u64 u; ++ struct nixx_af_sq_const_s { ++ u64 queues_per_lf : 24; ++ u64 smq_depth : 10; ++ u64 sqb_size : 16; ++ u64 reserved_50_63 : 14; ++ } s; ++ /* struct nixx_af_sq_const_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SQ_CONST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SQ_CONST(void) ++{ ++ return 0x40; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_sqm_active_cycles_pc ++ * ++ * NIX AF SQM Active Cycles Register These registers are indexed by the ++ * conditional clock domain number. ++ */ ++union nixx_af_sqm_active_cycles_pc { ++ u64 u; ++ struct nixx_af_sqm_active_cycles_pc_s { ++ u64 act_cyc : 64; ++ } s; ++ /* struct nixx_af_sqm_active_cycles_pc_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SQM_ACTIVE_CYCLES_PC(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SQM_ACTIVE_CYCLES_PC(void) ++{ ++ return 0x770; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_sqm_bp_test# ++ * ++ * INTERNAL: NIX AF SQM Backpressure Test Register ++ */ ++union nixx_af_sqm_bp_testx { ++ u64 u; ++ struct nixx_af_sqm_bp_testx_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 8; ++ u64 reserved_24_59 : 36; ++ u64 enable : 4; ++ } s; ++ /* struct nixx_af_sqm_bp_testx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SQM_BP_TESTX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SQM_BP_TESTX(u64 a) ++{ ++ return 0x760 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_sqm_dbg_ctl_status ++ * ++ * INTERNAL: NIX AF SQM Debug Register This register is for SQM ++ * diagnostic use only. ++ */ ++union nixx_af_sqm_dbg_ctl_status { ++ u64 u; ++ struct nixx_af_sqm_dbg_ctl_status_s { ++ u64 tm1 : 8; ++ u64 tm2 : 1; ++ u64 tm3 : 4; ++ u64 tm4 : 1; ++ u64 tm5 : 1; ++ u64 tm6 : 1; ++ u64 tm7 : 4; ++ u64 tm8 : 1; ++ u64 tm9 : 1; ++ u64 tm10 : 1; ++ u64 tm11 : 1; ++ u64 tm12 : 1; ++ u64 tm13 : 1; ++ u64 reserved_26_63 : 38; ++ } s; ++ struct nixx_af_sqm_dbg_ctl_status_cn96xxp1 { ++ u64 tm1 : 8; ++ u64 tm2 : 1; ++ u64 tm3 : 4; ++ u64 tm4 : 1; ++ u64 tm5 : 1; ++ u64 tm6 : 1; ++ u64 tm7 : 4; ++ u64 tm8 : 1; ++ u64 tm9 : 1; ++ u64 reserved_22_63 : 42; ++ } cn96xxp1; ++ /* struct nixx_af_sqm_dbg_ctl_status_s cn96xxp3; */ ++ /* struct nixx_af_sqm_dbg_ctl_status_s cn98xx; */ ++ /* struct nixx_af_sqm_dbg_ctl_status_cn96xxp1 cnf95xxp1; */ ++ struct nixx_af_sqm_dbg_ctl_status_cnf95xxp2 { ++ u64 tm1 : 8; ++ u64 tm2 : 1; ++ u64 tm3 : 4; ++ u64 tm4 : 1; ++ u64 tm5 : 1; ++ u64 tm6 : 1; ++ u64 tm7 : 4; ++ u64 tm8 : 1; ++ u64 tm9 : 1; ++ u64 reserved_22 : 1; ++ u64 reserved_23 : 1; ++ u64 reserved_24 : 1; ++ u64 reserved_25 : 1; ++ u64 reserved_26_63 : 38; ++ } cnf95xxp2; ++ /* struct nixx_af_sqm_dbg_ctl_status_s loki; */ ++}; ++ ++static inline u64 NIXX_AF_SQM_DBG_CTL_STATUS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SQM_DBG_CTL_STATUS(void) ++{ ++ return 0x750; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_sqm_eco ++ * ++ * INTERNAL: AF SQM ECO Register ++ */ ++union nixx_af_sqm_eco { ++ u64 u; ++ struct nixx_af_sqm_eco_s { ++ u64 eco_rw : 64; ++ } s; ++ /* struct nixx_af_sqm_eco_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_SQM_ECO(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_SQM_ECO(void) ++{ ++ return 0x5b0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_status ++ * ++ * NIX AF General Status Register ++ */ ++union nixx_af_status { ++ u64 u; ++ struct nixx_af_status_s { ++ u64 blk_busy : 10; ++ u64 calibrate_done : 1; ++ u64 reserved_11_15 : 5; ++ u64 calibrate_status : 15; ++ u64 reserved_31_63 : 33; ++ } s; ++ /* struct nixx_af_status_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_STATUS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_STATUS(void) ++{ ++ return 0x10; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tcp_timer ++ * ++ * NIX TCP Timer Register ++ */ ++union nixx_af_tcp_timer { ++ u64 u; ++ struct nixx_af_tcp_timer_s { ++ u64 dur_counter : 16; ++ u64 lf_counter : 8; ++ u64 reserved_24_31 : 8; ++ u64 duration : 16; ++ u64 reserved_48_62 : 15; ++ u64 ena : 1; ++ } s; ++ /* struct nixx_af_tcp_timer_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TCP_TIMER(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TCP_TIMER(void) ++{ ++ return 0x1e0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_cir ++ * ++ * NIX AF Transmit Level 1 Committed Information Rate Register ++ */ ++union nixx_af_tl1x_cir { ++ u64 u; ++ struct nixx_af_tl1x_cir_s { ++ u64 enable : 1; ++ u64 rate_mantissa : 8; ++ u64 rate_exponent : 4; ++ u64 rate_divider_exponent : 4; ++ u64 reserved_17_28 : 12; ++ u64 burst_mantissa : 8; ++ u64 burst_exponent : 4; ++ u64 reserved_41_63 : 23; ++ } s; ++ /* struct nixx_af_tl1x_cir_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_CIR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_CIR(u64 a) ++{ ++ return 0xc20 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_dropped_bytes ++ * ++ * NIX AF Transmit Level 1 Dropped Bytes Registers This register has the ++ * same bit fields as NIX_AF_TL1()_GREEN_BYTES. ++ */ ++union nixx_af_tl1x_dropped_bytes { ++ u64 u; ++ struct nixx_af_tl1x_dropped_bytes_s { ++ u64 count : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nixx_af_tl1x_dropped_bytes_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_DROPPED_BYTES(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_DROPPED_BYTES(u64 a) ++{ ++ return 0xd30 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_dropped_packets ++ * ++ * NIX AF Transmit Level 1 Dropped Packets Registers This register has ++ * the same bit fields as NIX_AF_TL1()_GREEN_PACKETS. ++ */ ++union nixx_af_tl1x_dropped_packets { ++ u64 u; ++ struct nixx_af_tl1x_dropped_packets_s { ++ u64 count : 40; ++ u64 reserved_40_63 : 24; ++ } s; ++ /* struct nixx_af_tl1x_dropped_packets_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_DROPPED_PACKETS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_DROPPED_PACKETS(u64 a) ++{ ++ return 0xd20 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_green ++ * ++ * INTERNAL: NIX Transmit Level 1 Green State Debug Register ++ */ ++union nixx_af_tl1x_green { ++ u64 u; ++ struct nixx_af_tl1x_green_s { ++ u64 tail : 8; ++ u64 reserved_8_9 : 2; ++ u64 head : 8; ++ u64 reserved_18_19 : 2; ++ u64 active_vec : 20; ++ u64 rr_active : 1; ++ u64 reserved_41_63 : 23; ++ } s; ++ /* struct nixx_af_tl1x_green_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_GREEN(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_GREEN(u64 a) ++{ ++ return 0xc90 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_green_bytes ++ * ++ * NIX AF Transmit Level 1 Green Sent Bytes Registers ++ */ ++union nixx_af_tl1x_green_bytes { ++ u64 u; ++ struct nixx_af_tl1x_green_bytes_s { ++ u64 count : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nixx_af_tl1x_green_bytes_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_GREEN_BYTES(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_GREEN_BYTES(u64 a) ++{ ++ return 0xd90 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_green_packets ++ * ++ * NIX AF Transmit Level 1 Green Sent Packets Registers ++ */ ++union nixx_af_tl1x_green_packets { ++ u64 u; ++ struct nixx_af_tl1x_green_packets_s { ++ u64 count : 40; ++ u64 reserved_40_63 : 24; ++ } s; ++ /* struct nixx_af_tl1x_green_packets_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_GREEN_PACKETS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_GREEN_PACKETS(u64 a) ++{ ++ return 0xd80 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_md_debug0 ++ * ++ * NIX AF Transmit Level 1 Meta Descriptor Debug 0 Registers ++ * NIX_AF_TL1()_MD_DEBUG0, NIX_AF_TL1()_MD_DEBUG1, NIX_AF_TL1()_MD_DEBUG2 ++ * and NIX_AF_TL1()_MD_DEBUG3 provide access to the TLn queue meta ++ * descriptor. A TLn queue can hold up to two packet meta descriptors ++ * (PMD) and one flush meta descriptor (FMD): * PMD0 state is accessed ++ * with [PMD0_VLD], [PMD0_LENGTH] and NIX_AF_TL1()_MD_DEBUG1. * PMD1 is ++ * accessed with [PMD1_VLD], [PMD1_LENGTH] and NIX_AF_TL1()_MD_DEBUG2. * ++ * FMD is accessed with NIX_AF_TL1()_MD_DEBUG3. ++ */ ++union nixx_af_tl1x_md_debug0 { ++ u64 u; ++ struct nixx_af_tl1x_md_debug0_s { ++ u64 pmd0_length : 16; ++ u64 pmd1_length : 16; ++ u64 pmd0_vld : 1; ++ u64 pmd1_vld : 1; ++ u64 reserved_34_45 : 12; ++ u64 drain_pri : 1; ++ u64 drain : 1; ++ u64 c_con : 1; ++ u64 p_con : 1; ++ u64 reserved_50_51 : 2; ++ u64 child : 10; ++ u64 reserved_62 : 1; ++ u64 pmd_count : 1; ++ } s; ++ /* struct nixx_af_tl1x_md_debug0_s cn96xxp1; */ ++ struct nixx_af_tl1x_md_debug0_cn96xxp3 { ++ u64 pmd0_length : 16; ++ u64 reserved_16_31 : 16; ++ u64 pmd0_vld : 1; ++ u64 reserved_33 : 1; ++ u64 reserved_34_45 : 12; ++ u64 reserved_46 : 1; ++ u64 reserved_47 : 1; ++ u64 c_con : 1; ++ u64 p_con : 1; ++ u64 reserved_50_51 : 2; ++ u64 child : 10; ++ u64 reserved_62 : 1; ++ u64 reserved_63 : 1; ++ } cn96xxp3; ++ /* struct nixx_af_tl1x_md_debug0_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_tl1x_md_debug0_s cnf95xx; */ ++ /* struct nixx_af_tl1x_md_debug0_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_MD_DEBUG0(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_MD_DEBUG0(u64 a) ++{ ++ return 0xcc0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_md_debug1 ++ * ++ * NIX AF Transmit Level 1 Meta Descriptor Debug 1 Registers Packet meta ++ * descriptor 0 debug. See NIX_AF_TL1()_MD_DEBUG0. ++ */ ++union nixx_af_tl1x_md_debug1 { ++ u64 u; ++ struct nixx_af_tl1x_md_debug1_s { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 uid : 4; ++ u64 reserved_23 : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } s; ++ struct nixx_af_tl1x_md_debug1_cn96xxp1 { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 uid : 4; ++ u64 drain : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } cn96xxp1; ++ struct nixx_af_tl1x_md_debug1_cn96xxp3 { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 reserved_19_22 : 4; ++ u64 flush : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } cn96xxp3; ++ /* struct nixx_af_tl1x_md_debug1_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_tl1x_md_debug1_cn96xxp1 cnf95xx; */ ++ /* struct nixx_af_tl1x_md_debug1_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_MD_DEBUG1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_MD_DEBUG1(u64 a) ++{ ++ return 0xcc8 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_md_debug2 ++ * ++ * NIX AF Transmit Level 1 Meta Descriptor Debug 2 Registers Packet meta ++ * descriptor 1 debug. See NIX_AF_TL1()_MD_DEBUG0. ++ */ ++union nixx_af_tl1x_md_debug2 { ++ u64 u; ++ struct nixx_af_tl1x_md_debug2_s { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 uid : 4; ++ u64 reserved_23 : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } s; ++ struct nixx_af_tl1x_md_debug2_cn96xxp1 { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 uid : 4; ++ u64 drain : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } cn96xxp1; ++ struct nixx_af_tl1x_md_debug2_cn96xxp3 { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 reserved_19_22 : 4; ++ u64 flush : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } cn96xxp3; ++ /* struct nixx_af_tl1x_md_debug2_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_tl1x_md_debug2_cn96xxp1 cnf95xx; */ ++ /* struct nixx_af_tl1x_md_debug2_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_MD_DEBUG2(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_MD_DEBUG2(u64 a) ++{ ++ return 0xcd0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_md_debug3 ++ * ++ * NIX AF Transmit Level 1 Meta Descriptor Debug 3 Registers Flush meta ++ * descriptor debug. See NIX_AF_TL1()_MD_DEBUG0. ++ */ ++union nixx_af_tl1x_md_debug3 { ++ u64 u; ++ struct nixx_af_tl1x_md_debug3_s { ++ u64 reserved_0_36 : 37; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } s; ++ /* struct nixx_af_tl1x_md_debug3_s cn96xxp1; */ ++ struct nixx_af_tl1x_md_debug3_cn96xxp3 { ++ u64 reserved_0_36 : 37; ++ u64 reserved_37_38 : 2; ++ u64 reserved_39_51 : 13; ++ u64 reserved_52_61 : 10; ++ u64 reserved_62 : 1; ++ u64 reserved_63 : 1; ++ } cn96xxp3; ++ /* struct nixx_af_tl1x_md_debug3_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_tl1x_md_debug3_s cnf95xx; */ ++ /* struct nixx_af_tl1x_md_debug3_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_MD_DEBUG3(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_MD_DEBUG3(u64 a) ++{ ++ return 0xcd8 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_red ++ * ++ * INTERNAL: NIX Transmit Level 1 Red State Debug Register This register ++ * has the same bit fields as NIX_AF_TL1()_YELLOW. ++ */ ++union nixx_af_tl1x_red { ++ u64 u; ++ struct nixx_af_tl1x_red_s { ++ u64 tail : 8; ++ u64 reserved_8_9 : 2; ++ u64 head : 8; ++ u64 reserved_18_63 : 46; ++ } s; ++ /* struct nixx_af_tl1x_red_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_RED(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_RED(u64 a) ++{ ++ return 0xcb0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_red_bytes ++ * ++ * NIX AF Transmit Level 1 Red Sent Bytes Registers This register has the ++ * same bit fields as NIX_AF_TL1()_GREEN_BYTES. ++ */ ++union nixx_af_tl1x_red_bytes { ++ u64 u; ++ struct nixx_af_tl1x_red_bytes_s { ++ u64 count : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nixx_af_tl1x_red_bytes_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_RED_BYTES(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_RED_BYTES(u64 a) ++{ ++ return 0xd50 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_red_packets ++ * ++ * NIX AF Transmit Level 1 Red Sent Packets Registers This register has ++ * the same bit fields as NIX_AF_TL1()_GREEN_PACKETS. ++ */ ++union nixx_af_tl1x_red_packets { ++ u64 u; ++ struct nixx_af_tl1x_red_packets_s { ++ u64 count : 40; ++ u64 reserved_40_63 : 24; ++ } s; ++ /* struct nixx_af_tl1x_red_packets_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_RED_PACKETS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_RED_PACKETS(u64 a) ++{ ++ return 0xd40 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_schedule ++ * ++ * NIX AF Transmit Level 1 Scheduling Control Register ++ */ ++union nixx_af_tl1x_schedule { ++ u64 u; ++ struct nixx_af_tl1x_schedule_s { ++ u64 rr_quantum : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ /* struct nixx_af_tl1x_schedule_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_SCHEDULE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_SCHEDULE(u64 a) ++{ ++ return 0xc00 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_shape ++ * ++ * NIX AF Transmit Level 1 Shaping Control Register ++ */ ++union nixx_af_tl1x_shape { ++ u64 u; ++ struct nixx_af_tl1x_shape_s { ++ u64 adjust : 9; ++ u64 reserved_9_23 : 15; ++ u64 length_disable : 1; ++ u64 reserved_25_63 : 39; ++ } s; ++ struct nixx_af_tl1x_shape_cn { ++ u64 adjust : 9; ++ u64 reserved_9_17 : 9; ++ u64 reserved_18_23 : 6; ++ u64 length_disable : 1; ++ u64 reserved_25_63 : 39; ++ } cn; ++}; ++ ++static inline u64 NIXX_AF_TL1X_SHAPE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_SHAPE(u64 a) ++{ ++ return 0xc10 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_shape_state ++ * ++ * NIX AF Transmit Level 1 Shape State Register This register must not be ++ * written during normal operation. ++ */ ++union nixx_af_tl1x_shape_state { ++ u64 u; ++ struct nixx_af_tl1x_shape_state_s { ++ u64 cir_accum : 26; ++ u64 reserved_26_51 : 26; ++ u64 color : 1; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct nixx_af_tl1x_shape_state_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_SHAPE_STATE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_SHAPE_STATE(u64 a) ++{ ++ return 0xc50 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_sw_xoff ++ * ++ * NIX AF Transmit Level 1 Software Controlled XOFF Registers ++ */ ++union nixx_af_tl1x_sw_xoff { ++ u64 u; ++ struct nixx_af_tl1x_sw_xoff_s { ++ u64 xoff : 1; ++ u64 drain : 1; ++ u64 reserved_2 : 1; ++ u64 drain_irq : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct nixx_af_tl1x_sw_xoff_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_SW_XOFF(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_SW_XOFF(u64 a) ++{ ++ return 0xc70 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_topology ++ * ++ * NIX AF Transmit Level 1 Topology Registers ++ */ ++union nixx_af_tl1x_topology { ++ u64 u; ++ struct nixx_af_tl1x_topology_s { ++ u64 reserved_0 : 1; ++ u64 rr_prio : 4; ++ u64 reserved_5_31 : 27; ++ u64 prio_anchor : 8; ++ u64 reserved_40_63 : 24; ++ } s; ++ /* struct nixx_af_tl1x_topology_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_TOPOLOGY(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_TOPOLOGY(u64 a) ++{ ++ return 0xc80 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_yellow ++ * ++ * INTERNAL: NIX Transmit Level 1 Yellow State Debug Register ++ */ ++union nixx_af_tl1x_yellow { ++ u64 u; ++ struct nixx_af_tl1x_yellow_s { ++ u64 tail : 8; ++ u64 reserved_8_9 : 2; ++ u64 head : 8; ++ u64 reserved_18_63 : 46; ++ } s; ++ /* struct nixx_af_tl1x_yellow_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_YELLOW(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_YELLOW(u64 a) ++{ ++ return 0xca0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_yellow_bytes ++ * ++ * NIX AF Transmit Level 1 Yellow Sent Bytes Registers This register has ++ * the same bit fields as NIX_AF_TL1()_GREEN_BYTES. ++ */ ++union nixx_af_tl1x_yellow_bytes { ++ u64 u; ++ struct nixx_af_tl1x_yellow_bytes_s { ++ u64 count : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nixx_af_tl1x_yellow_bytes_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_YELLOW_BYTES(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_YELLOW_BYTES(u64 a) ++{ ++ return 0xd70 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1#_yellow_packets ++ * ++ * NIX AF Transmit Level 1 Yellow Sent Packets Registers This register ++ * has the same bit fields as NIX_AF_TL1()_GREEN_PACKETS. ++ */ ++union nixx_af_tl1x_yellow_packets { ++ u64 u; ++ struct nixx_af_tl1x_yellow_packets_s { ++ u64 count : 40; ++ u64 reserved_40_63 : 24; ++ } s; ++ /* struct nixx_af_tl1x_yellow_packets_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1X_YELLOW_PACKETS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1X_YELLOW_PACKETS(u64 a) ++{ ++ return 0xd60 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl1_const ++ * ++ * NIX AF Transmit Level 1 Constants Register This register contains ++ * constants for software discovery. ++ */ ++union nixx_af_tl1_const { ++ u64 u; ++ struct nixx_af_tl1_const_s { ++ u64 count : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct nixx_af_tl1_const_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL1_CONST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL1_CONST(void) ++{ ++ return 0x70; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_cir ++ * ++ * NIX AF Transmit Level 2 Committed Information Rate Registers This ++ * register has the same bit fields as NIX_AF_TL1()_CIR. ++ */ ++union nixx_af_tl2x_cir { ++ u64 u; ++ struct nixx_af_tl2x_cir_s { ++ u64 enable : 1; ++ u64 rate_mantissa : 8; ++ u64 rate_exponent : 4; ++ u64 rate_divider_exponent : 4; ++ u64 reserved_17_28 : 12; ++ u64 burst_mantissa : 8; ++ u64 burst_exponent : 4; ++ u64 reserved_41_63 : 23; ++ } s; ++ /* struct nixx_af_tl2x_cir_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_CIR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_CIR(u64 a) ++{ ++ return 0xe20 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_green ++ * ++ * INTERNAL: NIX Transmit Level 2 Green State Debug Register This ++ * register has the same bit fields as NIX_AF_TL1()_GREEN. ++ */ ++union nixx_af_tl2x_green { ++ u64 u; ++ struct nixx_af_tl2x_green_s { ++ u64 tail : 8; ++ u64 reserved_8_9 : 2; ++ u64 head : 8; ++ u64 reserved_18_19 : 2; ++ u64 active_vec : 20; ++ u64 rr_active : 1; ++ u64 reserved_41_63 : 23; ++ } s; ++ /* struct nixx_af_tl2x_green_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_GREEN(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_GREEN(u64 a) ++{ ++ return 0xe90 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_md_debug0 ++ * ++ * NIX AF Transmit Level 2 Meta Descriptor Debug 0 Registers See ++ * NIX_AF_TL1()_MD_DEBUG0 ++ */ ++union nixx_af_tl2x_md_debug0 { ++ u64 u; ++ struct nixx_af_tl2x_md_debug0_s { ++ u64 pmd0_length : 16; ++ u64 pmd1_length : 16; ++ u64 pmd0_vld : 1; ++ u64 pmd1_vld : 1; ++ u64 reserved_34_45 : 12; ++ u64 drain_pri : 1; ++ u64 drain : 1; ++ u64 c_con : 1; ++ u64 p_con : 1; ++ u64 reserved_50_51 : 2; ++ u64 child : 10; ++ u64 reserved_62 : 1; ++ u64 pmd_count : 1; ++ } s; ++ /* struct nixx_af_tl2x_md_debug0_s cn96xxp1; */ ++ struct nixx_af_tl2x_md_debug0_cn96xxp3 { ++ u64 pmd0_length : 16; ++ u64 reserved_16_31 : 16; ++ u64 pmd0_vld : 1; ++ u64 reserved_33 : 1; ++ u64 reserved_34_45 : 12; ++ u64 reserved_46 : 1; ++ u64 reserved_47 : 1; ++ u64 c_con : 1; ++ u64 p_con : 1; ++ u64 reserved_50_51 : 2; ++ u64 child : 10; ++ u64 reserved_62 : 1; ++ u64 reserved_63 : 1; ++ } cn96xxp3; ++ /* struct nixx_af_tl2x_md_debug0_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_tl2x_md_debug0_s cnf95xx; */ ++ /* struct nixx_af_tl2x_md_debug0_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_MD_DEBUG0(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_MD_DEBUG0(u64 a) ++{ ++ return 0xec0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_md_debug1 ++ * ++ * NIX AF Transmit Level 2 Meta Descriptor Debug 1 Registers Packet meta ++ * descriptor 0 debug. See NIX_AF_TL1()_MD_DEBUG0. ++ */ ++union nixx_af_tl2x_md_debug1 { ++ u64 u; ++ struct nixx_af_tl2x_md_debug1_s { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 uid : 4; ++ u64 reserved_23 : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } s; ++ struct nixx_af_tl2x_md_debug1_cn96xxp1 { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 uid : 4; ++ u64 drain : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } cn96xxp1; ++ struct nixx_af_tl2x_md_debug1_cn96xxp3 { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 reserved_19_22 : 4; ++ u64 flush : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } cn96xxp3; ++ /* struct nixx_af_tl2x_md_debug1_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_tl2x_md_debug1_cn96xxp1 cnf95xx; */ ++ /* struct nixx_af_tl2x_md_debug1_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_MD_DEBUG1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_MD_DEBUG1(u64 a) ++{ ++ return 0xec8 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_md_debug2 ++ * ++ * NIX AF Transmit Level 2 Meta Descriptor Debug 2 Registers Packet meta ++ * descriptor 1 debug. See NIX_AF_TL1()_MD_DEBUG0. ++ */ ++union nixx_af_tl2x_md_debug2 { ++ u64 u; ++ struct nixx_af_tl2x_md_debug2_s { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 uid : 4; ++ u64 reserved_23 : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } s; ++ struct nixx_af_tl2x_md_debug2_cn96xxp1 { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 uid : 4; ++ u64 drain : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } cn96xxp1; ++ struct nixx_af_tl2x_md_debug2_cn96xxp3 { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 reserved_19_22 : 4; ++ u64 flush : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } cn96xxp3; ++ /* struct nixx_af_tl2x_md_debug2_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_tl2x_md_debug2_cn96xxp1 cnf95xx; */ ++ /* struct nixx_af_tl2x_md_debug2_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_MD_DEBUG2(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_MD_DEBUG2(u64 a) ++{ ++ return 0xed0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_md_debug3 ++ * ++ * NIX AF Transmit Level 2 Meta Descriptor Debug 3 Registers Flush meta ++ * descriptor debug. See NIX_AF_TL1()_MD_DEBUG0. ++ */ ++union nixx_af_tl2x_md_debug3 { ++ u64 u; ++ struct nixx_af_tl2x_md_debug3_s { ++ u64 reserved_0_36 : 37; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } s; ++ /* struct nixx_af_tl2x_md_debug3_s cn96xxp1; */ ++ struct nixx_af_tl2x_md_debug3_cn96xxp3 { ++ u64 reserved_0_36 : 37; ++ u64 reserved_37_38 : 2; ++ u64 reserved_39_51 : 13; ++ u64 reserved_52_61 : 10; ++ u64 reserved_62 : 1; ++ u64 reserved_63 : 1; ++ } cn96xxp3; ++ /* struct nixx_af_tl2x_md_debug3_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_tl2x_md_debug3_s cnf95xx; */ ++ /* struct nixx_af_tl2x_md_debug3_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_MD_DEBUG3(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_MD_DEBUG3(u64 a) ++{ ++ return 0xed8 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_parent ++ * ++ * NIX AF Transmit Level 2 Parent Registers ++ */ ++union nixx_af_tl2x_parent { ++ u64 u; ++ struct nixx_af_tl2x_parent_s { ++ u64 reserved_0_15 : 16; ++ u64 parent : 5; ++ u64 reserved_21_63 : 43; ++ } s; ++ /* struct nixx_af_tl2x_parent_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_PARENT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_PARENT(u64 a) ++{ ++ return 0xe88 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_pir ++ * ++ * NIX AF Transmit Level 2 Peak Information Rate Registers This register ++ * has the same bit fields as NIX_AF_TL1()_CIR. ++ */ ++union nixx_af_tl2x_pir { ++ u64 u; ++ struct nixx_af_tl2x_pir_s { ++ u64 enable : 1; ++ u64 rate_mantissa : 8; ++ u64 rate_exponent : 4; ++ u64 rate_divider_exponent : 4; ++ u64 reserved_17_28 : 12; ++ u64 burst_mantissa : 8; ++ u64 burst_exponent : 4; ++ u64 reserved_41_63 : 23; ++ } s; ++ /* struct nixx_af_tl2x_pir_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_PIR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_PIR(u64 a) ++{ ++ return 0xe30 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_pointers ++ * ++ * INTERNAL: NIX Transmit Level 2 Linked List Pointers Debug Register ++ */ ++union nixx_af_tl2x_pointers { ++ u64 u; ++ struct nixx_af_tl2x_pointers_s { ++ u64 next : 8; ++ u64 reserved_8_15 : 8; ++ u64 prev : 8; ++ u64 reserved_24_63 : 40; ++ } s; ++ /* struct nixx_af_tl2x_pointers_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_POINTERS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_POINTERS(u64 a) ++{ ++ return 0xe60 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_red ++ * ++ * INTERNAL: NIX Transmit Level 2 Red State Debug Register This register ++ * has the same bit fields as NIX_AF_TL1()_RED. ++ */ ++union nixx_af_tl2x_red { ++ u64 u; ++ struct nixx_af_tl2x_red_s { ++ u64 tail : 8; ++ u64 reserved_8_9 : 2; ++ u64 head : 8; ++ u64 reserved_18_63 : 46; ++ } s; ++ /* struct nixx_af_tl2x_red_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_RED(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_RED(u64 a) ++{ ++ return 0xeb0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_sched_state ++ * ++ * NIX AF Transmit Level 2 Scheduling Control State Registers ++ */ ++union nixx_af_tl2x_sched_state { ++ u64 u; ++ struct nixx_af_tl2x_sched_state_s { ++ u64 rr_count : 25; ++ u64 reserved_25_63 : 39; ++ } s; ++ /* struct nixx_af_tl2x_sched_state_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_SCHED_STATE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_SCHED_STATE(u64 a) ++{ ++ return 0xe40 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_schedule ++ * ++ * NIX AF Transmit Level 2 Scheduling Control Registers ++ */ ++union nixx_af_tl2x_schedule { ++ u64 u; ++ struct nixx_af_tl2x_schedule_s { ++ u64 rr_quantum : 24; ++ u64 prio : 4; ++ u64 reserved_28_63 : 36; ++ } s; ++ /* struct nixx_af_tl2x_schedule_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_SCHEDULE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_SCHEDULE(u64 a) ++{ ++ return 0xe00 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_shape ++ * ++ * NIX AF Transmit Level 2 Shaping Control Registers ++ */ ++union nixx_af_tl2x_shape { ++ u64 u; ++ struct nixx_af_tl2x_shape_s { ++ u64 adjust : 9; ++ u64 red_algo : 2; ++ u64 red_disable : 1; ++ u64 yellow_disable : 1; ++ u64 reserved_13_23 : 11; ++ u64 length_disable : 1; ++ u64 schedule_list : 2; ++ u64 reserved_27_63 : 37; ++ } s; ++ /* struct nixx_af_tl2x_shape_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_SHAPE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_SHAPE(u64 a) ++{ ++ return 0xe10 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_shape_state ++ * ++ * NIX AF Transmit Level 2 Shape State Registers This register must not ++ * be written during normal operation. ++ */ ++union nixx_af_tl2x_shape_state { ++ u64 u; ++ struct nixx_af_tl2x_shape_state_s { ++ u64 cir_accum : 26; ++ u64 pir_accum : 26; ++ u64 color : 2; ++ u64 reserved_54_63 : 10; ++ } s; ++ /* struct nixx_af_tl2x_shape_state_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_SHAPE_STATE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_SHAPE_STATE(u64 a) ++{ ++ return 0xe50 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_sw_xoff ++ * ++ * NIX AF Transmit Level 2 Software Controlled XOFF Registers This ++ * register has the same bit fields as NIX_AF_TL1()_SW_XOFF. ++ */ ++union nixx_af_tl2x_sw_xoff { ++ u64 u; ++ struct nixx_af_tl2x_sw_xoff_s { ++ u64 xoff : 1; ++ u64 drain : 1; ++ u64 reserved_2 : 1; ++ u64 drain_irq : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct nixx_af_tl2x_sw_xoff_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_SW_XOFF(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_SW_XOFF(u64 a) ++{ ++ return 0xe70 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_topology ++ * ++ * NIX AF Transmit Level 2 Topology Registers ++ */ ++union nixx_af_tl2x_topology { ++ u64 u; ++ struct nixx_af_tl2x_topology_s { ++ u64 reserved_0 : 1; ++ u64 rr_prio : 4; ++ u64 reserved_5_31 : 27; ++ u64 prio_anchor : 8; ++ u64 reserved_40_63 : 24; ++ } s; ++ /* struct nixx_af_tl2x_topology_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_TOPOLOGY(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_TOPOLOGY(u64 a) ++{ ++ return 0xe80 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2#_yellow ++ * ++ * INTERNAL: NIX Transmit Level 2 Yellow State Debug Register This ++ * register has the same bit fields as NIX_AF_TL1()_YELLOW. ++ */ ++union nixx_af_tl2x_yellow { ++ u64 u; ++ struct nixx_af_tl2x_yellow_s { ++ u64 tail : 8; ++ u64 reserved_8_9 : 2; ++ u64 head : 8; ++ u64 reserved_18_63 : 46; ++ } s; ++ /* struct nixx_af_tl2x_yellow_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL2X_YELLOW(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2X_YELLOW(u64 a) ++{ ++ return 0xea0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl2_const ++ * ++ * NIX AF Transmit Level 2 Constants Register This register contains ++ * constants for software discovery. ++ */ ++union nixx_af_tl2_const { ++ u64 u; ++ struct nixx_af_tl2_const_s { ++ u64 count : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct nixx_af_tl2_const_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL2_CONST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL2_CONST(void) ++{ ++ return 0x78; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_cir ++ * ++ * NIX AF Transmit Level 3 Committed Information Rate Registers This ++ * register has the same bit fields as NIX_AF_TL1()_CIR. ++ */ ++union nixx_af_tl3x_cir { ++ u64 u; ++ struct nixx_af_tl3x_cir_s { ++ u64 enable : 1; ++ u64 rate_mantissa : 8; ++ u64 rate_exponent : 4; ++ u64 rate_divider_exponent : 4; ++ u64 reserved_17_28 : 12; ++ u64 burst_mantissa : 8; ++ u64 burst_exponent : 4; ++ u64 reserved_41_63 : 23; ++ } s; ++ /* struct nixx_af_tl3x_cir_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_CIR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_CIR(u64 a) ++{ ++ return 0x1020 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_green ++ * ++ * INTERNAL: NIX Transmit Level 3 Green State Debug Register ++ */ ++union nixx_af_tl3x_green { ++ u64 u; ++ struct nixx_af_tl3x_green_s { ++ u64 tail : 9; ++ u64 reserved_9 : 1; ++ u64 head : 9; ++ u64 reserved_19 : 1; ++ u64 active_vec : 20; ++ u64 rr_active : 1; ++ u64 reserved_41_63 : 23; ++ } s; ++ /* struct nixx_af_tl3x_green_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_GREEN(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_GREEN(u64 a) ++{ ++ return 0x1090 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_md_debug0 ++ * ++ * NIX AF Transmit Level 3 Meta Descriptor Debug 0 Registers See ++ * NIX_AF_TL1()_MD_DEBUG0. ++ */ ++union nixx_af_tl3x_md_debug0 { ++ u64 u; ++ struct nixx_af_tl3x_md_debug0_s { ++ u64 pmd0_length : 16; ++ u64 pmd1_length : 16; ++ u64 pmd0_vld : 1; ++ u64 pmd1_vld : 1; ++ u64 reserved_34_45 : 12; ++ u64 drain_pri : 1; ++ u64 drain : 1; ++ u64 c_con : 1; ++ u64 p_con : 1; ++ u64 reserved_50_51 : 2; ++ u64 child : 10; ++ u64 reserved_62 : 1; ++ u64 pmd_count : 1; ++ } s; ++ /* struct nixx_af_tl3x_md_debug0_s cn96xxp1; */ ++ struct nixx_af_tl3x_md_debug0_cn96xxp3 { ++ u64 pmd0_length : 16; ++ u64 reserved_16_31 : 16; ++ u64 pmd0_vld : 1; ++ u64 reserved_33 : 1; ++ u64 reserved_34_45 : 12; ++ u64 reserved_46 : 1; ++ u64 reserved_47 : 1; ++ u64 c_con : 1; ++ u64 p_con : 1; ++ u64 reserved_50_51 : 2; ++ u64 child : 10; ++ u64 reserved_62 : 1; ++ u64 reserved_63 : 1; ++ } cn96xxp3; ++ /* struct nixx_af_tl3x_md_debug0_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_tl3x_md_debug0_s cnf95xx; */ ++ /* struct nixx_af_tl3x_md_debug0_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_MD_DEBUG0(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_MD_DEBUG0(u64 a) ++{ ++ return 0x10c0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_md_debug1 ++ * ++ * NIX AF Transmit Level 3 Meta Descriptor Debug 1 Registers Packet meta ++ * descriptor 0 debug. See NIX_AF_TL1()_MD_DEBUG0. ++ */ ++union nixx_af_tl3x_md_debug1 { ++ u64 u; ++ struct nixx_af_tl3x_md_debug1_s { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 uid : 4; ++ u64 reserved_23 : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } s; ++ struct nixx_af_tl3x_md_debug1_cn96xxp1 { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 uid : 4; ++ u64 drain : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } cn96xxp1; ++ struct nixx_af_tl3x_md_debug1_cn96xxp3 { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 reserved_19_22 : 4; ++ u64 flush : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } cn96xxp3; ++ /* struct nixx_af_tl3x_md_debug1_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_tl3x_md_debug1_cn96xxp1 cnf95xx; */ ++ /* struct nixx_af_tl3x_md_debug1_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_MD_DEBUG1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_MD_DEBUG1(u64 a) ++{ ++ return 0x10c8 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_md_debug2 ++ * ++ * NIX AF Transmit Level 3 Meta Descriptor Debug 2 Registers Packet meta ++ * descriptor 1 debug. See NIX_AF_TL1()_MD_DEBUG0. ++ */ ++union nixx_af_tl3x_md_debug2 { ++ u64 u; ++ struct nixx_af_tl3x_md_debug2_s { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 uid : 4; ++ u64 reserved_23 : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } s; ++ struct nixx_af_tl3x_md_debug2_cn96xxp1 { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 uid : 4; ++ u64 drain : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } cn96xxp1; ++ struct nixx_af_tl3x_md_debug2_cn96xxp3 { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 reserved_19_22 : 4; ++ u64 flush : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } cn96xxp3; ++ /* struct nixx_af_tl3x_md_debug2_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_tl3x_md_debug2_cn96xxp1 cnf95xx; */ ++ /* struct nixx_af_tl3x_md_debug2_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_MD_DEBUG2(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_MD_DEBUG2(u64 a) ++{ ++ return 0x10d0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_md_debug3 ++ * ++ * NIX AF Transmit Level 3 Meta Descriptor Debug 3 Registers Flush meta ++ * descriptor debug. See NIX_AF_TL1()_MD_DEBUG0. ++ */ ++union nixx_af_tl3x_md_debug3 { ++ u64 u; ++ struct nixx_af_tl3x_md_debug3_s { ++ u64 reserved_0_36 : 37; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } s; ++ /* struct nixx_af_tl3x_md_debug3_s cn96xxp1; */ ++ struct nixx_af_tl3x_md_debug3_cn96xxp3 { ++ u64 reserved_0_36 : 37; ++ u64 reserved_37_38 : 2; ++ u64 reserved_39_51 : 13; ++ u64 reserved_52_61 : 10; ++ u64 reserved_62 : 1; ++ u64 reserved_63 : 1; ++ } cn96xxp3; ++ /* struct nixx_af_tl3x_md_debug3_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_tl3x_md_debug3_s cnf95xx; */ ++ /* struct nixx_af_tl3x_md_debug3_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_MD_DEBUG3(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_MD_DEBUG3(u64 a) ++{ ++ return 0x10d8 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_parent ++ * ++ * NIX AF Transmit Level 3 Parent Registers ++ */ ++union nixx_af_tl3x_parent { ++ u64 u; ++ struct nixx_af_tl3x_parent_s { ++ u64 reserved_0_15 : 16; ++ u64 parent : 8; ++ u64 reserved_24_63 : 40; ++ } s; ++ /* struct nixx_af_tl3x_parent_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_PARENT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_PARENT(u64 a) ++{ ++ return 0x1088 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_pir ++ * ++ * NIX AF Transmit Level 3 Peak Information Rate Registers This register ++ * has the same bit fields as NIX_AF_TL1()_CIR. ++ */ ++union nixx_af_tl3x_pir { ++ u64 u; ++ struct nixx_af_tl3x_pir_s { ++ u64 enable : 1; ++ u64 rate_mantissa : 8; ++ u64 rate_exponent : 4; ++ u64 rate_divider_exponent : 4; ++ u64 reserved_17_28 : 12; ++ u64 burst_mantissa : 8; ++ u64 burst_exponent : 4; ++ u64 reserved_41_63 : 23; ++ } s; ++ /* struct nixx_af_tl3x_pir_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_PIR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_PIR(u64 a) ++{ ++ return 0x1030 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_pointers ++ * ++ * INTERNAL: NIX Transmit Level 3 Linked List Pointers Debug Register ++ * This register has the same bit fields as NIX_AF_TL2()_POINTERS. ++ */ ++union nixx_af_tl3x_pointers { ++ u64 u; ++ struct nixx_af_tl3x_pointers_s { ++ u64 next : 8; ++ u64 reserved_8_15 : 8; ++ u64 prev : 8; ++ u64 reserved_24_63 : 40; ++ } s; ++ /* struct nixx_af_tl3x_pointers_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_POINTERS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_POINTERS(u64 a) ++{ ++ return 0x1060 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_red ++ * ++ * INTERNAL: NIX Transmit Level 3 Red State Debug Register This register ++ * has the same bit fields as NIX_AF_TL3()_YELLOW. ++ */ ++union nixx_af_tl3x_red { ++ u64 u; ++ struct nixx_af_tl3x_red_s { ++ u64 tail : 9; ++ u64 reserved_9 : 1; ++ u64 head : 9; ++ u64 reserved_19_63 : 45; ++ } s; ++ /* struct nixx_af_tl3x_red_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_RED(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_RED(u64 a) ++{ ++ return 0x10b0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_sched_state ++ * ++ * NIX AF Transmit Level 3 Scheduling Control State Registers This ++ * register has the same bit fields as NIX_AF_TL2()_SCHED_STATE. ++ */ ++union nixx_af_tl3x_sched_state { ++ u64 u; ++ struct nixx_af_tl3x_sched_state_s { ++ u64 rr_count : 25; ++ u64 reserved_25_63 : 39; ++ } s; ++ /* struct nixx_af_tl3x_sched_state_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_SCHED_STATE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_SCHED_STATE(u64 a) ++{ ++ return 0x1040 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_schedule ++ * ++ * NIX AF Transmit Level 3 Scheduling Control Registers This register has ++ * the same bit fields as NIX_AF_TL2()_SCHEDULE. ++ */ ++union nixx_af_tl3x_schedule { ++ u64 u; ++ struct nixx_af_tl3x_schedule_s { ++ u64 rr_quantum : 24; ++ u64 prio : 4; ++ u64 reserved_28_63 : 36; ++ } s; ++ /* struct nixx_af_tl3x_schedule_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_SCHEDULE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_SCHEDULE(u64 a) ++{ ++ return 0x1000 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_shape ++ * ++ * NIX AF Transmit Level 3 Shaping Control Registers ++ */ ++union nixx_af_tl3x_shape { ++ u64 u; ++ struct nixx_af_tl3x_shape_s { ++ u64 adjust : 9; ++ u64 red_algo : 2; ++ u64 red_disable : 1; ++ u64 yellow_disable : 1; ++ u64 reserved_13_23 : 11; ++ u64 length_disable : 1; ++ u64 schedule_list : 2; ++ u64 reserved_27_63 : 37; ++ } s; ++ /* struct nixx_af_tl3x_shape_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_SHAPE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_SHAPE(u64 a) ++{ ++ return 0x1010 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_shape_state ++ * ++ * NIX AF Transmit Level 3 Shaping State Registers This register has the ++ * same bit fields as NIX_AF_TL2()_SHAPE_STATE. This register must not be ++ * written during normal operation. ++ */ ++union nixx_af_tl3x_shape_state { ++ u64 u; ++ struct nixx_af_tl3x_shape_state_s { ++ u64 cir_accum : 26; ++ u64 pir_accum : 26; ++ u64 color : 2; ++ u64 reserved_54_63 : 10; ++ } s; ++ /* struct nixx_af_tl3x_shape_state_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_SHAPE_STATE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_SHAPE_STATE(u64 a) ++{ ++ return 0x1050 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_sw_xoff ++ * ++ * NIX AF Transmit Level 3 Software Controlled XOFF Registers This ++ * register has the same bit fields as NIX_AF_TL1()_SW_XOFF ++ */ ++union nixx_af_tl3x_sw_xoff { ++ u64 u; ++ struct nixx_af_tl3x_sw_xoff_s { ++ u64 xoff : 1; ++ u64 drain : 1; ++ u64 reserved_2 : 1; ++ u64 drain_irq : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct nixx_af_tl3x_sw_xoff_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_SW_XOFF(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_SW_XOFF(u64 a) ++{ ++ return 0x1070 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_topology ++ * ++ * NIX AF Transmit Level 3 Topology Registers ++ */ ++union nixx_af_tl3x_topology { ++ u64 u; ++ struct nixx_af_tl3x_topology_s { ++ u64 reserved_0 : 1; ++ u64 rr_prio : 4; ++ u64 reserved_5_31 : 27; ++ u64 prio_anchor : 9; ++ u64 reserved_41_63 : 23; ++ } s; ++ /* struct nixx_af_tl3x_topology_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_TOPOLOGY(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_TOPOLOGY(u64 a) ++{ ++ return 0x1080 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3#_yellow ++ * ++ * INTERNAL: NIX Transmit Level 3 Yellow State Debug Register ++ */ ++union nixx_af_tl3x_yellow { ++ u64 u; ++ struct nixx_af_tl3x_yellow_s { ++ u64 tail : 9; ++ u64 reserved_9 : 1; ++ u64 head : 9; ++ u64 reserved_19_63 : 45; ++ } s; ++ /* struct nixx_af_tl3x_yellow_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3X_YELLOW(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3X_YELLOW(u64 a) ++{ ++ return 0x10a0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3_const ++ * ++ * NIX AF Transmit Level 3 Constants Register This register contains ++ * constants for software discovery. ++ */ ++union nixx_af_tl3_const { ++ u64 u; ++ struct nixx_af_tl3_const_s { ++ u64 count : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct nixx_af_tl3_const_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3_CONST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3_CONST(void) ++{ ++ return 0x80; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3_tl2#_bp_status ++ * ++ * NIX AF Transmit Level 3/2 Backpressure Status Registers ++ */ ++union nixx_af_tl3_tl2x_bp_status { ++ u64 u; ++ struct nixx_af_tl3_tl2x_bp_status_s { ++ u64 hw_xoff : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_tl3_tl2x_bp_status_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3_TL2X_BP_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3_TL2X_BP_STATUS(u64 a) ++{ ++ return 0x1610 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3_tl2#_cfg ++ * ++ * NIX AF Transmit Level 3/2 Configuration Registers ++ */ ++union nixx_af_tl3_tl2x_cfg { ++ u64 u; ++ struct nixx_af_tl3_tl2x_cfg_s { ++ u64 express : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_tl3_tl2x_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3_TL2X_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3_TL2X_CFG(u64 a) ++{ ++ return 0x1600 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl3_tl2#_link#_cfg ++ * ++ * NIX AF Transmit Level 3/2 Link Configuration Registers These registers ++ * specify the links and associated channels that a given TL3 or TL2 ++ * queue (depending on NIX_AF_PSE_CHANNEL_LEVEL[BP_LEVEL]) can transmit ++ * on. Each TL3/TL2 queue can be enabled to transmit on and be ++ * backpressured by one or more links and associated channels. The last ++ * index (LINK) is enumerated by NIX_LINK_E. ++ */ ++union nixx_af_tl3_tl2x_linkx_cfg { ++ u64 u; ++ struct nixx_af_tl3_tl2x_linkx_cfg_s { ++ u64 relchan : 8; ++ u64 reserved_8_11 : 4; ++ u64 ena : 1; ++ u64 bp_ena : 1; ++ u64 reserved_14_63 : 50; ++ } s; ++ /* struct nixx_af_tl3_tl2x_linkx_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL3_TL2X_LINKX_CFG(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL3_TL2X_LINKX_CFG(u64 a, u64 b) ++{ ++ return 0x1700 + 0x10000 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_bp_status ++ * ++ * NIX AF Transmit Level 4 Backpressure Status Registers ++ */ ++union nixx_af_tl4x_bp_status { ++ u64 u; ++ struct nixx_af_tl4x_bp_status_s { ++ u64 hw_xoff : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_tl4x_bp_status_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_BP_STATUS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_BP_STATUS(u64 a) ++{ ++ return 0xb00 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_cir ++ * ++ * NIX AF Transmit Level 4 Committed Information Rate Registers This ++ * register has the same bit fields as NIX_AF_TL1()_CIR. ++ */ ++union nixx_af_tl4x_cir { ++ u64 u; ++ struct nixx_af_tl4x_cir_s { ++ u64 enable : 1; ++ u64 rate_mantissa : 8; ++ u64 rate_exponent : 4; ++ u64 rate_divider_exponent : 4; ++ u64 reserved_17_28 : 12; ++ u64 burst_mantissa : 8; ++ u64 burst_exponent : 4; ++ u64 reserved_41_63 : 23; ++ } s; ++ /* struct nixx_af_tl4x_cir_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_CIR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_CIR(u64 a) ++{ ++ return 0x1220 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_green ++ * ++ * INTERNAL: NIX Transmit Level 4 Green State Debug Register This ++ * register has the same bit fields as NIX_AF_TL3()_GREEN. ++ */ ++union nixx_af_tl4x_green { ++ u64 u; ++ struct nixx_af_tl4x_green_s { ++ u64 tail : 9; ++ u64 reserved_9 : 1; ++ u64 head : 9; ++ u64 reserved_19 : 1; ++ u64 active_vec : 20; ++ u64 rr_active : 1; ++ u64 reserved_41_63 : 23; ++ } s; ++ /* struct nixx_af_tl4x_green_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_GREEN(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_GREEN(u64 a) ++{ ++ return 0x1290 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_md_debug0 ++ * ++ * NIX AF Transmit Level 4 Meta Descriptor Debug 0 Registers See ++ * NIX_AF_TL1()_MD_DEBUG0. ++ */ ++union nixx_af_tl4x_md_debug0 { ++ u64 u; ++ struct nixx_af_tl4x_md_debug0_s { ++ u64 pmd0_length : 16; ++ u64 pmd1_length : 16; ++ u64 pmd0_vld : 1; ++ u64 pmd1_vld : 1; ++ u64 reserved_34_45 : 12; ++ u64 drain_pri : 1; ++ u64 drain : 1; ++ u64 c_con : 1; ++ u64 p_con : 1; ++ u64 reserved_50_51 : 2; ++ u64 child : 10; ++ u64 reserved_62 : 1; ++ u64 pmd_count : 1; ++ } s; ++ /* struct nixx_af_tl4x_md_debug0_s cn96xxp1; */ ++ struct nixx_af_tl4x_md_debug0_cn96xxp3 { ++ u64 pmd0_length : 16; ++ u64 reserved_16_31 : 16; ++ u64 pmd0_vld : 1; ++ u64 reserved_33 : 1; ++ u64 reserved_34_45 : 12; ++ u64 reserved_46 : 1; ++ u64 reserved_47 : 1; ++ u64 c_con : 1; ++ u64 p_con : 1; ++ u64 reserved_50_51 : 2; ++ u64 child : 10; ++ u64 reserved_62 : 1; ++ u64 reserved_63 : 1; ++ } cn96xxp3; ++ /* struct nixx_af_tl4x_md_debug0_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_tl4x_md_debug0_s cnf95xx; */ ++ /* struct nixx_af_tl4x_md_debug0_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_MD_DEBUG0(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_MD_DEBUG0(u64 a) ++{ ++ return 0x12c0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_md_debug1 ++ * ++ * NIX AF Transmit Level 4 Meta Descriptor Debug 1 Registers Packet meta ++ * descriptor 0 debug. See NIX_AF_TL1()_MD_DEBUG0. ++ */ ++union nixx_af_tl4x_md_debug1 { ++ u64 u; ++ struct nixx_af_tl4x_md_debug1_s { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 uid : 4; ++ u64 reserved_23 : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } s; ++ struct nixx_af_tl4x_md_debug1_cn96xxp1 { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 uid : 4; ++ u64 drain : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } cn96xxp1; ++ struct nixx_af_tl4x_md_debug1_cn96xxp3 { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 reserved_19_22 : 4; ++ u64 flush : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } cn96xxp3; ++ /* struct nixx_af_tl4x_md_debug1_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_tl4x_md_debug1_cn96xxp1 cnf95xx; */ ++ /* struct nixx_af_tl4x_md_debug1_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_MD_DEBUG1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_MD_DEBUG1(u64 a) ++{ ++ return 0x12c8 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_md_debug2 ++ * ++ * NIX AF Transmit Level 4 Meta Descriptor Debug 2 Registers Packet meta ++ * descriptor 1 debug. See NIX_AF_TL1()_MD_DEBUG0. ++ */ ++union nixx_af_tl4x_md_debug2 { ++ u64 u; ++ struct nixx_af_tl4x_md_debug2_s { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 uid : 4; ++ u64 reserved_23 : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } s; ++ struct nixx_af_tl4x_md_debug2_cn96xxp1 { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 uid : 4; ++ u64 drain : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } cn96xxp1; ++ struct nixx_af_tl4x_md_debug2_cn96xxp3 { ++ u64 reserved_0_5 : 6; ++ u64 red_algo_override : 2; ++ u64 cir_dis : 1; ++ u64 pir_dis : 1; ++ u64 adjust : 9; ++ u64 reserved_19_22 : 4; ++ u64 flush : 1; ++ u64 bubble : 1; ++ u64 color : 2; ++ u64 pse_pkt_id : 9; ++ u64 reserved_36 : 1; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } cn96xxp3; ++ /* struct nixx_af_tl4x_md_debug2_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_tl4x_md_debug2_cn96xxp1 cnf95xx; */ ++ /* struct nixx_af_tl4x_md_debug2_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_MD_DEBUG2(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_MD_DEBUG2(u64 a) ++{ ++ return 0x12d0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_md_debug3 ++ * ++ * NIX AF Transmit Level 4 Meta Descriptor Debug 3 Registers Flush meta ++ * descriptor debug. See NIX_AF_TL1()_MD_DEBUG0. ++ */ ++union nixx_af_tl4x_md_debug3 { ++ u64 u; ++ struct nixx_af_tl4x_md_debug3_s { ++ u64 reserved_0_36 : 37; ++ u64 tx_pkt_p2x : 2; ++ u64 sqm_pkt_id : 13; ++ u64 mdq_idx : 10; ++ u64 reserved_62 : 1; ++ u64 vld : 1; ++ } s; ++ /* struct nixx_af_tl4x_md_debug3_s cn96xxp1; */ ++ struct nixx_af_tl4x_md_debug3_cn96xxp3 { ++ u64 reserved_0_36 : 37; ++ u64 reserved_37_38 : 2; ++ u64 reserved_39_51 : 13; ++ u64 reserved_52_61 : 10; ++ u64 reserved_62 : 1; ++ u64 reserved_63 : 1; ++ } cn96xxp3; ++ /* struct nixx_af_tl4x_md_debug3_cn96xxp3 cn98xx; */ ++ /* struct nixx_af_tl4x_md_debug3_s cnf95xx; */ ++ /* struct nixx_af_tl4x_md_debug3_cn96xxp3 loki; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_MD_DEBUG3(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_MD_DEBUG3(u64 a) ++{ ++ return 0x12d8 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_parent ++ * ++ * NIX AF Transmit Level 4 Parent Registers ++ */ ++union nixx_af_tl4x_parent { ++ u64 u; ++ struct nixx_af_tl4x_parent_s { ++ u64 reserved_0_15 : 16; ++ u64 parent : 8; ++ u64 reserved_24_63 : 40; ++ } s; ++ /* struct nixx_af_tl4x_parent_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_PARENT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_PARENT(u64 a) ++{ ++ return 0x1288 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_pir ++ * ++ * NIX AF Transmit Level 4 Peak Information Rate Registers This register ++ * has the same bit fields as NIX_AF_TL1()_CIR. ++ */ ++union nixx_af_tl4x_pir { ++ u64 u; ++ struct nixx_af_tl4x_pir_s { ++ u64 enable : 1; ++ u64 rate_mantissa : 8; ++ u64 rate_exponent : 4; ++ u64 rate_divider_exponent : 4; ++ u64 reserved_17_28 : 12; ++ u64 burst_mantissa : 8; ++ u64 burst_exponent : 4; ++ u64 reserved_41_63 : 23; ++ } s; ++ /* struct nixx_af_tl4x_pir_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_PIR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_PIR(u64 a) ++{ ++ return 0x1230 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_pointers ++ * ++ * INTERNAL: NIX Transmit Level 4 Linked List Pointers Debug Register ++ * This register has the same bit fields as NIX_AF_TL2()_POINTERS. ++ */ ++union nixx_af_tl4x_pointers { ++ u64 u; ++ struct nixx_af_tl4x_pointers_s { ++ u64 next : 9; ++ u64 reserved_9_15 : 7; ++ u64 prev : 9; ++ u64 reserved_25_63 : 39; ++ } s; ++ /* struct nixx_af_tl4x_pointers_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_POINTERS(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_POINTERS(u64 a) ++{ ++ return 0x1260 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_red ++ * ++ * INTERNAL: NIX Transmit Level 4 Red State Debug Register This register ++ * has the same bit fields as NIX_AF_TL3()_YELLOW. ++ */ ++union nixx_af_tl4x_red { ++ u64 u; ++ struct nixx_af_tl4x_red_s { ++ u64 tail : 9; ++ u64 reserved_9 : 1; ++ u64 head : 9; ++ u64 reserved_19_63 : 45; ++ } s; ++ /* struct nixx_af_tl4x_red_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_RED(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_RED(u64 a) ++{ ++ return 0x12b0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_sched_state ++ * ++ * NIX AF Transmit Level 4 Scheduling Control State Registers This ++ * register has the same bit fields as NIX_AF_TL2()_SCHED_STATE. ++ */ ++union nixx_af_tl4x_sched_state { ++ u64 u; ++ struct nixx_af_tl4x_sched_state_s { ++ u64 rr_count : 25; ++ u64 reserved_25_63 : 39; ++ } s; ++ /* struct nixx_af_tl4x_sched_state_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_SCHED_STATE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_SCHED_STATE(u64 a) ++{ ++ return 0x1240 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_schedule ++ * ++ * NIX AF Transmit Level 4 Scheduling Control Registers This register has ++ * the same bit fields as NIX_AF_TL2()_SCHEDULE. ++ */ ++union nixx_af_tl4x_schedule { ++ u64 u; ++ struct nixx_af_tl4x_schedule_s { ++ u64 rr_quantum : 24; ++ u64 prio : 4; ++ u64 reserved_28_63 : 36; ++ } s; ++ /* struct nixx_af_tl4x_schedule_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_SCHEDULE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_SCHEDULE(u64 a) ++{ ++ return 0x1200 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_sdp_link_cfg ++ * ++ * NIX AF Transmit Level 4 Link Configuration Registers These registers ++ * specify which TL4 queues transmit to and are optionally backpressured ++ * by SDP. ++ */ ++union nixx_af_tl4x_sdp_link_cfg { ++ u64 u; ++ struct nixx_af_tl4x_sdp_link_cfg_s { ++ u64 relchan : 8; ++ u64 reserved_8_11 : 4; ++ u64 ena : 1; ++ u64 bp_ena : 1; ++ u64 reserved_14_63 : 50; ++ } s; ++ /* struct nixx_af_tl4x_sdp_link_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_SDP_LINK_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_SDP_LINK_CFG(u64 a) ++{ ++ return 0xb10 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_shape ++ * ++ * NIX AF Transmit Level 4 Shaping Control Registers This register has ++ * the same bit fields as NIX_AF_TL2()_SHAPE. ++ */ ++union nixx_af_tl4x_shape { ++ u64 u; ++ struct nixx_af_tl4x_shape_s { ++ u64 adjust : 9; ++ u64 red_algo : 2; ++ u64 red_disable : 1; ++ u64 yellow_disable : 1; ++ u64 reserved_13_23 : 11; ++ u64 length_disable : 1; ++ u64 schedule_list : 2; ++ u64 reserved_27_63 : 37; ++ } s; ++ /* struct nixx_af_tl4x_shape_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_SHAPE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_SHAPE(u64 a) ++{ ++ return 0x1210 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_shape_state ++ * ++ * NIX AF Transmit Level 4 Shaping State Registers This register has the ++ * same bit fields as NIX_AF_TL2()_SHAPE_STATE. This register must not be ++ * written during normal operation. ++ */ ++union nixx_af_tl4x_shape_state { ++ u64 u; ++ struct nixx_af_tl4x_shape_state_s { ++ u64 cir_accum : 26; ++ u64 pir_accum : 26; ++ u64 color : 2; ++ u64 reserved_54_63 : 10; ++ } s; ++ /* struct nixx_af_tl4x_shape_state_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_SHAPE_STATE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_SHAPE_STATE(u64 a) ++{ ++ return 0x1250 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_sw_xoff ++ * ++ * NIX AF Transmit Level 4 Software Controlled XOFF Registers This ++ * register has the same bit fields as NIX_AF_TL1()_SW_XOFF ++ */ ++union nixx_af_tl4x_sw_xoff { ++ u64 u; ++ struct nixx_af_tl4x_sw_xoff_s { ++ u64 xoff : 1; ++ u64 drain : 1; ++ u64 reserved_2 : 1; ++ u64 drain_irq : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct nixx_af_tl4x_sw_xoff_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_SW_XOFF(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_SW_XOFF(u64 a) ++{ ++ return 0x1270 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_topology ++ * ++ * NIX AF Transmit Level 4 Topology Registers ++ */ ++union nixx_af_tl4x_topology { ++ u64 u; ++ struct nixx_af_tl4x_topology_s { ++ u64 reserved_0 : 1; ++ u64 rr_prio : 4; ++ u64 reserved_5_31 : 27; ++ u64 prio_anchor : 9; ++ u64 reserved_41_63 : 23; ++ } s; ++ /* struct nixx_af_tl4x_topology_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_TOPOLOGY(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_TOPOLOGY(u64 a) ++{ ++ return 0x1280 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4#_yellow ++ * ++ * INTERNAL: NIX Transmit Level 4 Yellow State Debug Register This ++ * register has the same bit fields as NIX_AF_TL3()_YELLOW ++ */ ++union nixx_af_tl4x_yellow { ++ u64 u; ++ struct nixx_af_tl4x_yellow_s { ++ u64 tail : 9; ++ u64 reserved_9 : 1; ++ u64 head : 9; ++ u64 reserved_19_63 : 45; ++ } s; ++ /* struct nixx_af_tl4x_yellow_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL4X_YELLOW(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4X_YELLOW(u64 a) ++{ ++ return 0x12a0 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tl4_const ++ * ++ * NIX AF Transmit Level 4 Constants Register This register contains ++ * constants for software discovery. ++ */ ++union nixx_af_tl4_const { ++ u64 u; ++ struct nixx_af_tl4_const_s { ++ u64 count : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct nixx_af_tl4_const_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TL4_CONST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TL4_CONST(void) ++{ ++ return 0x88; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tx_link#_expr_credit ++ * ++ * INTERNAL: NIX AF Transmit Link Express Credit Registers Internal: ++ * 802.3br frame preemption/express path is defeatured. Old definition: ++ * These registers track credits per link for express packets that may ++ * potentially preempt normal packets. Link index enumerated by ++ * NIX_LINK_E. ++ */ ++union nixx_af_tx_linkx_expr_credit { ++ u64 u; ++ struct nixx_af_tx_linkx_expr_credit_s { ++ u64 reserved_0 : 1; ++ u64 cc_enable : 1; ++ u64 cc_packet_cnt : 10; ++ u64 cc_unit_cnt : 20; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct nixx_af_tx_linkx_expr_credit_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TX_LINKX_EXPR_CREDIT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TX_LINKX_EXPR_CREDIT(u64 a) ++{ ++ return 0xa10 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tx_link#_hw_xoff ++ * ++ * NIX AF Transmit Link Hardware Controlled XOFF Registers Link index ++ * enumerated by NIX_LINK_E. ++ */ ++union nixx_af_tx_linkx_hw_xoff { ++ u64 u; ++ struct nixx_af_tx_linkx_hw_xoff_s { ++ u64 chan_xoff : 64; ++ } s; ++ /* struct nixx_af_tx_linkx_hw_xoff_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TX_LINKX_HW_XOFF(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TX_LINKX_HW_XOFF(u64 a) ++{ ++ return 0xa30 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tx_link#_norm_credit ++ * ++ * NIX AF Transmit Link Normal Credit Registers These registers track ++ * credits per link for normal packets sent to CGX and LBK. Link index ++ * enumerated by NIX_LINK_E. ++ */ ++union nixx_af_tx_linkx_norm_credit { ++ u64 u; ++ struct nixx_af_tx_linkx_norm_credit_s { ++ u64 reserved_0 : 1; ++ u64 cc_enable : 1; ++ u64 cc_packet_cnt : 10; ++ u64 cc_unit_cnt : 20; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct nixx_af_tx_linkx_norm_credit_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TX_LINKX_NORM_CREDIT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TX_LINKX_NORM_CREDIT(u64 a) ++{ ++ return 0xa00 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tx_link#_sw_xoff ++ * ++ * INTERNAL: NIX AF Transmit Link Software Controlled XOFF Registers ++ * Link index enumerated by NIX_LINK_E. Internal: Defeatured registers. ++ * Software should instead use NIX_AF_TL3()_SW_XOFF registers when ++ * NIX_AF_PSE_CHANNEL_LEVEL[BP_LEVEL] is set and NIX_AF_TL2()_SW_XOFF ++ * registers when NIX_AF_PSE_CHANNEL_LEVEL[BP_LEVEL] is clear. ++ */ ++union nixx_af_tx_linkx_sw_xoff { ++ u64 u; ++ struct nixx_af_tx_linkx_sw_xoff_s { ++ u64 chan_xoff : 64; ++ } s; ++ /* struct nixx_af_tx_linkx_sw_xoff_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TX_LINKX_SW_XOFF(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TX_LINKX_SW_XOFF(u64 a) ++{ ++ return 0xa20 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tx_mcast# ++ * ++ * NIX AF Transmit Multicast Registers These registers access transmit ++ * multicast table entries used to specify multicast replication lists. ++ * Each list consists of linked entries with [EOL] = 1 in the last entry. ++ * A transmit packet is multicast when the action returned by NPC has ++ * NIX_TX_ACTION_S[OP] = NIX_TX_ACTIONOP_E::MCAST. NIX_TX_ACTION_S[INDEX] ++ * points to the start of the multicast replication list, and [EOL] = 1 ++ * indicates the end of list. ++ */ ++union nixx_af_tx_mcastx { ++ u64 u; ++ struct nixx_af_tx_mcastx_s { ++ u64 channel : 12; ++ u64 eol : 1; ++ u64 reserved_13_15 : 3; ++ u64 next : 16; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct nixx_af_tx_mcastx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TX_MCASTX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TX_MCASTX(u64 a) ++{ ++ return 0x1900 + 0x8000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tx_npc_capture_config ++ * ++ * NIX AF Transmit NPC Response Capture Configuration Register Configures ++ * the NPC response capture logic for transmit packets. When enabled, ++ * allows NPC responses for selected packets to be captured in ++ * NIX_AF_TX_NPC_CAPTURE_INFO and NIX_AF_TX_NPC_CAPTURE_RESP(). ++ */ ++union nixx_af_tx_npc_capture_config { ++ u64 u; ++ struct nixx_af_tx_npc_capture_config_s { ++ u64 en : 1; ++ u64 continuous : 1; ++ u64 lso_segnum_en : 1; ++ u64 sqe_id_en : 1; ++ u64 sq_id_en : 1; ++ u64 lf_id_en : 1; ++ u64 reserved_6_11 : 6; ++ u64 lso_segnum : 8; ++ u64 sqe_id : 16; ++ u64 sq_id : 20; ++ u64 lf_id : 8; ++ } s; ++ /* struct nixx_af_tx_npc_capture_config_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TX_NPC_CAPTURE_CONFIG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TX_NPC_CAPTURE_CONFIG(void) ++{ ++ return 0x660; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tx_npc_capture_info ++ * ++ * NIX AF Transmit NPC Response Capture Information Register This ++ * register contains captured NPC response information for a transmit ++ * packet. See NIX_AF_TX_NPC_CAPTURE_CONFIG. ++ */ ++union nixx_af_tx_npc_capture_info { ++ u64 u; ++ struct nixx_af_tx_npc_capture_info_s { ++ u64 vld : 1; ++ u64 reserved_1_11 : 11; ++ u64 lso_segnum : 8; ++ u64 sqe_id : 16; ++ u64 sq_id : 20; ++ u64 lf_id : 8; ++ } s; ++ /* struct nixx_af_tx_npc_capture_info_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TX_NPC_CAPTURE_INFO(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TX_NPC_CAPTURE_INFO(void) ++{ ++ return 0x668; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tx_npc_capture_resp# ++ * ++ * NIX AF Transmit NPC Capture Response Registers These registers contain ++ * the captured NPC response for a transmit packet when ++ * NIX_AF_TX_NPC_CAPTURE_INFO[VLD] is set. See also ++ * NIX_AF_TX_NPC_CAPTURE_CONFIG. ++ */ ++union nixx_af_tx_npc_capture_respx { ++ u64 u; ++ struct nixx_af_tx_npc_capture_respx_s { ++ u64 data : 64; ++ } s; ++ /* struct nixx_af_tx_npc_capture_respx_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TX_NPC_CAPTURE_RESPX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TX_NPC_CAPTURE_RESPX(u64 a) ++{ ++ return 0x680 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tx_tstmp_cfg ++ * ++ * NIX AF Transmit Timestamp Configuration Register ++ */ ++union nixx_af_tx_tstmp_cfg { ++ u64 u; ++ struct nixx_af_tx_tstmp_cfg_s { ++ u64 tstmp_wd_period : 4; ++ u64 reserved_4_7 : 4; ++ u64 express : 16; ++ u64 reserved_24_63 : 40; ++ } s; ++ /* struct nixx_af_tx_tstmp_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TX_TSTMP_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TX_TSTMP_CFG(void) ++{ ++ return 0xc0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tx_vtag_def#_ctl ++ * ++ * NIX AF Transmit Vtag Definition Control Registers The transmit Vtag ++ * definition table specifies Vtag layers (e.g. VLAN, E-TAG) to ++ * optionally insert or replace in the TX packet header. Indexed by ++ * NIX_TX_VTAG_ACTION_S[VTAG*_DEF]. ++ */ ++union nixx_af_tx_vtag_defx_ctl { ++ u64 u; ++ struct nixx_af_tx_vtag_defx_ctl_s { ++ u64 size : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_af_tx_vtag_defx_ctl_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TX_VTAG_DEFX_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TX_VTAG_DEFX_CTL(u64 a) ++{ ++ return 0x1a00 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_af_tx_vtag_def#_data ++ * ++ * NIX AF Transmit Vtag Definition Data Registers See ++ * NIX_AF_TX_VTAG_DEF()_CTL. ++ */ ++union nixx_af_tx_vtag_defx_data { ++ u64 u; ++ struct nixx_af_tx_vtag_defx_data_s { ++ u64 data : 64; ++ } s; ++ /* struct nixx_af_tx_vtag_defx_data_s cn; */ ++}; ++ ++static inline u64 NIXX_AF_TX_VTAG_DEFX_DATA(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_AF_TX_VTAG_DEFX_DATA(u64 a) ++{ ++ return 0x1a10 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_cfg ++ * ++ * NIX LF Configuration Register ++ */ ++union nixx_lf_cfg { ++ u64 u; ++ struct nixx_lf_cfg_s { ++ u64 tcp_timer_int_ena : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_lf_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_CFG(void) ++{ ++ return 0x100; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_cint#_cnt ++ * ++ * NIX LF Completion Interrupt Count Registers ++ */ ++union nixx_lf_cintx_cnt { ++ u64 u; ++ struct nixx_lf_cintx_cnt_s { ++ u64 ecount : 32; ++ u64 qcount : 16; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nixx_lf_cintx_cnt_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_CINTX_CNT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_CINTX_CNT(u64 a) ++{ ++ return 0xd00 + 0x1000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_cint#_ena_w1c ++ * ++ * NIX LF Completion Interrupt Enable Clear Registers This register ++ * clears interrupt enable bits. ++ */ ++union nixx_lf_cintx_ena_w1c { ++ u64 u; ++ struct nixx_lf_cintx_ena_w1c_s { ++ u64 intr : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_lf_cintx_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_CINTX_ENA_W1C(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_CINTX_ENA_W1C(u64 a) ++{ ++ return 0xd50 + 0x1000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_cint#_ena_w1s ++ * ++ * NIX LF Completion Interrupt Enable Set Registers This register sets ++ * interrupt enable bits. ++ */ ++union nixx_lf_cintx_ena_w1s { ++ u64 u; ++ struct nixx_lf_cintx_ena_w1s_s { ++ u64 intr : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_lf_cintx_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_CINTX_ENA_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_CINTX_ENA_W1S(u64 a) ++{ ++ return 0xd40 + 0x1000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_cint#_int ++ * ++ * NIX LF Completion Interrupt Registers ++ */ ++union nixx_lf_cintx_int { ++ u64 u; ++ struct nixx_lf_cintx_int_s { ++ u64 intr : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_lf_cintx_int_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_CINTX_INT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_CINTX_INT(u64 a) ++{ ++ return 0xd20 + 0x1000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_cint#_int_w1s ++ * ++ * NIX LF Completion Interrupt Set Registers This register sets interrupt ++ * bits. ++ */ ++union nixx_lf_cintx_int_w1s { ++ u64 u; ++ struct nixx_lf_cintx_int_w1s_s { ++ u64 intr : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_lf_cintx_int_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_CINTX_INT_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_CINTX_INT_W1S(u64 a) ++{ ++ return 0xd30 + 0x1000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_cint#_wait ++ * ++ * NIX LF Completion Interrupt Count Registers ++ */ ++union nixx_lf_cintx_wait { ++ u64 u; ++ struct nixx_lf_cintx_wait_s { ++ u64 ecount_wait : 32; ++ u64 qcount_wait : 16; ++ u64 time_wait : 8; ++ u64 reserved_56_63 : 8; ++ } s; ++ /* struct nixx_lf_cintx_wait_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_CINTX_WAIT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_CINTX_WAIT(u64 a) ++{ ++ return 0xd10 + 0x1000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_cq_op_door ++ * ++ * NIX LF CQ Doorbell Operation Register A write to this register ++ * dequeues CQEs from a CQ ring within the LF. A read is RAZ. RSL ++ * accesses to this register are RAZ/WI. ++ */ ++union nixx_lf_cq_op_door { ++ u64 u; ++ struct nixx_lf_cq_op_door_s { ++ u64 count : 16; ++ u64 reserved_16_31 : 16; ++ u64 cq : 20; ++ u64 reserved_52_63 : 12; ++ } s; ++ /* struct nixx_lf_cq_op_door_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_CQ_OP_DOOR(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_CQ_OP_DOOR(void) ++{ ++ return 0xb30; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_cq_op_int ++ * ++ * NIX LF Completion Queue Interrupt Operation Register A 64-bit atomic ++ * load-and-add to this register reads CQ interrupts and interrupt ++ * enables. A write optionally sets or clears interrupts and interrupt ++ * enables. A read is RAZ. RSL accesses to this register are RAZ/WI. ++ */ ++union nixx_lf_cq_op_int { ++ u64 u; ++ struct nixx_lf_cq_op_int_s { ++ u64 cq_err_int : 8; ++ u64 cq_err_int_ena : 8; ++ u64 reserved_16_41 : 26; ++ u64 op_err : 1; ++ u64 setop : 1; ++ u64 cq : 20; ++ } s; ++ /* struct nixx_lf_cq_op_int_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_CQ_OP_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_CQ_OP_INT(void) ++{ ++ return 0xb00; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_cq_op_status ++ * ++ * NIX LF Completion Queue Status Operation Register A 64-bit atomic ++ * load-and-add to this register reads NIX_CQ_CTX_S[HEAD,TAIL]. The ++ * atomic write data has format NIX_OP_Q_WDATA_S and selects the CQ ++ * within LF. All other accesses to this register (e.g. reads and ++ * writes) are RAZ/WI. RSL accesses to this register are RAZ/WI. ++ */ ++union nixx_lf_cq_op_status { ++ u64 u; ++ struct nixx_lf_cq_op_status_s { ++ u64 tail : 20; ++ u64 head : 20; ++ u64 reserved_40_45 : 6; ++ u64 cq_err : 1; ++ u64 reserved_47_62 : 16; ++ u64 op_err : 1; ++ } s; ++ /* struct nixx_lf_cq_op_status_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_CQ_OP_STATUS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_CQ_OP_STATUS(void) ++{ ++ return 0xb40; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_err_int ++ * ++ * NIX LF Error Interrupt Register ++ */ ++union nixx_lf_err_int { ++ u64 u; ++ struct nixx_lf_err_int_s { ++ u64 sqb_fault : 1; ++ u64 sq_ctx_fault : 1; ++ u64 rq_ctx_fault : 1; ++ u64 cq_ctx_fault : 1; ++ u64 reserved_4 : 1; ++ u64 rsse_fault : 1; ++ u64 ipsec_dyno_fault : 1; ++ u64 sq_disabled : 1; ++ u64 sq_oor : 1; ++ u64 send_jump_fault : 1; ++ u64 send_sg_fault : 1; ++ u64 rq_disabled : 1; ++ u64 rq_oor : 1; ++ u64 rx_wqe_fault : 1; ++ u64 rss_err : 1; ++ u64 reserved_15_19 : 5; ++ u64 dyno_err : 1; ++ u64 reserved_21_23 : 3; ++ u64 cq_disabled : 1; ++ u64 cq_oor : 1; ++ u64 reserved_26_27 : 2; ++ u64 qint_fault : 1; ++ u64 cint_fault : 1; ++ u64 reserved_30_63 : 34; ++ } s; ++ /* struct nixx_lf_err_int_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_ERR_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_ERR_INT(void) ++{ ++ return 0x220; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_err_int_ena_w1c ++ * ++ * NIX LF Error Interrupt Enable Clear Register This register clears ++ * interrupt enable bits. ++ */ ++union nixx_lf_err_int_ena_w1c { ++ u64 u; ++ struct nixx_lf_err_int_ena_w1c_s { ++ u64 sqb_fault : 1; ++ u64 sq_ctx_fault : 1; ++ u64 rq_ctx_fault : 1; ++ u64 cq_ctx_fault : 1; ++ u64 reserved_4 : 1; ++ u64 rsse_fault : 1; ++ u64 ipsec_dyno_fault : 1; ++ u64 sq_disabled : 1; ++ u64 sq_oor : 1; ++ u64 send_jump_fault : 1; ++ u64 send_sg_fault : 1; ++ u64 rq_disabled : 1; ++ u64 rq_oor : 1; ++ u64 rx_wqe_fault : 1; ++ u64 rss_err : 1; ++ u64 reserved_15_19 : 5; ++ u64 dyno_err : 1; ++ u64 reserved_21_23 : 3; ++ u64 cq_disabled : 1; ++ u64 cq_oor : 1; ++ u64 reserved_26_27 : 2; ++ u64 qint_fault : 1; ++ u64 cint_fault : 1; ++ u64 reserved_30_63 : 34; ++ } s; ++ /* struct nixx_lf_err_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_ERR_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_ERR_INT_ENA_W1C(void) ++{ ++ return 0x230; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_err_int_ena_w1s ++ * ++ * NIX LF Error Interrupt Enable Set Register This register sets ++ * interrupt enable bits. ++ */ ++union nixx_lf_err_int_ena_w1s { ++ u64 u; ++ struct nixx_lf_err_int_ena_w1s_s { ++ u64 sqb_fault : 1; ++ u64 sq_ctx_fault : 1; ++ u64 rq_ctx_fault : 1; ++ u64 cq_ctx_fault : 1; ++ u64 reserved_4 : 1; ++ u64 rsse_fault : 1; ++ u64 ipsec_dyno_fault : 1; ++ u64 sq_disabled : 1; ++ u64 sq_oor : 1; ++ u64 send_jump_fault : 1; ++ u64 send_sg_fault : 1; ++ u64 rq_disabled : 1; ++ u64 rq_oor : 1; ++ u64 rx_wqe_fault : 1; ++ u64 rss_err : 1; ++ u64 reserved_15_19 : 5; ++ u64 dyno_err : 1; ++ u64 reserved_21_23 : 3; ++ u64 cq_disabled : 1; ++ u64 cq_oor : 1; ++ u64 reserved_26_27 : 2; ++ u64 qint_fault : 1; ++ u64 cint_fault : 1; ++ u64 reserved_30_63 : 34; ++ } s; ++ /* struct nixx_lf_err_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_ERR_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_ERR_INT_ENA_W1S(void) ++{ ++ return 0x238; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_err_int_w1s ++ * ++ * NIX LF Error Interrupt Set Register This register sets interrupt bits. ++ */ ++union nixx_lf_err_int_w1s { ++ u64 u; ++ struct nixx_lf_err_int_w1s_s { ++ u64 sqb_fault : 1; ++ u64 sq_ctx_fault : 1; ++ u64 rq_ctx_fault : 1; ++ u64 cq_ctx_fault : 1; ++ u64 reserved_4 : 1; ++ u64 rsse_fault : 1; ++ u64 ipsec_dyno_fault : 1; ++ u64 sq_disabled : 1; ++ u64 sq_oor : 1; ++ u64 send_jump_fault : 1; ++ u64 send_sg_fault : 1; ++ u64 rq_disabled : 1; ++ u64 rq_oor : 1; ++ u64 rx_wqe_fault : 1; ++ u64 rss_err : 1; ++ u64 reserved_15_19 : 5; ++ u64 dyno_err : 1; ++ u64 reserved_21_23 : 3; ++ u64 cq_disabled : 1; ++ u64 cq_oor : 1; ++ u64 reserved_26_27 : 2; ++ u64 qint_fault : 1; ++ u64 cint_fault : 1; ++ u64 reserved_30_63 : 34; ++ } s; ++ /* struct nixx_lf_err_int_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_ERR_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_ERR_INT_W1S(void) ++{ ++ return 0x228; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_gint ++ * ++ * NIX LF General Interrupt Register ++ */ ++union nixx_lf_gint { ++ u64 u; ++ struct nixx_lf_gint_s { ++ u64 drop : 1; ++ u64 tcp_timer : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct nixx_lf_gint_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_GINT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_GINT(void) ++{ ++ return 0x200; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_gint_ena_w1c ++ * ++ * NIX LF General Interrupt Enable Clear Register This register clears ++ * interrupt enable bits. ++ */ ++union nixx_lf_gint_ena_w1c { ++ u64 u; ++ struct nixx_lf_gint_ena_w1c_s { ++ u64 drop : 1; ++ u64 tcp_timer : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct nixx_lf_gint_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_GINT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_GINT_ENA_W1C(void) ++{ ++ return 0x210; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_gint_ena_w1s ++ * ++ * NIX LF General Interrupt Enable Set Register This register sets ++ * interrupt enable bits. ++ */ ++union nixx_lf_gint_ena_w1s { ++ u64 u; ++ struct nixx_lf_gint_ena_w1s_s { ++ u64 drop : 1; ++ u64 tcp_timer : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct nixx_lf_gint_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_GINT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_GINT_ENA_W1S(void) ++{ ++ return 0x218; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_gint_w1s ++ * ++ * NIX LF General Interrupt Set Register This register sets interrupt ++ * bits. ++ */ ++union nixx_lf_gint_w1s { ++ u64 u; ++ struct nixx_lf_gint_w1s_s { ++ u64 drop : 1; ++ u64 tcp_timer : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct nixx_lf_gint_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_GINT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_GINT_W1S(void) ++{ ++ return 0x208; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_mnq_err_dbg ++ * ++ * NIX LF Meta-descriptor Enqueue Error Debug Register This register ++ * captures debug info for an error detected during send meta-descriptor ++ * enqueue from an SQ to an SMQ. Hardware sets [VALID] when the debug ++ * info is captured, and subsequent errors are not captured until ++ * software clears [VALID] by writing a one to it. ++ */ ++union nixx_lf_mnq_err_dbg { ++ u64 u; ++ struct nixx_lf_mnq_err_dbg_s { ++ u64 errcode : 8; ++ u64 sq : 20; ++ u64 sqe_id : 16; ++ u64 valid : 1; ++ u64 reserved_45_63 : 19; ++ } s; ++ /* struct nixx_lf_mnq_err_dbg_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_MNQ_ERR_DBG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_MNQ_ERR_DBG(void) ++{ ++ return 0x270; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_op_ipsec_dyno_cnt ++ * ++ * INTERNAL: NIX LF IPSEC Dynamic Ordering Counter Operation Register ++ * Internal: Not used; no IPSEC fast-path. All accesses are RAZ/WI. ++ */ ++union nixx_lf_op_ipsec_dyno_cnt { ++ u64 u; ++ struct nixx_lf_op_ipsec_dyno_cnt_s { ++ u64 count : 32; ++ u64 reserved_32_46 : 15; ++ u64 storeop : 1; ++ u64 dyno_sel : 15; ++ u64 op_err : 1; ++ } s; ++ /* struct nixx_lf_op_ipsec_dyno_cnt_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_OP_IPSEC_DYNO_CNT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_OP_IPSEC_DYNO_CNT(void) ++{ ++ return 0x980; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_op_send# ++ * ++ * NIX LF Send Operation Registers An LMTST (or large store from CPT) to ++ * this address enqueues one or more SQEs to a send queue. ++ * NIX_SEND_HDR_S[SQ] in the first SQE selects the send queue.The maximum ++ * size of each SQE is specified by NIX_SQ_CTX_S[MAX_SQE_SIZE]. A read ++ * to this address is RAZ. An RSL access to this address will fault. ++ * The endianness of the instruction write data is controlled by ++ * NIX_AF_LF()_CFG[BE]. When a NIX_SEND_JUMP_S is not present in the ++ * SQE, the SQE consists of the entire send descriptor. When a ++ * NIX_SEND_JUMP_S is present in the SQE, the SQE must contain exactly ++ * the portion of the send descriptor up to and including the ++ * NIX_SEND_JUMP_S, and the remainder of the send descriptor must be at ++ * LF IOVA NIX_SEND_JUMP_S[ADDR] in LLC/DRAM. Software must ensure that ++ * all LLC/DRAM locations that will be referenced by NIX while processing ++ * this descriptor, including all packet data and post-jump ++ * subdescriptors contain the latest updates before issuing the LMTST. A ++ * DMB instruction may be required prior to the LMTST to ensure this. A ++ * DMB following the LMTST may be useful if SQ descriptor ordering ++ * matters and more than one CPU core is simultaneously enqueueing to the ++ * same SQ. ++ */ ++union nixx_lf_op_sendx { ++ u64 u; ++ struct nixx_lf_op_sendx_s { ++ u64 data : 64; ++ } s; ++ /* struct nixx_lf_op_sendx_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_OP_SENDX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_OP_SENDX(u64 a) ++{ ++ return 0x800 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_qint#_cnt ++ * ++ * NIX LF Queue Interrupt Count Registers ++ */ ++union nixx_lf_qintx_cnt { ++ u64 u; ++ struct nixx_lf_qintx_cnt_s { ++ u64 count : 22; ++ u64 reserved_22_63 : 42; ++ } s; ++ /* struct nixx_lf_qintx_cnt_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_QINTX_CNT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_QINTX_CNT(u64 a) ++{ ++ return 0xc00 + 0x1000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_qint#_ena_w1c ++ * ++ * NIX LF Queue Interrupt Enable Clear Registers This register clears ++ * interrupt enable bits. ++ */ ++union nixx_lf_qintx_ena_w1c { ++ u64 u; ++ struct nixx_lf_qintx_ena_w1c_s { ++ u64 intr : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_lf_qintx_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_QINTX_ENA_W1C(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_QINTX_ENA_W1C(u64 a) ++{ ++ return 0xc30 + 0x1000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_qint#_ena_w1s ++ * ++ * NIX LF Queue Interrupt Enable Set Registers This register sets ++ * interrupt enable bits. ++ */ ++union nixx_lf_qintx_ena_w1s { ++ u64 u; ++ struct nixx_lf_qintx_ena_w1s_s { ++ u64 intr : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_lf_qintx_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_QINTX_ENA_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_QINTX_ENA_W1S(u64 a) ++{ ++ return 0xc20 + 0x1000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_qint#_int ++ * ++ * NIX LF Queue Interrupt Registers ++ */ ++union nixx_lf_qintx_int { ++ u64 u; ++ struct nixx_lf_qintx_int_s { ++ u64 intr : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_lf_qintx_int_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_QINTX_INT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_QINTX_INT(u64 a) ++{ ++ return 0xc10 + 0x1000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_qint#_int_w1s ++ * ++ * INTERNAL: NIX LF Queue Interrupt Set Registers ++ */ ++union nixx_lf_qintx_int_w1s { ++ u64 u; ++ struct nixx_lf_qintx_int_w1s_s { ++ u64 intr : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct nixx_lf_qintx_int_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_QINTX_INT_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_QINTX_INT_W1S(u64 a) ++{ ++ return 0xc18 + 0x1000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_ras ++ * ++ * NIX LF RAS Interrupt Register ++ */ ++union nixx_lf_ras { ++ u64 u; ++ struct nixx_lf_ras_s { ++ u64 sqb_poison : 1; ++ u64 sq_ctx_poison : 1; ++ u64 rq_ctx_poison : 1; ++ u64 cq_ctx_poison : 1; ++ u64 reserved_4 : 1; ++ u64 rsse_poison : 1; ++ u64 ipsec_dyno_poison : 1; ++ u64 send_jump_poison : 1; ++ u64 send_sg_poison : 1; ++ u64 qint_poison : 1; ++ u64 cint_poison : 1; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct nixx_lf_ras_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_RAS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_RAS(void) ++{ ++ return 0x240; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_ras_ena_w1c ++ * ++ * NIX LF RAS Interrupt Enable Clear Register This register clears ++ * interrupt enable bits. ++ */ ++union nixx_lf_ras_ena_w1c { ++ u64 u; ++ struct nixx_lf_ras_ena_w1c_s { ++ u64 sqb_poison : 1; ++ u64 sq_ctx_poison : 1; ++ u64 rq_ctx_poison : 1; ++ u64 cq_ctx_poison : 1; ++ u64 reserved_4 : 1; ++ u64 rsse_poison : 1; ++ u64 ipsec_dyno_poison : 1; ++ u64 send_jump_poison : 1; ++ u64 send_sg_poison : 1; ++ u64 qint_poison : 1; ++ u64 cint_poison : 1; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct nixx_lf_ras_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_RAS_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_RAS_ENA_W1C(void) ++{ ++ return 0x250; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_ras_ena_w1s ++ * ++ * NIX LF RAS Interrupt Enable Set Register This register sets interrupt ++ * enable bits. ++ */ ++union nixx_lf_ras_ena_w1s { ++ u64 u; ++ struct nixx_lf_ras_ena_w1s_s { ++ u64 sqb_poison : 1; ++ u64 sq_ctx_poison : 1; ++ u64 rq_ctx_poison : 1; ++ u64 cq_ctx_poison : 1; ++ u64 reserved_4 : 1; ++ u64 rsse_poison : 1; ++ u64 ipsec_dyno_poison : 1; ++ u64 send_jump_poison : 1; ++ u64 send_sg_poison : 1; ++ u64 qint_poison : 1; ++ u64 cint_poison : 1; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct nixx_lf_ras_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_RAS_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_RAS_ENA_W1S(void) ++{ ++ return 0x258; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_ras_w1s ++ * ++ * NIX LF RAS Interrupt Set Register This register sets interrupt bits. ++ */ ++union nixx_lf_ras_w1s { ++ u64 u; ++ struct nixx_lf_ras_w1s_s { ++ u64 sqb_poison : 1; ++ u64 sq_ctx_poison : 1; ++ u64 rq_ctx_poison : 1; ++ u64 cq_ctx_poison : 1; ++ u64 reserved_4 : 1; ++ u64 rsse_poison : 1; ++ u64 ipsec_dyno_poison : 1; ++ u64 send_jump_poison : 1; ++ u64 send_sg_poison : 1; ++ u64 qint_poison : 1; ++ u64 cint_poison : 1; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct nixx_lf_ras_w1s_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_RAS_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_RAS_W1S(void) ++{ ++ return 0x248; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_rq_op_drop_octs ++ * ++ * NIX LF Receive Queue Dropped Octets Operation Register A 64-bit atomic ++ * load-and-add to this register reads NIX_RQ_CTX_S[DROP_OCTS]. The ++ * atomic write data has format NIX_OP_Q_WDATA_S and selects the RQ ++ * within LF. All other accesses to this register (e.g. reads and ++ * writes) are RAZ/WI. RSL accesses to this register are RAZ/WI. ++ */ ++union nixx_lf_rq_op_drop_octs { ++ u64 u; ++ struct nixx_lf_rq_op_drop_octs_s { ++ u64 cnt : 48; ++ u64 reserved_48_62 : 15; ++ u64 op_err : 1; ++ } s; ++ /* struct nixx_lf_rq_op_drop_octs_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_RQ_OP_DROP_OCTS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_RQ_OP_DROP_OCTS(void) ++{ ++ return 0x930; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_rq_op_drop_pkts ++ * ++ * NIX LF Receive Queue Dropped Packets Operation Register A 64-bit ++ * atomic load-and-add to this register reads NIX_RQ_CTX_S[DROP_PKTS]. ++ * The atomic write data has format NIX_OP_Q_WDATA_S and selects the RQ ++ * within LF. All other accesses to this register (e.g. reads and ++ * writes) are RAZ/WI. RSL accesses to this register are RAZ/WI. ++ */ ++union nixx_lf_rq_op_drop_pkts { ++ u64 u; ++ struct nixx_lf_rq_op_drop_pkts_s { ++ u64 cnt : 48; ++ u64 reserved_48_62 : 15; ++ u64 op_err : 1; ++ } s; ++ /* struct nixx_lf_rq_op_drop_pkts_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_RQ_OP_DROP_PKTS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_RQ_OP_DROP_PKTS(void) ++{ ++ return 0x940; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_rq_op_int ++ * ++ * NIX LF Receive Queue Interrupt Operation Register A 64-bit atomic ++ * load-and-add to this register reads RQ interrupts and interrupt ++ * enables. A 64-bit write optionally sets or clears interrupts and ++ * interrupt enables. All other accesses to this register (e.g. reads, ++ * 128-bit accesses) are RAZ/WI. RSL accesses to this register are ++ * RAZ/WI. ++ */ ++union nixx_lf_rq_op_int { ++ u64 u; ++ struct nixx_lf_rq_op_int_s { ++ u64 rq_int : 8; ++ u64 rq_int_ena : 8; ++ u64 reserved_16_41 : 26; ++ u64 op_err : 1; ++ u64 setop : 1; ++ u64 rq : 20; ++ } s; ++ /* struct nixx_lf_rq_op_int_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_RQ_OP_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_RQ_OP_INT(void) ++{ ++ return 0x900; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_rq_op_octs ++ * ++ * NIX LF Receive Queue Octets Operation Register A 64-bit atomic load- ++ * and-add to this register reads NIX_RQ_CTX_S[OCTS]. The atomic write ++ * data has format NIX_OP_Q_WDATA_S and selects the RQ within LF. All ++ * other accesses to this register (e.g. reads and writes) are RAZ/WI. ++ * RSL accesses to this register are RAZ/WI. ++ */ ++union nixx_lf_rq_op_octs { ++ u64 u; ++ struct nixx_lf_rq_op_octs_s { ++ u64 cnt : 48; ++ u64 reserved_48_62 : 15; ++ u64 op_err : 1; ++ } s; ++ /* struct nixx_lf_rq_op_octs_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_RQ_OP_OCTS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_RQ_OP_OCTS(void) ++{ ++ return 0x910; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_rq_op_pkts ++ * ++ * NIX LF Receive Queue Packets Operation Register A 64-bit atomic load- ++ * and-add to this register reads NIX_RQ_CTX_S[PKTS]. The atomic write ++ * data has format NIX_OP_Q_WDATA_S and selects the RQ within LF. All ++ * other accesses to this register (e.g. reads and writes) are RAZ/WI. ++ * RSL accesses to this register are RAZ/WI. ++ */ ++union nixx_lf_rq_op_pkts { ++ u64 u; ++ struct nixx_lf_rq_op_pkts_s { ++ u64 cnt : 48; ++ u64 reserved_48_62 : 15; ++ u64 op_err : 1; ++ } s; ++ /* struct nixx_lf_rq_op_pkts_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_RQ_OP_PKTS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_RQ_OP_PKTS(void) ++{ ++ return 0x920; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_rq_op_re_pkts ++ * ++ * NIX LF Receive Queue Errored Packets Operation Register A 64-bit ++ * atomic load-and-add to this register reads NIX_RQ_CTX_S[RE_PKTS]. The ++ * atomic write data has format NIX_OP_Q_WDATA_S and selects the RQ ++ * within LF. All other accesses to this register (e.g. reads and ++ * writes) are RAZ/WI. RSL accesses to this register are RAZ/WI. ++ */ ++union nixx_lf_rq_op_re_pkts { ++ u64 u; ++ struct nixx_lf_rq_op_re_pkts_s { ++ u64 cnt : 48; ++ u64 reserved_48_62 : 15; ++ u64 op_err : 1; ++ } s; ++ /* struct nixx_lf_rq_op_re_pkts_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_RQ_OP_RE_PKTS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_RQ_OP_RE_PKTS(void) ++{ ++ return 0x950; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_rx_secret# ++ * ++ * NIX LF Receive Secret Key Registers ++ */ ++union nixx_lf_rx_secretx { ++ u64 u; ++ struct nixx_lf_rx_secretx_s { ++ u64 key : 64; ++ } s; ++ /* struct nixx_lf_rx_secretx_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_RX_SECRETX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_RX_SECRETX(u64 a) ++{ ++ return 0 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_rx_stat# ++ * ++ * NIX LF Receive Statistics Registers The last dimension indicates which ++ * statistic, and is enumerated by NIX_STAT_LF_RX_E. ++ */ ++union nixx_lf_rx_statx { ++ u64 u; ++ struct nixx_lf_rx_statx_s { ++ u64 stat : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nixx_lf_rx_statx_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_RX_STATX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_RX_STATX(u64 a) ++{ ++ return 0x400 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_send_err_dbg ++ * ++ * NIX LF Send Error Debug Register This register captures debug info an ++ * error detected on packet send after a meta-descriptor is granted by ++ * PSE. Hardware sets [VALID] when the debug info is captured, and ++ * subsequent errors are not captured until software clears [VALID] by ++ * writing a one to it. ++ */ ++union nixx_lf_send_err_dbg { ++ u64 u; ++ struct nixx_lf_send_err_dbg_s { ++ u64 errcode : 8; ++ u64 sq : 20; ++ u64 sqe_id : 16; ++ u64 valid : 1; ++ u64 reserved_45_63 : 19; ++ } s; ++ /* struct nixx_lf_send_err_dbg_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_SEND_ERR_DBG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_SEND_ERR_DBG(void) ++{ ++ return 0x280; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_sq_op_drop_octs ++ * ++ * NIX LF Send Queue Dropped Octets Operation Register A 64-bit atomic ++ * load-and-add to this register reads NIX_SQ_CTX_S[DROP_OCTS]. The ++ * atomic write data has format NIX_OP_Q_WDATA_S and selects the SQ ++ * within LF. All other accesses to this register (e.g. reads and ++ * writes) are RAZ/WI. RSL accesses to this register are RAZ/WI. ++ */ ++union nixx_lf_sq_op_drop_octs { ++ u64 u; ++ struct nixx_lf_sq_op_drop_octs_s { ++ u64 cnt : 48; ++ u64 reserved_48_62 : 15; ++ u64 op_err : 1; ++ } s; ++ /* struct nixx_lf_sq_op_drop_octs_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_SQ_OP_DROP_OCTS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_SQ_OP_DROP_OCTS(void) ++{ ++ return 0xa40; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_sq_op_drop_pkts ++ * ++ * NIX LF Send Queue Dropped Packets Operation Register A 64-bit atomic ++ * load-and-add to this register reads NIX_SQ_CTX_S[DROP_PKTS]. The ++ * atomic write data has format NIX_OP_Q_WDATA_S and selects the SQ ++ * within LF. All other accesses to this register (e.g. reads and ++ * writes) are RAZ/WI. RSL accesses to this register are RAZ/WI. ++ */ ++union nixx_lf_sq_op_drop_pkts { ++ u64 u; ++ struct nixx_lf_sq_op_drop_pkts_s { ++ u64 cnt : 48; ++ u64 reserved_48_62 : 15; ++ u64 op_err : 1; ++ } s; ++ /* struct nixx_lf_sq_op_drop_pkts_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_SQ_OP_DROP_PKTS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_SQ_OP_DROP_PKTS(void) ++{ ++ return 0xa50; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_sq_op_err_dbg ++ * ++ * NIX LF SQ Operation Error Debug Register This register captures debug ++ * info for an error detected on LMT store to NIX_LF_OP_SEND() or when a ++ * NIX_LF_SQ_OP_* register is accessed. Hardware sets [VALID] when the ++ * debug info is captured, and subsequent errors are not captured until ++ * software clears [VALID] by writing a one to it. ++ */ ++union nixx_lf_sq_op_err_dbg { ++ u64 u; ++ struct nixx_lf_sq_op_err_dbg_s { ++ u64 errcode : 8; ++ u64 sq : 20; ++ u64 sqe_id : 16; ++ u64 valid : 1; ++ u64 reserved_45_63 : 19; ++ } s; ++ /* struct nixx_lf_sq_op_err_dbg_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_SQ_OP_ERR_DBG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_SQ_OP_ERR_DBG(void) ++{ ++ return 0x260; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_sq_op_int ++ * ++ * NIX LF Send Queue Interrupt Operation Register A 64-bit atomic load- ++ * and-add to this register reads SQ interrupts, interrupt enables and ++ * XOFF status. A write optionally sets or clears interrupts, interrupt ++ * enables and XOFF status. A read is RAZ. RSL accesses to this register ++ * are RAZ/WI. ++ */ ++union nixx_lf_sq_op_int { ++ u64 u; ++ struct nixx_lf_sq_op_int_s { ++ u64 sq_int : 8; ++ u64 sq_int_ena : 8; ++ u64 xoff : 1; ++ u64 reserved_17_41 : 25; ++ u64 op_err : 1; ++ u64 setop : 1; ++ u64 sq : 20; ++ } s; ++ /* struct nixx_lf_sq_op_int_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_SQ_OP_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_SQ_OP_INT(void) ++{ ++ return 0xa00; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_sq_op_octs ++ * ++ * NIX LF Send Queue Octets Operation Register A 64-bit atomic load-and- ++ * add to this register reads NIX_SQ_CTX_S[OCTS]. The atomic write data ++ * has format NIX_OP_Q_WDATA_S and selects the SQ within LF. All other ++ * accesses to this register (e.g. reads and writes) are RAZ/WI. RSL ++ * accesses to this register are RAZ/WI. ++ */ ++union nixx_lf_sq_op_octs { ++ u64 u; ++ struct nixx_lf_sq_op_octs_s { ++ u64 cnt : 48; ++ u64 reserved_48_62 : 15; ++ u64 op_err : 1; ++ } s; ++ /* struct nixx_lf_sq_op_octs_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_SQ_OP_OCTS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_SQ_OP_OCTS(void) ++{ ++ return 0xa10; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_sq_op_pkts ++ * ++ * NIX LF Send Queue Packets Operation Register A 64-bit atomic load-and- ++ * add to this register reads NIX_SQ_CTX_S[PKTS]. The atomic write data ++ * has format NIX_OP_Q_WDATA_S and selects the SQ within LF. All other ++ * accesses to this register (e.g. reads and writes) are RAZ/WI. RSL ++ * accesses to this register are RAZ/WI. ++ */ ++union nixx_lf_sq_op_pkts { ++ u64 u; ++ struct nixx_lf_sq_op_pkts_s { ++ u64 cnt : 48; ++ u64 reserved_48_62 : 15; ++ u64 op_err : 1; ++ } s; ++ /* struct nixx_lf_sq_op_pkts_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_SQ_OP_PKTS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_SQ_OP_PKTS(void) ++{ ++ return 0xa20; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_sq_op_status ++ * ++ * NIX LF Send Queue Status Operation Register A 64-bit atomic load-and- ++ * add to this register reads status fields in NIX_SQ_CTX_S. The atomic ++ * write data has format NIX_OP_Q_WDATA_S and selects the SQ within LF. ++ * Completion of the load-and-add operation also ensures that all ++ * previously issued LMT stores to NIX_LF_OP_SEND() have completed. All ++ * other accesses to this register (e.g. reads and writes) are RAZ/WI. ++ * RSL accesses to this register are RAZ/WI. ++ */ ++union nixx_lf_sq_op_status { ++ u64 u; ++ struct nixx_lf_sq_op_status_s { ++ u64 sqb_count : 16; ++ u64 reserved_16_19 : 4; ++ u64 head_offset : 6; ++ u64 reserved_26_27 : 2; ++ u64 tail_offset : 6; ++ u64 reserved_34_62 : 29; ++ u64 op_err : 1; ++ } s; ++ struct nixx_lf_sq_op_status_cn { ++ u64 sqb_count : 16; ++ u64 reserved_16_19 : 4; ++ u64 head_offset : 6; ++ u64 reserved_26_27 : 2; ++ u64 tail_offset : 6; ++ u64 reserved_34_35 : 2; ++ u64 reserved_36_62 : 27; ++ u64 op_err : 1; ++ } cn; ++}; ++ ++static inline u64 NIXX_LF_SQ_OP_STATUS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_SQ_OP_STATUS(void) ++{ ++ return 0xa30; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) nix#_lf_tx_stat# ++ * ++ * NIX LF Transmit Statistics Registers The last dimension indicates ++ * which statistic, and is enumerated by NIX_STAT_LF_TX_E. ++ */ ++union nixx_lf_tx_statx { ++ u64 u; ++ struct nixx_lf_tx_statx_s { ++ u64 stat : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct nixx_lf_tx_statx_s cn; */ ++}; ++ ++static inline u64 NIXX_LF_TX_STATX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_LF_TX_STATX(u64 a) ++{ ++ return 0x300 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_priv_af_int_cfg ++ * ++ * NIX Privileged Admin Function Interrupt Configuration Register ++ */ ++union nixx_priv_af_int_cfg { ++ u64 u; ++ struct nixx_priv_af_int_cfg_s { ++ u64 msix_offset : 11; ++ u64 reserved_11 : 1; ++ u64 msix_size : 8; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct nixx_priv_af_int_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_PRIV_AF_INT_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_PRIV_AF_INT_CFG(void) ++{ ++ return 0x8000000; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_priv_lf#_cfg ++ * ++ * NIX Privileged Local Function Configuration Registers These registers ++ * allow each NIX local function (LF) to be provisioned to a VF/PF for ++ * RVU. See also NIX_AF_RVU_LF_CFG_DEBUG. Software should read this ++ * register after write to ensure that the LF is mapped to [PF_FUNC] ++ * before issuing transactions to the mapped PF and function. [SLOT] ++ * must be zero. Internal: Hardware ignores [SLOT] and always assumes ++ * 0x0. ++ */ ++union nixx_priv_lfx_cfg { ++ u64 u; ++ struct nixx_priv_lfx_cfg_s { ++ u64 slot : 8; ++ u64 pf_func : 16; ++ u64 reserved_24_62 : 39; ++ u64 ena : 1; ++ } s; ++ /* struct nixx_priv_lfx_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_PRIV_LFX_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_PRIV_LFX_CFG(u64 a) ++{ ++ return 0x8000010 + 0x100 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) nix#_priv_lf#_int_cfg ++ * ++ * NIX Privileged LF Interrupt Configuration Registers ++ */ ++union nixx_priv_lfx_int_cfg { ++ u64 u; ++ struct nixx_priv_lfx_int_cfg_s { ++ u64 msix_offset : 11; ++ u64 reserved_11 : 1; ++ u64 msix_size : 8; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct nixx_priv_lfx_int_cfg_s cn; */ ++}; ++ ++static inline u64 NIXX_PRIV_LFX_INT_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NIXX_PRIV_LFX_INT_CFG(u64 a) ++{ ++ return 0x8000020 + 0x100 * a; ++} ++ ++#endif /* __CSRS_NIX_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx2/csrs/csrs-npa.h b/arch/arm/include/asm/arch-octeontx2/csrs/csrs-npa.h +new file mode 100644 +index 0000000000..19bea0ccd9 +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx2/csrs/csrs-npa.h +@@ -0,0 +1,2298 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++#ifndef __CSRS_NPA_H__ ++#define __CSRS_NPA_H__ ++ ++/** ++ * @file ++ * ++ * Configuration and status register (CSR) address and type definitions for ++ * NPA. ++ * ++ * This file is auto generated. Do not edit. ++ * ++ */ ++ ++/** ++ * Enumeration npa_af_int_vec_e ++ * ++ * NPA Admin Function Interrupt Vector Enumeration Enumerates the NPA AF ++ * MSI-X interrupt vectors. ++ */ ++#define NPA_AF_INT_VEC_E_AF_ERR (3) ++#define NPA_AF_INT_VEC_E_AQ_DONE (2) ++#define NPA_AF_INT_VEC_E_GEN (1) ++#define NPA_AF_INT_VEC_E_POISON (4) ++#define NPA_AF_INT_VEC_E_RVU (0) ++ ++/** ++ * Enumeration npa_aq_comp_e ++ * ++ * NPA Admin Queue Completion Enumeration Enumerates the values of ++ * NPA_AQ_RES_S[COMPCODE]. ++ */ ++#define NPA_AQ_COMP_E_CTX_FAULT (4) ++#define NPA_AQ_COMP_E_CTX_POISON (3) ++#define NPA_AQ_COMP_E_GOOD (1) ++#define NPA_AQ_COMP_E_LOCKERR (5) ++#define NPA_AQ_COMP_E_NOTDONE (0) ++#define NPA_AQ_COMP_E_SWERR (2) ++ ++/** ++ * Enumeration npa_aq_ctype_e ++ * ++ * NPA Admin Queue Context Type Enumeration Enumerates ++ * NPA_AQ_INST_S[CTYPE] values. ++ */ ++#define NPA_AQ_CTYPE_E_AURA (0) ++#define NPA_AQ_CTYPE_E_POOL (1) ++ ++/** ++ * Enumeration npa_aq_instop_e ++ * ++ * NPA Admin Queue Opcode Enumeration Enumerates NPA_AQ_INST_S[OP] ++ * values. ++ */ ++#define NPA_AQ_INSTOP_E_INIT (1) ++#define NPA_AQ_INSTOP_E_LOCK (4) ++#define NPA_AQ_INSTOP_E_NOP (0) ++#define NPA_AQ_INSTOP_E_READ (3) ++#define NPA_AQ_INSTOP_E_UNLOCK (5) ++#define NPA_AQ_INSTOP_E_WRITE (2) ++ ++/** ++ * Enumeration npa_aura_err_int_e ++ * ++ * NPA Aura Error Interrupt Enumeration Enumerates the bit index of ++ * NPA_AURA_S[ERR_INT], and NPA_AURA_S[ERR_INT_ENA]. ++ */ ++#define NPA_AURA_ERR_INT_E_AURA_ADD_OVER (1) ++#define NPA_AURA_ERR_INT_E_AURA_ADD_UNDER (2) ++#define NPA_AURA_ERR_INT_E_AURA_FREE_UNDER (0) ++#define NPA_AURA_ERR_INT_E_POOL_DIS (3) ++#define NPA_AURA_ERR_INT_E_RX(a) (0 + (a)) ++ ++/** ++ * Enumeration npa_bpintf_e ++ * ++ * NPA Backpressure Interface Enumeration Enumerates index of ++ * NPA_AURA_S[BP_ENA]. ++ */ ++#define NPA_BPINTF_E_NIXX_RX(a) (0 + (a)) ++ ++/** ++ * Enumeration npa_inpq_e ++ * ++ * NPA Input Queue Enumeration Enumerates ALLOC/FREE input queues from ++ * coprocessors. ++ */ ++#define NPA_INPQ_E_AURA_OP (0xe) ++#define NPA_INPQ_E_BPHY (7) ++#define NPA_INPQ_E_DPI (6) ++#define NPA_INPQ_E_DPI0 (6) ++#define NPA_INPQ_E_DPI1 (7) ++#define NPA_INPQ_E_INTERNAL_RSV (0xf) ++#define NPA_INPQ_E_NIXX_RX(a) (0 + 2 * (a)) ++#define NPA_INPQ_E_NIXX_TX(a) (1 + 2 * (a)) ++#define NPA_INPQ_E_RX(a) (0 + (a)) ++#define NPA_INPQ_E_SSO (4) ++#define NPA_INPQ_E_TIM (5) ++ ++/** ++ * Enumeration npa_lf_int_vec_e ++ * ++ * NPA Local Function Interrupt Vector Enumeration Enumerates the NPA ++ * MSI-X interrupt vectors per LF. ++ */ ++#define NPA_LF_INT_VEC_E_ERR_INT (0x40) ++#define NPA_LF_INT_VEC_E_POISON (0x41) ++#define NPA_LF_INT_VEC_E_QINTX(a) (0 + (a)) ++ ++/** ++ * Enumeration npa_ndc0_port_e ++ * ++ * NPA NDC0 Port Enumeration Enumerates NPA NDC0 (NDC_IDX_E::NPA_U(0)) ++ * ports and the PORT index of NDC_AF_PORT()_RT()_RW()_REQ_PC and ++ * NDC_AF_PORT()_RT()_RW()_LAT_PC. ++ */ ++#define NPA_NDC0_PORT_E_AURA0 (0) ++#define NPA_NDC0_PORT_E_AURA1 (1) ++#define NPA_NDC0_PORT_E_POOL0 (2) ++#define NPA_NDC0_PORT_E_POOL1 (3) ++#define NPA_NDC0_PORT_E_STACK0 (4) ++#define NPA_NDC0_PORT_E_STACK1 (5) ++ ++/** ++ * Enumeration npa_pool_err_int_e ++ * ++ * NPA Pool Error Interrupt Enumeration Enumerates the bit index of ++ * NPA_POOL_S[ERR_INT] and NPA_POOL_S[ERR_INT_ENA]. ++ */ ++#define NPA_POOL_ERR_INT_E_OVFLS (0) ++#define NPA_POOL_ERR_INT_E_PERR (2) ++#define NPA_POOL_ERR_INT_E_RX(a) (0 + (a)) ++#define NPA_POOL_ERR_INT_E_RANGE (1) ++ ++/** ++ * Structure npa_aq_inst_s ++ * ++ * NPA Admin Queue Instruction Structure This structure specifies the AQ ++ * instruction. Instructions and associated software structures are ++ * stored in memory as little-endian unless NPA_AF_GEN_CFG[AF_BE] is set. ++ * Hardware reads of NPA_AQ_INST_S do not allocate into LLC. Hardware ++ * reads and writes of the context structure selected by [CTYPE], [LF] ++ * and [CINDEX] use the NDC and LLC caching style configured for that ++ * context, i.e.: * NPA_AURA_HW_S reads and writes use ++ * NPA_AF_LF()_AURAS_CFG[CACHING] and NPA_AF_LF()_AURAS_CFG[WAY_MASK]. * ++ * NPA_POOL_HW_S reads and writes use NPA_AURA_HW_S[POOL_CACHING] and ++ * NPA_AURA_HW_S[POOL_WAY_MASK]. ++ */ ++union npa_aq_inst_s { ++ u64 u[2]; ++ struct npa_aq_inst_s_s { ++ u64 op : 4; ++ u64 ctype : 4; ++ u64 lf : 9; ++ u64 reserved_17_23 : 7; ++ u64 cindex : 20; ++ u64 reserved_44_62 : 19; ++ u64 doneint : 1; ++ u64 res_addr : 64; ++ } s; ++ /* struct npa_aq_inst_s_s cn; */ ++}; ++ ++/** ++ * Structure npa_aq_res_s ++ * ++ * NPA Admin Queue Result Structure NPA writes this structure after it ++ * completes the NPA_AQ_INST_S instruction. The result structure is ++ * exactly 16 bytes, and each instruction completion produces exactly one ++ * result structure. Results and associated software structures are ++ * stored in memory as little-endian unless NPA_AF_GEN_CFG[AF_BE] is set. ++ * When [OP] = NPA_AQ_INSTOP_E::INIT, WRITE or READ, this structure is ++ * immediately followed by context read or write data. See ++ * NPA_AQ_INSTOP_E. Hardware writes of NPA_AQ_RES_S and context data ++ * always allocate into LLC. Hardware reads of context data do not ++ * allocate into LLC. ++ */ ++union npa_aq_res_s { ++ u64 u[2]; ++ struct npa_aq_res_s_s { ++ u64 op : 4; ++ u64 ctype : 4; ++ u64 compcode : 8; ++ u64 doneint : 1; ++ u64 reserved_17_63 : 47; ++ u64 reserved_64_127 : 64; ++ } s; ++ /* struct npa_aq_res_s_s cn; */ ++}; ++ ++/** ++ * Structure npa_aura_op_wdata_s ++ * ++ * NPA Aura Operation Write Data Structure This structure specifies the ++ * write data format of a 64-bit atomic load-and-add to ++ * NPA_LF_AURA_OP_ALLOC() and NPA_LF_POOL_OP_PC, and a 128-bit atomic ++ * CASP operation to NPA_LF_AURA_OP_ALLOC(). ++ */ ++union npa_aura_op_wdata_s { ++ u64 u; ++ struct npa_aura_op_wdata_s_s { ++ u64 aura : 20; ++ u64 reserved_20_62 : 43; ++ u64 drop : 1; ++ } s; ++ /* struct npa_aura_op_wdata_s_s cn; */ ++}; ++ ++/** ++ * Structure npa_aura_s ++ * ++ * NPA Aura Context Structure This structure specifies the format used by ++ * software with the NPA admin queue to read and write an aura's ++ * NPA_AURA_HW_S structure maintained by hardware in LLC/DRAM. ++ */ ++union npa_aura_s { ++ u64 u[8]; ++ struct npa_aura_s_s { ++ u64 pool_addr : 64; ++ u64 ena : 1; ++ u64 reserved_65_66 : 2; ++ u64 pool_caching : 1; ++ u64 pool_way_mask : 16; ++ u64 avg_con : 9; ++ u64 reserved_93 : 1; ++ u64 pool_drop_ena : 1; ++ u64 aura_drop_ena : 1; ++ u64 bp_ena : 2; ++ u64 reserved_98_103 : 6; ++ u64 aura_drop : 8; ++ u64 shift : 6; ++ u64 reserved_118_119 : 2; ++ u64 avg_level : 8; ++ u64 count : 36; ++ u64 reserved_164_167 : 4; ++ u64 nix0_bpid : 9; ++ u64 reserved_177_179 : 3; ++ u64 nix1_bpid : 9; ++ u64 reserved_189_191 : 3; ++ u64 limit : 36; ++ u64 reserved_228_231 : 4; ++ u64 bp : 8; ++ u64 reserved_240_243 : 4; ++ u64 fc_ena : 1; ++ u64 fc_up_crossing : 1; ++ u64 fc_stype : 2; ++ u64 fc_hyst_bits : 4; ++ u64 reserved_252_255 : 4; ++ u64 fc_addr : 64; ++ u64 pool_drop : 8; ++ u64 update_time : 16; ++ u64 err_int : 8; ++ u64 err_int_ena : 8; ++ u64 thresh_int : 1; ++ u64 thresh_int_ena : 1; ++ u64 thresh_up : 1; ++ u64 reserved_363 : 1; ++ u64 thresh_qint_idx : 7; ++ u64 reserved_371 : 1; ++ u64 err_qint_idx : 7; ++ u64 reserved_379_383 : 5; ++ u64 thresh : 36; ++ u64 reserved_420_447 : 28; ++ u64 reserved_448_511 : 64; ++ } s; ++ /* struct npa_aura_s_s cn; */ ++}; ++ ++/** ++ * Structure npa_pool_s ++ * ++ * NPA Pool Context Structure This structure specifies the format used by ++ * software with the NPA admin queue to read and write a pool's ++ * NPA_POOL_HW_S structure maintained by hardware in LLC/DRAM. ++ */ ++union npa_pool_s { ++ u64 u[16]; ++ struct npa_pool_s_s { ++ u64 stack_base : 64; ++ u64 ena : 1; ++ u64 nat_align : 1; ++ u64 reserved_66_67 : 2; ++ u64 stack_caching : 1; ++ u64 reserved_69_71 : 3; ++ u64 stack_way_mask : 16; ++ u64 buf_offset : 12; ++ u64 reserved_100_103 : 4; ++ u64 buf_size : 11; ++ u64 reserved_115_127 : 13; ++ u64 stack_max_pages : 32; ++ u64 stack_pages : 32; ++ u64 op_pc : 48; ++ u64 reserved_240_255 : 16; ++ u64 stack_offset : 4; ++ u64 reserved_260_263 : 4; ++ u64 shift : 6; ++ u64 reserved_270_271 : 2; ++ u64 avg_level : 8; ++ u64 avg_con : 9; ++ u64 fc_ena : 1; ++ u64 fc_stype : 2; ++ u64 fc_hyst_bits : 4; ++ u64 fc_up_crossing : 1; ++ u64 reserved_297_299 : 3; ++ u64 update_time : 16; ++ u64 reserved_316_319 : 4; ++ u64 fc_addr : 64; ++ u64 ptr_start : 64; ++ u64 ptr_end : 64; ++ u64 reserved_512_535 : 24; ++ u64 err_int : 8; ++ u64 err_int_ena : 8; ++ u64 thresh_int : 1; ++ u64 thresh_int_ena : 1; ++ u64 thresh_up : 1; ++ u64 reserved_555 : 1; ++ u64 thresh_qint_idx : 7; ++ u64 reserved_563 : 1; ++ u64 err_qint_idx : 7; ++ u64 reserved_571_575 : 5; ++ u64 thresh : 36; ++ u64 reserved_612_639 : 28; ++ u64 reserved_640_703 : 64; ++ u64 reserved_704_767 : 64; ++ u64 reserved_768_831 : 64; ++ u64 reserved_832_895 : 64; ++ u64 reserved_896_959 : 64; ++ u64 reserved_960_1023 : 64; ++ } s; ++ /* struct npa_pool_s_s cn; */ ++}; ++ ++/** ++ * Structure npa_qint_hw_s ++ * ++ * NPA Queue Interrupt Context Hardware Structure This structure contains ++ * context state maintained by hardware for each queue interrupt (QINT) ++ * in NDC/LLC/DRAM. Software accesses this structure with the ++ * NPA_LF_QINT()_* registers. Hardware maintains a table of ++ * NPA_AF_CONST[QINTS] contiguous NPA_QINT_HW_S structures per LF ++ * starting at IOVA NPA_AF_LF()_QINTS_BASE. Always stored in byte ++ * invariant little-endian format (LE8). ++ */ ++union npa_qint_hw_s { ++ u32 u; ++ struct npa_qint_hw_s_s { ++ u32 count : 22; ++ u32 reserved_22_30 : 9; ++ u32 ena : 1; ++ } s; ++ /* struct npa_qint_hw_s_s cn; */ ++}; ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_active_cycles_pc ++ * ++ * NPA AF Active Cycles Register ++ */ ++union npa_af_active_cycles_pc { ++ u64 u; ++ struct npa_af_active_cycles_pc_s { ++ u64 act_cyc : 64; ++ } s; ++ /* struct npa_af_active_cycles_pc_s cn; */ ++}; ++ ++static inline u64 NPA_AF_ACTIVE_CYCLES_PC(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_ACTIVE_CYCLES_PC(void) ++{ ++ return 0xf0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_aq_base ++ * ++ * NPA AF Admin Queue Base Address Register ++ */ ++union npa_af_aq_base { ++ u64 u; ++ struct npa_af_aq_base_s { ++ u64 reserved_0_6 : 7; ++ u64 base_addr : 46; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct npa_af_aq_base_s cn; */ ++}; ++ ++static inline u64 NPA_AF_AQ_BASE(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_AQ_BASE(void) ++{ ++ return 0x610; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_aq_cfg ++ * ++ * NPA AF Admin Queue Configuration Register ++ */ ++union npa_af_aq_cfg { ++ u64 u; ++ struct npa_af_aq_cfg_s { ++ u64 qsize : 4; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct npa_af_aq_cfg_s cn; */ ++}; ++ ++static inline u64 NPA_AF_AQ_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_AQ_CFG(void) ++{ ++ return 0x600; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_aq_done ++ * ++ * NPA AF AQ Done Count Register ++ */ ++union npa_af_aq_done { ++ u64 u; ++ struct npa_af_aq_done_s { ++ u64 done : 20; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct npa_af_aq_done_s cn; */ ++}; ++ ++static inline u64 NPA_AF_AQ_DONE(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_AQ_DONE(void) ++{ ++ return 0x650; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_aq_done_ack ++ * ++ * NPA AF AQ Done Count Ack Register This register is written by software ++ * to acknowledge interrupts. ++ */ ++union npa_af_aq_done_ack { ++ u64 u; ++ struct npa_af_aq_done_ack_s { ++ u64 done_ack : 20; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct npa_af_aq_done_ack_s cn; */ ++}; ++ ++static inline u64 NPA_AF_AQ_DONE_ACK(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_AQ_DONE_ACK(void) ++{ ++ return 0x660; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_aq_done_ena_w1c ++ * ++ * NPA AF AQ Done Interrupt Enable Clear Register This register clears ++ * interrupt enable bits. ++ */ ++union npa_af_aq_done_ena_w1c { ++ u64 u; ++ struct npa_af_aq_done_ena_w1c_s { ++ u64 done : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npa_af_aq_done_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NPA_AF_AQ_DONE_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_AQ_DONE_ENA_W1C(void) ++{ ++ return 0x698; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_aq_done_ena_w1s ++ * ++ * NPA AF AQ Done Interrupt Enable Set Register This register sets ++ * interrupt enable bits. ++ */ ++union npa_af_aq_done_ena_w1s { ++ u64 u; ++ struct npa_af_aq_done_ena_w1s_s { ++ u64 done : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npa_af_aq_done_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NPA_AF_AQ_DONE_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_AQ_DONE_ENA_W1S(void) ++{ ++ return 0x690; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_aq_done_int ++ * ++ * NPA AF AQ Done Interrupt Register ++ */ ++union npa_af_aq_done_int { ++ u64 u; ++ struct npa_af_aq_done_int_s { ++ u64 done : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npa_af_aq_done_int_s cn; */ ++}; ++ ++static inline u64 NPA_AF_AQ_DONE_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_AQ_DONE_INT(void) ++{ ++ return 0x680; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_aq_done_int_w1s ++ * ++ * INTERNAL: NPA AF AQ Done Interrupt Set Register ++ */ ++union npa_af_aq_done_int_w1s { ++ u64 u; ++ struct npa_af_aq_done_int_w1s_s { ++ u64 done : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npa_af_aq_done_int_w1s_s cn; */ ++}; ++ ++static inline u64 NPA_AF_AQ_DONE_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_AQ_DONE_INT_W1S(void) ++{ ++ return 0x688; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_aq_done_timer ++ * ++ * NPA AF Admin Queue Done Interrupt Timer Register Used to debug the ++ * queue interrupt coalescing timer. ++ */ ++union npa_af_aq_done_timer { ++ u64 u; ++ struct npa_af_aq_done_timer_s { ++ u64 count : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct npa_af_aq_done_timer_s cn; */ ++}; ++ ++static inline u64 NPA_AF_AQ_DONE_TIMER(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_AQ_DONE_TIMER(void) ++{ ++ return 0x670; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_aq_done_wait ++ * ++ * NPA AF AQ Done Interrupt Coalescing Wait Register Specifies the queue ++ * interrupt coalescing settings. ++ */ ++union npa_af_aq_done_wait { ++ u64 u; ++ struct npa_af_aq_done_wait_s { ++ u64 num_wait : 20; ++ u64 reserved_20_31 : 12; ++ u64 time_wait : 16; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct npa_af_aq_done_wait_s cn; */ ++}; ++ ++static inline u64 NPA_AF_AQ_DONE_WAIT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_AQ_DONE_WAIT(void) ++{ ++ return 0x640; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_aq_door ++ * ++ * NPA AF Admin Queue Doorbell Register Software writes to this register ++ * to enqueue one or more entries to AQ. ++ */ ++union npa_af_aq_door { ++ u64 u; ++ struct npa_af_aq_door_s { ++ u64 count : 16; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct npa_af_aq_door_s cn; */ ++}; ++ ++static inline u64 NPA_AF_AQ_DOOR(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_AQ_DOOR(void) ++{ ++ return 0x630; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_aq_status ++ * ++ * NPA AF Admin Queue Status Register ++ */ ++union npa_af_aq_status { ++ u64 u; ++ struct npa_af_aq_status_s { ++ u64 reserved_0_3 : 4; ++ u64 head_ptr : 20; ++ u64 reserved_24_35 : 12; ++ u64 tail_ptr : 20; ++ u64 reserved_56_61 : 6; ++ u64 aq_busy : 1; ++ u64 aq_err : 1; ++ } s; ++ struct npa_af_aq_status_cn { ++ u64 reserved_0_3 : 4; ++ u64 head_ptr : 20; ++ u64 reserved_24_31 : 8; ++ u64 reserved_32_35 : 4; ++ u64 tail_ptr : 20; ++ u64 reserved_56_61 : 6; ++ u64 aq_busy : 1; ++ u64 aq_err : 1; ++ } cn; ++}; ++ ++static inline u64 NPA_AF_AQ_STATUS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_AQ_STATUS(void) ++{ ++ return 0x620; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_avg_delay ++ * ++ * NPA AF Queue Average Delay Register ++ */ ++union npa_af_avg_delay { ++ u64 u; ++ struct npa_af_avg_delay_s { ++ u64 avg_dly : 19; ++ u64 reserved_19_23 : 5; ++ u64 avg_timer : 16; ++ u64 reserved_40_62 : 23; ++ u64 avg_timer_dis : 1; ++ } s; ++ /* struct npa_af_avg_delay_s cn; */ ++}; ++ ++static inline u64 NPA_AF_AVG_DELAY(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_AVG_DELAY(void) ++{ ++ return 0x100; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_bar2_alias# ++ * ++ * INTERNAL: NPA Admin Function BAR2 Alias Registers These registers ++ * alias to the NPA BAR2 registers for the PF and function selected by ++ * NPA_AF_BAR2_SEL[PF_FUNC]. Internal: Not implemented. Placeholder for ++ * bug33464. ++ */ ++union npa_af_bar2_aliasx { ++ u64 u; ++ struct npa_af_bar2_aliasx_s { ++ u64 data : 64; ++ } s; ++ /* struct npa_af_bar2_aliasx_s cn; */ ++}; ++ ++static inline u64 NPA_AF_BAR2_ALIASX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_BAR2_ALIASX(u64 a) ++{ ++ return 0x9100000 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_bar2_sel ++ * ++ * INTERNAL: NPA Admin Function BAR2 Select Register This register ++ * configures BAR2 accesses from the NPA_AF_BAR2_ALIAS() registers in ++ * BAR0. Internal: Not implemented. Placeholder for bug33464. ++ */ ++union npa_af_bar2_sel { ++ u64 u; ++ struct npa_af_bar2_sel_s { ++ u64 alias_pf_func : 16; ++ u64 alias_ena : 1; ++ u64 reserved_17_63 : 47; ++ } s; ++ /* struct npa_af_bar2_sel_s cn; */ ++}; ++ ++static inline u64 NPA_AF_BAR2_SEL(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_BAR2_SEL(void) ++{ ++ return 0x9000000; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_blk_rst ++ * ++ * NPA AF Block Reset Register ++ */ ++union npa_af_blk_rst { ++ u64 u; ++ struct npa_af_blk_rst_s { ++ u64 rst : 1; ++ u64 reserved_1_62 : 62; ++ u64 busy : 1; ++ } s; ++ /* struct npa_af_blk_rst_s cn; */ ++}; ++ ++static inline u64 NPA_AF_BLK_RST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_BLK_RST(void) ++{ ++ return 0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_bp_test ++ * ++ * INTERNAL: NPA AF Backpressure Test Register ++ */ ++union npa_af_bp_test { ++ u64 u; ++ struct npa_af_bp_test_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 32; ++ u64 enable : 16; ++ } s; ++ /* struct npa_af_bp_test_s cn; */ ++}; ++ ++static inline u64 NPA_AF_BP_TEST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_BP_TEST(void) ++{ ++ return 0x200; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_const ++ * ++ * NPA AF Constants Register This register contains constants for ++ * software discovery. ++ */ ++union npa_af_const { ++ u64 u; ++ struct npa_af_const_s { ++ u64 stack_page_bytes : 8; ++ u64 stack_page_ptrs : 8; ++ u64 lfs : 12; ++ u64 qints : 12; ++ u64 num_ndc : 3; ++ u64 reserved_43_63 : 21; ++ } s; ++ /* struct npa_af_const_s cn; */ ++}; ++ ++static inline u64 NPA_AF_CONST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_CONST(void) ++{ ++ return 0x10; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_const1 ++ * ++ * NPA AF Constants Register 1 This register contains constants for ++ * software discovery. ++ */ ++union npa_af_const1 { ++ u64 u; ++ struct npa_af_const1_s { ++ u64 aura_log2bytes : 4; ++ u64 pool_log2bytes : 4; ++ u64 qint_log2bytes : 4; ++ u64 reserved_12_63 : 52; ++ } s; ++ /* struct npa_af_const1_s cn; */ ++}; ++ ++static inline u64 NPA_AF_CONST1(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_CONST1(void) ++{ ++ return 0x18; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_dtx_filter_ctl ++ * ++ * NPA AF DTX LF Filter Control Register ++ */ ++union npa_af_dtx_filter_ctl { ++ u64 u; ++ struct npa_af_dtx_filter_ctl_s { ++ u64 ena : 1; ++ u64 reserved_1_3 : 3; ++ u64 lf : 7; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct npa_af_dtx_filter_ctl_s cn; */ ++}; ++ ++static inline u64 NPA_AF_DTX_FILTER_CTL(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_DTX_FILTER_CTL(void) ++{ ++ return 0x10040; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_eco ++ * ++ * INTERNAL: NPA AF ECO Register ++ */ ++union npa_af_eco { ++ u64 u; ++ struct npa_af_eco_s { ++ u64 eco_rw : 32; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct npa_af_eco_s cn; */ ++}; ++ ++static inline u64 NPA_AF_ECO(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_ECO(void) ++{ ++ return 0x300; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_err_int ++ * ++ * NPA Admin Function Error Interrupt Register ++ */ ++union npa_af_err_int { ++ u64 u; ++ struct npa_af_err_int_s { ++ u64 reserved_0_11 : 12; ++ u64 aq_door_err : 1; ++ u64 aq_res_fault : 1; ++ u64 aq_inst_fault : 1; ++ u64 reserved_15_63 : 49; ++ } s; ++ /* struct npa_af_err_int_s cn; */ ++}; ++ ++static inline u64 NPA_AF_ERR_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_ERR_INT(void) ++{ ++ return 0x180; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_err_int_ena_w1c ++ * ++ * NPA Admin Function Error Interrupt Enable Clear Register This register ++ * clears interrupt enable bits. ++ */ ++union npa_af_err_int_ena_w1c { ++ u64 u; ++ struct npa_af_err_int_ena_w1c_s { ++ u64 reserved_0_11 : 12; ++ u64 aq_door_err : 1; ++ u64 aq_res_fault : 1; ++ u64 aq_inst_fault : 1; ++ u64 reserved_15_63 : 49; ++ } s; ++ /* struct npa_af_err_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NPA_AF_ERR_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_ERR_INT_ENA_W1C(void) ++{ ++ return 0x198; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_err_int_ena_w1s ++ * ++ * NPA Admin Function Error Interrupt Enable Set Register This register ++ * sets interrupt enable bits. ++ */ ++union npa_af_err_int_ena_w1s { ++ u64 u; ++ struct npa_af_err_int_ena_w1s_s { ++ u64 reserved_0_11 : 12; ++ u64 aq_door_err : 1; ++ u64 aq_res_fault : 1; ++ u64 aq_inst_fault : 1; ++ u64 reserved_15_63 : 49; ++ } s; ++ /* struct npa_af_err_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NPA_AF_ERR_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_ERR_INT_ENA_W1S(void) ++{ ++ return 0x190; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_err_int_w1s ++ * ++ * NPA Admin Function Error Interrupt Set Register This register sets ++ * interrupt bits. ++ */ ++union npa_af_err_int_w1s { ++ u64 u; ++ struct npa_af_err_int_w1s_s { ++ u64 reserved_0_11 : 12; ++ u64 aq_door_err : 1; ++ u64 aq_res_fault : 1; ++ u64 aq_inst_fault : 1; ++ u64 reserved_15_63 : 49; ++ } s; ++ /* struct npa_af_err_int_w1s_s cn; */ ++}; ++ ++static inline u64 NPA_AF_ERR_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_ERR_INT_W1S(void) ++{ ++ return 0x188; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_gen_cfg ++ * ++ * NPA AF General Configuration Register This register provides NPA ++ * control and status information. ++ */ ++union npa_af_gen_cfg { ++ u64 u; ++ struct npa_af_gen_cfg_s { ++ u64 reserved_0 : 1; ++ u64 af_be : 1; ++ u64 reserved_2 : 1; ++ u64 force_cond_clk_en : 1; ++ u64 force_intf_clk_en : 1; ++ u64 reserved_5_9 : 5; ++ u64 ocla_bp : 1; ++ u64 reserved_11 : 1; ++ u64 ratem1 : 4; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct npa_af_gen_cfg_s cn; */ ++}; ++ ++static inline u64 NPA_AF_GEN_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_GEN_CFG(void) ++{ ++ return 0x30; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_gen_int ++ * ++ * NPA AF General Interrupt Register This register contains general error ++ * interrupt summary bits. ++ */ ++union npa_af_gen_int { ++ u64 u; ++ struct npa_af_gen_int_s { ++ u64 free_dis : 16; ++ u64 alloc_dis : 16; ++ u64 unmapped_pf_func : 1; ++ u64 reserved_33_63 : 31; ++ } s; ++ /* struct npa_af_gen_int_s cn; */ ++}; ++ ++static inline u64 NPA_AF_GEN_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_GEN_INT(void) ++{ ++ return 0x140; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_gen_int_ena_w1c ++ * ++ * NPA AF General Interrupt Enable Clear Register This register clears ++ * interrupt enable bits. ++ */ ++union npa_af_gen_int_ena_w1c { ++ u64 u; ++ struct npa_af_gen_int_ena_w1c_s { ++ u64 free_dis : 16; ++ u64 alloc_dis : 16; ++ u64 unmapped_pf_func : 1; ++ u64 reserved_33_63 : 31; ++ } s; ++ /* struct npa_af_gen_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NPA_AF_GEN_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_GEN_INT_ENA_W1C(void) ++{ ++ return 0x158; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_gen_int_ena_w1s ++ * ++ * NPA AF General Interrupt Enable Set Register This register sets ++ * interrupt enable bits. ++ */ ++union npa_af_gen_int_ena_w1s { ++ u64 u; ++ struct npa_af_gen_int_ena_w1s_s { ++ u64 free_dis : 16; ++ u64 alloc_dis : 16; ++ u64 unmapped_pf_func : 1; ++ u64 reserved_33_63 : 31; ++ } s; ++ /* struct npa_af_gen_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NPA_AF_GEN_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_GEN_INT_ENA_W1S(void) ++{ ++ return 0x150; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_gen_int_w1s ++ * ++ * NPA AF General Interrupt Set Register This register sets interrupt ++ * bits. ++ */ ++union npa_af_gen_int_w1s { ++ u64 u; ++ struct npa_af_gen_int_w1s_s { ++ u64 free_dis : 16; ++ u64 alloc_dis : 16; ++ u64 unmapped_pf_func : 1; ++ u64 reserved_33_63 : 31; ++ } s; ++ /* struct npa_af_gen_int_w1s_s cn; */ ++}; ++ ++static inline u64 NPA_AF_GEN_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_GEN_INT_W1S(void) ++{ ++ return 0x148; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_inp_ctl ++ * ++ * NPA AF Input Control Register ++ */ ++union npa_af_inp_ctl { ++ u64 u; ++ struct npa_af_inp_ctl_s { ++ u64 free_dis : 16; ++ u64 alloc_dis : 16; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct npa_af_inp_ctl_s cn; */ ++}; ++ ++static inline u64 NPA_AF_INP_CTL(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_INP_CTL(void) ++{ ++ return 0xd0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_lf#_auras_cfg ++ * ++ * NPA AF Local Function Auras Configuration Registers ++ */ ++union npa_af_lfx_auras_cfg { ++ u64 u; ++ struct npa_af_lfx_auras_cfg_s { ++ u64 way_mask : 16; ++ u64 loc_aura_size : 4; ++ u64 loc_aura_offset : 14; ++ u64 caching : 1; ++ u64 be : 1; ++ u64 rmt_aura_size : 4; ++ u64 rmt_aura_offset : 14; ++ u64 rmt_lf : 7; ++ u64 reserved_61_63 : 3; ++ } s; ++ struct npa_af_lfx_auras_cfg_cn96xxp1 { ++ u64 way_mask : 16; ++ u64 loc_aura_size : 4; ++ u64 loc_aura_offset : 14; ++ u64 caching : 1; ++ u64 reserved_35 : 1; ++ u64 rmt_aura_size : 4; ++ u64 rmt_aura_offset : 14; ++ u64 rmt_lf : 7; ++ u64 reserved_61_63 : 3; ++ } cn96xxp1; ++ /* struct npa_af_lfx_auras_cfg_s cn96xxp3; */ ++ /* struct npa_af_lfx_auras_cfg_s cn98xx; */ ++ /* struct npa_af_lfx_auras_cfg_s cnf95xx; */ ++ /* struct npa_af_lfx_auras_cfg_s loki; */ ++}; ++ ++static inline u64 NPA_AF_LFX_AURAS_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_LFX_AURAS_CFG(u64 a) ++{ ++ return 0x4000 + 0x40000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_lf#_loc_auras_base ++ * ++ * NPA AF Local Function Auras Base Registers ++ */ ++union npa_af_lfx_loc_auras_base { ++ u64 u; ++ struct npa_af_lfx_loc_auras_base_s { ++ u64 reserved_0_6 : 7; ++ u64 addr : 46; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct npa_af_lfx_loc_auras_base_s cn; */ ++}; ++ ++static inline u64 NPA_AF_LFX_LOC_AURAS_BASE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_LFX_LOC_AURAS_BASE(u64 a) ++{ ++ return 0x4010 + 0x40000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_lf#_qints_base ++ * ++ * NPA AF Local Function Queue Interrupts Base Registers ++ */ ++union npa_af_lfx_qints_base { ++ u64 u; ++ struct npa_af_lfx_qints_base_s { ++ u64 reserved_0_6 : 7; ++ u64 addr : 46; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct npa_af_lfx_qints_base_s cn; */ ++}; ++ ++static inline u64 NPA_AF_LFX_QINTS_BASE(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_LFX_QINTS_BASE(u64 a) ++{ ++ return 0x4110 + 0x40000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_lf#_qints_cfg ++ * ++ * NPA AF Local Function Queue Interrupts Configuration Registers This ++ * register controls access to the LF's queue interrupt context table in ++ * LLC/DRAM. The table consists of NPA_AF_CONST[QINTS] contiguous ++ * NPA_QINT_HW_S structures. The size of each structure is 1 \<\< ++ * NPA_AF_CONST1[QINT_LOG2BYTES] bytes. ++ */ ++union npa_af_lfx_qints_cfg { ++ u64 u; ++ struct npa_af_lfx_qints_cfg_s { ++ u64 reserved_0_19 : 20; ++ u64 way_mask : 16; ++ u64 caching : 2; ++ u64 reserved_38_63 : 26; ++ } s; ++ /* struct npa_af_lfx_qints_cfg_s cn; */ ++}; ++ ++static inline u64 NPA_AF_LFX_QINTS_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_LFX_QINTS_CFG(u64 a) ++{ ++ return 0x4100 + 0x40000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_lf_rst ++ * ++ * NPA Admin Function LF Reset Register ++ */ ++union npa_af_lf_rst { ++ u64 u; ++ struct npa_af_lf_rst_s { ++ u64 lf : 8; ++ u64 reserved_8_11 : 4; ++ u64 exec : 1; ++ u64 reserved_13_63 : 51; ++ } s; ++ /* struct npa_af_lf_rst_s cn; */ ++}; ++ ++static inline u64 NPA_AF_LF_RST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_LF_RST(void) ++{ ++ return 0x20; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_ndc_cfg ++ * ++ * NDC AF General Configuration Register This register provides NDC ++ * control. ++ */ ++union npa_af_ndc_cfg { ++ u64 u; ++ struct npa_af_ndc_cfg_s { ++ u64 ndc_bypass : 1; ++ u64 ndc_ign_pois : 1; ++ u64 byp_aura : 1; ++ u64 byp_pool : 1; ++ u64 byp_stack : 1; ++ u64 byp_qint : 1; ++ u64 reserved_6_63 : 58; ++ } s; ++ /* struct npa_af_ndc_cfg_s cn; */ ++}; ++ ++static inline u64 NPA_AF_NDC_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_NDC_CFG(void) ++{ ++ return 0x40; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_ndc_sync ++ * ++ * NPA AF NDC Sync Register Used to synchronize the NPA NDC. ++ */ ++union npa_af_ndc_sync { ++ u64 u; ++ struct npa_af_ndc_sync_s { ++ u64 lf : 8; ++ u64 reserved_8_11 : 4; ++ u64 exec : 1; ++ u64 reserved_13_63 : 51; ++ } s; ++ /* struct npa_af_ndc_sync_s cn; */ ++}; ++ ++static inline u64 NPA_AF_NDC_SYNC(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_NDC_SYNC(void) ++{ ++ return 0x50; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_ras ++ * ++ * NPA AF RAS Interrupt Register This register is intended for delivery ++ * of RAS events to the SCP, so should be ignored by OS drivers. ++ */ ++union npa_af_ras { ++ u64 u; ++ struct npa_af_ras_s { ++ u64 reserved_0_31 : 32; ++ u64 aq_ctx_poison : 1; ++ u64 aq_res_poison : 1; ++ u64 aq_inst_poison : 1; ++ u64 reserved_35_63 : 29; ++ } s; ++ /* struct npa_af_ras_s cn; */ ++}; ++ ++static inline u64 NPA_AF_RAS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_RAS(void) ++{ ++ return 0x1a0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_ras_ena_w1c ++ * ++ * NPA AF RAS Interrupt Enable Clear Register This register clears ++ * interrupt enable bits. ++ */ ++union npa_af_ras_ena_w1c { ++ u64 u; ++ struct npa_af_ras_ena_w1c_s { ++ u64 reserved_0_31 : 32; ++ u64 aq_ctx_poison : 1; ++ u64 aq_res_poison : 1; ++ u64 aq_inst_poison : 1; ++ u64 reserved_35_63 : 29; ++ } s; ++ /* struct npa_af_ras_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NPA_AF_RAS_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_RAS_ENA_W1C(void) ++{ ++ return 0x1b8; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_ras_ena_w1s ++ * ++ * NPA AF RAS Interrupt Enable Set Register This register sets interrupt ++ * enable bits. ++ */ ++union npa_af_ras_ena_w1s { ++ u64 u; ++ struct npa_af_ras_ena_w1s_s { ++ u64 reserved_0_31 : 32; ++ u64 aq_ctx_poison : 1; ++ u64 aq_res_poison : 1; ++ u64 aq_inst_poison : 1; ++ u64 reserved_35_63 : 29; ++ } s; ++ /* struct npa_af_ras_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NPA_AF_RAS_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_RAS_ENA_W1S(void) ++{ ++ return 0x1b0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_ras_w1s ++ * ++ * NPA AF RAS Interrupt Set Register This register sets interrupt bits. ++ */ ++union npa_af_ras_w1s { ++ u64 u; ++ struct npa_af_ras_w1s_s { ++ u64 reserved_0_31 : 32; ++ u64 aq_ctx_poison : 1; ++ u64 aq_res_poison : 1; ++ u64 aq_inst_poison : 1; ++ u64 reserved_35_63 : 29; ++ } s; ++ /* struct npa_af_ras_w1s_s cn; */ ++}; ++ ++static inline u64 NPA_AF_RAS_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_RAS_W1S(void) ++{ ++ return 0x1a8; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_rvu_int ++ * ++ * NPA AF RVU Interrupt Register This register contains RVU error ++ * interrupt summary bits. ++ */ ++union npa_af_rvu_int { ++ u64 u; ++ struct npa_af_rvu_int_s { ++ u64 unmapped_slot : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npa_af_rvu_int_s cn; */ ++}; ++ ++static inline u64 NPA_AF_RVU_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_RVU_INT(void) ++{ ++ return 0x160; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_rvu_int_ena_w1c ++ * ++ * NPA AF RVU Interrupt Enable Clear Register This register clears ++ * interrupt enable bits. ++ */ ++union npa_af_rvu_int_ena_w1c { ++ u64 u; ++ struct npa_af_rvu_int_ena_w1c_s { ++ u64 unmapped_slot : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npa_af_rvu_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NPA_AF_RVU_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_RVU_INT_ENA_W1C(void) ++{ ++ return 0x178; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_rvu_int_ena_w1s ++ * ++ * NPA AF RVU Interrupt Enable Set Register This register sets interrupt ++ * enable bits. ++ */ ++union npa_af_rvu_int_ena_w1s { ++ u64 u; ++ struct npa_af_rvu_int_ena_w1s_s { ++ u64 unmapped_slot : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npa_af_rvu_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NPA_AF_RVU_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_RVU_INT_ENA_W1S(void) ++{ ++ return 0x170; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_rvu_int_w1s ++ * ++ * NPA AF RVU Interrupt Set Register This register sets interrupt bits. ++ */ ++union npa_af_rvu_int_w1s { ++ u64 u; ++ struct npa_af_rvu_int_w1s_s { ++ u64 unmapped_slot : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npa_af_rvu_int_w1s_s cn; */ ++}; ++ ++static inline u64 NPA_AF_RVU_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_RVU_INT_W1S(void) ++{ ++ return 0x168; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_af_rvu_lf_cfg_debug ++ * ++ * NPA Privileged LF Configuration Debug Register This debug register ++ * allows software to lookup the reverse mapping from VF/PF slot to LF. ++ * The forward mapping is programmed with NPA_PRIV_LF()_CFG. ++ */ ++union npa_af_rvu_lf_cfg_debug { ++ u64 u; ++ struct npa_af_rvu_lf_cfg_debug_s { ++ u64 lf : 12; ++ u64 lf_valid : 1; ++ u64 exec : 1; ++ u64 reserved_14_15 : 2; ++ u64 slot : 8; ++ u64 pf_func : 16; ++ u64 reserved_40_63 : 24; ++ } s; ++ /* struct npa_af_rvu_lf_cfg_debug_s cn; */ ++}; ++ ++static inline u64 NPA_AF_RVU_LF_CFG_DEBUG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_AF_RVU_LF_CFG_DEBUG(void) ++{ ++ return 0x10030; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_aura_op_alloc# ++ * ++ * NPA Aura Allocate Operation Registers These registers are used to ++ * allocate one or two pointers from a given aura's pool. A 64-bit atomic ++ * load-and-add to NPA_LF_AURA_OP_ALLOC(0) allocates a single pointer. A ++ * 128-bit atomic CASP operation to NPA_LF_AURA_OP_ALLOC(0..1) allocates ++ * two pointers. The atomic write data format is NPA_AURA_OP_WDATA_S. For ++ * CASP, the first SWAP word in the write data contains ++ * NPA_AURA_OP_WDATA_S and the remaining write data words are ignored. ++ * All other accesses to this register (e.g. reads and writes) are ++ * RAZ/WI. RSL accesses to this register are RAZ/WI. ++ */ ++union npa_lf_aura_op_allocx { ++ u64 u; ++ struct npa_lf_aura_op_allocx_s { ++ u64 addr : 64; ++ } s; ++ /* struct npa_lf_aura_op_allocx_s cn; */ ++}; ++ ++static inline u64 NPA_LF_AURA_OP_ALLOCX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_AURA_OP_ALLOCX(u64 a) ++{ ++ return 0x10 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_aura_op_cnt ++ * ++ * NPA LF Aura Count Register A 64-bit atomic load-and-add to this ++ * register returns a given aura's count. A write sets or adds the aura's ++ * count. A read is RAZ. RSL accesses to this register are RAZ/WI. ++ */ ++union npa_lf_aura_op_cnt { ++ u64 u; ++ struct npa_lf_aura_op_cnt_s { ++ u64 count : 36; ++ u64 reserved_36_41 : 6; ++ u64 op_err : 1; ++ u64 cnt_add : 1; ++ u64 aura : 20; ++ } s; ++ /* struct npa_lf_aura_op_cnt_s cn; */ ++}; ++ ++static inline u64 NPA_LF_AURA_OP_CNT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_AURA_OP_CNT(void) ++{ ++ return 0x30; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_aura_op_free0 ++ * ++ * NPA LF Aura Free Operation Register 0 A 128-bit write (STP) to ++ * NPA_LF_AURA_OP_FREE0 and NPA_LF_AURA_OP_FREE1 frees a pointer into a ++ * given aura's pool. All other accesses to these registers (e.g. reads ++ * and 64-bit writes) are RAZ/WI. RSL accesses to this register are ++ * RAZ/WI. ++ */ ++union npa_lf_aura_op_free0 { ++ u64 u; ++ struct npa_lf_aura_op_free0_s { ++ u64 addr : 64; ++ } s; ++ /* struct npa_lf_aura_op_free0_s cn; */ ++}; ++ ++static inline u64 NPA_LF_AURA_OP_FREE0(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_AURA_OP_FREE0(void) ++{ ++ return 0x20; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_aura_op_free1 ++ * ++ * NPA LF Aura Free Operation Register 1 See NPA_LF_AURA_OP_FREE0. RSL ++ * accesses to this register are RAZ/WI. ++ */ ++union npa_lf_aura_op_free1 { ++ u64 u; ++ struct npa_lf_aura_op_free1_s { ++ u64 aura : 20; ++ u64 reserved_20_62 : 43; ++ u64 fabs : 1; ++ } s; ++ /* struct npa_lf_aura_op_free1_s cn; */ ++}; ++ ++static inline u64 NPA_LF_AURA_OP_FREE1(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_AURA_OP_FREE1(void) ++{ ++ return 0x28; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_aura_op_int ++ * ++ * NPA LF Aura Interrupt Operation Register A 64-bit atomic load-and-add ++ * to this register reads ++ * NPA_AURA_HW_S[ERR_INT,ERR_INT_ENA,THRESH_INT,THRESH_INT_ENA]. A write ++ * optionally sets or clears these fields. A read is RAZ. RSL accesses ++ * to this register are RAZ/WI. ++ */ ++union npa_lf_aura_op_int { ++ u64 u; ++ struct npa_lf_aura_op_int_s { ++ u64 err_int : 8; ++ u64 err_int_ena : 8; ++ u64 thresh_int : 1; ++ u64 thresh_int_ena : 1; ++ u64 reserved_18_41 : 24; ++ u64 op_err : 1; ++ u64 setop : 1; ++ u64 aura : 20; ++ } s; ++ /* struct npa_lf_aura_op_int_s cn; */ ++}; ++ ++static inline u64 NPA_LF_AURA_OP_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_AURA_OP_INT(void) ++{ ++ return 0x60; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_aura_op_limit ++ * ++ * NPA LF Aura Allocation Limit Register A 64-bit atomic load-and-add to ++ * this register returns a given aura's limit. A write sets the aura's ++ * limit. A read is RAZ. RSL accesses to this register are RAZ/WI. ++ */ ++union npa_lf_aura_op_limit { ++ u64 u; ++ struct npa_lf_aura_op_limit_s { ++ u64 limit : 36; ++ u64 reserved_36_41 : 6; ++ u64 op_err : 1; ++ u64 reserved_43 : 1; ++ u64 aura : 20; ++ } s; ++ /* struct npa_lf_aura_op_limit_s cn; */ ++}; ++ ++static inline u64 NPA_LF_AURA_OP_LIMIT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_AURA_OP_LIMIT(void) ++{ ++ return 0x50; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_aura_op_thresh ++ * ++ * NPA LF Aura Threshold Operation Register A 64-bit atomic load-and-add ++ * to this register reads NPA_AURA_HW_S[THRESH_UP,THRESH]. A write to the ++ * register writes NPA_AURA_HW_S[THRESH_UP,THRESH] and recomputes ++ * NPA_AURA_HW_S[THRESH_INT]. A read is RAZ. RSL accesses to this ++ * register are RAZ/WI. ++ */ ++union npa_lf_aura_op_thresh { ++ u64 u; ++ struct npa_lf_aura_op_thresh_s { ++ u64 thresh : 36; ++ u64 reserved_36_41 : 6; ++ u64 op_err : 1; ++ u64 thresh_up : 1; ++ u64 aura : 20; ++ } s; ++ /* struct npa_lf_aura_op_thresh_s cn; */ ++}; ++ ++static inline u64 NPA_LF_AURA_OP_THRESH(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_AURA_OP_THRESH(void) ++{ ++ return 0x70; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_err_int ++ * ++ * NPA LF Error Interrupt Register ++ */ ++union npa_lf_err_int { ++ u64 u; ++ struct npa_lf_err_int_s { ++ u64 aura_dis : 1; ++ u64 aura_oor : 1; ++ u64 reserved_2 : 1; ++ u64 rmt_req_oor : 1; ++ u64 reserved_4_11 : 8; ++ u64 aura_fault : 1; ++ u64 pool_fault : 1; ++ u64 stack_fault : 1; ++ u64 qint_fault : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct npa_lf_err_int_s cn; */ ++}; ++ ++static inline u64 NPA_LF_ERR_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_ERR_INT(void) ++{ ++ return 0x200; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_err_int_ena_w1c ++ * ++ * NPA LF Error Interrupt Enable Clear Register This register clears ++ * interrupt enable bits. ++ */ ++union npa_lf_err_int_ena_w1c { ++ u64 u; ++ struct npa_lf_err_int_ena_w1c_s { ++ u64 aura_dis : 1; ++ u64 aura_oor : 1; ++ u64 reserved_2 : 1; ++ u64 rmt_req_oor : 1; ++ u64 reserved_4_11 : 8; ++ u64 aura_fault : 1; ++ u64 pool_fault : 1; ++ u64 stack_fault : 1; ++ u64 qint_fault : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct npa_lf_err_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NPA_LF_ERR_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_ERR_INT_ENA_W1C(void) ++{ ++ return 0x210; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_err_int_ena_w1s ++ * ++ * NPA LF Error Interrupt Enable Set Register This register sets ++ * interrupt enable bits. ++ */ ++union npa_lf_err_int_ena_w1s { ++ u64 u; ++ struct npa_lf_err_int_ena_w1s_s { ++ u64 aura_dis : 1; ++ u64 aura_oor : 1; ++ u64 reserved_2 : 1; ++ u64 rmt_req_oor : 1; ++ u64 reserved_4_11 : 8; ++ u64 aura_fault : 1; ++ u64 pool_fault : 1; ++ u64 stack_fault : 1; ++ u64 qint_fault : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct npa_lf_err_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NPA_LF_ERR_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_ERR_INT_ENA_W1S(void) ++{ ++ return 0x218; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_err_int_w1s ++ * ++ * NPA LF Error Interrupt Set Register This register sets interrupt bits. ++ */ ++union npa_lf_err_int_w1s { ++ u64 u; ++ struct npa_lf_err_int_w1s_s { ++ u64 aura_dis : 1; ++ u64 aura_oor : 1; ++ u64 reserved_2 : 1; ++ u64 rmt_req_oor : 1; ++ u64 reserved_4_11 : 8; ++ u64 aura_fault : 1; ++ u64 pool_fault : 1; ++ u64 stack_fault : 1; ++ u64 qint_fault : 1; ++ u64 reserved_16_63 : 48; ++ } s; ++ /* struct npa_lf_err_int_w1s_s cn; */ ++}; ++ ++static inline u64 NPA_LF_ERR_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_ERR_INT_W1S(void) ++{ ++ return 0x208; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_pool_op_available ++ * ++ * NPA LF Pool Available Count Operation Register A 64-bit atomic load- ++ * and-add to this register returns a given pool's free pointer count. ++ * Reads and writes are RAZ/WI. RSL accesses to this register are ++ * RAZ/WI. ++ */ ++union npa_lf_pool_op_available { ++ u64 u; ++ struct npa_lf_pool_op_available_s { ++ u64 count : 36; ++ u64 reserved_36_41 : 6; ++ u64 op_err : 1; ++ u64 reserved_43 : 1; ++ u64 aura : 20; ++ } s; ++ /* struct npa_lf_pool_op_available_s cn; */ ++}; ++ ++static inline u64 NPA_LF_POOL_OP_AVAILABLE(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_POOL_OP_AVAILABLE(void) ++{ ++ return 0x110; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_pool_op_int ++ * ++ * NPA LF Pool Interrupt Operation Register A 64-bit atomic load-and-add ++ * to this register reads ++ * NPA_POOL_S[ERR_INT,ERR_INT_ENA,THRESH_INT,THRESH_INT_ENA]. A write ++ * optionally sets or clears these fields. A read is RAZ. RSL accesses ++ * to this register are RAZ/WI. ++ */ ++union npa_lf_pool_op_int { ++ u64 u; ++ struct npa_lf_pool_op_int_s { ++ u64 err_int : 8; ++ u64 err_int_ena : 8; ++ u64 thresh_int : 1; ++ u64 thresh_int_ena : 1; ++ u64 reserved_18_41 : 24; ++ u64 op_err : 1; ++ u64 setop : 1; ++ u64 aura : 20; ++ } s; ++ /* struct npa_lf_pool_op_int_s cn; */ ++}; ++ ++static inline u64 NPA_LF_POOL_OP_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_POOL_OP_INT(void) ++{ ++ return 0x160; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_pool_op_pc ++ * ++ * NPA LF Pool Performance Count Register A 64-bit atomic load-and-add to ++ * this register reads NPA_POOL_S[OP_PC] from a given aura's pool. The ++ * aura is selected by the atomic write data, whose format is ++ * NPA_AURA_OP_WDATA_S. Reads and writes are RAZ/WI. RSL accesses to ++ * this register are RAZ/WI. ++ */ ++union npa_lf_pool_op_pc { ++ u64 u; ++ struct npa_lf_pool_op_pc_s { ++ u64 op_pc : 48; ++ u64 op_err : 1; ++ u64 reserved_49_63 : 15; ++ } s; ++ /* struct npa_lf_pool_op_pc_s cn; */ ++}; ++ ++static inline u64 NPA_LF_POOL_OP_PC(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_POOL_OP_PC(void) ++{ ++ return 0x100; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_pool_op_ptr_end0 ++ * ++ * NPA LF Pool Pointer End Operation Register 0 A 128-bit write (STP) to ++ * the NPA_LF_POOL_OP_PTR_END0 and NPA_LF_POOL_OP_PTR_END1 registers ++ * writes to a given pool's pointer end value. All other accesses to ++ * these registers (e.g. reads and 64-bit writes) are RAZ/WI. RSL ++ * accesses to this register are RAZ/WI. ++ */ ++union npa_lf_pool_op_ptr_end0 { ++ u64 u; ++ struct npa_lf_pool_op_ptr_end0_s { ++ u64 ptr_end : 64; ++ } s; ++ /* struct npa_lf_pool_op_ptr_end0_s cn; */ ++}; ++ ++static inline u64 NPA_LF_POOL_OP_PTR_END0(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_POOL_OP_PTR_END0(void) ++{ ++ return 0x130; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_pool_op_ptr_end1 ++ * ++ * NPA LF Pool Pointer End Operation Register 1 See ++ * NPA_LF_POOL_OP_PTR_END0. RSL accesses to this register are RAZ/WI. ++ */ ++union npa_lf_pool_op_ptr_end1 { ++ u64 u; ++ struct npa_lf_pool_op_ptr_end1_s { ++ u64 aura : 20; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct npa_lf_pool_op_ptr_end1_s cn; */ ++}; ++ ++static inline u64 NPA_LF_POOL_OP_PTR_END1(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_POOL_OP_PTR_END1(void) ++{ ++ return 0x138; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_pool_op_ptr_start0 ++ * ++ * NPA LF Pool Pointer Start Operation Register 0 A 128-bit write (STP) ++ * to the NPA_LF_POOL_OP_PTR_START0 and NPA_LF_POOL_OP_PTR_START1 ++ * registers writes to a given pool's pointer start value. All other ++ * accesses to these registers (e.g. reads and 64-bit writes) are RAZ/WI. ++ * RSL accesses to this register are RAZ/WI. ++ */ ++union npa_lf_pool_op_ptr_start0 { ++ u64 u; ++ struct npa_lf_pool_op_ptr_start0_s { ++ u64 ptr_start : 64; ++ } s; ++ /* struct npa_lf_pool_op_ptr_start0_s cn; */ ++}; ++ ++static inline u64 NPA_LF_POOL_OP_PTR_START0(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_POOL_OP_PTR_START0(void) ++{ ++ return 0x120; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_pool_op_ptr_start1 ++ * ++ * NPA LF Pool Pointer Start Operation Register 1 See ++ * NPA_LF_POOL_OP_PTR_START0. RSL accesses to this register are RAZ/WI. ++ */ ++union npa_lf_pool_op_ptr_start1 { ++ u64 u; ++ struct npa_lf_pool_op_ptr_start1_s { ++ u64 aura : 20; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct npa_lf_pool_op_ptr_start1_s cn; */ ++}; ++ ++static inline u64 NPA_LF_POOL_OP_PTR_START1(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_POOL_OP_PTR_START1(void) ++{ ++ return 0x128; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_pool_op_thresh ++ * ++ * NPA LF Pool Threshold Operation Register A 64-bit atomic load-and-add ++ * to this register reads NPA_POOL_S[THRESH_UP,THRESH]. A write to the ++ * register writes NPA_POOL_S[THRESH_UP,THRESH]. A read is RAZ. RSL ++ * accesses to this register are RAZ/WI. ++ */ ++union npa_lf_pool_op_thresh { ++ u64 u; ++ struct npa_lf_pool_op_thresh_s { ++ u64 thresh : 36; ++ u64 reserved_36_41 : 6; ++ u64 op_err : 1; ++ u64 thresh_up : 1; ++ u64 aura : 20; ++ } s; ++ /* struct npa_lf_pool_op_thresh_s cn; */ ++}; ++ ++static inline u64 NPA_LF_POOL_OP_THRESH(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_POOL_OP_THRESH(void) ++{ ++ return 0x170; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_qint#_cnt ++ * ++ * NPA LF Queue Interrupt Count Registers ++ */ ++union npa_lf_qintx_cnt { ++ u64 u; ++ struct npa_lf_qintx_cnt_s { ++ u64 count : 22; ++ u64 reserved_22_63 : 42; ++ } s; ++ /* struct npa_lf_qintx_cnt_s cn; */ ++}; ++ ++static inline u64 NPA_LF_QINTX_CNT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_QINTX_CNT(u64 a) ++{ ++ return 0x300 + 0x1000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_qint#_ena_w1c ++ * ++ * NPA LF Queue Interrupt Enable Clear Registers This register clears ++ * interrupt enable bits. ++ */ ++union npa_lf_qintx_ena_w1c { ++ u64 u; ++ struct npa_lf_qintx_ena_w1c_s { ++ u64 intr : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npa_lf_qintx_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NPA_LF_QINTX_ENA_W1C(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_QINTX_ENA_W1C(u64 a) ++{ ++ return 0x330 + 0x1000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_qint#_ena_w1s ++ * ++ * NPA LF Queue Interrupt Enable Set Registers This register sets ++ * interrupt enable bits. ++ */ ++union npa_lf_qintx_ena_w1s { ++ u64 u; ++ struct npa_lf_qintx_ena_w1s_s { ++ u64 intr : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npa_lf_qintx_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NPA_LF_QINTX_ENA_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_QINTX_ENA_W1S(u64 a) ++{ ++ return 0x320 + 0x1000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_qint#_int ++ * ++ * NPA LF Queue Interrupt Registers ++ */ ++union npa_lf_qintx_int { ++ u64 u; ++ struct npa_lf_qintx_int_s { ++ u64 intr : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npa_lf_qintx_int_s cn; */ ++}; ++ ++static inline u64 NPA_LF_QINTX_INT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_QINTX_INT(u64 a) ++{ ++ return 0x310 + 0x1000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_qint#_int_w1s ++ * ++ * INTERNAL: NPA LF Queue Interrupt Set Registers ++ */ ++union npa_lf_qintx_int_w1s { ++ u64 u; ++ struct npa_lf_qintx_int_w1s_s { ++ u64 intr : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npa_lf_qintx_int_w1s_s cn; */ ++}; ++ ++static inline u64 NPA_LF_QINTX_INT_W1S(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_QINTX_INT_W1S(u64 a) ++{ ++ return 0x318 + 0x1000 * a; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_ras ++ * ++ * NPA LF RAS Interrupt Register ++ */ ++union npa_lf_ras { ++ u64 u; ++ struct npa_lf_ras_s { ++ u64 aura_poison : 1; ++ u64 pool_poison : 1; ++ u64 stack_poison : 1; ++ u64 qint_poison : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct npa_lf_ras_s cn; */ ++}; ++ ++static inline u64 NPA_LF_RAS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_RAS(void) ++{ ++ return 0x220; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_ras_ena_w1c ++ * ++ * NPA LF RAS Interrupt Enable Clear Register This register clears ++ * interrupt enable bits. ++ */ ++union npa_lf_ras_ena_w1c { ++ u64 u; ++ struct npa_lf_ras_ena_w1c_s { ++ u64 aura_poison : 1; ++ u64 pool_poison : 1; ++ u64 stack_poison : 1; ++ u64 qint_poison : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct npa_lf_ras_ena_w1c_s cn; */ ++}; ++ ++static inline u64 NPA_LF_RAS_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_RAS_ENA_W1C(void) ++{ ++ return 0x230; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_ras_ena_w1s ++ * ++ * NPA LF RAS Interrupt Enable Set Register This register sets interrupt ++ * enable bits. ++ */ ++union npa_lf_ras_ena_w1s { ++ u64 u; ++ struct npa_lf_ras_ena_w1s_s { ++ u64 aura_poison : 1; ++ u64 pool_poison : 1; ++ u64 stack_poison : 1; ++ u64 qint_poison : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct npa_lf_ras_ena_w1s_s cn; */ ++}; ++ ++static inline u64 NPA_LF_RAS_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_RAS_ENA_W1S(void) ++{ ++ return 0x238; ++} ++ ++/** ++ * Register (RVU_PFVF_BAR2) npa_lf_ras_w1s ++ * ++ * NPA LF RAS Interrupt Set Register This register sets interrupt bits. ++ */ ++union npa_lf_ras_w1s { ++ u64 u; ++ struct npa_lf_ras_w1s_s { ++ u64 aura_poison : 1; ++ u64 pool_poison : 1; ++ u64 stack_poison : 1; ++ u64 qint_poison : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct npa_lf_ras_w1s_s cn; */ ++}; ++ ++static inline u64 NPA_LF_RAS_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_LF_RAS_W1S(void) ++{ ++ return 0x228; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_priv_af_int_cfg ++ * ++ * NPA Privileged AF Interrupt Configuration Register ++ */ ++union npa_priv_af_int_cfg { ++ u64 u; ++ struct npa_priv_af_int_cfg_s { ++ u64 msix_offset : 11; ++ u64 reserved_11 : 1; ++ u64 msix_size : 8; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct npa_priv_af_int_cfg_s cn; */ ++}; ++ ++static inline u64 NPA_PRIV_AF_INT_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_PRIV_AF_INT_CFG(void) ++{ ++ return 0x10000; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_priv_lf#_cfg ++ * ++ * NPA Privileged Local Function Configuration Registers These registers ++ * allow each NPA local function (LF) to be provisioned to a VF/PF slot ++ * for RVU. See also NPA_AF_RVU_LF_CFG_DEBUG. Software should read this ++ * register after write to ensure that the LF is mapped to [PF_FUNC] ++ * before issuing transactions to the mapped PF and function. [SLOT] ++ * must be zero. Internal: Hardware ignores [SLOT] and always assumes ++ * 0x0. ++ */ ++union npa_priv_lfx_cfg { ++ u64 u; ++ struct npa_priv_lfx_cfg_s { ++ u64 slot : 8; ++ u64 pf_func : 16; ++ u64 reserved_24_62 : 39; ++ u64 ena : 1; ++ } s; ++ /* struct npa_priv_lfx_cfg_s cn; */ ++}; ++ ++static inline u64 NPA_PRIV_LFX_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_PRIV_LFX_CFG(u64 a) ++{ ++ return 0x10010 + 0x100 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npa_priv_lf#_int_cfg ++ * ++ * NPA Privileged LF Interrupt Configuration Registers ++ */ ++union npa_priv_lfx_int_cfg { ++ u64 u; ++ struct npa_priv_lfx_int_cfg_s { ++ u64 msix_offset : 11; ++ u64 reserved_11 : 1; ++ u64 msix_size : 8; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct npa_priv_lfx_int_cfg_s cn; */ ++}; ++ ++static inline u64 NPA_PRIV_LFX_INT_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPA_PRIV_LFX_INT_CFG(u64 a) ++{ ++ return 0x10020 + 0x100 * a; ++} ++ ++#endif /* __CSRS_NPA_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx2/csrs/csrs-npc.h b/arch/arm/include/asm/arch-octeontx2/csrs/csrs-npc.h +new file mode 100644 +index 0000000000..6fe5bfa8b0 +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx2/csrs/csrs-npc.h +@@ -0,0 +1,1936 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++#ifndef __CSRS_NPC_H__ ++#define __CSRS_NPC_H__ ++ ++/** ++ * @file ++ * ++ * Configuration and status register (CSR) address and type definitions for ++ * NPC. ++ * ++ * This file is auto generated. Do not edit. ++ * ++ */ ++ ++/** ++ * Enumeration npc_errlev_e ++ * ++ * NPC Error Level Enumeration Enumerates the lowest protocol layer ++ * containing an error. ++ */ ++#define NPC_ERRLEV_E_LA (1) ++#define NPC_ERRLEV_E_LB (2) ++#define NPC_ERRLEV_E_LC (3) ++#define NPC_ERRLEV_E_LD (4) ++#define NPC_ERRLEV_E_LE (5) ++#define NPC_ERRLEV_E_LF (6) ++#define NPC_ERRLEV_E_LG (7) ++#define NPC_ERRLEV_E_LH (8) ++#define NPC_ERRLEV_E_NIX (0xf) ++#define NPC_ERRLEV_E_RX(a) (0 + (a)) ++#define NPC_ERRLEV_E_RE (0) ++ ++/** ++ * Enumeration npc_intf_e ++ * ++ * NPC Interface Enumeration Enumerates the NPC interfaces. ++ */ ++#define NPC_INTF_E_NIXX_RX(a) (0 + 2 * (a)) ++#define NPC_INTF_E_NIXX_TX(a) (1 + 2 * (a)) ++ ++/** ++ * Enumeration npc_lid_e ++ * ++ * NPC Layer ID Enumeration Enumerates layers parsed by NPC. ++ */ ++#define NPC_LID_E_LA (0) ++#define NPC_LID_E_LB (1) ++#define NPC_LID_E_LC (2) ++#define NPC_LID_E_LD (3) ++#define NPC_LID_E_LE (4) ++#define NPC_LID_E_LF (5) ++#define NPC_LID_E_LG (6) ++#define NPC_LID_E_LH (7) ++ ++/** ++ * Enumeration npc_lkupop_e ++ * ++ * NPC Lookup Operation Enumeration Enumerates the lookup operation for ++ * NPC_AF_LKUP_CTL[OP]. ++ */ ++#define NPC_LKUPOP_E_KEY (1) ++#define NPC_LKUPOP_E_PKT (0) ++ ++/** ++ * Enumeration npc_mcamkeyw_e ++ * ++ * NPC MCAM Search Key Width Enumeration ++ */ ++#define NPC_MCAMKEYW_E_X1 (0) ++#define NPC_MCAMKEYW_E_X2 (1) ++#define NPC_MCAMKEYW_E_X4 (2) ++ ++/** ++ * Structure npc_layer_info_s ++ * ++ * NPC Layer Parse Information Structure This structure specifies the ++ * format of NPC_RESULT_S[LA,LB,...,LH]. ++ */ ++union npc_layer_info_s { ++ u32 u; ++ struct npc_layer_info_s_s { ++ u32 lptr : 8; ++ u32 flags : 8; ++ u32 ltype : 4; ++ u32 reserved_20_31 : 12; ++ } s; ++ /* struct npc_layer_info_s_s cn; */ ++}; ++ ++/** ++ * Structure npc_layer_kex_s ++ * ++ * NPC Layer MCAM Search Key Extract Structure This structure specifies ++ * the format of each of the NPC_PARSE_KEX_S[LA,LB,...,LH] fields. It ++ * contains the subset of NPC_LAYER_INFO_S fields that can be included in ++ * the MCAM search key. See NPC_PARSE_KEX_S and NPC_AF_INTF()_KEX_CFG. ++ */ ++union npc_layer_kex_s { ++ u32 u; ++ struct npc_layer_kex_s_s { ++ u32 flags : 8; ++ u32 ltype : 4; ++ u32 reserved_12_31 : 20; ++ } s; ++ /* struct npc_layer_kex_s_s cn; */ ++}; ++ ++/** ++ * Structure npc_mcam_key_x1_s ++ * ++ * NPC MCAM Search Key X1 Structure This structure specifies the MCAM ++ * search key format used by an interface when ++ * NPC_AF_INTF()_KEX_CFG[KEYW] = NPC_MCAMKEYW_E::X1. ++ */ ++union npc_mcam_key_x1_s { ++ u64 u[3]; ++ struct npc_mcam_key_x1_s_s { ++ u64 intf : 2; ++ u64 reserved_2_63 : 62; ++ u64 kw0 : 64; ++ u64 kw1 : 48; ++ u64 reserved_176_191 : 16; ++ } s; ++ /* struct npc_mcam_key_x1_s_s cn; */ ++}; ++ ++/** ++ * Structure npc_mcam_key_x2_s ++ * ++ * NPC MCAM Search Key X2 Structure This structure specifies the MCAM ++ * search key format used by an interface when ++ * NPC_AF_INTF()_KEX_CFG[KEYW] = NPC_MCAMKEYW_E::X2. ++ */ ++union npc_mcam_key_x2_s { ++ u64 u[5]; ++ struct npc_mcam_key_x2_s_s { ++ u64 intf : 2; ++ u64 reserved_2_63 : 62; ++ u64 kw0 : 64; ++ u64 kw1 : 64; ++ u64 kw2 : 64; ++ u64 kw3 : 32; ++ u64 reserved_288_319 : 32; ++ } s; ++ /* struct npc_mcam_key_x2_s_s cn; */ ++}; ++ ++/** ++ * Structure npc_mcam_key_x4_s ++ * ++ * NPC MCAM Search Key X4 Structure This structure specifies the MCAM ++ * search key format used by an interface when ++ * NPC_AF_INTF()_KEX_CFG[KEYW] = NPC_MCAMKEYW_E::X4. ++ */ ++union npc_mcam_key_x4_s { ++ u64 u[8]; ++ struct npc_mcam_key_x4_s_s { ++ u64 intf : 2; ++ u64 reserved_2_63 : 62; ++ u64 kw0 : 64; ++ u64 kw1 : 64; ++ u64 kw2 : 64; ++ u64 kw3 : 64; ++ u64 kw4 : 64; ++ u64 kw5 : 64; ++ u64 kw6 : 64; ++ } s; ++ /* struct npc_mcam_key_x4_s_s cn; */ ++}; ++ ++/** ++ * Structure npc_parse_kex_s ++ * ++ * NPC Parse Key Extract Structure This structure contains the subset of ++ * NPC_RESULT_S fields that can be included in the MCAM search key. See ++ * NPC_AF_INTF()_KEX_CFG. ++ */ ++union npc_parse_kex_s { ++ u64 u[2]; ++ struct npc_parse_kex_s_s { ++ u64 chan : 12; ++ u64 errlev : 4; ++ u64 errcode : 8; ++ u64 l2m : 1; ++ u64 l2b : 1; ++ u64 l3m : 1; ++ u64 l3b : 1; ++ u64 la : 12; ++ u64 lb : 12; ++ u64 lc : 12; ++ u64 ld : 12; ++ u64 le : 12; ++ u64 lf : 12; ++ u64 lg : 12; ++ u64 lh : 12; ++ u64 reserved_124_127 : 4; ++ } s; ++ /* struct npc_parse_kex_s_s cn; */ ++}; ++ ++/** ++ * Structure npc_result_s ++ * ++ * NPC Result Structure This structure contains a packet's parse and flow ++ * identification information. ++ */ ++union npc_result_s { ++ u64 u[6]; ++ struct npc_result_s_s { ++ u64 intf : 2; ++ u64 pkind : 6; ++ u64 chan : 12; ++ u64 errlev : 4; ++ u64 errcode : 8; ++ u64 l2m : 1; ++ u64 l2b : 1; ++ u64 l3m : 1; ++ u64 l3b : 1; ++ u64 eoh_ptr : 8; ++ u64 reserved_44_63 : 20; ++ u64 action : 64; ++ u64 vtag_action : 64; ++ u64 la : 20; ++ u64 lb : 20; ++ u64 lc : 20; ++ u64 reserved_252_255 : 4; ++ u64 ld : 20; ++ u64 le : 20; ++ u64 lf : 20; ++ u64 reserved_316_319 : 4; ++ u64 lg : 20; ++ u64 lh : 20; ++ u64 reserved_360_383 : 24; ++ } s; ++ /* struct npc_result_s_s cn; */ ++}; ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_active_pc ++ * ++ * NPC Interrupt-Timer Configuration Register ++ */ ++union npc_af_active_pc { ++ u64 u; ++ struct npc_af_active_pc_s { ++ u64 active_pc : 64; ++ } s; ++ /* struct npc_af_active_pc_s cn; */ ++}; ++ ++static inline u64 NPC_AF_ACTIVE_PC(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_ACTIVE_PC(void) ++{ ++ return 0x10; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_blk_rst ++ * ++ * NPC AF Block Reset Register ++ */ ++union npc_af_blk_rst { ++ u64 u; ++ struct npc_af_blk_rst_s { ++ u64 rst : 1; ++ u64 reserved_1_62 : 62; ++ u64 busy : 1; ++ } s; ++ /* struct npc_af_blk_rst_s cn; */ ++}; ++ ++static inline u64 NPC_AF_BLK_RST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_BLK_RST(void) ++{ ++ return 0x40; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_cfg ++ * ++ * NPC AF General Configuration Register ++ */ ++union npc_af_cfg { ++ u64 u; ++ struct npc_af_cfg_s { ++ u64 reserved_0_1 : 2; ++ u64 cclk_force : 1; ++ u64 force_intf_clk_en : 1; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct npc_af_cfg_s cn; */ ++}; ++ ++static inline u64 NPC_AF_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_CFG(void) ++{ ++ return 0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_const ++ * ++ * NPC AF Constants Register This register contains constants for ++ * software discovery. ++ */ ++union npc_af_const { ++ u64 u; ++ struct npc_af_const_s { ++ u64 intfs : 4; ++ u64 lids : 4; ++ u64 kpus : 5; ++ u64 reserved_13_15 : 3; ++ u64 mcam_bank_width : 10; ++ u64 reserved_26_27 : 2; ++ u64 mcam_bank_depth : 16; ++ u64 mcam_banks : 4; ++ u64 match_stats : 16; ++ } s; ++ /* struct npc_af_const_s cn; */ ++}; ++ ++static inline u64 NPC_AF_CONST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_CONST(void) ++{ ++ return 0x20; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_const1 ++ * ++ * NPC AF Constants 1 Register This register contains constants for ++ * software discovery. ++ */ ++union npc_af_const1 { ++ u64 u; ++ struct npc_af_const1_s { ++ u64 kpu_entries : 12; ++ u64 pkinds : 8; ++ u64 cpi_size : 16; ++ u64 reserved_36_62 : 27; ++ u64 have_const2 : 1; ++ } s; ++ struct npc_af_const1_cn96xx { ++ u64 kpu_entries : 12; ++ u64 pkinds : 8; ++ u64 cpi_size : 16; ++ u64 reserved_36_63 : 28; ++ } cn96xx; ++ /* struct npc_af_const1_s cn98xx; */ ++ /* struct npc_af_const1_cn96xx cnf95xx; */ ++ /* struct npc_af_const1_cn96xx loki; */ ++}; ++ ++static inline u64 NPC_AF_CONST1(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_CONST1(void) ++{ ++ return 0x30; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_const2 ++ * ++ * NPC AF Constants 2 Register This register contains constants for ++ * software discovery. ++ */ ++union npc_af_const2 { ++ u64 u; ++ struct npc_af_const2_s { ++ u64 mcam_bank_depth_ext : 16; ++ u64 match_stats_ext : 16; ++ u64 reserved_32_62 : 31; ++ u64 have_const3 : 1; ++ } s; ++ /* struct npc_af_const2_s cn; */ ++}; ++ ++static inline u64 NPC_AF_CONST2(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_CONST2(void) ++{ ++ return 0x100; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_const3 ++ * ++ * NPC AF Constants 3 Register This register contains constants for ++ * software discovery. ++ */ ++union npc_af_const3 { ++ u64 u; ++ struct npc_af_const3_s { ++ u64 reserved_0_63 : 64; ++ } s; ++ /* struct npc_af_const3_s cn; */ ++}; ++ ++static inline u64 NPC_AF_CONST3(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_CONST3(void) ++{ ++ return 0x110; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_cpi#_cfg ++ * ++ * NPC AF Channel Parse Index Table Registers ++ */ ++union npc_af_cpix_cfg { ++ u64 u; ++ struct npc_af_cpix_cfg_s { ++ u64 padd : 4; ++ u64 reserved_4_63 : 60; ++ } s; ++ /* struct npc_af_cpix_cfg_s cn; */ ++}; ++ ++static inline u64 NPC_AF_CPIX_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_CPIX_CFG(u64 a) ++{ ++ return 0x200000 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_dbg_ctl ++ * ++ * NPC AF Debug Control Register This register controls the capture of ++ * debug information in NPC_AF_KPU()_DBG, NPC_AF_MCAM_DBG, ++ * NPC_AF_DBG_DATA() and NPC_AF_DBG_RESULT(). ++ */ ++union npc_af_dbg_ctl { ++ u64 u; ++ struct npc_af_dbg_ctl_s { ++ u64 continuous : 1; ++ u64 lkup_dbg : 1; ++ u64 intf_dbg : 4; ++ u64 reserved_6_63 : 58; ++ } s; ++ /* struct npc_af_dbg_ctl_s cn; */ ++}; ++ ++static inline u64 NPC_AF_DBG_CTL(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_DBG_CTL(void) ++{ ++ return 0x3000000; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_dbg_data# ++ * ++ * NPC AF Debug Data Registers These registers contain the packet header ++ * data of the last packet/lookup whose debug information is captured by ++ * NPC_AF_DBG_CTL[INTF_DBG,LKUP_DBG]. ++ */ ++union npc_af_dbg_datax { ++ u64 u; ++ struct npc_af_dbg_datax_s { ++ u64 data : 64; ++ } s; ++ /* struct npc_af_dbg_datax_s cn; */ ++}; ++ ++static inline u64 NPC_AF_DBG_DATAX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_DBG_DATAX(u64 a) ++{ ++ return 0x3001400 + 0x10 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_dbg_result# ++ * ++ * NPC AF Debug Result Registers These registers contain the result data ++ * of the last packet/lookup whose debug information is captured by ++ * NPC_AF_DBG_CTL[INTF_DBG,LKUP_DBG]. ++ */ ++union npc_af_dbg_resultx { ++ u64 u; ++ struct npc_af_dbg_resultx_s { ++ u64 data : 64; ++ } s; ++ /* struct npc_af_dbg_resultx_s cn; */ ++}; ++ ++static inline u64 NPC_AF_DBG_RESULTX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_DBG_RESULTX(u64 a) ++{ ++ return 0x3001800 + 0x10 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_dbg_status ++ * ++ * NPC AF Debug Status Register ++ */ ++union npc_af_dbg_status { ++ u64 u; ++ struct npc_af_dbg_status_s { ++ u64 done : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npc_af_dbg_status_s cn; */ ++}; ++ ++static inline u64 NPC_AF_DBG_STATUS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_DBG_STATUS(void) ++{ ++ return 0x3000010; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_dv_fc_scratch ++ * ++ * INTERNAL: NPC AF Scratch Register Internal: This register is for ++ * internal DV purpose. ++ */ ++union npc_af_dv_fc_scratch { ++ u64 u; ++ struct npc_af_dv_fc_scratch_s { ++ u64 it : 64; ++ } s; ++ /* struct npc_af_dv_fc_scratch_s cn; */ ++}; ++ ++static inline u64 NPC_AF_DV_FC_SCRATCH(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_DV_FC_SCRATCH(void) ++{ ++ return 0x60; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_eco0 ++ * ++ * INTERNAL: ECO 0 Register ++ */ ++union npc_af_eco0 { ++ u64 u; ++ struct npc_af_eco0_s { ++ u64 eco_rw : 32; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct npc_af_eco0_s cn; */ ++}; ++ ++static inline u64 NPC_AF_ECO0(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_ECO0(void) ++{ ++ return 0x200; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_ikpu_err_ctl ++ * ++ * NPC AF Initial KPU Error Control Registers Similar to ++ * NPC_AF_KPU()_ERR_CTL, but specifies values captured in ++ * NPC_RESULT_S[ERRLEV,ERRCODE] for errors detected by the PKIND-based ++ * initial actions from NPC_AF_PKIND()_ACTION0 and ++ * NPC_AF_PKIND()_ACTION1. [DP_OFFSET_ERRCODE] from this register is ++ * never used. ++ */ ++union npc_af_ikpu_err_ctl { ++ u64 u; ++ struct npc_af_ikpu_err_ctl_s { ++ u64 errlev : 4; ++ u64 dp_offset_errcode : 8; ++ u64 ptr_advance_errcode : 8; ++ u64 var_len_offset_errcode : 8; ++ u64 reserved_28_63 : 36; ++ } s; ++ /* struct npc_af_ikpu_err_ctl_s cn; */ ++}; ++ ++static inline u64 NPC_AF_IKPU_ERR_CTL(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_IKPU_ERR_CTL(void) ++{ ++ return 0x3000080; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_intf#_kex_cfg ++ * ++ * NPC AF Interface Key Extract Configuration Registers ++ */ ++union npc_af_intfx_kex_cfg { ++ u64 u; ++ struct npc_af_intfx_kex_cfg_s { ++ u64 parse_nibble_ena : 31; ++ u64 reserved_31 : 1; ++ u64 keyw : 3; ++ u64 reserved_35_63 : 29; ++ } s; ++ /* struct npc_af_intfx_kex_cfg_s cn; */ ++}; ++ ++static inline u64 NPC_AF_INTFX_KEX_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_INTFX_KEX_CFG(u64 a) ++{ ++ return 0x1010 + 0x100 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_intf#_ldata#_flags#_cfg ++ * ++ * NPC AF Interface Layer Data Flags Configuration Registers These ++ * registers control the extraction of layer data (LDATA) into the MCAM ++ * search key for each interface based on the FLAGS\<3:0\> bits of two ++ * layers selected by NPC_AF_KEX_LDATA()_FLAGS_CFG. ++ */ ++union npc_af_intfx_ldatax_flagsx_cfg { ++ u64 u; ++ struct npc_af_intfx_ldatax_flagsx_cfg_s { ++ u64 key_offset : 6; ++ u64 reserved_6 : 1; ++ u64 ena : 1; ++ u64 hdr_offset : 8; ++ u64 bytesm1 : 4; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct npc_af_intfx_ldatax_flagsx_cfg_s cn; */ ++}; ++ ++static inline u64 NPC_AF_INTFX_LDATAX_FLAGSX_CFG(u64 a, u64 b, u64 c) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_INTFX_LDATAX_FLAGSX_CFG(u64 a, u64 b, u64 c) ++{ ++ return 0x980000 + 0x10000 * a + 0x1000 * b + 8 * c; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_intf#_lid#_lt#_ld#_cfg ++ * ++ * NPC AF Interface Layer Data Extract Configuration Registers These ++ * registers control the extraction of layer data (LDATA) into the MCAM ++ * search key for each interface. Up to two LDATA fields can be extracted ++ * per layer (LID(0..7) indexed by NPC_LID_E), with up to 16 bytes per ++ * LDATA field. For each layer, the corresponding NPC_LAYER_INFO_S[LTYPE] ++ * value in NPC_RESULT_S is used as the LTYPE(0..15) index and select the ++ * associated LDATA(0..1) registers. NPC_LAYER_INFO_S[LTYPE]=0x0 means ++ * the corresponding layer not parsed (invalid), so software should keep ++ * NPC_AF_INTF()_LID()_LT(0)_LD()_CFG[ENA] clear to disable extraction ++ * when LTYPE is zero. ++ */ ++union npc_af_intfx_lidx_ltx_ldx_cfg { ++ u64 u; ++ struct npc_af_intfx_lidx_ltx_ldx_cfg_s { ++ u64 key_offset : 6; ++ u64 flags_ena : 1; ++ u64 ena : 1; ++ u64 hdr_offset : 8; ++ u64 bytesm1 : 4; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct npc_af_intfx_lidx_ltx_ldx_cfg_s cn; */ ++}; ++ ++static inline u64 NPC_AF_INTFX_LIDX_LTX_LDX_CFG(u64 a, u64 b, u64 c, u64 d) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_INTFX_LIDX_LTX_LDX_CFG(u64 a, u64 b, u64 c, u64 d) ++{ ++ return 0x900000 + 0x10000 * a + 0x1000 * b + 0x20 * c + 8 * d; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_intf#_miss_act ++ * ++ * NPC AF Interface MCAM Miss Action Data Registers When a combination of ++ * NPC_AF_MCAME()_BANK()_CAM()_* and NPC_AF_MCAME()_BANK()_CFG[ENA] ++ * yields an MCAM miss for a packet, this register specifies the packet's ++ * match action captured in NPC_RESULT_S[ACTION]. ++ */ ++union npc_af_intfx_miss_act { ++ u64 u; ++ struct npc_af_intfx_miss_act_s { ++ u64 action : 64; ++ } s; ++ /* struct npc_af_intfx_miss_act_s cn; */ ++}; ++ ++static inline u64 NPC_AF_INTFX_MISS_ACT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_INTFX_MISS_ACT(u64 a) ++{ ++ return 0x1a00000 + 0x10 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_intf#_miss_stat_act ++ * ++ * NPC AF Interface MCAM Miss Stat Action Data Registers Used to ++ * optionally increment a NPC_AF_MATCH_STAT() counter when a packet ++ * misses an MCAM entry. ++ */ ++union npc_af_intfx_miss_stat_act { ++ u64 u; ++ struct npc_af_intfx_miss_stat_act_s { ++ u64 stat_sel : 9; ++ u64 ena : 1; ++ u64 reserved_10_11 : 2; ++ u64 stat_sel_ext : 3; ++ u64 reserved_15_63 : 49; ++ } s; ++ struct npc_af_intfx_miss_stat_act_cn96xx { ++ u64 stat_sel : 9; ++ u64 ena : 1; ++ u64 reserved_10_63 : 54; ++ } cn96xx; ++ /* struct npc_af_intfx_miss_stat_act_s cn98xx; */ ++ /* struct npc_af_intfx_miss_stat_act_cn96xx cnf95xx; */ ++ /* struct npc_af_intfx_miss_stat_act_cn96xx loki; */ ++}; ++ ++static inline u64 NPC_AF_INTFX_MISS_STAT_ACT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_INTFX_MISS_STAT_ACT(u64 a) ++{ ++ return 0x1880040 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_intf#_miss_tag_act ++ * ++ * NPC AF Interface MCAM Miss VTag Action Data Registers When a ++ * combination of NPC_AF_MCAME()_BANK()_CAM()_* and ++ * NPC_AF_MCAME()_BANK()_CFG[ENA] yields an MCAM miss for a packet, this ++ * register specifies the packet's match Vtag action captured in ++ * NPC_RESULT_S[VTAG_ACTION]. ++ */ ++union npc_af_intfx_miss_tag_act { ++ u64 u; ++ struct npc_af_intfx_miss_tag_act_s { ++ u64 vtag_action : 64; ++ } s; ++ /* struct npc_af_intfx_miss_tag_act_s cn; */ ++}; ++ ++static inline u64 NPC_AF_INTFX_MISS_TAG_ACT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_INTFX_MISS_TAG_ACT(u64 a) ++{ ++ return 0x1b00008 + 0x10 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_intf#_stat ++ * ++ * NPC AF Interface Statistics Registers Statistics per interface. Index ++ * enumerated by NPC_INTF_E. ++ */ ++union npc_af_intfx_stat { ++ u64 u; ++ struct npc_af_intfx_stat_s { ++ u64 count : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct npc_af_intfx_stat_s cn; */ ++}; ++ ++static inline u64 NPC_AF_INTFX_STAT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_INTFX_STAT(u64 a) ++{ ++ return 0x2000800 + 0x10 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_kcam_scrub_ctl ++ * ++ * NPC AF KCAM Scrub Control Register ++ */ ++union npc_af_kcam_scrub_ctl { ++ u64 u; ++ struct npc_af_kcam_scrub_ctl_s { ++ u64 ena : 1; ++ u64 reserved_1_7 : 7; ++ u64 lp_dis : 1; ++ u64 reserved_9_15 : 7; ++ u64 toth : 4; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct npc_af_kcam_scrub_ctl_s cn; */ ++}; ++ ++static inline u64 NPC_AF_KCAM_SCRUB_CTL(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_KCAM_SCRUB_CTL(void) ++{ ++ return 0xb0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_kex_ldata#_flags_cfg ++ * ++ * NPC AF Key Extract Layer Data Flags Configuration Register ++ */ ++union npc_af_kex_ldatax_flags_cfg { ++ u64 u; ++ struct npc_af_kex_ldatax_flags_cfg_s { ++ u64 lid : 3; ++ u64 reserved_3_63 : 61; ++ } s; ++ /* struct npc_af_kex_ldatax_flags_cfg_s cn; */ ++}; ++ ++static inline u64 NPC_AF_KEX_LDATAX_FLAGS_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_KEX_LDATAX_FLAGS_CFG(u64 a) ++{ ++ return 0x800 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_kpu#_cfg ++ * ++ * NPC AF KPU Configuration Registers ++ */ ++union npc_af_kpux_cfg { ++ u64 u; ++ struct npc_af_kpux_cfg_s { ++ u64 ena : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npc_af_kpux_cfg_s cn; */ ++}; ++ ++static inline u64 NPC_AF_KPUX_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_KPUX_CFG(u64 a) ++{ ++ return 0x500 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_kpu#_dbg ++ * ++ * NPC AF KPU Debug Registers This register contains information for the ++ * last packet/lookup for which debug is enabled by ++ * NPC_AF_DBG_CTL[INTF_DBG,LKUP_DBG]. The register contents are undefined ++ * when debug information is captured for a software key lookup ++ * (NPC_AF_LKUP_CTL[OP] = NPC_LKUPOP_E::KEY). ++ */ ++union npc_af_kpux_dbg { ++ u64 u; ++ struct npc_af_kpux_dbg_s { ++ u64 hit_entry : 8; ++ u64 byp : 1; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct npc_af_kpux_dbg_s cn; */ ++}; ++ ++static inline u64 NPC_AF_KPUX_DBG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_KPUX_DBG(u64 a) ++{ ++ return 0x3000020 + 0x100 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_kpu#_entry#_action0 ++ * ++ * NPC AF KPU Entry Action Data 0 Registers When a KPU's search data ++ * matches a KPU CAM entry in NPC_AF_KPU()_ENTRY()_CAM(), the ++ * corresponding entry action in NPC_AF_KPU()_ENTRY()_ACTION0 and ++ * NPC_AF_KPU()_ENTRY()_ACTION1 specifies the next state and operations ++ * to perform before exiting the KPU. ++ */ ++union npc_af_kpux_entryx_action0 { ++ u64 u; ++ struct npc_af_kpux_entryx_action0_s { ++ u64 var_len_shift : 3; ++ u64 var_len_right : 1; ++ u64 var_len_mask : 8; ++ u64 var_len_offset : 8; ++ u64 ptr_advance : 8; ++ u64 capture_flags : 8; ++ u64 capture_ltype : 4; ++ u64 capture_lid : 3; ++ u64 reserved_43 : 1; ++ u64 next_state : 8; ++ u64 parse_done : 1; ++ u64 capture_ena : 1; ++ u64 byp_count : 3; ++ u64 reserved_57_63 : 7; ++ } s; ++ /* struct npc_af_kpux_entryx_action0_s cn; */ ++}; ++ ++static inline u64 NPC_AF_KPUX_ENTRYX_ACTION0(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_KPUX_ENTRYX_ACTION0(u64 a, u64 b) ++{ ++ return 0x100020 + 0x4000 * a + 0x40 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_kpu#_entry#_action1 ++ * ++ * NPC AF KPU Entry Action Data 0 Registers See ++ * NPC_AF_KPU()_ENTRY()_ACTION0. ++ */ ++union npc_af_kpux_entryx_action1 { ++ u64 u; ++ struct npc_af_kpux_entryx_action1_s { ++ u64 dp0_offset : 8; ++ u64 dp1_offset : 8; ++ u64 dp2_offset : 8; ++ u64 errcode : 8; ++ u64 errlev : 4; ++ u64 reserved_36_63 : 28; ++ } s; ++ /* struct npc_af_kpux_entryx_action1_s cn; */ ++}; ++ ++static inline u64 NPC_AF_KPUX_ENTRYX_ACTION1(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_KPUX_ENTRYX_ACTION1(u64 a, u64 b) ++{ ++ return 0x100028 + 0x4000 * a + 0x40 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_kpu#_entry#_cam# ++ * ++ * NPC AF KPU Entry CAM Registers KPU comparison ternary data. The field ++ * values in NPC_AF_KPU()_ENTRY()_CAM() are ternary, where each data bit ++ * of the search key matches as follows: _ [CAM(1)]\=0, ++ * [CAM(0)]\=0: Always match; search key data\ don't care. _ ++ * [CAM(1)]\=0, [CAM(0)]\=1: Match when search key data\ == ++ * 0. _ [CAM(1)]\=1, [CAM(0)]\=0: Match when search key data\ ++ * == 1. _ [CAM(1)]\=1, [CAM(0)]\=1: Reserved. The reserved ++ * combination is not allowed. Hardware suppresses any write to CAM(0) or ++ * CAM(1) that would result in the reserved combination for any CAM bit. ++ * The reset value for all non-reserved fields is all zeros for CAM(1) ++ * and all ones for CAM(0), matching a search key of all zeros. Software ++ * must program a default entry for each KPU, e.g. by programming each ++ * KPU's last entry {b} (NPC_AF_KPU()_ENTRY({b})_CAM()) to always match ++ * all bits. ++ */ ++union npc_af_kpux_entryx_camx { ++ u64 u; ++ struct npc_af_kpux_entryx_camx_s { ++ u64 dp0_data : 16; ++ u64 dp1_data : 16; ++ u64 dp2_data : 16; ++ u64 state : 8; ++ u64 reserved_56_63 : 8; ++ } s; ++ /* struct npc_af_kpux_entryx_camx_s cn; */ ++}; ++ ++static inline u64 NPC_AF_KPUX_ENTRYX_CAMX(u64 a, u64 b, u64 c) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_KPUX_ENTRYX_CAMX(u64 a, u64 b, u64 c) ++{ ++ return 0x100000 + 0x4000 * a + 0x40 * b + 8 * c; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_kpu#_entry_dis# ++ * ++ * NPC AF KPU Entry Disable Registers See NPC_AF_KPU()_ENTRY()_ACTION0. ++ */ ++union npc_af_kpux_entry_disx { ++ u64 u; ++ struct npc_af_kpux_entry_disx_s { ++ u64 dis : 64; ++ } s; ++ /* struct npc_af_kpux_entry_disx_s cn; */ ++}; ++ ++static inline u64 NPC_AF_KPUX_ENTRY_DISX(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_KPUX_ENTRY_DISX(u64 a, u64 b) ++{ ++ return 0x180000 + 0x40 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_kpu#_err_ctl ++ * ++ * NPC AF KPU Error Control Registers This register specifies values ++ * captured in NPC_RESULT_S[ERRLEV,ERRCODE] when errors are detected by a ++ * KPU. ++ */ ++union npc_af_kpux_err_ctl { ++ u64 u; ++ struct npc_af_kpux_err_ctl_s { ++ u64 errlev : 4; ++ u64 dp_offset_errcode : 8; ++ u64 ptr_advance_errcode : 8; ++ u64 var_len_offset_errcode : 8; ++ u64 reserved_28_63 : 36; ++ } s; ++ /* struct npc_af_kpux_err_ctl_s cn; */ ++}; ++ ++static inline u64 NPC_AF_KPUX_ERR_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_KPUX_ERR_CTL(u64 a) ++{ ++ return 0x30000a0 + 0x100 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_kpu_diag ++ * ++ * INTERNAL : NPC AF Debug Result Registers ++ */ ++union npc_af_kpu_diag { ++ u64 u; ++ struct npc_af_kpu_diag_s { ++ u64 skip_dis : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npc_af_kpu_diag_s cn; */ ++}; ++ ++static inline u64 NPC_AF_KPU_DIAG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_KPU_DIAG(void) ++{ ++ return 0x3002000; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_lkup_ctl ++ * ++ * NPC AF Software Lookup Control Registers ++ */ ++union npc_af_lkup_ctl { ++ u64 u; ++ struct npc_af_lkup_ctl_s { ++ u64 intf : 2; ++ u64 pkind : 6; ++ u64 chan : 12; ++ u64 hdr_sizem1 : 8; ++ u64 op : 3; ++ u64 exec : 1; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct npc_af_lkup_ctl_s cn; */ ++}; ++ ++static inline u64 NPC_AF_LKUP_CTL(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_LKUP_CTL(void) ++{ ++ return 0x2000000; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_lkup_data# ++ * ++ * NPC AF Software Lookup Data Registers ++ */ ++union npc_af_lkup_datax { ++ u64 u; ++ struct npc_af_lkup_datax_s { ++ u64 data : 64; ++ } s; ++ /* struct npc_af_lkup_datax_s cn; */ ++}; ++ ++static inline u64 NPC_AF_LKUP_DATAX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_LKUP_DATAX(u64 a) ++{ ++ return 0x2000200 + 0x10 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_lkup_result# ++ * ++ * NPC AF Software Lookup Result Registers ++ */ ++union npc_af_lkup_resultx { ++ u64 u; ++ struct npc_af_lkup_resultx_s { ++ u64 data : 64; ++ } s; ++ /* struct npc_af_lkup_resultx_s cn; */ ++}; ++ ++static inline u64 NPC_AF_LKUP_RESULTX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_LKUP_RESULTX(u64 a) ++{ ++ return 0x2000400 + 0x10 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_match_stat# ++ * ++ * NPC AF Match Statistics Registers ++ */ ++union npc_af_match_statx { ++ u64 u; ++ struct npc_af_match_statx_s { ++ u64 count : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct npc_af_match_statx_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MATCH_STATX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MATCH_STATX(u64 a) ++{ ++ return 0x1880008 + 0x100 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_match_stat#_ext ++ * ++ * NPC AF Match Statistics Registers ++ */ ++union npc_af_match_statx_ext { ++ u64 u; ++ struct npc_af_match_statx_ext_s { ++ u64 count : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct npc_af_match_statx_ext_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MATCH_STATX_EXT(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MATCH_STATX_EXT(u64 a) ++{ ++ return 0x8000078 + 0x100 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcam_bank#_hit# ++ * ++ * NPC AF MCAM Bank Hit Registers ++ */ ++union npc_af_mcam_bankx_hitx { ++ u64 u; ++ struct npc_af_mcam_bankx_hitx_s { ++ u64 hit : 64; ++ } s; ++ /* struct npc_af_mcam_bankx_hitx_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAM_BANKX_HITX(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAM_BANKX_HITX(u64 a, u64 b) ++{ ++ return 0x1c80000 + 0x100 * a + 0x10 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcam_bank#_hit#_ext ++ * ++ * NPC AF MCAM Bank Hit Registers ++ */ ++union npc_af_mcam_bankx_hitx_ext { ++ u64 u; ++ struct npc_af_mcam_bankx_hitx_ext_s { ++ u64 hit : 64; ++ } s; ++ /* struct npc_af_mcam_bankx_hitx_ext_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAM_BANKX_HITX_EXT(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAM_BANKX_HITX_EXT(u64 a, u64 b) ++{ ++ return 0x8000070 + 0x1000000 * a + 0x100 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcam_dbg ++ * ++ * NPC AF MCAM Debug Register This register contains information for the ++ * last packet/lookup for which debug is enabled by ++ * NPC_AF_DBG_CTL[INTF_DBG,LKUP_DBG]. ++ */ ++union npc_af_mcam_dbg { ++ u64 u; ++ struct npc_af_mcam_dbg_s { ++ u64 hit_entry : 10; ++ u64 reserved_10_11 : 2; ++ u64 hit_bank : 2; ++ u64 reserved_14_15 : 2; ++ u64 miss : 1; ++ u64 reserved_17_63 : 47; ++ } s; ++ /* struct npc_af_mcam_dbg_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAM_DBG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAM_DBG(void) ++{ ++ return 0x3001000; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcam_scrub_ctl ++ * ++ * NPC AF MCAM Scrub Control Register ++ */ ++union npc_af_mcam_scrub_ctl { ++ u64 u; ++ struct npc_af_mcam_scrub_ctl_s { ++ u64 ena : 1; ++ u64 reserved_1_7 : 7; ++ u64 lp_dis : 1; ++ u64 reserved_9_15 : 7; ++ u64 toth : 4; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct npc_af_mcam_scrub_ctl_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAM_SCRUB_CTL(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAM_SCRUB_CTL(void) ++{ ++ return 0xa0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcame#_bank#_action ++ * ++ * NPC AF MCAM Entry Bank Action Data Registers Specifies a packet's ++ * match action captured in NPC_RESULT_S[ACTION]. When an interface is ++ * configured to use the NPC_MCAM_KEY_X2_S search key format ++ * (NPC_AF_INTF()_KEX_CFG[KEYW] = NPC_MCAMKEYW_E::X2), * ++ * NPC_AF_MCAME()_BANK(0)_ACTION/_TAG_ACT/_STAT_ACT are used if the ++ * search key matches NPC_AF_MCAME()_BANK(0..1)_CAM()_W*. * ++ * NPC_AF_MCAME()_BANK(2)_ACTION/_TAG_ACT/_STAT_ACT are used if the ++ * search key matches NPC_AF_MCAME()_BANK(2..3)_CAM()_W*. * ++ * NPC_AF_MCAME()_BANK(1,3)_ACTION/_TAG_ACT/_STAT_ACT are not used. When ++ * an interface is configured to use the NPC_MCAM_KEY_X4_S search key ++ * format (NPC_AF_INTF()_KEX_CFG[KEYW] = NPC_MCAMKEYW_E::X4): * ++ * NPC_AF_MCAME()_BANK(0)_ACTION/_TAG_ACT/_STAT_ACT are used if the ++ * search key matches NPC_AF_MCAME()_BANK(0..3)_CAM()_W*. * ++ * NPC_AF_MCAME()_BANK(1..3)_ACTION/_TAG_ACT/_STAT_ACT are not used. ++ */ ++union npc_af_mcamex_bankx_action { ++ u64 u; ++ struct npc_af_mcamex_bankx_action_s { ++ u64 action : 64; ++ } s; ++ /* struct npc_af_mcamex_bankx_action_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAMEX_BANKX_ACTION(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAMEX_BANKX_ACTION(u64 a, u64 b) ++{ ++ return 0x1900000 + 0x100 * a + 0x10 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcame#_bank#_action_ext ++ * ++ * NPC AF MCAM Entry Bank Action Data Registers ++ */ ++union npc_af_mcamex_bankx_action_ext { ++ u64 u; ++ struct npc_af_mcamex_bankx_action_ext_s { ++ u64 action : 64; ++ } s; ++ /* struct npc_af_mcamex_bankx_action_ext_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAMEX_BANKX_ACTION_EXT(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAMEX_BANKX_ACTION_EXT(u64 a, u64 b) ++{ ++ return 0x8000040 + 0x100 * a + 0x1000000 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcame#_bank#_cam#_intf ++ * ++ * NPC AF MCAM Entry Bank CAM Data Interface Registers MCAM comparison ++ * ternary data interface word. The field values in ++ * NPC_AF_MCAME()_BANK()_CAM()_INTF, NPC_AF_MCAME()_BANK()_CAM()_W0 and ++ * NPC_AF_MCAME()_BANK()_CAM()_W1 are ternary, where each data bit of ++ * the search key matches as follows: _ [CAM(1)]\=0, [CAM(0)]\=0: ++ * Always match; search key data\ don't care. _ [CAM(1)]\=0, ++ * [CAM(0)]\=1: Match when search key data\ == 0. _ ++ * [CAM(1)]\=1, [CAM(0)]\=0: Match when search key data\ == ++ * 1. _ [CAM(1)]\=1, [CAM(0)]\=1: Reserved. The reserved ++ * combination is not allowed. Hardware suppresses any write to CAM(0) or ++ * CAM(1) that would result in the reserved combination for any CAM bit. ++ * The reset value for all non-reserved fields in ++ * NPC_AF_MCAME()_BANK()_CAM()_INTF, NPC_AF_MCAME()_BANK()_CAM()_W0 and ++ * NPC_AF_MCAME()_BANK()_CAM()_W1 is all zeros for CAM(1) and all ones ++ * for CAM(0), matching a search key of all zeros. When an interface is ++ * configured to use the NPC_MCAM_KEY_X1_S search key format ++ * (NPC_AF_INTF()_KEX_CFG[KEYW] = NPC_MCAMKEYW_E::X1), the four banks of ++ * every MCAM entry are used as individual entries, each of which is ++ * independently compared with the search key as follows: _ ++ * NPC_AF_MCAME()_BANK()_CAM()_INTF[INTF] corresponds to ++ * NPC_MCAM_KEY_X1_S[INTF]. _ NPC_AF_MCAME()_BANK()_CAM()_W0[MD] ++ * corresponds to NPC_MCAM_KEY_X1_S[KW0]. _ ++ * NPC_AF_MCAME()_BANK()_CAM()_W1[MD] corresponds to ++ * NPC_MCAM_KEY_X1_S[KW1]. When an interface is configured to use the ++ * NPC_MCAM_KEY_X2_S search key format (NPC_AF_INTF()_KEX_CFG[KEYW] = ++ * NPC_MCAMKEYW_E::X2), banks 0-1 of every MCAM entry are used as one ++ * double-wide entry, banks 2-3 as a second double-wide entry, and each ++ * double-wide entry is independently compared with the search key as ++ * follows: _ NPC_AF_MCAME()_BANK(0,2)_CAM()_INTF[INTF] corresponds to ++ * NPC_MCAM_KEY_X2_S[INTF]. _ NPC_AF_MCAME()_BANK(0,2)_CAM()_W0[MD] ++ * corresponds to NPC_MCAM_KEY_X2_S[KW0]. _ ++ * NPC_AF_MCAME()_BANK(0,2)_CAM()_W1[MD] corresponds to ++ * NPC_MCAM_KEY_X2_S[KW1]\<47:0\>. _ ++ * NPC_AF_MCAME()_BANK(1,3)_CAM()_INTF[INTF] corresponds to ++ * NPC_MCAM_KEY_X2_S[INTF]. _ ++ * NPC_AF_MCAME()_BANK(1,3)_CAM()_W0[MD]\<15:0\> corresponds to ++ * NPC_MCAM_KEY_X2_S[KW1]\<63:48\>. _ ++ * NPC_AF_MCAME()_BANK(1,3)_CAM()_W0[MD]\<63:16\> corresponds to ++ * NPC_MCAM_KEY_X2_S[KW2]\<47:0\>. _ ++ * NPC_AF_MCAME()_BANK(1,3)_CAM()_W1[MD]\<15:0\> corresponds to ++ * NPC_MCAM_KEY_X2_S[KW2]\<63:48\>. _ ++ * NPC_AF_MCAME()_BANK(1,3)_CAM()_W1[MD]\<47:16\> corresponds to ++ * NPC_MCAM_KEY_X2_S[KW3]\<31:0\>. When an interface is configured to ++ * use the NPC_MCAM_KEY_X4_S search key format ++ * (NPC_AF_INTF()_KEX_CFG[KEYW] = NPC_MCAMKEYW_E::X4), the four banks of ++ * every MCAM entry are used as a single quad-wide entry that is compared ++ * with the search key as follows: _ ++ * NPC_AF_MCAME()_BANK(0)_CAM()_INTF[INTF] corresponds to ++ * NPC_MCAM_KEY_X4_S[INTF]. _ NPC_AF_MCAME()_BANK(0)_CAM()_W0[MD] ++ * corresponds to NPC_MCAM_KEY_X4_S[KW0]. _ ++ * NPC_AF_MCAME()_BANK(0)_CAM()_W1[MD] corresponds to ++ * NPC_MCAM_KEY_X4_S[KW1]\<47:0\>. _ ++ * NPC_AF_MCAME()_BANK(1)_CAM()_INTF[INTF] corresponds to ++ * NPC_MCAM_KEY_X4_S[INTF]. _ NPC_AF_MCAME()_BANK(1)_CAM()_W0[MD]\<15:0\> ++ * corresponds to NPC_MCAM_KEY_X4_S[KW1]\<63:48\>. _ ++ * NPC_AF_MCAME()_BANK(1)_CAM()_W0[MD]\<63:16\> corresponds to ++ * NPC_MCAM_KEY_X4_S[KW2]\<47:0\>. _ ++ * NPC_AF_MCAME()_BANK(1)_CAM()_W1[MD]\<15:0\> corresponds to ++ * NPC_MCAM_KEY_X4_S[KW2]\<63:48\>. _ ++ * NPC_AF_MCAME()_BANK(1)_CAM()_W1[MD]\<47:16\> corresponds to ++ * NPC_MCAM_KEY_X4_S[KW3]\<31:0\>. _ ++ * NPC_AF_MCAME()_BANK(2)_CAM()_INTF[INTF] corresponds to ++ * NPC_MCAM_KEY_X4_S[INTF]. _ NPC_AF_MCAME()_BANK(2)_CAM()_W0[MD]\<31:0\> ++ * corresponds to NPC_MCAM_KEY_X4_S[KW3]\<63:32\>. _ ++ * NPC_AF_MCAME()_BANK(2)_CAM()_W0[MD]\<63:32\> corresponds to ++ * NPC_MCAM_KEY_X4_S[KW4]\<31:0\>. _ ++ * NPC_AF_MCAME()_BANK(2)_CAM()_W1[MD]\<31:0\> corresponds to ++ * NPC_MCAM_KEY_X4_S[KW4]\<63:32\>. _ ++ * NPC_AF_MCAME()_BANK(2)_CAM()_W1[MD]\<47:32\> corresponds to ++ * NPC_MCAM_KEY_X4_S[KW5]\<15:0\>. _ ++ * NPC_AF_MCAME()_BANK(3)_CAM()_INTF[INTF] corresponds to ++ * NPC_MCAM_KEY_X4_S[INTF]. _ NPC_AF_MCAME()_BANK(3)_CAM()_W0[MD]\<47:0\> ++ * corresponds to NPC_MCAM_KEY_X4_S[KW5]\<63:16\>. _ ++ * NPC_AF_MCAME()_BANK(3)_CAM()_W0[MD]\<63:48\> corresponds to ++ * NPC_MCAM_KEY_X4_S[KW6]\<15:0\>. _ NPC_AF_MCAME()_BANK(3)_CAM()_W1[MD] ++ * corresponds to NPC_MCAM_KEY_X4_S[KW6]\<63:16\>. Note that for the X2 ++ * and X4 formats, a wide entry will not match unless the INTF fields ++ * from the associated two or four banks match the INTF value from the ++ * search key. For the X1 and X2 formats, a match in a lower-numbered ++ * bank takes priority over a match in any higher numbered banks. Within ++ * each bank, the lowest numbered matching entry takes priority over any ++ * higher numbered entry. ++ */ ++union npc_af_mcamex_bankx_camx_intf { ++ u64 u; ++ struct npc_af_mcamex_bankx_camx_intf_s { ++ u64 intf : 2; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct npc_af_mcamex_bankx_camx_intf_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAMEX_BANKX_CAMX_INTF(u64 a, u64 b, u64 c) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAMEX_BANKX_CAMX_INTF(u64 a, u64 b, u64 c) ++{ ++ return 0x1000000 + 0x400 * a + 0x40 * b + 8 * c; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcame#_bank#_cam#_intf_ext ++ * ++ * NPC AF Extended MCAM Entry Bank CAM Data Interface Registers ++ */ ++union npc_af_mcamex_bankx_camx_intf_ext { ++ u64 u; ++ struct npc_af_mcamex_bankx_camx_intf_ext_s { ++ u64 intf : 2; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct npc_af_mcamex_bankx_camx_intf_ext_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAMEX_BANKX_CAMX_INTF_EXT(u64 a, u64 b, u64 c) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAMEX_BANKX_CAMX_INTF_EXT(u64 a, u64 b, u64 c) ++{ ++ return 0x8000000 + 0x100 * a + 0x1000000 * b + 8 * c; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcame#_bank#_cam#_w0 ++ * ++ * NPC AF MCAM Entry Bank CAM Data Word 0 Registers MCAM comparison ++ * ternary data word 0. See NPC_AF_MCAME()_BANK()_CAM()_INTF. ++ */ ++union npc_af_mcamex_bankx_camx_w0 { ++ u64 u; ++ struct npc_af_mcamex_bankx_camx_w0_s { ++ u64 md : 64; ++ } s; ++ /* struct npc_af_mcamex_bankx_camx_w0_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAMEX_BANKX_CAMX_W0(u64 a, u64 b, u64 c) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAMEX_BANKX_CAMX_W0(u64 a, u64 b, u64 c) ++{ ++ return 0x1000010 + 0x400 * a + 0x40 * b + 8 * c; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcame#_bank#_cam#_w0_ext ++ * ++ * NPC AF MCAM Entry Bank CAM Data Word 0 Registers ++ */ ++union npc_af_mcamex_bankx_camx_w0_ext { ++ u64 u; ++ struct npc_af_mcamex_bankx_camx_w0_ext_s { ++ u64 md : 64; ++ } s; ++ /* struct npc_af_mcamex_bankx_camx_w0_ext_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAMEX_BANKX_CAMX_W0_EXT(u64 a, u64 b, u64 c) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAMEX_BANKX_CAMX_W0_EXT(u64 a, u64 b, u64 c) ++{ ++ return 0x8000010 + 0x100 * a + 0x1000000 * b + 8 * c; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcame#_bank#_cam#_w1 ++ * ++ * NPC AF MCAM Entry Bank Data Word 1 Registers MCAM comparison ternary ++ * data word 1. See NPC_AF_MCAME()_BANK()_CAM()_INTF. ++ */ ++union npc_af_mcamex_bankx_camx_w1 { ++ u64 u; ++ struct npc_af_mcamex_bankx_camx_w1_s { ++ u64 md : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct npc_af_mcamex_bankx_camx_w1_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAMEX_BANKX_CAMX_W1(u64 a, u64 b, u64 c) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAMEX_BANKX_CAMX_W1(u64 a, u64 b, u64 c) ++{ ++ return 0x1000020 + 0x400 * a + 0x40 * b + 8 * c; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcame#_bank#_cam#_w1_ext ++ * ++ * NPC AF MCAM Entry Bank Data Word 1 Registers ++ */ ++union npc_af_mcamex_bankx_camx_w1_ext { ++ u64 u; ++ struct npc_af_mcamex_bankx_camx_w1_ext_s { ++ u64 md : 48; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct npc_af_mcamex_bankx_camx_w1_ext_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAMEX_BANKX_CAMX_W1_EXT(u64 a, u64 b, u64 c) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAMEX_BANKX_CAMX_W1_EXT(u64 a, u64 b, u64 c) ++{ ++ return 0x8000020 + 0x100 * a + 0x1000000 * b + 8 * c; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcame#_bank#_cfg ++ * ++ * NPC AF MCAM Entry Bank Configuration Registers ++ */ ++union npc_af_mcamex_bankx_cfg { ++ u64 u; ++ struct npc_af_mcamex_bankx_cfg_s { ++ u64 ena : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npc_af_mcamex_bankx_cfg_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAMEX_BANKX_CFG(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAMEX_BANKX_CFG(u64 a, u64 b) ++{ ++ return 0x1800000 + 0x100 * a + 0x10 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcame#_bank#_cfg_ext ++ * ++ * NPC AF MCAM Entry Bank Configuration Registers ++ */ ++union npc_af_mcamex_bankx_cfg_ext { ++ u64 u; ++ struct npc_af_mcamex_bankx_cfg_ext_s { ++ u64 ena : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct npc_af_mcamex_bankx_cfg_ext_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAMEX_BANKX_CFG_EXT(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAMEX_BANKX_CFG_EXT(u64 a, u64 b) ++{ ++ return 0x8000038 + 0x100 * a + 0x1000000 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcame#_bank#_stat_act ++ * ++ * NPC AF MCAM Entry Bank Statistics Action Registers Used to optionally ++ * increment a NPC_AF_MATCH_STAT() counter when a packet matches an MCAM ++ * entry. See also NPC_AF_MCAME()_BANK()_ACTION. ++ */ ++union npc_af_mcamex_bankx_stat_act { ++ u64 u; ++ struct npc_af_mcamex_bankx_stat_act_s { ++ u64 stat_sel : 9; ++ u64 ena : 1; ++ u64 reserved_10_11 : 2; ++ u64 stat_sel_ext : 3; ++ u64 reserved_15_63 : 49; ++ } s; ++ struct npc_af_mcamex_bankx_stat_act_cn96xx { ++ u64 stat_sel : 9; ++ u64 ena : 1; ++ u64 reserved_10_63 : 54; ++ } cn96xx; ++ /* struct npc_af_mcamex_bankx_stat_act_s cn98xx; */ ++ /* struct npc_af_mcamex_bankx_stat_act_cn96xx cnf95xx; */ ++ /* struct npc_af_mcamex_bankx_stat_act_cn96xx loki; */ ++}; ++ ++static inline u64 NPC_AF_MCAMEX_BANKX_STAT_ACT(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAMEX_BANKX_STAT_ACT(u64 a, u64 b) ++{ ++ return 0x1880000 + 0x100 * a + 0x10 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcame#_bank#_stat_act_ext ++ * ++ * NPC AF MCAM Entry Bank Statistics Action Registers ++ */ ++union npc_af_mcamex_bankx_stat_act_ext { ++ u64 u; ++ struct npc_af_mcamex_bankx_stat_act_ext_s { ++ u64 stat_sel : 9; ++ u64 ena : 1; ++ u64 reserved_10_11 : 2; ++ u64 stat_sel_ext : 3; ++ u64 reserved_15_63 : 49; ++ } s; ++ /* struct npc_af_mcamex_bankx_stat_act_ext_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAMEX_BANKX_STAT_ACT_EXT(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAMEX_BANKX_STAT_ACT_EXT(u64 a, u64 b) ++{ ++ return 0x8000050 + 0x100 * a + 0x1000000 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcame#_bank#_tag_act ++ * ++ * NPC AF MCAM Entry Bank VTag Action Data Registers Specifies a packet's ++ * match Vtag action captured in NPC_RESULT_S[VTAG_ACTION]. See also ++ * NPC_AF_MCAME()_BANK()_ACTION. ++ */ ++union npc_af_mcamex_bankx_tag_act { ++ u64 u; ++ struct npc_af_mcamex_bankx_tag_act_s { ++ u64 vtag_action : 64; ++ } s; ++ /* struct npc_af_mcamex_bankx_tag_act_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAMEX_BANKX_TAG_ACT(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAMEX_BANKX_TAG_ACT(u64 a, u64 b) ++{ ++ return 0x1900008 + 0x100 * a + 0x10 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_mcame#_bank#_tag_act_ext ++ * ++ * NPC AF MCAM Entry Bank VTag Action Data Registers ++ */ ++union npc_af_mcamex_bankx_tag_act_ext { ++ u64 u; ++ struct npc_af_mcamex_bankx_tag_act_ext_s { ++ u64 vtag_action : 64; ++ } s; ++ /* struct npc_af_mcamex_bankx_tag_act_ext_s cn; */ ++}; ++ ++static inline u64 NPC_AF_MCAMEX_BANKX_TAG_ACT_EXT(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_MCAMEX_BANKX_TAG_ACT_EXT(u64 a, u64 b) ++{ ++ return 0x8000048 + 0x100 * a + 0x1000000 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_nife_bp_test ++ * ++ * INTERNAL: NPC AF NIFE Backpressure Test Register ++ */ ++union npc_af_nife_bp_test { ++ u64 u; ++ struct npc_af_nife_bp_test_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 8; ++ u64 reserved_24_59 : 36; ++ u64 enable : 4; ++ } s; ++ /* struct npc_af_nife_bp_test_s cn; */ ++}; ++ ++static inline u64 NPC_AF_NIFE_BP_TEST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_NIFE_BP_TEST(void) ++{ ++ return 0x3003008; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_nifi_bp_test ++ * ++ * INTERNAL: NPC AF NIFI Backpressure Test Register ++ */ ++union npc_af_nifi_bp_test { ++ u64 u; ++ struct npc_af_nifi_bp_test_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 8; ++ u64 reserved_24_59 : 36; ++ u64 enable : 4; ++ } s; ++ /* struct npc_af_nifi_bp_test_s cn; */ ++}; ++ ++static inline u64 NPC_AF_NIFI_BP_TEST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_NIFI_BP_TEST(void) ++{ ++ return 0x3003000; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_pck_cfg ++ * ++ * NPC AF Protocol Check Configuration Register ++ */ ++union npc_af_pck_cfg { ++ u64 u; ++ struct npc_af_pck_cfg_s { ++ u64 reserved_0 : 1; ++ u64 iip4_cksum : 1; ++ u64 oip4_cksum : 1; ++ u64 reserved_3 : 1; ++ u64 l3b : 1; ++ u64 l3m : 1; ++ u64 l2b : 1; ++ u64 l2m : 1; ++ u64 reserved_8_23 : 16; ++ u64 iip4_cksum_errcode : 8; ++ u64 oip4_cksum_errcode : 8; ++ u64 reserved_40_63 : 24; ++ } s; ++ /* struct npc_af_pck_cfg_s cn; */ ++}; ++ ++static inline u64 NPC_AF_PCK_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_PCK_CFG(void) ++{ ++ return 0x600; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_pck_def_iip4 ++ * ++ * NPC AF Protocol Check Inner IPv4 Definition Register Provides layer ++ * information used by the protocol checker to identify an inner IPv4 ++ * header. ++ */ ++union npc_af_pck_def_iip4 { ++ u64 u; ++ struct npc_af_pck_def_iip4_s { ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct npc_af_pck_def_iip4_s cn; */ ++}; ++ ++static inline u64 NPC_AF_PCK_DEF_IIP4(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_PCK_DEF_IIP4(void) ++{ ++ return 0x640; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_pck_def_oip4 ++ * ++ * NPC AF Protocol Check Outer IPv4 Definition Register Provides layer ++ * information used by the protocol checker to identify an outer IPv4 ++ * header. ++ */ ++union npc_af_pck_def_oip4 { ++ u64 u; ++ struct npc_af_pck_def_oip4_s { ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct npc_af_pck_def_oip4_s cn; */ ++}; ++ ++static inline u64 NPC_AF_PCK_DEF_OIP4(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_PCK_DEF_OIP4(void) ++{ ++ return 0x620; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_pck_def_oip6 ++ * ++ * NPC AF Protocol Check Outer IPv6 Definition Register Provides layer ++ * information used by the protocol checker to identify an outer IPv6 ++ * header. [LID] must have the same value as NPC_AF_PCK_DEF_OIP4[LID]. ++ */ ++union npc_af_pck_def_oip6 { ++ u64 u; ++ struct npc_af_pck_def_oip6_s { ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct npc_af_pck_def_oip6_s cn; */ ++}; ++ ++static inline u64 NPC_AF_PCK_DEF_OIP6(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_PCK_DEF_OIP6(void) ++{ ++ return 0x630; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_pck_def_ol2 ++ * ++ * NPC AF Protocol Check Outer L2 Definition Register Provides layer ++ * information used by the protocol checker to identify an outer L2 ++ * header. ++ */ ++union npc_af_pck_def_ol2 { ++ u64 u; ++ struct npc_af_pck_def_ol2_s { ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_11_63 : 53; ++ } s; ++ /* struct npc_af_pck_def_ol2_s cn; */ ++}; ++ ++static inline u64 NPC_AF_PCK_DEF_OL2(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_PCK_DEF_OL2(void) ++{ ++ return 0x610; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_pkind#_action0 ++ * ++ * NPC AF Port Kind Action Data 0 Registers NPC_AF_PKIND()_ACTION0 and ++ * NPC_AF_PKIND()_ACTION1 specify the initial parse state and operations ++ * to perform before entering KPU 0. ++ */ ++union npc_af_pkindx_action0 { ++ u64 u; ++ struct npc_af_pkindx_action0_s { ++ u64 var_len_shift : 3; ++ u64 var_len_right : 1; ++ u64 var_len_mask : 8; ++ u64 var_len_offset : 8; ++ u64 ptr_advance : 8; ++ u64 capture_flags : 8; ++ u64 capture_ltype : 4; ++ u64 capture_lid : 3; ++ u64 reserved_43 : 1; ++ u64 next_state : 8; ++ u64 parse_done : 1; ++ u64 capture_ena : 1; ++ u64 byp_count : 3; ++ u64 reserved_57_63 : 7; ++ } s; ++ /* struct npc_af_pkindx_action0_s cn; */ ++}; ++ ++static inline u64 NPC_AF_PKINDX_ACTION0(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_PKINDX_ACTION0(u64 a) ++{ ++ return 0x80000 + 0x40 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_pkind#_action1 ++ * ++ * NPC AF Port Kind Action Data 1 Registers NPC_AF_PKIND()_ACTION0 and ++ * NPC_AF_PKIND()_ACTION1 specify the initial parse state and operations ++ * to perform before entering KPU 0. ++ */ ++union npc_af_pkindx_action1 { ++ u64 u; ++ struct npc_af_pkindx_action1_s { ++ u64 dp0_offset : 8; ++ u64 dp1_offset : 8; ++ u64 dp2_offset : 8; ++ u64 errcode : 8; ++ u64 errlev : 4; ++ u64 reserved_36_63 : 28; ++ } s; ++ /* struct npc_af_pkindx_action1_s cn; */ ++}; ++ ++static inline u64 NPC_AF_PKINDX_ACTION1(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_PKINDX_ACTION1(u64 a) ++{ ++ return 0x80008 + 0x40 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) npc_af_pkind#_cpi_def# ++ * ++ * NPC AF Port Kind Channel Parse Index Definition Registers These ++ * registers specify the layer information and algorithm to compute a ++ * packet's channel parse index (CPI), which provides a port to channel ++ * adder for calculating NPC_RESULT_S[CHAN]. There are two CPI ++ * definitions per port kind, allowing the CPI computation to use two ++ * possible layer definitions in the parsed packet, e.g. DiffServ DSCP ++ * from either IPv4 or IPv6 header. CPI pseudocode: \ for (i = 0; ++ * i \< 2; i++) { cpi_def = NPC_AF_PKIND()_CPI_DEF(i); LX = LA, LB, ++ * ..., or LH as selected by cpi_def[LID]; if (cpi_def[ENA] && ++ * ((cpi_def[LTYPE_MATCH] & cpi_def[LTYPE_MASK]) == ++ * (NPC_RESULT_S[LX[LTYPE]] & cpi_def[LTYPE_MASK])) && ++ * ((cpi_def[FLAGS_MATCH] & cpi_def[FLAGS_MASK]) == ++ * (NPC_RESULT_S[LX[FLAGS]] & cpi_def[FLAGS_MASK]))) { // Found ++ * matching layer nibble_offset = (2*NPC_RESULT_S[LX[LPTR]]) + ++ * cpi_def[ADD_OFFSET]; add_byte = byte at nibble_offset from start ++ * of packet; cpi_add = (add_byte & cpi_def[ADD_MASK]) \>\> ++ * cpi_def[ADD_SHIFT]; cpi = cpi_def[CPI_BASE] + cpi_add; ++ * NPC_RESULT_S[CHAN] += NPC_AF_CPI(cpi)_CFG[PADD]; break; } } ++ * \ ++ */ ++union npc_af_pkindx_cpi_defx { ++ u64 u; ++ struct npc_af_pkindx_cpi_defx_s { ++ u64 cpi_base : 10; ++ u64 reserved_10_11 : 2; ++ u64 add_shift : 3; ++ u64 reserved_15 : 1; ++ u64 add_mask : 8; ++ u64 add_offset : 8; ++ u64 flags_mask : 8; ++ u64 flags_match : 8; ++ u64 ltype_mask : 4; ++ u64 ltype_match : 4; ++ u64 lid : 3; ++ u64 reserved_59_62 : 4; ++ u64 ena : 1; ++ } s; ++ /* struct npc_af_pkindx_cpi_defx_s cn; */ ++}; ++ ++static inline u64 NPC_AF_PKINDX_CPI_DEFX(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 NPC_AF_PKINDX_CPI_DEFX(u64 a, u64 b) ++{ ++ return 0x80020 + 0x40 * a + 8 * b; ++} ++ ++#endif /* __CSRS_NPC_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx2/csrs/csrs-rvu.h b/arch/arm/include/asm/arch-octeontx2/csrs/csrs-rvu.h +new file mode 100644 +index 0000000000..df64199350 +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx2/csrs/csrs-rvu.h +@@ -0,0 +1,2480 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++#ifndef __CSRS_RVU_H__ ++#define __CSRS_RVU_H__ ++ ++/** ++ * @file ++ * ++ * Configuration and status register (CSR) address and type definitions for ++ * RVU. ++ * ++ * This file is auto generated. Do not edit. ++ * ++ */ ++ ++/** ++ * Enumeration rvu_af_int_vec_e ++ * ++ * RVU Admin Function Interrupt Vector Enumeration Enumerates the MSI-X ++ * interrupt vectors. Internal: RVU maintains the state of these vectors ++ * internally, and generates GIB messages for it without accessing the ++ * MSI-X table region in LLC/DRAM. ++ */ ++#define RVU_AF_INT_VEC_E_GEN (3) ++#define RVU_AF_INT_VEC_E_MBOX (4) ++#define RVU_AF_INT_VEC_E_PFFLR (1) ++#define RVU_AF_INT_VEC_E_PFME (2) ++#define RVU_AF_INT_VEC_E_POISON (0) ++ ++/** ++ * Enumeration rvu_bar_e ++ * ++ * RVU Base Address Register Enumeration Enumerates the base address ++ * registers. Internal: For documentation only. ++ */ ++#define RVU_BAR_E_RVU_PFX_BAR0(a) (0x840000000000ll + 0x1000000000ll * (a)) ++#define RVU_BAR_E_RVU_PFX_BAR0_SIZE 0x10000000ull ++#define RVU_BAR_E_RVU_PFX_FUNCX_BAR2(a, b) \ ++ (0x840200000000ll + 0x1000000000ll * (a) + 0x2000000ll * (b)) ++#define RVU_BAR_E_RVU_PFX_FUNCX_BAR2_SIZE 0x100000ull ++#define RVU_BAR_E_RVU_PFX_FUNCX_BAR4(a, b) \ ++ (0x840400000000ll + 0x1000000000ll * (a) + 0x2000000ll * (b)) ++#define RVU_BAR_E_RVU_PFX_FUNCX_BAR4_SIZE 0x10000ull ++ ++/** ++ * Enumeration rvu_block_addr_e ++ * ++ * RVU Block Address Enumeration Enumerates addressing of RVU resource ++ * blocks within each RVU BAR, i.e. values of RVU_FUNC_ADDR_S[BLOCK] and ++ * RVU_AF_ADDR_S[BLOCK]. CNXXXX may not implement all enumerated blocks. ++ * Software can read RVU_PF/RVU_VF_BLOCK_ADDR()_DISC[IMP] to discover ++ * which blocks are implemented and enabled. ++ */ ++#define RVU_BLOCK_ADDR_E_CPTX(a) (0xa + (a)) ++#define RVU_BLOCK_ADDR_E_LMT (1) ++#define RVU_BLOCK_ADDR_E_NDCX(a) (0xc + (a)) ++#define RVU_BLOCK_ADDR_E_NIXX(a) (4 + (a)) ++#define RVU_BLOCK_ADDR_E_NPA (3) ++#define RVU_BLOCK_ADDR_E_NPC (6) ++#define RVU_BLOCK_ADDR_E_RX(a) (0 + (a)) ++#define RVU_BLOCK_ADDR_E_REEX(a) (0x14 + (a)) ++#define RVU_BLOCK_ADDR_E_RVUM (0) ++#define RVU_BLOCK_ADDR_E_SSO (7) ++#define RVU_BLOCK_ADDR_E_SSOW (8) ++#define RVU_BLOCK_ADDR_E_TIM (9) ++ ++/** ++ * Enumeration rvu_block_type_e ++ * ++ * RVU Block Type Enumeration Enumerates values of ++ * RVU_PF/RVU_VF_BLOCK_ADDR()_DISC[BTYPE]. ++ */ ++#define RVU_BLOCK_TYPE_E_CPT (9) ++#define RVU_BLOCK_TYPE_E_DDF (0xb) ++#define RVU_BLOCK_TYPE_E_LMT (2) ++#define RVU_BLOCK_TYPE_E_NDC (0xa) ++#define RVU_BLOCK_TYPE_E_NIX (3) ++#define RVU_BLOCK_TYPE_E_NPA (4) ++#define RVU_BLOCK_TYPE_E_NPC (5) ++#define RVU_BLOCK_TYPE_E_RAD (0xd) ++#define RVU_BLOCK_TYPE_E_REE (0xe) ++#define RVU_BLOCK_TYPE_E_RVUM (0) ++#define RVU_BLOCK_TYPE_E_SSO (6) ++#define RVU_BLOCK_TYPE_E_SSOW (7) ++#define RVU_BLOCK_TYPE_E_TIM (8) ++#define RVU_BLOCK_TYPE_E_ZIP (0xc) ++ ++/** ++ * Enumeration rvu_bus_lf_e ++ * ++ * INTERNAL: RVU Bus LF Range Enumeration Enumerates the LF range for ++ * the RVU bus. Internal: This is an enum used in csr3 virtual equations. ++ */ ++#define RVU_BUS_LF_E_RVU_BUS_LFX(a) (0 + 0x2000000 * (a)) ++ ++/** ++ * Enumeration rvu_bus_lf_slot_e ++ * ++ * INTERNAL: RVU Bus LF Slot Range Enumeration Enumerates the LF and ++ * Slot range for the RVU bus. Internal: This is an enum used in csr3 ++ * virtual equations. ++ */ ++#define RVU_BUS_LF_SLOT_E_RVU_BUS_LFX_SLOTX(a, b) \ ++ (0 + 0x2000000 * (a) + 0x1000 * (b)) ++ ++/** ++ * Enumeration rvu_bus_pf_e ++ * ++ * INTERNAL: RVU Bus PF Range Enumeration Enumerates the PF range for ++ * the RVU bus. Internal: This is an enum used in csr3 virtual equations. ++ */ ++#define RVU_BUS_PF_E_RVU_BUS_PFX(a) (0ll + 0x1000000000ll * (a)) ++ ++/** ++ * Enumeration rvu_bus_pfvf_e ++ * ++ * INTERNAL: RVU Bus PFVF Range Enumeration Enumerates the PF and VF ++ * ranges for the RVU bus. Internal: This is an enum used in csr3 virtual ++ * equations. ++ */ ++#define RVU_BUS_PFVF_E_RVU_BUS_PFX(a) (0 + 0x2000000 * (a)) ++#define RVU_BUS_PFVF_E_RVU_BUS_VFX(a) (0 + 0x2000000 * (a)) ++ ++/** ++ * Enumeration rvu_busbar_e ++ * ++ * INTERNAL: RVU Bus Base Address Region Enumeration Enumerates the base ++ * address region for the RVU bus. Internal: This is an enum used in csr3 ++ * virtual equations. ++ */ ++#define RVU_BUSBAR_E_RVU_BUSBAR0 (0) ++#define RVU_BUSBAR_E_RVU_BUSBAR2 (0x200000000ll) ++ ++/** ++ * Enumeration rvu_busdid_e ++ * ++ * INTERNAL: RVU Bus DID Enumeration Enumerates the DID offset for the ++ * RVU bus. Internal: This is an enum used in csr3 virtual equations. ++ */ ++#define RVU_BUSDID_E_RVU_BUSDID (0x840000000000ll) ++ ++/** ++ * Enumeration rvu_pf_int_vec_e ++ * ++ * RVU PF Interrupt Vector Enumeration Enumerates the MSI-X interrupt ++ * vectors. ++ */ ++#define RVU_PF_INT_VEC_E_AFPF_MBOX (6) ++#define RVU_PF_INT_VEC_E_VFFLRX(a) (0 + (a)) ++#define RVU_PF_INT_VEC_E_VFMEX(a) (2 + (a)) ++#define RVU_PF_INT_VEC_E_VFPF_MBOXX(a) (4 + (a)) ++ ++/** ++ * Enumeration rvu_vf_int_vec_e ++ * ++ * RVU VF Interrupt Vector Enumeration Enumerates the MSI-X interrupt ++ * vectors. ++ */ ++#define RVU_VF_INT_VEC_E_MBOX (0) ++ ++/** ++ * Structure rvu_af_addr_s ++ * ++ * RVU Admin Function Register Address Structure Address format for ++ * accessing shared Admin Function (AF) registers in RVU PF BAR0. These ++ * registers may be accessed by all RVU PFs whose ++ * RVU_PRIV_PF()_CFG[AF_ENA] bit is set. ++ */ ++union rvu_af_addr_s { ++ u64 u; ++ struct rvu_af_addr_s_s { ++ u64 addr : 28; ++ u64 block : 5; ++ u64 reserved_33_63 : 31; ++ } s; ++ /* struct rvu_af_addr_s_s cn; */ ++}; ++ ++/** ++ * Structure rvu_func_addr_s ++ * ++ * RVU Function-unique Address Structure Address format for accessing ++ * function-unique registers in RVU PF/FUNC BAR2. ++ */ ++union rvu_func_addr_s { ++ u32 u; ++ struct rvu_func_addr_s_s { ++ u32 addr : 12; ++ u32 lf_slot : 8; ++ u32 block : 5; ++ u32 reserved_25_31 : 7; ++ } s; ++ /* struct rvu_func_addr_s_s cn; */ ++}; ++ ++/** ++ * Structure rvu_msix_vec_s ++ * ++ * RVU MSI-X Vector Structure Format of entries in the RVU MSI-X table ++ * region in LLC/DRAM. See RVU_PRIV_PF()_MSIX_CFG. ++ */ ++union rvu_msix_vec_s { ++ u64 u[2]; ++ struct rvu_msix_vec_s_s { ++ u64 addr : 64; ++ u64 data : 32; ++ u64 mask : 1; ++ u64 pend : 1; ++ u64 reserved_98_127 : 30; ++ } s; ++ /* struct rvu_msix_vec_s_s cn; */ ++}; ++ ++/** ++ * Structure rvu_pf_func_s ++ * ++ * RVU PF Function Identification Structure Identifies an RVU PF/VF, and ++ * format of *_PRIV_LF()_CFG[PF_FUNC] in RVU resource blocks, e.g. ++ * NPA_PRIV_LF()_CFG[PF_FUNC]. Internal: Also used for PF/VF ++ * identification on inter-coprocessor hardware interfaces (NPA, SSO, ++ * CPT, ...). ++ */ ++union rvu_pf_func_s { ++ u32 u; ++ struct rvu_pf_func_s_s { ++ u32 func : 10; ++ u32 pf : 6; ++ u32 reserved_16_31 : 16; ++ } s; ++ /* struct rvu_pf_func_s_s cn; */ ++}; ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_afpf#_mbox# ++ * ++ * RVU Admin Function AF/PF Mailbox Registers ++ */ ++union rvu_af_afpfx_mboxx { ++ u64 u; ++ struct rvu_af_afpfx_mboxx_s { ++ u64 data : 64; ++ } s; ++ /* struct rvu_af_afpfx_mboxx_s cn; */ ++}; ++ ++static inline u64 RVU_AF_AFPFX_MBOXX(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_AFPFX_MBOXX(u64 a, u64 b) ++{ ++ return 0x2000 + 0x10 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_bar2_alias# ++ * ++ * INTERNAL: RVU Admin Function BAR2 Alias Registers These registers ++ * alias to the RVU BAR2 registers for the PF and function selected by ++ * RVU_AF_BAR2_SEL[PF_FUNC]. Internal: Not implemented. Placeholder for ++ * bug33464. ++ */ ++union rvu_af_bar2_aliasx { ++ u64 u; ++ struct rvu_af_bar2_aliasx_s { ++ u64 data : 64; ++ } s; ++ /* struct rvu_af_bar2_aliasx_s cn; */ ++}; ++ ++static inline u64 RVU_AF_BAR2_ALIASX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_BAR2_ALIASX(u64 a) ++{ ++ return 0x9100000 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_bar2_sel ++ * ++ * INTERNAL: RVU Admin Function BAR2 Select Register This register ++ * configures BAR2 accesses from the RVU_AF_BAR2_ALIAS() registers in ++ * BAR0. Internal: Not implemented. Placeholder for bug33464. ++ */ ++union rvu_af_bar2_sel { ++ u64 u; ++ struct rvu_af_bar2_sel_s { ++ u64 alias_pf_func : 16; ++ u64 alias_ena : 1; ++ u64 reserved_17_63 : 47; ++ } s; ++ /* struct rvu_af_bar2_sel_s cn; */ ++}; ++ ++static inline u64 RVU_AF_BAR2_SEL(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_BAR2_SEL(void) ++{ ++ return 0x9000000; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_blk_rst ++ * ++ * RVU Master Admin Function Block Reset Register ++ */ ++union rvu_af_blk_rst { ++ u64 u; ++ struct rvu_af_blk_rst_s { ++ u64 rst : 1; ++ u64 reserved_1_62 : 62; ++ u64 busy : 1; ++ } s; ++ /* struct rvu_af_blk_rst_s cn; */ ++}; ++ ++static inline u64 RVU_AF_BLK_RST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_BLK_RST(void) ++{ ++ return 0x30; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_bp_test ++ * ++ * INTERNAL: RVUM Backpressure Test Registers ++ */ ++union rvu_af_bp_test { ++ u64 u; ++ struct rvu_af_bp_test_s { ++ u64 lfsr_freq : 12; ++ u64 reserved_12_15 : 4; ++ u64 bp_cfg : 16; ++ u64 enable : 8; ++ u64 reserved_40_63 : 24; ++ } s; ++ /* struct rvu_af_bp_test_s cn; */ ++}; ++ ++static inline u64 RVU_AF_BP_TEST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_BP_TEST(void) ++{ ++ return 0x4000; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_eco ++ * ++ * INTERNAL: RVU Admin Function ECO Register ++ */ ++union rvu_af_eco { ++ u64 u; ++ struct rvu_af_eco_s { ++ u64 eco_rw : 32; ++ u64 reserved_32_63 : 32; ++ } s; ++ /* struct rvu_af_eco_s cn; */ ++}; ++ ++static inline u64 RVU_AF_ECO(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_ECO(void) ++{ ++ return 0x20; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_gen_int ++ * ++ * RVU Admin Function General Interrupt Register This register contains ++ * General interrupt summary bits. ++ */ ++union rvu_af_gen_int { ++ u64 u; ++ struct rvu_af_gen_int_s { ++ u64 unmapped : 1; ++ u64 msix_fault : 1; ++ u64 bar4_mem_fault : 1; ++ u64 reserved_3_63 : 61; ++ } s; ++ struct rvu_af_gen_int_cn96xx { ++ u64 unmapped : 1; ++ u64 msix_fault : 1; ++ u64 reserved_2_63 : 62; ++ } cn96xx; ++ /* struct rvu_af_gen_int_s cn98xx; */ ++ /* struct rvu_af_gen_int_cn96xx cnf95xx; */ ++ /* struct rvu_af_gen_int_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_GEN_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_GEN_INT(void) ++{ ++ return 0x120; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_gen_int_ena_w1c ++ * ++ * RVU Admin Function General Interrupt Enable Clear Register This ++ * register clears interrupt enable bits. ++ */ ++union rvu_af_gen_int_ena_w1c { ++ u64 u; ++ struct rvu_af_gen_int_ena_w1c_s { ++ u64 unmapped : 1; ++ u64 msix_fault : 1; ++ u64 bar4_mem_fault : 1; ++ u64 reserved_3_63 : 61; ++ } s; ++ struct rvu_af_gen_int_ena_w1c_cn96xx { ++ u64 unmapped : 1; ++ u64 msix_fault : 1; ++ u64 reserved_2_63 : 62; ++ } cn96xx; ++ /* struct rvu_af_gen_int_ena_w1c_s cn98xx; */ ++ /* struct rvu_af_gen_int_ena_w1c_cn96xx cnf95xx; */ ++ /* struct rvu_af_gen_int_ena_w1c_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_GEN_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_GEN_INT_ENA_W1C(void) ++{ ++ return 0x138; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_gen_int_ena_w1s ++ * ++ * RVU Admin Function General Interrupt Enable Set Register This register ++ * sets interrupt enable bits. ++ */ ++union rvu_af_gen_int_ena_w1s { ++ u64 u; ++ struct rvu_af_gen_int_ena_w1s_s { ++ u64 unmapped : 1; ++ u64 msix_fault : 1; ++ u64 bar4_mem_fault : 1; ++ u64 reserved_3_63 : 61; ++ } s; ++ struct rvu_af_gen_int_ena_w1s_cn96xx { ++ u64 unmapped : 1; ++ u64 msix_fault : 1; ++ u64 reserved_2_63 : 62; ++ } cn96xx; ++ /* struct rvu_af_gen_int_ena_w1s_s cn98xx; */ ++ /* struct rvu_af_gen_int_ena_w1s_cn96xx cnf95xx; */ ++ /* struct rvu_af_gen_int_ena_w1s_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_GEN_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_GEN_INT_ENA_W1S(void) ++{ ++ return 0x130; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_gen_int_w1s ++ * ++ * RVU Admin Function General Interrupt Set Register This register sets ++ * interrupt bits. ++ */ ++union rvu_af_gen_int_w1s { ++ u64 u; ++ struct rvu_af_gen_int_w1s_s { ++ u64 unmapped : 1; ++ u64 msix_fault : 1; ++ u64 bar4_mem_fault : 1; ++ u64 reserved_3_63 : 61; ++ } s; ++ struct rvu_af_gen_int_w1s_cn96xx { ++ u64 unmapped : 1; ++ u64 msix_fault : 1; ++ u64 reserved_2_63 : 62; ++ } cn96xx; ++ /* struct rvu_af_gen_int_w1s_s cn98xx; */ ++ /* struct rvu_af_gen_int_w1s_cn96xx cnf95xx; */ ++ /* struct rvu_af_gen_int_w1s_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_GEN_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_GEN_INT_W1S(void) ++{ ++ return 0x128; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_hwvf_rst ++ * ++ * RVU Admin Function Hardware VF Reset Register ++ */ ++union rvu_af_hwvf_rst { ++ u64 u; ++ struct rvu_af_hwvf_rst_s { ++ u64 hwvf : 8; ++ u64 reserved_8_11 : 4; ++ u64 exec : 1; ++ u64 reserved_13_63 : 51; ++ } s; ++ /* struct rvu_af_hwvf_rst_s cn; */ ++}; ++ ++static inline u64 RVU_AF_HWVF_RST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_HWVF_RST(void) ++{ ++ return 0x2850; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_msixtr_base ++ * ++ * RVU Admin Function MSI-X Table Region Base-Address Register ++ */ ++union rvu_af_msixtr_base { ++ u64 u; ++ struct rvu_af_msixtr_base_s { ++ u64 reserved_0_6 : 7; ++ u64 addr : 46; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct rvu_af_msixtr_base_s cn; */ ++}; ++ ++static inline u64 RVU_AF_MSIXTR_BASE(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_MSIXTR_BASE(void) ++{ ++ return 0x10; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pf#_vf_bar4_addr ++ * ++ * RVU Admin Function PF/VF BAR4 Address Registers ++ */ ++union rvu_af_pfx_vf_bar4_addr { ++ u64 u; ++ struct rvu_af_pfx_vf_bar4_addr_s { ++ u64 reserved_0_15 : 16; ++ u64 addr : 48; ++ } s; ++ /* struct rvu_af_pfx_vf_bar4_addr_s cn; */ ++}; ++ ++static inline u64 RVU_AF_PFX_VF_BAR4_ADDR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PFX_VF_BAR4_ADDR(u64 a) ++{ ++ return 0x1000 + 0x10 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pf_bar4_addr ++ * ++ * RVU Admin Function PF BAR4 Address Registers ++ */ ++union rvu_af_pf_bar4_addr { ++ u64 u; ++ struct rvu_af_pf_bar4_addr_s { ++ u64 reserved_0_15 : 16; ++ u64 addr : 48; ++ } s; ++ /* struct rvu_af_pf_bar4_addr_s cn; */ ++}; ++ ++static inline u64 RVU_AF_PF_BAR4_ADDR(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PF_BAR4_ADDR(void) ++{ ++ return 0x40; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pf_rst ++ * ++ * RVU Admin Function PF Reset Register ++ */ ++union rvu_af_pf_rst { ++ u64 u; ++ struct rvu_af_pf_rst_s { ++ u64 pf : 5; ++ u64 reserved_5_11 : 7; ++ u64 exec : 1; ++ u64 reserved_13_63 : 51; ++ } s; ++ struct rvu_af_pf_rst_cn96xx { ++ u64 pf : 4; ++ u64 reserved_4_11 : 8; ++ u64 exec : 1; ++ u64 reserved_13_63 : 51; ++ } cn96xx; ++ /* struct rvu_af_pf_rst_s cn98xx; */ ++ /* struct rvu_af_pf_rst_cn96xx cnf95xx; */ ++ /* struct rvu_af_pf_rst_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_PF_RST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PF_RST(void) ++{ ++ return 0x2840; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pfaf_mbox_int ++ * ++ * RVU Admin Function PF to AF Mailbox Interrupt Registers ++ */ ++union rvu_af_pfaf_mbox_int { ++ u64 u; ++ struct rvu_af_pfaf_mbox_int_s { ++ u64 mbox : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ struct rvu_af_pfaf_mbox_int_cn96xx { ++ u64 mbox : 16; ++ u64 reserved_16_63 : 48; ++ } cn96xx; ++ /* struct rvu_af_pfaf_mbox_int_s cn98xx; */ ++ /* struct rvu_af_pfaf_mbox_int_cn96xx cnf95xx; */ ++ /* struct rvu_af_pfaf_mbox_int_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_PFAF_MBOX_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PFAF_MBOX_INT(void) ++{ ++ return 0x2880; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pfaf_mbox_int_ena_w1c ++ * ++ * RVU Admin Function PF to AF Mailbox Interrupt Enable Clear Registers ++ * This register clears interrupt enable bits. ++ */ ++union rvu_af_pfaf_mbox_int_ena_w1c { ++ u64 u; ++ struct rvu_af_pfaf_mbox_int_ena_w1c_s { ++ u64 mbox : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ struct rvu_af_pfaf_mbox_int_ena_w1c_cn96xx { ++ u64 mbox : 16; ++ u64 reserved_16_63 : 48; ++ } cn96xx; ++ /* struct rvu_af_pfaf_mbox_int_ena_w1c_s cn98xx; */ ++ /* struct rvu_af_pfaf_mbox_int_ena_w1c_cn96xx cnf95xx; */ ++ /* struct rvu_af_pfaf_mbox_int_ena_w1c_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_PFAF_MBOX_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PFAF_MBOX_INT_ENA_W1C(void) ++{ ++ return 0x2898; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pfaf_mbox_int_ena_w1s ++ * ++ * RVU Admin Function PF to AF Mailbox Interrupt Enable Set Registers ++ * This register sets interrupt enable bits. ++ */ ++union rvu_af_pfaf_mbox_int_ena_w1s { ++ u64 u; ++ struct rvu_af_pfaf_mbox_int_ena_w1s_s { ++ u64 mbox : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ struct rvu_af_pfaf_mbox_int_ena_w1s_cn96xx { ++ u64 mbox : 16; ++ u64 reserved_16_63 : 48; ++ } cn96xx; ++ /* struct rvu_af_pfaf_mbox_int_ena_w1s_s cn98xx; */ ++ /* struct rvu_af_pfaf_mbox_int_ena_w1s_cn96xx cnf95xx; */ ++ /* struct rvu_af_pfaf_mbox_int_ena_w1s_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_PFAF_MBOX_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PFAF_MBOX_INT_ENA_W1S(void) ++{ ++ return 0x2890; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pfaf_mbox_int_w1s ++ * ++ * RVU Admin Function PF to AF Mailbox Interrupt Set Registers This ++ * register sets interrupt bits. ++ */ ++union rvu_af_pfaf_mbox_int_w1s { ++ u64 u; ++ struct rvu_af_pfaf_mbox_int_w1s_s { ++ u64 mbox : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ struct rvu_af_pfaf_mbox_int_w1s_cn96xx { ++ u64 mbox : 16; ++ u64 reserved_16_63 : 48; ++ } cn96xx; ++ /* struct rvu_af_pfaf_mbox_int_w1s_s cn98xx; */ ++ /* struct rvu_af_pfaf_mbox_int_w1s_cn96xx cnf95xx; */ ++ /* struct rvu_af_pfaf_mbox_int_w1s_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_PFAF_MBOX_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PFAF_MBOX_INT_W1S(void) ++{ ++ return 0x2888; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pfflr_int ++ * ++ * RVU Admin Function PF Function Level Reset Interrupt Registers ++ */ ++union rvu_af_pfflr_int { ++ u64 u; ++ struct rvu_af_pfflr_int_s { ++ u64 flr : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ struct rvu_af_pfflr_int_cn96xx { ++ u64 flr : 16; ++ u64 reserved_16_63 : 48; ++ } cn96xx; ++ /* struct rvu_af_pfflr_int_s cn98xx; */ ++ /* struct rvu_af_pfflr_int_cn96xx cnf95xx; */ ++ /* struct rvu_af_pfflr_int_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_PFFLR_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PFFLR_INT(void) ++{ ++ return 0x28a0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pfflr_int_ena_w1c ++ * ++ * RVU Admin Function PF Function Level Reset Interrupt Enable Clear ++ * Registers This register clears interrupt enable bits. ++ */ ++union rvu_af_pfflr_int_ena_w1c { ++ u64 u; ++ struct rvu_af_pfflr_int_ena_w1c_s { ++ u64 flr : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ struct rvu_af_pfflr_int_ena_w1c_cn96xx { ++ u64 flr : 16; ++ u64 reserved_16_63 : 48; ++ } cn96xx; ++ /* struct rvu_af_pfflr_int_ena_w1c_s cn98xx; */ ++ /* struct rvu_af_pfflr_int_ena_w1c_cn96xx cnf95xx; */ ++ /* struct rvu_af_pfflr_int_ena_w1c_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_PFFLR_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PFFLR_INT_ENA_W1C(void) ++{ ++ return 0x28b8; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pfflr_int_ena_w1s ++ * ++ * RVU Admin Function PF Function Level Reset Interrupt Enable Set ++ * Registers This register sets interrupt enable bits. ++ */ ++union rvu_af_pfflr_int_ena_w1s { ++ u64 u; ++ struct rvu_af_pfflr_int_ena_w1s_s { ++ u64 flr : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ struct rvu_af_pfflr_int_ena_w1s_cn96xx { ++ u64 flr : 16; ++ u64 reserved_16_63 : 48; ++ } cn96xx; ++ /* struct rvu_af_pfflr_int_ena_w1s_s cn98xx; */ ++ /* struct rvu_af_pfflr_int_ena_w1s_cn96xx cnf95xx; */ ++ /* struct rvu_af_pfflr_int_ena_w1s_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_PFFLR_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PFFLR_INT_ENA_W1S(void) ++{ ++ return 0x28b0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pfflr_int_w1s ++ * ++ * RVU Admin Function PF Function Level Reset Interrupt Set Registers ++ * This register sets interrupt bits. ++ */ ++union rvu_af_pfflr_int_w1s { ++ u64 u; ++ struct rvu_af_pfflr_int_w1s_s { ++ u64 flr : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ struct rvu_af_pfflr_int_w1s_cn96xx { ++ u64 flr : 16; ++ u64 reserved_16_63 : 48; ++ } cn96xx; ++ /* struct rvu_af_pfflr_int_w1s_s cn98xx; */ ++ /* struct rvu_af_pfflr_int_w1s_cn96xx cnf95xx; */ ++ /* struct rvu_af_pfflr_int_w1s_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_PFFLR_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PFFLR_INT_W1S(void) ++{ ++ return 0x28a8; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pfme_int ++ * ++ * RVU Admin Function PF Bus Master Enable Interrupt Registers ++ */ ++union rvu_af_pfme_int { ++ u64 u; ++ struct rvu_af_pfme_int_s { ++ u64 me : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ struct rvu_af_pfme_int_cn96xx { ++ u64 me : 16; ++ u64 reserved_16_63 : 48; ++ } cn96xx; ++ /* struct rvu_af_pfme_int_s cn98xx; */ ++ /* struct rvu_af_pfme_int_cn96xx cnf95xx; */ ++ /* struct rvu_af_pfme_int_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_PFME_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PFME_INT(void) ++{ ++ return 0x28c0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pfme_int_ena_w1c ++ * ++ * RVU Admin Function PF Bus Master Enable Interrupt Enable Clear ++ * Registers This register clears interrupt enable bits. ++ */ ++union rvu_af_pfme_int_ena_w1c { ++ u64 u; ++ struct rvu_af_pfme_int_ena_w1c_s { ++ u64 me : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ struct rvu_af_pfme_int_ena_w1c_cn96xx { ++ u64 me : 16; ++ u64 reserved_16_63 : 48; ++ } cn96xx; ++ /* struct rvu_af_pfme_int_ena_w1c_s cn98xx; */ ++ /* struct rvu_af_pfme_int_ena_w1c_cn96xx cnf95xx; */ ++ /* struct rvu_af_pfme_int_ena_w1c_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_PFME_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PFME_INT_ENA_W1C(void) ++{ ++ return 0x28d8; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pfme_int_ena_w1s ++ * ++ * RVU Admin Function PF Bus Master Enable Interrupt Enable Set Registers ++ * This register sets interrupt enable bits. ++ */ ++union rvu_af_pfme_int_ena_w1s { ++ u64 u; ++ struct rvu_af_pfme_int_ena_w1s_s { ++ u64 me : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ struct rvu_af_pfme_int_ena_w1s_cn96xx { ++ u64 me : 16; ++ u64 reserved_16_63 : 48; ++ } cn96xx; ++ /* struct rvu_af_pfme_int_ena_w1s_s cn98xx; */ ++ /* struct rvu_af_pfme_int_ena_w1s_cn96xx cnf95xx; */ ++ /* struct rvu_af_pfme_int_ena_w1s_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_PFME_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PFME_INT_ENA_W1S(void) ++{ ++ return 0x28d0; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pfme_int_w1s ++ * ++ * RVU Admin Function PF Bus Master Enable Interrupt Set Registers This ++ * register sets interrupt bits. ++ */ ++union rvu_af_pfme_int_w1s { ++ u64 u; ++ struct rvu_af_pfme_int_w1s_s { ++ u64 me : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ struct rvu_af_pfme_int_w1s_cn96xx { ++ u64 me : 16; ++ u64 reserved_16_63 : 48; ++ } cn96xx; ++ /* struct rvu_af_pfme_int_w1s_s cn98xx; */ ++ /* struct rvu_af_pfme_int_w1s_cn96xx cnf95xx; */ ++ /* struct rvu_af_pfme_int_w1s_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_PFME_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PFME_INT_W1S(void) ++{ ++ return 0x28c8; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pfme_status ++ * ++ * RVU Admin Function PF Bus Master Enable Status Registers ++ */ ++union rvu_af_pfme_status { ++ u64 u; ++ struct rvu_af_pfme_status_s { ++ u64 me : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ struct rvu_af_pfme_status_cn96xx { ++ u64 me : 16; ++ u64 reserved_16_63 : 48; ++ } cn96xx; ++ /* struct rvu_af_pfme_status_s cn98xx; */ ++ /* struct rvu_af_pfme_status_cn96xx cnf95xx; */ ++ /* struct rvu_af_pfme_status_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_PFME_STATUS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PFME_STATUS(void) ++{ ++ return 0x2800; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pftrpend ++ * ++ * RVU Admin Function PF Transaction Pending Registers ++ */ ++union rvu_af_pftrpend { ++ u64 u; ++ struct rvu_af_pftrpend_s { ++ u64 trpend : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ struct rvu_af_pftrpend_cn96xx { ++ u64 trpend : 16; ++ u64 reserved_16_63 : 48; ++ } cn96xx; ++ /* struct rvu_af_pftrpend_s cn98xx; */ ++ /* struct rvu_af_pftrpend_cn96xx cnf95xx; */ ++ /* struct rvu_af_pftrpend_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_PFTRPEND(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PFTRPEND(void) ++{ ++ return 0x2810; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_pftrpend_w1s ++ * ++ * RVU Admin Function PF Transaction Pending Set Registers This register ++ * reads or sets bits. ++ */ ++union rvu_af_pftrpend_w1s { ++ u64 u; ++ struct rvu_af_pftrpend_w1s_s { ++ u64 trpend : 24; ++ u64 reserved_24_63 : 40; ++ } s; ++ struct rvu_af_pftrpend_w1s_cn96xx { ++ u64 trpend : 16; ++ u64 reserved_16_63 : 48; ++ } cn96xx; ++ /* struct rvu_af_pftrpend_w1s_s cn98xx; */ ++ /* struct rvu_af_pftrpend_w1s_cn96xx cnf95xx; */ ++ /* struct rvu_af_pftrpend_w1s_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_PFTRPEND_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_PFTRPEND_W1S(void) ++{ ++ return 0x2820; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_ras ++ * ++ * RVU Admin Function RAS Interrupt Register This register is intended ++ * for delivery of RAS events to the SCP, so should be ignored by OS ++ * drivers. ++ */ ++union rvu_af_ras { ++ u64 u; ++ struct rvu_af_ras_s { ++ u64 msix_poison : 1; ++ u64 bar4_mem_poison : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ struct rvu_af_ras_cn96xx { ++ u64 msix_poison : 1; ++ u64 reserved_1_63 : 63; ++ } cn96xx; ++ /* struct rvu_af_ras_s cn98xx; */ ++ /* struct rvu_af_ras_cn96xx cnf95xx; */ ++ /* struct rvu_af_ras_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_RAS(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_RAS(void) ++{ ++ return 0x100; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_ras_ena_w1c ++ * ++ * RVU Admin Function RAS Interrupt Enable Clear Register This register ++ * clears interrupt enable bits. ++ */ ++union rvu_af_ras_ena_w1c { ++ u64 u; ++ struct rvu_af_ras_ena_w1c_s { ++ u64 msix_poison : 1; ++ u64 bar4_mem_poison : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ struct rvu_af_ras_ena_w1c_cn96xx { ++ u64 msix_poison : 1; ++ u64 reserved_1_63 : 63; ++ } cn96xx; ++ /* struct rvu_af_ras_ena_w1c_s cn98xx; */ ++ /* struct rvu_af_ras_ena_w1c_cn96xx cnf95xx; */ ++ /* struct rvu_af_ras_ena_w1c_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_RAS_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_RAS_ENA_W1C(void) ++{ ++ return 0x118; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_ras_ena_w1s ++ * ++ * RVU Admin Function RAS Interrupt Enable Set Register This register ++ * sets interrupt enable bits. ++ */ ++union rvu_af_ras_ena_w1s { ++ u64 u; ++ struct rvu_af_ras_ena_w1s_s { ++ u64 msix_poison : 1; ++ u64 bar4_mem_poison : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ struct rvu_af_ras_ena_w1s_cn96xx { ++ u64 msix_poison : 1; ++ u64 reserved_1_63 : 63; ++ } cn96xx; ++ /* struct rvu_af_ras_ena_w1s_s cn98xx; */ ++ /* struct rvu_af_ras_ena_w1s_cn96xx cnf95xx; */ ++ /* struct rvu_af_ras_ena_w1s_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_RAS_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_RAS_ENA_W1S(void) ++{ ++ return 0x110; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_af_ras_w1s ++ * ++ * RVU Admin Function RAS Interrupt Set Register This register sets ++ * interrupt bits. ++ */ ++union rvu_af_ras_w1s { ++ u64 u; ++ struct rvu_af_ras_w1s_s { ++ u64 msix_poison : 1; ++ u64 bar4_mem_poison : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ struct rvu_af_ras_w1s_cn96xx { ++ u64 msix_poison : 1; ++ u64 reserved_1_63 : 63; ++ } cn96xx; ++ /* struct rvu_af_ras_w1s_s cn98xx; */ ++ /* struct rvu_af_ras_w1s_cn96xx cnf95xx; */ ++ /* struct rvu_af_ras_w1s_cn96xx loki; */ ++}; ++ ++static inline u64 RVU_AF_RAS_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_AF_RAS_W1S(void) ++{ ++ return 0x108; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_block_addr#_disc ++ * ++ * RVU PF Block Address Discovery Registers These registers allow each PF ++ * driver to discover block resources that are provisioned to its PF. The ++ * register's BLOCK_ADDR index is enumerated by RVU_BLOCK_ADDR_E. ++ */ ++union rvu_pf_block_addrx_disc { ++ u64 u; ++ struct rvu_pf_block_addrx_disc_s { ++ u64 num_lfs : 9; ++ u64 reserved_9_10 : 2; ++ u64 imp : 1; ++ u64 rid : 8; ++ u64 btype : 8; ++ u64 reserved_28_63 : 36; ++ } s; ++ /* struct rvu_pf_block_addrx_disc_s cn; */ ++}; ++ ++static inline u64 RVU_PF_BLOCK_ADDRX_DISC(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_BLOCK_ADDRX_DISC(u64 a) ++{ ++ return 0x200 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_int ++ * ++ * RVU PF Interrupt Registers ++ */ ++union rvu_pf_int { ++ u64 u; ++ struct rvu_pf_int_s { ++ u64 mbox : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct rvu_pf_int_s cn; */ ++}; ++ ++static inline u64 RVU_PF_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_INT(void) ++{ ++ return 0xc20; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_int_ena_w1c ++ * ++ * RVU PF Interrupt Enable Clear Register This register clears interrupt ++ * enable bits. ++ */ ++union rvu_pf_int_ena_w1c { ++ u64 u; ++ struct rvu_pf_int_ena_w1c_s { ++ u64 mbox : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct rvu_pf_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 RVU_PF_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_INT_ENA_W1C(void) ++{ ++ return 0xc38; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_int_ena_w1s ++ * ++ * RVU PF Interrupt Enable Set Register This register sets interrupt ++ * enable bits. ++ */ ++union rvu_pf_int_ena_w1s { ++ u64 u; ++ struct rvu_pf_int_ena_w1s_s { ++ u64 mbox : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct rvu_pf_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 RVU_PF_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_INT_ENA_W1S(void) ++{ ++ return 0xc30; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_int_w1s ++ * ++ * RVU PF Interrupt Set Register This register sets interrupt bits. ++ */ ++union rvu_pf_int_w1s { ++ u64 u; ++ struct rvu_pf_int_w1s_s { ++ u64 mbox : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct rvu_pf_int_w1s_s cn; */ ++}; ++ ++static inline u64 RVU_PF_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_INT_W1S(void) ++{ ++ return 0xc28; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_msix_pba# ++ * ++ * RVU PF MSI-X Pending-Bit-Array Registers This register is the MSI-X PF ++ * PBA table. ++ */ ++union rvu_pf_msix_pbax { ++ u64 u; ++ struct rvu_pf_msix_pbax_s { ++ u64 pend : 64; ++ } s; ++ /* struct rvu_pf_msix_pbax_s cn; */ ++}; ++ ++static inline u64 RVU_PF_MSIX_PBAX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_MSIX_PBAX(u64 a) ++{ ++ return 0xf0000 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_msix_vec#_addr ++ * ++ * RVU PF MSI-X Vector-Table Address Registers These registers and ++ * RVU_PF_MSIX_VEC()_CTL form the PF MSI-X vector table. The number of ++ * MSI-X vectors for a given PF is specified by ++ * RVU_PRIV_PF()_MSIX_CFG[PF_MSIXT_SIZEM1] (plus 1). Software must do a ++ * read after any writes to the MSI-X vector table to ensure that the ++ * writes have completed before interrupts are generated to the modified ++ * vectors. ++ */ ++union rvu_pf_msix_vecx_addr { ++ u64 u; ++ struct rvu_pf_msix_vecx_addr_s { ++ u64 secvec : 1; ++ u64 reserved_1 : 1; ++ u64 addr : 51; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct rvu_pf_msix_vecx_addr_s cn; */ ++}; ++ ++static inline u64 RVU_PF_MSIX_VECX_ADDR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_MSIX_VECX_ADDR(u64 a) ++{ ++ return 0x80000 + 0x10 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_msix_vec#_ctl ++ * ++ * RVU PF MSI-X Vector-Table Control and Data Registers These registers ++ * and RVU_PF_MSIX_VEC()_ADDR form the PF MSI-X vector table. ++ */ ++union rvu_pf_msix_vecx_ctl { ++ u64 u; ++ struct rvu_pf_msix_vecx_ctl_s { ++ u64 data : 32; ++ u64 mask : 1; ++ u64 reserved_33_63 : 31; ++ } s; ++ /* struct rvu_pf_msix_vecx_ctl_s cn; */ ++}; ++ ++static inline u64 RVU_PF_MSIX_VECX_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_MSIX_VECX_CTL(u64 a) ++{ ++ return 0x80008 + 0x10 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_pfaf_mbox# ++ * ++ * RVU PF/AF Mailbox Registers ++ */ ++union rvu_pf_pfaf_mboxx { ++ u64 u; ++ struct rvu_pf_pfaf_mboxx_s { ++ u64 data : 64; ++ } s; ++ /* struct rvu_pf_pfaf_mboxx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_PFAF_MBOXX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_PFAF_MBOXX(u64 a) ++{ ++ return 0xc00 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vf#_pfvf_mbox# ++ * ++ * RVU PF/VF Mailbox Registers ++ */ ++union rvu_pf_vfx_pfvf_mboxx { ++ u64 u; ++ struct rvu_pf_vfx_pfvf_mboxx_s { ++ u64 data : 64; ++ } s; ++ /* struct rvu_pf_vfx_pfvf_mboxx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VFX_PFVF_MBOXX(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VFX_PFVF_MBOXX(u64 a, u64 b) ++{ ++ return 0 + 0x1000 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vf_bar4_addr ++ * ++ * RVU PF VF BAR4 Address Registers ++ */ ++union rvu_pf_vf_bar4_addr { ++ u64 u; ++ struct rvu_pf_vf_bar4_addr_s { ++ u64 reserved_0_15 : 16; ++ u64 addr : 48; ++ } s; ++ /* struct rvu_pf_vf_bar4_addr_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VF_BAR4_ADDR(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VF_BAR4_ADDR(void) ++{ ++ return 0x10; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vfflr_int# ++ * ++ * RVU PF VF Function Level Reset Interrupt Registers ++ */ ++union rvu_pf_vfflr_intx { ++ u64 u; ++ struct rvu_pf_vfflr_intx_s { ++ u64 flr : 64; ++ } s; ++ /* struct rvu_pf_vfflr_intx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VFFLR_INTX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VFFLR_INTX(u64 a) ++{ ++ return 0x900 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vfflr_int_ena_w1c# ++ * ++ * RVU PF VF Function Level Reset Interrupt Enable Clear Registers This ++ * register clears interrupt enable bits. ++ */ ++union rvu_pf_vfflr_int_ena_w1cx { ++ u64 u; ++ struct rvu_pf_vfflr_int_ena_w1cx_s { ++ u64 flr : 64; ++ } s; ++ /* struct rvu_pf_vfflr_int_ena_w1cx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VFFLR_INT_ENA_W1CX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VFFLR_INT_ENA_W1CX(u64 a) ++{ ++ return 0x960 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vfflr_int_ena_w1s# ++ * ++ * RVU PF VF Function Level Reset Interrupt Enable Set Registers This ++ * register sets interrupt enable bits. ++ */ ++union rvu_pf_vfflr_int_ena_w1sx { ++ u64 u; ++ struct rvu_pf_vfflr_int_ena_w1sx_s { ++ u64 flr : 64; ++ } s; ++ /* struct rvu_pf_vfflr_int_ena_w1sx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VFFLR_INT_ENA_W1SX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VFFLR_INT_ENA_W1SX(u64 a) ++{ ++ return 0x940 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vfflr_int_w1s# ++ * ++ * RVU PF VF Function Level Reset Interrupt Set Registers This register ++ * sets interrupt bits. ++ */ ++union rvu_pf_vfflr_int_w1sx { ++ u64 u; ++ struct rvu_pf_vfflr_int_w1sx_s { ++ u64 flr : 64; ++ } s; ++ /* struct rvu_pf_vfflr_int_w1sx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VFFLR_INT_W1SX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VFFLR_INT_W1SX(u64 a) ++{ ++ return 0x920 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vfme_int# ++ * ++ * RVU PF VF Bus Master Enable Interrupt Registers ++ */ ++union rvu_pf_vfme_intx { ++ u64 u; ++ struct rvu_pf_vfme_intx_s { ++ u64 me : 64; ++ } s; ++ /* struct rvu_pf_vfme_intx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VFME_INTX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VFME_INTX(u64 a) ++{ ++ return 0x980 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vfme_int_ena_w1c# ++ * ++ * RVU PF VF Bus Master Enable Interrupt Enable Clear Registers This ++ * register clears interrupt enable bits. ++ */ ++union rvu_pf_vfme_int_ena_w1cx { ++ u64 u; ++ struct rvu_pf_vfme_int_ena_w1cx_s { ++ u64 me : 64; ++ } s; ++ /* struct rvu_pf_vfme_int_ena_w1cx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VFME_INT_ENA_W1CX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VFME_INT_ENA_W1CX(u64 a) ++{ ++ return 0x9e0 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vfme_int_ena_w1s# ++ * ++ * RVU PF VF Bus Master Enable Interrupt Enable Set Registers This ++ * register sets interrupt enable bits. ++ */ ++union rvu_pf_vfme_int_ena_w1sx { ++ u64 u; ++ struct rvu_pf_vfme_int_ena_w1sx_s { ++ u64 me : 64; ++ } s; ++ /* struct rvu_pf_vfme_int_ena_w1sx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VFME_INT_ENA_W1SX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VFME_INT_ENA_W1SX(u64 a) ++{ ++ return 0x9c0 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vfme_int_w1s# ++ * ++ * RVU PF VF Bus Master Enable Interrupt Set Registers This register sets ++ * interrupt bits. ++ */ ++union rvu_pf_vfme_int_w1sx { ++ u64 u; ++ struct rvu_pf_vfme_int_w1sx_s { ++ u64 me : 64; ++ } s; ++ /* struct rvu_pf_vfme_int_w1sx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VFME_INT_W1SX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VFME_INT_W1SX(u64 a) ++{ ++ return 0x9a0 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vfme_status# ++ * ++ * RVU PF VF Bus Master Enable Status Registers ++ */ ++union rvu_pf_vfme_statusx { ++ u64 u; ++ struct rvu_pf_vfme_statusx_s { ++ u64 me : 64; ++ } s; ++ /* struct rvu_pf_vfme_statusx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VFME_STATUSX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VFME_STATUSX(u64 a) ++{ ++ return 0x800 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vfpf_mbox_int# ++ * ++ * RVU VF to PF Mailbox Interrupt Registers ++ */ ++union rvu_pf_vfpf_mbox_intx { ++ u64 u; ++ struct rvu_pf_vfpf_mbox_intx_s { ++ u64 mbox : 64; ++ } s; ++ /* struct rvu_pf_vfpf_mbox_intx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VFPF_MBOX_INTX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VFPF_MBOX_INTX(u64 a) ++{ ++ return 0x880 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vfpf_mbox_int_ena_w1c# ++ * ++ * RVU VF to PF Mailbox Interrupt Enable Clear Registers This register ++ * clears interrupt enable bits. ++ */ ++union rvu_pf_vfpf_mbox_int_ena_w1cx { ++ u64 u; ++ struct rvu_pf_vfpf_mbox_int_ena_w1cx_s { ++ u64 mbox : 64; ++ } s; ++ /* struct rvu_pf_vfpf_mbox_int_ena_w1cx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VFPF_MBOX_INT_ENA_W1CX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VFPF_MBOX_INT_ENA_W1CX(u64 a) ++{ ++ return 0x8e0 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vfpf_mbox_int_ena_w1s# ++ * ++ * RVU VF to PF Mailbox Interrupt Enable Set Registers This register sets ++ * interrupt enable bits. ++ */ ++union rvu_pf_vfpf_mbox_int_ena_w1sx { ++ u64 u; ++ struct rvu_pf_vfpf_mbox_int_ena_w1sx_s { ++ u64 mbox : 64; ++ } s; ++ /* struct rvu_pf_vfpf_mbox_int_ena_w1sx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VFPF_MBOX_INT_ENA_W1SX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VFPF_MBOX_INT_ENA_W1SX(u64 a) ++{ ++ return 0x8c0 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vfpf_mbox_int_w1s# ++ * ++ * RVU VF to PF Mailbox Interrupt Set Registers This register sets ++ * interrupt bits. ++ */ ++union rvu_pf_vfpf_mbox_int_w1sx { ++ u64 u; ++ struct rvu_pf_vfpf_mbox_int_w1sx_s { ++ u64 mbox : 64; ++ } s; ++ /* struct rvu_pf_vfpf_mbox_int_w1sx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VFPF_MBOX_INT_W1SX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VFPF_MBOX_INT_W1SX(u64 a) ++{ ++ return 0x8a0 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vftrpend# ++ * ++ * RVU PF VF Transaction Pending Registers ++ */ ++union rvu_pf_vftrpendx { ++ u64 u; ++ struct rvu_pf_vftrpendx_s { ++ u64 trpend : 64; ++ } s; ++ /* struct rvu_pf_vftrpendx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VFTRPENDX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VFTRPENDX(u64 a) ++{ ++ return 0x820 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR2) rvu_pf_vftrpend_w1s# ++ * ++ * RVU PF VF Transaction Pending Set Registers This register reads or ++ * sets bits. ++ */ ++union rvu_pf_vftrpend_w1sx { ++ u64 u; ++ struct rvu_pf_vftrpend_w1sx_s { ++ u64 trpend : 64; ++ } s; ++ /* struct rvu_pf_vftrpend_w1sx_s cn; */ ++}; ++ ++static inline u64 RVU_PF_VFTRPEND_W1SX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PF_VFTRPEND_W1SX(u64 a) ++{ ++ return 0x840 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_active_pc ++ * ++ * RVU Active Program Counter Register ++ */ ++union rvu_priv_active_pc { ++ u64 u; ++ struct rvu_priv_active_pc_s { ++ u64 active_pc : 64; ++ } s; ++ /* struct rvu_priv_active_pc_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_ACTIVE_PC(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_ACTIVE_PC(void) ++{ ++ return 0x8000030; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_block_type#_rev ++ * ++ * RVU Privileged Block Type Revision Registers These registers are used ++ * by configuration software to specify the revision ID of each block ++ * type enumerated by RVU_BLOCK_TYPE_E, to assist VF/PF software ++ * discovery. ++ */ ++union rvu_priv_block_typex_rev { ++ u64 u; ++ struct rvu_priv_block_typex_rev_s { ++ u64 rid : 8; ++ u64 reserved_8_63 : 56; ++ } s; ++ /* struct rvu_priv_block_typex_rev_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_BLOCK_TYPEX_REV(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_BLOCK_TYPEX_REV(u64 a) ++{ ++ return 0x8000400 + 8 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_clk_cfg ++ * ++ * RVU Privileged General Configuration Register ++ */ ++union rvu_priv_clk_cfg { ++ u64 u; ++ struct rvu_priv_clk_cfg_s { ++ u64 blk_clken : 1; ++ u64 ncbi_clken : 1; ++ u64 reserved_2_63 : 62; ++ } s; ++ /* struct rvu_priv_clk_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_CLK_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_CLK_CFG(void) ++{ ++ return 0x8000020; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_const ++ * ++ * RVU Privileged Constants Register This register contains constants for ++ * software discovery. ++ */ ++union rvu_priv_const { ++ u64 u; ++ struct rvu_priv_const_s { ++ u64 max_msix : 20; ++ u64 hwvfs : 12; ++ u64 pfs : 8; ++ u64 max_vfs_per_pf : 8; ++ u64 reserved_48_63 : 16; ++ } s; ++ /* struct rvu_priv_const_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_CONST(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_CONST(void) ++{ ++ return 0x8000000; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_gen_cfg ++ * ++ * RVU Privileged General Configuration Register ++ */ ++union rvu_priv_gen_cfg { ++ u64 u; ++ struct rvu_priv_gen_cfg_s { ++ u64 lock : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct rvu_priv_gen_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_GEN_CFG(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_GEN_CFG(void) ++{ ++ return 0x8000010; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_hwvf#_cpt#_cfg ++ * ++ * RVU Privileged Hardware VF CPT Configuration Registers Similar to ++ * RVU_PRIV_HWVF()_NIX()_CFG, but for CPT({a}) block. ++ */ ++union rvu_priv_hwvfx_cptx_cfg { ++ u64 u; ++ struct rvu_priv_hwvfx_cptx_cfg_s { ++ u64 num_lfs : 9; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct rvu_priv_hwvfx_cptx_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_HWVFX_CPTX_CFG(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_HWVFX_CPTX_CFG(u64 a, u64 b) ++{ ++ return 0x8001350 + 0x10000 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_hwvf#_int_cfg ++ * ++ * RVU Privileged Hardware VF Interrupt Configuration Registers ++ */ ++union rvu_priv_hwvfx_int_cfg { ++ u64 u; ++ struct rvu_priv_hwvfx_int_cfg_s { ++ u64 msix_offset : 11; ++ u64 reserved_11 : 1; ++ u64 msix_size : 8; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct rvu_priv_hwvfx_int_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_HWVFX_INT_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_HWVFX_INT_CFG(u64 a) ++{ ++ return 0x8001280 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_hwvf#_nix#_cfg ++ * ++ * RVU Privileged Hardware VF NIX Configuration Registers These registers ++ * are used to assist VF software discovery. For each HWVF, if the HWVF ++ * is mapped to a VF by RVU_PRIV_PF()_CFG[FIRST_HWVF,NVF], software ++ * writes NIX block's resource configuration for the VF in this register. ++ * The VF driver can read RVU_VF_BLOCK_ADDR()_DISC to discover the ++ * configuration. ++ */ ++union rvu_priv_hwvfx_nixx_cfg { ++ u64 u; ++ struct rvu_priv_hwvfx_nixx_cfg_s { ++ u64 has_lf : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct rvu_priv_hwvfx_nixx_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_HWVFX_NIXX_CFG(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_HWVFX_NIXX_CFG(u64 a, u64 b) ++{ ++ return 0x8001300 + 0x10000 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_hwvf#_npa_cfg ++ * ++ * RVU Privileged Hardware VF NPA Configuration Registers Similar to ++ * RVU_PRIV_HWVF()_NIX()_CFG, but for NPA block. ++ */ ++union rvu_priv_hwvfx_npa_cfg { ++ u64 u; ++ struct rvu_priv_hwvfx_npa_cfg_s { ++ u64 has_lf : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct rvu_priv_hwvfx_npa_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_HWVFX_NPA_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_HWVFX_NPA_CFG(u64 a) ++{ ++ return 0x8001310 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_hwvf#_ree#_cfg ++ * ++ * RVU Privileged Hardware VF REE Configuration Registers Similar to ++ * RVU_PRIV_HWVF()_NIX()_CFG, but for REE({a}) block. ++ */ ++union rvu_priv_hwvfx_reex_cfg { ++ u64 u; ++ struct rvu_priv_hwvfx_reex_cfg_s { ++ u64 num_lfs : 9; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct rvu_priv_hwvfx_reex_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_HWVFX_REEX_CFG(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_HWVFX_REEX_CFG(u64 a, u64 b) ++{ ++ return 0x8001360 + 0x10000 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_hwvf#_sso_cfg ++ * ++ * RVU Privileged Hardware VF SSO Configuration Registers Similar to ++ * RVU_PRIV_HWVF()_NIX()_CFG, but for SSO block. ++ */ ++union rvu_priv_hwvfx_sso_cfg { ++ u64 u; ++ struct rvu_priv_hwvfx_sso_cfg_s { ++ u64 num_lfs : 9; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct rvu_priv_hwvfx_sso_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_HWVFX_SSO_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_HWVFX_SSO_CFG(u64 a) ++{ ++ return 0x8001320 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_hwvf#_ssow_cfg ++ * ++ * RVU Privileged Hardware VF SSO Work Slot Configuration Registers ++ * Similar to RVU_PRIV_HWVF()_NIX()_CFG, but for SSOW block. ++ */ ++union rvu_priv_hwvfx_ssow_cfg { ++ u64 u; ++ struct rvu_priv_hwvfx_ssow_cfg_s { ++ u64 num_lfs : 9; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct rvu_priv_hwvfx_ssow_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_HWVFX_SSOW_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_HWVFX_SSOW_CFG(u64 a) ++{ ++ return 0x8001330 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_hwvf#_tim_cfg ++ * ++ * RVU Privileged Hardware VF SSO Work Slot Configuration Registers ++ * Similar to RVU_PRIV_HWVF()_NIX()_CFG, but for TIM block. ++ */ ++union rvu_priv_hwvfx_tim_cfg { ++ u64 u; ++ struct rvu_priv_hwvfx_tim_cfg_s { ++ u64 num_lfs : 9; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct rvu_priv_hwvfx_tim_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_HWVFX_TIM_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_HWVFX_TIM_CFG(u64 a) ++{ ++ return 0x8001340 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_pf#_cfg ++ * ++ * RVU Privileged PF Configuration Registers ++ */ ++union rvu_priv_pfx_cfg { ++ u64 u; ++ struct rvu_priv_pfx_cfg_s { ++ u64 first_hwvf : 12; ++ u64 nvf : 8; ++ u64 ena : 1; ++ u64 af_ena : 1; ++ u64 me_flr_ena : 1; ++ u64 pf_vf_io_bar4 : 1; ++ u64 reserved_24_63 : 40; ++ } s; ++ struct rvu_priv_pfx_cfg_cn96xxp1 { ++ u64 first_hwvf : 12; ++ u64 nvf : 8; ++ u64 ena : 1; ++ u64 af_ena : 1; ++ u64 me_flr_ena : 1; ++ u64 reserved_23_63 : 41; ++ } cn96xxp1; ++ /* struct rvu_priv_pfx_cfg_s cn96xxp3; */ ++ /* struct rvu_priv_pfx_cfg_s cn98xx; */ ++ /* struct rvu_priv_pfx_cfg_cn96xxp1 cnf95xx; */ ++ /* struct rvu_priv_pfx_cfg_s loki; */ ++}; ++ ++static inline u64 RVU_PRIV_PFX_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_PFX_CFG(u64 a) ++{ ++ return 0x8000100 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_pf#_cpt#_cfg ++ * ++ * RVU Privileged PF CPT Configuration Registers Similar to ++ * RVU_PRIV_PF()_NIX()_CFG, but for CPT({a}) block. ++ */ ++union rvu_priv_pfx_cptx_cfg { ++ u64 u; ++ struct rvu_priv_pfx_cptx_cfg_s { ++ u64 num_lfs : 9; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct rvu_priv_pfx_cptx_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_PFX_CPTX_CFG(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_PFX_CPTX_CFG(u64 a, u64 b) ++{ ++ return 0x8000350 + 0x10000 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_pf#_id_cfg ++ * ++ * RVU Privileged PF ID Configuration Registers ++ */ ++union rvu_priv_pfx_id_cfg { ++ u64 u; ++ struct rvu_priv_pfx_id_cfg_s { ++ u64 pf_devid : 8; ++ u64 vf_devid : 8; ++ u64 class_code : 24; ++ u64 reserved_40_63 : 24; ++ } s; ++ /* struct rvu_priv_pfx_id_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_PFX_ID_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_PFX_ID_CFG(u64 a) ++{ ++ return 0x8000120 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_pf#_int_cfg ++ * ++ * RVU Privileged PF Interrupt Configuration Registers ++ */ ++union rvu_priv_pfx_int_cfg { ++ u64 u; ++ struct rvu_priv_pfx_int_cfg_s { ++ u64 msix_offset : 11; ++ u64 reserved_11 : 1; ++ u64 msix_size : 8; ++ u64 reserved_20_63 : 44; ++ } s; ++ /* struct rvu_priv_pfx_int_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_PFX_INT_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_PFX_INT_CFG(u64 a) ++{ ++ return 0x8000200 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_pf#_msix_cfg ++ * ++ * RVU Privileged PF MSI-X Configuration Registers These registers ++ * specify MSI-X table sizes and locations for RVU PFs and associated ++ * VFs. Hardware maintains all RVU MSI-X tables in a contiguous memory ++ * region in LLC/DRAM called the MSI-X table region. The table region's ++ * base AF IOVA is specified by RVU_AF_MSIXTR_BASE, and its size as a ++ * multiple of 16-byte RVU_MSIX_VEC_S structures must be less than or ++ * equal to RVU_PRIV_CONST[MAX_MSIX]. A PF's MSI-X table consists of the ++ * following range of RVU_MSIX_VEC_S structures in the table region: * ++ * First index: [PF_MSIXT_OFFSET]. * Last index: [PF_MSIXT_OFFSET] + ++ * [PF_MSIXT_SIZEM1]. If a PF has enabled VFs (associated ++ * RVU_PRIV_PF()_CFG[NVF] is nonzero), then each VF's MSI-X table ++ * consumes the following range of RVU_MSIX_VEC_S structures: * First ++ * index: [VF_MSIXT_OFFSET] + N*([VF_MSIXT_SIZEM1] + 1). * Last index: ++ * [VF_MSIXT_OFFSET] + N*([VF_MSIXT_SIZEM1] + 1) + [VF_MSIXT_SIZEM1]. ++ * N=0 for the first VF, N=1 for the second VF, etc. Different PFs and ++ * VFs must have non-overlapping vector ranges, and the last index of any ++ * range must be less than RVU_PRIV_CONST[MAX_MSIX]. ++ */ ++union rvu_priv_pfx_msix_cfg { ++ u64 u; ++ struct rvu_priv_pfx_msix_cfg_s { ++ u64 vf_msixt_sizem1 : 12; ++ u64 vf_msixt_offset : 20; ++ u64 pf_msixt_sizem1 : 12; ++ u64 pf_msixt_offset : 20; ++ } s; ++ /* struct rvu_priv_pfx_msix_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_PFX_MSIX_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_PFX_MSIX_CFG(u64 a) ++{ ++ return 0x8000110 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_pf#_nix#_cfg ++ * ++ * RVU Privileged PF NIX Configuration Registers These registers are used ++ * to assist PF software discovery. For each enabled RVU PF, software ++ * writes the block's resource configuration for the PF in this register. ++ * The PF driver can read RVU_PF_BLOCK_ADDR()_DISC to discover the ++ * configuration. ++ */ ++union rvu_priv_pfx_nixx_cfg { ++ u64 u; ++ struct rvu_priv_pfx_nixx_cfg_s { ++ u64 has_lf : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct rvu_priv_pfx_nixx_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_PFX_NIXX_CFG(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_PFX_NIXX_CFG(u64 a, u64 b) ++{ ++ return 0x8000300 + 0x10000 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_pf#_npa_cfg ++ * ++ * RVU Privileged PF NPA Configuration Registers Similar to ++ * RVU_PRIV_PF()_NIX()_CFG, but for NPA block. ++ */ ++union rvu_priv_pfx_npa_cfg { ++ u64 u; ++ struct rvu_priv_pfx_npa_cfg_s { ++ u64 has_lf : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct rvu_priv_pfx_npa_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_PFX_NPA_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_PFX_NPA_CFG(u64 a) ++{ ++ return 0x8000310 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_pf#_ree#_cfg ++ * ++ * RVU Privileged PF REE Configuration Registers Similar to ++ * RVU_PRIV_PF()_NIX()_CFG, but for REE({a}) block. ++ */ ++union rvu_priv_pfx_reex_cfg { ++ u64 u; ++ struct rvu_priv_pfx_reex_cfg_s { ++ u64 num_lfs : 9; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct rvu_priv_pfx_reex_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_PFX_REEX_CFG(u64 a, u64 b) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_PFX_REEX_CFG(u64 a, u64 b) ++{ ++ return 0x8000360 + 0x10000 * a + 8 * b; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_pf#_sso_cfg ++ * ++ * RVU Privileged PF SSO Configuration Registers Similar to ++ * RVU_PRIV_PF()_NIX()_CFG, but for SSO block. ++ */ ++union rvu_priv_pfx_sso_cfg { ++ u64 u; ++ struct rvu_priv_pfx_sso_cfg_s { ++ u64 num_lfs : 9; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct rvu_priv_pfx_sso_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_PFX_SSO_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_PFX_SSO_CFG(u64 a) ++{ ++ return 0x8000320 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_pf#_ssow_cfg ++ * ++ * RVU Privileged PF SSO Work Slot Configuration Registers Similar to ++ * RVU_PRIV_PF()_NIX()_CFG, but for SSOW block. ++ */ ++union rvu_priv_pfx_ssow_cfg { ++ u64 u; ++ struct rvu_priv_pfx_ssow_cfg_s { ++ u64 num_lfs : 9; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct rvu_priv_pfx_ssow_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_PFX_SSOW_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_PFX_SSOW_CFG(u64 a) ++{ ++ return 0x8000330 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_PF_BAR0) rvu_priv_pf#_tim_cfg ++ * ++ * RVU Privileged PF SSO Work Slot Configuration Registers Similar to ++ * RVU_PRIV_PF()_NIX()_CFG, but for TIM block. ++ */ ++union rvu_priv_pfx_tim_cfg { ++ u64 u; ++ struct rvu_priv_pfx_tim_cfg_s { ++ u64 num_lfs : 9; ++ u64 reserved_9_63 : 55; ++ } s; ++ /* struct rvu_priv_pfx_tim_cfg_s cn; */ ++}; ++ ++static inline u64 RVU_PRIV_PFX_TIM_CFG(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_PRIV_PFX_TIM_CFG(u64 a) ++{ ++ return 0x8000340 + 0x10000 * a; ++} ++ ++/** ++ * Register (RVU_VF_BAR2) rvu_vf_block_addr#_disc ++ * ++ * RVU VF Block Address Discovery Registers These registers allow each VF ++ * driver to discover block resources that are provisioned to its VF. The ++ * register's BLOCK_ADDR index is enumerated by RVU_BLOCK_ADDR_E. ++ */ ++union rvu_vf_block_addrx_disc { ++ u64 u; ++ struct rvu_vf_block_addrx_disc_s { ++ u64 num_lfs : 9; ++ u64 reserved_9_10 : 2; ++ u64 imp : 1; ++ u64 rid : 8; ++ u64 btype : 8; ++ u64 reserved_28_63 : 36; ++ } s; ++ /* struct rvu_vf_block_addrx_disc_s cn; */ ++}; ++ ++static inline u64 RVU_VF_BLOCK_ADDRX_DISC(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_VF_BLOCK_ADDRX_DISC(u64 a) ++{ ++ return 0x200 + 8 * a; ++} ++ ++/** ++ * Register (RVU_VF_BAR2) rvu_vf_int ++ * ++ * RVU VF Interrupt Registers ++ */ ++union rvu_vf_int { ++ u64 u; ++ struct rvu_vf_int_s { ++ u64 mbox : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct rvu_vf_int_s cn; */ ++}; ++ ++static inline u64 RVU_VF_INT(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_VF_INT(void) ++{ ++ return 0x20; ++} ++ ++/** ++ * Register (RVU_VF_BAR2) rvu_vf_int_ena_w1c ++ * ++ * RVU VF Interrupt Enable Clear Register This register clears interrupt ++ * enable bits. ++ */ ++union rvu_vf_int_ena_w1c { ++ u64 u; ++ struct rvu_vf_int_ena_w1c_s { ++ u64 mbox : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct rvu_vf_int_ena_w1c_s cn; */ ++}; ++ ++static inline u64 RVU_VF_INT_ENA_W1C(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_VF_INT_ENA_W1C(void) ++{ ++ return 0x38; ++} ++ ++/** ++ * Register (RVU_VF_BAR2) rvu_vf_int_ena_w1s ++ * ++ * RVU VF Interrupt Enable Set Register This register sets interrupt ++ * enable bits. ++ */ ++union rvu_vf_int_ena_w1s { ++ u64 u; ++ struct rvu_vf_int_ena_w1s_s { ++ u64 mbox : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct rvu_vf_int_ena_w1s_s cn; */ ++}; ++ ++static inline u64 RVU_VF_INT_ENA_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_VF_INT_ENA_W1S(void) ++{ ++ return 0x30; ++} ++ ++/** ++ * Register (RVU_VF_BAR2) rvu_vf_int_w1s ++ * ++ * RVU VF Interrupt Set Register This register sets interrupt bits. ++ */ ++union rvu_vf_int_w1s { ++ u64 u; ++ struct rvu_vf_int_w1s_s { ++ u64 mbox : 1; ++ u64 reserved_1_63 : 63; ++ } s; ++ /* struct rvu_vf_int_w1s_s cn; */ ++}; ++ ++static inline u64 RVU_VF_INT_W1S(void) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_VF_INT_W1S(void) ++{ ++ return 0x28; ++} ++ ++/** ++ * Register (RVU_VF_BAR2) rvu_vf_msix_pba# ++ * ++ * RVU VF MSI-X Pending-Bit-Array Registers This register is the MSI-X VF ++ * PBA table. ++ */ ++union rvu_vf_msix_pbax { ++ u64 u; ++ struct rvu_vf_msix_pbax_s { ++ u64 pend : 64; ++ } s; ++ /* struct rvu_vf_msix_pbax_s cn; */ ++}; ++ ++static inline u64 RVU_VF_MSIX_PBAX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_VF_MSIX_PBAX(u64 a) ++{ ++ return 0xf0000 + 8 * a; ++} ++ ++/** ++ * Register (RVU_VF_BAR2) rvu_vf_msix_vec#_addr ++ * ++ * RVU VF MSI-X Vector-Table Address Registers These registers and ++ * RVU_VF_MSIX_VEC()_CTL form the VF MSI-X vector table. The number of ++ * MSI-X vectors for a given VF is specified by ++ * RVU_PRIV_PF()_MSIX_CFG[VF_MSIXT_SIZEM1] (plus 1). Software must do a ++ * read after any writes to the MSI-X vector table to ensure that the ++ * writes have completed before interrupts are generated to the modified ++ * vectors. ++ */ ++union rvu_vf_msix_vecx_addr { ++ u64 u; ++ struct rvu_vf_msix_vecx_addr_s { ++ u64 secvec : 1; ++ u64 reserved_1 : 1; ++ u64 addr : 51; ++ u64 reserved_53_63 : 11; ++ } s; ++ /* struct rvu_vf_msix_vecx_addr_s cn; */ ++}; ++ ++static inline u64 RVU_VF_MSIX_VECX_ADDR(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_VF_MSIX_VECX_ADDR(u64 a) ++{ ++ return 0x80000 + 0x10 * a; ++} ++ ++/** ++ * Register (RVU_VF_BAR2) rvu_vf_msix_vec#_ctl ++ * ++ * RVU VF MSI-X Vector-Table Control and Data Registers These registers ++ * and RVU_VF_MSIX_VEC()_ADDR form the VF MSI-X vector table. ++ */ ++union rvu_vf_msix_vecx_ctl { ++ u64 u; ++ struct rvu_vf_msix_vecx_ctl_s { ++ u64 data : 32; ++ u64 mask : 1; ++ u64 reserved_33_63 : 31; ++ } s; ++ /* struct rvu_vf_msix_vecx_ctl_s cn; */ ++}; ++ ++static inline u64 RVU_VF_MSIX_VECX_CTL(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_VF_MSIX_VECX_CTL(u64 a) ++{ ++ return 0x80008 + 0x10 * a; ++} ++ ++/** ++ * Register (RVU_VF_BAR2) rvu_vf_vfpf_mbox# ++ * ++ * RVU VF/PF Mailbox Registers ++ */ ++union rvu_vf_vfpf_mboxx { ++ u64 u; ++ struct rvu_vf_vfpf_mboxx_s { ++ u64 data : 64; ++ } s; ++ /* struct rvu_vf_vfpf_mboxx_s cn; */ ++}; ++ ++static inline u64 RVU_VF_VFPF_MBOXX(u64 a) ++ __attribute__ ((pure, always_inline)); ++static inline u64 RVU_VF_VFPF_MBOXX(u64 a) ++{ ++ return 0 + 8 * a; ++} ++ ++#endif /* __CSRS_RVU_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx2/gpio.h b/arch/arm/include/asm/arch-octeontx2/gpio.h +new file mode 100644 +index 0000000000..3943ffd952 +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx2/gpio.h +@@ -0,0 +1,6 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ +diff --git a/arch/arm/include/asm/arch-octeontx2/lock.h b/arch/arm/include/asm/arch-octeontx2/lock.h +new file mode 100644 +index 0000000000..65fab6865f +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx2/lock.h +@@ -0,0 +1,139 @@ ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ */ ++ ++#ifndef __OCTEONTX2_LOCK_H__ ++#define __OCTEONTX2_LOCK_H__ ++ ++/** ++ * U-Boot doesn't implement spinlocks but we need them here since ++ * we could be sharing with other processes (i.e. ATF) ++ * ++ * This is copied from the Linux kernel arm64 implementation. ++ */ ++typedef struct octeontx_spinlock { ++ u16 next; ++ u16 owner; ++} __aligned(4) octeontx_spinlock_t; ++ ++/** ++ * Atomic compare and exchange, derived from atomic_ll_sc.h in Linux ++ * ++ * @param ptr pointer to 128 bits to compare and exchange ++ * @param old_hi expected old value first 64 bits ++ * @param old_lo expected old value second 64 bits ++ * @param new_hi new first 64-bit value to set ++ * @param new_lo new second 64-bit value to set ++ * @param last_hi pointer to previous first 64-bit value ++ * @param last_lo pointer previous second 64-bit value ++ * ++ * @return true if successful, false if the old values mismatched ++ * ++ * last_hi and last_lo may be NULL. ++ */ ++static inline bool octeontx_cmpxchg_atomic128(volatile void *ptr, ++ u64 old_hi, u64 old_lo, ++ u64 new_hi, u64 new_lo, ++ u64 *last_hi, u64 *last_lo) ++{ ++ u64 tmp_hi, tmp_lo, oldval_hi, oldval_lo; ++ u32 tmp; ++ ++ asm volatile ( ++ " prfm pstl1strm, %[v] \n" ++ "1: ldaxp %[oldval_lo], %[oldval_hi], %[v] \n" ++ " eor %[tmp_lo], %[oldval_lo], %[old_lo] \n" ++ " eor %[tmp_hi], %[oldval_hi], %[old_hi] \n" ++ " cbnz %[tmp_lo], 2f \n" ++ " cbnz %[tmp_hi], 2f \n" ++ " stxp %w[tmp], %[new_hi], %[new_lo], %[v] \n" ++ " cbnz %w[tmp], 1b \n" ++ "2: \n" ++ : [tmp] "=&r" (tmp), ++ [oldval_lo] "=&r" (oldval_lo), ++ [oldval_hi] "=&r" (oldval_hi), ++ [v] "+Q" (*(u64 *)ptr), ++ [tmp_lo] "=&r" (tmp_lo), [tmp_hi] "=&r" (tmp_hi) ++ : [old_lo] "Lr" (old_lo), [old_hi] "Lr" (old_hi), ++ [new_lo] "r" (new_lo), [new_hi] "r" (new_hi) ++ : "memory"); ++ if (last_hi) ++ *last_hi = oldval_hi; ++ if (last_lo) ++ *last_lo = oldval_lo; ++ return !(tmp_hi | tmp_lo); ++} ++ ++static inline void octeontx_init_spin_lock(octeontx_spinlock_t *lock) ++{ ++ *(u32 *)lock = 0; ++ __iowmb(); ++} ++ ++/** ++ * Acquires a spinlock ++ * ++ * @param lock pointer to lock ++ * ++ * This code is copied from the Linux aarch64 spinlock.h file ++ * and is compatible with it. ++ */ ++static inline void octeontx_spin_lock(octeontx_spinlock_t *lock) ++{ ++ unsigned int tmp; ++ octeontx_spinlock_t lockval, newval; ++ ++ asm volatile ( ++ /* Atomically increment the next ticket. */ ++ /* LL/SC */ ++" prfm pstl1strm, %3 \n" ++"1: ldaxr %w0, %3 \n" ++" add %w1, %w0, %w5 \n" ++" stxr %w2, %w1, %3 \n" ++" cbnz %w2, 1b \n" ++ ++ /* Did we get the lock? */ ++" eor %w1, %w0, %w0, ror #16 \n" ++" cbz %w1, 3f \n" ++ /* ++ * No: spin on the owner. Send a local event to avoid missing an ++ * unlock before the exclusive load. ++ */ ++" sevl \n" ++"2: wfe \n" ++" ldaxrh %w2, %4 \n" ++" eor %w1, %w2, %w0, lsr #16 \n" ++" cbnz %w1, 2b \n" ++ /* We got the lock. Critical section starts here. */ ++"3:" ++ : "=&r" (lockval), "=&r" (newval), "=&r" (tmp), "+Q" (*lock) ++ : "Q" (lock->owner), "I" (1 << 16) ++ : "memory"); ++} ++ ++/** ++ * Releases a spinlock ++ * ++ * @param lock pointer to lock ++ * ++ * This code is copied from the Linux aarch64 spinlock.h file. ++ */ ++static inline void octeontx_spin_unlock(octeontx_spinlock_t *lock) ++{ ++ unsigned long tmp; ++ ++ asm volatile ( ++ " ldrh %w1, %0 \n" ++ " add %w1, %w1, #1 \n" ++ " stlrh %w1, %0 \n" ++ " nop \n" ++ : "=Q" (lock->owner), "=&r" (tmp) ++ : ++ : "memory" ++ ++ ); ++} ++ ++#endif /* __OCTEONTX2_LOCK_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx2/smc-id.h b/arch/arm/include/asm/arch-octeontx2/smc-id.h +new file mode 100644 +index 0000000000..c7f9fa73fc +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx2/smc-id.h +@@ -0,0 +1,41 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#ifndef __SMC_ID_H__ ++#define __SMC_ID_H__ ++ ++/* SMC function IDs for general purpose queries */ ++ ++#define OCTEONTX2_SVC_CALL_COUNT 0xc200ff00 ++#define OCTEONTX2_SVC_UID 0xc200ff01 ++ ++#define OCTEONTX2_SVC_VERSION 0xc200ff03 ++ ++/* OcteonTX Service Calls version numbers */ ++#define OCTEONTX2_VERSION_MAJOR 0x1 ++#define OCTEONTX2_VERSION_MINOR 0x0 ++ ++/* x1 - node number */ ++#define OCTEONTX2_DRAM_SIZE 0xc2000301 ++#define OCTEONTX2_NODE_COUNT 0xc2000601 ++#define OCTEONTX2_DISABLE_RVU_LFS 0xc2000b01 ++ ++#define OCTEONTX2_CONFIG_OOO 0xc2000b04 ++ ++/* fail safe */ ++#define OCTEONTX2_FSAFE_PR_BOOT_SUCCESS 0xc2000b02 ++#define OCTEONTX2_FSAFE_CLR_FORCE_SEC 0xc2000b03 ++ ++#define OCTEONTX2_MDIO_DBG_READ 0xc2000d01 ++#define OCTEONTX2_MDIO_DBG_WRITE 0xc2000d02 ++ ++#define OCTEONTX_ATTESTATION_QUERY 0xc2000d03 ++#define OCTEONTX_ATTESTATION_QUERY_SUBCMD_LEGACY 0 ++#define OCTEONTX_ATTESTATION_QUERY_SUBCMD_BUFFER 1 ++#define OCTEONTX_ATTESTATION_QUERY_SUBCMD_INFO 2 ++ ++#endif /* __SMC_ID_H__ */ +diff --git a/arch/arm/include/asm/arch-octeontx2/smc.h b/arch/arm/include/asm/arch-octeontx2/smc.h +new file mode 100644 +index 0000000000..ecbed3882c +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx2/smc.h +@@ -0,0 +1,26 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#ifndef __SMC_H__ ++#define __SMC_H__ ++ ++#include ++ ++ssize_t smc_configure_ooo(unsigned int val); ++ssize_t smc_dram_size(unsigned int node); ++ssize_t smc_disable_rvu_lfs(unsigned int node); ++ssize_t smc_flsf_fw_booted(void); ++ssize_t smc_flsf_clr_force_2ndry(void); ++ssize_t smc_mdio_dbg_read(int cgx_lmac, int mode, int phyaddr, int devad, ++ int reg); ++ssize_t smc_mdio_dbg_write(int cgx_lmac, int mode, int phyaddr, int devad, ++ int reg, int val); ++#ifdef CONFIG_CMD_ATTEST ++ssize_t smc_attest(long subcmd, long ctx_arg); ++#endif ++ ++#endif +diff --git a/arch/arm/include/asm/arch-octeontx2/soc.h b/arch/arm/include/asm/arch-octeontx2/soc.h +new file mode 100644 +index 0000000000..63d792c46a +--- /dev/null ++++ b/arch/arm/include/asm/arch-octeontx2/soc.h +@@ -0,0 +1,35 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#ifndef __SOC_H__ ++#define __SOC_H__ ++ ++/* Product PARTNUM */ ++#define CN98XX 0xB1 ++#define CN96XX 0xB2 ++#define CN95XX 0xB3 ++#define LOKI 0xB4 ++#define F95MM 0xB5 ++ ++/* Register defines */ ++ ++#define otx_is_soc(soc) (read_partnum() == (soc)) ++#define otx_is_board(model) (!strcmp(read_board_name(), model)) ++#define otx_is_platform(platform) (read_platform() == (platform)) ++ ++typedef enum { ++ PLATFORM_HW = 0, ++ PLATFORM_EMULATOR = 1, ++ PLATFORM_ASIM = 3, ++} platform_t; ++ ++platform_t read_platform(void); ++u8 read_partnum(void); ++u8 read_partvar(void); ++const char *read_board_name(void); ++ ++#endif /* __SOC_H */ +diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h +index e6d27b69f9..0f51552018 100644 +--- a/arch/arm/include/asm/io.h ++++ b/arch/arm/include/asm/io.h +@@ -226,6 +226,14 @@ static inline void __raw_readsl(unsigned long addr, void *data, int longlen) + #define setbits_8(addr, set) setbits(8, addr, set) + #define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set) + ++#define clrbits_be64(addr, clear) clrbits(be64, addr, clear) ++#define setbits_be64(addr, set) setbits(be64, addr, set) ++#define clrsetbits_be64(addr, clear, set) clrsetbits(be64, addr, clear, set) ++ ++#define clrbits_le64(addr, clear) clrbits(le64, addr, clear) ++#define setbits_le64(addr, set) setbits(le64, addr, set) ++#define clrsetbits_le64(addr, clear, set) clrsetbits(le64, addr, clear, set) ++ + /* + * Now, pick up the machine-defined IO definitions + */ +diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h +index a1a5e35ef6..8a99ed39da 100644 +--- a/arch/arm/include/asm/system.h ++++ b/arch/arm/include/asm/system.h +@@ -253,6 +253,11 @@ void mmu_change_region_attr(phys_addr_t start, size_t size, u64 attrs); + */ + void smc_call(struct pt_regs *args); + ++/* Return codes defined in ARM DEN 0070A */ ++#define SMCCC_RET_SUCCESS 0 ++#define SMCCC_RET_NOT_SUPPORTED -1 ++#define SMCCC_RET_NOT_REQUIRED -2 ++ + void __noreturn psci_system_reset(void); + void __noreturn psci_system_off(void); + +diff --git a/arch/arm/lib/interrupts_64.c b/arch/arm/lib/interrupts_64.c +index 0bfdb8d93d..33ec856087 100644 +--- a/arch/arm/lib/interrupts_64.c ++++ b/arch/arm/lib/interrupts_64.c +@@ -94,6 +94,10 @@ void do_bad_error(struct pt_regs *pt_regs, unsigned int esr) + panic("Resetting CPU ...\n"); + } + ++__weak void plat_do_sync(void) ++{ ++} ++ + /* + * do_sync handles the Synchronous Abort exception. + */ +@@ -101,6 +105,8 @@ void do_sync(struct pt_regs *pt_regs, unsigned int esr) + { + efi_restore_gd(); + printf("\"Synchronous Abort\" handler, esr 0x%08x\n", esr); ++ ++ plat_do_sync(); + show_regs(pt_regs); + show_efi_loaded_images(pt_regs); + panic("Resetting CPU ...\n"); +diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig +index fdd39685b7..09d871ee27 100644 +--- a/arch/arm/mach-mvebu/Kconfig ++++ b/arch/arm/mach-mvebu/Kconfig +@@ -16,10 +16,6 @@ config ARMADA_32BIT + select SUPPORT_SPL + select TRANSLATION_OFFSET + +-config ARMADA_64BIT +- bool +- select ARM64 +- + # ARMv7 SoCs... + config ARMADA_375 + bool +@@ -43,6 +39,7 @@ config ARMADA_3700 + config ARMADA_8K + bool + select ARM64 ++ select HAVE_MVEBU_EFUSE + + # Armada PLL frequency (used for NAND clock generation) + config SYS_MVEBU_PLL_CLOCK +@@ -113,6 +110,10 @@ config TARGET_DB_88F6820_AMC + bool "Support DB-88F6820-AMC" + select 88F6820 + ++config TARGET_DB_88F6820_AP ++ bool "Support DB-88F6820-AP" ++ select 88F6820 ++ + config TARGET_TURRIS_OMNIA + bool "Support Turris Omnia" + select 88F6820 +@@ -134,6 +135,12 @@ config TARGET_MVEBU_ARMADA_8K + select BOARD_LATE_INIT + imply SCSI + ++config TARGET_OCTEONTX2_CN913x ++ bool "Support CN913x" ++ select ARMADA_8K ++ select BOARD_LATE_INIT ++ imply SCSI ++ + config TARGET_DB_MV784MP_GP + bool "Support db-mv784mp-gp" + select MV78460 +@@ -177,9 +184,11 @@ config SYS_BOARD + default "db-88f6720" if TARGET_DB_88F6720 + default "db-88f6820-gp" if TARGET_DB_88F6820_GP + default "db-88f6820-amc" if TARGET_DB_88F6820_AMC ++ default "db-88f6820-ap" if TARGET_DB_88F6820_AP + default "turris_omnia" if TARGET_TURRIS_OMNIA + default "turris_mox" if TARGET_TURRIS_MOX + default "mvebu_armada-8k" if TARGET_MVEBU_ARMADA_8K ++ default "octeontx2_cn913x" if TARGET_OCTEONTX2_CN913x + default "db-mv784mp-gp" if TARGET_DB_MV784MP_GP + default "ds414" if TARGET_DS414 + default "maxbcm" if TARGET_MAXBCM +@@ -196,7 +205,9 @@ config SYS_CONFIG_NAME + default "db-88f6720" if TARGET_DB_88F6720 + default "db-88f6820-gp" if TARGET_DB_88F6820_GP + default "db-88f6820-amc" if TARGET_DB_88F6820_AMC ++ default "db-88f6820-ap" if TARGET_DB_88F6820_AP + default "mvebu_armada-8k" if TARGET_MVEBU_ARMADA_8K ++ default "octeontx2_cn913x" if TARGET_OCTEONTX2_CN913x + default "db-mv784mp-gp" if TARGET_DB_MV784MP_GP + default "ds414" if TARGET_DS414 + default "maxbcm" if TARGET_MAXBCM +@@ -214,9 +225,11 @@ config SYS_VENDOR + default "Marvell" if TARGET_DB_88F6720 + default "Marvell" if TARGET_DB_88F6820_GP + default "Marvell" if TARGET_DB_88F6820_AMC ++ default "Marvell" if TARGET_DB_88F6820_AP + default "Marvell" if TARGET_MVEBU_ARMADA_8K + default "Marvell" if TARGET_DB_XC3_24G4XG + default "Marvell" if TARGET_MVEBU_DB_88F7040 ++ default "Marvell" if TARGET_OCTEONTX2_CN913x + default "solidrun" if TARGET_CLEARFOG + default "kobol" if TARGET_HELIOS4 + default "Synology" if TARGET_DS414 +@@ -235,6 +248,9 @@ choice + config MVEBU_SPL_BOOT_DEVICE_SPI + bool "SPI NOR flash" + ++config MVEBU_SPL_BOOT_DEVICE_NAND ++ bool "NAND flash" ++ + config MVEBU_SPL_BOOT_DEVICE_MMC + bool "SDIO/MMC card" + select SPL_LIBDISK_SUPPORT +@@ -249,23 +265,6 @@ config MVEBU_SPL_BOOT_DEVICE_UART + + endchoice + +-config MVEBU_EFUSE +- bool "Enable eFuse support" +- default n +- depends on HAVE_MVEBU_EFUSE +- help +- Enable support for reading and writing eFuses on mvebu SoCs. +- +-config MVEBU_EFUSE_FAKE +- bool "Fake eFuse access (dry run)" +- default n +- depends on MVEBU_EFUSE +- help +- This enables a "dry run" mode where eFuses are not really programmed. +- Instead the eFuse accesses are emulated by writing to and reading +- from a memory block. +- This is can be used for testing prog scripts. +- + config SECURED_MODE_IMAGE + bool "Build image for trusted boot" + default false +@@ -279,4 +278,6 @@ config SECURED_MODE_CSK_INDEX + default 0 + depends on SECURED_MODE_IMAGE + ++source "arch/arm/mach-mvebu/armada3700/Kconfig" ++ + endif +diff --git a/arch/arm/mach-mvebu/Makefile b/arch/arm/mach-mvebu/Makefile +index 8228a17972..1bf147440b 100644 +--- a/arch/arm/mach-mvebu/Makefile ++++ b/arch/arm/mach-mvebu/Makefile +@@ -26,7 +26,6 @@ obj-$(CONFIG_ARMADA_375) += ../../../drivers/ddr/marvell/axp/xor.o + obj-$(CONFIG_ARMADA_38X) += ../../../drivers/ddr/marvell/a38x/xor.o + obj-$(CONFIG_ARMADA_XP) += ../../../drivers/ddr/marvell/axp/xor.o + obj-$(CONFIG_ARMADA_MSYS) += ../../../drivers/ddr/marvell/axp/xor.o +-obj-$(CONFIG_MVEBU_EFUSE) += efuse.o + + extra-y += kwbimage.cfg + +@@ -34,6 +33,9 @@ KWB_REPLACE += BOOT_FROM + ifneq ($(CONFIG_MVEBU_SPL_BOOT_DEVICE_SPI),) + KWB_CFG_BOOT_FROM=spi + endif ++ifneq ($(CONFIG_MVEBU_SPL_BOOT_DEVICE_NAND),) ++ KWB_CFG_BOOT_FROM=nand ++endif + ifneq ($(CONFIG_MVEBU_SPL_BOOT_DEVICE_MMC),) + KWB_CFG_BOOT_FROM=sdio + endif +diff --git a/arch/arm/mach-mvebu/arm64-common.c b/arch/arm/mach-mvebu/arm64-common.c +index aaf7b7c447..2809db8c51 100644 +--- a/arch/arm/mach-mvebu/arm64-common.c ++++ b/arch/arm/mach-mvebu/arm64-common.c +@@ -14,6 +14,8 @@ + #include + #include + #include ++#include ++#include + + DECLARE_GLOBAL_DATA_PTR; + +@@ -84,10 +86,44 @@ static void a8k_dram_init_banksize(void) + } + } + ++static u64 a3700_dram_scan_ap_sz(void) ++{ ++ struct pt_regs pregs; ++ ++ pregs.regs[0] = MV_SIP_DRAM_SIZE; ++ smc_call(&pregs); ++ ++ return pregs.regs[0]; ++} ++ ++static void a3700_dram_init_banksize(void) ++{ ++ /* If ddr size is below 2GB there is only one ddr bank used */ ++ gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE; ++ if (gd->ram_size <= SZ_2G) { ++ gd->bd->bi_dram[0].size = gd->ram_size; ++ return; ++ } ++ ++ /* ++ * If ddr size is above 2GB there is only one case 4GB but the firmware ++ * uses 4 decoding windows for describing it in way reflected below. ++ */ ++ gd->bd->bi_dram[0].size = SZ_2G; ++ gd->bd->bi_dram[1].start = SZ_2G; ++ gd->bd->bi_dram[1].size = SZ_1G; ++ gd->bd->bi_dram[2].start = SZ_2G + SZ_1G; ++ gd->bd->bi_dram[2].size = SZ_256M; ++ gd->bd->bi_dram[3].start = 0xe0000000; ++ gd->bd->bi_dram[3].size = SZ_128M; ++} ++ + __weak int dram_init_banksize(void) + { + if (CONFIG_IS_ENABLED(ARMADA_8K)) + a8k_dram_init_banksize(); ++ else if (CONFIG_IS_ENABLED(ARMADA_3700)) ++ a3700_dram_init_banksize(); + else + fdtdec_setup_memory_banksize(); + +@@ -96,11 +132,13 @@ __weak int dram_init_banksize(void) + + __weak int dram_init(void) + { +- if (CONFIG_IS_ENABLED(ARMADA_8K)) { ++ if (CONFIG_IS_ENABLED(ARMADA_8K)) + gd->ram_size = a8k_dram_scan_ap_sz(); +- if (gd->ram_size != 0) +- return 0; +- } ++ else if (CONFIG_IS_ENABLED(ARMADA_3700)) ++ gd->ram_size = a3700_dram_scan_ap_sz(); ++ ++ if (gd->ram_size != 0) ++ return 0; + + if (fdtdec_setup_mem_size_base() != 0) + return -EINVAL; +@@ -120,6 +158,8 @@ int arch_early_init_r(void) + int ret; + int i; + ++ printf("Running in RAM - U-Boot at: 0x%08lx\n", gd->relocaddr); ++ printf(" Env at: 0x%08lx\n", gd->env_addr); + /* + * Loop over all MISC uclass drivers to call the comphy code + * and init all CP110 devices enabled in the DT +@@ -134,6 +174,16 @@ int arch_early_init_r(void) + break; + } + ++ i = 0; ++ while (1) { ++ /* Call the pinctrl code via the PINCTRL uclass driver */ ++ ret = uclass_get_device(UCLASS_PINCTRL, i++, &dev); ++ ++ /* We're done, once no further CP110 device is found */ ++ if (ret) ++ break; ++ } ++ + /* Cause the SATA device to do its early init */ + uclass_first_device(UCLASS_AHCI, &dev); + +@@ -144,3 +194,24 @@ int arch_early_init_r(void) + + return 0; + } ++ ++void plat_do_sync(void) ++{ ++ u32 far, el; ++ ++ el = current_el(); ++ ++ if (el == 1) ++ asm volatile("mrs %0, far_el1" : "=r" (far)); ++ else if (el == 2) ++ asm volatile("mrs %0, far_el2" : "=r" (far)); ++ else ++ asm volatile("mrs %0, far_el3" : "=r" (far)); ++ ++ if (far >= ATF_REGION_START && far <= ATF_REGION_END) { ++ pr_err("\n\tAttempt to access RT service or TEE region (addr: 0x%x, el%d)\n", ++ far, el); ++ pr_err("\tDo not use address range 0x%x-0x%x\n\n", ++ ATF_REGION_START, ATF_REGION_END); ++ } ++} +diff --git a/arch/arm/mach-mvebu/armada3700/Kconfig b/arch/arm/mach-mvebu/armada3700/Kconfig +new file mode 100644 +index 0000000000..2bd127fe59 +--- /dev/null ++++ b/arch/arm/mach-mvebu/armada3700/Kconfig +@@ -0,0 +1,12 @@ ++menu "eFuse support" ++ ++config MVEBU_EFUSE_SUPPORT ++ bool "eFuse support" ++ depends on TARGET_MVEBU_ARMADA_37XX && CMD_MVEBU_EFUSE ++ default n ++ help ++ Choose this option to add support ++ for eFuse access driver and enable ++ mailbox for eFuse read/write actions ++ ++endmenu +diff --git a/arch/arm/mach-mvebu/armada3700/Makefile b/arch/arm/mach-mvebu/armada3700/Makefile +index 031b3e854e..7a638de8c8 100644 +--- a/arch/arm/mach-mvebu/armada3700/Makefile ++++ b/arch/arm/mach-mvebu/armada3700/Makefile +@@ -3,3 +3,6 @@ + # Copyright (C) 2016 Stefan Roese + + obj-y = cpu.o ++obj-y += clock.o ++obj-$(CONFIG_MVEBU_EFUSE_SUPPORT) += efuse.o ++obj-$(CONFIG_MVEBU_EFUSE_SUPPORT) += mbox.o +diff --git a/arch/arm/mach-mvebu/armada3700/clock.c b/arch/arm/mach-mvebu/armada3700/clock.c +new file mode 100644 +index 0000000000..f81ba48305 +--- /dev/null ++++ b/arch/arm/mach-mvebu/armada3700/clock.c +@@ -0,0 +1,244 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define NB_CLOCK_REGS_BASE (MVEBU_REGISTER(0x13000)) ++#define NB_PLL_BASE (NB_CLOCK_REGS_BASE + 0x200) ++#define NB_TBG_CTRL0 (NB_PLL_BASE + 0x4) ++ #define NB_TBG_CTRL0_TBG_A_FBDIV_OFFSET 2 ++ #define NB_TBG_CTRL0_TBG_A_FBDIV_MASK 0x1FFUL ++ #define NB_TBG_CTRL0_TBG_B_FBDIV_OFFSET 18 ++ #define NB_TBG_CTRL0_TBG_B_FBDIV_MASK 0x1FFUL ++ ++#define NB_TBG_CTRL1 (NB_PLL_BASE + 0x8) ++ #define NB_TBG_CTRL1_TBG_B_VCODIV_SEL_SE_OFFSET 16 ++ #define NB_TBG_CTRL1_TBG_B_VCODIV_SEL_SE_MASK 0x1FFUL ++ #define NB_TBG_CTRL1_TBG_A_VCODIV_SEL_SE_MASK 0x1FFUL ++ ++#define NB_TBG_CTRL7 (NB_PLL_BASE + 0x20) ++ #define NB_TBG_CTRL7_TBG_B_REFDIV_OFFSET 16 ++ #define NB_TBG_CTRL7_TBG_B_REFDIV_MASK 0x1FFUL ++ #define NB_TBG_CTRL7_TBG_A_REFDIV_MASK 0x1FFUL ++ ++#define NB_TBG_CTRL8 (NB_PLL_BASE + 0x30) ++ #define NB_TBG_CTRL8_TBG_A_VCODIV_SEL_DIFF_OFFSET 1 ++ #define NB_TBG_CTRL8_TBG_A_VCODIV_SEL_DIFF_MASK 0x1FFUL ++ #define NB_TBG_CTRL8_TBG_B_VCODIV_SEL_DIFF_OFFSET 17 ++ #define NB_TBG_CTRL8_TBG_B_VCODIV_SEL_DIFF_MASK 0x1FFUL ++ ++#define NB_CLOCK_TBG_SELECT_REG NB_CLOCK_REGS_BASE ++ #define NB_CLOCK_TBG_SEL_A53_CPU_PCLK_OFFSET 22 ++ #define NB_CLOCK_TBG_SEL_A53_CPU_PCLK_MASK 0x3 ++ ++/* north bridge clock divider select registers */ ++#define NB_CLOCK_DIV_SEL0_REG (NB_CLOCK_REGS_BASE + 0x4) ++ #define NB_CLOCK_DIV_SEL0_A53_CPU_CLK_PRSCL_OFFSET 28 ++ #define NB_CLOCK_DIV_SEL0_A53_CPU_CLK_PRSCL_MASK 0x7 ++ ++/* north bridge clock source register */ ++#define NB_CLOCK_SELECT_REG (NB_CLOCK_REGS_BASE + 0x10) ++ #define NB_CLOCK_SEL_DDR_PHY_CLK_SEL_OFFSET 10 ++ #define NB_CLOCK_SEL_DDR_PHY_CLK_SEL_MASK 0x1 ++ #define NB_CLOCK_SEL_A53_CPU_CLK_OFFSET 15 ++ #define NB_CLOCK_SEL_A53_CPU_CLK_MASK 0x1 ++ ++#define TBG_A_REFDIV_GET(reg_val) ((reg_val >> 0) &\ ++ NB_TBG_CTRL7_TBG_A_REFDIV_MASK) ++#define TBG_B_REFDIV_GET(reg_val) ((reg_val >>\ ++ NB_TBG_CTRL7_TBG_B_REFDIV_OFFSET) &\ ++ NB_TBG_CTRL7_TBG_B_REFDIV_MASK) ++#define TBG_A_FBDIV_GET(reg_val) ((reg_val >>\ ++ NB_TBG_CTRL0_TBG_A_FBDIV_OFFSET) &\ ++ NB_TBG_CTRL0_TBG_A_FBDIV_MASK) ++#define TBG_B_FBDIV_GET(reg_val) ((reg_val >>\ ++ NB_TBG_CTRL0_TBG_B_FBDIV_OFFSET) &\ ++ NB_TBG_CTRL0_TBG_B_FBDIV_MASK) ++#define TBG_A_VCODIV_SEL_SE_GET(reg_val) ((reg_val >> 0) &\ ++ NB_TBG_CTRL1_TBG_A_VCODIV_SEL_SE_MASK) ++#define TBG_B_VCODIV_SEL_SE_GET(reg_val) ((reg_val >>\ ++ NB_TBG_CTRL1_TBG_B_VCODIV_SEL_SE_OFFSET) &\ ++ NB_TBG_CTRL1_TBG_B_VCODIV_SEL_SE_MASK) ++#define TBG_A_VCODIV_SEL_DIFF_GET(reg_val) ((reg_val >>\ ++ NB_TBG_CTRL8_TBG_A_VCODIV_SEL_DIFF_OFFSET) &\ ++ NB_TBG_CTRL8_TBG_A_VCODIV_SEL_DIFF_MASK) ++#define TBG_B_VCODIV_SEL_DIFF_GET(reg_val) ((reg_val >>\ ++ NB_TBG_CTRL8_TBG_B_VCODIV_SEL_DIFF_OFFSET) &\ ++ NB_TBG_CTRL8_TBG_B_VCODIV_SEL_DIFF_MASK) ++#define A53_CPU_CLK_SEL_GET(reg_val) ((reg_val >>\ ++ NB_CLOCK_SEL_A53_CPU_CLK_OFFSET) &\ ++ NB_CLOCK_SEL_A53_CPU_CLK_MASK) ++#define A53_CPU_PCLK_SEL_GET(reg_val) ((reg_val >>\ ++ NB_CLOCK_TBG_SEL_A53_CPU_PCLK_OFFSET) &\ ++ NB_CLOCK_TBG_SEL_A53_CPU_PCLK_MASK) ++#define A53_CPU_CLK_PRSCL_GET(reg_val) ((reg_val >>\ ++ NB_CLOCK_DIV_SEL0_A53_CPU_CLK_PRSCL_OFFSET) &\ ++ NB_CLOCK_DIV_SEL0_A53_CPU_CLK_PRSCL_MASK) ++#define DDR_PHY_CLK_SEL_GET(reg_val) ((reg_val >>\ ++ NB_CLOCK_SEL_DDR_PHY_CLK_SEL_OFFSET) &\ ++ NB_CLOCK_SEL_DDR_PHY_CLK_SEL_MASK) ++ ++#define TCLK 200 ++#define L2_CLK 800 ++#define TIMER_CLK 800 ++ ++enum a3700_clock_line { ++ TBG_A_P = 0, ++ TBG_B_P = 1, ++ TBG_A_S = 2, ++ TBG_B_S = 3 ++}; ++ ++/* Clock source selection */ ++enum a3700_clk_select { ++ CLK_SEL_OSC = 0, ++ CLK_SEL_TBG, ++}; ++ ++/* TBG divider */ ++enum a3700_tbg_divider { ++ TBG_DIVIDER_1 = 1, ++ TBG_DIVIDER_2, ++ TBG_DIVIDER_3, ++ TBG_DIVIDER_4, ++ TBG_DIVIDER_5, ++ TBG_DIVIDER_6, ++ TBG_DIVIDER_NUM ++}; ++ ++static u32 get_tbg_clk(enum a3700_clock_line tbg_typ) ++{ ++ u32 tbg_M, tbg_N, vco_div; ++ u32 ref, reg_val; ++ ++ /* get ref clock */ ++ ref = get_ref_clk(); ++ ++ /* get M, N */ ++ reg_val = readl(NB_TBG_CTRL7); ++ tbg_M = ((tbg_typ == TBG_A_S) || (tbg_typ == TBG_A_P)) ? ++ TBG_A_REFDIV_GET(reg_val) : TBG_B_REFDIV_GET(reg_val); ++ tbg_M = (tbg_M == 0) ? 1 : tbg_M; ++ ++ reg_val = readl(NB_TBG_CTRL0); ++ tbg_N = ((tbg_typ == TBG_A_S) || (tbg_typ == TBG_A_P)) ? ++ TBG_A_FBDIV_GET(reg_val) : TBG_B_FBDIV_GET(reg_val); ++ ++ if ((tbg_typ == TBG_A_S) || (tbg_typ == TBG_B_S)) { ++ /* get SE VCODIV */ ++ reg_val = readl(NB_TBG_CTRL1); ++ reg_val = (tbg_typ == TBG_A_S) ? ++ TBG_A_VCODIV_SEL_SE_GET(reg_val) : ++ TBG_B_VCODIV_SEL_SE_GET(reg_val); ++ } else { ++ /* get DIFF VCODIV */ ++ reg_val = readl(NB_TBG_CTRL8); ++ reg_val = (tbg_typ == TBG_A_P) ? ++ TBG_A_VCODIV_SEL_DIFF_GET(reg_val) : ++ TBG_B_VCODIV_SEL_DIFF_GET(reg_val); ++ } ++ if (reg_val > 7) ++ return 0; /*invalid*/ ++ ++ vco_div = 0x1 << reg_val; ++ ++ return ((tbg_N * ref) << 2) / (tbg_M * vco_div); ++} ++ ++u32 soc_cpu_clk_get(void) ++{ ++ u32 tbg, cpu_prscl; ++ enum a3700_clock_line tbg_typ; ++ ++ /* 1. check cpu clock select */ ++ if (!A53_CPU_CLK_SEL_GET(readl(NB_CLOCK_SELECT_REG))) ++ return 0; /* CPU clock is using XTAL output*/ ++ ++ /* 2. get TBG select */ ++ tbg_typ = A53_CPU_PCLK_SEL_GET(readl(NB_CLOCK_TBG_SELECT_REG)); ++ ++ /* 3. get TBG clock */ ++ tbg = get_tbg_clk(tbg_typ); ++ if (tbg == 0) ++ return 0; ++ ++ /* 4. get CPU clk divider */ ++ cpu_prscl = A53_CPU_CLK_PRSCL_GET(readl(NB_CLOCK_DIV_SEL0_REG)); ++ if (cpu_prscl == 7) ++ return 0; /* divider value error */ ++ ++ return tbg / cpu_prscl; ++} ++ ++u32 soc_ddr_clk_get(void) ++{ ++ u32 tbg; ++ ++ /* 1. check DDR clock select */ ++ if (!DDR_PHY_CLK_SEL_GET(readl(NB_CLOCK_SELECT_REG))) ++ return 0; /* DDR clock is using XTAL output*/ ++ ++ /* 2. get TBG_A clock */ ++ tbg = get_tbg_clk(TBG_A_S); ++ if (tbg == 0) ++ return 0; ++ ++ return tbg >> 1; ++} ++ ++/****************************************************************************** ++ * Name: get_cpu_clk_src_div ++ * ++ * Description: Get CPU clock source selection and prescaling divider ++ * ++ * Input: None ++ * Output: cpu_clk_sel: CPU clock source selection ++ * cpu_clk_prscl: CPU clock prescaling divider ++ * Return: Non-zero if failed to get the CPU clock selection and prescaling ++ ******************************************************************************* ++ */ ++int get_cpu_clk_src_div(u32 *cpu_clk_sel, u32 *cpu_clk_prscl) ++{ ++ /* 1. check cpu clock select */ ++ if (!A53_CPU_CLK_SEL_GET(readl(NB_CLOCK_SELECT_REG))) ++ return -1; /* CPU clock is using XTAL output*/ ++ ++ /* 2. get TBG select */ ++ *cpu_clk_sel = A53_CPU_PCLK_SEL_GET(readl(NB_CLOCK_TBG_SELECT_REG)); ++ ++ /* 3. get CPU clk divider */ ++ *cpu_clk_prscl = A53_CPU_CLK_PRSCL_GET(readl(NB_CLOCK_DIV_SEL0_REG)); ++ ++ return 0; ++} ++ ++u32 soc_tclk_get(void) ++{ ++ return TCLK; ++} ++ ++u32 soc_l2_clk_get(void) ++{ ++ return L2_CLK; ++} ++ ++u32 soc_timer_clk_get(void) ++{ ++ return TIMER_CLK; ++} ++ ++void soc_print_clock_info(void) ++{ ++ printf(" CPU %d [MHz]\n", soc_cpu_clk_get()); ++ printf(" L2 %d [MHz]\n", soc_l2_clk_get()); ++ printf(" TClock %d [MHz]\n", soc_tclk_get()); ++ printf(" DDR %d [MHz]\n", soc_ddr_clk_get()); ++} +diff --git a/arch/arm/mach-mvebu/armada3700/cpu.c b/arch/arm/mach-mvebu/armada3700/cpu.c +index 7c8e4cade1..4ca8cc4cb9 100644 +--- a/arch/arm/mach-mvebu/armada3700/cpu.c ++++ b/arch/arm/mach-mvebu/armada3700/cpu.c +@@ -12,6 +12,8 @@ + #include + #include + #include ++#include ++#include + + /* Armada 3700 */ + #define MVEBU_GPIO_NB_REG_BASE (MVEBU_REGISTER(0x13800)) +@@ -30,6 +32,15 @@ static struct mm_region mvebu_mem_map[] = { + /* RAM */ + .phys = 0x0UL, + .virt = 0x0UL, ++ .size = ATF_REGION_START, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | ++ PTE_BLOCK_INNER_SHARE ++ }, ++ /* ATF and TEE region 0x4000000-0x5400000 not mapped */ ++ { ++ /* RAM */ ++ .phys = ATF_REGION_END, ++ .virt = ATF_REGION_END, + .size = 0x80000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE +@@ -84,3 +95,12 @@ u32 get_ref_clk(void) + else + return 40; + } ++ ++#if defined(CONFIG_DISPLAY_BOARDINFO) ++int print_cpuinfo(void) ++{ ++ soc_print_clock_info(); ++ ++ return 0; ++} ++#endif +diff --git a/arch/arm/mach-mvebu/armada3700/efuse.c b/arch/arm/mach-mvebu/armada3700/efuse.c +new file mode 100644 +index 0000000000..2857eb471e +--- /dev/null ++++ b/arch/arm/mach-mvebu/armada3700/efuse.c +@@ -0,0 +1,448 @@ ++/* ++ * Copyright (C) 2017 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++enum a3700_boot_dev { ++ AUTO = 0, ++ SPINOR = 1, ++ EMMCNORM = 2, ++ EMMCALT = 3, ++ SATA = 4, ++ SPINAND = 5, ++ UART = 6, ++ INVALID = 7, ++ VECTOR_DIV = 8, ++ VECTOR_XTAL = 9, ++ ++ MAX_BOOT_DEVS ++}; ++ ++#define A3700_BOOT_DEV_NAMES {"AUTO", "SPINOR", "EMMCNORM", "EMMCALT", \ ++ "SATA", "SPINAND", "UART", "", "", ""} ++ ++struct a3700_efuse_info { ++ /* efuse ID */ ++ enum efuse_id id; ++ /* mailbox operation size bit/byte/word, etc. */ ++ enum mbox_opsize mbopsz; ++ /* efuse row or start row for multi-row values */ ++ uint32_t row; ++ /* number of write operations required for setting the field */ ++ uint32_t numops; ++ /* efuse bit offset within the row for bit size efuses */ ++ int32_t bitoffs[4]; ++}; ++ ++#define A3700_EFUSE_INFO { \ ++ { EFUSE_ID_BOOT_DEVICE, MB_OPSZ_BIT, 1, 4, { 48, 52, 56, 60 } }, \ ++ { EFUSE_ID_KAK_DIGEST, MB_OPSZ_256B, 8, 1, { 0, 0, 0, 0 } }, \ ++ { EFUSE_ID_CSK_INDEX, MB_OPSZ_DWORD, 3, 1, { 0, 0, 0, 0 } }, \ ++ { EFUSE_ID_AES_KEY, MB_OPSZ_256B, 26, 1, { 0, 0, 0, 0 } }, \ ++ { EFUSE_ID_ENCRYPTION_EN, MB_OPSZ_BIT, 0, 2, { 56, 60, 0, 0 } }, \ ++ { EFUSE_ID_JTAG_DIGECT, MB_OPSZ_256B, 16, 1, { 0, 0, 0, 0 } }, \ ++ { EFUSE_ID_SEC_JTAG_DIS, MB_OPSZ_BIT, 0, 1, { 24, 0, 0, 0 } }, \ ++ { EFUSE_ID_SEC_JTAG_PERM_DIS, MB_OPSZ_BIT, 0, 1, { 28, 0, 0, 0 } }, \ ++ { EFUSE_ID_AP_JTAG_DIS, MB_OPSZ_BIT, 0, 1, { 16, 0, 0, 0 } }, \ ++ { EFUSE_ID_AP_JTAG_PERM_DIS, MB_OPSZ_BIT, 0, 1, { 20, 0, 0, 0 } }, \ ++ { EFUSE_ID_SPI_NAND_CFG, MB_OPSZ_DWORD, 6, 1, { 0, 0, 0, 0 } }, \ ++ { EFUSE_ID_PIN, MB_OPSZ_DWORD, 4, 1, { 0, 0, 0, 0 } }, \ ++ { EFUSE_ID_TOKEN, MB_OPSZ_DWORD, 5, 1, { 0, 0, 0, 0 } }, \ ++ { EFUSE_ID_SPI_CS, MB_OPSZ_BIT, 1, 2, { 40, 44, 0, 0 } }, \ ++ { EFUSE_ID_EMMC_CLOCK, MB_OPSZ_BIT, 1, 2, { 32, 36, 0, 0 } }, \ ++ { EFUSE_ID_OPERATION_MODE, MB_OPSZ_BIT, 1, 2, { 0, 4, 0, 0 } }, \ ++ { EFUSE_ID_UART_DIS, MB_OPSZ_BIT, 0, 1, { 32, 0, 0, 0 } }, \ ++ { EFUSE_ID_UART_PERM_DIS, MB_OPSZ_BIT, 0, 1, { 36, 0, 0, 0 } }, \ ++ { EFUSE_ID_ESC_SEQ_DIS, MB_OPSZ_BIT, 1, 1, { 20, 0, 0, 0 } }, \ ++ { EFUSE_ID_GPIO_TOGGLE_DIS, MB_OPSZ_BIT, 1, 1, { 16, 0, 0, 0 } }, \ ++ { EFUSE_ID_LONG_KEY_EN, MB_OPSZ_BIT, 1, 1, { 12, 0, 0, 0 } } \ ++} ++ ++static struct a3700_efuse_info efuse_info[EFUSE_ID_MAX] = A3700_EFUSE_INFO; ++static char *bdnames[] = A3700_BOOT_DEV_NAMES; ++ ++/****************************************************************************** ++ * efuse_id_valid ++ ******************************************************************************/ ++int efuse_id_valid(enum efuse_id fid) ++{ ++ if (fid < EFUSE_ID_MAX) ++ return 1; ++ else ++ return 0; ++} ++ ++/****************************************************************************** ++ * efuse_write ++ ******************************************************************************/ ++int efuse_write(enum efuse_id fid, const char *value) ++{ ++ uint32_t args[MBOX_MAX_ARGS]; ++ enum a3700_boot_dev bdev; ++ uint32_t info_idx, numval = 0; ++ uint32_t numwords, ascii_words; ++ char buf[9]; ++ int status, n; ++ enum mbox_status cmd_stat; ++ uint64_t fullrow; ++ char *str, *strcopy, *substr; ++ uint32_t val[4]; ++ ++ /* Find efuse info with length and offset */ ++ for (info_idx = 0; info_idx < EFUSE_ID_MAX; info_idx++) { ++ if (efuse_info[info_idx].id == fid) ++ break; ++ } ++ ++ if (info_idx == EFUSE_ID_MAX) { ++ printf("%s: Unsupported eFuse ID\n", __func__); ++ return 1; ++ } ++ ++ /* Each word is coded by 8 ASCII characters, one character per nibble */ ++ numwords = strlen(value) >> 3; ++ memset(buf, 0, 9); ++ memset(args, 0, MBOX_MAX_ARGS * sizeof(uint32_t)); ++ ++ /* parse input parameter */ ++ switch (fid) { ++ case EFUSE_ID_BOOT_DEVICE: ++ for (bdev = 0; bdev < MAX_BOOT_DEVS; bdev++) { ++ if (strcmp(value, bdnames[bdev]) == 0) ++ break; ++ } ++ if (bdev == MAX_BOOT_DEVS) { ++ printf("%s: Unsupported Boot Device\n", __func__); ++ return 1; ++ } ++ numval = bdev; ++ break; ++ ++ case EFUSE_ID_KAK_DIGEST: ++ case EFUSE_ID_AES_KEY: ++ case EFUSE_ID_JTAG_DIGECT: ++ case EFUSE_ID_PIN: ++ case EFUSE_ID_TOKEN: ++ /* TODO - add support for 512b keys if needed */ ++ if (efuse_info[info_idx].mbopsz == MB_OPSZ_256B) { ++ ascii_words = 8; ++ } else if (efuse_info[info_idx].mbopsz == MB_OPSZ_DWORD) { ++ ascii_words = 2; ++ } else { ++ printf("Bad operation size for this key!\n"); ++ return 1; ++ } ++ if (numwords != ascii_words) { ++ printf("%s: Unsupported digest length (%d) - expected %d bytes\n", ++ __func__, numwords << 3, ascii_words << 3); ++ return 1; ++ } ++ /* Convert ASCII representation to WORD integer arguments ++ The eFuse has to have LSB part in lower rows */ ++ for (n = 0; n < numwords; n++) { ++ /* 8 ASCII characters in WORD argument */ ++ memcpy(buf, &value[n * 8], 8); ++ args[numwords - n - 1] = simple_strtoul(buf, 0, 16); ++ } ++ break; ++ ++ case EFUSE_ID_CSK_INDEX: ++ numval = simple_strtoul(value, 0, 10); ++ if (numval > 15) { ++ printf("%s: Invalid CSK index %d, expected [0..15]\n", ++ __func__, numval); ++ return 1; ++ } ++ /* The CSK key validity is stored in a single efuse row, ++ but the bit offset depends on CSK index. ++ Each index is selected by majority vote out of 3 bits. ++ In order to set single index, 2 or 3 physical bits should ++ be programmed. Gap between index start positions is 4 bits. ++ */ ++ fullrow = 0x7 << (4 * numval); ++ args[0] = fullrow & 0xFFFFFFFF; ++ args[1] = (fullrow >> 32) & 0xFFFFFFFF; ++ break; ++ ++ case EFUSE_ID_ENCRYPTION_EN: ++ numval = simple_strtoul(value, 0, 16); ++ if ((numval != 0x11) && (numval != 0x10) && (numval != 0x1)) { ++ printf("%s: Invalid value %x, expected 1, 10 or 11\n", ++ __func__, numval); ++ return 1; ++ } ++ numval = (numval & 1) | ((numval & 0x10) >> 3); ++ break; ++ ++ case EFUSE_ID_SEC_JTAG_DIS: ++ case EFUSE_ID_SEC_JTAG_PERM_DIS: ++ case EFUSE_ID_AP_JTAG_DIS: ++ case EFUSE_ID_AP_JTAG_PERM_DIS: ++ case EFUSE_ID_UART_DIS: ++ case EFUSE_ID_UART_PERM_DIS: ++ case EFUSE_ID_ESC_SEQ_DIS: ++ case EFUSE_ID_GPIO_TOGGLE_DIS: ++ case EFUSE_ID_LONG_KEY_EN: ++ case EFUSE_ID_EMMC_CLOCK: ++ numval = simple_strtoul(value, 0, 10); ++ if (numval != 1) { ++ printf("%s: Invalid value %d, expected 1\n", ++ __func__, numval); ++ return 1; ++ } ++ break; ++ ++ case EFUSE_ID_OPERATION_MODE: ++ case EFUSE_ID_SPI_CS: ++ numval = simple_strtoul(value, 0, 10); ++ if (numval > 3) { ++ printf("%s: Invalid value %d, expected [0..3]\n", ++ __func__, numval); ++ return 1; ++ } ++ break; ++ ++ case EFUSE_ID_SPI_NAND_CFG: ++ strcopy = strdup(value); ++ if (strcopy == NULL) { ++ printf("%s: Unable to duplicate parameters list!\n", ++ __func__); ++ return 1; ++ } ++ str = strcopy; ++ for (n = 0; n < 4; n++) { ++ if (str == NULL) { ++ printf("%s: Invalid parameters list, expected PZ.BP.SO.SN\n", ++ __func__); ++ return 1; ++ } ++ substr = strsep(&str, "."); ++ val[n] = simple_strtoul(substr, 0, 10); ++ if (((n == 0) && (val[n] > 0xFFFF)) || ++ ((n > 0) && (val[n] > 0xFF))) { ++ printf("%s: Invalid value[%d] %d, expected %s\n", ++ __func__, n, val[n], n == 0 ? ++ "0 - 65535" : "0 - 255"); ++ return 1; ++ } ++ } ++ free(strcopy); ++ /* PZ - bit[15:0], PB - bit[23:16] */ ++ args[0] = (val[1] << 16) | val[0]; ++ /* SO - bit[39:32], SN - bit[55:48] */ ++ args[1] = (val[3] << 16) | val[2]; ++ break; ++ ++ default: ++ printf("%s: This eFuse ID write function is not implemented\n", ++ __func__); ++ return 1; ++ } ++ ++ /* Send command to the remote CPU */ ++ for (n = 0; n < efuse_info[info_idx].numops; n++) { ++ /* for bit fields write 1 bit a time */ ++ if (efuse_info[info_idx].mbopsz == MB_OPSZ_BIT) ++ args[0] = (numval >> n) & 1; ++ ++ status = mbox_send(efuse_info[info_idx].mbopsz, ++ MB_OP_WRITE, ++ efuse_info[info_idx].row, ++ efuse_info[info_idx].bitoffs[n], ++ args); ++ ++ if (status != 0) { ++ printf("%s: Failed to dispatch command to remote CPU (n=%d)\n", ++ __func__, n); ++ break; ++ } ++ ++ /* Ensure the command execution ended on remote CPU */ ++ cmd_stat = MB_STAT_SUCCESS; ++ status = mbox_receive(&cmd_stat, args, MBOX_CMD_TIMEOUT); ++ if (status != 0 || cmd_stat != MB_STAT_SUCCESS) { ++ printf("%s: Remote command execution failed (n=%d). Error local=%d, remote=%d\n", ++ __func__, n, status, cmd_stat); ++ break; ++ } ++ } ++ ++ return status; ++} ++ ++/****************************************************************************** ++ * efuse_read ++ ******************************************************************************/ ++int efuse_read(enum efuse_id fid, char *value) ++{ ++ uint32_t args[MBOX_MAX_ARGS]; ++ uint32_t info_idx, n; ++ uint32_t count; ++ int status; ++ enum mbox_status cmd_stat; ++ uint32_t numval = 0; ++ uint32_t page_sz, page_block, spare_offs, spare_page; ++ uint32_t numwords; ++ uint64_t fullrow; ++ ++ /* Find efuse info with length and offset */ ++ for (info_idx = 0; info_idx < EFUSE_ID_MAX; info_idx++) { ++ if (efuse_info[info_idx].id == fid) ++ break; ++ } ++ if (info_idx == EFUSE_ID_MAX) { ++ printf("%s: Unsupported eFuse ID\n", __func__); ++ return 1; ++ } ++ ++ memset(args, 0, MBOX_MAX_ARGS * sizeof(uint32_t)); ++ ++ /* Send command to the remote CPU */ ++ for (n = 0; n < efuse_info[info_idx].numops; n++) { ++ status = mbox_send(efuse_info[info_idx].mbopsz, ++ MB_OP_READ, ++ efuse_info[info_idx].row, ++ efuse_info[info_idx].bitoffs[n], ++ args); ++ ++ if (status != 0) { ++ printf("%s: Failed to dispatch command to remote CPU (n=%d)\n", ++ __func__, n); ++ return status; ++ } ++ ++ /* ++ * Ensure the command execution ended ++ * on remote CPU and get the result ++ */ ++ cmd_stat = MB_STAT_SUCCESS; ++ status = mbox_receive(&cmd_stat, args, MBOX_CMD_TIMEOUT); ++ if (status != 0) { ++ printf("%s: Failed locally (n=%d). Error=%d\n", ++ __func__, n, status); ++ return status; ++ } else if (cmd_stat != MB_STAT_SUCCESS) { ++ printf("%s: Failed on remote (n=%d). Error=%d\n", ++ __func__, n, cmd_stat); ++ return 1; ++ } ++ ++ /* for bit fields collect 1 bit a time */ ++ if (efuse_info[info_idx].mbopsz == MB_OPSZ_BIT) ++ numval |= (args[0] & 1) << n; ++ } ++ ++ /* format the output value */ ++ switch (fid) { ++ case EFUSE_ID_BOOT_DEVICE: ++ if (numval >= MAX_BOOT_DEVS || numval == INVALID) ++ sprintf(value, "INVALID VALUE (%d)", numval); ++ else ++ sprintf(value, "%s (%d)", bdnames[numval], numval); ++ break; ++ ++ case EFUSE_ID_KAK_DIGEST: ++ case EFUSE_ID_AES_KEY: ++ case EFUSE_ID_JTAG_DIGECT: ++ case EFUSE_ID_PIN: ++ case EFUSE_ID_TOKEN: ++ /* TODO - add support for 512b keys if needed */ ++ if (efuse_info[info_idx].mbopsz == MB_OPSZ_256B) { ++ numwords = 8; ++ } else if (efuse_info[info_idx].mbopsz == MB_OPSZ_DWORD) { ++ numwords = 2; ++ } else { ++ printf("Bad operation size for this key!\n"); ++ return 1; ++ } ++ /* The eFuse has LSB part in lower rows */ ++ for (n = 0; n < numwords; n++) ++ sprintf(value + n * 8, "%08X", args[numwords - n - 1]); ++ break; ++ ++ case EFUSE_ID_CSK_INDEX: ++ /* show all valid CSK IDs */ ++ count = 0; ++ fullrow = args[1]; /* MSB */ ++ fullrow <<= 32; ++ fullrow |= args[0]; /* LSB */ ++ for (n = 0; n < 15; n++) { ++ /* Each CSK validity is a 3 bit majority vote ++ The distance between fileds is 4 bits */ ++ numval = (fullrow >> (n * 4)) & 0x7; ++ /* Two or more bits set - CSK is valid */ ++ if (numval > 4 || numval == 3) ++ count += sprintf(value + count, "%d ", n); ++ } ++ if (count == 0) ++ sprintf(value, "NONE"); ++ break; ++ ++ case EFUSE_ID_ENCRYPTION_EN: ++ sprintf(value, "%01d%01d", (numval >> 1) & 1, numval & 1); ++ break; ++ ++ case EFUSE_ID_LONG_KEY_EN: ++ sprintf(value, "%s (%d)", numval == 0 ? ++ "DISABLED" : "ENABLED", numval); ++ break; ++ ++ case EFUSE_ID_SEC_JTAG_DIS: ++ case EFUSE_ID_SEC_JTAG_PERM_DIS: ++ case EFUSE_ID_AP_JTAG_DIS: ++ case EFUSE_ID_AP_JTAG_PERM_DIS: ++ case EFUSE_ID_UART_DIS: ++ case EFUSE_ID_UART_PERM_DIS: ++ case EFUSE_ID_ESC_SEQ_DIS: ++ case EFUSE_ID_GPIO_TOGGLE_DIS: ++ sprintf(value, "%s (%d)", numval == 1 ? ++ "DISABLED" : "ENABLED", numval); ++ break; ++ ++ case EFUSE_ID_OPERATION_MODE: ++ case EFUSE_ID_SPI_CS: ++ sprintf(value, "%d", numval); ++ break; ++ ++ case EFUSE_ID_EMMC_CLOCK: ++ sprintf(value, "%s (%d)", numval == 0 ? ++ "12.5MHz" : "50MHz", numval); ++ break; ++ ++ case EFUSE_ID_SPI_NAND_CFG: ++ page_sz = args[0] & 0xFFFF; /* bit[15:0] */ ++ page_block = (args[0] >> 16) & 0xFF; /* bit[23:16] */ ++ /* bit[39:32], value 1 means byte 0 */ ++ spare_offs = args[1] & 0xFF; ++ /* bit[55:48], value 1 means page 0 */ ++ spare_page = (args[1] >> 16) & 0xFF; ++ sprintf(value, "%04d.%02d.%02d.%02d", page_sz, ++ page_block, spare_offs, spare_page); ++ break; ++ ++ default: ++ sprintf(value, "NOT IMPLEMENTED"); ++ } ++ ++ return 0; ++} ++ ++/****************************************************************************** ++ * efuse_raw_dump ++ ******************************************************************************/ ++void efuse_raw_dump(void) ++{ ++ printf("Raw eFuse dump is not supported on this platform\n"); ++ return; ++} +diff --git a/arch/arm/mach-mvebu/armada3700/mbox.c b/arch/arm/mach-mvebu/armada3700/mbox.c +new file mode 100644 +index 0000000000..e7071e7d5a +--- /dev/null ++++ b/arch/arm/mach-mvebu/armada3700/mbox.c +@@ -0,0 +1,170 @@ ++/* ++ * Copyright (C) 2017 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++ ++enum a3700_boot_dev { ++ AUTO = 0, ++ SPINOR = 1, ++ EMMCNORM = 2, ++ EMMCALT = 3, ++ SATA = 4, ++ SPINAND = 5, ++ UART = 6, ++ INVALID = 7, ++ VECTOR_DIV = 8, ++ VECTOR_XTAL = 9, ++ ++ MAX_BOOT_DEVS ++}; ++ ++#define A3700_BOOT_DEV_NAMES {"AUTO", "SPINOR", "EMMCNORM", "EMMCALT", \ ++ "SATA", "SPINAND", "UART", "", "", ""} ++ ++struct a3700_efuse_info { ++ /* efuse ID */ ++ enum efuse_id id; ++ /* mailbox operation size bit/byte/word, etc. */ ++ enum mbox_opsize mbopsz; ++ /* efuse row or start row for multi-row values */ ++ uint32_t row; ++ /* number of write operations required for setting the field */ ++ uint32_t numops; ++ /* efuse bit offset within the row for bit size efuses */ ++ int32_t bitoffs[4]; ++}; ++ ++#define A3700_EFUSE_INFO { \ ++ { EFUSE_ID_BOOT_DEVICE, MB_OPSZ_BIT, 1, 4, { 48, 52, 56, 60 } }, \ ++ { EFUSE_ID_KAK_DIGEST, MB_OPSZ_256B, 8, 1, { 0, 0, 0, 0 } }, \ ++ { EFUSE_ID_CSK_INDEX, MB_OPSZ_DWORD, 3, 1, { 0, 0, 0, 0 } }, \ ++ { EFUSE_ID_AES_KEY, MB_OPSZ_256B, 26, 1, { 0, 0, 0, 0 } }, \ ++ { EFUSE_ID_ENCRYPTION_EN, MB_OPSZ_BIT, 0, 2, { 56, 60, 0, 0 } }, \ ++ { EFUSE_ID_JTAG_DIGECT, MB_OPSZ_256B, 16, 1, { 0, 0, 0, 0 } }, \ ++ { EFUSE_ID_SEC_JTAG_DIS, MB_OPSZ_BIT, 0, 1, { 24, 0, 0, 0 } }, \ ++ { EFUSE_ID_SEC_JTAG_PERM_DIS, MB_OPSZ_BIT, 0, 1, { 28, 0, 0, 0 } }, \ ++ { EFUSE_ID_AP_JTAG_DIS, MB_OPSZ_BIT, 0, 1, { 16, 0, 0, 0 } }, \ ++ { EFUSE_ID_AP_JTAG_PERM_DIS, MB_OPSZ_BIT, 0, 1, { 20, 0, 0, 0 } }, \ ++ { EFUSE_ID_SPI_NAND_CFG, MB_OPSZ_DWORD, 6, 1, { 0, 0, 0, 0 } }, \ ++ { EFUSE_ID_PIN, MB_OPSZ_DWORD, 4, 1, { 0, 0, 0, 0 } }, \ ++ { EFUSE_ID_TOKEN, MB_OPSZ_DWORD, 5, 1, { 0, 0, 0, 0 } }, \ ++ { EFUSE_ID_SPI_CS, MB_OPSZ_BIT, 1, 2, { 40, 44, 0, 0 } }, \ ++ { EFUSE_ID_EMMC_CLOCK, MB_OPSZ_BIT, 1, 2, { 32, 36, 0, 0 } }, \ ++ { EFUSE_ID_OPERATION_MODE, MB_OPSZ_BIT, 1, 2, { 0, 4, 0, 0 } }, \ ++ { EFUSE_ID_UART_DIS, MB_OPSZ_BIT, 0, 1, { 32, 0, 0, 0 } }, \ ++ { EFUSE_ID_UART_PERM_DIS, MB_OPSZ_BIT, 0, 1, { 36, 0, 0, 0 } }, \ ++ { EFUSE_ID_ESC_SEQ_DIS, MB_OPSZ_BIT, 1, 1, { 20, 0, 0, 0 } }, \ ++ { EFUSE_ID_GPIO_TOGGLE_DIS, MB_OPSZ_BIT, 1, 1, { 16, 0, 0, 0 } }, \ ++ { EFUSE_ID_LONG_KEY_EN, MB_OPSZ_BIT, 1, 1, { 12, 0, 0, 0 } } \ ++} ++ ++/***************************************************************************** ++ * mbox_send ++ *****************************************************************************/ ++int mbox_send(enum mbox_opsize opsz, enum mbox_op op, uint32_t row, ++ uint32_t offs, uint32_t *args) ++{ ++ uint32_t params[MBOX_MAX_ARGS]; ++ uint32_t n, params_to_send; ++ ++ if (args == 0) { ++ printf("%s: Invalid argument\n", __func__); ++ return 1; ++ } ++ ++ if (op != MB_OP_READ && op != MB_OP_WRITE) { ++ printf("%s: Invalid operation\n", __func__); ++ return 1; ++ } ++ ++ memset(params, 0, MBOX_MAX_ARGS * sizeof(uint32_t)); ++ ++ /* First parameter in the list describes eFuse row */ ++ params[0] = row; ++ ++ switch (opsz) { ++ case MB_OPSZ_BIT: ++ case MB_OPSZ_BYTE: ++ case MB_OPSZ_WORD: ++ params_to_send = 3; ++ params[1] = offs; ++ params[2] = args[0]; ++ break; ++ case MB_OPSZ_DWORD: ++ params_to_send = 3; ++ params[1] = args[0]; ++ params[2] = args[1]; ++ break; ++ case MB_OPSZ_256B: ++ params_to_send = 9; ++ memcpy(¶ms[1], args, 8 * sizeof(uint32_t)); ++ break; ++ default: ++ printf("%s: Invalid size\n", __func__); ++ return 1; ++ } ++ ++ ++ /* First, fill all command arguments */ ++ for (n = 0; n < params_to_send; n++) { ++ debug("=>MBOX WRITE PARAM[%d] = %08X\n", n, params[n]); ++ writel(params[n], (long)MBOX_SEND_ARG_OFFS(n)); ++ } ++ ++ /* Writing command triggers mailbox dispatch and ++ intarrupt on secure CPU side */ ++ debug("=>MBOX WRITE CMD = %08X\n", MBOX_COMMAND(opsz, op)); ++ writel(MBOX_COMMAND(opsz, op), MBOX_SEND_CMD_OFFS); ++ ++ return 0; ++} ++ ++/***************************************************************************** ++ * mbox_receive - BLOCKING ++ *****************************************************************************/ ++int mbox_receive(enum mbox_status *stat, uint32_t *args, ++ uint32_t timeout_us) ++{ ++ uint32_t n; ++ uint32_t regval; ++ ++ if (args == 0) { ++ *stat = MB_STAT_BAD_ARGUMENT; ++ return 1; ++ } ++ ++ /* Poll for secure CPU command completion */ ++ for (n = 0; n < timeout_us; n++) { ++ regval = readl(MBOX_SEC_CPU_INT_STAT_REG); ++ if (regval & MBOX_SEC_CPU_CMD_SET) ++ break; ++ mdelay(100); ++ } ++ ++ if (n == timeout_us) { ++ printf("%s: MB timeout\n", __func__); ++ return 1; ++ } ++ ++ /* Read comamnd status and arguments */ ++ for (n = 0; n < MBOX_MAX_ARGS; n++) { ++ args[n] = readl((long)MBOX_RECEIVE_ARG_OFFS(n)); ++ debug("<=MBOX READ ARG[%d] = %08X\n", n, args[n]); ++ } ++ ++ *stat = readl(MBOX_RECEIVE_STAT_OFFS); ++ debug("<=MBOX READ STATUS = %08X\n", *stat); ++ ++ /* Reset host interrupt */ ++ regval = readl(MBOX_HOST_INT_RESET) | MBOX_SEC_CPU_CMD_COMPLETE; ++ writel(regval, MBOX_HOST_INT_RESET); ++ ++ return 0; ++} +diff --git a/arch/arm/mach-mvebu/armada8k/Makefile b/arch/arm/mach-mvebu/armada8k/Makefile +index 82cb25b417..4391a0199c 100644 +--- a/arch/arm/mach-mvebu/armada8k/Makefile ++++ b/arch/arm/mach-mvebu/armada8k/Makefile +@@ -3,4 +3,6 @@ + # Copyright (C) 2016 Stefan Roese + + obj-y = cpu.o ++obj-y += soc.o ++obj-y += clock.o + obj-y += cache_llc.o +diff --git a/arch/arm/mach-mvebu/armada8k/clock.c b/arch/arm/mach-mvebu/armada8k/clock.c +new file mode 100644 +index 0000000000..3b02bea127 +--- /dev/null ++++ b/arch/arm/mach-mvebu/armada8k/clock.c +@@ -0,0 +1,53 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++ ++#ifndef CONFIG_PALLADIUM ++#define CONFIG_MSS_FREQUENCY (200 * 1000000) ++#else ++#define CONFIG_MSS_FREQUENCY (384000) ++#endif ++ ++u32 soc_ring_clk_get(void) ++{ ++ struct sar_val sar; ++ ++ mvebu_sar_value_get(SAR_AP_FABRIC_FREQ, &sar); ++ return sar.freq; ++} ++ ++u32 soc_mss_clk_get(void) ++{ ++ return CONFIG_MSS_FREQUENCY; ++} ++ ++u32 soc_cpu_clk_get(void) ++{ ++ struct sar_val sar; ++ ++ mvebu_sar_value_get(SAR_CPU_FREQ, &sar); ++ return sar.freq; ++} ++ ++u32 soc_ddr_clk_get(void) ++{ ++ struct sar_val sar; ++ ++ mvebu_sar_value_get(SAR_DDR_FREQ, &sar); ++ return sar.freq; ++} ++ ++void soc_print_clock_info(void) ++{ ++ printf("Clock: CPU %-4d [MHz]\n", soc_cpu_clk_get() / MHz); ++ printf("\tDDR %-4d [MHz]\n", soc_ddr_clk_get() / MHz); ++ printf("\tFABRIC %-4d [MHz]\n", soc_ring_clk_get() / MHz); ++ printf("\tMSS %-4d [MHz]\n", soc_mss_clk_get() / MHz); ++} +diff --git a/arch/arm/mach-mvebu/armada8k/cpu.c b/arch/arm/mach-mvebu/armada8k/cpu.c +index 959a7cff76..fe216c2c4a 100644 +--- a/arch/arm/mach-mvebu/armada8k/cpu.c ++++ b/arch/arm/mach-mvebu/armada8k/cpu.c +@@ -7,11 +7,15 @@ + #include + #include + #include ++#include + #include + #include + #include + #include + #include ++#include ++#include ++#include + + /* Armada 7k/8k */ + #define MVEBU_RFU_BASE (MVEBU_REGISTER(0x6f0000)) +@@ -22,65 +26,45 @@ + #define BOOT_MODE_MASK 0x3f + #define BOOT_MODE_OFFSET 4 + +-/* +- * The following table includes all memory regions for Armada 7k and +- * 8k SoCs. The Armada 7k is missing the CP110 slave regions here. Lets +- * define these regions at the beginning of the struct so that they +- * can be easier removed later dynamically if an Armada 7k device is detected. +- * For a detailed memory map, please see doc/mvebu/armada-8k-memory.txt +- */ +-#define ARMADA_7K8K_COMMON_REGIONS_START 2 + static struct mm_region mvebu_mem_map[] = { + /* Armada 80x0 memory regions include the CP1 (slave) units */ + { +- /* SRAM, MMIO regions - CP110 slave region */ +- .phys = 0xf4000000UL, +- .virt = 0xf4000000UL, +- .size = 0x02000000UL, /* 32MiB internal registers */ +- .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | +- PTE_BLOCK_NON_SHARE +- }, +- { +- /* PCI CP1 regions */ +- .phys = 0xfa000000UL, +- .virt = 0xfa000000UL, +- .size = 0x04000000UL, /* 64MiB CP110 slave PCI space */ +- .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | +- PTE_BLOCK_NON_SHARE +- }, +- /* Armada 80x0 and 70x0 common memory regions start here */ +- { +- /* RAM */ ++ /* RAM 0-64MB */ + .phys = 0x0UL, + .virt = 0x0UL, +- .size = 0x80000000UL, ++ .size = ATF_REGION_START, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_INNER_SHARE + }, ++ /* ATF and TEE region 0x4000000-0x5400000 not mapped */ + { +- /* SRAM, MMIO regions - AP806 region */ +- .phys = 0xf0000000UL, +- .virt = 0xf0000000UL, +- .size = 0x01000000UL, /* 16MiB internal registers */ +- .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | +- PTE_BLOCK_NON_SHARE ++ /* RAM 66MB-2GB */ ++ .phys = ATF_REGION_END, ++ .virt = ATF_REGION_END, ++ .size = SZ_2G, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | ++ PTE_BLOCK_INNER_SHARE + }, + { +- /* SRAM, MMIO regions - CP110 master region */ +- .phys = 0xf2000000UL, +- .virt = 0xf2000000UL, +- .size = 0x02000000UL, /* 32MiB internal registers */ ++ /* MMIO regions */ ++ .phys = MMIO_REGS_PHY_BASE, ++ .virt = MMIO_REGS_PHY_BASE, ++ .size = SZ_1G, ++ + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE + }, ++#if defined(CONFIG_PCIE_DW_MVEBU_EP) + { +- /* PCI CP0 regions */ +- .phys = 0xf6000000UL, +- .virt = 0xf6000000UL, +- .size = 0x04000000UL, /* 64MiB CP110 master PCI space */ ++ /* PCIe OCP regions */ ++ .phys = MV_PCIE_EP_REGION_BASE, ++ .virt = MV_PCIE_EP_REGION_BASE, ++ .size = MV_PCIE_EP_REGION_SIZE, ++ + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE + }, ++#endif + { + 0, + } +@@ -90,15 +74,6 @@ struct mm_region *mem_map = mvebu_mem_map; + + void enable_caches(void) + { +- /* +- * Armada 7k is not equipped with the CP110 slave CP. In case this +- * code runs on an Armada 7k device, lets remove the CP110 slave +- * entries from the memory mapping by moving the start to the +- * common regions. +- */ +- if (of_machine_is_compatible("marvell,armada7040")) +- mem_map = &mvebu_mem_map[ARMADA_7K8K_COMMON_REGIONS_START]; +- + icache_enable(); + dcache_enable(); + } +@@ -112,24 +87,6 @@ void reset_cpu(ulong ignored) + writel(reg, RFU_GLOBAL_SW_RST); + } + +-/* +- * TODO - implement this functionality using platform +- * clock driver once it gets available +- * Return NAND clock in Hz +- */ +-u32 mvebu_get_nand_clock(void) +-{ +- unsigned long NAND_FLASH_CLK_CTRL = 0xF2440700UL; +- unsigned long NF_CLOCK_SEL_MASK = 0x1; +- u32 reg; +- +- reg = readl(NAND_FLASH_CLK_CTRL); +- if (reg & NF_CLOCK_SEL_MASK) +- return 400 * 1000000; +- else +- return 250 * 1000000; +-} +- + int mmc_get_env_dev(void) + { + u32 reg; +@@ -149,3 +106,13 @@ int mmc_get_env_dev(void) + + return CONFIG_SYS_MMC_ENV_DEV; + } ++ ++#if defined(CONFIG_DISPLAY_BOARDINFO) ++int print_cpuinfo(void) ++{ ++ soc_print_device_info(); ++ soc_print_clock_info(); ++ soc_print_system_cache_info(); ++ return 0; ++} ++#endif +diff --git a/arch/arm/mach-mvebu/armada8k/soc.c b/arch/arm/mach-mvebu/armada8k/soc.c +new file mode 100644 +index 0000000000..6ace53a9dd +--- /dev/null ++++ b/arch/arm/mach-mvebu/armada8k/soc.c +@@ -0,0 +1,347 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define CP_DEV_ID_STATUS_REG (MVEBU_REGISTER(0x2400240)) ++#define DEVICE_ID_STATUS_MASK 0xffff ++#define AP_DEV_ID_STATUS_REG (SOC_REGS_PHY_BASE + 0x6F8240) ++#define JTAG_DEV_ID_STATUS_REG (SOC_REGS_PHY_BASE + 0x6F8244) ++#define AP_DEV_ID_STATUS_MASK 0xfff ++#define AP_DEV_REV_ID_STATUS_MASK 0xf0000000 ++#define SW_REV_STATUS_OFFSET 16 ++#define AP_REV_STATUS_OFFSET 28 ++#define SW_REV_STATUS_MASK 0xf ++ ++#define A8040_DEVICE_ID 0x8040 ++#define CN9130_DEVICE_ID 0x7025 ++ ++#define AP807_ID 0x807 ++ ++/* to differentiate differnet SOC with similar DEVICE_ID */ ++#define AP807_SHARED_DEVICE_ID_A0 0x7045 ++#define AP807_SHARED_DEVICE_ID_A1 0x6025 ++ ++#define DEVICE_ID_SUB_REV (MVEBU_REGISTER(0x2400230)) ++#define DEVICE_ID_SUB_REV_OFFSET 7 ++#define DEVICE_ID_SUB_REV_MASK (0xffff << DEVICE_ID_SUB_REV_OFFSET) ++ ++#define NF_CLOCK_SEL_MASK 0x1 ++#define SOC_MUX_NAND_EN_MASK 0x1 ++#define CLOCK_1Mhz 1000000 ++ ++struct mochi_module { ++ u32 module_type; ++ u32 module_rev; ++}; ++ ++struct soc_info { ++ struct mochi_module soc; ++ char *soc_name; ++ struct mochi_module ap; ++ struct mochi_module cp; ++ u32 ap_num; ++ u32 cp_num; ++ u32 sub_rev; ++}; ++ ++static struct soc_info soc_info_table[] = { ++ { {0x7025, 0}, "cn9130-A1", {0x807, 2}, {0x115, 0}, 1, 1, 0}, ++ { {0x7025, 0}, "cn9131-A1", {0x807, 2}, {0x115, 0}, 1, 2, 0}, ++ { {0x7025, 0}, "cn9132-A1", {0x807, 2}, {0x115, 0}, 1, 3, 0}, ++ { {0x6025, 0}, "Armada3900-A1", {0x807, 1}, {0x115, 0}, 1, 1, 0}, ++ { {0x6025, 0}, "Armada3900-A3", {0x807, 2}, {0x115, 0}, 1, 1, 0}, ++ { {0x7045, 0}, "Armada3900-A0", {0x807, 0}, {0x115, 0}, 1, 1, 0}, ++ { {0x7040, 1}, "Armada7040-A1", {0x806, 1}, {0x110, 1}, 1, 1, 0}, ++ { {0x7040, 2}, "Armada7040-A2", {0x806, 1}, {0x110, 2}, 1, 1, 0}, ++ { {0x7045, 0}, "Armada7040-B0", {0x806, 2}, {0x115, 0}, 1, 1, 0}, ++ { {0x8040, 1}, "Armada8040-A1", {0x806, 1}, {0x110, 1}, 1, 2, 0}, ++ { {0x8040, 2}, "Armada8040-A2", {0x806, 1}, {0x110, 2}, 1, 2, 0}, ++ { {0x8045, 0}, "Armada8040-B0", {0x806, 2}, {0x115, 0}, 1, 2, 0}, ++}; ++ ++int mvebu_dfx_smc(u32 subfid, u32 *reg, u32 addr, u32 val) ++{ ++ struct pt_regs pregs = {0}; ++ ++ pregs.regs[0] = MV_SIP_DFX; ++ pregs.regs[1] = subfid; ++ pregs.regs[2] = addr; ++ pregs.regs[3] = val; ++ ++ smc_call(&pregs); ++ ++ if (pregs.regs[0] == 0 && reg) ++ *reg = pregs.regs[1]; ++ ++ debug("%s: sub-fid %d, reg_val 0x%x, addr 0x%x, val 0x%x, ret %ld\n", ++ __func__, subfid, reg ? *reg : -1, addr, val, pregs.regs[0]); ++ ++ return pregs.regs[0]; ++} ++ ++static int get_soc_type_rev(u32 *type, u32 *rev) ++{ ++ *type = readl(CP_DEV_ID_STATUS_REG) & DEVICE_ID_STATUS_MASK; ++ *rev = (readl(CP_DEV_ID_STATUS_REG) >> SW_REV_STATUS_OFFSET) & ++ SW_REV_STATUS_MASK; ++ ++ return 0; ++} ++ ++static int get_ap_soc_type(u32 *type) ++{ ++ int ret; ++ ++ /* Try read it with firmware use, if fails try legacy */ ++ ret = mvebu_dfx_sread(type, AP_DEV_ID_STATUS_REG); ++ if (ret != SMCCC_RET_SUCCESS) ++ *type = readl(AP_DEV_ID_STATUS_REG); ++ ++ *type &= AP_DEV_ID_STATUS_MASK; ++ ++ return 0; ++} ++ ++static int get_ap_soc_rev(u32 *rev) ++{ ++ int ret; ++ ++ /* Try read it with firmware use, if fails try legacy */ ++ ret = mvebu_dfx_sread(rev, JTAG_DEV_ID_STATUS_REG); ++ if (ret != SMCCC_RET_SUCCESS) ++ *rev = readl(JTAG_DEV_ID_STATUS_REG); ++ ++ *rev = (*rev & AP_DEV_REV_ID_STATUS_MASK) >> AP_REV_STATUS_OFFSET; ++ return 0; ++} ++ ++static int get_soc_sub_rev(u32 *sub_rev) ++{ ++ u32 soc_type, rev, ap_type; ++ ++ get_soc_type_rev(&soc_type, &rev); ++ get_ap_soc_type(&ap_type); ++ ++ if (ap_type == AP807_ID) { ++ *sub_rev = readl(DEVICE_ID_SUB_REV) & DEVICE_ID_SUB_REV_MASK; ++ *sub_rev >>= DEVICE_ID_SUB_REV_OFFSET; ++ return 0; ++ } ++ ++ *sub_rev = 0; ++ ++ return -1; ++} ++ ++static int get_soc_table_index(u32 *index) ++{ ++ u32 soc_type; ++ u32 rev, i, ret = 1; ++ u32 ap_type, sub_rev, ap_rev; ++ ++ *index = 0; ++ get_soc_type_rev(&soc_type, &rev); ++ get_ap_soc_type(&ap_type); ++ get_ap_soc_rev(&ap_rev); ++ ++ /* specific checks needed for 9131,9132, */ ++ /* since their soc+ap characteristics same as 9130*/ ++ if ((of_machine_is_compatible("marvell,cn9131-db"))) { ++ for (i = 0; i < ARRAY_SIZE(soc_info_table) && ret != 0; i++) { ++ if (strcmp(soc_info_table[i].soc_name, ++ "cn9131-A1") != 0) ++ continue; ++ *index = i; ++ ret = 0; ++ } ++ } else if ((of_machine_is_compatible("marvell,cn9132-db"))) { ++ for (i = 0; i < ARRAY_SIZE(soc_info_table) && ret != 0; i++) { ++ if (strcmp(soc_info_table[i].soc_name, ++ "cn9132-A1") != 0) ++ continue; ++ *index = i; ++ ret = 0; ++ } ++ } else { ++ for (i = 0; i < ARRAY_SIZE(soc_info_table) && ret != 0; i++) { ++ if ((soc_type != soc_info_table[i].soc.module_type) || ++ (rev != soc_info_table[i].soc.module_rev) || ++ ap_type != soc_info_table[i].ap.module_type || ++ (ap_rev != soc_info_table[i].ap.module_rev)) ++ continue; ++ ++ if (!get_soc_sub_rev(&sub_rev) && ++ (sub_rev != soc_info_table[i].sub_rev)) ++ continue; ++ ++ *index = i; ++ ret = 0; ++ } ++ } ++ ++ if (ret) ++ pr_err("using default SoC info: %s\n", ++ soc_info_table[*index].soc_name); ++ ++ return ret; ++} ++ ++static int get_soc_name(char **soc_name) ++{ ++ u32 index; ++ ++ get_soc_table_index(&index); ++ *soc_name = soc_info_table[index].soc_name; ++ ++ return 0; ++} ++ ++int soc_get_ap_cp_num(void *ap_num, void *cp_num) ++{ ++ u32 index; ++ ++ get_soc_table_index(&index); ++ *((u32 *)ap_num) = soc_info_table[index].ap_num; ++ *((u32 *)cp_num) = soc_info_table[index].cp_num; ++ ++ return 0; ++} ++ ++/* Get SoC's Application Processor (AP) module type and revision */ ++static int get_ap_type_rev(u32 *type, u32 *rev) ++{ ++ u32 index; ++ ++ get_soc_table_index(&index); ++ *type = soc_info_table[index].ap.module_type; ++ *rev = soc_info_table[index].ap.module_rev; ++ ++ return 0; ++} ++ ++/* Get SoC's Communication Processor (CP) module type and revision */ ++static int get_cp_type_rev(u32 *type, u32 *rev) ++{ ++ u32 index; ++ ++ get_soc_table_index(&index); ++ *type = soc_info_table[index].cp.module_type; ++ *rev = soc_info_table[index].cp.module_rev; ++ ++ return 0; ++} ++ ++/* Print device's SoC name and AP & CP information */ ++void soc_print_device_info(void) ++{ ++ u32 ap_num, cp_num, ap_type, ap_rev, cp_type, cp_rev; ++ char *soc_name = NULL; ++ ++ soc_get_ap_cp_num(&ap_num, &cp_num); ++ ++ get_soc_name(&soc_name); ++ get_ap_type_rev(&ap_type, &ap_rev); ++ get_cp_type_rev(&cp_type, &cp_rev); ++ ++ if (ap_rev > 1) ++ printf("SoC: %s; AP%x-B0; ", soc_name, ap_type); ++ else ++ printf("SoC: %s; AP%x-A%d; ", soc_name, ap_type, ap_rev); ++ ++ /* more than one cp module */ ++ if (cp_num > 1) ++ printf("%dxCP%x-A%d\n", cp_num, cp_type, cp_rev); ++ else ++ printf("CP%x-A%d\n", cp_type, cp_rev); ++} ++ ++/* Print System cache (LLC) status and mode */ ++void soc_print_system_cache_info(void) ++{ ++ u32 val; ++ int llc_en = 0, excl = 0; ++ ++ val = readl(MVEBU_LLC_BASE + LLC_CTRL_REG_OFFSET); ++ if (val & LLC_EN) { ++ llc_en = 1; ++ if (val & LLC_EXCL_EN) ++ excl = 1; ++ } ++ ++ printf("LLC %s%s\n", llc_en ? "Enabled" : "Disabled", ++ excl ? " (Exclusive Mode)" : ""); ++} ++ ++#ifdef CONFIG_NAND_PXA3XX ++/* Return NAND clock in Hz */ ++u32 mvebu_get_nand_clock(void __iomem *nand_flash_clk_ctrl_reg) ++{ ++ u32 reg; ++ ++ if (!nand_flash_clk_ctrl_reg) ++ return 0; ++ ++ reg = readl(nand_flash_clk_ctrl_reg); ++ if (reg & NF_CLOCK_SEL_MASK) ++ return 400 * CLOCK_1Mhz; ++ else ++ return 250 * CLOCK_1Mhz; ++} ++ ++/* Select NAND in the device bus multiplexer */ ++void mvebu_nand_select(void __iomem *soc_dev_multiplex_reg) ++{ ++ if (!soc_dev_multiplex_reg) ++ return; ++ ++ setbits_le32(soc_dev_multiplex_reg, SOC_MUX_NAND_EN_MASK); ++} ++#endif ++ ++int soc_early_init_f(void) ++{ ++#ifdef CONFIG_MVEBU_SAR ++ /* Sample at reset register init */ ++ mvebu_sar_init(); ++#endif ++ ++ return 0; ++} ++ ++#ifdef CONFIG_ARCH_MISC_INIT ++int arch_misc_init(void) ++{ ++ u32 type, rev; ++ ++ get_soc_type_rev(&type, &rev); ++ ++ /* A8040 A1/A2 doesn't support linux kernel cpuidle feautre, ++ * so U-boot needs to update Linux bootargs according ++ * to the device id: ++ * ++ * Device Device_ID ++ * ------------------------------- ++ * A8040 A1 0x18040 ++ * A8040 A2 0x28040 ++ * A8040 B0 0x08045 ++ * ++ * So we need to check if 16 LSB bits are 0x8040. ++ * The variable 'type', which is returned by ++ * get_soc_type_rev() holds these bits. ++ */ ++ if (type == A8040_DEVICE_ID) ++ env_set("cpuidle", "cpuidle.off=1"); ++ ++ return 0; ++} ++#endif +diff --git a/arch/arm/mach-mvebu/cpu.c b/arch/arm/mach-mvebu/cpu.c +index f4b7a4fa80..c14eae58c0 100644 +--- a/arch/arm/mach-mvebu/cpu.c ++++ b/arch/arm/mach-mvebu/cpu.c +@@ -4,6 +4,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -12,9 +13,15 @@ + #include + #include + ++#if defined(CONFIG_MVEBU_EFUSE) ++#include ++#endif ++ + #define DDR_BASE_CS_OFF(n) (0x0000 + ((n) << 3)) + #define DDR_SIZE_CS_OFF(n) (0x0004 + ((n) << 3)) + ++#define SOC_MUX_NAND_EN_MASK 0x1 ++ + static struct mbus_win windows[] = { + /* SPI */ + { MBUS_SPI_BASE, MBUS_SPI_SIZE, +@@ -489,11 +496,22 @@ int arch_cpu_init(void) + /* Disable MBUS error propagation */ + clrsetbits_le32(SOC_COHERENCY_FABRIC_CTRL_REG, MBUS_ERR_PROP_EN, 0); + ++#if defined(CONFIG_MVEBU_EFUSE) ++ if (mvebu_soc_family() == MVEBU_SOC_A38X) { ++ struct fuse_ops a38x_ops; ++ ++ a38x_ops.fuse_init = mvebu_efuse_init_hw; ++ a38x_ops.fuse_hd_read = NULL; ++ a38x_ops.fuse_hd_prog = NULL; ++ reg_fuse_ops(&a38x_ops); ++ } ++#endif ++ + return 0; + } + #endif /* CONFIG_ARCH_CPU_INIT */ + +-u32 mvebu_get_nand_clock(void) ++u32 mvebu_get_nand_clock(void __iomem *unused) + { + u32 reg; + +@@ -509,6 +527,14 @@ u32 mvebu_get_nand_clock(void) + NAND_ECC_DIVCKL_RATIO_MASK) >> NAND_ECC_DIVCKL_RATIO_OFFS); + } + ++void mvebu_nand_select(void __iomem *soc_dev_multiplex_reg) ++{ ++ if (!soc_dev_multiplex_reg) ++ return; ++ ++ setbits_le32(soc_dev_multiplex_reg, SOC_MUX_NAND_EN_MASK); ++} ++ + /* + * SOC specific misc init + */ +@@ -682,3 +708,28 @@ void v7_outer_cache_disable(void) + + clrbits_le32(&pl310->pl310_ctrl, L2X0_CTRL_EN); + } ++ ++int arch_early_init_r(void) ++{ ++ struct udevice *dev; ++ int ret; ++ int i; ++ ++ /* Loop over all MISC uclass drivers */ ++ i = 0; ++ while (1) { ++ /* Call relevant driver code via the MISC uclass driver */ ++ ret = uclass_get_device(UCLASS_MISC, i++, &dev); ++ ++ /* We're done, once no further MISC device node is found */ ++ if (ret) ++ break; ++ } ++ ++#ifdef CONFIG_DM_PCI ++ /* Trigger PCIe devices detection */ ++ pci_init(); ++#endif ++ ++ return 0; ++} +diff --git a/arch/arm/mach-mvebu/efuse.c b/arch/arm/mach-mvebu/efuse.c +deleted file mode 100644 +index 16ccfec933..0000000000 +--- a/arch/arm/mach-mvebu/efuse.c ++++ /dev/null +@@ -1,263 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0+ +-/* +- * Copyright (C) 2015-2016 Reinhard Pfau +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#if defined(CONFIG_MVEBU_EFUSE_FAKE) +-#define DRY_RUN +-#else +-#undef DRY_RUN +-#endif +- +-#define MBUS_EFUSE_BASE 0xF6000000 +-#define MBUS_EFUSE_SIZE BIT(20) +- +-#define MVEBU_EFUSE_CONTROL (MVEBU_REGISTER(0xE4008)) +- +-enum { +- MVEBU_EFUSE_CTRL_PROGRAM_ENABLE = (1 << 31), +-}; +- +-struct mvebu_hd_efuse { +- u32 bits_31_0; +- u32 bits_63_32; +- u32 bit64; +- u32 reserved0; +-}; +- +-#ifndef DRY_RUN +-static struct mvebu_hd_efuse *efuses = +- (struct mvebu_hd_efuse *)(MBUS_EFUSE_BASE + 0xF9000); +-#else +-static struct mvebu_hd_efuse efuses[EFUSE_LINE_MAX + 1]; +-#endif +- +-static int efuse_initialised; +- +-static struct mvebu_hd_efuse *get_efuse_line(int nr) +-{ +- if (nr < 0 || nr > 63 || !efuse_initialised) +- return NULL; +- +- return efuses + nr; +-} +- +-static void enable_efuse_program(void) +-{ +-#ifndef DRY_RUN +- setbits_le32(MVEBU_EFUSE_CONTROL, MVEBU_EFUSE_CTRL_PROGRAM_ENABLE); +-#endif +-} +- +-static void disable_efuse_program(void) +-{ +-#ifndef DRY_RUN +- clrbits_le32(MVEBU_EFUSE_CONTROL, MVEBU_EFUSE_CTRL_PROGRAM_ENABLE); +-#endif +-} +- +-static int do_prog_efuse(struct mvebu_hd_efuse *efuse, +- struct efuse_val *new_val, u32 mask0, u32 mask1) +-{ +- struct efuse_val val; +- +- val.dwords.d[0] = readl(&efuse->bits_31_0); +- val.dwords.d[1] = readl(&efuse->bits_63_32); +- val.lock = readl(&efuse->bit64); +- +- if (val.lock & 1) +- return -EPERM; +- +- val.dwords.d[0] |= (new_val->dwords.d[0] & mask0); +- val.dwords.d[1] |= (new_val->dwords.d[1] & mask1); +- val.lock |= new_val->lock; +- +- writel(val.dwords.d[0], &efuse->bits_31_0); +- mdelay(1); +- writel(val.dwords.d[1], &efuse->bits_63_32); +- mdelay(1); +- writel(val.lock, &efuse->bit64); +- mdelay(5); +- +- return 0; +-} +- +-static int prog_efuse(int nr, struct efuse_val *new_val, u32 mask0, u32 mask1) +-{ +- struct mvebu_hd_efuse *efuse; +- int res = 0; +- +- res = mvebu_efuse_init_hw(); +- if (res) +- return res; +- +- efuse = get_efuse_line(nr); +- if (!efuse) +- return -ENODEV; +- +- if (!new_val) +- return -EINVAL; +- +- /* only write a fuse line with lock bit */ +- if (!new_val->lock) +- return -EINVAL; +- +- /* according to specs ECC protection bits must be 0 on write */ +- if (new_val->bytes.d[7] & 0xFE) +- return -EINVAL; +- +- if (!new_val->dwords.d[0] && !new_val->dwords.d[1] && (mask0 | mask1)) +- return 0; +- +- enable_efuse_program(); +- +- res = do_prog_efuse(efuse, new_val, mask0, mask1); +- +- disable_efuse_program(); +- +- return res; +-} +- +-int mvebu_efuse_init_hw(void) +-{ +- int ret; +- +- if (efuse_initialised) +- return 0; +- +- ret = mvebu_mbus_add_window_by_id( +- CPU_TARGET_SATA23_DFX, 0xA, MBUS_EFUSE_BASE, MBUS_EFUSE_SIZE); +- +- if (ret) +- return ret; +- +- efuse_initialised = 1; +- +- return 0; +-} +- +-int mvebu_read_efuse(int nr, struct efuse_val *val) +-{ +- struct mvebu_hd_efuse *efuse; +- int res; +- +- res = mvebu_efuse_init_hw(); +- if (res) +- return res; +- +- efuse = get_efuse_line(nr); +- if (!efuse) +- return -ENODEV; +- +- if (!val) +- return -EINVAL; +- +- val->dwords.d[0] = readl(&efuse->bits_31_0); +- val->dwords.d[1] = readl(&efuse->bits_63_32); +- val->lock = readl(&efuse->bit64); +- return 0; +-} +- +-int mvebu_write_efuse(int nr, struct efuse_val *val) +-{ +- return prog_efuse(nr, val, ~0, ~0); +-} +- +-int mvebu_lock_efuse(int nr) +-{ +- struct efuse_val val = { +- .lock = 1, +- }; +- +- return prog_efuse(nr, &val, 0, 0); +-} +- +-/* +- * wrapper funcs providing the fuse API +- * +- * we use the following mapping: +- * "bank" -> eFuse line +- * "word" -> 0: bits 0-31 +- * 1: bits 32-63 +- * 2: bit 64 (lock) +- */ +- +-static struct efuse_val prog_val; +-static int valid_prog_words; +- +-int fuse_read(u32 bank, u32 word, u32 *val) +-{ +- struct efuse_val fuse_line; +- int res; +- +- if (bank < EFUSE_LINE_MIN || bank > EFUSE_LINE_MAX || word > 2) +- return -EINVAL; +- +- res = mvebu_read_efuse(bank, &fuse_line); +- if (res) +- return res; +- +- if (word < 2) +- *val = fuse_line.dwords.d[word]; +- else +- *val = fuse_line.lock; +- +- return res; +-} +- +-int fuse_sense(u32 bank, u32 word, u32 *val) +-{ +- /* not supported */ +- return -ENOSYS; +-} +- +-int fuse_prog(u32 bank, u32 word, u32 val) +-{ +- int res = 0; +- +- /* +- * NOTE: Fuse line should be written as whole. +- * So how can we do that with this API? +- * For now: remember values for word == 0 and word == 1 and write the +- * whole line when word == 2. +- * This implies that we always require all 3 fuse prog cmds (one for +- * for each word) to write a single fuse line. +- * Exception is a single write to word 2 which will lock the fuse line. +- * +- * Hope that will be OK. +- */ +- +- if (bank < EFUSE_LINE_MIN || bank > EFUSE_LINE_MAX || word > 2) +- return -EINVAL; +- +- if (word < 2) { +- prog_val.dwords.d[word] = val; +- valid_prog_words |= (1 << word); +- } else if ((valid_prog_words & 3) == 0 && val) { +- res = mvebu_lock_efuse(bank); +- valid_prog_words = 0; +- } else if ((valid_prog_words & 3) != 3 || !val) { +- res = -EINVAL; +- } else { +- prog_val.lock = val != 0; +- res = mvebu_write_efuse(bank, &prog_val); +- valid_prog_words = 0; +- } +- +- return res; +-} +- +-int fuse_override(u32 bank, u32 word, u32 val) +-{ +- /* not supported */ +- return -ENOSYS; +-} +diff --git a/arch/arm/mach-mvebu/include/mach/clock.h b/arch/arm/mach-mvebu/include/mach/clock.h +new file mode 100644 +index 0000000000..9cfd757e55 +--- /dev/null ++++ b/arch/arm/mach-mvebu/include/mach/clock.h +@@ -0,0 +1,23 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ * https://spdx.org/licenses ++ */ ++ ++#ifndef _MVEBU_CLOCK_H_ ++#define _MVEBU_CLOCK_H_ ++ ++#define KHz 1000 ++#define MHz 1000000 ++#define GHz 1000000000 ++ ++u32 soc_cpu_clk_get(void); ++u32 soc_ddr_clk_get(void); ++u32 soc_tclk_get(void); ++u32 soc_l2_clk_get(void); ++u32 soc_timer_clk_get(void); ++ ++void soc_print_clock_info(void); ++ ++#endif /* _MVEBU_CLOCK_H_ */ +diff --git a/arch/arm/mach-mvebu/include/mach/cpu.h b/arch/arm/mach-mvebu/include/mach/cpu.h +index 2e2d72aac8..7723150188 100644 +--- a/arch/arm/mach-mvebu/include/mach/cpu.h ++++ b/arch/arm/mach-mvebu/include/mach/cpu.h +@@ -140,7 +140,8 @@ unsigned int mvebu_sdram_bs(enum memory_bank bank); + void mvebu_sdram_size_adjust(enum memory_bank bank); + int mvebu_mbus_probe(struct mbus_win windows[], int count); + int mvebu_soc_family(void); +-u32 mvebu_get_nand_clock(void); ++u32 mvebu_get_nand_clock(void __iomem *maybe_unused); ++void mvebu_nand_select(void __iomem *maybe_unused); + + void return_to_bootrom(void); + +diff --git a/arch/arm/mach-mvebu/include/mach/efuse.h b/arch/arm/mach-mvebu/include/mach/efuse.h +deleted file mode 100644 +index bbc5844d84..0000000000 +--- a/arch/arm/mach-mvebu/include/mach/efuse.h ++++ /dev/null +@@ -1,68 +0,0 @@ +-/* SPDX-License-Identifier: GPL-2.0+ */ +-/* +- * Copyright (C) 2015 Reinhard Pfau +- */ +- +-#ifndef _MVEBU_EFUSE_H +-#define _MVEBU_EFUSE_H +- +-#include +- +-struct efuse_val { +- union { +- struct { +- u8 d[8]; +- } bytes; +- struct { +- u16 d[4]; +- } words; +- struct { +- u32 d[2]; +- } dwords; +- }; +- u32 lock; +-}; +- +-#if defined(CONFIG_ARMADA_38X) +- +-enum efuse_line { +- EFUSE_LINE_SECURE_BOOT = 24, +- EFUSE_LINE_PUBKEY_DIGEST_0 = 26, +- EFUSE_LINE_PUBKEY_DIGEST_1 = 27, +- EFUSE_LINE_PUBKEY_DIGEST_2 = 28, +- EFUSE_LINE_PUBKEY_DIGEST_3 = 29, +- EFUSE_LINE_PUBKEY_DIGEST_4 = 30, +- EFUSE_LINE_CSK_0_VALID = 31, +- EFUSE_LINE_CSK_1_VALID = 32, +- EFUSE_LINE_CSK_2_VALID = 33, +- EFUSE_LINE_CSK_3_VALID = 34, +- EFUSE_LINE_CSK_4_VALID = 35, +- EFUSE_LINE_CSK_5_VALID = 36, +- EFUSE_LINE_CSK_6_VALID = 37, +- EFUSE_LINE_CSK_7_VALID = 38, +- EFUSE_LINE_CSK_8_VALID = 39, +- EFUSE_LINE_CSK_9_VALID = 40, +- EFUSE_LINE_CSK_10_VALID = 41, +- EFUSE_LINE_CSK_11_VALID = 42, +- EFUSE_LINE_CSK_12_VALID = 43, +- EFUSE_LINE_CSK_13_VALID = 44, +- EFUSE_LINE_CSK_14_VALID = 45, +- EFUSE_LINE_CSK_15_VALID = 46, +- EFUSE_LINE_FLASH_ID = 47, +- EFUSE_LINE_BOX_ID = 48, +- +- EFUSE_LINE_MIN = 0, +- EFUSE_LINE_MAX = 63, +-}; +- +-#endif +- +-int mvebu_efuse_init_hw(void); +- +-int mvebu_read_efuse(int nr, struct efuse_val *val); +- +-int mvebu_write_efuse(int nr, struct efuse_val *val); +- +-int mvebu_lock_efuse(int nr); +- +-#endif +diff --git a/arch/arm/mach-mvebu/include/mach/fw_info.h b/arch/arm/mach-mvebu/include/mach/fw_info.h +new file mode 100644 +index 0000000000..3ee35ec348 +--- /dev/null ++++ b/arch/arm/mach-mvebu/include/mach/fw_info.h +@@ -0,0 +1,23 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++#ifndef _FW_INFO_H_ ++#define _FW_INFO_H_ ++ ++/* Protected ATF and TEE region */ ++#define ATF_REGION_START 0x4000000 ++#define ATF_REGION_END 0x5400000 ++ ++/* PCIe EP mappings */ ++#define MV_PCIE_EP_REGION_BASE 0x8000000000ULL ++#define MV_PCIE_EP_REGION_SIZE 0x800000000ULL ++ ++/* Firmware related definition used for SMC calls */ ++#define MV_SIP_DRAM_SIZE 0x82000010 ++ ++#define MMIO_REGS_PHY_BASE 0xc0000000 ++ ++#endif /* _FW_INFO_H_ */ +diff --git a/arch/arm/mach-mvebu/include/mach/soc.h b/arch/arm/mach-mvebu/include/mach/soc.h +index acb9257c90..56ad6aa059 100644 +--- a/arch/arm/mach-mvebu/include/mach/soc.h ++++ b/arch/arm/mach-mvebu/include/mach/soc.h +@@ -36,7 +36,33 @@ + + /* SOC specific definations */ + #define INTREG_BASE 0xd0000000 ++ ++#if defined(CONFIG_ARMADA_8K_PLUS) ++/*=============== A8K+ =================*/ ++#define MVEBU_REGS_BASE_AP(ap) (0xe8000000ULL - (ap) * 0x04000000) ++#define MVEBU_REGS_BASE_CP(ap, cp) (0x8100000000ULL + \ ++ (ap) * 0x1d00000000ULL + \ ++ (cp) * 0x700000000ULL) ++#define MVEBU_CCU_MAX_WINS (5) ++#define MVEBU_IO_WIN_MAX_WINS (11) ++#define MVEBU_IO_WIN_GCR_OFFSET (0xF0) ++#define MVEBU_GWIN_MAX_WINS (16) ++#elif defined(CONFIG_ARMADA_8K) ++/*=============== A8K =================*/ ++#define MVEBU_REGS_BASE_AP(ap) (0xf0000000ULL) ++#define MVEBU_REGS_BASE_CP(ap, cp) (0xf2000000ULL + (cp) * 0x02000000) ++#define MVEBU_CCU_MAX_WINS (8) ++#define MVEBU_IO_WIN_MAX_WINS (7) ++#define MVEBU_IO_WIN_GCR_OFFSET (0x70) ++#endif ++ + #define INTREG_BASE_ADDR_REG (INTREG_BASE + 0x20080) ++ ++#if defined(CONFIG_ARMADA_8K) ++/*=============== A8K =================*/ ++#define MVEBU_REGS_BASE_AP(ap) (0xf0000000ULL) ++#endif ++ + #if defined(CONFIG_SPL_BUILD) || defined(CONFIG_ARMADA_3700) + /* + * The SPL U-Boot version still runs with the default +@@ -159,6 +185,7 @@ + #define BOOT_DEV_SEL_MASK (0x3f << BOOT_DEV_SEL_OFFS) + + #define BOOT_FROM_NAND 0x0A ++#define BOOT_FROM_NAND_ALT 0x0E + #define BOOT_FROM_SATA 0x22 + #define BOOT_FROM_UART 0x28 + #define BOOT_FROM_SATA_ALT 0x2A +@@ -203,4 +230,31 @@ + #define BOOT_FROM_SPI 0x3 + #endif + ++/* FW related definitions */ ++#define MV_SIP_DFX 0x82000014 ++#define MV_SIP_DDR_PHY_WRITE 0x82000015 ++#define MV_SIP_DDR_PHY_READ 0x82000016 ++ ++#define MV_SIP_DFX_THERMAL_INIT 1 ++#define MV_SIP_DFX_THERMAL_READ 2 ++#define MV_SIP_DFX_THERMAL_IS_VALID 3 ++ ++#define MV_SIP_DFX_SREAD 20 ++#define MV_SIP_DFX_SWRITE 21 ++ ++#ifndef __ASSEMBLY__ ++#include ++ ++int mvebu_dfx_smc(u32 subfid, u32 *reg, u32 addr, u32 val); ++void soc_print_device_info(void); ++int soc_get_ap_cp_num(void *ap_num, void *cp_num); ++void soc_print_system_cache_info(void); ++ ++#define mvebu_dfx_smc_thermal(subfid, preg) \ ++ mvebu_dfx_smc(subfid, preg, 0, 0) ++#define mvebu_dfx_sread(preg, addr) \ ++ mvebu_dfx_smc(MV_SIP_DFX_SREAD, preg, addr, 0) ++#define mvebu_dfx_swrite(addr, val) \ ++ mvebu_dfx_smc(MV_SIP_DFX_SWRITE, 0, addr, val) ++#endif /* __ASSEMBLY__ */ + #endif /* _MVEBU_SOC_H */ +diff --git a/arch/arm/mach-mvebu/spl.c b/arch/arm/mach-mvebu/spl.c +index 3cb27b7f4b..f4c8b419da 100644 +--- a/arch/arm/mach-mvebu/spl.c ++++ b/arch/arm/mach-mvebu/spl.c +@@ -47,6 +47,7 @@ static u32 get_boot_device(void) + switch (boot_device) { + #if defined(CONFIG_ARMADA_38X) + case BOOT_FROM_NAND: ++ case BOOT_FROM_NAND_ALT: + return BOOT_DEVICE_NAND; + #endif + #ifdef CONFIG_SPL_MMC_SUPPORT +diff --git a/arch/arm/mach-octeontx/Kconfig b/arch/arm/mach-octeontx/Kconfig +new file mode 100644 +index 0000000000..28ecf9821f +--- /dev/null ++++ b/arch/arm/mach-octeontx/Kconfig +@@ -0,0 +1,23 @@ ++if ARCH_OCTEONTX ++ ++choice ++ prompt "OcteonTX board select" ++ optional ++ ++config TARGET_OCTEONTX_81XX ++ bool "Marvell OcteonTX CN81XX" ++ ++config TARGET_OCTEONTX_83XX ++ bool "Marvell OcteonTX CN83XX" ++ ++endchoice ++ ++config SYS_SOC ++ string ++ default "octeontx" ++ ++config SYS_PCI_64BIT ++ bool ++ default y ++ ++endif +diff --git a/arch/arm/mach-octeontx/Makefile b/arch/arm/mach-octeontx/Makefile +new file mode 100644 +index 0000000000..8706becd0f +--- /dev/null ++++ b/arch/arm/mach-octeontx/Makefile +@@ -0,0 +1,8 @@ ++#/* SPDX-License-Identifier: GPL-2.0 ++# * ++# * Copyright (C) 2018 Marvell International Ltd. ++# * ++# * https://spdx.org/licenses ++# */ ++ ++obj-y += lowlevel_init.o clock.o cpu.o +diff --git a/arch/arm/mach-octeontx/clock.c b/arch/arm/mach-octeontx/clock.c +new file mode 100644 +index 0000000000..9da21077ec +--- /dev/null ++++ b/arch/arm/mach-octeontx/clock.c +@@ -0,0 +1,35 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++ ++/** ++ * Returns the I/O clock speed in Hz ++ */ ++u64 octeontx_get_io_clock(void) ++{ ++ union rst_boot rst_boot; ++ ++ rst_boot.u = readq(RST_BOOT); ++ ++ return rst_boot.s.pnr_mul * PLL_REF_CLK; ++} ++ ++/** ++ * Returns the core clock speed in Hz ++ */ ++u64 octeontx_get_core_clock(void) ++{ ++ union rst_boot rst_boot; ++ ++ rst_boot.u = readq(RST_BOOT); ++ ++ return rst_boot.s.c_mul * PLL_REF_CLK; ++} +diff --git a/arch/arm/mach-octeontx/cpu.c b/arch/arm/mach-octeontx/cpu.c +new file mode 100644 +index 0000000000..0f4f73286e +--- /dev/null ++++ b/arch/arm/mach-octeontx/cpu.c +@@ -0,0 +1,78 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++#define OTX_MEM_MAP_USED 3 ++ ++/* 1 for 83xx, +1 is end of list which needs to be empty */ ++#define OTX_MEM_MAP_MAX (OTX_MEM_MAP_USED + 1 + CONFIG_NR_DRAM_BANKS + 1) ++ ++static struct mm_region otx_mem_map[OTX_MEM_MAP_MAX] = { ++ { ++ .virt = 0x800000000000UL, ++ .phys = 0x800000000000UL, ++ .size = 0x40000000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | ++ PTE_BLOCK_NON_SHARE ++ }, { ++ .virt = 0x840000000000UL, ++ .phys = 0x840000000000UL, ++ .size = 0x40000000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | ++ PTE_BLOCK_NON_SHARE ++ }, { ++ .virt = 0x880000000000UL, ++ .phys = 0x880000000000UL, ++ .size = 0x40000000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | ++ PTE_BLOCK_NON_SHARE ++ } ++ ++}; ++ ++struct mm_region *mem_map = otx_mem_map; ++ ++void mem_map_fill(void) ++{ ++ int banks = OTX_MEM_MAP_USED; ++ u32 dram_start = CONFIG_SYS_TEXT_BASE; ++ ++ if (otx_is_soc(CN83XX)) { ++ /* Add 4K pci bootcmd buffer range */ ++ dram_start -= 0x1000; ++ otx_mem_map[banks].virt = 0x8c0000000000UL; ++ otx_mem_map[banks].phys = 0x8c0000000000UL; ++ otx_mem_map[banks].size = 0x40000000000UL; ++ otx_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | ++ PTE_BLOCK_NON_SHARE; ++ banks = banks + 1; ++ } ++ ++ for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { ++ otx_mem_map[banks].virt = dram_start; ++ otx_mem_map[banks].phys = dram_start; ++ otx_mem_map[banks].size = gd->ram_size; ++ otx_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | ++ PTE_BLOCK_NON_SHARE; ++ banks = banks + 1; ++ } ++} ++ ++u64 get_page_table_size(void) ++{ ++ return 0x80000; ++} ++ ++void reset_cpu(ulong addr) ++{ ++} +diff --git a/arch/arm/mach-octeontx/lowlevel_init.S b/arch/arm/mach-octeontx/lowlevel_init.S +new file mode 100644 +index 0000000000..41a9f08aed +--- /dev/null ++++ b/arch/arm/mach-octeontx/lowlevel_init.S +@@ -0,0 +1,33 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++ ++.align 8 ++.global fdt_base_addr ++fdt_base_addr: ++ .dword 0x0 ++ ++.global save_boot_params ++save_boot_params: ++ /* Read FDT base from x1 register passed by ATF */ ++ adr x21, fdt_base_addr ++ str x1, [x21] ++ ++ /* Returns */ ++ b save_boot_params_ret ++ ++ENTRY(lowlevel_init) ++ mov x29, lr /* Save LR */ ++ ++ /* any lowlevel init should go here */ ++ ++ mov lr, x29 /* Restore LR */ ++ ret ++ENDPROC(lowlevel_init) +diff --git a/arch/arm/mach-octeontx2/Kconfig b/arch/arm/mach-octeontx2/Kconfig +new file mode 100644 +index 0000000000..951dec72f6 +--- /dev/null ++++ b/arch/arm/mach-octeontx2/Kconfig +@@ -0,0 +1,32 @@ ++if ARCH_OCTEONTX2 ++ ++choice ++ prompt "OcteonTX2 board select" ++ optional ++ ++config TARGET_OCTEONTX2_95XX ++ bool "Marvell OcteonTX2 CN95XX" ++ ++config TARGET_OCTEONTX2_96XX ++ bool "Marvell OcteonTX2 CN96XX" ++ ++config TARGET_OCTEONTX2_LOKI ++ bool "Marvell OcteonTX2 LOKI" ++ ++config TARGET_OCTEONTX2_98XX ++ bool "Marvell OcteonTX2 CN98XX" ++ ++config TARGET_OCTEONTX2_95MM ++ bool "Marvell OcteonTX2 CN95MM" ++ ++endchoice ++ ++config SYS_SOC ++ string ++ default "octeontx2" ++ ++config SYS_PCI_64BIT ++ bool ++ default y ++ ++endif +diff --git a/arch/arm/mach-octeontx2/Makefile b/arch/arm/mach-octeontx2/Makefile +new file mode 100644 +index 0000000000..b3073a84b1 +--- /dev/null ++++ b/arch/arm/mach-octeontx2/Makefile +@@ -0,0 +1,8 @@ ++#/* ++# * Copyright (C) 2018 Marvell International Ltd. ++# * ++# * SPDX-License-Identifier: GPL-2.0 ++# * https://spdx.org/licenses ++# */ ++ ++obj-y += lowlevel_init.o clock.o cpu.o +diff --git a/arch/arm/mach-octeontx2/clock.c b/arch/arm/mach-octeontx2/clock.c +new file mode 100644 +index 0000000000..9da21077ec +--- /dev/null ++++ b/arch/arm/mach-octeontx2/clock.c +@@ -0,0 +1,35 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++ ++/** ++ * Returns the I/O clock speed in Hz ++ */ ++u64 octeontx_get_io_clock(void) ++{ ++ union rst_boot rst_boot; ++ ++ rst_boot.u = readq(RST_BOOT); ++ ++ return rst_boot.s.pnr_mul * PLL_REF_CLK; ++} ++ ++/** ++ * Returns the core clock speed in Hz ++ */ ++u64 octeontx_get_core_clock(void) ++{ ++ union rst_boot rst_boot; ++ ++ rst_boot.u = readq(RST_BOOT); ++ ++ return rst_boot.s.c_mul * PLL_REF_CLK; ++} +diff --git a/arch/arm/mach-octeontx2/config.mk b/arch/arm/mach-octeontx2/config.mk +new file mode 100644 +index 0000000000..9214f6b742 +--- /dev/null ++++ b/arch/arm/mach-octeontx2/config.mk +@@ -0,0 +1,4 @@ ++ifeq ($(CONFIG_ARCH_OCTEONTX2),y) ++PLATFORM_CPPFLAGS += $(call cc-option,-march=armv8.2-a,) ++PLATFORM_CPPFLAGS += $(call cc-option,-mtune=octeontx2,) ++endif +diff --git a/arch/arm/mach-octeontx2/cpu.c b/arch/arm/mach-octeontx2/cpu.c +new file mode 100644 +index 0000000000..a8039d6a35 +--- /dev/null ++++ b/arch/arm/mach-octeontx2/cpu.c +@@ -0,0 +1,75 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++#define OTX2_MEM_MAP_USED 4 ++ ++/* +1 is end of list which needs to be empty */ ++#define OTX2_MEM_MAP_MAX (OTX2_MEM_MAP_USED + CONFIG_NR_DRAM_BANKS + 1) ++ ++static struct mm_region otx2_mem_map[OTX2_MEM_MAP_MAX] = { ++ { ++ .virt = 0x800000000000UL, ++ .phys = 0x800000000000UL, ++ .size = 0x40000000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | ++ PTE_BLOCK_NON_SHARE ++ }, { ++ .virt = 0x840000000000UL, ++ .phys = 0x840000000000UL, ++ .size = 0x40000000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | ++ PTE_BLOCK_NON_SHARE ++ }, { ++ .virt = 0x880000000000UL, ++ .phys = 0x880000000000UL, ++ .size = 0x40000000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | ++ PTE_BLOCK_NON_SHARE ++ }, { ++ .virt = 0x8c0000000000UL, ++ .phys = 0x8c0000000000UL, ++ .size = 0x40000000000UL, ++ .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | ++ PTE_BLOCK_NON_SHARE ++ } ++}; ++ ++struct mm_region *mem_map = otx2_mem_map; ++ ++void mem_map_fill(void) ++{ ++ int banks = OTX2_MEM_MAP_USED; ++ u32 dram_start = CONFIG_SYS_TEXT_BASE; ++ ++ /* Add 4K pci bootcmd buffer range for 96xx boards */ ++ if (otx_is_soc(CN96XX)) ++ dram_start -= 0x1000; ++ for (int i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { ++ otx2_mem_map[banks].virt = dram_start; ++ otx2_mem_map[banks].phys = dram_start; ++ otx2_mem_map[banks].size = gd->ram_size; ++ otx2_mem_map[banks].attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | ++ PTE_BLOCK_NON_SHARE; ++ banks = banks + 1; ++ } ++} ++ ++u64 get_page_table_size(void) ++{ ++ return 0x80000; ++} ++ ++void reset_cpu(ulong addr) ++{ ++} +diff --git a/arch/arm/mach-octeontx2/lowlevel_init.S b/arch/arm/mach-octeontx2/lowlevel_init.S +new file mode 100644 +index 0000000000..41a9f08aed +--- /dev/null ++++ b/arch/arm/mach-octeontx2/lowlevel_init.S +@@ -0,0 +1,33 @@ ++/* SPDX-License-Identifier: GPL-2.0 ++ * ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++ ++.align 8 ++.global fdt_base_addr ++fdt_base_addr: ++ .dword 0x0 ++ ++.global save_boot_params ++save_boot_params: ++ /* Read FDT base from x1 register passed by ATF */ ++ adr x21, fdt_base_addr ++ str x1, [x21] ++ ++ /* Returns */ ++ b save_boot_params_ret ++ ++ENTRY(lowlevel_init) ++ mov x29, lr /* Save LR */ ++ ++ /* any lowlevel init should go here */ ++ ++ mov lr, x29 /* Restore LR */ ++ ret ++ENDPROC(lowlevel_init) +diff --git a/board/Marvell/common/Kconfig b/board/Marvell/common/Kconfig +new file mode 100644 +index 0000000000..ec9d115ecc +--- /dev/null ++++ b/board/Marvell/common/Kconfig +@@ -0,0 +1,22 @@ ++menu "MVEBU Development Board Utilities" ++ depends on ARCH_MVEBU ++ ++config BOARD_CONFIG_EEPROM ++ bool "Support configuration EEPROM" ++ default n ++ help ++ If this option is enabled, U-Boot will initialize ++ configuration EEPROM on board. ++ It will be enabled once the CMD_MVEBU_BOX_INFO or ++ MULTI_DT_FILE is enabled ++ ++config MVEBU_SAR ++ bool "Support MVEBU SAR Utility" ++ default n ++ help ++ Say Y here to add support for Sample ++ at Reset Utility. You need this only if ++ you work on a Marvell development board. ++ If not, keep this off to reduce code size ++ ++endmenu +diff --git a/board/Marvell/common/Makefile b/board/Marvell/common/Makefile +new file mode 100644 +index 0000000000..1adfef4246 +--- /dev/null ++++ b/board/Marvell/common/Makefile +@@ -0,0 +1,9 @@ ++# ++# Copyright (C) 2018 Marvell International Ltd. ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# https://spdx.org/licenses ++# ++ ++obj-$(CONFIG_BOARD_CONFIG_EEPROM) += cfg_eeprom.o ++obj-$(CONFIG_MVEBU_SAR) += sar.o +diff --git a/board/Marvell/common/cfg_eeprom.c b/board/Marvell/common/cfg_eeprom.c +new file mode 100644 +index 0000000000..1986e4e949 +--- /dev/null ++++ b/board/Marvell/common/cfg_eeprom.c +@@ -0,0 +1,385 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ */ ++ ++#include ++#include ++ ++struct eeprom_struct board_config_val = CFG_DEFAULT_VALUE; ++struct config_types_info config_types_info[] = MV_EEPROM_CONFIG_INFO; ++int eeprom_initialized = -1; ++int g_board_hw_info = -1; ++ ++static char hw_info_param_list[][HW_INFO_MAX_NAME_LEN] = { ++ "pcb_slm", ++ "pcb_rev", ++ "eco_rev", ++ "pcb_sn", ++ "ethaddr", ++ "eth1addr", ++ "eth2addr", ++ "eth3addr", ++ "eth4addr", ++ "eth5addr", ++ "eth6addr", ++ "eth7addr", ++ "eth8addr", ++ "eth9addr" ++}; ++ ++static int hw_info_param_num = (sizeof(hw_info_param_list) / ++ sizeof(hw_info_param_list[0])); ++ ++static u32 cfg_eeprom_checksum8(u8 *start, u32 len) ++{ ++ u32 sum = 0; ++ u8 *startp = start; ++ ++ do { ++ sum += *startp; ++ startp++; ++ len--; ++ } while (len > 0); ++ return sum; ++} ++ ++/* cfg_eeprom_get_config_type ++ * config_info input pointer receive the mapping of the ++ * required field in the local struct ++ */ ++static bool cfg_eeprom_get_config_type(enum mv_config_type_id id, ++ struct config_types_info *config_info) ++{ ++ int i; ++ ++ /* verify existence of requested config type, pull its data */ ++ for (i = 0; i < MV_CONFIG_TYPE_MAX_OPTION ; i++) ++ if (config_types_info[i].config_id == id) { ++ *config_info = config_types_info[i]; ++ return true; ++ } ++ pr_err("requested MV_CONFIG_TYPE_ID was not found (%d)\n", id); ++ ++ return false; ++} ++ ++/* read specific field from EEPROM ++ * @data_length: if equal to -1 read number of bytes as the length of the field. ++ */ ++static void read_field_from_eeprom(enum mv_config_type_id id, ++ u8 *data, int data_length) ++{ ++ struct config_types_info config_info; ++ struct udevice *dev; ++ int err; ++ ++ err = i2c_get_chip_for_busnum(BOARD_HW_INFO_EEPROM_DEV, ++ BOARD_DEV_TWSI_INIT_EEPROM, ++ BOARD_HW_INFO_EEPROM_ADDR_LEN, ++ &dev); ++ if (err) { ++ debug("%s: Cannot find EEPROM I2C chip\n", __func__); ++ return; ++ } ++ ++ if (!cfg_eeprom_get_config_type(id, &config_info)) { ++ pr_err("Could not find field %x in EEPROM struct\n", id); ++ return; ++ } ++ ++ if (data_length == READ_SPECIFIC_FIELD) ++ data_length = config_info.byte_cnt; ++ ++ dm_i2c_read(dev, config_info.byte_num, data, data_length); ++} ++ ++/* cfg_eeprom_write_to_eeprom - write the global struct to EEPROM. */ ++int cfg_eeprom_write_to_eeprom(int length) ++{ ++ int reserve_length, size_of_loop, i; ++ struct udevice *dev; ++ u8 *pattern = (u8 *)&board_config_val.pattern; ++ int err; ++ ++ err = i2c_get_chip_for_busnum(BOARD_HW_INFO_EEPROM_DEV, ++ BOARD_DEV_TWSI_INIT_EEPROM, ++ BOARD_HW_INFO_EEPROM_ADDR_LEN, ++ &dev); ++ if (err) { ++ debug("%s: Cannot find EEPROM I2C chip\n", __func__); ++ return err; ++ } ++ ++ /* calculate checksum and save it in struct */ ++ board_config_val.checksum = cfg_eeprom_checksum8(pattern, ++ EEPROM_STRUCT_SIZE - ++ 4); ++ ++ /* write fdt struct to EEPROM */ ++ size_of_loop = length / I2C_PAGE_WRITE_SIZE; ++ reserve_length = length % I2C_PAGE_WRITE_SIZE; ++ ++ /* i2c support on page write with size 32-byets */ ++ for (i = 0; i < size_of_loop; i++) { ++ u8 *buffer = (u8 *)&(board_config_val) + ++ i * I2C_PAGE_WRITE_SIZE; ++ dm_i2c_write(dev, i * I2C_PAGE_WRITE_SIZE, ++ buffer, ++ I2C_PAGE_WRITE_SIZE); ++#ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS ++ /* EEPROM write need delay, or cause write operation fail */ ++ udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); ++#endif ++ } ++ ++ /* write the reserve data from 32-bytes */ ++ if (reserve_length) { ++ u8 *buffer = (u8 *)&(board_config_val) + ++ i * I2C_PAGE_WRITE_SIZE; ++ dm_i2c_write(dev, i * I2C_PAGE_WRITE_SIZE, ++ buffer, ++ reserve_length); ++#ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS ++ /* EEPROM write need delay */ ++ udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); ++#endif ++ } ++ ++ return 0; ++} ++ ++/* cfg_eeprom_save - write the local struct to EEPROM */ ++void cfg_eeprom_save(int length) ++{ ++ /* write local struct with fdt blob to EEPROM */ ++ cfg_eeprom_write_to_eeprom(length); ++ /* reset g_board_id so it will get board ID from EEPROM again */ ++ g_board_hw_info = -1; ++} ++ ++/* cfg_eeprom_get_board_config - return the whole board config ++ * It is assumed the cfg_eeprom_init must be called prior to this routine, ++ * otherwise static default configuration will be used. ++ */ ++struct eeprom_struct *cfg_eeprom_get_board_config(void) ++{ ++ return &board_config_val; ++} ++ ++/* cfg_eeprom_get_hw_info_str - copy hw_info from cfg_eeprom to destination */ ++void cfg_eeprom_get_hw_info_str(uchar *hw_info_str) ++{ ++ int len; ++ ++ /* hw_info isn't initialized, need to read hw_info from EEPROM */ ++ if (g_board_hw_info == -1) { ++ u8 *hw_info = (u8 *)board_config_val.man_info.hw_info; ++ /* read hw_info config from EEPROM */ ++ read_field_from_eeprom(MV_CONFIG_HW_INFO, ++ hw_info, ++ READ_SPECIFIC_FIELD); ++ } ++ len = strlen((const char *)board_config_val.man_info.hw_info); ++ if (len >= MVEBU_HW_INFO_LEN) ++ len = MVEBU_HW_INFO_LEN - 1; ++ ++ memcpy(hw_info_str, board_config_val.man_info.hw_info, len); ++} ++ ++/* cfg_eeprom_set_hw_info_str - copy hw_info sting to cfg_eeprom module ++ * It is assumed the cfg_eeprom_init must be called prior to this routine, ++ * otherwise static default configuration will be used. ++ */ ++void cfg_eeprom_set_hw_info_str(uchar *hw_info_str) ++{ ++ int len; ++ struct config_types_info config_info; ++ ++ /* read hw_info config from EEPROM */ ++ if (!cfg_eeprom_get_config_type(MV_CONFIG_HW_INFO, &config_info)) { ++ pr_err("Could not find MV_CONFIG_hw_info\n"); ++ return; ++ } ++ ++ len = strlen((const char *)hw_info_str); ++ if (len >= config_info.byte_cnt) ++ len = config_info.byte_cnt - 1; ++ ++ /* need to set all value to 0 at first for later string operation */ ++ memset(board_config_val.man_info.hw_info, 0, config_info.byte_cnt); ++ memcpy(board_config_val.man_info.hw_info, hw_info_str, len); ++} ++ ++/* cfg_eeprom_skip_space - skip the space character */ ++static char *cfg_eeprom_skip_space(char *buf) ++{ ++ while ((buf[0] == ' ' || buf[0] == '\t')) ++ ++buf; ++ return buf; ++} ++ ++/* ++ * cfg_eeprom_parse_hw_info ++ * - parse the hw_info from string to name/value pairs ++ */ ++int cfg_eeprom_parse_hw_info(struct hw_info_data_struct *hw_info_data_array) ++{ ++ int count; ++ char *name; ++ char *value; ++ int len; ++ uchar hw_info_str[MVEBU_HW_INFO_LEN]; ++ ++ /* need to set all to 0 for later string operation */ ++ memset(hw_info_str, 0, sizeof(hw_info_str)); ++ ++ cfg_eeprom_get_hw_info_str(hw_info_str); ++ name = (char *)hw_info_str; ++ name = cfg_eeprom_skip_space(name); ++ /* return 0 in case the string is empty */ ++ if (!name) ++ return 0; ++ ++ for (count = 0; name; count++) { ++ value = strchr(name, '='); ++ ++ if (!value) ++ return count; ++ ++ *value = '\0'; ++ len = strlen(name); ++ memcpy(hw_info_data_array[count].name, name, len); ++ hw_info_data_array[count].name[len] = '\0'; ++ value++; ++ ++ name = strchr(value, ' '); ++ if (!name) ++ return ++count; ++ ++ *name = '\0'; ++ len = strlen(value); ++ memcpy(hw_info_data_array[count].value, value, len); ++ hw_info_data_array[count].value[len] = '\0'; ++ name = cfg_eeprom_skip_space(name + 1); ++ } ++ count++; ++ ++ return count; ++} ++ ++/* cfg_eeprom_validate_name - check parameter's name is valid or not ++ * valid - return 0 ++ * invalid - return -1 ++ */ ++int cfg_eeprom_validate_name(char *name) ++{ ++ int idx; ++ ++ for (idx = 0; idx < hw_info_param_num; idx++) { ++ if (strcmp(name, hw_info_param_list[idx]) == 0) ++ return 0; ++ } ++ ++ return -1; ++} ++ ++/* cfg_eeprom_parse_env - parse the env from env to name/value pairs */ ++int cfg_eeprom_parse_env(struct hw_info_data_struct *data_array, ++ int size) ++{ ++ int param_num = 0; ++ int idx; ++ int len; ++ char *name; ++ char *value; ++ ++ /* need to memset to 0 for later string operation */ ++ memset(data_array, 0, size); ++ for (idx = 0; idx < hw_info_param_num; idx++) { ++ name = hw_info_param_list[idx]; ++ value = env_get(name); ++ ++ if (!value) { ++ printf("miss %s in env, please set it at first\n", ++ hw_info_param_list[idx]); ++ continue; ++ } ++ ++ len = strlen(name); ++ if (len > HW_INFO_MAX_NAME_LEN) ++ len = HW_INFO_MAX_NAME_LEN; ++ memcpy(data_array[param_num].name, name, len); ++ len = strlen(value); ++ if (len > HW_INFO_MAX_NAME_LEN) ++ len = HW_INFO_MAX_NAME_LEN; ++ memcpy(data_array[param_num].value, value, len); ++ ++ param_num++; ++ } ++ ++ return param_num; ++} ++ ++/* ++ * cfg_eeprom_init - initialize FDT configuration struct ++ * The EEPROM FDT is used if 1) the checksum is valid, 2) the system ++ * is not in recovery mode, 3) validation_counter < AUTO_RECOVERY_RETRY_TIMES ++ * Otherwise the default FDT is used. ++ */ ++int cfg_eeprom_init(void) ++{ ++ struct eeprom_struct eeprom_buffer; ++ u32 calculate_checksum; ++ struct udevice *dev; ++ u8 *pattern = (u8 *)&eeprom_buffer.pattern; ++ int err; ++ ++ err = i2c_get_chip_for_busnum(BOARD_HW_INFO_EEPROM_DEV, ++ BOARD_DEV_TWSI_INIT_EEPROM, ++ BOARD_HW_INFO_EEPROM_ADDR_LEN, ++ &dev); ++ if (err) { ++ debug("%s: Cannot find EEPROM I2C chip\n", __func__); ++ return err; ++ } ++ ++ /* It is possible that this init will be called by several ++ * modules during init, however only need to initialize it ++ * for one time ++ */ ++ if (eeprom_initialized == 1) ++ return 0; ++ ++ /* read pattern from EEPROM */ ++ read_field_from_eeprom(MV_CONFIG_PATTERN, ++ pattern, ++ READ_SPECIFIC_FIELD); ++ ++ /* check if pattern in EEPROM is invalid */ ++ if (eeprom_buffer.pattern != board_config_val.pattern) { ++ printf("EEPROM configuration pattern not detected.\n"); ++ goto init_done; ++ } ++ ++ /* read struct from EEPROM */ ++ err = dm_i2c_read(dev, 0, ++ (u8 *)&eeprom_buffer, ++ EEPROM_STRUCT_SIZE); ++ if (err) { ++ pr_err("read error from device: %p", dev); ++ return err; ++ } ++ ++ /* calculate checksum */ ++ calculate_checksum = cfg_eeprom_checksum8(pattern, ++ EEPROM_STRUCT_SIZE - 4); ++ if (calculate_checksum == eeprom_buffer.checksum) { ++ /* update board_config_val struct with read from EEPROM */ ++ board_config_val = eeprom_buffer; ++ } ++ ++init_done: ++ eeprom_initialized = 1; ++ return 0; ++} +diff --git a/board/Marvell/common/sar.c b/board/Marvell/common/sar.c +new file mode 100644 +index 0000000000..6e94196304 +--- /dev/null ++++ b/board/Marvell/common/sar.c +@@ -0,0 +1,516 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++struct sar_data __attribute__((section(".data"))) sar_board; ++#define board_get_sar() (&sar_board) ++#define board_get_sar_table() (sar_board.sar_lookup) ++ ++static u32 swap_value(u32 val, u32 bit_length) ++{ ++ u32 var_mask = (1 << bit_length) - 1; ++ ++ val = (val & 0xFFFF0000) >> 16 | (val & 0x0000FFFF) << 16; ++ val = (val & 0xFF00FF00) >> 8 | (val & 0x00FF00FF) << 8; ++ val = (val & 0xF0F0F0F0) >> 4 | (val & 0x0F0F0F0F) << 4; ++ val = (val & 0xCCCCCCCC) >> 2 | (val & 0x33333333) << 2; ++ val = (val & 0xAAAAAAAA) >> 1 | (val & 0x55555555) << 1; ++ val = (val >> (32 - bit_length)) & var_mask; ++ debug("value is swaped, new value = 0x%x\n", val); ++ ++ return val; ++} ++ ++static int sar_read_reg(u32 *reg) ++{ ++ struct udevice *dev; ++ uchar byte = 0; ++ int ret, chip; ++ u32 sar_reg = 0; ++ struct sar_data *sar = board_get_sar(); ++ int reg_width = sar->bit_width; ++ u8 reg_mask = (1 << reg_width) - 1; ++ ++ for (chip = 0; chip < sar->chip_count; chip++) { ++ ret = i2c_get_chip_for_busnum(0, sar->chip_addr[chip], 1, &dev); ++ if (ret) { ++ printf("Error: %s: Failed getting chip busnum 0x%x\n", ++ __func__, sar->chip_addr[chip]); ++ return -1; ++ } ++ ret = dm_i2c_read(dev, 0, &byte, 1); ++ if (ret) { ++ printf("Error: %s: Failed reading from chip 0x%x\n", ++ __func__, sar->chip_addr[chip]); ++ return -1; ++ } ++ sar_reg |= (byte & reg_mask) << (chip * reg_width); ++ } ++ debug("read: sar register = 0x%08x\n", sar_reg); ++ *reg = sar_reg; ++ ++ return 0; ++} ++ ++int sar_write_reg(u32 sar_reg) ++{ ++ struct udevice *dev; ++ uchar byte = 0; ++ int ret, chip; ++ struct sar_data *sar = board_get_sar(); ++ int reg_width = sar->bit_width; ++ u8 reg_mask = (1 << reg_width) - 1; ++ ++ for (chip = 0; chip < sar->chip_count; chip++) { ++ byte = (sar_reg >> (chip * reg_width)) & reg_mask; ++ ret = i2c_get_chip_for_busnum(0, sar->chip_addr[chip], 1, &dev); ++ if (ret) { ++ printf("Error: %s: Failed getting chip busnum 0x%x\n", ++ __func__, sar->chip_addr[chip]); ++ return -1; ++ } ++ ++ ret = dm_i2c_write(dev, 0, &byte, 1); ++ if (ret) { ++ printf("Error: %s: Failed writing to chip 0x%x\n", ++ __func__, sar->chip_addr[chip]); ++ return -1; ++ } ++ } ++ debug("write: sar register = 0x%08x\n", sar_reg); ++ /* ++ * Wait for the write to complete. The write can take ++ * up to 10mSec (we allow a little more time). ++ */ ++ mdelay(11); ++ ++ return 0; ++} ++ ++int sar_read_var(struct sar_var *var, int *val) ++{ ++ u32 sar_reg; ++ u32 var_mask = (1 << var->bit_length) - 1; ++ ++ if (sar_read_reg(&sar_reg)) ++ return -1; ++ ++ (*val) = (sar_reg >> var->start_bit) & var_mask; ++ if (var->swap_bit) ++ (*val) = swap_value(*val, var->bit_length); ++ ++ debug("var offset = %d len = %d val = 0x%x\n", var->start_bit, ++ var->bit_length, (*val)); ++ ++ return 0; ++} ++ ++int sar_write_var(struct sar_var *var, int val) ++{ ++ u32 sar_reg; ++ u32 var_mask = (1 << var->bit_length) - 1; ++ ++ if (sar_read_reg(&sar_reg)) ++ return -1; ++ ++ /* Update the bitfield inside the sar register */ ++ if (var->swap_bit) ++ val = swap_value(val, var->bit_length); ++ val &= var_mask; ++ sar_reg &= ~(var_mask << var->start_bit); ++ sar_reg |= (val << var->start_bit); ++ ++ /* Write the full sar register back to i2c */ ++ if (sar_write_reg(sar_reg)) ++ return -1; ++ ++ return 0; ++} ++ ++static int sar_default_var(struct sar_var *var) ++{ ++ struct var_opts *opts; ++ struct var_opts *dflt = NULL; ++ int i; ++ ++ opts = var->option_desc; ++ ++ for (i = 0; i < var->option_cnt; i++, opts++) { ++ if (opts->flags & VAR_IS_DEFAULT) ++ dflt = opts; ++ } ++ ++ if (!dflt) { ++ printf("Error: Failed to find default option"); ++ return -1; ++ } ++ ++ if (sar_write_var(var, dflt->value)) { ++ printf("Error: Failed to write default value"); ++ return -1; ++ } ++ ++ debug("Wrote default value 0x%x = %s\n", dflt->value, dflt->desc); ++ return 0; ++} ++ ++int sar_get_key_id(const char *key) ++{ ++ struct sar_var *sar_table = board_get_sar_table(); ++ int id; ++ ++ for (id = 0; id < MAX_SAR; id++) { ++ if (strcmp(key, sar_table[id].key) == 0) ++ return id; ++ } ++ return -1; ++} ++ ++int sar_is_var_active(int id) ++{ ++ struct sar_var *sar_table = board_get_sar_table(); ++ ++ return sar_table[id].active; ++} ++ ++struct var_opts *sar_get_var_opts(int id, int *cnt) ++{ ++ struct sar_var *sar_table = board_get_sar_table(); ++ ++ (*cnt) = sar_table[id].option_cnt; ++ ++ return sar_table[id].option_desc; ++} ++ ++int sar_validate_key(const char *key) ++{ ++ int id = sar_get_key_id(key); ++ ++ if (id == -1) { ++ printf("Satr: Error: Unknown key \"%s\"\n", key); ++ return -1; ++ } ++ if (sar_is_var_active(id) == 0) { ++ printf("Satr: Error: Key \"%s\" is inactive on this board\n", ++ key); ++ return -1; ++ } ++ return id; ++} ++ ++struct sar_var *sar_id_to_var(int id) ++{ ++ struct sar_var *sar_table = board_get_sar_table(); ++ ++ sar_table += id; ++ return sar_table; ++} ++ ++/* Interface to SatR command */ ++int sar_is_available(void) ++{ ++ if (!board_get_sar_table()) ++ return 0; ++ else ++ return 1; ++} ++ ++void sar_print_var(int id, bool print_opts) ++{ ++ int cnt; ++ struct var_opts *opts; ++ struct sar_var *sar_table = board_get_sar_table(); ++ ++ printf("%-10s %s\n", sar_table[id].key, sar_table[id].desc); ++ ++ if (print_opts) { ++ opts = sar_get_var_opts(id, &cnt); ++ while (cnt--) { ++ printf("\t0x%-2x %s ", opts->value, opts->desc); ++ if (opts->flags & VAR_IS_DEFAULT) ++ printf("[Default]"); ++ printf("\n"); ++ opts++; ++ } ++ } ++} ++ ++int sar_read_all(void) ++{ ++ struct sar_var *var; ++ int id; ++ ++ for (id = 0; id < MAX_SAR; id++) ++ if (sar_is_var_active(id)) { ++ var = sar_id_to_var(id); ++ sar_print_key(var->key); ++ } ++ ++ return 0; ++} ++ ++void sar_list_keys(void) ++{ ++ int id; ++ ++ printf("\n"); ++ for (id = 0; id < MAX_SAR; id++) { ++ if (sar_is_var_active(id)) ++ sar_print_var(id, 0); ++ } ++ printf("\n"); ++} ++ ++int sar_list_key_opts(const char *key) ++{ ++ int id = sar_validate_key(key); ++ ++ if (id == -1) ++ return -EINVAL; ++ ++ printf("\n"); ++ sar_print_var(id, 1); ++ printf("\n"); ++ ++ return 0; ++} ++ ++int sar_print_key(const char *key) ++{ ++ int id = sar_validate_key(key); ++ struct sar_var *var; ++ struct var_opts *opts; ++ char *desc = NULL; ++ int val, ret, cnt; ++ ++ if (id == -1) ++ return -EINVAL; ++ ++ var = sar_id_to_var(id); ++ ret = sar_read_var(var, &val); ++ if (ret) ++ return ret; ++ ++ opts = sar_get_var_opts(id, &cnt); ++ while (cnt--) { ++ if (opts->value == val) ++ desc = opts->desc; ++ opts++; ++ } ++ ++ if (!desc) ++ printf("%s = 0x%x ERROR: UNKNOWN OPTION\n", key, val); ++ else ++ printf("%s = 0x%x %s\n", key, val, desc); ++ ++ return 0; ++} ++ ++int sar_write_key(const char *key, int val) ++{ ++ int id = sar_validate_key(key); ++ struct sar_var *var; ++ struct var_opts *opts; ++ char *desc = NULL; ++ int cnt; ++ ++ if (id == -1) ++ return -EINVAL; ++ ++ var = sar_id_to_var(id); ++ opts = sar_get_var_opts(id, &cnt); ++ while (cnt--) { ++ if (opts->value == val) ++ desc = opts->desc; ++ opts++; ++ } ++ ++ if (!desc) { ++ printf("ERROR: value 0x%x not supported for key %s\n", ++ val, key); ++ printf("use \"SatR list %s\" to print supported values\n", ++ key); ++ return -1; ++ } ++ ++ if (sar_write_var(var, val)) ++ return -1; ++ ++ /* Display the updated variable */ ++ sar_print_key(key); ++ ++ return 0; ++} ++ ++int sar_default_all(void) ++{ ++ struct sar_var *var; ++ int id; ++ int ret = 0; ++ ++ for (id = 0; id < MAX_SAR; id++) { ++ if (sar_is_var_active(id)) { ++ var = sar_id_to_var(id); ++ ret |= sar_default_var(var); ++ sar_print_key(var->key); ++ } ++ } ++ ++ return ret; ++} ++ ++int sar_default_key(const char *key) ++{ ++ int id = sar_validate_key(key); ++ struct sar_var *var; ++ int ret; ++ ++ if (id == -1) ++ return -EINVAL; ++ ++ var = sar_id_to_var(id); ++ ret = sar_default_var(var); ++ if (ret) ++ return ret; ++ ++ /* Display the updated variable */ ++ sar_print_key(key); ++ ++ return 0; ++} ++ ++static void sar_dump(void) ++{ ++#ifdef DEBUG ++ struct sar_data *sar = board_get_sar(); ++ struct sar_var *sar_var; ++ int i, id; ++ ++ printf("Sample at reset Dumper:\n"); ++ printf("\tSatR had %d chip addresses: ", sar->chip_count); ++ for (i = 0; i < sar->chip_count; i++) ++ printf("0x%x ", sar->chip_addr[i]); ++ printf("\n\tBit width for the I2C chip is: 0x%x\n", sar->bit_width); ++ printf("\tAll SatR variables thet available:\n"); ++ for (i = 0, sar_var = sar->sar_lookup; i < MAX_SAR; i++, sar_var++) { ++ if (sar_var->active == 0) ++ continue; ++ printf("\t\tID = %d, ", i); ++ printf("Key = %s, ", sar_var->key); ++ printf("Desc. = %s", sar_var->desc); ++ if (sar_var->swap_bit) ++ printf(", BIT is swapped"); ++ printf("\n\t\tStart bit = 0x%x, ", sar_var->start_bit); ++ printf("Bit length = %d\n", sar_var->bit_length); ++ printf("\t\tThis variable had %d options:\n", ++ sar_var->option_cnt); ++ for (id = 0; id < sar_var->option_cnt; id++) { ++ printf("\t\t\tValue = 0x%x, ", ++ sar_var->option_desc[id].value); ++ printf("Desc. = %s, ", sar_var->option_desc[id].desc); ++ printf("Is Default = %d\n", ++ sar_var->option_desc[id].flags); ++ } ++ } ++#endif ++} ++ ++void sar_init(void) ++{ ++ int i, var_default; ++ int node, var, len, lenp; ++ const char *str; ++ const void *blob = gd->fdt_blob; ++ struct sar_var *sar_var; ++ struct sar_data *sar = board_get_sar(); ++ ++ /* Get sar node from the FDT blob */ ++ node = fdt_node_offset_by_compatible(blob, -1, ++ fdtdec_get_compatible( ++ COMPAT_MVEBU_SAR)); ++ if (node < 0) { ++ debug("No sar node found in FDT blob\n"); ++ return; ++ } ++ ++ /* Get the bit width of the sapmple at reset i2c register */ ++ sar->bit_width = fdtdec_get_int(blob, node, "bit_width", 1); ++ /* Get the address count of sample at reset i2c */ ++ sar->chip_count = fdtdec_get_int(blob, node, "chip_count", 1); ++ /* get the address in array */ ++ if (fdtdec_get_int_array(blob, node, "reg", ++ sar->chip_addr, sar->chip_count) != 0) { ++ pr_err("No sample at reset addresses found in FDT blob\n"); ++ return; ++ } ++ /* Get the fisrt variable in sample at reset */ ++ var = fdt_first_subnode(blob, node); ++ if (!var) { ++ pr_err("No sample at reset variables found in FDT\n"); ++ return; ++ } ++ sar_var = sar->sar_lookup; ++ /* Find the variables under sample at reset node */ ++ while (var > 0) { ++ /* if the variable is disabled skip it */ ++ if (!fdtdec_get_is_enabled(blob, var)) { ++ /* Get the offset of the next subnode */ ++ var = fdt_next_subnode(blob, var); ++ sar_var++; ++ continue; ++ } ++ /* Get the key of the var option */ ++ sar_var->key = (char *)fdt_stringlist_get(blob, var, "key", ++ 0, &lenp); ++ /* Get the description of the var */ ++ sar_var->desc = (char *)fdt_stringlist_get(blob, var, ++ "description", 0, ++ &lenp); ++ /* set the different options of the var */ ++ sar_var->active = 1; ++ sar_var->start_bit = fdtdec_get_int(blob, var, "start-bit", 0); ++ sar_var->bit_length = fdtdec_get_int(blob, var, ++ "bit-length", 0); ++ sar_var->option_cnt = fdtdec_get_int(blob, var, ++ "option-cnt", 0); ++ sar_var->swap_bit = fdtdec_get_bool(blob, var, "swap-bit"); ++ /* Get the options list */ ++ len = fdt_stringlist_count(blob, var, "options"); ++ if ((len < 0) || (sar_var->option_cnt * 2 != len)) { ++ pr_err("%s: failed to parse the \"options\" property", ++ __func__); ++ return; ++ } ++ var_default = fdtdec_get_int(blob, var, "default", 0); ++ /* Fill the struct with the options from the FDT */ ++ for (i = 0; i < len; i += 2) { ++ str = fdt_stringlist_get(blob, var, "options", i, ++ &lenp); ++ sar_var->option_desc[i / 2].value = simple_strtoul( ++ str, NULL, 16); ++ sar_var->option_desc[i / 2].desc = ++ (char *)fdt_stringlist_get(blob, var, "options", ++ i + 1, &lenp); ++ if (sar_var->option_desc[i / 2].value == var_default) ++ sar_var->option_desc[i / 2].flags = ++ VAR_IS_DEFAULT; ++ } ++ /* Get the offset of the next subnode */ ++ var = fdt_next_subnode(blob, var); ++ sar_var++; ++ } ++ ++ sar_dump(); ++} +diff --git a/board/Marvell/db-88f6820-ap/Makefile b/board/Marvell/db-88f6820-ap/Makefile +new file mode 100644 +index 0000000000..8d565ec718 +--- /dev/null ++++ b/board/Marvell/db-88f6820-ap/Makefile +@@ -0,0 +1,8 @@ ++# ++# Copyright (C) 2018 Grzegorz Jaszczyk ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++ccflags-y += -Idrivers/ddr/marvell/a38x/ -Iarch/arm/mach-mvebu/serdes/a38x/ ++obj-y := db-88f6820-ap.o +diff --git a/board/Marvell/db-88f6820-ap/db-88f6820-ap.c b/board/Marvell/db-88f6820-ap/db-88f6820-ap.c +new file mode 100644 +index 0000000000..ac35832e9a +--- /dev/null ++++ b/board/Marvell/db-88f6820-ap/db-88f6820-ap.c +@@ -0,0 +1,140 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "../drivers/ddr/marvell/a38x/ddr3_init.h" ++#include ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++#define ETH_PHY_CTRL_REG 0 ++#define ETH_PHY_CTRL_POWER_DOWN_MASK BIT(11) ++ ++/* ++ * Those values and defines are taken from the Marvell U-Boot version ++ * "u-boot-2013.01-2014_T3.0" ++ */ ++ ++#define DB_AP_88F68XX_GPP_OUT_ENA_LOW \ ++ (~(BIT(21))) ++#define DB_AP_88F68XX_GPP_OUT_ENA_MID \ ++ (~(BIT(1) | BIT(2) | BIT(3) | BIT(5) | BIT(15))) ++#define DB_AP_88F68XX_GPP_OUT_ENA_HIGH (~(BIT(1))) ++ ++#define DB_AP_88F68XX_GPP_OUT_VAL_LOW 0x0 ++#define DB_AP_88F68XX_GPP_OUT_VAL_MID BIT(15) ++#define DB_AP_88F68XX_GPP_OUT_VAL_HIGH 0x0 ++#define DB_AP_88F68XX_GPP_POL_LOW 0x0 ++#define DB_AP_88F68XX_GPP_POL_MID 0x0 ++#define DB_AP_88F68XX_GPP_POL_HIGH 0x0 ++ ++static struct serdes_map board_serdes_map[] = { ++ {PEX0, SERDES_SPEED_5_GBPS, PEX_ROOT_COMPLEX_X1, 0, 0}, ++ {SGMII1, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0, 0}, ++ {PEX1, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0}, ++ {SGMII2, SERDES_SPEED_3_125_GBPS, SERDES_DEFAULT_MODE, 0, 0}, ++ {USB3_HOST0, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0}, ++ {PEX2, SERDES_SPEED_5_GBPS, SERDES_DEFAULT_MODE, 0, 0} ++}; ++ ++int hws_board_topology_load(struct serdes_map **serdes_map_array, u8 *count) ++{ ++ *serdes_map_array = board_serdes_map; ++ *count = ARRAY_SIZE(board_serdes_map); ++ return 0; ++} ++ ++/* ++ * Define the DDR layout / topology here in the board file. This will ++ * be used by the DDR3 init code in the SPL U-Boot version to configure ++ * the DDR3 controller. ++ */ ++static struct mv_ddr_topology_map board_topology_map = { ++ DEBUG_LEVEL_ERROR, ++ 0x1, /* active interfaces */ ++ /* cs_mask, mirror, dqs_swap, ck_swap X PUPs */ ++ { { { {0x1, 0, 0, 0}, ++ {0x1, 0, 0, 0}, ++ {0x1, 0, 0, 0}, ++ {0x1, 0, 0, 0}, ++ {0x1, 0, 0, 0} }, ++ SPEED_BIN_DDR_1866L, /* speed_bin */ ++ MV_DDR_DEV_WIDTH_8BIT, /* memory_width */ ++ MV_DDR_DIE_CAP_4GBIT, /* mem_size */ ++ MV_DDR_FREQ_800, /* frequency */ ++ 0, 0, /* cas_l cas_wl */ ++ MV_DDR_TEMP_LOW, /* temperature */ ++ MV_DDR_TIM_DEFAULT} }, /* timing */ ++ BUS_MASK_32BIT, /* Busses mask */ ++ MV_DDR_CFG_DEFAULT, /* ddr configuration data source */ ++ { {0} }, /* raw spd data */ ++ {0} /* timing parameters */ ++}; ++ ++struct mv_ddr_topology_map *mv_ddr_topology_map_get(void) ++{ ++ /* Return the board topology as defined in the board code */ ++ return &board_topology_map; ++} ++ ++int board_early_init_f(void) ++{ ++ /* Configure MPP */ ++ writel(0x11111111, MVEBU_MPP_BASE + 0x00); ++ writel(0x11111111, MVEBU_MPP_BASE + 0x04); ++ writel(0x55066011, MVEBU_MPP_BASE + 0x08); ++ writel(0x05050050, MVEBU_MPP_BASE + 0x0c); ++ writel(0x05055555, MVEBU_MPP_BASE + 0x10); ++ writel(0x01100565, MVEBU_MPP_BASE + 0x14); ++ writel(0x00000000, MVEBU_MPP_BASE + 0x18); ++ writel(0x00004444, MVEBU_MPP_BASE + 0x1c); ++ ++ /* Set GPP Out value */ ++ writel(DB_AP_88F68XX_GPP_OUT_VAL_LOW, MVEBU_GPIO0_BASE + 0x00); ++ writel(DB_AP_88F68XX_GPP_OUT_VAL_MID, MVEBU_GPIO1_BASE + 0x00); ++ writel(DB_AP_88F68XX_GPP_OUT_VAL_HIGH, MVEBU_GPIO1_BASE + 0x40 + 0x00); ++ ++ /* Set GPP Polarity */ ++ writel(DB_AP_88F68XX_GPP_POL_LOW, MVEBU_GPIO0_BASE + 0x0c); ++ writel(DB_AP_88F68XX_GPP_POL_MID, MVEBU_GPIO1_BASE + 0x0c); ++ writel(DB_AP_88F68XX_GPP_POL_HIGH, (MVEBU_GPIO1_BASE + 0x40) + 0x0c); ++ ++ /* Set GPP Out Enable */ ++ writel(DB_AP_88F68XX_GPP_OUT_ENA_LOW, MVEBU_GPIO0_BASE + 0x04); ++ writel(DB_AP_88F68XX_GPP_OUT_ENA_MID, MVEBU_GPIO1_BASE + 0x04); ++ writel(DB_AP_88F68XX_GPP_OUT_ENA_HIGH, (MVEBU_GPIO1_BASE + 0x40) + ++ 0x04); ++ ++ return 0; ++} ++ ++int board_init(void) ++{ ++ /* address of boot parameters */ ++ gd->bd->bi_boot_params = mvebu_sdram_bar(0) + 0x100; ++ ++ return 0; ++} ++ ++int checkboard(void) ++{ ++ puts("Board: Marvell DB-88F6820-AP\n"); ++ ++ return 0; ++} ++ ++int board_eth_init(bd_t *bis) ++{ ++ cpu_eth_init(bis); /* Built in controller(s) come first */ ++ return pci_eth_init(bis); ++} +diff --git a/board/Marvell/db-88f6820-ap/kwbimage.cfg b/board/Marvell/db-88f6820-ap/kwbimage.cfg +new file mode 100644 +index 0000000000..9d271469d3 +--- /dev/null ++++ b/board/Marvell/db-88f6820-ap/kwbimage.cfg +@@ -0,0 +1,12 @@ ++# ++# Copyright (C) 2018 Grzegorz Jaszczyk ++# ++ ++# Armada XP uses version 1 image format ++VERSION 1 ++ ++# Boot Media configurations ++BOOT_FROM nand ++ ++# Binary Header (bin_hdr) with DDR3 training code ++BINARY spl/u-boot-spl-dtb.bin 0000005b 00000068 +diff --git a/board/Marvell/mvebu_armada-37xx/board.c b/board/Marvell/mvebu_armada-37xx/board.c +index bef4e1767c..3d5ce8f36c 100644 +--- a/board/Marvell/mvebu_armada-37xx/board.c ++++ b/board/Marvell/mvebu_armada-37xx/board.c +@@ -10,15 +10,29 @@ + #include + #include + #include ++#include ++#ifdef CONFIG_BOARD_CONFIG_EEPROM ++#include ++#endif + + DECLARE_GLOBAL_DATA_PTR; + ++/* on Armada3700 rev2 devel-board, IO expander (with I2C address 0x22) bit ++ * 14 is used as Serdes Lane 2 muxing, which could be used as SATA PHY or ++ * USB3 PHY. ++ */ ++enum COMPHY_LANE2_MUXING { ++ COMPHY_LANE2_MUX_USB3, ++ COMPHY_LANE2_MUX_SATA ++}; ++ + /* IO expander I2C device */ + #define I2C_IO_EXP_ADDR 0x22 + #define I2C_IO_CFG_REG_0 0x6 + #define I2C_IO_DATA_OUT_REG_0 0x2 + #define I2C_IO_REG_0_SATA_OFF 2 + #define I2C_IO_REG_0_USB_H_OFF 1 ++#define I2C_IO_COMPHY_SATA3_USB_MUX_BIT 14 + + /* The pin control values are the same for DB and Espressobin */ + #define PINCTRL_NB_REG_VALUE 0x000173fa +@@ -47,8 +61,73 @@ DECLARE_GLOBAL_DATA_PTR; + #define MVEBU_G2_SMI_PHY_CMD_REG (24) + #define MVEBU_G2_SMI_PHY_DATA_REG (25) + ++/* ++* For Armada3700 A0 chip, comphy serdes lane 2 could be used as PHY for SATA ++* or USB3. ++* For Armada3700 rev2 devel-board, pin 14 of IO expander PCA9555 with I2C ++* address 0x22 is used as Serdes Lane 2 muxing; the pin needs to be set in ++* output mode: high level is for SATA while low level is for USB3; ++*/ ++static int board_comphy_usb3_sata_mux(enum COMPHY_LANE2_MUXING comphy_mux) ++{ ++ int ret; ++ u8 buf[8]; ++ struct udevice *i2c_dev; ++ int i2c_byte, i2c_bit_in_byte; ++ ++ if (!of_machine_is_compatible("marvell,armada-3720-db-v2") && ++ !of_machine_is_compatible("marvell,armada-3720-db-v3")) ++ return 0; ++ ++ ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &i2c_dev); ++ if (ret) { ++ printf("Cannot find PCA9555: %d\n", ret); ++ return 0; ++ } ++ ++ ret = dm_i2c_read(i2c_dev, I2C_IO_CFG_REG_0, buf, 2); ++ if (ret) { ++ printf("Failed to read IO expander value via I2C\n"); ++ return ret; ++ } ++ ++ i2c_byte = I2C_IO_COMPHY_SATA3_USB_MUX_BIT / 8; ++ i2c_bit_in_byte = I2C_IO_COMPHY_SATA3_USB_MUX_BIT % 8; ++ ++ /* Configure IO exander bit 14 of address 0x22 in output mode */ ++ buf[i2c_byte] &= ~(1 << i2c_bit_in_byte); ++ ret = dm_i2c_write(i2c_dev, I2C_IO_CFG_REG_0, buf, 2); ++ if (ret) { ++ printf("Failed to set IO expander via I2C\n"); ++ return ret; ++ } ++ ++ ret = dm_i2c_read(i2c_dev, I2C_IO_DATA_OUT_REG_0, buf, 2); ++ if (ret) { ++ printf("Failed to read IO expander value via I2C\n"); ++ return ret; ++ } ++ ++ /* Configure output level for IO exander bit 14 of address 0x22 */ ++ if (comphy_mux == COMPHY_LANE2_MUX_SATA) ++ buf[i2c_byte] |= (1 << i2c_bit_in_byte); ++ else ++ buf[i2c_byte] &= ~(1 << i2c_bit_in_byte); ++ ++ ret = dm_i2c_write(i2c_dev, I2C_IO_DATA_OUT_REG_0, buf, 2); ++ if (ret) { ++ printf("Failed to set IO expander via I2C\n"); ++ return ret; ++ } ++ ++ return 0; ++} ++ + int board_early_init_f(void) + { ++#ifdef CONFIG_BOARD_CONFIG_EEPROM ++ cfg_eeprom_init(); ++#endif + return 0; + } + +@@ -57,6 +136,9 @@ int board_init(void) + /* adress of boot parameters */ + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; + ++ /* enable serdes lane 2 mux for sata phy */ ++ board_comphy_usb3_sata_mux(COMPHY_LANE2_MUX_SATA); ++ + return 0; + } + +diff --git a/board/Marvell/mvebu_armada-8k/board.c b/board/Marvell/mvebu_armada-8k/board.c +index e927e338ea..c348b8c630 100644 +--- a/board/Marvell/mvebu_armada-8k/board.c ++++ b/board/Marvell/mvebu_armada-8k/board.c +@@ -4,158 +4,129 @@ + */ + + #include ++#include + #include + #include + #include + #include + #include ++#include ++#ifdef CONFIG_BOARD_CONFIG_EEPROM ++#include ++#endif ++ ++#define CP_USB20_BASE_REG(cp, p) (MVEBU_REGS_BASE_CP(0, cp) + \ ++ 0x00580000 + 0x1000 * (p)) ++#define CP_USB20_TX_CTRL_REG(cp, p) (CP_USB20_BASE_REG(cp, p) + 0xC) ++#define CP_USB20_TX_OUT_AMPL_MASK (0x7 << 20) ++#define CP_USB20_TX_OUT_AMPL_VALUE (0x3 << 20) + + DECLARE_GLOBAL_DATA_PTR; + +-/* +- * Information specific to the DB-88F7040 eval board. We strive to use +- * DT for such platform specfic configurations. At some point, this +- * might be removed here and implemented via DT. +- */ +-/* IO expander I2C device */ +-#define I2C_IO_EXP_ADDR 0x21 +-#define I2C_IO_CFG_REG_0 0x6 +-#define I2C_IO_DATA_OUT_REG_0 0x2 +-/* VBus enable */ +-#define I2C_IO_REG_0_USB_H0_OFF 0 +-#define I2C_IO_REG_0_USB_H1_OFF 1 +-#define I2C_IO_REG_VBUS ((1 << I2C_IO_REG_0_USB_H0_OFF) | \ +- (1 << I2C_IO_REG_0_USB_H1_OFF)) +-/* Current limit */ +-#define I2C_IO_REG_0_USB_H0_CL 4 +-#define I2C_IO_REG_0_USB_H1_CL 5 +-#define I2C_IO_REG_CL ((1 << I2C_IO_REG_0_USB_H0_CL) | \ +- (1 << I2C_IO_REG_0_USB_H1_CL)) +- +-static int usb_enabled = 0; +- +-/* Board specific xHCI dis-/enable code */ ++#define BOOTCMD_NAME "pci-bootcmd" + +-/* +- * Set USB VBUS signals (via I2C IO expander/GPIO) as output and set +- * output value as disabled +- * +- * Set USB Current Limit signals (via I2C IO expander/GPIO) as output +- * and set output value as enabled +- */ +-int board_xhci_config(void) ++int __soc_early_init_f(void) + { +- struct udevice *dev; +- int ret; +- u8 buf[8]; +- +- if (of_machine_is_compatible("marvell,armada7040-db")) { +- /* Configure IO exander PCA9555: 7bit address 0x21 */ +- ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev); +- if (ret) { +- printf("Cannot find PCA9555: %d\n", ret); +- return 0; +- } +- +- /* +- * Read configuration (direction) and set VBUS pin as output +- * (reset pin = output) +- */ +- ret = dm_i2c_read(dev, I2C_IO_CFG_REG_0, buf, 1); +- if (ret) { +- printf("Failed to read IO expander value via I2C\n"); +- return -EIO; +- } +- buf[0] &= ~I2C_IO_REG_VBUS; +- buf[0] &= ~I2C_IO_REG_CL; +- ret = dm_i2c_write(dev, I2C_IO_CFG_REG_0, buf, 1); +- if (ret) { +- printf("Failed to set IO expander via I2C\n"); +- return -EIO; +- } +- +- /* Read output value and configure it */ +- ret = dm_i2c_read(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); +- if (ret) { +- printf("Failed to read IO expander value via I2C\n"); +- return -EIO; +- } +- buf[0] &= ~I2C_IO_REG_VBUS; +- buf[0] |= I2C_IO_REG_CL; +- ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); +- if (ret) { +- printf("Failed to set IO expander via I2C\n"); +- return -EIO; +- } +- +- mdelay(500); /* required delay to let output value settle */ +- } +- + return 0; + } + +-int board_xhci_enable(fdt_addr_t base) ++int soc_early_init_f(void) __attribute__((weak, alias("__soc_early_init_f"))); ++ ++int board_early_init_f(void) + { +- struct udevice *dev; +- int ret; +- u8 buf[8]; +- +- if (of_machine_is_compatible("marvell,armada7040-db")) { +- /* +- * This function enables all USB ports simultaniously, +- * it only needs to get called once +- */ +- if (usb_enabled) +- return 0; +- +- /* Configure IO exander PCA9555: 7bit address 0x21 */ +- ret = i2c_get_chip_for_busnum(0, I2C_IO_EXP_ADDR, 1, &dev); +- if (ret) { +- printf("Cannot find PCA9555: %d\n", ret); +- return 0; +- } +- +- /* Read VBUS output value */ +- ret = dm_i2c_read(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); +- if (ret) { +- printf("Failed to read IO expander value via I2C\n"); +- return -EIO; +- } +- +- /* Enable VBUS power: Set output value of VBUS pin as enabled */ +- buf[0] |= I2C_IO_REG_VBUS; +- ret = dm_i2c_write(dev, I2C_IO_DATA_OUT_REG_0, buf, 1); +- if (ret) { +- printf("Failed to set IO expander via I2C\n"); +- return -EIO; +- } +- +- mdelay(500); /* required delay to let output value settle */ +- usb_enabled = 1; +- } ++ soc_early_init_f(); + + return 0; + } + +-int board_early_init_f(void) ++int board_early_init_r(void) + { +- /* Nothing to do (yet), perhaps later some pin-muxing etc */ ++#ifdef CONFIG_DM_REGULATOR ++ /* Check if any existing regulator should be turned down */ ++ regulators_enable_boot_off(false); ++#endif + + return 0; + } + + int board_init(void) + { +- /* adress of boot parameters */ ++ /* address of boot parameters */ + gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; + ++#ifdef CONFIG_BOARD_CONFIG_EEPROM ++ cfg_eeprom_init(); ++#endif ++ + return 0; + } + ++#if (CONFIG_IS_ENABLED(OCTEONTX_SERIAL_BOOTCMD) || \ ++ CONFIG_IS_ENABLED(OCTEONTX_SERIAL_PCIE_CONSOLE)) && \ ++ !CONFIG_IS_ENABLED(CONSOLE_MUX) ++# error CONFIG_CONSOLE_MUX must be enabled! ++#endif ++ ++#if CONFIG_IS_ENABLED(OCTEONTX_SERIAL_BOOTCMD) ++static int init_bootcmd_console(void) ++{ ++ int ret = 0; ++ char *stdinname = env_get("stdin"); ++ struct udevice *bootcmd_dev = NULL; ++ bool stdin_set; ++ char iomux_name[128]; ++ ++ debug("%s: stdin before: %s\n", __func__, ++ stdinname ? stdinname : "NONE"); ++ if (!stdinname) { ++ env_set("stdin", "serial"); ++ stdinname = env_get("stdin"); ++ } ++ stdin_set = !!strstr(stdinname, BOOTCMD_NAME); ++ ret = uclass_get_device_by_driver(UCLASS_SERIAL, ++ DM_GET_DRIVER(octeontx_bootcmd), ++ &bootcmd_dev); ++ if (ret) { ++ pr_err("%s: Error getting %s serial class\n", __func__, ++ BOOTCMD_NAME); ++ } else if (bootcmd_dev) { ++ if (stdin_set) ++ strncpy(iomux_name, stdinname, sizeof(iomux_name)); ++ else ++ snprintf(iomux_name, sizeof(iomux_name), "%s,%s", ++ stdinname, bootcmd_dev->name); ++ ret = iomux_doenv(stdin, iomux_name); ++ if (ret) ++ pr_err("%s: Error %d enabling the PCI bootcmd input console \"%s\"\n", ++ __func__, ret, iomux_name); ++ if (!stdin_set) ++ env_set("stdin", iomux_name); ++ } ++ debug("%s: Set iomux and stdin to %s (ret: %d)\n", ++ __func__, iomux_name, ret); ++ return ret; ++} ++#endif ++ + int board_late_init(void) + { + /* Pre-configure the USB ports (overcurrent, VBus) */ +- board_xhci_config(); + ++ /* Adjust the USB 2.0 port TX output driver amplitude ++ * for passing compatibility tests ++ */ ++ if (of_machine_is_compatible("marvell,armada3900-vd")) { ++ u32 port; ++ ++ for (port = 0; port < 2; port++) ++ clrsetbits_le32(CP_USB20_TX_CTRL_REG(0, port), ++ CP_USB20_TX_OUT_AMPL_MASK, ++ CP_USB20_TX_OUT_AMPL_VALUE); ++ } ++ ++#if CONFIG_IS_ENABLED(OCTEONTX_SERIAL_BOOTCMD) ++ if (init_bootcmd_console()) ++ printf("Failed to init bootcmd input\n"); ++#endif + return 0; + } +diff --git a/board/Marvell/octeontx/Kconfig b/board/Marvell/octeontx/Kconfig +new file mode 100644 +index 0000000000..45d115916c +--- /dev/null ++++ b/board/Marvell/octeontx/Kconfig +@@ -0,0 +1,14 @@ ++if TARGET_OCTEONTX_81XX || TARGET_OCTEONTX_83XX ++ ++config SYS_VENDOR ++ string ++ default "Marvell" ++ ++config SYS_BOARD ++ string ++ default "octeontx" ++ ++config SYS_CONFIG_NAME ++ default "octeontx_common" ++ ++endif +diff --git a/board/Marvell/octeontx/MAINTAINERS b/board/Marvell/octeontx/MAINTAINERS +new file mode 100644 +index 0000000000..10816c7a03 +--- /dev/null ++++ b/board/Marvell/octeontx/MAINTAINERS +@@ -0,0 +1,9 @@ ++OCTEONTX BOARD ++M: Suneel Garapati ++M: Aaron Williams ++S: Maintained ++F: board/Marvell/octeontx/ ++F: include/configs/octeontx_81xx.h ++F: include/configs/octeontx_83xx.h ++F: configs/octeontx_81xx_defconfig ++F: configs/octeontx_83xx_defconfig +diff --git a/board/Marvell/octeontx/Makefile b/board/Marvell/octeontx/Makefile +new file mode 100644 +index 0000000000..fbe32ae003 +--- /dev/null ++++ b/board/Marvell/octeontx/Makefile +@@ -0,0 +1,9 @@ ++#/* ++# * Copyright (C) 2018 Marvell International Ltd. ++# * ++# * SPDX-License-Identifier: GPL-2.0 ++# * https://spdx.org/licenses ++# */ ++ ++obj-y := board.o smc.o soc-utils.o ++obj-$(CONFIG_OF_LIBFDT) += board-fdt.o +diff --git a/board/Marvell/octeontx/board-fdt.c b/board/Marvell/octeontx/board-fdt.c +new file mode 100644 +index 0000000000..8124e9e4b9 +--- /dev/null ++++ b/board/Marvell/octeontx/board-fdt.c +@@ -0,0 +1,347 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++extern unsigned long fdt_base_addr; ++ ++#ifdef CONFIG_NET_OCTEONTX ++static int fdt_get_mdio_bus(const void *fdt, int phy_offset) ++{ ++ int node, bus = -1; ++ const u64 *reg; ++ u64 addr; ++ ++ if (phy_offset < 0) ++ return -1; ++ /* obtain mdio node and get the reg prop */ ++ node = fdt_parent_offset(fdt, phy_offset); ++ if (node < 0) ++ return -1; ++ ++ reg = fdt_getprop(fdt, node, "reg", NULL); ++ addr = fdt64_to_cpu(*reg); ++ bus = (addr & (1 << 7)) ? 1 : 0; ++ return bus; ++} ++ ++static int fdt_get_phy_addr(const void *fdt, int phy_offset) ++{ ++ const u32 *reg; ++ int addr = -1; ++ ++ if (phy_offset < 0) ++ return -1; ++ reg = fdt_getprop(fdt, phy_offset, "reg", NULL); ++ addr = fdt32_to_cpu(*reg); ++ return addr; ++} ++ ++void fdt_parse_phy_info(void) ++{ ++ const void *fdt = gd->fdt_blob; ++ int offset = 0, node, bgx_id = 0, lmacid = 0; ++ const u32 *val; ++ char bgxname[24]; ++ int len, rgx_id = 0, eth_id = 0; ++ int phandle, phy_offset; ++ int subnode, i; ++ int bdknode; ++ ++ bdknode = fdt_path_offset(fdt, "/cavium,bdk"); ++ if (bdknode < 0) { ++ printf("%s: bdk node is missing from device tree: %s\n", ++ __func__, fdt_strerror(bdknode)); ++ } ++ ++ offset = fdt_node_offset_by_compatible(fdt, -1, "pci-bridge"); ++ if (offset < 1) ++ return; ++ ++ for (bgx_id = 0; bgx_id < MAX_BGX_PER_NODE; bgx_id++) { ++ int phy_addr[LMAC_CNT] = {[0 ... LMAC_CNT - 1] = -1}; ++ bool autoneg_dis[LMAC_CNT] = {[0 ... LMAC_CNT - 1] = 0}; ++ int mdio_bus[LMAC_CNT] = {[0 ... LMAC_CNT - 1] = -1}; ++ bool lmac_reg[LMAC_CNT] = {[0 ... LMAC_CNT - 1] = 0}; ++ bool lmac_enable[LMAC_CNT] = {[0 ... LMAC_CNT - 1] = 0}; ++ ++ snprintf(bgxname, sizeof(bgxname), "bgx%d", bgx_id); ++ node = fdt_subnode_offset(fdt, offset, bgxname); ++ if (node < 0) { ++ /* check if it is rgx node */ ++ snprintf(bgxname, sizeof(bgxname), "rgx%d", rgx_id); ++ node = fdt_subnode_offset(fdt, offset, bgxname); ++ if (node < 0) { ++ debug("bgx%d/rgx0 node not found\n", bgx_id); ++ return; ++ } ++ } ++ debug("bgx%d node found\n", bgx_id); ++ ++ /* ++ * loop through each of the bgx/rgx nodes ++ * to find PHY nodes ++ */ ++ fdt_for_each_subnode(subnode, fdt, node) { ++ /* Check for reg property */ ++ val = fdt_getprop(fdt, subnode, "reg", &len); ++ if (val) { ++ debug("lmacid = %d\n", lmacid); ++ lmac_reg[lmacid] = 1; ++ } ++ /* check for phy-handle property */ ++ val = fdt_getprop(fdt, subnode, "phy-handle", &len); ++ if (val) { ++ phandle = fdt32_to_cpu(*val); ++ if (!phandle) { ++ debug("phandle not valid %d\n", lmacid); ++ } else { ++ phy_offset = fdt_node_offset_by_phandle ++ (fdt, phandle); ++ phy_addr[lmacid] = fdt_get_phy_addr ++ (fdt, phy_offset); ++ mdio_bus[lmacid] = fdt_get_mdio_bus ++ (fdt, phy_offset); ++ } ++ } else { ++ debug("phy-handle prop not found %d\n", ++ lmacid); ++ } ++ /* check for autonegotiation property */ ++ val = fdt_getprop(fdt, subnode, ++ "cavium,disable-autonegotiation", ++ &len); ++ if (val) ++ autoneg_dis[lmacid] = 1; ++ ++ eth_id++; ++ lmacid++; ++ } ++ ++ for (i = 0; i < MAX_LMAC_PER_BGX; i++) { ++ const char *str; ++ ++ snprintf(bgxname, sizeof(bgxname), ++ "BGX-ENABLE.N0.BGX%d.P%d", bgx_id, i); ++ if (bdknode >= 0) { ++ str = fdt_getprop(fdt, bdknode, ++ bgxname, &len); ++ if (str) ++ lmac_enable[i] = ++ simple_strtol(str, NULL, ++ 10); ++ } ++ } ++ ++ lmacid = 0; ++ bgx_set_board_info(bgx_id, mdio_bus, phy_addr, ++ autoneg_dis, lmac_reg, lmac_enable); ++ } ++} ++#endif ++ ++static int fdt_get_bdk_node(void) ++{ ++ int node, ret; ++ const void *fdt = gd->fdt_blob; ++ ++ if (!fdt) { ++ printf("ERROR: %s: no valid device tree found\n", __func__); ++ return 0; ++ } ++ ++ ret = fdt_check_header(fdt); ++ if (ret < 0) { ++ printf("fdt: %s\n", fdt_strerror(ret)); ++ return 0; ++ } ++ ++ node = fdt_path_offset(fdt, "/cavium,bdk"); ++ if (node < 0) { ++ printf("%s: /cavium,bdk is missing from device tree: %s\n", ++ __func__, fdt_strerror(node)); ++ return 0; ++ } ++ return node; ++} ++ ++const char *fdt_get_board_serial(void) ++{ ++ const void *fdt = gd->fdt_blob; ++ int node, len = 64; ++ const char *str = NULL; ++ ++ node = fdt_get_bdk_node(); ++ if (!node) ++ return NULL; ++ ++ str = fdt_getprop(fdt, node, "BOARD-SERIAL", &len); ++ if (!str) ++ printf("Error: cannot retrieve board serial from fdt\n"); ++ return str; ++} ++ ++const char *fdt_get_board_revision(void) ++{ ++ const void *fdt = gd->fdt_blob; ++ int node, len = 64; ++ const char *str = NULL; ++ ++ node = fdt_get_bdk_node(); ++ if (!node) ++ return NULL; ++ ++ str = fdt_getprop(fdt, node, "BOARD-REVISION", &len); ++ if (!str) ++ printf("Error: cannot retrieve board revision from fdt\n"); ++ return str; ++} ++ ++const char *fdt_get_board_model(void) ++{ ++ const void *fdt = gd->fdt_blob; ++ int node, len = 16; ++ const char *str = NULL; ++ ++ node = fdt_get_bdk_node(); ++ if (!node) ++ return NULL; ++ ++ str = fdt_getprop(fdt, node, "BOARD-MODEL", &len); ++ if (!str) ++ printf("Error: cannot retrieve board model from fdt\n"); ++ return str; ++} ++ ++void fdt_board_get_ethaddr(int bgx, int lmac, unsigned char *eth) ++{ ++ const void *fdt = gd->fdt_blob; ++ const char *mac = NULL; ++ int offset = 0, node, len; ++ int subnode, i = 0; ++ char bgxname[24]; ++ ++ offset = fdt_node_offset_by_compatible(fdt, -1, "pci-bridge"); ++ if (offset < 0) { ++ printf("%s couldn't find mrml bridge node in fdt\n", ++ __func__); ++ return; ++ } ++ if (bgx == 2 && otx_is_soc(CN81XX)) { ++ snprintf(bgxname, sizeof(bgxname), "rgx%d", 0); ++ lmac = 0; ++ } else { ++ snprintf(bgxname, sizeof(bgxname), "bgx%d", bgx); ++ } ++ ++ node = fdt_subnode_offset(fdt, offset, bgxname); ++ ++ fdt_for_each_subnode(subnode, fdt, node) { ++ if (i++ != lmac) ++ continue; ++ /* check for local-mac-address */ ++ mac = fdt_getprop(fdt, subnode, "local-mac-address", &len); ++ if (mac) { ++ debug("%s mac %pM\n", __func__, mac); ++ memcpy(eth, mac, ARP_HLEN); ++ } else { ++ memset(eth, 0, ARP_HLEN); ++ } ++ debug("%s eth %pM\n", __func__, eth); ++ return; ++ } ++} ++ ++#ifdef ALLOW_USER_MAC_ADDR ++void fdt_board_update_macaddr(int bgxid, int lmacid, char *mac) ++{ ++ void *fdt = (void *)gd->fdt_blob; ++ int offset = 0, node; ++ int subnode, i = 0; ++ char bgxname[24], macaddr[ARP_HLEN]; ++ ++ offset = fdt_node_offset_by_compatible(fdt, -1, "pci-bridge"); ++ if (offset < 0) { ++ printf("%s couldn't find mrml bridge node in fdt\n", ++ __func__); ++ return; ++ } ++ if (bgxid == 2 && otx_is_soc(CN81XX)) { ++ snprintf(bgxname, sizeof(bgxname), "rgx%d", 0); ++ lmacid = 0; ++ } else { ++ snprintf(bgxname, sizeof(bgxname), "bgx%d", bgxid); ++ } ++ ++ node = fdt_subnode_offset(fdt, offset, bgxname); ++ ++ memcpy(macaddr, mac, ARP_HLEN); ++ fdt_for_each_subnode(subnode, fdt, node) { ++ /* update lmac node's local-mac-address */ ++ if (i++ == lmacid) ++ fdt_setprop(fdt, subnode, "local-mac-address", ++ (void *)macaddr, sizeof(macaddr)); ++ } ++} ++#endif ++ ++int arch_fixup_memory_node(void *blob) ++{ ++ return 0; ++} ++ ++int ft_board_setup(void *blob, bd_t *bd) ++{ ++ /* remove "cavium, bdk" node from DT */ ++ int ret = 0, offset; ++ ++ ret = fdt_check_header(blob); ++ if (ret < 0) { ++ printf("ERROR: %s\n", fdt_strerror(ret)); ++ return ret; ++ } ++ ++ if (blob) { ++ offset = fdt_path_offset(blob, "/cavium,bdk"); ++ if (offset < 0) { ++ printf("ERROR: FDT BDK node not found\n"); ++ return offset; ++ } ++ ++ /* delete node */ ++ ret = fdt_del_node(blob, offset); ++ if (ret < 0) { ++ printf("WARNING : could not remove bdk node\n"); ++ return ret; ++ } ++ ++ debug("%s deleted bdk node\n", __func__); ++ } ++ ++ return 0; ++} ++ ++/** ++ * Return the FDT base address that was passed by ATF ++ * ++ * @return FDT base address received from ATF in x1 register ++ */ ++void *board_fdt_blob_setup(void) ++{ ++ return (void *)fdt_base_addr; ++} +diff --git a/board/Marvell/octeontx/board.c b/board/Marvell/octeontx/board.c +new file mode 100644 +index 0000000000..123d35d2cc +--- /dev/null ++++ b/board/Marvell/octeontx/board.c +@@ -0,0 +1,321 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++#define BOOTCMD_NAME "pci-bootcmd" ++#define CONSOLE_NAME "pci-console@0" ++ ++extern unsigned long fdt_base_addr; ++ ++void octeontx_cleanup_ethaddr(void) ++{ ++ char ename[32]; ++ ++ for (int i = 0; i < 20; i++) { ++ sprintf(ename, i ? "eth%daddr" : "ethaddr", i); ++ if (env_get(ename)) ++ env_set(ename, NULL); ++ } ++} ++ ++int octeontx_board_has_pmp(void) ++{ ++ return (otx_is_board("sff8104") || otx_is_board("nas8104")); ++} ++ ++int board_early_init_r(void) ++{ ++ pci_init(); ++ return 0; ++} ++ ++int board_init(void) ++{ ++#ifdef CONFIG_NET_OCTEONTX ++ fdt_parse_phy_info(); ++#endif ++ return 0; ++} ++ ++int timer_init(void) ++{ ++ return 0; ++} ++ ++int dram_init(void) ++{ ++ gd->ram_size = smc_dram_size(0); ++ gd->ram_size -= CONFIG_SYS_SDRAM_BASE; ++ mem_map_fill(); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_NET_OCTEONTX ++void board_late_probe_devices(void) ++{ ++ struct udevice *dev; ++ int err, bgx_cnt, i; ++ ++ /* Probe MAC(BGX) and NIC PF devices before Network stack init */ ++ bgx_cnt = otx_is_soc(CN81XX) ? 2 : 4; ++ for (i = 0; i < bgx_cnt; i++) { ++ err = dm_pci_find_device(PCI_VENDOR_ID_CAVIUM, 0xA026, i, ++ &dev); ++ if (err) ++ debug("%s BGX%d device not found\n", __func__, i); ++ } ++ if (otx_is_soc(CN81XX)) { ++ err = dm_pci_find_device(PCI_VENDOR_ID_CAVIUM, 0xA054, 0, ++ &dev); ++ if (err) ++ debug("%s RGX device not found\n", __func__); ++ } ++ err = dm_pci_find_device(PCI_VENDOR_ID_CAVIUM, 0xA01E, 0, &dev); ++ if (err) ++ debug("NIC PF device not found\n"); ++} ++#endif ++ ++#if (CONFIG_IS_ENABLED(OCTEONTX_SERIAL_BOOTCMD) || \ ++ CONFIG_IS_ENABLED(OCTEONTX_SERIAL_PCIE_CONSOLE)) && \ ++ !CONFIG_IS_ENABLED(CONSOLE_MUX) ++# error CONFIG_CONSOLE_MUX must be enabled! ++#endif ++ ++#if CONFIG_IS_ENABLED(OCTEONTX_SERIAL_BOOTCMD) ++static int init_bootcmd_console(void) ++{ ++ int ret = 0; ++ char *stdinname = env_get("stdin"); ++ struct udevice *bootcmd_dev = NULL; ++ bool stdin_set; ++ char iomux_name[128]; ++ ++ debug("%s: stdin before: %s\n", __func__, ++ stdinname ? stdinname : "NONE"); ++ if (!stdinname) { ++ env_set("stdin", "serial"); ++ stdinname = env_get("stdin"); ++ } ++ stdin_set = !!strstr(stdinname, BOOTCMD_NAME); ++ ret = uclass_get_device_by_driver(UCLASS_SERIAL, ++ DM_GET_DRIVER(octeontx_bootcmd), ++ &bootcmd_dev); ++ if (ret) { ++ pr_err("%s: Error getting %s serial class\n", __func__, ++ BOOTCMD_NAME); ++ } else if (bootcmd_dev) { ++ if (stdin_set) ++ strncpy(iomux_name, stdinname, sizeof(iomux_name)); ++ else ++ snprintf(iomux_name, sizeof(iomux_name), "%s,%s", ++ stdinname, bootcmd_dev->name); ++ ret = iomux_doenv(stdin, iomux_name); ++ if (ret) ++ pr_err("%s: Error %d enabling the PCI bootcmd input console \"%s\"\n", ++ __func__, ret, iomux_name); ++ if (!stdin_set) ++ env_set("stdin", iomux_name); ++ } ++ debug("%s: Set iomux and stdin to %s (ret: %d)\n", ++ __func__, iomux_name, ret); ++ return ret; ++} ++#endif ++ ++#if CONFIG_IS_ENABLED(OCTEONTX_SERIAL_PCIE_CONSOLE) ++static int init_pcie_console(void) ++{ ++ int ret = 0; ++ char *stdinname = env_get("stdin"); ++ char *stdoutname = env_get("stdout"); ++ char *stderrname = env_get("stderr"); ++ struct udevice *pcie_console_dev = NULL; ++ bool stdin_set, stdout_set, stderr_set; ++ char iomux_name[128]; ++ ++ debug("%s: stdin: %s, stdout: %s, stderr: %s\n", __func__, stdinname, ++ stdoutname, stderrname); ++ if (!stdinname) { ++ env_set("stdin", "serial"); ++ stdinname = env_get("stdin"); ++ } ++ if (!stdoutname) { ++ env_set("stdout", "serial"); ++ stdoutname = env_get("stdout"); ++ } ++ if (!stderrname) { ++ env_set("stderr", "serial"); ++ stderrname = env_get("stderr"); ++ } ++ ++ if (!stdinname || !stdoutname || !stderrname) { ++ printf("%s: Error setting environment variables for serial\n", ++ __func__); ++ return -1; ++ } ++ ++ stdin_set = !!strstr(stdinname, CONSOLE_NAME); ++ stdout_set = !!strstr(stdoutname, CONSOLE_NAME); ++ stderr_set = !!strstr(stderrname, CONSOLE_NAME); ++ ++ pr_debug("stdin: %d, \"%s\", stdout: %d, \"%s\", stderr: %d, \"%s\"\n", ++ stdin_set, stdinname, stdout_set, stdoutname, ++ stderr_set, stderrname); ++ ret = uclass_get_device_by_name(UCLASS_SERIAL, CONSOLE_NAME, ++ &pcie_console_dev); ++ if (ret || !pcie_console_dev) { ++ debug("%s: No PCI console device %s found\n", __func__, ++ CONSOLE_NAME); ++ return 0; ++ } ++ ++ if (stdin_set) ++ strncpy(iomux_name, stdinname, sizeof(iomux_name)); ++ else ++ snprintf(iomux_name, sizeof(iomux_name), "%s,%s", ++ stdinname, pcie_console_dev->name); ++ ++ ret = iomux_doenv(stdin, iomux_name); ++ if (ret) { ++ pr_err("%s: Error setting I/O stdin MUX to %s\n", ++ __func__, iomux_name); ++ return ret; ++ } ++ ++ if (!stdin_set) ++ env_set("stdin", iomux_name); ++ ++ if (stdout_set) ++ strncpy(iomux_name, stdoutname, sizeof(iomux_name)); ++ else ++ snprintf(iomux_name, sizeof(iomux_name), "%s,%s", stdoutname, ++ pcie_console_dev->name); ++ ++ ret = iomux_doenv(stdout, iomux_name); ++ if (ret) { ++ pr_err("%s: Error setting I/O stdout MUX to %s\n", ++ __func__, iomux_name); ++ return ret; ++ } ++ if (!stdout_set) ++ env_set("stdout", iomux_name); ++ ++ if (stderr_set) ++ strncpy(iomux_name, stderrname, sizeof(iomux_name)); ++ else ++ snprintf(iomux_name, sizeof(iomux_name), "%s,%s", stderrname, ++ pcie_console_dev->name); ++ ++ ret = iomux_doenv(stderr, iomux_name); ++ if (ret) { ++ pr_err("%s: Error setting I/O stderr MUX to %s\n", ++ __func__, iomux_name); ++ return ret; ++ } ++ ++ if (!stderr_set) ++ env_set("stderr", iomux_name); ++ ++ debug("%s: stdin: %s, stdout: %s, stderr: %s, ret: %d\n", ++ __func__, env_get("stdin"), env_get("stdout"), ++ env_get("stderr"), ret); ++ ++ return ret; ++} ++#endif ++ ++/** ++ * Board late initialization routine. ++ */ ++int board_late_init(void) ++{ ++ char boardname[32]; ++ char boardserial[150], boardrev[150]; ++ bool save_env = false; ++ const char *str; ++ ++ /* ++ * Try to cleanup ethaddr env variables, this is needed ++ * as with each boot, configuration of network interfaces can change. ++ */ ++ octeontx_cleanup_ethaddr(); ++ ++ snprintf(boardname, sizeof(boardname), "%s> ", fdt_get_board_model()); ++ env_set("prompt", boardname); ++ ++ set_working_fdt_addr(env_get_hex("fdtcontroladdr", fdt_base_addr)); ++ ++ str = fdt_get_board_revision(); ++ if (str) { ++ snprintf(boardrev, sizeof(boardrev), "%s", str); ++ if (env_get("boardrev") && ++ strcmp(boardrev, env_get("boardrev"))) ++ save_env = true; ++ env_set("boardrev", boardrev); ++ } ++ ++ str = fdt_get_board_serial(); ++ if (str) { ++ snprintf(boardserial, sizeof(boardserial), "%s", str); ++ if (env_get("serial#") && ++ strcmp(boardserial, env_get("serial#"))) ++ save_env = true; ++ env_set("serial#", boardserial); ++ } ++ ++#ifdef CONFIG_NET_OCTEONTX ++ board_late_probe_devices(); ++#endif ++#if CONFIG_IS_ENABLED(OCTEONTX_SERIAL_BOOTCMD) ++ if (init_bootcmd_console()) ++ printf("Failed to init bootcmd input\n"); ++#endif ++#if CONFIG_IS_ENABLED(OCTEONTX_SERIAL_PCIE_CONSOLE) ++ if (init_pcie_console()) ++ printf("Failed to init pci console\n"); ++#endif ++ if (save_env) ++ env_save(); ++ return 0; ++} ++ ++/* ++ * Invoked before relocation, so limit to stack variables. ++ */ ++int show_board_info(void) ++{ ++ char *str = NULL; ++ ++ if (otx_is_soc(CN81XX)) ++ str = "CN81XX"; ++ if (otx_is_soc(CN83XX)) ++ str = "CN83XX"; ++ printf("OcteonTX %s ARM V8 Core\n", str); ++ ++ printf("Board: %s\n", fdt_get_board_model()); ++ ++ return 0; ++} +diff --git a/board/Marvell/octeontx/smc.c b/board/Marvell/octeontx/smc.c +new file mode 100644 +index 0000000000..e74f6794fa +--- /dev/null ++++ b/board/Marvell/octeontx/smc.c +@@ -0,0 +1,29 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++ ++#include ++#include ++ ++#include ++ ++#include ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++ssize_t smc_dram_size(unsigned int node) ++{ ++ struct pt_regs regs; ++ ++ regs.regs[0] = OCTEONTX_DRAM_SIZE; ++ regs.regs[1] = node; ++ smc_call(®s); ++ ++ return regs.regs[0]; ++} +diff --git a/board/Marvell/octeontx/soc-utils.c b/board/Marvell/octeontx/soc-utils.c +new file mode 100644 +index 0000000000..33f8ae27c9 +--- /dev/null ++++ b/board/Marvell/octeontx/soc-utils.c +@@ -0,0 +1,60 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++platform_t read_platform(void) ++{ ++ platform_t plat = PLATFORM_HW; ++ ++ const char *model = fdt_get_board_model(); ++ ++ if (model && !strncmp(model, "ASIM-", 5)) ++ plat = PLATFORM_ASIM; ++ if (model && !strncmp(model, "EMUL-", 5)) ++ plat = PLATFORM_EMULATOR; ++ return plat; ++} ++ ++static inline u64 read_midr(void) ++{ ++ u64 result; ++ ++ asm ("mrs %[rd],MIDR_EL1" : [rd] "=r" (result)); ++ return result; ++} ++ ++u8 read_partnum(void) ++{ ++ return ((read_midr() >> 4) & 0xFF); ++} ++ ++const char *read_board_name(void) ++{ ++ return fdt_get_board_model(); ++} ++ ++bool read_alt_pkg(void) ++{ ++ union mio_fus_dat2 fus_dat2; ++ ++ fus_dat2.u = readq(MIO_FUS_DAT2); ++ if (fus_dat2.s.chip_id >> 6) ++ return true; ++ /* Some parts only have lmc_mode32 set */ ++ if (read_partnum() == CN81XX && fus_dat2.s.lmc_mode32) ++ return true; ++ return false; ++} +diff --git a/board/Marvell/octeontx2/Kconfig b/board/Marvell/octeontx2/Kconfig +new file mode 100644 +index 0000000000..ff09050f5a +--- /dev/null ++++ b/board/Marvell/octeontx2/Kconfig +@@ -0,0 +1,18 @@ ++if TARGET_OCTEONTX2_95XX || TARGET_OCTEONTX2_96XX || TARGET_OCTEONTX2_LOKI || TARGET_OCTEONTX2_98XX || TARGET_OCTEONTX2_95MM ++ ++config SYS_VENDOR ++ string ++ default "Marvell" ++ ++config SYS_BOARD ++ string ++ default "octeontx2" ++ ++config SYS_CONFIG_NAME ++ default "octeontx2_96xx" if TARGET_OCTEONTX2_96XX ++ default "octeontx2_95xx" if TARGET_OCTEONTX2_95XX ++ default "octeontx2_loki" if TARGET_OCTEONTX2_LOKI ++ default "octeontx2_98xx" if TARGET_OCTEONTX2_98XX ++ default "octeontx2_95mm" if TARGET_OCTEONTX2_95MM ++ ++endif +diff --git a/board/Marvell/octeontx2/MAINTAINERS b/board/Marvell/octeontx2/MAINTAINERS +new file mode 100644 +index 0000000000..73026ccdc6 +--- /dev/null ++++ b/board/Marvell/octeontx2/MAINTAINERS +@@ -0,0 +1,9 @@ ++OCTEONTX2 BOARD ++M: Suneel Garapati ++M: Aaron Williams ++S: Maintained ++F: board/Marvell/octeontx2/ ++F: include/configs/octeontx2_96xx.h ++F: include/configs/octeontx2_95xx.h ++F: configs/octeontx2_96xx_defconfig ++F: configs/octeontx2_95xx_defconfig +diff --git a/board/Marvell/octeontx2/Makefile b/board/Marvell/octeontx2/Makefile +new file mode 100644 +index 0000000000..1f763b197b +--- /dev/null ++++ b/board/Marvell/octeontx2/Makefile +@@ -0,0 +1,9 @@ ++#/* SPDX-License-Identifier: GPL-2.0 ++# * ++# * Copyright (C) 2018 Marvell International Ltd. ++# * ++# * https://spdx.org/licenses ++# */ ++ ++obj-y := board.o smc.o soc-utils.o ++obj-$(CONFIG_OF_LIBFDT) += board-fdt.o +diff --git a/board/Marvell/octeontx2/board-fdt.c b/board/Marvell/octeontx2/board-fdt.c +new file mode 100644 +index 0000000000..c975bcdf71 +--- /dev/null ++++ b/board/Marvell/octeontx2/board-fdt.c +@@ -0,0 +1,221 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++extern unsigned long fdt_base_addr; ++ ++static int fdt_get_bdk_node(void) ++{ ++ int node, ret; ++ const void *fdt = gd->fdt_blob; ++ ++ if (!fdt) { ++ printf("ERROR: %s: no valid device tree found\n", __func__); ++ return 0; ++ } ++ ++ ret = fdt_check_header(fdt); ++ if (ret < 0) { ++ printf("fdt: %s\n", fdt_strerror(ret)); ++ return 0; ++ } ++ ++ node = fdt_path_offset(fdt, "/cavium,bdk"); ++ if (node < 0) { ++ printf("%s: /cavium,bdk is missing from device tree: %s\n", ++ __func__, fdt_strerror(node)); ++ return 0; ++ } ++ return node; ++} ++ ++u64 fdt_get_board_mac_addr(void) ++{ ++ int node, len = 16; ++ const char *str = NULL; ++ const void *fdt = gd->fdt_blob; ++ u64 mac_addr = 0; ++ ++ node = fdt_get_bdk_node(); ++ if (!node) ++ return mac_addr; ++ str = fdt_getprop(fdt, node, "BOARD-MAC-ADDRESS", &len); ++ if (str) ++ mac_addr = simple_strtol(str, NULL, 16); ++ return mac_addr; ++} ++ ++int fdt_get_board_mac_cnt(void) ++{ ++ int node, len = 16; ++ const char *str = NULL; ++ const void *fdt = gd->fdt_blob; ++ int mac_count = 0; ++ ++ node = fdt_get_bdk_node(); ++ if (!node) ++ return mac_count; ++ str = fdt_getprop(fdt, node, "BOARD-MAC-ADDRESS-NUM", &len); ++ if (str) { ++ mac_count = simple_strtol(str, NULL, 10); ++ if (!mac_count) ++ mac_count = simple_strtol(str, NULL, 16); ++ debug("fdt: MAC_NUM %d\n", mac_count); ++ } else { ++ printf("Error: cannot retrieve mac count prop from fdt\n"); ++ } ++ str = fdt_getprop(gd->fdt_blob, node, "BOARD-MAC-ADDRESS-NUM-OVERRIDE", ++ &len); ++ if (str) { ++ if (simple_strtol(str, NULL, 10) >= 0) ++ mac_count = simple_strtol(str, NULL, 10); ++ debug("fdt: MAC_NUM %d\n", mac_count); ++ } else { ++ printf("Error: cannot retrieve mac num override prop\n"); ++ } ++ return mac_count; ++} ++ ++const char *fdt_get_board_serial(void) ++{ ++ const void *fdt = gd->fdt_blob; ++ int node, len = 64; ++ const char *str = NULL; ++ ++ node = fdt_get_bdk_node(); ++ if (!node) ++ return NULL; ++ ++ str = fdt_getprop(fdt, node, "BOARD-SERIAL", &len); ++ if (!str) ++ printf("Error: cannot retrieve board serial from fdt\n"); ++ return str; ++} ++ ++const char *fdt_get_board_revision(void) ++{ ++ const void *fdt = gd->fdt_blob; ++ int node, len = 64; ++ const char *str = NULL; ++ ++ node = fdt_get_bdk_node(); ++ if (!node) ++ return NULL; ++ ++ str = fdt_getprop(fdt, node, "BOARD-REVISION", &len); ++ if (!str) ++ printf("Error: cannot retrieve board revision from fdt\n"); ++ return str; ++} ++ ++const char *fdt_get_board_model(void) ++{ ++ int node, len = 16; ++ const char *str = NULL; ++ const void *fdt = gd->fdt_blob; ++ ++ node = fdt_get_bdk_node(); ++ if (!node) ++ return NULL; ++ str = fdt_getprop(fdt, node, "BOARD-MODEL", &len); ++ if (!str) ++ printf("Error: cannot retrieve board model from fdt\n"); ++ return str; ++} ++ ++int arch_fixup_memory_node(void *blob) ++{ ++ return 0; ++} ++ ++int ft_board_setup(void *blob, bd_t *bd) ++{ ++ int nodeoff, node, ret, i; ++ const char *temp; ++ ++ static const char * const ++ octeontx_brd_nodes[] = {"BOARD-MODEL", ++ "BOARD-SERIAL", ++ "BOARD-MAC-ADDRESS", ++ "BOARD-REVISION", ++ "BOARD-MAC-ADDRESS-NUM" ++ }; ++ char nodes[ARRAY_SIZE(octeontx_brd_nodes)][32]; ++ ++ ret = fdt_check_header(blob); ++ if (ret < 0) { ++ printf("ERROR: %s\n", fdt_strerror(ret)); ++ return ret; ++ } ++ ++ if (blob) { ++ nodeoff = fdt_path_offset(blob, "/cavium,bdk"); ++ if (nodeoff < 0) { ++ printf("ERROR: FDT BDK node not found\n"); ++ return nodeoff; ++ } ++ ++ /* Read properties in temporary variables */ ++ for (i = 0; i < ARRAY_SIZE(octeontx_brd_nodes); i++) { ++ temp = fdt_getprop(blob, nodeoff, ++ octeontx_brd_nodes[i], NULL); ++ strncpy(nodes[i], temp, sizeof(nodes[i])); ++ } ++ ++ /* Delete cavium,bdk node */ ++ ret = fdt_del_node(blob, nodeoff); ++ if (ret < 0) { ++ printf("WARNING : could not remove cavium, bdk node\n"); ++ return ret; ++ } ++ debug("%s deleted 'cavium,bdk' node\n", __func__); ++ /* ++ * Add a new node at root level which would have ++ * necessary info ++ */ ++ node = fdt_add_subnode(blob, 0, "octeontx_brd"); ++ if (node < 0) { ++ printf("Cannot create node octeontx_brd: %s\n", ++ fdt_strerror(node)); ++ return -EIO; ++ } ++ ++ /* Populate properties in node */ ++ for (i = 0; i < ARRAY_SIZE(octeontx_brd_nodes); i++) { ++ if (fdt_setprop_string(blob, node, ++ octeontx_brd_nodes[i], ++ nodes[i])) { ++ printf("Can't set %s\n", nodes[i]); ++ return -EIO; ++ } ++ } ++ } ++ ++ return 0; ++} ++/** ++ * Return the FDT base address that was passed by ATF ++ * ++ * @return FDT base address received from ATF in x1 register ++ */ ++void *board_fdt_blob_setup(void) ++{ ++ return (void *)fdt_base_addr; ++} +diff --git a/board/Marvell/octeontx2/board.c b/board/Marvell/octeontx2/board.c +new file mode 100644 +index 0000000000..39eca2349f +--- /dev/null ++++ b/board/Marvell/octeontx2/board.c +@@ -0,0 +1,441 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++#define BOOTCMD_NAME "pci-bootcmd" ++#define CONSOLE_NAME "pci-console@0" ++ ++extern unsigned long fdt_base_addr; ++extern void cgx_intf_shutdown(void); ++ ++void cleanup_env_ethaddr(void) ++{ ++ char ename[32]; ++ ++ for (int i = 0; i < 20; i++) { ++ sprintf(ename, i ? "eth%daddr" : "ethaddr", i); ++ if (env_get(ename)) ++ env_set(ename, NULL); ++ } ++} ++ ++void octeontx2_board_get_mac_addr(u8 index, u8 *mac_addr) ++{ ++ u64 tmp_mac, board_mac_addr = fdt_get_board_mac_addr(); ++ static int board_mac_num; ++ ++ board_mac_num = fdt_get_board_mac_cnt(); ++ if ((!is_zero_ethaddr((u8 *)&board_mac_addr)) && board_mac_num) { ++ tmp_mac = board_mac_addr; ++ tmp_mac += index; ++ tmp_mac = swab64(tmp_mac) >> 16; ++ memcpy(mac_addr, (u8 *)&tmp_mac, ARP_HLEN); ++ board_mac_num--; ++ } else { ++ memset(mac_addr, 0, ARP_HLEN); ++ } ++ debug("%s mac %pM\n", __func__, mac_addr); ++} ++ ++void board_get_env_spi_bus_cs(int *bus, int *cs) ++{ ++ const void *blob = gd->fdt_blob; ++ int env_bus, env_cs; ++ int node, preg; ++ ++ env_bus = -1; ++ env_cs = -1; ++ node = fdt_node_offset_by_compatible(blob, -1, "spi-flash"); ++ while (node > 0) { ++ if (fdtdec_get_bool(blob, node, "u-boot,env")) { ++ env_cs = fdtdec_get_int(blob, node, "reg", -1); ++ preg = fdtdec_get_int(blob, ++ fdt_parent_offset(blob, node), ++ "reg", -1); ++ /* SPI node will have PCI addr, so map it */ ++ if (preg == 0x3000) ++ env_bus = 0; ++ if (preg == 0x3800) ++ env_bus = 1; ++ debug("\n Env SPI [bus:cs] [%d:%d]\n", ++ env_bus, env_cs); ++ break; ++ } ++ node = fdt_node_offset_by_compatible(blob, node, "spi-flash"); ++ } ++ if (env_bus == -1) ++ debug("\'u-boot,env\' property not found in fdt\n"); ++ ++ *bus = env_bus; ++ *cs = env_cs; ++} ++ ++void board_quiesce_devices(void) ++{ ++ struct uclass *uc_dev; ++ int ret; ++ ++ /* Removes all RVU PF devices */ ++ ret = uclass_get(UCLASS_ETH, &uc_dev); ++ if (uc_dev) ++ ret = uclass_destroy(uc_dev); ++ if (ret) ++ printf("couldn't remove rvu pf devices\n"); ++ ++#ifdef CONFIG_OCTEONTX2_CGX_INTF ++ /* Bring down all cgx lmac links */ ++ cgx_intf_shutdown(); ++#endif ++ ++ /* Removes all CGX and RVU AF devices */ ++ ret = uclass_get(UCLASS_MISC, &uc_dev); ++ if (uc_dev) ++ ret = uclass_destroy(uc_dev); ++ if (ret) ++ printf("couldn't remove misc (cgx/rvu_af) devices\n"); ++ ++ /* SMC call - removes all LF<->PF mappings */ ++ smc_disable_rvu_lfs(0); ++} ++ ++int board_early_init_r(void) ++{ ++ pci_init(); ++ return 0; ++} ++ ++int board_init(void) ++{ ++ return 0; ++} ++ ++int timer_init(void) ++{ ++ return 0; ++} ++ ++int dram_init(void) ++{ ++ gd->ram_size = smc_dram_size(0); ++ gd->ram_size -= CONFIG_SYS_SDRAM_BASE; ++ ++ mem_map_fill(); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_NET_OCTEONTX2 ++void board_late_probe_devices(void) ++{ ++ struct udevice *dev; ++ int err, cgx_cnt, i; ++ ++ switch (read_partnum()) { ++ case CN98XX: ++ cgx_cnt = 5; ++ break; ++ case F95MM: ++ cgx_cnt = 2; ++ break; ++ case LOKI: ++ cgx_cnt = 4; ++ break; ++ default: ++ cgx_cnt = 3; ++ break; ++ } ++ /* Probe MAC(CGX) and NIC AF devices before Network stack init */ ++ for (i = 0; i < cgx_cnt; i++) { ++ err = dm_pci_find_device(PCI_VENDOR_ID_CAVIUM, 0xA059, i, ++ &dev); ++ if (err) ++ debug("%s CGX%d device not found\n", __func__, i); ++ } ++ err = dm_pci_find_device(PCI_VENDOR_ID_CAVIUM, 0xA065, 0, &dev); ++ if (err) ++ debug("NIC AF device not found\n"); ++} ++#endif ++ ++#if (CONFIG_IS_ENABLED(OCTEONTX_SERIAL_BOOTCMD) || \ ++ CONFIG_IS_ENABLED(OCTEONTX_SERIAL_PCIE_CONSOLE)) && \ ++ !CONFIG_IS_ENABLED(CONSOLE_MUX) ++# error CONFIG_CONSOLE_MUX must be enabled! ++#endif ++ ++#if CONFIG_IS_ENABLED(OCTEONTX_SERIAL_BOOTCMD) ++static int init_bootcmd_console(void) ++{ ++ int ret = 0; ++ char *stdinname = env_get("stdin"); ++ struct udevice *bootcmd_dev = NULL; ++ bool stdin_set; ++ char iomux_name[128]; ++ ++ debug("%s: stdin before: %s\n", __func__, ++ stdinname ? stdinname : "NONE"); ++ if (!stdinname) { ++ env_set("stdin", "serial"); ++ stdinname = env_get("stdin"); ++ } ++ stdin_set = !!strstr(stdinname, BOOTCMD_NAME); ++ ret = uclass_get_device_by_driver(UCLASS_SERIAL, ++ DM_GET_DRIVER(octeontx_bootcmd), ++ &bootcmd_dev); ++ if (ret) { ++ pr_err("%s: Error getting %s serial class\n", __func__, ++ BOOTCMD_NAME); ++ } else if (bootcmd_dev) { ++ if (stdin_set) ++ strncpy(iomux_name, stdinname, sizeof(iomux_name)); ++ else ++ snprintf(iomux_name, sizeof(iomux_name), "%s,%s", ++ stdinname, bootcmd_dev->name); ++ ret = iomux_doenv(stdin, iomux_name); ++ if (ret) ++ pr_err("%s: Error %d enabling the PCI bootcmd input console \"%s\"\n", ++ __func__, ret, iomux_name); ++ if (!stdin_set) ++ env_set("stdin", iomux_name); ++ } ++ debug("%s: Set iomux and stdin to %s (ret: %d)\n", ++ __func__, iomux_name, ret); ++ return ret; ++} ++#endif ++ ++#if CONFIG_IS_ENABLED(OCTEONTX_SERIAL_PCIE_CONSOLE) ++static int init_pcie_console(void) ++{ ++ int ret = 0; ++ char *stdinname = env_get("stdin"); ++ char *stdoutname = env_get("stdout"); ++ char *stderrname = env_get("stderr"); ++ struct udevice *pcie_console_dev = NULL; ++ bool stdin_set, stdout_set, stderr_set; ++ char iomux_name[128]; ++ ++ debug("%s: stdin: %s, stdout: %s, stderr: %s\n", __func__, stdinname, ++ stdoutname, stderrname); ++ if (!stdinname) { ++ env_set("stdin", "serial"); ++ stdinname = env_get("stdin"); ++ } ++ if (!stdoutname) { ++ env_set("stdout", "serial"); ++ stdoutname = env_get("stdout"); ++ } ++ if (!stderrname) { ++ env_set("stderr", "serial"); ++ stderrname = env_get("stderr"); ++ } ++ ++ if (!stdinname || !stdoutname || !stderrname) { ++ printf("%s: Error setting environment variables for serial\n", ++ __func__); ++ return -1; ++ } ++ ++ stdin_set = !!strstr(stdinname, CONSOLE_NAME); ++ stdout_set = !!strstr(stdoutname, CONSOLE_NAME); ++ stderr_set = !!strstr(stderrname, CONSOLE_NAME); ++ ++ pr_debug("stdin: %d, \"%s\", stdout: %d, \"%s\", stderr: %d, \"%s\"\n", ++ stdin_set, stdinname, stdout_set, stdoutname, ++ stderr_set, stderrname); ++ ret = uclass_get_device_by_name(UCLASS_SERIAL, CONSOLE_NAME, ++ &pcie_console_dev); ++ if (ret || !pcie_console_dev) { ++ debug("%s: No PCI console device %s found\n", __func__, ++ CONSOLE_NAME); ++ return 0; ++ } ++ ++ if (stdin_set) ++ strncpy(iomux_name, stdinname, sizeof(iomux_name)); ++ else ++ snprintf(iomux_name, sizeof(iomux_name), "%s,%s", ++ stdinname, pcie_console_dev->name); ++ ++ ret = iomux_doenv(stdin, iomux_name); ++ if (ret) { ++ pr_err("%s: Error setting I/O stdin MUX to %s\n", ++ __func__, iomux_name); ++ return ret; ++ } ++ ++ if (!stdin_set) ++ env_set("stdin", iomux_name); ++ ++ if (stdout_set) ++ strncpy(iomux_name, stdoutname, sizeof(iomux_name)); ++ else ++ snprintf(iomux_name, sizeof(iomux_name), "%s,%s", stdoutname, ++ pcie_console_dev->name); ++ ++ ret = iomux_doenv(stdout, iomux_name); ++ if (ret) { ++ pr_err("%s: Error setting I/O stdout MUX to %s\n", ++ __func__, iomux_name); ++ return ret; ++ } ++ if (!stdout_set) ++ env_set("stdout", iomux_name); ++ ++ if (stderr_set) ++ strncpy(iomux_name, stderrname, sizeof(iomux_name)); ++ else ++ snprintf(iomux_name, sizeof(iomux_name), "%s,%s", stderrname, ++ pcie_console_dev->name); ++ ++ ret = iomux_doenv(stderr, iomux_name); ++ if (ret) { ++ pr_err("%s: Error setting I/O stderr MUX to %s\n", ++ __func__, iomux_name); ++ return ret; ++ } ++ ++ if (!stderr_set) ++ env_set("stderr", iomux_name); ++ ++ debug("%s: stdin: %s, stdout: %s, stderr: %s, ret: %d\n", ++ __func__, env_get("stdin"), env_get("stdout"), ++ env_get("stderr"), ret); ++ ++ return ret; ++} ++#endif ++ ++/** ++ * Board late initialization routine. ++ */ ++int board_late_init(void) ++{ ++ char boardname[32]; ++ char boardserial[150], boardrev[150]; ++ long val; ++ bool save_env = false; ++ const char *str; ++ ++ debug("%s()\n", __func__); ++ ++ /* ++ * Now that pci_init initializes env device. ++ * Try to cleanup ethaddr env variables, this is needed ++ * as with each boot, configuration of QLM can change. ++ */ ++ cleanup_env_ethaddr(); ++ ++ snprintf(boardname, sizeof(boardname), "%s> ", fdt_get_board_model()); ++ env_set("prompt", boardname); ++ set_working_fdt_addr(env_get_hex("fdtcontroladdr", fdt_base_addr)); ++ ++ str = fdt_get_board_revision(); ++ if (str) { ++ snprintf(boardrev, sizeof(boardrev), "%s", str); ++ if (env_get("boardrev") && ++ strcmp(boardrev, env_get("boardrev"))) ++ save_env = true; ++ env_set("boardrev", boardrev); ++ } ++ ++ str = fdt_get_board_serial(); ++ if (str) { ++ snprintf(boardserial, sizeof(boardserial), "%s", str); ++ if (env_get("serial#") && ++ strcmp(boardserial, env_get("serial#"))) ++ save_env = true; ++ env_set("serial#", boardserial); ++ } ++ ++ val = env_get_hex("disable_ooo", 0); ++ smc_configure_ooo(val); ++ ++#ifdef CONFIG_NET_OCTEONTX2 ++ board_late_probe_devices(); ++#endif ++ ++#if CONFIG_IS_ENABLED(OCTEONTX_SERIAL_BOOTCMD) ++ if (init_bootcmd_console()) ++ printf("Failed to init bootcmd input\n"); ++#endif ++#if CONFIG_IS_ENABLED(OCTEONTX_SERIAL_PCIE_CONSOLE) ++ if (init_pcie_console()) ++ printf("Failed to init pci console\n"); ++#endif ++ if (save_env) ++ env_save(); ++ ++ return 0; ++} ++ ++/* ++ * Invoked before relocation, so limit to stack variables. ++ */ ++int show_board_info(void) ++{ ++ char *str = NULL; ++ ++ if (otx_is_soc(CN96XX)) ++ str = "CN96XX"; ++ if (otx_is_soc(CN95XX)) ++ str = "CN95XX"; ++ if (otx_is_soc(LOKI)) ++ str = "LOKI"; ++ if (otx_is_soc(CN98XX)) ++ str = "CN98XX"; ++ if (otx_is_soc(F95MM)) ++ str = "F95MM"; ++ printf("OcteonTX2 %s ARM V8 Core\n", str); ++ ++ printf("Board: %s\n", fdt_get_board_model()); ++ ++ return 0; ++} ++ ++void acquire_flash_arb(bool acquire) ++{ ++ union cpc_boot_ownerx ownerx; ++ ++ if (!acquire) { ++ ownerx.u = readl(CPC_BOOT_OWNERX(3)); ++ ownerx.s.boot_req = 0; ++ writel(ownerx.u, CPC_BOOT_OWNERX(3)); ++ } else { ++ ownerx.u = 0; ++ ownerx.s.boot_req = 1; ++ writel(ownerx.u, CPC_BOOT_OWNERX(3)); ++ udelay(1); ++ do { ++ ownerx.u = readl(CPC_BOOT_OWNERX(3)); ++ } while (ownerx.s.boot_wait); ++ } ++} ++ ++#ifdef CONFIG_LAST_STAGE_INIT ++int last_stage_init(void) ++{ ++ (void)smc_flsf_fw_booted(); ++ return 0; ++} ++#endif +diff --git a/board/Marvell/octeontx2/smc.c b/board/Marvell/octeontx2/smc.c +new file mode 100644 +index 0000000000..3ae428d726 +--- /dev/null ++++ b/board/Marvell/octeontx2/smc.c +@@ -0,0 +1,142 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++ ++#include ++#include ++ ++#include ++ ++#include ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++ssize_t smc_dram_size(unsigned int node) ++{ ++ struct pt_regs regs; ++ ++ regs.regs[0] = OCTEONTX2_DRAM_SIZE; ++ regs.regs[1] = node; ++ smc_call(®s); ++ ++ return regs.regs[0]; ++} ++ ++ssize_t smc_disable_rvu_lfs(unsigned int node) ++{ ++ struct pt_regs regs; ++ ++ regs.regs[0] = OCTEONTX2_DISABLE_RVU_LFS; ++ regs.regs[1] = node; ++ smc_call(®s); ++ ++ return regs.regs[0]; ++} ++ ++ssize_t smc_configure_ooo(unsigned int val) ++{ ++ struct pt_regs regs; ++ ++ regs.regs[0] = OCTEONTX2_CONFIG_OOO; ++ regs.regs[1] = val; ++ smc_call(®s); ++ ++ return regs.regs[0]; ++} ++ ++ssize_t smc_flsf_fw_booted(void) ++{ ++ struct pt_regs regs; ++ ++ regs.regs[0] = OCTEONTX2_FSAFE_PR_BOOT_SUCCESS; ++ smc_call(®s); ++ ++ return regs.regs[0]; ++} ++ ++ssize_t smc_flsf_clr_force_2ndry(void) ++{ ++ struct pt_regs regs; ++ ++ regs.regs[0] = OCTEONTX2_FSAFE_CLR_FORCE_SEC; ++ smc_call(®s); ++ ++ return regs.regs[0]; ++} ++ ++ssize_t smc_mdio_dbg_read(int cgx_lmac, int mode, int phyaddr, int devad, ++ int reg) ++{ ++ struct pt_regs regs; ++ ++ regs.regs[0] = OCTEONTX2_MDIO_DBG_READ; ++ regs.regs[1] = cgx_lmac; ++ regs.regs[2] = mode; ++ regs.regs[3] = phyaddr; ++ regs.regs[4] = devad; ++ regs.regs[5] = reg; ++ smc_call(®s); ++ ++ return regs.regs[0]; ++} ++ ++ssize_t smc_mdio_dbg_write(int cgx_lmac, int mode, int phyaddr, int devad, ++ int reg, int val) ++{ ++ struct pt_regs regs; ++ ++ regs.regs[0] = OCTEONTX2_MDIO_DBG_WRITE; ++ regs.regs[1] = cgx_lmac; ++ regs.regs[2] = mode; ++ regs.regs[3] = phyaddr; ++ regs.regs[4] = devad; ++ regs.regs[5] = reg; ++ regs.regs[6] = val; ++ smc_call(®s); ++ ++ return regs.regs[0]; ++} ++ ++/* ++ * on entry, ++ * subcmd: one of OCTEONTX_ATTESTATION_QUERY_SUBCMD_xxx ++ * ctx_arg: subcmd-specific argument ++ * ++ * returns, ++ * signed value: <0 - error code ++ * 0 - success ++ */ ++#ifdef CONFIG_CMD_ATTEST ++ssize_t smc_attest(long subcmd, long ctx_arg) ++{ ++ struct pt_regs regs; ++ ++ regs.regs[0] = OCTEONTX_ATTESTATION_QUERY; ++ regs.regs[1] = ctx_arg; ++ regs.regs[2] = subcmd; ++ ++ switch (subcmd) { ++ /* deprecated sub-command */ ++ case OCTEONTX_ATTESTATION_QUERY_SUBCMD_LEGACY: ++ return -1; ++ ++ case OCTEONTX_ATTESTATION_QUERY_SUBCMD_BUFFER: ++ case OCTEONTX_ATTESTATION_QUERY_SUBCMD_INFO: ++ /* no args */ ++ break; ++ ++ default: ++ return -1; ++ } ++ ++ smc_call(®s); ++ ++ return regs.regs[0]; ++} ++#endif // CONFIG_CMD_ATTEST +diff --git a/board/Marvell/octeontx2/soc-utils.c b/board/Marvell/octeontx2/soc-utils.c +new file mode 100644 +index 0000000000..7fc7ae7e90 +--- /dev/null ++++ b/board/Marvell/octeontx2/soc-utils.c +@@ -0,0 +1,53 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++platform_t read_platform(void) ++{ ++ platform_t plat = PLATFORM_HW; ++ ++ const char *model = fdt_get_board_model(); ++ ++ if (model && !strncmp(model, "ASIM-", 5)) ++ plat = PLATFORM_ASIM; ++ if (model && !strncmp(model, "EMUL-", 5)) ++ plat = PLATFORM_EMULATOR; ++ ++ return plat; ++} ++ ++static inline u64 read_midr(void) ++{ ++ u64 result; ++ ++ asm ("mrs %[rd],MIDR_EL1" : [rd] "=r" (result)); ++ return result; ++} ++ ++u8 read_partvar(void) ++{ ++ return ((read_midr() >> 20) & 0xF); ++} ++ ++u8 read_partnum(void) ++{ ++ return ((read_midr() >> 4) & 0xFF); ++} ++ ++const char *read_board_name(void) ++{ ++ return fdt_get_board_model(); ++} +diff --git a/board/Marvell/octeontx2_cn913x/MAINTAINERS b/board/Marvell/octeontx2_cn913x/MAINTAINERS +new file mode 100644 +index 0000000000..9e390a22b1 +--- /dev/null ++++ b/board/Marvell/octeontx2_cn913x/MAINTAINERS +@@ -0,0 +1,4 @@ ++OCTEONTX2_CN913x BOARD ++F: board/Marvell/octeontx2_cn913x/ ++F: include/configs/octeontx2_cn913x.h ++F: configs/mvebu_db_cn91xx_defconfig +diff --git a/board/Marvell/octeontx2_cn913x/Makefile b/board/Marvell/octeontx2_cn913x/Makefile +new file mode 100644 +index 0000000000..8c6ffb9328 +--- /dev/null ++++ b/board/Marvell/octeontx2_cn913x/Makefile +@@ -0,0 +1,8 @@ ++# ++# Copyright (C) 2016 Stefan Roese ++# Copyright (C) 2019 Marvell International Ltd. ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++obj-y := board.o +diff --git a/board/Marvell/octeontx2_cn913x/board.c b/board/Marvell/octeontx2_cn913x/board.c +new file mode 100644 +index 0000000000..00b475769b +--- /dev/null ++++ b/board/Marvell/octeontx2_cn913x/board.c +@@ -0,0 +1,121 @@ ++/* ++ * Copyright (C) 2016 Stefan Roese ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0+ ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef CONFIG_BOARD_CONFIG_EEPROM ++#include ++#endif ++ ++#define CP_USB20_BASE_REG(cp, p) (MVEBU_REGS_BASE_CP(0, cp) + \ ++ 0x00580000 + 0x1000 * (p)) ++#define CP_USB20_TX_CTRL_REG(cp, p) (CP_USB20_BASE_REG(cp, p) + 0xC) ++#define CP_USB20_TX_OUT_AMPL_MASK (0x7 << 20) ++#define CP_USB20_TX_OUT_AMPL_VALUE (0x3 << 20) ++ ++DECLARE_GLOBAL_DATA_PTR; ++ ++#define BOOTCMD_NAME "pci-bootcmd" ++ ++int __soc_early_init_f(void) ++{ ++ return 0; ++} ++ ++int soc_early_init_f(void) ++ __attribute__((weak, alias("__soc_early_init_f"))); ++ ++int board_early_init_f(void) ++{ ++ soc_early_init_f(); ++ ++ return 0; ++} ++ ++int board_early_init_r(void) ++{ ++#ifdef CONFIG_DM_REGULATOR ++ /* Check if any existing regulator should be turned down */ ++ regulators_enable_boot_off(false); ++#endif ++ ++ return 0; ++} ++ ++int board_init(void) ++{ ++ /* address of boot parameters */ ++ gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; ++ ++#ifdef CONFIG_BOARD_CONFIG_EEPROM ++ cfg_eeprom_init(); ++#endif ++ ++ return 0; ++} ++ ++#if (CONFIG_IS_ENABLED(OCTEONTX_SERIAL_BOOTCMD) || \ ++ CONFIG_IS_ENABLED(OCTEONTX_SERIAL_PCIE_CONSOLE)) && \ ++ !CONFIG_IS_ENABLED(CONSOLE_MUX) ++# error CONFIG_CONSOLE_MUX must be enabled! ++#endif ++ ++#if CONFIG_IS_ENABLED(OCTEONTX_SERIAL_BOOTCMD) ++static int init_bootcmd_console(void) ++{ ++ int ret = 0; ++ char *stdinname = env_get("stdin"); ++ struct udevice *bootcmd_dev = NULL; ++ bool stdin_set; ++ char iomux_name[128]; ++ ++ debug("%s: stdin before: %s\n", __func__, ++ stdinname ? stdinname : "NONE"); ++ if (!stdinname) { ++ env_set("stdin", "serial"); ++ stdinname = env_get("stdin"); ++ } ++ stdin_set = !!strstr(stdinname, BOOTCMD_NAME); ++ ret = uclass_get_device_by_driver(UCLASS_SERIAL, ++ DM_GET_DRIVER(octeontx_bootcmd), ++ &bootcmd_dev); ++ if (ret) { ++ pr_err("%s: Error getting %s serial class\n", __func__, ++ BOOTCMD_NAME); ++ } else if (bootcmd_dev) { ++ if (stdin_set) ++ strncpy(iomux_name, stdinname, sizeof(iomux_name)); ++ else ++ snprintf(iomux_name, sizeof(iomux_name), "%s,%s", ++ stdinname, bootcmd_dev->name); ++ ret = iomux_doenv(stdin, iomux_name); ++ if (ret) ++ pr_err("%s: Error %d enabling the PCI bootcmd input console \"%s\"\n", ++ __func__, ret, iomux_name); ++ if (!stdin_set) ++ env_set("stdin", iomux_name); ++ } ++ debug("%s: Set iomux and stdin to %s (ret: %d)\n", ++ __func__, iomux_name, ret); ++ return ret; ++} ++#endif ++ ++int board_late_init(void) ++{ ++#if CONFIG_IS_ENABLED(OCTEONTX_SERIAL_BOOTCMD) ++ if (init_bootcmd_console()) ++ printf("Failed to init bootcmd input\n"); ++#endif ++ return 0; ++} +diff --git a/board/cavium/thunderx/Kconfig b/board/cavium/thunderx/Kconfig +deleted file mode 100644 +index 927d8765d6..0000000000 +--- a/board/cavium/thunderx/Kconfig ++++ /dev/null +@@ -1,27 +0,0 @@ +-if TARGET_THUNDERX_88XX +- +-config SYS_CPU +- string +- default "armv8" +- +-config SYS_BOARD +- string +- default "thunderx" +- +-config SYS_VENDOR +- string +- default "cavium" +- +-config SYS_CONFIG_NAME +- string +- default "thunderx_88xx" +- +-config CMD_ATF +- bool "Enable ATF query commands" +- default y +- help +- Enable vendor specific ATF query commands such as SPI and SD/MMC +- devices access, low level environment query, boot device layout +- and node count. +- +-endif +diff --git a/board/cavium/thunderx/MAINTAINERS b/board/cavium/thunderx/MAINTAINERS +deleted file mode 100644 +index c84d3b553d..0000000000 +--- a/board/cavium/thunderx/MAINTAINERS ++++ /dev/null +@@ -1,6 +0,0 @@ +-THUNDERX BOARD +-M: Sergey Temerkhanov +-S: Maintained +-F: board/cavium/thunderx/ +-F: include/configs/thunderx_88xx.h +-F: configs/thunderx_88xx_defconfig +diff --git a/board/cavium/thunderx/Makefile b/board/cavium/thunderx/Makefile +deleted file mode 100644 +index 4088c7678d..0000000000 +--- a/board/cavium/thunderx/Makefile ++++ /dev/null +@@ -1,6 +0,0 @@ +-# SPDX-License-Identifier: GPL-2.0+ +-# (C) Copyright 2014, Cavium Inc. +-# +-# +- +-obj-y := thunderx.o atf.o +diff --git a/board/cavium/thunderx/atf.c b/board/cavium/thunderx/atf.c +deleted file mode 100644 +index 2e7ba69d76..0000000000 +--- a/board/cavium/thunderx/atf.c ++++ /dev/null +@@ -1,309 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0+ +-/** +- * (C) Copyright 2014, Cavium Inc. +-**/ +- +-#include +-#include +- +-#include +-#include +-#include +-#include +- +-#include +- +-#include +- +-ssize_t atf_read_mmc(uintptr_t offset, void *buffer, size_t size) +-{ +- struct pt_regs regs; +- regs.regs[0] = THUNDERX_MMC_READ; +- regs.regs[1] = offset; +- regs.regs[2] = size; +- regs.regs[3] = (uintptr_t)buffer; +- +- smc_call(®s); +- +- return regs.regs[0]; +-} +- +-ssize_t atf_read_nor(uintptr_t offset, void *buffer, size_t size) +-{ +- struct pt_regs regs; +- regs.regs[0] = THUNDERX_NOR_READ; +- regs.regs[1] = offset; +- regs.regs[2] = size; +- regs.regs[3] = (uintptr_t)buffer; +- +- smc_call(®s); +- +- return regs.regs[0]; +-} +- +-ssize_t atf_get_pcount(void) +-{ +- struct pt_regs regs; +- regs.regs[0] = THUNDERX_PART_COUNT; +- +- smc_call(®s); +- +- return regs.regs[0]; +-} +- +-ssize_t atf_get_part(struct storage_partition *part, unsigned int index) +-{ +- struct pt_regs regs; +- regs.regs[0] = THUNDERX_GET_PART; +- regs.regs[1] = (uintptr_t)part; +- regs.regs[2] = index; +- +- smc_call(®s); +- +- return regs.regs[0]; +-} +- +-ssize_t atf_erase_nor(uintptr_t offset, size_t size) +-{ +- struct pt_regs regs; +- +- regs.regs[0] = THUNDERX_NOR_ERASE; +- regs.regs[1] = offset; +- +- smc_call(®s); +- +- return regs.regs[0]; +-} +- +-ssize_t atf_write_nor(uintptr_t offset, const void *buffer, size_t size) +-{ +- struct pt_regs regs; +- +- regs.regs[0] = THUNDERX_NOR_WRITE; +- regs.regs[1] = offset; +- regs.regs[2] = size; +- regs.regs[3] = (uintptr_t)buffer; +- +- smc_call(®s); +- +- return regs.regs[0]; +-} +- +-ssize_t atf_write_mmc(uintptr_t offset, const void *buffer, size_t size) +-{ +- struct pt_regs regs; +- +- regs.regs[0] = THUNDERX_MMC_WRITE; +- regs.regs[1] = offset; +- regs.regs[2] = size; +- regs.regs[3] = (uintptr_t)buffer; +- +- smc_call(®s); +- +- return regs.regs[0]; +-} +- +-ssize_t atf_dram_size(unsigned int node) +-{ +- struct pt_regs regs; +- regs.regs[0] = THUNDERX_DRAM_SIZE; +- regs.regs[1] = node; +- +- smc_call(®s); +- +- return regs.regs[0]; +-} +- +-ssize_t atf_node_count(void) +-{ +- struct pt_regs regs; +- regs.regs[0] = THUNDERX_NODE_COUNT; +- +- smc_call(®s); +- +- return regs.regs[0]; +-} +- +-ssize_t atf_env_count(void) +-{ +- struct pt_regs regs; +- regs.regs[0] = THUNDERX_ENV_COUNT; +- +- smc_call(®s); +- +- return regs.regs[0]; +-} +- +-ssize_t atf_env_string(size_t index, char *str) +-{ +- uint64_t *buf = (void *)str; +- struct pt_regs regs; +- regs.regs[0] = THUNDERX_ENV_STRING; +- regs.regs[1] = index; +- +- smc_call(®s); +- +- if (regs.regs > 0) { +- buf[0] = regs.regs[0]; +- buf[1] = regs.regs[1]; +- buf[2] = regs.regs[2]; +- buf[3] = regs.regs[3]; +- +- return 1; +- } else { +- return regs.regs[0]; +- } +-} +- +-#ifdef CONFIG_CMD_ATF +- +-static void atf_print_ver(void) +-{ +- struct pt_regs regs; +- regs.regs[0] = ARM_STD_SVC_VERSION; +- +- smc_call(®s); +- +- printf("ARM Std FW version: %ld.%ld\n", regs.regs[0], regs.regs[1]); +- +- regs.regs[0] = THUNDERX_SVC_VERSION; +- +- smc_call(®s); +- +- printf("ThunderX OEM ver: %ld.%ld\n", regs.regs[0], regs.regs[1]); +-} +- +-static void atf_print_uid(void) +-{ +-} +- +-static void atf_print_part_table(void) +-{ +- size_t pcount; +- unsigned long i; +- int ret; +- char *ptype; +- +- struct storage_partition *part = (void *)CONFIG_SYS_LOWMEM_BASE; +- +- pcount = atf_get_pcount(); +- +- printf("Partition count: %lu\n\n", pcount); +- printf("%10s %10s %10s\n", "Type", "Size", "Offset"); +- +- for (i = 0; i < pcount; i++) { +- ret = atf_get_part(part, i); +- +- if (ret < 0) { +- printf("Uknown error while reading partition: %d\n", +- ret); +- return; +- } +- +- switch (part->type) { +- case PARTITION_NBL1FW_REST: +- ptype = "NBL1FW"; +- break; +- case PARTITION_BL2_BL31: +- ptype = "BL2_BL31"; +- break; +- case PARTITION_UBOOT: +- ptype = "BOOTLDR"; +- break; +- case PARTITION_KERNEL: +- ptype = "KERNEL"; +- break; +- case PARTITION_DEVICE_TREE: +- ptype = "DEVTREE"; +- break; +- default: +- ptype = "UNKNOWN"; +- } +- printf("%10s %10d %10lx\n", ptype, part->size, part->offset); +- } +-} +- +-int do_atf(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +-{ +- ssize_t ret; +- size_t size, offset; +- void *buffer = 0; +- unsigned int index, node; +- char str[4 * sizeof(uint64_t)]; +- +- if ((argc == 5) && !strcmp(argv[1], "readmmc")) { +- buffer = (void *)simple_strtoul(argv[2], NULL, 16); +- offset = simple_strtoul(argv[3], NULL, 10); +- size = simple_strtoul(argv[4], NULL, 10); +- +- ret = atf_read_mmc(offset, buffer, size); +- } else if ((argc == 5) && !strcmp(argv[1], "readnor")) { +- buffer = (void *)simple_strtoul(argv[2], NULL, 16); +- offset = simple_strtoul(argv[3], NULL, 10); +- size = simple_strtoul(argv[4], NULL, 10); +- +- ret = atf_read_nor(offset, buffer, size); +- } else if ((argc == 5) && !strcmp(argv[1], "writemmc")) { +- buffer = (void *)simple_strtoul(argv[2], NULL, 16); +- offset = simple_strtoul(argv[3], NULL, 10); +- size = simple_strtoul(argv[4], NULL, 10); +- +- ret = atf_write_mmc(offset, buffer, size); +- } else if ((argc == 5) && !strcmp(argv[1], "writenor")) { +- buffer = (void *)simple_strtoul(argv[2], NULL, 16); +- offset = simple_strtoul(argv[3], NULL, 10); +- size = simple_strtoul(argv[4], NULL, 10); +- +- ret = atf_write_nor(offset, buffer, size); +- } else if ((argc == 2) && !strcmp(argv[1], "part")) { +- atf_print_part_table(); +- } else if ((argc == 4) && !strcmp(argv[1], "erasenor")) { +- offset = simple_strtoul(argv[2], NULL, 10); +- size = simple_strtoul(argv[3], NULL, 10); +- +- ret = atf_erase_nor(offset, size); +- } else if ((argc == 2) && !strcmp(argv[1], "envcount")) { +- ret = atf_env_count(); +- printf("Number of environment strings: %zd\n", ret); +- } else if ((argc == 3) && !strcmp(argv[1], "envstring")) { +- index = simple_strtoul(argv[2], NULL, 10); +- ret = atf_env_string(index, str); +- if (ret > 0) +- printf("Environment string %d: %s\n", index, str); +- else +- printf("Return code: %zd\n", ret); +- } else if ((argc == 3) && !strcmp(argv[1], "dramsize")) { +- node = simple_strtoul(argv[2], NULL, 10); +- ret = atf_dram_size(node); +- printf("DRAM size: %zd Mbytes\n", ret >> 20); +- } else if ((argc == 2) && !strcmp(argv[1], "nodes")) { +- ret = atf_node_count(); +- printf("Nodes count: %zd\n", ret); +- } else if ((argc == 2) && !strcmp(argv[1], "ver")) { +- atf_print_ver(); +- } else if ((argc == 2) && !strcmp(argv[1], "uid")) { +- atf_print_uid(); +- } else { +- return CMD_RET_USAGE; +- } +- +- return 0; +-} +- +-U_BOOT_CMD( +- atf, 10, 1, do_atf, +- "issue calls to ATF", +- "\t readmmc addr offset size - read MMC card\n" +- "\t readnor addr offset size - read NOR flash\n" +- "\t writemmc addr offset size - write MMC card\n" +- "\t writenor addr offset size - write NOR flash\n" +- "\t erasenor offset size - erase NOR flash\n" +- "\t nodes - number of nodes\n" +- "\t dramsize node - size of DRAM attached to node\n" +- "\t envcount - number of environment strings\n" +- "\t envstring index - print the environment string\n" +- "\t part - print MMC partition table\n" +- "\t ver - print ATF call set versions\n" +-); +- +-#endif +diff --git a/board/cavium/thunderx/thunderx.c b/board/cavium/thunderx/thunderx.c +deleted file mode 100644 +index cf55b633c3..0000000000 +--- a/board/cavium/thunderx/thunderx.c ++++ /dev/null +@@ -1,128 +0,0 @@ +-// SPDX-License-Identifier: GPL-2.0+ +-/** +- * (C) Copyright 2014, Cavium Inc. +-**/ +- +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +- +-#if !CONFIG_IS_ENABLED(OF_CONTROL) +-#include +- +-static const struct pl01x_serial_platdata serial0 = { +- .base = CONFIG_SYS_SERIAL0, +- .type = TYPE_PL011, +- .clock = 0, +- .skip_init = true, +-}; +- +-U_BOOT_DEVICE(thunderx_serial0) = { +- .name = "serial_pl01x", +- .platdata = &serial0, +-}; +- +-static const struct pl01x_serial_platdata serial1 = { +- .base = CONFIG_SYS_SERIAL1, +- .type = TYPE_PL011, +- .clock = 0, +- .skip_init = true, +-}; +- +-U_BOOT_DEVICE(thunderx_serial1) = { +- .name = "serial_pl01x", +- .platdata = &serial1, +-}; +-#endif +- +-DECLARE_GLOBAL_DATA_PTR; +- +-static struct mm_region thunderx_mem_map[] = { +- { +- .virt = 0x000000000000UL, +- .phys = 0x000000000000UL, +- .size = 0x40000000000UL, +- .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_NON_SHARE, +- }, { +- .virt = 0x800000000000UL, +- .phys = 0x800000000000UL, +- .size = 0x40000000000UL, +- .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | +- PTE_BLOCK_NON_SHARE, +- }, { +- .virt = 0x840000000000UL, +- .phys = 0x840000000000UL, +- .size = 0x40000000000UL, +- .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | +- PTE_BLOCK_NON_SHARE, +- }, { +- /* List terminator */ +- 0, +- } +-}; +- +-struct mm_region *mem_map = thunderx_mem_map; +- +-int board_init(void) +-{ +- return 0; +-} +- +-int timer_init(void) +-{ +- return 0; +-} +- +-int dram_init(void) +-{ +- ssize_t node_count = atf_node_count(); +- ssize_t dram_size; +- int node; +- +- printf("Initializing\nNodes in system: %zd\n", node_count); +- +- gd->ram_size = 0; +- +- for (node = 0; node < node_count; node++) { +- dram_size = atf_dram_size(node); +- printf("Node %d: %zd MBytes of DRAM\n", node, dram_size >> 20); +- gd->ram_size += dram_size; +- } +- +- gd->ram_size -= MEM_BASE; +- +- *(unsigned long *)CPU_RELEASE_ADDR = 0; +- +- puts("DRAM size:"); +- +- return 0; +-} +- +-/* +- * Board specific reset that is system reset. +- */ +-void reset_cpu(ulong addr) +-{ +-} +- +-/* +- * Board specific ethernet initialization routine. +- */ +-int board_eth_init(bd_t *bis) +-{ +- int rc = 0; +- +- return rc; +-} +- +-#ifdef CONFIG_PCI +-void pci_init_board(void) +-{ +- printf("DEBUG: PCI Init TODO *****\n"); +-} +-#endif +diff --git a/board/raspberrypi/rpi/rpi.c b/board/raspberrypi/rpi/rpi.c +index 9e0abdda31..98a07deaa4 100644 +--- a/board/raspberrypi/rpi/rpi.c ++++ b/board/raspberrypi/rpi/rpi.c +@@ -516,6 +516,16 @@ void *board_fdt_blob_setup(void) + return (void *)fw_dtb_pointer; + } + ++/* ++ * If the firmware passed a device tree use it for U-Boot. ++ */ ++void *board_fdt_blob_setup(void) ++{ ++ if (fdt_magic(fw_dtb_pointer) != FDT_MAGIC) ++ return NULL; ++ return (void *)fw_dtb_pointer; ++} ++ + int ft_board_setup(void *blob, bd_t *bd) + { + /* +diff --git a/cmd/Kconfig b/cmd/Kconfig +index a87bcfffbb..1ccd09aead 100644 +--- a/cmd/Kconfig ++++ b/cmd/Kconfig +@@ -188,6 +188,13 @@ comment "Commands" + + menu "Info commands" + ++config CMD_MVEBU_SAR ++ bool "sar" ++ depends on MVEBU_SAR ++ default n ++ help ++ sar - Modify SOC's sample at reset (SAR) values ++ + config CMD_BDI + bool "bdinfo" + default y +@@ -1393,6 +1400,15 @@ config BOOTP_PREFER_SERVERIP + takes precedence over DHCP server IP and will only be set by the DHCP + server if not already set in the environment. + ++config BOOTP_TFTP_SERVERIP ++ bool "Allow DHCP server to specify tftp server address" ++ depends on CMD_BOOTP ++ default y ++ help ++ With this option enabled, the DHCP server can specify the IP address ++ of a TFTP server to load images from by using option 150 as specified ++ in RFC5859. ++ + config BOOTP_SUBNETMASK + bool "Request & store 'netmask' from BOOTP/DHCP server" + default y +@@ -1680,6 +1696,7 @@ config CMD_QFW + via -kernel / -initrd + + source "cmd/mvebu/Kconfig" ++source "cmd/marvell/Kconfig" + + config CMD_TERMINAL + bool "terminal - provides a way to attach a serial terminal" +diff --git a/cmd/Makefile b/cmd/Makefile +index c10f2e308b..5aef55249c 100644 +--- a/cmd/Makefile ++++ b/cmd/Makefile +@@ -178,6 +178,10 @@ obj-$(CONFIG_RISCV) += riscv/ + obj-$(CONFIG_X86) += x86/ + + obj-$(CONFIG_ARCH_MVEBU) += mvebu/ ++ ++obj-$(CONFIG_ARCH_OCTEONTX2) += marvell/ ++obj-$(CONFIG_ARCH_OCTEONTX) += marvell/ ++ + endif # !CONFIG_SPL_BUILD + + obj-$(CONFIG_$(SPL_)CMD_TLV_EEPROM) += tlv_eeprom.o +diff --git a/cmd/fdt.c b/cmd/fdt.c +index 25a6ed40d2..92fece9ecb 100644 +--- a/cmd/fdt.c ++++ b/cmd/fdt.c +@@ -1090,7 +1090,8 @@ static int fdt_print(const char *pathp, char *prop, int depth) + } + break; + case FDT_NOP: +- printf("%s/* NOP */\n", &tabs[MAX_LEVEL - level]); ++ if (!env_get("fdt_hide_nop")) ++ printf("%s/* NOP */\n", &tabs[MAX_LEVEL - level]); + break; + case FDT_END: + return 1; +diff --git a/cmd/marvell/Kconfig b/cmd/marvell/Kconfig +new file mode 100644 +index 0000000000..27d1293d6c +--- /dev/null ++++ b/cmd/marvell/Kconfig +@@ -0,0 +1,41 @@ ++menu "Marvell specific command line interface" ++ ++config CMD_FAILSAFE ++ depends on ARCH_OCTEONTX2 ++ bool "Command for supporting fail safe boot" ++ help ++ Support for fail safe boot on Marvell's OcteonTX2 platforms. ++ Disables forced secondary boot and reports if boot from ++ primary device was successful. ++ ++config CMD_ETH ++ depends on NET_OCTEONTX2 ++ bool "Command to change fec and phy-mod type" ++ help ++ Support for change of fec and phy-mod type for some specific ++ LMAC modes on RVU PF [CGX] network interfaces on Marvell ++ OcteonTX2 platforms. ++ ++config CMD_MDIO_DBG ++ depends on ARCH_OCTEONTX2 ++ bool "PHY registers read/write support on mdio bus" ++ help ++ Support to debug phy registers over MDIO bus using SMC interface ++ to ATF for RVU PF [CGX] network interfaces on Marvell OcteonTX2 ++ platforms. ++ ++config CMD_ATTEST ++ depends on ARCH_OCTEONTX2 ++ bool "Command for supporting Software Attestation" ++ help ++ Support for Software Attestation on Marvell's OcteonTX2 platforms. ++ Displays Secure Boot software component version information. ++ ++config CMD_BOOTIMGUP ++ depends on ARCH_OCTEONTX || ARCH_OCTEONTX2 ++ depends on MMC_OCTEONTX || SPI_FLASH ++ bool "bootimgup" ++ help ++ bootimgup command support ++ ++endmenu +diff --git a/cmd/marvell/Makefile b/cmd/marvell/Makefile +new file mode 100644 +index 0000000000..0f0bf73355 +--- /dev/null ++++ b/cmd/marvell/Makefile +@@ -0,0 +1,16 @@ ++# Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ ++# ++# SPDX-License-Identifier: GPL-2.0+ ++# ++ ++ifdef CONFIG_ARCH_OCTEONTX2 ++obj-$(CONFIG_CMD_BOOTIMGUP) += bootimgup.o ++obj-$(CONFIG_CMD_FAILSAFE) += octeontx2_failsafe_cmds.o ++obj-$(CONFIG_CMD_ETH) += eth_cmds.o ++obj-$(CONFIG_CMD_MDIO_DBG) += mdio_dbg.o ++obj-$(CONFIG_OCTEONTX2_CGX_INTF) += octeontx2_qlm_cmds.o ++obj-$(CONFIG_CMD_ATTEST) += octeontx2_attest_cmds.o ++endif ++ifdef CONFIG_ARCH_OCTEONTX ++obj-$(CONFIG_CMD_BOOTIMGUP) += bootimgup.o ++endif +diff --git a/cmd/marvell/bootimgup.c b/cmd/marvell/bootimgup.c +new file mode 100644 +index 0000000000..e9f8b4dc1a +--- /dev/null ++++ b/cmd/marvell/bootimgup.c +@@ -0,0 +1,1251 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Offsets and sizes to various structures in the image */ ++#define SCR_MAX_SIZE 0x40000 ++#define MAX_FW_SIZE 0x5C0000 ++#define MIN_SIZE 0x500000 ++#define INFO_SIZE 0x100 ++#define SIG_SIZE 0x100 ++#define AP_NB1FW_INFO 0x10000 ++#define SCP_NB1FW_INFO 0x10400 ++#define SCP_NB1FW_INFO_BLK (SCP_NB1FW_INFO / 512) ++#define SCP_TBL1FW_INFO 0x10600 ++#define SCP_TBL1FW_INFO_BLK (SCP_TBL1FW_INFO / 512) ++#define AP_NBL1FW_OPAQUE 0x20000 ++#define AP_NBL1FW_OPAQUE_SIZE 0x30000 ++#define AP_TBL1FW_OPAQUE 0x50000 ++#define AP_TBL1FW_OPAQUE_SIZE 0x30000 ++#define INFO_MAGIC "CVM_CLIB" ++#define INFO_MAGIC_SIZE 8 ++#define INFO_MAX_OFFSET 0x1000000 ++#define INFO_VERSION 0 ++#define AP_NBL1FW_HEADER "OCTEONTX" ++#define ATF_BL2_STAGE1 0x400000 /** uses bdk_header */ ++#define ATF_BL2_STAGE1_SIZE 0x40000 ++#define ATF_FIP_ADDRESS 0x440000 ++#define ATF_FIP_NAME 0xAA640001 ++ ++/** ++ * The BDK is located inAP_NBL1FW ++ */ ++struct bdk_header { ++ u32 skip_insn; ++ u32 length; /** Length, including header */ ++ char magic[8]; /** OCTEONTX */ ++ u32 crc32; /** CRC32 */ ++ u32 zero; ++ char name[64]; /** Zero terminated name */ ++ char version[32]; /** Zero terminated version */ ++ char pad[136]; ++}; ++ ++/** ROM Code Load Information-Block Structure, all fields are little-endian */ ++struct rom_clib { ++ u8 magic[8]; /** CVM_CLIB */ ++ u8 pad[7]; /** 0 */ ++ u8 ver; /** 0 */ ++ u64 offset; ++ u64 size; ++ u32 rom_script_size; ++ u32 rom_script_offset; ++ u32 rom_script_chksum; ++ u32 pad2[5]; ++ u64 csib_sig[8]; ++ u64 pad3[12]; ++}; ++ ++/** ++ * Information saved to later restore the buffer when preserving the ROM ++ * script area ++ * ++ * @param desc block descriptor if mmc is used ++ * @param flash SPI flash descriptor if flash is used ++ * @param bak_nb1fw_scr Pointer to backup of script in new image, ++ * NULL if not present. ++ * @param nb1fw_scr_size Size of SCP NB1FW script, 0 if not present ++ * @param nb1fw_scr_offset Offset of SCP NB1FW script in image ++ * @param bak_tbl1fw_scr Pointer to backup of script in new image, ++ * NULL if not present. ++ * @param tbl1fw_scr_size Size of SCP TBL1FW script, 0 if not present ++ * @param tbl1fw_scr_offset Offset of SCP TBL1FW script in image ++ * @param bak_scp_nb1fw_info SCP NB1FW INFO from new image ++ * @param bak_scp_tbl1fw_info SCP TBL1FW INFO from new image ++ */ ++struct rom_scr_info { ++ struct blk_desc *desc; ++ struct spi_flash *flash; ++ u8 *bak_nb1fw_scr; ++ u32 nb1fw_scr_size; ++ u32 nb1fw_scr_offset; ++ u8 *bak_tbl1fw_scr; ++ u32 tbl1fw_scr_size; ++ u32 tbl1fw_scr_offset; ++ struct rom_clib bak_scp_nb1fw_info; ++ struct rom_clib bak_scp_tbl1fw_info; ++}; ++ ++struct dos_partition { ++ unsigned char boot_ind; /* 0x80 - active */ ++ unsigned char head; /* starting head */ ++ unsigned char sector; /* starting sector */ ++ unsigned char cyl; /* starting cylinder */ ++ unsigned char sys_ind; /* What partition type */ ++ unsigned char end_head; /* end head */ ++ unsigned char end_sector; /* end sector */ ++ unsigned char end_cyl; /* end cylinder */ ++ unsigned int start4; /* starting sector counting from 0 */ ++ unsigned int size4; /* nr of sectors in partition */ ++}; ++ ++static struct spi_flash *flash; ++ ++/** ++ * Validates the BDK headers ++ * ++ * @param addr address of BDK image ++ * ++ * @return 0 for success or !0 for error ++ */ ++static int validate_bdk(unsigned long addr, size_t size) ++{ ++ struct bdk_header *bhdr = (struct bdk_header *)addr; ++ u32 crc; ++ const u32 zero = 0; ++ u32 len = le32_to_cpu(bhdr->length); ++ ++ if (len > size) { ++ printf("Invalid header length %#x for BDK type image at %#lx\n", ++ len, addr); ++ return 1; ++ } ++ ++ if (strncmp(bhdr->magic, AP_NBL1FW_HEADER, 8)) { ++ printf("%s: Invalid header \"%8s\"\n", __func__, bhdr->magic); ++ return 1; ++ } ++ crc = crc32(0, (u8 *)bhdr, 0x10); ++ crc = crc32(crc, (u8 *)&zero, sizeof(zero)); ++ crc = crc32(crc, (u8 *)&bhdr->zero, bhdr->length - 0x14); ++ debug("%s: calculated CRC: %#x, CRC: %#x, length: %#x\n", ++ __func__, crc, bhdr->crc32, bhdr->length); ++ return crc != bhdr->crc32; ++} ++ ++/** ++ * Validates a CLIB header ++ * ++ * @param addr address of CLIB header ++ * ++ * @return 0 for success, !0 for error ++ */ ++static int validate_clib(unsigned long addr) ++{ ++ struct rom_clib *clib = (struct rom_clib *)addr; ++ ++ if (memcmp(clib->magic, INFO_MAGIC, sizeof(clib->magic))) { ++ printf("Invalid CLIB magic value for CLIB at %#lx\n", addr); ++ return 1; ++ } ++ if (clib->ver != INFO_VERSION) { ++ printf("CLIB version %#x invalid, should be %#x\n", ++ clib->ver, INFO_VERSION); ++ return 1; ++ } ++ if (le32_to_cpu(clib->offset) + le32_to_cpu(clib->size) > ++ INFO_MAX_OFFSET) { ++ printf("Image offset %#llx and size %#llx out of range for CLIB at %#lx\n", ++ le64_to_cpu(clib->offset), le64_to_cpu(clib->size), ++ addr); ++ return 1; ++ } ++ if ((le32_to_cpu(clib->rom_script_offset) + ++ le32_to_cpu(clib->rom_script_size) > INFO_MAX_OFFSET) || ++ (le32_to_cpu(clib->rom_script_offset) % 512)) { ++ printf("Invalid CLIB ROM script offset %#x, size %#x for CLIP at %#lx\n", ++ le32_to_cpu(clib->rom_script_offset), ++ le32_to_cpu(clib->rom_script_size), addr); ++ return 1; ++ } ++ return 0; ++} ++ ++/** ++ * Validate a number of headers in the image to make sure it's sane ++ * ++ * @param addr Base address of the image ++ * ++ * @return 0 for success, !0 for error ++ */ ++static int validate_bootimg_header(unsigned long addr) ++{ ++ u32 fip_toc_header = *(u32 *)(addr + ATF_FIP_ADDRESS); ++ ++ if (validate_clib(addr + AP_NB1FW_INFO)) { ++ printf("%s: AP NB1FW INFO CLIB bad\n", __func__); ++ return 1; ++ } ++ if (validate_clib(addr + SCP_NB1FW_INFO)) { ++ printf("%s: SCP NB1FW INFO CLIB bad\n", __func__); ++ return 1; ++ } ++ if (validate_clib(addr + SCP_TBL1FW_INFO)) { ++ printf("%s: SCP TBL1FW INFO CLIB bad\n", __func__); ++ return 1; ++ } ++ ++ if (validate_bdk(addr + AP_NBL1FW_OPAQUE, AP_NBL1FW_OPAQUE_SIZE)) { ++ printf("Invalid BDK image at %#lx\n", addr + AP_NBL1FW_OPAQUE); ++ return 1; ++ } ++ if (validate_bdk(addr + AP_TBL1FW_OPAQUE, AP_TBL1FW_OPAQUE_SIZE)) { ++ printf("Invalid BDK image at %#lx\n", addr + AP_TBL1FW_OPAQUE); ++ return 1; ++ } ++ if (le32_to_cpu(fip_toc_header) != ATF_FIP_NAME) { ++ printf("Invalid FIP TOC header\n"); ++ return 1; ++ } ++ return 0; ++} ++ ++#if !CONFIG_IS_ENABLED(ARCH_OCTEONTX) ++/** ++ * Calculate checksum for ROM script ++ * ++ * @param[in] rom_script pointer to ROM script ++ * @param len length of script in bytes ++ * ++ * @return checksum of ROM script ++ */ ++static u32 scr_chksum(const void *rom_script, u32 len) ++{ ++ u32 csum = 0; ++ const u32 *ptr; ++ ++ debug("%s(%p, %u)\n", __func__, rom_script, len); ++ for (ptr = (u32 *)rom_script; ++ ptr < (u32 *)(rom_script + len); ++ ptr++) { ++ csum += le32_to_cpu(*ptr); ++ /* Wrap overflow. */ ++ csum += (csum < le32_to_cpu(*ptr)) ? 1 : 0; ++ } ++ debug("%s: csum: %#x, ptr: %p\n", __func__, csum, ptr); ++ return csum; ++} ++#endif ++ ++/** ++ * This function takes a byte length and a delta unit of time to compute the ++ * approximate bytes per second ++ * ++ * @param len amount of bytes currently processed ++ * @param start_ms start time of processing in ms ++ * @return bytes per second if OK, 0 on error ++ */ ++static ulong bytes_per_second(unsigned int len, ulong start_ms) ++{ ++ /* less accurate but avoids overflow */ ++ if (len >= ((unsigned int)-1) / 1024) ++ return len / (max(get_timer(start_ms) / 1024, 1UL)); ++ else ++ return 1024 * len / max(get_timer(start_ms), 1UL); ++} ++ ++/** ++ * Write a block of data to SPI flash, first checking if it is different from ++ * what is already there. ++ * ++ * If the data being written is the same, then *skipped is incremented by len. ++ * ++ * @param flash flash context pointer ++ * @param offset flash offset to write ++ * @param len number of bytes to write ++ * @param buf buffer to write from ++ * @return NULL if OK, else a string containing the stage which failed ++ */ ++static const char *spi_flash_update_block(struct spi_flash *flash, u32 offset, ++ size_t len, const char *buf, ++ char *cmp_buf) ++{ ++ char *ret = NULL; ++ char *ptr = (char *)buf; ++ char *rbuf = cmp_buf; ++ ++ /* Read the entire sector so to allow for rewriting */ ++ if (spi_flash_read(flash, offset, flash->sector_size, rbuf)) { ++ ret = "read"; ++ debug("%s: Read at offset %#x, len: %#lx\n", ++ __func__, offset, len); ++ goto error; ++ } ++ /* Compare only what is meaningful (len) */ ++ if (memcmp(rbuf, buf, len) == 0) { ++ return ret; ++ } ++ ++ /* Erase the entire sector */ ++ if (spi_flash_erase(flash, offset, flash->sector_size)) { ++ ret = "erase"; ++ goto error; ++ } ++ ++ /* Write one complete sector */ ++ if (spi_flash_write(flash, offset, len, ptr)) { ++ ret = "write"; ++ goto error; ++ } ++ ++ if (spi_flash_read(flash, offset, len, rbuf)) { ++ ret = "read"; ++ goto error; ++ } ++ ++ if (memcmp(ptr, rbuf, len)) { ++ ret = "compare"; ++ debug("%s: Comparison at offset %#x, len: %#lx\n", ++ __func__, offset, len); ++#ifdef DEBUG ++ debug("Written values:\n"); ++ print_buffer(offset, ptr, 1, min(len, 1024UL), 0); ++ debug("Read values:\n"); ++ print_buffer(offset, rbuf, 1, min(len, 1024UL), 0); ++#endif ++ } ++ ++error: ++ return ret; ++} ++ ++/** ++ * Update an area of SPI flash by erasing and writing any blocks which need ++ * to change. Existing blocks with the correct data are left unchanged. ++ * ++ * @param flash flash context pointer ++ * @param offset flash offset to write ++ * @param len number of bytes to write ++ * @param buf buffer to write from ++ * @return 0 if ok, 1 on error ++ */ ++static int spi_flash_update(struct spi_flash *flash, u32 offset, ++ size_t len, const char *buf) ++{ ++ const char *err_oper = NULL; ++ const char *end = buf + len; ++ size_t todo; /* number of bytes to do in this pass */ ++ const ulong start_time = get_timer(0); ++ size_t scale = 1; ++ const char *start_buf = buf; ++ char *cmp_buf; ++ ulong delta; ++ ++ if (end - buf >= 200) ++ scale = (end - buf) / 100; ++ cmp_buf = memalign(ARCH_DMA_MINALIGN, flash->sector_size); ++ if (!cmp_buf) { ++ printf("%s: Out of memory\n", __func__); ++ return 1; ++ } ++ ulong last_update = get_timer(0); ++ ++ for (; (buf < end) && (!err_oper); buf += todo, offset += todo) { ++ todo = min_t(size_t, end - buf, flash->sector_size); ++ if (get_timer(last_update) > 100) { ++ printf(" \rUpdating, %zu%% %lu B/s", ++ 100 - (end - buf) / scale, ++ bytes_per_second(buf - start_buf, ++ start_time)); ++ last_update = get_timer(0); ++ } ++ err_oper = spi_flash_update_block(flash, offset, todo, buf, ++ cmp_buf); ++ if (err_oper) ++ break; ++ } ++ free(cmp_buf); ++ putc('\r'); ++ if (err_oper) { ++ printf("SPI flash failed in %s step\n", err_oper); ++ return 1; ++ } ++ ++ delta = get_timer(start_time); ++ printf("%zu bytes written", len); ++ printf(" in %ld.%lds, speed %ld B/s\n", ++ delta / 1000, delta % 1000, bytes_per_second(len, start_time)); ++ ++ return 0; ++} ++ ++static int do_spi_flash_probe(unsigned int bus, unsigned int cs) ++{ ++ unsigned int speed = CONFIG_SF_DEFAULT_SPEED; ++ unsigned int mode = CONFIG_SF_DEFAULT_MODE; ++ struct udevice *new; ++ int ret; ++ ++ ret = spi_flash_probe_bus_cs(bus, cs, speed, mode, &new); ++ if (ret) { ++ printf("Failed to initialize SPI flash at %u:%u (error %d)\n", ++ bus, cs, ret); ++ return 1; ++ } ++ ++ flash = dev_get_uclass_priv(new); ++ ++ return flash ? 0 : 1; ++} ++ ++/** ++ * Converts a length into the number of mmc blocks ++ */ ++static inline size_t get_num_blocks(size_t len) ++{ ++ return DIV_ROUND_UP(len, 512); ++} ++ ++#if !CONFIG_IS_ENABLED(ARCH_OCTEONTX) ++/** ++ * Extract any ROM scripts present for the SCP NB1FW and SCP TBL1FW blocks ++ * ++ * @param[in] buf pointer to input buffer ++ * @param[out] scp_nb1fw_info data structure with the NB1FW CLIB ++ * @param[out] scp_nb1fw Pointer to buffer with ROM script ++ * or NULL if no NB1FW ROM script. ++ * @param[out] scp_nb1fw_size size of firmware, 0 if no firmware ++ * @param[out] scp_nb1fw_offset offset of NB1FW ROM script ++ * @param[out] scp_tbl1fw_info data structure with the SBL1FW CLIB ++ * @param[out] scp_tbl1fw Pointer to buffer with ROM script ++ * or NULL if no SBL1FW ROM script. ++ * @param[out] scp_tbl1fw_size size of firmware, 0 if no firmware ++ * @param[out] scp_tbl1fw_offset offset of SBL1FW ROM script ++ * ++ * @return 0 for success or -ENOMEM or -EINVAL on error ++ * ++ * NOTE: The allocated script data buffer will be rounded up to the nearest ++ * 512 bytes for eMMC support. No data is copied into the sec_data field. ++ */ ++static int get_rom_script(struct rom_clib *clib, ++ u8 **scr_data, ++ u32 *scr_size, ++ u32 *scr_offset, ++ u32 *scr_chksum) ++{ ++ *scr_size = le32_to_cpu(clib->rom_script_size); ++ *scr_offset = le32_to_cpu(clib->rom_script_offset); ++ *scr_chksum = le32_to_cpu(clib->rom_script_chksum); ++ if (*scr_size > SCR_MAX_SIZE) { ++ printf("%s: CLIB at %p script size %#x exceeds maximum size %#x\n", ++ __func__, clib, *scr_size, SCR_MAX_SIZE); ++ return -EINVAL; ++ } ++ if (*scr_size) { ++ /* Round size up for eMMC */ ++ *scr_data = malloc(roundup(*scr_size, 512)); ++ if (!(*scr_data)) ++ return -ENOMEM; ++ } else { ++ *scr_data = NULL; ++ } ++ return 0; ++} ++ ++/** ++ * Preserve the original ROM script for updating ++ * ++ * @param si script information pointer ++ * @param buf pointer to file buffer ++ * ++ * @return 0 for success, !0 for error ++ * ++ * NOTE: This will modify the contents of the buffer. Use finish_rom_scr() ++ * when finished to restore the buffer. On error the buffer may be ++ * modified and may not be able to be restored. ++ */ ++static int prepare_rom_scr(struct rom_scr_info *si, u8 *buf) ++{ ++ bool is_mmc = !!si->desc; ++ u8 buffer[512]; ++ u32 chksum; ++ int n; ++ int nb; ++ int ret = 1; ++ u8 *nb1fw_scr = NULL; ++ u8 *tbl1fw_scr = NULL; ++ u32 nb1fw_scr_chksum; ++ u32 tbl1fw_scr_chksum; ++ struct rom_clib old_scp_nb1fw_info; ++ struct rom_clib *new_scp_nb1fw_info; ++ struct rom_clib old_scp_tbl1fw_info; ++ struct rom_clib *new_scp_tbl1fw_info; ++ ++ si->bak_nb1fw_scr = NULL; ++ si->bak_tbl1fw_scr = NULL; ++ memset(&si->bak_scp_nb1fw_info, 0, sizeof(si->bak_scp_nb1fw_info)); ++ memset(&si->bak_scp_tbl1fw_info, 0, sizeof(si->bak_scp_tbl1fw_info)); ++ ++ if ((!si->flash && !si->desc) || (si->flash && si->desc)) { ++ printf("%s: Error: either SPI flash or MMC must be passed\n", ++ __func__); ++ return -1; ++ } ++ ++ /* ++ * If we're preserving the SCP ROM data then we first read ++ * this section from the SPI NOR and copy it to the buffer ++ * after preserving the original contents of the buffer ++ * before writing it. ++ */ ++ /* Read the NB1FW CLIB descriptor */ ++ if (is_mmc) { ++ n = blk_dread(si->desc, SCP_NB1FW_INFO_BLK, 1, buffer); ++ ret = n != 1; ++ memcpy(&old_scp_nb1fw_info, buffer, ++ sizeof(old_scp_nb1fw_info)); ++ } else { ++ ret = spi_flash_read(si->flash, SCP_NB1FW_INFO, ++ sizeof(old_scp_nb1fw_info), ++ &old_scp_nb1fw_info); ++ } ++ if (ret) { ++ printf("%s: Error reading SCP NB1FW info descriptor\n", ++ __func__); ++ goto error; ++ } ++ ++ /* Parse it for ROM scripts */ ++ ret = get_rom_script(&old_scp_nb1fw_info, ++ &nb1fw_scr, &si->nb1fw_scr_size, ++ &si->nb1fw_scr_offset, ++ &nb1fw_scr_chksum); ++ if (ret) { ++ printf("%s: Error parsing SCP NB1FW info descriptor\n", ++ __func__); ++ goto error; ++ } ++ ++ debug("%s: old rom SCP NB1FW script size: %u, offset: %#x, checksum: %#x\n", ++ __func__, si->nb1fw_scr_size, si->nb1fw_scr_offset, ++ nb1fw_scr_chksum); ++ ++ /* Backup the info field */ ++ memcpy(&si->bak_scp_nb1fw_info, buf + SCP_NB1FW_INFO, ++ sizeof(si->bak_scp_nb1fw_info)); ++ ++ /* Read the TBL1FW CLIB descriptor */ ++ if (is_mmc) { ++ n = blk_dread(si->desc, SCP_TBL1FW_INFO_BLK, 1, buffer); ++ ret = n != 1; ++ memcpy(&old_scp_tbl1fw_info, buffer, ++ sizeof(old_scp_tbl1fw_info)); ++ } else { ++ ret = spi_flash_read(si->flash, SCP_TBL1FW_INFO, ++ sizeof(old_scp_tbl1fw_info), ++ &old_scp_tbl1fw_info); ++ } ++ if (ret) { ++ printf("%s: Error reading SFP TBL1FW info descriptor\n", ++ __func__); ++ goto error; ++ } ++ /* Parse it for ROM scripts */ ++ ret = get_rom_script(&old_scp_tbl1fw_info, ++ &tbl1fw_scr, &si->tbl1fw_scr_size, ++ &si->tbl1fw_scr_offset, &tbl1fw_scr_chksum); ++ if (ret) { ++ printf("%s: Error parsing SCP TBL1FW info descriptor\n", ++ __func__); ++ goto error; ++ } ++ ++ debug("%s: old rom SCP TBL1FW script size: %u, offset: %#x, checksum: %#x\n", ++ __func__, si->tbl1fw_scr_size, si->tbl1fw_scr_offset, ++ tbl1fw_scr_chksum); ++ ++ /* Back up the info field */ ++ memcpy(&si->bak_scp_tbl1fw_info, buf + SCP_TBL1FW_INFO, ++ sizeof(si->bak_scp_tbl1fw_info)); ++ ++ if (si->nb1fw_scr_size) { ++ /* Save area for NB1FW ROM script to restore later */ ++ si->bak_nb1fw_scr = malloc(si->nb1fw_scr_size); ++ debug("%s: Allocated bak_nb1fw_scr at %p, size: %#x\n", ++ __func__, si->bak_nb1fw_scr, si->nb1fw_scr_size); ++ ++ if (!si->bak_nb1fw_scr) { ++ printf("%s: Could not allocate %u bytes for SCP NB1FW ROM script\n", ++ __func__, si->nb1fw_scr_size); ++ ret = -ENOMEM; ++ goto error; ++ } ++ memcpy(si->bak_nb1fw_scr, buf + si->nb1fw_scr_offset, ++ si->nb1fw_scr_size); ++#ifdef DEBUG ++ print_buffer(0, si->bak_nb1fw_scr, 4, ++ si->nb1fw_scr_size / 4, 0); ++#endif ++ } ++ ++ if (si->tbl1fw_scr_size) { ++ /* Save area for NB1FW ROM script to restore later */ ++ si->bak_tbl1fw_scr = malloc(si->tbl1fw_scr_size); ++ debug("%s: Allocated bak_tbl1fw_scr at %p, size: %#x\n", ++ __func__, si->bak_tbl1fw_scr, si->tbl1fw_scr_size); ++ if (!si->bak_tbl1fw_scr) { ++ printf("%s: Could not allocate %u bytes for SCP TBL1FW ROM script\n", ++ __func__, si->tbl1fw_scr_size); ++ if (si->bak_nb1fw_scr) { ++ /* Don't later restore this */ ++ free(si->bak_nb1fw_scr); ++ si->bak_nb1fw_scr = NULL; ++ } ++ ret = -ENOMEM; ++ goto error; ++ } ++ memcpy(si->bak_tbl1fw_scr, buf + si->tbl1fw_scr_offset, ++ si->tbl1fw_scr_size); ++#ifdef DEBUG ++ print_buffer(0, si->bak_tbl1fw_scr, 4, ++ si->tbl1fw_scr_size / 4, 0); ++#endif ++ } ++ ++ /* Read NB1FW ROM script if present */ ++ if (si->nb1fw_scr_size) { ++ debug("%s: Reading nb1fw script at offset: %#x, size: %u\n", ++ __func__, si->nb1fw_scr_offset, si->nb1fw_scr_size); ++ if (is_mmc) { ++ nb = get_num_blocks(si->nb1fw_scr_size); ++ n = blk_dread(si->desc, si->nb1fw_scr_offset / 512, ++ nb, nb1fw_scr); ++ ret = n != nb; ++ } else { ++ ret = spi_flash_read(si->flash, si->nb1fw_scr_offset, ++ si->nb1fw_scr_size, nb1fw_scr); ++ } ++ if (ret) { ++ printf("%s: Error reading %u bytes for NB1FW script at %#x\n", ++ __func__, si->nb1fw_scr_size, ++ si->nb1fw_scr_offset); ++ goto error; ++ } ++ chksum = scr_chksum(nb1fw_scr, si->nb1fw_scr_size); ++ if (chksum != nb1fw_scr_chksum) { ++ printf("Error: invalid checksum in SCP NB1FW ROM script, old checksum: %#x, calculated: %#x\n", ++ nb1fw_scr_chksum, chksum); ++ ret = -EINVAL; ++ goto error; ++ } ++ ++ /* Copy old ROM script into buffer */ ++ memcpy(buf + si->nb1fw_scr_offset, nb1fw_scr, ++ si->nb1fw_scr_size); ++ ++#ifdef DEBUG ++ print_buffer(0, nb1fw_scr, 4, si->nb1fw_scr_size / 4, 0); ++#endif ++ new_scp_nb1fw_info = ++ (struct rom_clib *)(buf + SCP_NB1FW_INFO); ++ /* Update ROM CLIB to old ROM script info */ ++ new_scp_nb1fw_info->rom_script_offset = ++ cpu_to_le32(si->nb1fw_scr_offset); ++ new_scp_nb1fw_info->rom_script_size = ++ cpu_to_le32(si->nb1fw_scr_size); ++ new_scp_nb1fw_info->rom_script_chksum = ++ cpu_to_le32(nb1fw_scr_chksum); ++ printf("Preserving SCP NB1FW ROM script at offset: %#x, size: %u, checksum: %#x\n", ++ si->nb1fw_scr_offset, si->nb1fw_scr_size, ++ nb1fw_scr_chksum); ++ } ++ ++ /* Read TBL1FW ROM script if present */ ++ if (si->tbl1fw_scr_size) { ++ if (is_mmc) { ++ nb = get_num_blocks(si->tbl1fw_scr_size); ++ n = blk_dread(si->desc, si->tbl1fw_scr_offset / 512, ++ nb, tbl1fw_scr); ++ ret = n != nb; ++ } else { ++ ret = spi_flash_read(flash, si->tbl1fw_scr_offset, ++ si->tbl1fw_scr_size, ++ tbl1fw_scr); ++ } ++ if (ret) { ++ printf("%s: Error reading %u bytes for TBL1FW script at %#x\n", ++ __func__, si->tbl1fw_scr_size, ++ si->tbl1fw_scr_offset); ++ goto error; ++ } ++ chksum = scr_chksum(tbl1fw_scr, si->tbl1fw_scr_size); ++ if (chksum != tbl1fw_scr_chksum) { ++ printf("Error: invalid checksum in SCP TBL1FW ROM script. Old checksum: %#x, calculated: %#x\n", ++ tbl1fw_scr_chksum, chksum); ++ ret = -EINVAL; ++ goto error; ++ } ++ ++ /* Copy old ROM script to buffer */ ++ memcpy(buf + si->tbl1fw_scr_offset, tbl1fw_scr, ++ si->tbl1fw_scr_size); ++#ifdef DEBUG ++ print_buffer(0, nb1fw_scr, 4, si->nb1fw_scr_size / 4, 0); ++#endif ++ new_scp_tbl1fw_info = ++ (struct rom_clib *)(buf + SCP_TBL1FW_INFO); ++ debug("%s: scp tbl1fw info: %p\n", __func__, ++ new_scp_tbl1fw_info); ++ /* Update ROM CLIB to old ROM script info */ ++ new_scp_tbl1fw_info->rom_script_offset = ++ cpu_to_le32(si->tbl1fw_scr_offset); ++ new_scp_tbl1fw_info->rom_script_size = ++ cpu_to_le32(si->tbl1fw_scr_size); ++ new_scp_tbl1fw_info->rom_script_chksum = ++ cpu_to_le32(tbl1fw_scr_chksum); ++ printf("Preserving SCP TBL1FW ROM script at offset: %#x, size: %u, checksum: %#x\n", ++ si->tbl1fw_scr_offset, si->tbl1fw_scr_size, ++ tbl1fw_scr_chksum); ++ } ++ ++error: ++ /* Free up any memory */ ++ if (nb1fw_scr) ++ free(nb1fw_scr); ++ if (tbl1fw_scr) ++ free(tbl1fw_scr); ++ ++ if (ret) { ++ /* Attempt cleanup */ ++ if (si->bak_nb1fw_scr) { ++ if (!memcmp(si->bak_scp_nb1fw_info.magic, INFO_MAGIC, ++ INFO_MAGIC_SIZE)) ++ memcpy(buf + SCP_NB1FW_INFO, ++ &si->bak_scp_nb1fw_info, ++ INFO_SIZE); ++ memcpy(buf + si->nb1fw_scr_offset, si->bak_nb1fw_scr, ++ si->nb1fw_scr_size); ++ free(si->bak_nb1fw_scr); ++ si->bak_nb1fw_scr = NULL; ++ } ++ if (si->bak_tbl1fw_scr) { ++ if (!memcmp(si->bak_scp_tbl1fw_info.magic, INFO_MAGIC, ++ INFO_MAGIC_SIZE)) ++ memcpy(buf + SCP_TBL1FW_INFO, ++ &si->bak_scp_tbl1fw_info, ++ INFO_SIZE); ++ memcpy(buf + SCP_NB1FW_INFO, &si->bak_scp_nb1fw_info, ++ INFO_SIZE); ++ memcpy(buf + si->tbl1fw_scr_offset, si->bak_tbl1fw_scr, ++ si->tbl1fw_scr_size); ++ free(si->bak_tbl1fw_scr); ++ si->bak_tbl1fw_scr = NULL; ++ } ++ } ++ return ret; ++} ++ ++/** ++ * Restores the file buffer to its original state ++ * ++ * @param si script info pointer ++ * @param buf pointer to buffer file was loaded to ++ * ++ * @return 0 for success ++ */ ++static int finish_rom_scr(struct rom_scr_info *si, u8 *buf) ++{ ++ if (si->bak_nb1fw_scr) { ++ memcpy(buf + si->nb1fw_scr_offset, ++ si->bak_nb1fw_scr, si->nb1fw_scr_size); ++ memcpy(buf + SCP_NB1FW_INFO, &si->bak_scp_nb1fw_info, ++ sizeof(si->bak_scp_nb1fw_info)); ++ free(si->bak_nb1fw_scr); ++ } ++ if (si->bak_tbl1fw_scr) { ++ memcpy(buf + si->tbl1fw_scr_offset, si->bak_tbl1fw_scr, ++ si->tbl1fw_scr_size); ++ memcpy(buf + SCP_TBL1FW_INFO, &si->bak_scp_tbl1fw_info, ++ sizeof(si->bak_scp_tbl1fw_info)); ++ free(si->bak_tbl1fw_scr); ++ } ++ return 0; ++} ++#endif ++ ++static int do_bootu_spi(int argc, char * const argv[], bool update_scr) ++{ ++ unsigned long addr, offset, len; ++ void *buf; ++ char *env1, *env2; ++ char *endp; ++ int ret = 1; ++ unsigned int bus = 0, cs; ++#if !CONFIG_IS_ENABLED(ARCH_OCTEONTX) ++ struct rom_scr_info si; ++#endif ++ ++ if ((argc < 1) || (argc > 4)) ++ return -1; ++ ++ if (argc == 1) { ++ bus = cs = 0; ++ env1 = env_get("fileaddr"); ++ env2 = env_get("filesize"); ++ if (!env1 || !env2) { ++ printf("Missing env variables fileaddr/filesize\n"); ++ return CMD_RET_USAGE; ++ } ++ } else if (argc == 2) { ++ cs = simple_strtoul(argv[1], &endp, 0); ++ if (*argv[1] == 0 || (*endp != 0 && *endp != ':')) ++ return -1; ++ if (*endp == ':') { ++ if (endp[1] == 0) ++ return CMD_RET_USAGE; ++ ++ bus = cs; ++ cs = simple_strtoul(endp + 1, &endp, 0); ++ if (*endp != 0) ++ return CMD_RET_USAGE; ++ } ++ env1 = env_get("fileaddr"); ++ env2 = env_get("filesize"); ++ if (!env1 || !env2) { ++ printf("Missing env variables fileaddr/filesize\n"); ++ return CMD_RET_USAGE; ++ } ++ } else if (argc == 4) { ++ cs = simple_strtoul(argv[1], &endp, 0); ++ if (*argv[1] == 0 || (*endp != 0 && *endp != ':')) ++ return -1; ++ if (*endp == ':') { ++ if (endp[1] == 0) ++ return CMD_RET_USAGE; ++ ++ bus = cs; ++ cs = simple_strtoul(endp + 1, &endp, 0); ++ if (*endp != 0) ++ return CMD_RET_USAGE; ++ } ++ debug("%s argv0 %s argv1 %s\n", __func__, argv[0], argv[1]); ++ debug("%s argv2 %s argv3 %s\n", __func__, argv[2], argv[3]); ++ env1 = argv[2]; ++ env2 = argv[3]; ++ } else { ++ printf("Missing args\n"); ++ return CMD_RET_USAGE; ++ } ++ debug("%s update SCP: %s\n", __func__, update_scr ? "yes" : "no"); ++ debug("%s fileaddr %s filesize %s\n", __func__, env1, env2); ++ debug("%s bus %d cs %d\n", __func__, bus, cs); ++ ++ offset = 0; ++ ret = strict_strtoul(env1, 16, &addr); ++ if (ret) ++ return CMD_RET_USAGE; ++ debug("%s addr %#lx\n", __func__, addr); ++ ++ ret = strict_strtoul(env2, 16, &len); ++ if (ret) ++ return CMD_RET_USAGE; ++ debug("%s len %#lx\n", __func__, len); ++ ++ if( !addr || !len) { ++ printf("image address or length is 0\n"); ++ return CMD_RET_USAGE; ++ } ++ buf = (u8 *)addr; ++ ++ if (validate_bootimg_header(addr)) { ++ printf("\n No valid boot image header found \n"); ++ return CMD_RET_FAILURE; ++ } ++ ++ ret = do_spi_flash_probe(bus, cs); ++ if (ret) { ++ printf("Could not probe SPI flash %d:%d\n", bus, cs); ++ return CMD_RET_FAILURE; ++ } ++ ++ /* Consistency checking */ ++ if (offset + len > flash->size) { ++ printf("ERROR: attempting %s past flash size (%#x)\n", ++ argv[0], flash->size); ++ return CMD_RET_FAILURE; ++ } ++ ++#if !CONFIG_IS_ENABLED(ARCH_OCTEONTX) ++ if (!update_scr) { ++ si.desc = NULL; ++ si.flash = flash; ++ ret = prepare_rom_scr(&si, buf); ++ if (ret) { ++ printf("%s: Error preparing ROM script info.\n", ++ __func__); ++ goto error; ++ } ++ } ++#endif ++ ++ ret = spi_flash_update(flash, offset, len, buf); ++ ++ printf("bootu SPI : %zu bytes @ %#x Written ", ++ (size_t)len, (u32)offset); ++ if (ret) ++ printf("ERROR %d\n", ret); ++ else ++ printf("OK\n"); ++ ++#if !CONFIG_IS_ENABLED(ARCH_OCTEONTX) ++ if (!update_scr) ++ ret = finish_rom_scr(&si, buf); ++error: ++#endif ++ if (ret) ++ debug("%s: Return code: %d\n", __func__, ret); ++ ++ return ret == 0 ? CMD_RET_SUCCESS : CMD_RET_FAILURE; ++} ++ ++/** ++ * Make sure the partition table is sane ++ * ++ * @param[in] buf pointer to buffer with partition table ++ * ++ * @return 0 for success, !0 for error ++ */ ++static int validate_partition_table(const unsigned char *buf) ++{ ++ struct dos_partition *p; ++ ++ if ((buf[510] != 0x55) || (buf[511] != 0xaa)) { ++ printf("No valid MBR signature in first sector\n"); ++ return 1; /* no DOS Signature at all */ ++ } ++ ++ /* checks for FAT12 as partition 1 */ ++ p = (struct dos_partition *)&buf[446]; ++ if (p->sys_ind != 0x01) { ++ printf("%s Invalid first partition type %x" ++ " expected FAT12 \n", __func__, p->sys_ind); ++ return 1; ++ } ++ /* check for second partition start <16MB */ ++ p = (struct dos_partition *)&buf[446 + 16]; ++ if (p->sys_ind != 0) ++ if (p->start4 < 0x8000) { ++ printf("%s partition type %x start sector at %d " ++ "below 16MB(reserved for boot image)\n", ++ __func__, p->sys_ind, p->start4); ++ return 1; ++ } ++ ++ // FIXME below checks really needed? ++ /* check for third partition start <16MB */ ++ p = (struct dos_partition *)&buf[446 + 16 * 2]; ++ if (p->sys_ind != 0) ++ if (p->start4 < 0x8000) { ++ printf("%s partition type %x start sector at %d " ++ "below 16MB(reserved for boot image)\n", ++ __func__, p->sys_ind, p->start4); ++ return 1; ++ } ++ /* check for fourth partition start <16MB */ ++ p = (struct dos_partition *)&buf[446 + 16 * 3]; ++ if (p->sys_ind != 0) ++ if (p->start4 < 0x8000) { ++ printf("%s partition type %x start sector at %d " ++ "below 16MB(reserved for boot image)\n", ++ __func__, p->sys_ind, p->start4); ++ return 1; ++ } ++ return 0; ++} ++ ++static struct mmc *init_mmc_device(int dev, bool force_init) ++{ ++ struct mmc *mmc; ++ ++ mmc = find_mmc_device(dev); ++ if (!mmc) { ++ printf("no mmc device at slot %x\n", dev); ++ return NULL; ++ } ++ if (force_init) ++ mmc->has_init = 0; ++ if (mmc_init(mmc)) ++ return NULL; ++ return mmc; ++} ++ ++static int do_bootu_mmc(int argc, char * const argv[], ++ bool update_scp, bool overwrite_part) ++{ ++ static int curr_device = -1; ++ struct mmc *mmc; ++ struct blk_desc *desc; ++ char *env1, *env2, *endp; ++ unsigned long blk, len, n, blk_cnt = 0; ++ unsigned long addr; ++ u8 *buf; ++ int ret = 0; ++ u32 num_blks; ++ u8 buffer[512]; ++#if !CONFIG_IS_ENABLED(ARCH_OCTEONTX) ++ struct rom_scr_info si; ++#endif ++ ++ if ((argc < 1) || (argc > 4)) { ++ printf("Invalid # args \n"); ++ return CMD_RET_USAGE; ++ } ++ if (argc == 1) { ++ curr_device = 0; ++ env1 = env_get("fileaddr"); ++ env2 = env_get("filesize"); ++ if (!env1 || !env2) { ++ printf("Missing env variables fileaddr/filesize\n"); ++ return CMD_RET_USAGE; ++ } ++ } else if (argc == 2) { ++ curr_device = simple_strtoul(argv[1], &endp, 0); ++ env1 = env_get("fileaddr"); ++ env2 = env_get("filesize"); ++ if (!env1 || !env2) { ++ printf("Missing env variables fileaddr/filesize\n"); ++ return CMD_RET_USAGE; ++ } ++ } else if (argc == 3) { ++ printf("Missing args - image addr or image size\n"); ++ return CMD_RET_USAGE; ++ } else if (argc == 4) { ++ curr_device = simple_strtoul(argv[1], &endp, 0); ++ debug("%s argv0 %s argv1 %s\n", __func__, argv[0], argv[1]); ++ env1 = argv[2]; ++ env2 = argv[3]; ++ } ++ debug("%s update scp: %s, overwrite partition table: %s\n", ++ __func__, update_scp ? "yes" : "no", ++ overwrite_part ? "yes" : "no"); ++ debug("%s loadaddr %s filesize %s\n", __func__, env1, env2); ++ debug("%s curr_device %d\n", __func__, curr_device); ++ blk = 0; ++ ++ ret = strict_strtoul(env1, 16, &addr); ++ if (ret) ++ return -1; ++ debug("%s addr %ld\n", __func__, addr); ++ ++ ret = strict_strtoul(env2, 16, &len); ++ if (ret) ++ return -1; ++ debug("%s len %ld\n", __func__, len); ++ if( !addr || !len) { ++ printf("image address or length is 0\n"); ++ return CMD_RET_USAGE; ++ } ++ len = DIV_ROUND_UP(len, 512); ++ debug("%s len %ld\n", __func__, len); ++ ++ if ((blk + 512 * len) > 0x1000000) { ++ printf("\nBoot Image size exceeding 16MB\n"); ++ return CMD_RET_FAILURE; ++ } ++ ++ if (validate_bootimg_header(addr)) { ++ printf("\nNo valid boot image header found\n"); ++ return CMD_RET_FAILURE; ++ } ++ ++ if (get_mmc_num() < curr_device) { ++ puts("No MMC device available\n"); ++ return CMD_RET_FAILURE; ++ } ++ ++ mmc = init_mmc_device(curr_device, false); ++ if (!mmc) ++ return CMD_RET_FAILURE; ++ ++ desc = mmc_get_blk_desc(mmc); ++ if (!desc) ++ return CMD_RET_FAILURE; ++ ++ buf = (u8 *)addr; ++ ++ n = blk_dread(desc, 0, 1, buffer); ++ if (n != 1) { ++ printf("ERROR: read partition table failed\n"); ++ return CMD_RET_FAILURE; ++ } ++ ++ if (!overwrite_part && validate_partition_table(buffer)) { ++ printf("Invalid partition setup, can't write bootimg\n"); ++ return CMD_RET_FAILURE; ++ } ++ ++ if (mmc_getwp(mmc) == 1) { ++ printf("Error: card is write protected!\n"); ++ return CMD_RET_FAILURE; ++ } ++ ++ if (len <= get_num_blocks(MIN_SIZE)) { ++ printf("\nError: Image size is too small, missing SCP section\n"); ++ return CMD_RET_FAILURE; ++ } ++ ++#if !CONFIG_IS_ENABLED(ARCH_OCTEONTX) ++ if (!update_scp) { ++ si.flash = NULL; ++ si.desc = desc; ++ ret = prepare_rom_scr(&si, buf); ++ if (ret) ++ goto error; ++ } ++#endif ++ ++ printf("\nMMC write: dev # %d, block # %ld, count %ld ... ", ++ curr_device, blk, len); ++ ++ num_blks = len - blk; ++ n = blk_dwrite(desc, blk, num_blks, buf); ++ blk_cnt += n; ++ if (n != num_blks) ++ goto error; ++ ++#if !CONFIG_IS_ENABLED(ARCH_OCTEONTX) ++ if (!update_scp) ++ ret = finish_rom_scr(&si, buf); ++#endif ++ ++error: ++ ++ printf("%lu blocks written: %s\n", blk_cnt, ++ (blk_cnt == len && !ret) ? "OK" : "ERROR"); ++ ++ if (blk_cnt != len || ret) ++ return CMD_RET_FAILURE; ++ ++ if (!overwrite_part) { ++ /* Update partition table with FAT entry of boot image */ ++ memcpy(&buffer[446], (void *)(addr + 446), 16); ++ ++ /* Update partition table with read boot sector */ ++ n = blk_dwrite(desc, 0, 1, (void *)buffer); ++ printf("%lu blocks written: %s\n", n, ++ (n == 1) ? "OK" : "ERROR"); ++ if (n != 1) ++ return CMD_RET_FAILURE; ++ } ++ ++ return CMD_RET_SUCCESS; ++} ++ ++static int do_bootimgup(cmd_tbl_t *cmdtp, int flag, int argc, ++ char * const argv[]) ++{ ++ const char *cmd; ++ int ret; ++ int i; ++ bool overwrite_part = false; ++#if CONFIG_IS_ENABLED(ARCH_OCTEONTX) ++ /* OcteonTX does not have a SCP section so it is always updated */ ++ const bool update_scp = true; ++#else ++ bool update_scp = false; ++#endif ++ ++ /* Check flags at the beginning */ ++ if (argc > 1) { ++ for (i = 1; i < min(argc, 3); i++) { ++#if !CONFIG_IS_ENABLED(ARCH_OCTEONTX) ++ if (!strcmp(argv[1], "-s")) { ++ update_scp = true; ++ argv++; ++ argc--; ++ } ++#endif ++ if (!strcmp(argv[1], "-p")) { ++ overwrite_part = true; ++ argv++; ++ argc--; ++ } ++ } ++ } ++ ++ /* need at least two arguments */ ++ if (argc < 2) ++ goto usage; ++ ++ cmd = argv[1]; ++ --argc; ++ ++argv; ++ ++ if (strcmp(cmd, "spi") == 0) { ++ if (overwrite_part) ++ puts("-p is ignored for SPI\n"); ++ ret = do_bootu_spi(argc, argv, update_scp); ++ } ++ else if (strcmp(cmd, "mmc") == 0) ++ ret = do_bootu_mmc(argc, argv, update_scp, overwrite_part); ++ else ++ ret = -1; ++ ++ if (ret != -1) ++ return ret; ++ ++usage: ++ return CMD_RET_USAGE; ++} ++ ++U_BOOT_CMD( ++#if !CONFIG_IS_ENABLED(ARCH_OCTEONTX) ++ bootimgup, 7, 1, do_bootimgup, "Updates Boot Image", ++ " <[-s]> <[-p]> <[devid] | [bus:cs]> [image_address] [image_size]\n" ++ " where: \n" ++ " -s - overwrite SCP ROM area\n" ++#else ++ bootimgup, 6, 1, do_bootimgup, "Updates Boot Image", ++ " <[-p]> <[devid] | [bus:cs]> [image_address] [image_size]\n" ++#endif ++ " -p - (MMC only) overwrite the partition table\n" ++ " spi - updates boot image on spi flash \n" ++ " bus and cs should be passed together, passing only one \n" ++ " of them treated as invalid. If [bus:cs] not given, 0:0 is used \n" ++ " image_address - address at which image is located in RAM \n" ++ " image_size - size of image in hex \n" ++ " eg. to load on spi0 chipselect 0 \n" ++ " bootimgup spi 0:0 $loadaddr $filesize \n" ++ " eg. to load on spi1 chipselect 1 \n" ++ " bootimgup spi 1:1 $loadaddr $filesize \n" ++ " \n" ++ " mmc - updates boot image on mmc card/chip \n" ++ " eg. to load on device 0 \n" ++ " bootimgup mmc 0 $loadaddr $filesize \n" ++ " eg. to load on device 1. If device id not given, 0 is used \n" ++ " bootimgup mmc 1 $loadaddr $filesize \n" ++ " image_address - address at which image is located in RAM \n" ++ " image_size - size of image in hex \n" ++ " image_address, image_size should be passed together, \n" ++ " passing only one of them treated as invalid. \n" ++ " \n" ++ " If not given, then $loadaddr and $filesize values in \n" ++ " environment are used, otherwise fail to update. \n" ++); +diff --git a/cmd/marvell/eth_cmds.c b/cmd/marvell/eth_cmds.c +new file mode 100644 +index 0000000000..2f971625fa +--- /dev/null ++++ b/cmd/marvell/eth_cmds.c +@@ -0,0 +1,225 @@ ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++extern int cgx_intf_set_fec(struct udevice *ethdev, int type); ++extern int cgx_intf_get_fec(struct udevice *ethdev); ++extern int cgx_intf_get_phy_mod_type(struct udevice *ethdev); ++extern int cgx_intf_set_phy_mod_type(struct udevice *ethdev, int type); ++extern int cgx_intf_set_mode(struct udevice *ethdev, int mode); ++extern int cgx_intf_set_an_lbk(struct udevice *ethdev, int enable); ++extern int cgx_intf_set_ignore(struct udevice *ethdev, int cgxid, int lmacid, ++ int ignore); ++extern int cgx_intf_get_ignore(struct udevice *ethdev, int cgxid, int lmacid); ++extern int cgx_intf_get_mode(struct udevice *ethdev); ++extern void nix_print_mac_info(struct udevice *dev); ++ ++static int do_ethlist(cmd_tbl_t *cmdtp, int flag, int argc, ++ char *const argv[]) ++{ ++ struct udevice *dev; ++ ++ for (uclass_find_first_device(UCLASS_ETH, &dev); dev; ++ uclass_find_next_device(&dev)) { ++ printf("eth%d [%s]", dev->seq, dev->name); ++ if (!strncmp(dev->name, "rvu_", 4)) ++ nix_print_mac_info(dev); ++ printf("\n"); ++ } ++ return 0; ++} ++ ++U_BOOT_CMD( ++ ethlist, 1, 1, do_ethlist, "Display ethernet interface list", ++ "Prints all detected ethernet interfaces with below format\n" ++ "ethX [device name] [LMAC info for RVU PF devices]\n" ++); ++ ++static int do_ethparam_common(cmd_tbl_t *cmdtp, int flag, int argc, ++ char *const argv[]) ++{ ++ const char *cmd; ++ char *endp; ++ const char *devname; ++ int ret = CMD_RET_USAGE, arg, cgx = -1, lmac = -1; ++ struct udevice *dev = NULL; ++ ++ if (argc < 2) ++ return ret; ++ ++ cmd = argv[0]; ++ ++ if (strncmp(argv[1], "eth", 3)) { ++ if (strcmp(cmd, "set_ignore") == 0) { ++ if (argc != 4) ++ return ret; ++ cgx = simple_strtol(argv[1], &endp, 0); ++ if (cgx < 0 || cgx > 4) ++ return ret; ++ lmac = simple_strtol(argv[2], &endp, 0); ++ if (lmac < 0 || lmac > 3) ++ return ret; ++ } else if (strcmp(cmd, "get_ignore") == 0) { ++ if (argc != 3) ++ return ret; ++ cgx = simple_strtol(argv[1], &endp, 0); ++ if (cgx < 0 || cgx > 4) ++ return ret; ++ lmac = simple_strtol(argv[2], &endp, 0); ++ if (lmac < 0 || lmac > 3) ++ return ret; ++ } else { ++ return ret; ++ } ++ } else { ++ devname = argv[1]; ++ dev = eth_get_dev_by_name(devname); ++ if (!dev) { ++ printf("device interface %s not found\n", devname); ++ return CMD_RET_FAILURE; ++ } ++ if (strncmp(dev->name, "rvu_", 4)) { ++ printf("Invalid eth interface choose RVU PF device\n"); ++ return CMD_RET_FAILURE; ++ } ++ } ++ ++ if (strcmp(cmd, "set_fec") == 0) { ++ if (argc < 3) ++ return CMD_RET_FAILURE; ++ arg = simple_strtol(argv[2], &endp, 0); ++ if (arg < 0 || arg > 2) ++ return ret; ++ ret = cgx_intf_set_fec(dev, arg); ++ } else if (strcmp(cmd, "get_fec") == 0) { ++ ret = cgx_intf_get_fec(dev); ++ } else if (strcmp(cmd, "set_an_lbk") == 0) { ++ if (argc < 3) ++ return CMD_RET_FAILURE; ++ arg = simple_strtol(argv[2], &endp, 0); ++ if (arg < 0 || arg > 1) ++ return CMD_RET_USAGE; ++ ret = cgx_intf_set_an_lbk(dev, arg); ++ } else if (strcmp(cmd, "set_ignore") == 0) { ++ if (dev) ++ arg = simple_strtol(argv[2], &endp, 0); ++ else ++ arg = simple_strtol(argv[3], &endp, 0); ++ if (arg < 0 || arg > 1) ++ return ret; ++ ret = cgx_intf_set_ignore(dev, cgx, lmac, arg); ++ } else if (strcmp(cmd, "get_ignore") == 0) { ++ ret = cgx_intf_get_ignore(dev, cgx, lmac); ++ } else if (strcmp(cmd, "set_phymod") == 0) { ++ if (argc < 3) ++ return CMD_RET_FAILURE; ++ arg = simple_strtol(argv[2], &endp, 0); ++ if (arg < 0 || arg > 1) ++ return ret; ++ ret = cgx_intf_set_phy_mod_type(dev, arg); ++ } else if (strcmp(cmd, "get_phymod") == 0) { ++ ret = cgx_intf_get_phy_mod_type(dev); ++ } else if (strcmp(cmd, "get_mode") == 0) { ++ ret = cgx_intf_get_mode(dev); ++ } else if (strcmp(cmd, "set_mode") == 0) { ++ if (argc < 3) ++ return CMD_RET_FAILURE; ++ arg = simple_strtol(argv[2], &endp, 0); ++ if (arg < 0 || arg > 6) ++ return ret; ++ ret = cgx_intf_set_mode(dev, arg); ++ } ++ return (ret == 0) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; ++} ++ ++U_BOOT_CMD( ++ set_fec, 3, 1, do_ethparam_common, ++ "Modify fec type for selected ethernet interface", ++ "Example - set_fec [type]\n" ++ "Set FEC type for any of RVU PF based network interfaces\n" ++ "- where type - 0 [NO FEC] 1 [BASER_FEC] 2 [RS_FEC]\n" ++ "Use 'ethlist' command to display network interface names\n" ++); ++ ++U_BOOT_CMD( ++ get_fec, 2, 1, do_ethparam_common, ++ "Display fec type for selected ethernet interface", ++ "Example - get_fec \n" ++ "Get FEC type for any of RVU PF based network interfaces\n" ++ "Use 'ethlist' command to display network interface names\n" ++); ++ ++U_BOOT_CMD(set_an_lbk, 3, 1, do_ethparam_common, ++ "Set or clear Auto-neg loopback for ethernet interface", ++ "Example - set_an_lbk [value]\n" ++ "0 [clear] or 1 [set]\n" ++ "Use 'ethlist' command to display network interface names\n" ++); ++ ++U_BOOT_CMD(set_ignore, 4, 1, do_ethparam_common, ++ "Set or clear ignore param in persist storage for eth interface", ++ "Example - set_ignore [value]\n" ++ "0 [clear ignore] or 1 [set ignore]\n" ++ "Example - set_ignore [value]\n" ++ "For CGX0 LMAC3 - set_ignore 0 3 [value]\n" ++ "0 [clear ignore] or 1 [set ignore]\n" ++ "Helps to ignore all persist settings for selected ethernet\n" ++ "interface on next boot\n" ++ "Use 'ethlist' command to display network interface names\n" ++); ++ ++U_BOOT_CMD(get_ignore, 3, 1, do_ethparam_common, ++ "Display ignore param in persist storage for ethernet interface", ++ "Example - get_ignore or\n" ++ "Example - get_ignore \n" ++ "For CGX0 LMAC3 - get_ignore 0 3\n" ++ "Use 'ethlist' command to display network interface names\n" ++); ++ ++U_BOOT_CMD( ++ set_phymod, 3, 1, do_ethparam_common, ++ "Modify line side phy-mod type for selected ethernet interface", ++ "Example - set_phymod [type]\n" ++ "Set PHY MOD type for any of RVU PF based network interfaces\n" ++ "Currently, only 50G_R mode supports type 0 [NRZ] or 1 [PAM4]\n" ++ "Use 'ethlist' command to display network interface names\n" ++); ++ ++U_BOOT_CMD( ++ get_phymod, 2, 1, do_ethparam_common, ++ "Display line side phy-mod type for selected ethernet interface", ++ "Example - get_phymod \n" ++ "Get PHY MOD type for any of RVU PF based network interfaces\n" ++ "Use 'ethlist' command to display network interface names\n" ++); ++ ++U_BOOT_CMD(get_mode, 2, 1, do_ethparam_common, ++ "Display Interface mode for selected ethernet interface", ++ "Example - get_mode \n" ++ "Use 'ethlist' command to display network interface names\n" ++); ++ ++U_BOOT_CMD(set_mode, 3, 1, do_ethparam_common, ++ "Modify Interface mode for selected ethernet interface", ++ "Example - set_mode [mode]\n" ++ "Change mode of selected network interface\n" ++ "\n" ++ "mode encoding -\n" ++ " 0 - 10G_C2C\n" ++ " 1 - 10G_C2M\n" ++ " 2 - 10G_KR\n" ++ " 3 - 25G_C2C\n" ++ " 4 - 25G_2_C2C\n" ++ " 5 - 50G_C2C\n" ++ " 6 - 50G_4_C2C\n" ++ "Use 'ethlist' command to display network interface names\n" ++); +diff --git a/cmd/marvell/mdio_dbg.c b/cmd/marvell/mdio_dbg.c +new file mode 100644 +index 0000000000..5378293a1c +--- /dev/null ++++ b/cmd/marvell/mdio_dbg.c +@@ -0,0 +1,83 @@ ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++ ++extern void nix_get_cgx_lmac_id(struct udevice *dev, int *cgxid, int *lmacid); ++ ++static int do_mdio_dbg(cmd_tbl_t *cmdtp, int flag, int argc, ++ char *const argv[]) ++{ ++ const char *cmd; ++ char *endp; ++ const char *devname; ++ int ret = -1; ++ int mode, phyaddr, devaddr, regaddr, data, cgx, lmac, cgx_lmac; ++ struct udevice *dev; ++ ++ if (argc < 7) ++ return CMD_RET_USAGE; ++ ++ devaddr = -1; ++ cmd = argv[1]; ++ devname = argv[2]; ++ ++ dev = eth_get_dev_by_name(devname); ++ if (!dev) { ++ printf("device interface %s not found\n", devname); ++ return CMD_RET_FAILURE; ++ } ++ if (strncmp(dev->name, "rvu_", 4)) { ++ printf("Invalid eth interface, choose RVU PF device\n"); ++ return CMD_RET_FAILURE; ++ } ++ nix_get_cgx_lmac_id(dev, &cgx, &lmac); ++ cgx_lmac = (lmac & 0xF) | ((cgx & 0xF) << 4); ++ ++ mode = simple_strtol(argv[3], &endp, 0); ++ if (mode < 0 || mode > 1) { ++ printf("Invalid clause selection\n"); ++ return CMD_RET_FAILURE; ++ } ++ phyaddr = simple_strtol(argv[4], &endp, 0); ++ ++ if (strcmp(cmd, "read") == 0) { ++ if (mode) ++ devaddr = simple_strtol(argv[5], &endp, 0); ++ regaddr = simple_strtol(argv[6], &endp, 0); ++ ret = smc_mdio_dbg_read(cgx_lmac, mode, phyaddr, devaddr, ++ regaddr); ++ printf("Read register 0x%x devad[%d] of PHY@0x%x => 0x%x\n", ++ regaddr, devaddr, phyaddr, ret); ++ } else if (strcmp(cmd, "write") == 0) { ++ if (mode) ++ devaddr = simple_strtol(argv[5], &endp, 0); ++ regaddr = simple_strtol(argv[6], &endp, 0); ++ data = simple_strtol(argv[7], &endp, 0); ++ ret = smc_mdio_dbg_write(cgx_lmac, mode, phyaddr, devaddr, ++ regaddr, data); ++ printf("Write register 0x%x devad[%d] of PHY@0x%x <= 0x%x\n", ++ regaddr, devaddr, phyaddr, data); ++ } ++ return (ret == 0) ? CMD_RET_SUCCESS : CMD_RET_FAILURE; ++} ++ ++U_BOOT_CMD( ++ mdio_dbg, 8, 1, do_mdio_dbg, ++ "MDIO Debug utility commands", ++ "mdio_dbg read \n" ++ " - read register of PHY@addr using at .\n" ++ "mdio_dbg write \n" ++ " - write register of PHY@addr using at .\n" ++ "\n" ++ " - mode 0 [CLAUSE22] and 1 [CLAUSE45]\n" ++ " - devad should be -1 for clause22 and device address for clause45\n" ++ "Use 'ethlist' command to display network interface names\n" ++); +diff --git a/cmd/marvell/octeontx2_attest_cmds.c b/cmd/marvell/octeontx2_attest_cmds.c +new file mode 100644 +index 0000000000..6824b4c699 +--- /dev/null ++++ b/cmd/marvell/octeontx2_attest_cmds.c +@@ -0,0 +1,282 @@ ++/* ++ * Copyright (C) 2019 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static int get_fit_image_ids(const char *img_str, ++ sw_attestation_tlv_t **tlv_ptr, void *tlv_limit); ++ ++static void hexdump(const char *prefix, unsigned char *buf, int len) ++{ ++ int i; ++ ++ for (i = 0; i < len; i++) { ++ if ((i % 16) == 0) ++ printf("%s%s%08lx: ", i ? "\n" : "", ++ prefix ? prefix : "", ++ (unsigned long)i /* i.e. offset */); ++ printf("%02x ", buf[i]); ++ } ++ printf("\n"); ++} ++ ++static const char *tlv_type_name(enum sw_attestation_tlv_type type) ++{ ++ static const char *tlv_types[ATT_TLV_TYPE_COUNT] = { ++ [ATT_IMG_INIT_BIN] = "ATT_IMG_INIT_BIN", ++ [ATT_IMG_ATF_BL1] = "ATT_IMG_ATF_BL1", ++ [ATT_IMG_BOARD_DT] = "ATT_IMG_BOARD_DT", ++ [ATT_IMG_LINUX_DT] = "ATT_IMG_LINUX_DT", ++ [ATT_IMG_SCP_TBL1FW] = "ATT_IMG_SCP_TBL1FW", ++ [ATT_IMG_MCP_TBL1FW] = "ATT_IMG_MCP_TBL1FW", ++ [ATT_IMG_AP_TBL1FW] = "ATT_IMG_AP_TBL1FW", ++ [ATT_IMG_ATF_BL2] = "ATT_IMG_ATF_BL2", ++ [ATT_IMG_ATF_BL31] = "ATT_IMG_ATF_BL31", ++ [ATT_IMG_ATF_BL33] = "ATT_IMG_ATF_BL33", ++ [ATT_SIG_NONCE] = "ATT_SIG_NONCE", ++ [ATT_IMG_FIT_KERNEL] = "ATT_IMG_FIT_KERNEL", ++ }; ++ if (type < 0 || type >= ATT_TLV_TYPE_COUNT) ++ return "Unknown"; ++ else ++ return tlv_types[type]; ++} ++ ++static int do_attest(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) ++{ ++ ssize_t len; ++ uintptr_t attest_ret; ++ const char *img_str; ++ sw_attestation_info_hdr_t *att_info; ++ sw_attestation_tlv_t *tlv; ++ void *tlv_limit, *next_tlv, *cert, *sig; ++ unsigned long nonce_len; ++ ++ if (argc < 2) { ++ printf("Please specify nonce string & optional FIT address.\n"); ++ return CMD_RET_USAGE; ++ } ++ ++ nonce_len = strlen(argv[1]); ++ if (nonce_len > SW_ATT_INFO_NONCE_MAX_LEN) { ++ printf("Input nonce too large (%lu vs %u)\n", ++ nonce_len, SW_ATT_INFO_NONCE_MAX_LEN); ++ return CMD_RET_USAGE; ++ } ++ ++ if (argc > 2) ++ img_str = argv[2]; ++ else ++ img_str = NULL; ++ ++ /* query for buffer address & len */ ++ attest_ret = smc_attest(OCTEONTX_ATTESTATION_QUERY_SUBCMD_BUFFER, 0); ++ ++ if ((ssize_t)attest_ret <= 0) { ++ printf("Error: unable to obtain buffer address.\n"); ++ return CMD_RET_FAILURE; ++ } ++ ++ att_info = (void *)attest_ret; ++ ++ if (ntohl(att_info->magic_be) != ATTESTATION_MAGIC_ID) { ++ printf("Error: invalid buffer magic ID.\n"); ++ return CMD_RET_FAILURE; ++ } ++ ++ tlv = att_info->tlv_list; ++ tlv_limit = (void *)tlv + (long)(ntohs(att_info->tlv_len_be)); ++ ++ /* Pass nonce data & optional FIT image data to service */ ++ len = nonce_len; ++ tlv->type_be = htons(ATT_SIG_NONCE); ++ tlv->length_be = htons(len); ++ memcpy(tlv->value, argv[1], len); ++ tlv = (sw_attestation_tlv_t *)&tlv->value[len]; ++ ++ if (img_str) { ++ if (get_fit_image_ids(img_str, &tlv, tlv_limit) != 0) { ++ printf("Error parsing FIT image attestation IDs\n"); ++ return CMD_RET_FAILURE; ++ } ++ } ++ ++ len = (uintptr_t)tlv - (uintptr_t)att_info->tlv_list; ++ ++ attest_ret = smc_attest(OCTEONTX_ATTESTATION_QUERY_SUBCMD_INFO, len); ++ ++ if ((ssize_t)attest_ret != 0) { ++ printf("Error %ld from attest command\n", attest_ret); ++ return CMD_RET_FAILURE; ++ } ++ ++ printf("Attestation decode:\n"); ++ printf("\tMagic: %08x\n", ntohl(att_info->magic_be)); ++ tlv = att_info->tlv_list; ++ tlv_limit = (void *)tlv + (long)(ntohs(att_info->tlv_len_be)); ++ while ((uintptr_t)tlv < (uintptr_t)tlv_limit) { ++ next_tlv = (void *)tlv + ntohs(tlv->length_be) + ++ sizeof(*tlv); ++ if ((uintptr_t)next_tlv > (uintptr_t)tlv_limit) { ++ printf("Error: invalid TLV construct\n"); ++ break; ++ } ++ printf("\t%s:\n", tlv_type_name(ntohs(tlv->type_be))); ++ hexdump("\t ", tlv->value, ntohs(tlv->length_be)); ++ tlv = (sw_attestation_tlv_t *)next_tlv; ++ } ++ ++ /* command returned successfully, but with malformed data */ ++ if (tlv != tlv_limit) ++ return CMD_RET_SUCCESS; ++ ++ /* Certificate is contiguous to TLV date */ ++ cert = tlv_limit; ++ printf("\tCertificate:\n"); ++ hexdump("\t ", (unsigned char *)cert, ++ ntohs(att_info->certificate_len_be)); ++ ++ len = ntohs(att_info->total_len_be); ++ len -= ntohs(att_info->signature_len_be); ++ printf("\tAttestation [Signed] Image:\n"); ++ hexdump("\t ", (unsigned char *)att_info, len); ++ ++ /* Authentication signature is contiguous to certificate */ ++ sig = (void *)cert + ntohs(att_info->certificate_len_be); ++ printf("\tAuthentication signature:\n"); ++ hexdump("\t ", sig, htons(att_info->signature_len_be)); ++ ++ return CMD_RET_SUCCESS; ++} ++ ++/* ++ * get_fit_image_ids() ++ * ++ * This extracts the kernel image hash from within a FIT image and ++ * adds it as a TLV entry to be submitted to ATF as part of the ++ * Software Attestation information. ++ * ++ * on entry, ++ * img_str: FIT image specifier; this supports syntax :kernel@x. ++ * If not kernel is specified, the first one will be used. ++ * tlv_ptr: address of TLV entries to be filled-in ++ * tlv_limit: limit of TLV data ++ * ++ * returns, ++ * 0 upon success ++ * -1 upon error ++ */ ++static int get_fit_image_ids(const char *img_str, ++ sw_attestation_tlv_t **tlv_ptr, void *tlv_limit) ++{ ++ int images_noffset, ndepth, count, ret, len, fit_value_len; ++ int subnoffset, noffset; ++ u8 img_type; ++ u8 *fit_value; ++ void *fit_hdr; ++ const char *name, *img_name; ++ uintptr_t img_addr; ++ sw_attestation_tlv_t *tlv; ++ ++ if (!tlv_ptr) ++ return -1; ++ ++ tlv = *tlv_ptr; ++ ++ /* default to error */ ++ ret = -1; ++ ++ img_addr = simple_strtoul(img_str, NULL, 16); ++ fit_parse_subimage(img_str, img_addr, &img_addr, &img_name); ++ fit_hdr = (void *)img_addr; ++ ++ if ((genimg_get_format(fit_hdr) != IMAGE_FORMAT_FIT) || ++ !fit_check_format(fit_hdr)) ++ return ret; ++ ++ /* Find images parent node offset */ ++ images_noffset = fdt_path_offset(fit_hdr, FIT_IMAGES_PATH); ++ if (images_noffset < 0) ++ return ret; ++ ++ for (ndepth = 0, count = 0, ++ noffset = fdt_next_node(fit_hdr, images_noffset, &ndepth); ++ (noffset >= 0) && (ndepth > 0); ++ noffset = img_name ? -1 : ++ fdt_next_node(fit_hdr, noffset, &ndepth)) { ++ /* if image was specified, use its offset */ ++ if (img_name) { ++ noffset = fdt_subnode_offset(fit_hdr, images_noffset, ++ img_name); ++ if (noffset < 0) { ++ printf("Unable to locate '%s'...\n", img_name); ++ continue; ++ } ++ ndepth = 1; ++ } ++ ++ if (ndepth == 1) { ++ /* ++ * Direct child node of the images parent node, ++ * i.e. component image node. ++ */ ++ count++; ++ ++ fit_image_get_type(fit_hdr, noffset, &img_type); ++ if (img_type != IH_TYPE_KERNEL) { ++ printf("img type not KERNEL (%d)\n", img_type); ++ continue; ++ } ++ ++ /* locate the HASH for this image */ ++ fdt_for_each_subnode(subnoffset, fit_hdr, noffset) { ++ name = fit_get_name(fit_hdr, subnoffset, NULL); ++ if (strncmp(name, FIT_HASH_NODENAME, ++ strlen(FIT_HASH_NODENAME))) ++ continue; ++ ++ if (fit_image_hash_get_value(fit_hdr, ++ subnoffset, ++ &fit_value, ++ &fit_value_len)) ++ continue; ++ ++ len = fit_value_len; ++ tlv->type_be = htons(ATT_IMG_FIT_KERNEL); ++ tlv->length_be = htons(len); ++ if (((uintptr_t)tlv + len) > (uintptr_t) ++ tlv_limit) ++ break; ++ ++ memcpy(tlv->value, fit_value, len); ++ tlv = (sw_attestation_tlv_t *)&tlv->value[len]; ++ ret = 0; ++ break; ++ } ++ break; ++ } ++ } ++ ++ *tlv_ptr = tlv; ++ ++ return ret; ++} ++ ++U_BOOT_CMD(attest, 3, 0, do_attest, ++ "Retrieve attestation information", ++ " []\n" ++ " - consists of ASCII characters.\n" ++ " - specifies FIT image containing Linux kernel.\n" ++ " This supports the FIT syntax .\n" ++ "\nExample: attest ABCDEF0123\n" ++); +diff --git a/cmd/marvell/octeontx2_failsafe_cmds.c b/cmd/marvell/octeontx2_failsafe_cmds.c +new file mode 100644 +index 0000000000..785f300095 +--- /dev/null ++++ b/cmd/marvell/octeontx2_failsafe_cmds.c +@@ -0,0 +1,22 @@ ++/* ++ * Copyright (C) 2018 Marvell International Ltd. ++ * ++ * SPDX-License-Identifier: GPL-2.0 ++ * https://spdx.org/licenses ++ */ ++ ++#include ++#include ++#include ++ ++static int do_fsafe_clr( ++ cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) ++{ ++ (void)smc_flsf_clr_force_2ndry(); ++ return CMD_RET_SUCCESS; ++} ++ ++U_BOOT_CMD( ++ fsafe_clr, 1, 0, do_fsafe_clr, ++ "Marvell OcteonTX2 Fail Safe: clear secondary boot", "" ++); +diff --git a/cmd/marvell/octeontx2_qlm_cmds.c b/cmd/marvell/octeontx2_qlm_cmds.c +new file mode 100644 +index 0000000000..caa40abcbf +--- /dev/null ++++ b/cmd/marvell/octeontx2_qlm_cmds.c +@@ -0,0 +1,86 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * https://spdx.org/licenses ++ * ++ * Copyright (C) 2019 Marvell International Ltd. ++ */ ++ ++#include ++#include ++ ++extern int cgx_intf_prbs(u8 qlm, u8 mode, u32 time, u32 lane); ++extern int cgx_intf_display_eye(u8 qlm, u8 lane); ++extern int cgx_intf_display_serdes(u8 qlm, u8 lane); ++ ++static int do_prbs(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) ++{ ++ ulong time; ++ ulong mode; ++ ulong qlm; ++ ulong lane; ++ ++ if (argc == 5) { ++ qlm = simple_strtoul(argv[1], NULL, 10); ++ lane = simple_strtoul(argv[2], NULL, 10); ++ mode = simple_strtoul(argv[3], NULL, 10); ++ time = simple_strtoul(argv[4], NULL, 10); ++ } else { ++ return CMD_RET_USAGE; ++ } ++ ++ cgx_intf_prbs(qlm, mode, time, lane); ++ ++ return CMD_RET_SUCCESS; ++} ++ ++U_BOOT_CMD(prbs, 5, 1, do_prbs, ++ "command to run PRBS on slected QLM", ++ "