diff --git a/.gitignore b/.gitignore index 001d99a..da7e323 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ vscode-bitbake-build/ documentation/_build/ documentation/oe-logs documentation/oe-workdir -__pycache__ \ No newline at end of file +__pycache__ +.venv/ diff --git a/.gitmodules b/.gitmodules index e531f44..6b44124 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,22 +3,22 @@ url = ssh://git@bitbucket.gad.local:7999/ico/bitbake.git branch = 2.0 [submodule "layers/openembedded-core"] - path = layers/openembedded-core + path = external-layers/openembedded-core url = ssh://git@bitbucket.gad.local:7999/ico/openembedded-core.git branch = kirkstone [submodule "layers/meta-openembedded"] - path = layers/meta-openembedded + path = external-layers/meta-openembedded url = ssh://git@bitbucket.gad.local:7999/ico/meta-openembedded.git branch = kirkstone [submodule "layers/meta-virtualization"] - path = layers/meta-virtualization + path = external-layers/meta-virtualization url = ssh://git@bitbucket.gad.local:7999/ico/meta-virtualization.git branch = kirkstone [submodule "layers/meta-efibootguard"] - path = layers/meta-efibootguard + path = external-layers/meta-efibootguard url = ssh://git@bitbucket.gad.local:7999/ico/meta-efibootguard.git - branch = coreos/master + branch = master [submodule "layers/meta-swupdate"] - path = layers/meta-swupdate + path = external-layers/meta-swupdate url = ssh://git@bitbucket.gad.local:7999/ico/meta-swupdate.git branch = kirkstone diff --git a/.vscode/extensions.json b/.vscode/extensions.json index c39b0c8..ac5a5fb 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,6 +1,10 @@ { "recommendations": [ "ms-vscode.makefile-tools", - "timonwong.shellcheck" + "timonwong.shellcheck", + "eugenwiens.bitbake", + "kweihmann.oelint-vscode", + "lextudio.restructuredtext", + "trond-snekvik.simple-rst" ] } \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index b6d0c36..86af9a6 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -3,7 +3,10 @@ "**/build/cache/**": true, "**/build/downloads/**": true, "**/build/sstate-cache/**": true, - "**/build/tmp/**": true + "**/build/tmp/**": true, + "**/documentation/_build/**": true, + "**/build/workspace": true }, - "python.formatting.provider": "black" + "python.formatting.provider": "black", + "editor.rulers": [80,100,120] } \ No newline at end of file diff --git a/bitbake b/bitbake index 0c6f86b..907416e 160000 --- a/bitbake +++ b/bitbake @@ -1 +1 @@ -Subproject commit 0c6f86b60cfba67c20733516957c0a654eb2b44c +Subproject commit 907416ee1062f87f5844ab0638b54616abfc1a22 diff --git a/coreos-init-build-env b/coreos-init-build-env index 4c9762e..fa54294 100755 --- a/coreos-init-build-env +++ b/coreos-init-build-env @@ -26,7 +26,7 @@ COREOS_ROOT=$(readlink -f "${COREOS_ROOT}") # Set the path to bitbake, openembedded-core and the template directory # All theses values can be overriden by the caller of coreos-init-build-env BITBAKEDIR="${BITBAKEDIR:-${COREOS_ROOT}/bitbake}" -OEROOT="${OEROOT:-${COREOS_ROOT}/layers/openembedded-core}" +OEROOT="${OEROOT:-${COREOS_ROOT}/external-layers/openembedded-core}" TEMPLATECONF="${TEMPLATECONF:-${COREOS_ROOT}/templates}" # Sanity checks @@ -84,6 +84,13 @@ coreos_path_add "${COREOS_ROOT}/scripts" # Add support for ##COREOS_LAYERSDIR## inside of bblayer template coreos-bblayers-envsub COREOS_LAYERSDIR "${COREOS_ROOT}/layers" +# Add support for ##COREOS_EXTLAYERSDIR## inside of bblayer template +coreos-bblayers-envsub COREOS_EXTLAYERSDIR "${COREOS_ROOT}/external-layers" + # Generate the ${BUILDDIR}/key directory. The scripts doesn't generate anything it # the directory already exist, so it's safe to call it everytime -coreos-keygen > /dev/null 2> /dev/null +# stdout is redirected to reduce the amount of output but not stderr +coreos-keygen > /dev/null || { + echo "The coreos-keygen script has failed" >&2 + return 1 +} \ No newline at end of file diff --git a/documentation/boot/overview.rst b/documentation/boot/overview.rst index 9c22297..3b5970a 100644 --- a/documentation/boot/overview.rst +++ b/documentation/boot/overview.rst @@ -63,6 +63,11 @@ machine. Firmware requirements --------------------- +.. warning:: + + CoreOS support at the moment only hardware that contains a block storage + device (SD Card, eMMC, ...) formatted with GPT. MBR disk or MTD device are + not supported. ARM32 / AArch32 based machine ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -70,10 +75,7 @@ ARM32 / AArch32 based machine The firmware for ARM32 should implement a subset of the UEFI specification, as defined by the EBBR Specification. As this architecure is used on old hardware, it's ok to use the part of the specification that are marked as deprecated or -legacy like: - -- MBR partitionning instead of GPT -- Fixed offsets to firmware data +legacy. We require the firmware to provide a DeviceTree based system description and not an ACPI based table (as allowed by the specification). diff --git a/documentation/components/optional/index.rst b/documentation/components/optional/index.rst index 1bd8a95..20cb7d2 100644 --- a/documentation/components/optional/index.rst +++ b/documentation/components/optional/index.rst @@ -12,3 +12,4 @@ CoreOS Optional Components Network Manager: NetworkManager SSH Server: OpenSSH Container: Podman + CoreOS Installer diff --git a/documentation/components/optional/installer.rst b/documentation/components/optional/installer.rst new file mode 100644 index 0000000..b3858e4 --- /dev/null +++ b/documentation/components/optional/installer.rst @@ -0,0 +1,35 @@ +.. index:: COREOS_INSTALLER + +CoreOS Installer +**************** + +The CoreOS installer is a set of script running on the target and a +corresponding bitbake image that is used into the bootstrap process of CoreOS. + +coreos-image-installer +====================== + +The CoreOS installer image is a single binary EFI file that include a kernel, +device tree and an initramfs with all the tools needed to install CoreOS. + +An installer image is automatically built in parallel of a normal image. +This can be deactivated by setting `COREOS_IMAGE_GENERATE_INSTALLER` to 0. + +The installer image build by default only a single EFI binary named +coreos-installer-MACHINE.efi. An SDCard image can be generate if +`COREOS_INSTALLER_WKS_FILE` is set to a wks file. + +coreos-installer +================ + +The coreos-installer recipe installs some script that is used at startup +to automatically format the internal emmc of the device. It also contains +a swupdate configuration file to setup swupdate correctly for that use case. + +coreos-installer-config +======================= + +The coreos-installer-config recipe installs device specific configuration file +used by the coreos-installer. This includes the partitionner config file. Distro +and project based on CoreOS can change the partionning scheme or partition size +by installing their own version of this package using a `bbappend file`. diff --git a/documentation/hardware/beaglebone.rst b/documentation/hardware/beaglebone.rst new file mode 100644 index 0000000..10f6eda --- /dev/null +++ b/documentation/hardware/beaglebone.rst @@ -0,0 +1,61 @@ +.. _beaglebone: + +********** +BeagleBone +********** + +.. important:: + + The BeagleBone target uses an old TI AM3358 ARM 32 BIT CPU. This processor + of the AM335x family is used in a lot of current and legacy device at + Hirschmann and NetModule. Thus we only support this target to ensure + that our architecture is working on older architecture too. + +CoreOS build instruction +======================== + +.. code-block:: + + MACHINE=beaglebone bitbake coreos-image-all-features + cd tmp/deploy/images/beaglebone + +.. list-table:: Image artifacts for BeagleBone + :widths: 25 75 + :header-rows: 1 + + * - Filename + - Description + * - -beaglebone.swu + - System image bundle used by the CoreOS installer or the CoreOS updater + * - -beaglebone.wic.xz + - System image for SDCard + * - coreos-image-installer-beaglebone.wic.xz + - CoreOS installer image for SD Card + +.. hint:: + + Only the .swu image is need if you have already a working installation of CoreOS + running on the board that you want to update. + +CoreOS Pre-installation guide +============================= + +If you want to use the internal emmc storage as boot target, you will need to +flash coreos-image-installer-beaglebone.wic.xz to your SDCard using bmaptool. + +If you want to use the sdcard as boot target, you will need to flash +-beaglebone.wic.xz to your SDCard using bmaptool. + +By default the board boot on the internal emmc storage. To boot with a SDCard +instead, you will need to push the S2 button (boot switch) while powering up the +board. + +.. image:: beaglebone/beaglebone-s2-switch.png + +Serial access is available on the 5-pin header. See +`this page `_ for +more info on the serial connector. + +Now that you have the installer running, CoreOS can be installed by following +the :ref:`generic installation manual` using the SDCard +mehtod. diff --git a/documentation/hardware/beaglebone/beaglebone-s2-switch.png b/documentation/hardware/beaglebone/beaglebone-s2-switch.png new file mode 100644 index 0000000..d99bcdf Binary files /dev/null and b/documentation/hardware/beaglebone/beaglebone-s2-switch.png differ diff --git a/documentation/hardware/netmodule-hw34.rst b/documentation/hardware/netmodule-hw34.rst new file mode 100644 index 0000000..cfccf60 --- /dev/null +++ b/documentation/hardware/netmodule-hw34.rst @@ -0,0 +1,126 @@ +.. _netmodule-hw34: + +******************************* +NetModule HW34 (XG900 A-Sample) +******************************* + +.. important:: + + netmodule-hw34 support is currently only available on the features branch + feat/netmodule-bsp + +.. image:: netmodule-hw34/hw34.png + +CoreOS build instruction +======================== + +.. code-block:: + + MACHINE=netmodule-hw34 bitbake coreos-image-all-features + cd tmp/deploy/images/netmodule-hw34 + +.. list-table:: Image artifacts for NetModule HW32 + :widths: 25 75 + :header-rows: 1 + + * - Filename + - Description + * - -netmodule-hw34.swu + - System image bundle used by the CoreOS installer or the CoreOS updater + * - coreos-installer-netmodule-hw34.efi + - CoreOS installer bundled in a single EFI binary + * - tiboot3.bin + - SPL Bootloader for the wakeup domain (arm32 R5 core) + * - tispl.bin + - SPL bootloader for the main domain (aarch64 main core) + * - u-boot.bin + - Third stage bootloader the main domain (aarch64 main core) + +.. hint:: + + Only the .swu image is need if you have already a working installation of CoreOS + running on the board that you want to update. + +CoreOS Pre-installation guide +============================= + +The CoreOS installation process expect a working EFI firmware based on u-boot +running on the board. + +For board that have no firmware or a defect firmware, we can provide the firmware by +booting over USB. + +First, we need to put the board in USB Boot mode by modifying the dip-switch +on the back of the board: + +.. code-block:: + + ON + S500 ▄ ▀ ▄ ▀ ▄ ▄ ▄ ▄ + 1 2 3 4 5 6 7 8 + +.. hint:: + + Unflashed board or board without a valid tiboot3.bin image will default to + USB boot mode, so settings the dip-switch may be skipped in this case. + +Then you need to populate the jumper X600 near the USB port: + +.. image:: netmodule-hw34/hw34-usb-device.png + +Then power-up the board by first apply 12V throug the main connector, then +connect a USB-C cable. Console access to the board can be accessed using the +serial port on the main connector. + + +.. important:: + + When removing the power, ensure that the USB cable is removed first. Otherwise + the processor will not get shutdown properly + + +Now you should see the board from you computer: + +.. code-block:: sh + + lsusb | grep DFU + Bus 003 Device 048: ID 0451:6165 Texas Instruments, Inc. AM64x DFU + +Now we start downloading the bootloaders into RAM by using dfu-utils: + +.. code-block:: sh + + dfu-util -D tiboot3.bin -a 0 + dfu-util -D tispl.bin -a 0 + + # Eject and start execution of tispl + dfu-util -e -a 0 + dfu-util -D u-boot.img -a 1 + + # Eject ans tart of u-boot.img + dfu-util -e -a 1 + +.. hint:: + + The firmware was uploaded to the RAM, thus will not survice a reboot. + + +Now that we have a firmware running, CoreOS can be installed by following +the :ref:`generic installation manual`. + + +CoreOS Post-Installation +======================== + +When the installation of CoreOS is done, power down the board by first +removing the USB-C cable then the main power. + +Now, put the board back in emmc boot mode: + +.. code-block:: + + ON + S500 ▀ ▄ ▄ ▀ ▄ ▄ ▄ ▄ + 1 2 3 4 5 6 7 8 + +Then power-up the board again and CoreOS should boot. diff --git a/documentation/hardware/netmodule-hw34/hw34-usb-device.png b/documentation/hardware/netmodule-hw34/hw34-usb-device.png new file mode 100644 index 0000000..891e473 Binary files /dev/null and b/documentation/hardware/netmodule-hw34/hw34-usb-device.png differ diff --git a/documentation/hardware/netmodule-hw34/hw34.png b/documentation/hardware/netmodule-hw34/hw34.png new file mode 100644 index 0000000..4ee69b2 Binary files /dev/null and b/documentation/hardware/netmodule-hw34/hw34.png differ diff --git a/documentation/hardware/overview.rst b/documentation/hardware/overview.rst new file mode 100644 index 0000000..cce0fa4 --- /dev/null +++ b/documentation/hardware/overview.rst @@ -0,0 +1,33 @@ +****************** +Supported Hardware +****************** + +.. _Hardware Overview: +.. list-table:: Supported BitBake MACHINE + :widths: 25 75 25 + :header-rows: 1 + + * - BitBake MACHINE + - Compatible hardware + - Documentation + * - cn9131-bldn-mbv + - Falcon A3 Sample + - + * - netmodule-hw34 + - NetModule HW34 (XG900 Sample) + - :ref:`🔗 links ` + * - cn9130-cf-pro + - Solidrun cn9130-cf-pro + - + * - beaglebone + - Beaglebone, Beaglebone Black, Beaglebone Green + - :ref:`🔗 links ` + * - vm-x64 + - Virtual Machine + - + +.. hint:: + + Please contact the CoreOS team when starting a new project based on CoreOS + or want to contribute the hardware support for an existing Hardware. + diff --git a/documentation/index.rst b/documentation/index.rst index a90d640..fa6029f 100644 --- a/documentation/index.rst +++ b/documentation/index.rst @@ -28,20 +28,28 @@ same structures. .. toctree:: :maxdepth: 1 - :caption: Software Components - - Core Components - Optional Components + :caption: Supported Hardware + Overview + NetModule HW34 (XG900 Sample) + BeagleBone .. toctree:: :maxdepth: 1 :caption: Manuals + Installation Manual Reference Manual Boot Concepts Best Practices +.. toctree:: + :maxdepth: 1 + :caption: Software Components + + Core Components + Optional Components + .. toctree:: :maxdepth: 1 :caption: Indexes diff --git a/documentation/installation/index.rst b/documentation/installation/index.rst new file mode 100644 index 0000000..646d020 --- /dev/null +++ b/documentation/installation/index.rst @@ -0,0 +1,22 @@ + +.. _Installation Manual: + +====================================== +Belden CoreOS EMMC Installation Manual +====================================== + +.. important:: + + This manual expect that the board you want to install CoreOS on have a + running UEFI firmware based on u-boot. Information about how to get console + access and a running firmware can be found for your hardware in the + :ref:`Hardware Overview ` + +| + +.. toctree:: + :caption: Table of Contents + :numbered: + + starting + partitionning \ No newline at end of file diff --git a/documentation/installation/partitionning.rst b/documentation/installation/partitionning.rst new file mode 100644 index 0000000..727b7f2 --- /dev/null +++ b/documentation/installation/partitionning.rst @@ -0,0 +1,50 @@ +************ +Installation +************ + +The installer automatically creates all the needed partitions when starting up. + +Now you have to upload the .swu file to start the flashing process. + +Choose one of these methods to upload the system image to the installer: + +Upload the .swu file over the network using a browser +===================================================== + + +Now you can install the desired CoreOS version by uploading the desired +.swu file to the board using a browser, by going to http://:8080 + +Upload the .swu file over the network using devtool +=================================================== + +If you have a working build environement, you can upload the image using +the devtool command: + +.. code-block:: + + MACHINE= devtool swupdate-www-push + + +.. hint:: + Replace with the image recipe name, eg: coreos-image-all-features + Replace by the machine name (if not set in local.conf) + Replace by the IP adress of the board + +Upload the .swu file over the network using coreos-device +========================================================= + +If you don't have a working build environement, you can upload the image using +the coreos-device python script: + +.. code-block:: + + ./coreos-device swupdate-www-push + +.. hint:: + Replace with the the path to the SWU, eg: ./coreos-image-all-features-.swu + Replace by the IP adress of the board + +.. hint:: + You will find the coreos-device script under the scripts directory inside + the CoreOS repository. diff --git a/documentation/installation/starting.rst b/documentation/installation/starting.rst new file mode 100644 index 0000000..ee9fc3d --- /dev/null +++ b/documentation/installation/starting.rst @@ -0,0 +1,64 @@ +********************** +Starting the installer +********************** + +Choose one of these methods to start the bootloader: + +Starting the installer over the network with TFTP +================================================= + +Put the coreos-installer EFI bundle (coreos-installer-.efi) into an +accessible TFTP server, then enter the following command into u-boot: + +.. code-block:: + + setenv ipaddr ; setenv serverip ; + tftp $loadaddr coreos-installer-.efi + bootefi $loadaddr + +.. hint:: + + Replace by a valid IP adress for the target, eg: 192.168.1.1 + Replace by the IP adress of the server, eg: 192.168.1.254 + Replace by the name of the machine set in bitbake + +Starting the installer over the network with DHCP/BOOTP/TFTP +============================================================ + +Use a DHCP/BOOTP/TFTP server to configure automatically the device. You can +use dnsmasq for this task. + + +.. code-block: ini + + interface= + + dhcp-range=,10.237.30.2,10.237.30.100,4h + dhcp-range=,10.237.40.2,10.237.40.100,4h + + enable-tftp + dhcp-boot=tag:,coreos-installer-.efi + tftp-root=/var/lib/tftpboot + +.. hint:: + + Replace by the name of the network interface that is connected + to the target. Eg: enp3s0 + Replace by the name of the machine set in bitbake + +Put the coreos-installer EFI bundle (coreos-installer-.efi) into the +/var/lib/tftpboot folder then enter the following command into u-boot: + +.. code-block:: + + setenv autoload yes + setenv autostart no + dhcp + bootefi $loadaddr + +Starting the installer using an SD Card +======================================= + +Flash the coreos-image-installer.wic.xz into an SDCard and put the board +in SDCard boot mode. Insert the SDCard and power up the board. The CoreOS +installer should start automatically. diff --git a/documentation/quick-build.rst b/documentation/quick-build.rst index 7fec776..45d29f7 100644 --- a/documentation/quick-build.rst +++ b/documentation/quick-build.rst @@ -46,7 +46,7 @@ Theses packages are needed on your build machine: chrpath socat cpio python3 python3-pip python3-pexpect xz-utils \ debianutils iputils-ping python3-git python3-jinja2 libegl1-mesa \ libsdl1.2-dev pylint3 xterm python3-subunit mesa-common-dev zstd \ - liblz4-tool bmap-tools efitools openssl sbsign python3-click \ + liblz4-tool bmap-tools efitools openssl sbsigntool python3-click \ python3-aiohttp Use Git to clone CoreOS diff --git a/documentation/ref-manual/features.rst b/documentation/ref-manual/features.rst index 810821b..8b24be0 100644 --- a/documentation/ref-manual/features.rst +++ b/documentation/ref-manual/features.rst @@ -10,9 +10,14 @@ to Belden CoreOS. Machine Features ================ -CoreOS doesn't define any custom machine feature for now, but the :external:ref:`MACHINE_FEATURES ` of OpenEmbedded-Core -can be used. +can be used with CoreOS. + +In addition, those CoreOS specific MACHINE_FEATURES can be used too: + +- *sdcard:* the machine as an internal SD Card or MicroSD Slot. +- *emmc:* the machine as an internal emmc based storage + .. index:: DISTRO_FEATURES diff --git a/external-layers/meta-efibootguard b/external-layers/meta-efibootguard new file mode 160000 index 0000000..e3581b1 --- /dev/null +++ b/external-layers/meta-efibootguard @@ -0,0 +1 @@ +Subproject commit e3581b11d30d91d0363acb48a6aee47043b7e0bc diff --git a/external-layers/meta-openembedded b/external-layers/meta-openembedded new file mode 160000 index 0000000..3467537 --- /dev/null +++ b/external-layers/meta-openembedded @@ -0,0 +1 @@ +Subproject commit 346753705e49a2486867dc150181a1c7f4d69377 diff --git a/external-layers/meta-swupdate b/external-layers/meta-swupdate new file mode 160000 index 0000000..eaa4dcb --- /dev/null +++ b/external-layers/meta-swupdate @@ -0,0 +1 @@ +Subproject commit eaa4dcbac224c9f5e7da784dcda78b67f117cf63 diff --git a/external-layers/meta-virtualization b/external-layers/meta-virtualization new file mode 160000 index 0000000..af02908 --- /dev/null +++ b/external-layers/meta-virtualization @@ -0,0 +1 @@ +Subproject commit af02908efda1580e77b3fdeed25b124a2b8d9482 diff --git a/external-layers/openembedded-core b/external-layers/openembedded-core new file mode 160000 index 0000000..8ce2b1a --- /dev/null +++ b/external-layers/openembedded-core @@ -0,0 +1 @@ +Subproject commit 8ce2b1a3083f61e5a3df3a80c3de7d294bc71bb5 diff --git a/layers/meta-belden-coreos-bsp/classes/coreos-image-swupdate-beaglebone.bbclass b/layers/meta-belden-coreos-bsp/classes/coreos-image-swupdate-beaglebone.bbclass new file mode 100644 index 0000000..95141f4 --- /dev/null +++ b/layers/meta-belden-coreos-bsp/classes/coreos-image-swupdate-beaglebone.bbclass @@ -0,0 +1,26 @@ + +SWUPDATE_IMAGES += "MLO" +SWUPDATE_IMAGES += "u-boot-beaglebone" +SWUPDATE_IMAGES_FSTYPES[MLO] = "" +SWUPDATE_IMAGES_FSTYPES[u-boot-beaglebone] = ".img" + +COREOS_SWUPDATE_EXTENDS_FOR:append = "beaglebone" + +def coreos_swupdate_extends_images_for_beaglebone(d,s): + mlo = { + "filename" : "MLO", + "installed-directly" : "true", + "device" : "/dev/disk/by-partlabel/mlo", + "type" : "raw", + "sha256" : swupdate_get_sha256(d, s, "MLO"), + } + + uboot = { + "filename" : "u-boot-beaglebone.img", + "installed-directly" : "true", + "device" : "/dev/disk/by-partlabel/uboot", + "type" : "raw", + "sha256" : swupdate_get_sha256(d, s, "u-boot-beaglebone.img"), + } + + return [mlo, uboot] diff --git a/layers/meta-belden-coreos-bsp/conf/machine/beaglebone.conf b/layers/meta-belden-coreos-bsp/conf/machine/beaglebone.conf index a7e1f4c..d5dc4b4 100644 --- a/layers/meta-belden-coreos-bsp/conf/machine/beaglebone.conf +++ b/layers/meta-belden-coreos-bsp/conf/machine/beaglebone.conf @@ -11,6 +11,7 @@ include conf/machine/include/arm/armv7a/tune-cortexa8.inc IMAGE_FSTYPES += "wic wic.xz wic.bmap" WKS_FILE ?= "beaglebone-sdcard.wks.in" +COREOS_INSTALLER_WKS_FILE ?= "beaglebone-sdcard-installer.wks" MACHINE_ESSENTIAL_EXTRA_RDEPENDS += "kernel-image kernel-devicetree" do_image_wic[depends] += "mtools-native:do_populate_sysroot dosfstools-native:do_populate_sysroot gptfdisk-native:do_populate_sysroot virtual/bootloader:do_deploy" do_image_wic[recrdeptask] += "do_bootimg" @@ -36,9 +37,6 @@ UBOOT_LOADADDRESS = "0x80008000" MACHINE_FEATURES = "usbgadget usbhost vfat alsa" -IMAGE_BOOT_FILES ?= "u-boot.${UBOOT_SUFFIX} ${SPL_BINARY}" -IMAGE_EFI_BOOT_FILES ?= "${KERNEL_DEVICETREE}" - # support runqemu EXTRA_IMAGEDEPENDS += "qemu-native qemu-helper-native" IMAGE_CLASSES += "qemuboot" @@ -59,12 +57,7 @@ QB_TCPSERIAL_OPT = "-device virtio-serial-device -chardev socket,id=virtcon,port # No watchdog available yet EFIBOOTGUARD_TIMEOUT ?= "0" -# MBR disk can't select the root device by partition label as MBR doesn't have -# a partition label. Using filesystem label only work with an initramfs and we -# don't support it yet. -COREOS_PLATFORM0_ROOT ?= "/dev/mmcblk0p3" -COREOS_PLATFORM1_ROOT ?= "/dev/mmcblk0p4" +COREOS_IMAGE_SWUPDATE_EXTRACLASSES += "coreos-image-swupdate-beaglebone" require conf/machine/include/coreos-generic-features/efi.inc -require conf/machine/include/coreos-generic-features/legacy-mbr-disk.inc -require conf/machine/include/coreos-generic-features/emmc.inc +require conf/machine/include/coreos-generic-features/partitions.inc diff --git a/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-features/efi.inc b/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-features/efi.inc index 19e10d4..44c7808 100644 --- a/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-features/efi.inc +++ b/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-features/efi.inc @@ -4,11 +4,3 @@ MACHINE_FEATURES:append = " efi" do_image_wic[depends] += "efibootguard-native:do_populate_sysroot efibootguard:do_deploy" - -# Variable used in WKS file - -WKS_PART_EFI ??= 'part --source efibootguard-efi --label efi --align 1024 --part-type=EF00' -WKS_PART_ROOT_A ??= 'part / --source rootfs --fstype=ext4 --label platform0 --align 1024' -WKS_PART_ROOT_B ??= 'part --fstype=ext4 --label platform1 --align 1024' -WKS_PART_EFIBOOTGUARD_A ??= 'part --source efibootguard-boot --label boot0 --align 1024 --part-type=0700 --sourceparams "watchdog=${EFIBOOTGUARD_TIMEOUT},revision=2,kernel=kernel0-${MACHINE}.efi;KERNEL0.EFI"' -WKS_PART_EFIBOOTGUARD_B ??= 'part --source efibootguard-boot --label boot1 --align 1024 --part-type=0700 --sourceparams "watchdog=${EFIBOOTGUARD_TIMEOUT},revision=1,kernel=kernel1-${MACHINE}.efi;KERNEL1.EFI"' diff --git a/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-features/emmc.inc b/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-features/emmc.inc deleted file mode 100644 index 87e64f5..0000000 --- a/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-features/emmc.inc +++ /dev/null @@ -1,7 +0,0 @@ -# This configuration file should be included for all hardware that has an -# integrated emmc - -MACHINE_FEATURES += "emmc" - -# Generate a SWU image to flash the emmc -do_image[depends] += "coreos-emmc-flasher-${MACHINE}:do_swuimage" diff --git a/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-features/legacy-mbr-disk.inc b/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-features/legacy-mbr-disk.inc deleted file mode 100644 index 9997044..0000000 --- a/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-features/legacy-mbr-disk.inc +++ /dev/null @@ -1,19 +0,0 @@ - -# MBR disk are still supported by CoreOS, but only for legacy product -# This ensure that efibootguard / swupdate work with MBR disk - -# Do not include this file in a machine configuration if the machine support -# a GPT disk instead -COREOS_DISK_PARTLABEL_LOOKUP_DIRECTORY ?= "/dev/disk/by-label" - -# MBR can't disk can't use partition label, but may use filesystem label -# This will only work with an initramfs. If no initramfs is used, this will -# have to be set to the right disk device inside the machine configuration -# like that COREOS_PLATFORMx_ROOT = "/dev/mmcblkp" -COREOS_PLATFORM0_ROOT ?= "LABEL=platform0" -COREOS_PLATFORM1_ROOT ?= "LABEL=platform1" - -# MBR disk can't use --part-type but can use system-id -WKS_PART_EFI ?= 'part --source efibootguard-efi --label efi --system-id 0xef' -WKS_PART_EFIBOOTGUARD_A ?= 'part --source efibootguard-boot --label boot0 --sourceparams "watchdog=${EFIBOOTGUARD_TIMEOUT},revision=2,kernel=kernel0-${MACHINE}.efi;KERNEL0.EFI"' -WKS_PART_EFIBOOTGUARD_B ?= 'part --source efibootguard-boot --label boot1 --sourceparams "watchdog=${EFIBOOTGUARD_TIMEOUT},revision=1,kernel=kernel1-${MACHINE}.efi;KERNEL1.EFI"' diff --git a/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-features/partitions.inc b/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-features/partitions.inc new file mode 100644 index 0000000..d2aa1a4 --- /dev/null +++ b/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-features/partitions.inc @@ -0,0 +1,15 @@ + +# Variable used in WKS file + +WKS_PART_EFI ??= 'part --source efibootguard-efi --label efi --part-type=EF00' +WKS_PART_EFIBOOTGUARD_A ??= 'part --source efibootguard-boot --label ebg0 --part-type=0700 --sourceparams "args=coreos.root=rootfs0,watchdog=${EFIBOOTGUARD_TIMEOUT},revision=2,kernel=kernel-${MACHINE}.efi;KERNEL.EFI"' +WKS_PART_EFIBOOTGUARD_B ??= 'part --source efibootguard-boot --label ebg1 --part-type=0700 --sourceparams "args=coreos.root=rootfs1,watchdog=${EFIBOOTGUARD_TIMEOUT},revision=1,kernel=kernel-${MACHINE}.efi;KERNEL.EFI"' +WKS_PART_ROOT_A ??= 'part / --source rootfs --fstype=ext4 --label rootfs0' +WKS_PART_ROOT_B ??= 'part --fstype=ext4 --label rootfs1' +WKS_PART_ROOT_SIZE ??= '2G' + +SFDISK_PART_EFI ??= 'type=C12A7328-F81F-11D2-BA4B-00A0C93EC93B, name="efi"' +SFDISK_PART_EFIBOOTGUARD_A ??= 'type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7, name="ebg0"' +SFDISK_PART_EFIBOOTGUARD_B ??= 'type=EBD0A0A2-B9E5-4433-87C0-68B6B72699C7, name="ebg1"' +SFDISK_PART_ROOT_A ??= 'type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="rootfs0"' +SFDISK_PART_ROOT_B ??= 'type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, name="rootfs0"' diff --git a/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-machine/vm.inc b/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-machine/vm.inc index eef8e70..b9c3df6 100644 --- a/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-machine/vm.inc +++ b/layers/meta-belden-coreos-bsp/conf/machine/include/coreos-generic-machine/vm.inc @@ -22,3 +22,4 @@ do_image_wic[recrdeptask] += "do_bootimg" COREOS_EFI_SECUREBOOT_INSTALL_PUBKEY_IN_EFIDIR = "1" require conf/machine/include/coreos-generic-features/efi.inc +require conf/machine/include/coreos-generic-features/partitions.inc diff --git a/layers/meta-belden-coreos-bsp/recipes-bsp/coreos-emmc-flasher/coreos-emmc-flasher-beaglebone.bb b/layers/meta-belden-coreos-bsp/recipes-bsp/coreos-emmc-flasher/coreos-emmc-flasher-beaglebone.bb deleted file mode 100644 index f3d2678..0000000 --- a/layers/meta-belden-coreos-bsp/recipes-bsp/coreos-emmc-flasher/coreos-emmc-flasher-beaglebone.bb +++ /dev/null @@ -1,6 +0,0 @@ -COMPATIBLE_MACHINE = "beaglebone" - -require coreos-emmc-flasher.inc -require coreos-emmc-flasher-uboot.inc - -SWUPDATE_IMAGES += "MLO" diff --git a/layers/meta-belden-coreos-bsp/recipes-bsp/coreos-emmc-flasher/coreos-emmc-flasher-beaglebone/sw-description b/layers/meta-belden-coreos-bsp/recipes-bsp/coreos-emmc-flasher/coreos-emmc-flasher-beaglebone/sw-description deleted file mode 100644 index a2b6359..0000000 --- a/layers/meta-belden-coreos-bsp/recipes-bsp/coreos-emmc-flasher/coreos-emmc-flasher-beaglebone/sw-description +++ /dev/null @@ -1,48 +0,0 @@ -software = -{ - version = "@@DISTRO_VERSION@@"; - @@MACHINE@@ = { - hardware-compatibility: ["1.0"]; - factory = { - emmc = { - partitions: ( - { - type = "diskpart"; - device = "/dev/mmcblk1"; - properties: { - labeltype = "dos"; - partition-1 = [ "size=32M", "start=133120", "name=efi", "type=0xef", "fstype=fat16"]; - }; - } - ); - images: ( - { - filename = "MLO"; - device = "/dev/mmcblk1"; - offset = "128K"; - sha256 = "$swupdate_get_sha256(MLO)"; - }, - { - filename = "u-boot-beaglebone.img"; - device = "/dev/mmcblk1"; - offset = "384K"; - sha256 = "$swupdate_get_sha256(u-boot-beaglebone.img)"; - - } - ); - files: ( - { - filename = "efibootguardarm.efi"; - path = "/EFI/BOOT/bootarm.efi"; - device = "/dev/mmcblk1p1"; - filesystem = "vfat"; - sha256 = "$swupdate_get_sha256(efibootguardarm.efi)"; - properties: { - create-destination = "true"; - } - } - ); - } - } - } -} diff --git a/layers/meta-belden-coreos-bsp/recipes-bsp/coreos-emmc-flasher/coreos-emmc-flasher-uboot.inc b/layers/meta-belden-coreos-bsp/recipes-bsp/coreos-emmc-flasher/coreos-emmc-flasher-uboot.inc deleted file mode 100644 index f096e38..0000000 --- a/layers/meta-belden-coreos-bsp/recipes-bsp/coreos-emmc-flasher/coreos-emmc-flasher-uboot.inc +++ /dev/null @@ -1,10 +0,0 @@ -# Machine that use u-boot can include this file after -# coreo-swupdate-flasher.inc - -# Add support to flash u-boot -IMAGE_DEPENDS += "virtual/bootloader" - -UBOOT_SUFFIX ??= "img" -SWUPDATE_IMAGES += "u-boot" -SWUPDATE_IMAGES_FSTYPES[u-boot] = ".${UBOOT_SUFFIX}" - diff --git a/layers/meta-belden-coreos-bsp/recipes-bsp/coreos-emmc-flasher/coreos-emmc-flasher.inc b/layers/meta-belden-coreos-bsp/recipes-bsp/coreos-emmc-flasher/coreos-emmc-flasher.inc deleted file mode 100644 index fdf4049..0000000 --- a/layers/meta-belden-coreos-bsp/recipes-bsp/coreos-emmc-flasher/coreos-emmc-flasher.inc +++ /dev/null @@ -1,31 +0,0 @@ - -DESCRIPTION = "SWU Image generation to flash the internal emmc" -SECTION = "bootloaders" -LICENSE = "CLOSED" -PR = "r1" - -SRC_URI = " \ - file://sw-description \ - " - -# efibootguard -# ============================================================================== -# efibootguard support is not machine depends so it can be done here - -require conf/image-uefi.conf - -# The efibootguard binary has to be embedded into the image. swupdate will check -# that the binary exist -IMAGE_DEPENDS += "efibootguard" -SWUPDATE_IMAGES += "efibootguard${EFI_ARCH}" - -# Override or variable are not supported in var[flag] statement, but having more -# flags than necessary doesn't do any arm -SWUPDATE_IMAGES_FSTYPES[efibootguardx64] = ".efi" -SWUPDATE_IMAGES_FSTYPES[efibootguardaa64] = ".efi" -SWUPDATE_IMAGES_FSTYPES[efibootguardarm] = ".efi" - -# Image generated should be named coreos-swupdater-flasher-${MACHINE} -# and not the default coreos-swupdate-flasher-${MACHINE}-${MACHINE} -IMAGE_BASENAME ?= "coreos-emmc-flasher" -inherit swupdate diff --git a/layers/meta-belden-coreos-bsp/recipes-coreos/coreos-installer/coreos-installer-config/beaglebone_1.0.sfdisk b/layers/meta-belden-coreos-bsp/recipes-coreos/coreos-installer/coreos-installer-config/beaglebone_1.0.sfdisk new file mode 100644 index 0000000..3cc9887 --- /dev/null +++ b/layers/meta-belden-coreos-bsp/recipes-coreos/coreos-installer/coreos-installer-config/beaglebone_1.0.sfdisk @@ -0,0 +1,19 @@ +label: gpt +device: /dev/mmcblk1 +unit: sectors +first-lba: 34 +last-lba: 7471070 +sector-size: 512 + +# EBBR 2.1.0 section 4.1.1 mandate the use of an unused type UUID and to set +# the RequiredPartition label for part of the firmware stored in the main disk +# https://arm-software.github.io/ebbr/#section-gpt-parts +# next two type were generated +/dev/mmcblk1p1 : start= 256, size= 512, type=4DA6E9DA-C803-4BE4-BAC4-8192717C5EB0, name="mlo", attrs="RequiredPartition" +/dev/mmcblk1p2 : start= 768, size= 8192, type=5B97345D-B7A1-47D3-A491-ED40F4841639, name="uboot", attrs="RequiredPartition" + +/dev/mmcblk1p3 : start= 8960, size= 131072, ${SFDISK_PART_EFI} +/dev/mmcblk1p4 : start= 140032, size= 262144, ${SFDISK_PART_EFIBOOTGUARD_A} +/dev/mmcblk1p5 : start= 402176, size= 262144, ${SFDISK_PART_EFIBOOTGUARD_B} +/dev/mmcblk1p6 : start= 664320, size= 3403375, ${SFDISK_PART_ROOT_A} +/dev/mmcblk1p7 : start= 4067695, size= 3403375, ${SFDISK_PART_ROOT_B} diff --git a/layers/meta-belden-coreos-bsp/recipes-coreos/coreos-installer/coreos-installer-config_%.bbappend b/layers/meta-belden-coreos-bsp/recipes-coreos/coreos-installer/coreos-installer-config_%.bbappend new file mode 100644 index 0000000..749c84f --- /dev/null +++ b/layers/meta-belden-coreos-bsp/recipes-coreos/coreos-installer/coreos-installer-config_%.bbappend @@ -0,0 +1,3 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/coreos-installer-config:" + +SRC_URI:append:beaglebone = " file://beaglebone_1.0.sfdisk" diff --git a/layers/meta-belden-coreos-bsp/wic/beaglebone-sdcard-installer.wks b/layers/meta-belden-coreos-bsp/wic/beaglebone-sdcard-installer.wks new file mode 100644 index 0000000..eed45a4 --- /dev/null +++ b/layers/meta-belden-coreos-bsp/wic/beaglebone-sdcard-installer.wks @@ -0,0 +1,20 @@ +# short-description: Create SD card image for Beaglebone +# long-description: Creates a partitioned SD card image for Beaglebone. + +# offset 1S => 1 sector (1x512 byte) +# The bootloader can be at 4 different position in raw mode: 0S, 256S, 512S, 768S +# MBR disk use only the sector 0, so 1S is free +# GPT disk use sector 0-33S, so first free slot is 256S +# Offset are from the BBB default settings + +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +# Don't name partition in the installer disk image, otherwise the installer may not work as it rely on partition label! +# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +part --offset 256S --source rawcopy --sourceparams="file=MLO" --ondisk mmcblk0 --fixed-size 256K +part --offset 768S --source rawcopy --sourceparams="file=u-boot.img" --ondisk mmcblk0 --fixed-size 4M + +# Let's define a 4MiB maximum size for the bootloader +# 4MiB => 4*1024*1024/512=8192S | 768S + 8192S => 8960S +part --source bootimg-partition --part-type=EF00 --ondisk mmcblk0 --offset 8960S --fixed-size 125M +bootloader --ptable gpt diff --git a/layers/meta-belden-coreos-bsp/wic/beaglebone-sdcard.wks.in b/layers/meta-belden-coreos-bsp/wic/beaglebone-sdcard.wks.in index c915464..cfaac14 100644 --- a/layers/meta-belden-coreos-bsp/wic/beaglebone-sdcard.wks.in +++ b/layers/meta-belden-coreos-bsp/wic/beaglebone-sdcard.wks.in @@ -1,11 +1,20 @@ # short-description: Create SD card image for Beaglebone # long-description: Creates a partitioned SD card image for Beaglebone. -# Boot files are located in the first vfat partition. -part --source bootimg-partition --ondisk mmcblk0 --fstype=vfat --label boot --active --align 4 --size 32M --extra-space 0 --overhead-factor 1 -${WKS_PART_EFI} --ondisk mmcblk0 --align 1024 --size 32M --extra-space 0 --overhead-factor 1 -${WKS_PART_ROOT_A} --ondisk mmcblk0 --size 2G --extra-space 0 --overhead-factor 1 -${WKS_PART_ROOT_B} --ondisk mmcblk0 --size 2G --extra-space 0 --overhead-factor 1 -${WKS_PART_EFIBOOTGUARD_A} --ondisk mmcblk0 --align 1024 --size 128M --extra-space 0 --overhead-factor 1 -${WKS_PART_EFIBOOTGUARD_B} --ondisk mmcblk0 --align 1024 --size 128M --extra-space 0 --overhead-factor 1 -bootloader --ptable msdos +# offset 1S => 1 sector (1x512 byte) +# The bootloader can be at 4 different position in raw mode: 0S, 256S, 512S, 768S +# MBR disk use only the sector 0, so 1S is free +# GPT disk use sector 0-33S, so first free slot is 256S +# Offset are from the BBB default settings +part --offset 256S --source rawcopy --sourceparams="file=MLO" --ondisk mmcblk0 --fixed-size 256K --part-name "mlo" +part --offset 768S --source rawcopy --sourceparams="file=u-boot.img" --ondisk mmcblk0 --fixed-size 4M --part-name "uboot" + + +# Let's define a 4MiB maximum size for the bootloader +# 4MiB => 4*1024*1024/512=8192S | 768S + 8192S => 8960S +${WKS_PART_EFI} --ondisk mmcblk0 --offset 8960S --fixed-size 32M +${WKS_PART_EFIBOOTGUARD_A} --ondisk mmcblk0 --fixed-size 128M +${WKS_PART_EFIBOOTGUARD_B} --ondisk mmcblk0 --fixed-size 128M +${WKS_PART_ROOT_A} --ondisk mmcblk0 --fixed-size ${WKS_PART_ROOT_SIZE} +${WKS_PART_ROOT_B} --ondisk mmcblk0 --fixed-size ${WKS_PART_ROOT_SIZE} +bootloader --ptable gpt diff --git a/layers/meta-belden-coreos-bsp/wic/generic-uefi.wks.in b/layers/meta-belden-coreos-bsp/wic/generic-uefi.wks.in index 40233fc..153284a 100644 --- a/layers/meta-belden-coreos-bsp/wic/generic-uefi.wks.in +++ b/layers/meta-belden-coreos-bsp/wic/generic-uefi.wks.in @@ -1,8 +1,8 @@ # short-description: Create an EFI disk image for genericx86* # long-description: Creates a partitioned EFI disk image for genericx86* machines ${WKS_PART_EFI} --ondisk sda --align 1024 --size 64M --extra-space 0 --overhead-factor 1 -${WKS_PART_ROOT_A} --ondisk sda --size 2G --extra-space 0 --overhead-factor 1 -${WKS_PART_ROOT_B} --ondisk sda --size 2G --extra-space 0 --overhead-factor 1 +${WKS_PART_ROOT_A} --ondisk sda --size ${WKS_PART_ROOT_SIZE} --extra-space 0 --overhead-factor 1 +${WKS_PART_ROOT_B} --ondisk sda --size ${WKS_PART_ROOT_SIZE} --extra-space 0 --overhead-factor 1 ${WKS_PART_EFIBOOTGUARD_A} --ondisk sda --align 1024 --size 128M --extra-space 0 --overhead-factor 1 ${WKS_PART_EFIBOOTGUARD_B} --ondisk sda --align 1024 --size 128M --extra-space 0 --overhead-factor 1 diff --git a/layers/meta-belden-coreos/classes/coreos-image-ci.bbclass b/layers/meta-belden-coreos/classes/coreos-image-ci.bbclass index 0d30147..890cbd9 100644 --- a/layers/meta-belden-coreos/classes/coreos-image-ci.bbclass +++ b/layers/meta-belden-coreos/classes/coreos-image-ci.bbclass @@ -32,6 +32,12 @@ def get_coreos_ci_artifacts(d): if d.getVar('COREOS_IMAGE_GENERATE_SWU') == '1': artifacts.append(d.getVar('IMAGE_LINK_NAME') + '.swu') + # CoreOS Installer + # ========================================================================== + + if d.getVar('COREOS_IMAGE_GENERATE_INSTALLER') == '1': + artifacts.append('coreos-installer-' + d.getVar('MACHINE') + '.efi') + # Kernel # ========================================================================== @@ -40,8 +46,7 @@ def get_coreos_ci_artifacts(d): artifacts.append(kernel_imagetype + '-' + machine + kernel_image_bin_ext) if d.getVar('COREOS_IMAGE_GENERATE_UKI') == '1': - artifacts.append(d.getVar('COREOS_KERNEL0_FILENAME')) - artifacts.append(d.getVar('COREOS_KERNEL1_FILENAME')) + artifacts.append(d.getVar('COREOS_KERNEL_FILENAME')) # Bootloaders # ========================================================================== diff --git a/layers/meta-belden-coreos/classes/coreos-image-swupdate.bbclass b/layers/meta-belden-coreos/classes/coreos-image-swupdate.bbclass index 36357e7..11dd9c6 100644 --- a/layers/meta-belden-coreos/classes/coreos-image-swupdate.bbclass +++ b/layers/meta-belden-coreos/classes/coreos-image-swupdate.bbclass @@ -7,9 +7,6 @@ # Swupdate image generation # ============================================================================== -# Machine using MBR override this value, see legacy-mbr-disk.inc -COREOS_DISK_PARTLABEL_LOOKUP_DIRECTORY ??= "/dev/disk/by-partlabel" - IMAGE_FSTYPES:append = " ext4.zst" python () { image = d.getVar('IMAGE_BASENAME') @@ -19,16 +16,58 @@ python () { inherit swupdate-image # Ensure than variable used in the sw-description files are watched for change -do_swuimage[vardeps] += "COREOS_KERNEL0_FILENAME COREOS_KERNEL1_FILENAME EFIBOOTGUARD_TIMEOUT COREOS_DISK_PARTLABEL_LOOKUP_DIRECTORY APPEND" +do_swuimage[vardeps] += "COREOS_KERNEL_FILENAME EFIBOOTGUARD_TIMEOUT EFIDIR EFI_BOOT_IMAGE COREOS_EFIBOOTGUARD_FILENAME" do_swuimage[deptask] += "do_bundle_uki" -SWUPDATE_IMAGES += "${COREOS_KERNEL0_NAME} ${COREOS_KERNEL1_NAME}" + +COREOS_EFIBOOTGUARD_NAME ?= "efibootguard${EFI_ARCH}" +COREOS_EFIBOOTGUARD_EXT ?= ".efi" +COREOS_EFIBOOTGUARD_FILENAME = "${COREOS_EFIBOOTGUARD_NAME}${COREOS_EFIBOOTGUARD_EXT}" + +SWUPDATE_IMAGES += "${COREOS_KERNEL_NAME} ${COREOS_EFIBOOTGUARD_NAME}" python () { - kernel0 = d.getVar('COREOS_KERNEL0_NAME') - kernel1 = d.getVar('COREOS_KERNEL1_NAME') + kernel = d.getVar('COREOS_KERNEL_NAME') kernelext = d.getVar('COREOS_KERNEL_EXT') - d.setVarFlag("SWUPDATE_IMAGES_FSTYPES", kernel0, kernelext) - d.setVarFlag("SWUPDATE_IMAGES_FSTYPES", kernel1, kernelext) + d.setVarFlag("SWUPDATE_IMAGES_FSTYPES", kernel, kernelext) + + efibootguard = d.getVar('COREOS_EFIBOOTGUARD_NAME') + efibootguardext = d.getVar('COREOS_EFIBOOTGUARD_EXT') + d.setVarFlag("SWUPDATE_IMAGES_FSTYPES", efibootguard, efibootguardext) } FILESEXTRAPATHS:append := ":${COREOS_ROOT}/layers/meta-belden-coreos/files" + +# Space seperated list of extension points +COREOS_SWUPDATE_EXTENDS_FOR ??= "" + +def coreos_swupdate_extends(d, s, key): + """ + Extends the swupdate for each extension points defined by COREOS_SWUPDATE_EXTENDS_FOR + """ + extends_for = d.getVar('COREOS_SWUPDATE_EXTENDS_FOR', True).replace("-", "_").split() + + def kv_to_sw_description(kv): + swdescr = ",{\n" + for key, value in kv.items(): + swdescr += f'{key} = "{value}";\n' + swdescr += "}\n" + return swdescr + + text = "" + + # BSP and Distro can extends the swupdate by implementing some python + # function that return a list of dictionary. + for extension_point in extends_for: + try: + kv_list = globals()[f"coreos_swupdate_extends_{key}_for_{extension_point}"](d,s) + except KeyError: + # Don't fail if the extension is not implemented + pass + else: + for kv in kv_list: + text += kv_to_sw_description(kv) + + return text + +COREOS_IMAGE_SWUPDATE_EXTRACLASSES ?= "" +inherit ${COREOS_IMAGE_SWUPDATE_EXTRACLASSES} diff --git a/layers/meta-belden-coreos/classes/coreos-image-uki.bbclass b/layers/meta-belden-coreos/classes/coreos-image-uki.bbclass index 5558acc..4867fd2 100644 --- a/layers/meta-belden-coreos/classes/coreos-image-uki.bbclass +++ b/layers/meta-belden-coreos/classes/coreos-image-uki.bbclass @@ -10,32 +10,28 @@ inherit coreos-efi-sbsign # ============================================================================== COREOS_KERNEL_EXT ??= ".efi" -COREOS_KERNEL0_NAME ??= "kernel0-${MACHINE}" -COREOS_KERNEL1_NAME ??= "kernel1-${MACHINE}" -COREOS_KERNEL0_FILENAME ??= "${COREOS_KERNEL0_NAME}${COREOS_KERNEL_EXT}" -COREOS_KERNEL0 ??= "${DEPLOY_DIR_IMAGE}/${COREOS_KERNEL0_FILENAME}" -COREOS_KERNEL1_FILENAME ??= "${COREOS_KERNEL1_NAME}${COREOS_KERNEL_EXT}" -COREOS_KERNEL1 ??= "${DEPLOY_DIR_IMAGE}/${COREOS_KERNEL1_FILENAME}" +COREOS_KERNEL_NAME ??= "kernel-${MACHINE}" +COREOS_KERNEL_FILENAME ??= "${COREOS_KERNEL_NAME}${COREOS_KERNEL_EXT}" +COREOS_KERNEL ??= "${DEPLOY_DIR_IMAGE}/${COREOS_KERNEL_FILENAME}" # Kernel command line # ============================================================================== -APPEND += "rootwait " -COREOS_PLATFORM0_ROOT ??= "PARTLABEL=platform0" -COREOS_PLATFORM1_ROOT ??= "PARTLABEL=platform1" -COREOS_KERNEL0_CMDLINE ??= "root=${COREOS_PLATFORM0_ROOT} ${APPEND}" -COREOS_KERNEL1_CMDLINE ??= "root=${COREOS_PLATFORM1_ROOT} ${APPEND}" +# AUTOLABEL will be replaced by the right PARTLABEL (rootfs0 or rootfs1) at +# runtime in the efibootguard UKI stub +COREOS_ROOTFS_ROOT ??= "PARTLABEL=AUTOLABEL" +COREOS_KERNEL_CMDLINE ??= "root=${COREOS_ROOTFS_ROOT} ${APPEND} rootwait" COREOS_UKI_PART_KERNEL_FILENAME ??= "${KERNEL_IMAGETYPE}-${MACHINE}${KERNEL_IMAGE_BIN_EXT}" COREOS_UKI_PART_KERNEL ??= "${DEPLOY_DIR_IMAGE}/${COREOS_UKI_PART_KERNEL_FILENAME}" COREOS_UKI_PART_STUB_FILENAME ??= "kernel-stub${EFI_ARCH}.efi" COREOS_UKI_PART_STUB ??= "${STAGING_LIBDIR}/efibootguard/${COREOS_UKI_PART_STUB_FILENAME}" - +COREOS_UKI_PART_INITRAMFS ??= "" # UKI Generation # ============================================================================== -do_bundle_uki() { +do_image_uki() { deployDir="${DEPLOY_DIR_IMAGE}" # Create an array with device tree if any @@ -49,26 +45,35 @@ do_bundle_uki() { echo "kernel: ${COREOS_UKI_PART_KERNEL_FILENAME}" echo "dtb: ${DTB_PARAMS}" - echo "cmdline0: ${COREOS_KERNEL0_CMDLINE}" - echo "cmdline1: ${COREOS_KERNEL1_CMDLINE}" + echo "cmdline: ${COREOS_KERNEL_CMDLINE}" + echo "initramfs: ${COREOS_UKI_PART_INITRAMFS}" + + if [ ! -z "${COREOS_UKI_PART_INITRAMFS}" ]; then + DTB_PARAMS="${DTB_PARAMS} --initrd=${COREOS_UKI_PART_INITRAMFS}" + fi + + echo "initramfs: ${INITRAMFS_PARAMS}" bg_gen_unified_kernel \ "${COREOS_UKI_PART_STUB}" \ "${COREOS_UKI_PART_KERNEL}" \ - "${COREOS_KERNEL0}" \ - --cmdline "${COREOS_KERNEL0_CMDLINE}" \ + "${COREOS_KERNEL}" \ + --cmdline "${COREOS_KERNEL_CMDLINE}" \ ${DTB_PARAMS} - bg_gen_unified_kernel \ - "${COREOS_UKI_PART_STUB}" \ - "${COREOS_UKI_PART_KERNEL}" \ - "${COREOS_KERNEL1}" \ - --cmdline "${COREOS_KERNEL1_CMDLINE}" \ - ${DTB_PARAMS} - - coreos_efi_secureboot_sign_app "${deployDir}/${COREOS_KERNEL0_FILENAME}" - coreos_efi_secureboot_sign_app "${deployDir}/${COREOS_KERNEL1_FILENAME}" + coreos_efi_secureboot_sign_app "${deployDir}/${COREOS_KERNEL_FILENAME}" } -do_bundle_uki[depends] += "virtual/kernel:do_deploy efibootguard-native:do_populate_sysroot efibootguard:do_populate_sysroot" -addtask bundle_uki after do_rootfs before do_image +do_image_uki[depends] += "virtual/kernel:do_deploy efibootguard-native:do_populate_sysroot efibootguard:do_populate_sysroot" + + +addtask image_uki after do_image before do_image_complete + +# UKI image is normally embedded into a WIC image +do_image_wic[recrdeptask] += "do_image_uki" + +# UKI image is normally embedded into a SWU image +do_image_swu[recrdeptask] += "${@'do_image_uki' if d.getVar('COREOS_IMAGE_GENERATE_SWU') == '1' else ''}" + +# UKI image may embedded the rootfs as a cpio archive, in this case do_image_uki should run after do_image_cpio +do_image_uki[recrdeptask] += "${@'do_image_cpio' if d.getVar('COREOS_UKI_PART_INITRAMFS') else ''}" diff --git a/layers/meta-belden-coreos/classes/coreos-image.bbclass b/layers/meta-belden-coreos/classes/coreos-image.bbclass index 685ea48..057d652 100644 --- a/layers/meta-belden-coreos/classes/coreos-image.bbclass +++ b/layers/meta-belden-coreos/classes/coreos-image.bbclass @@ -24,6 +24,7 @@ FEATURE_PACKAGES_cockpit = "packagegroup-coreos-cockpit ${@get_feature_packages_ # *-dev-tools FEATURES_PACKAGES for any image features FEATURE_PACKAGES_dev-tools = "${@get_feature_packages_with_suffix('dev-tools', d)}" + def get_feature_packages_with_suffix(suffix, d): """ For each feature inside IMAGE_FEATURES, look if a FEATURE_PACKAGE variable @@ -89,9 +90,13 @@ IMAGE_ROOTFS_EXTRA_SPACE:append = " ${@bb.utils.contains('DISTRO_FEATURES', 'sys # ============================================================================== # Support for Unified Kernel Image and Swupdate are optional +COREOS_IMAGE_GENERATE_INSTALLER ?= "1" COREOS_IMAGE_GENERATE_UKI ?= "1" COREOS_IMAGE_GENERATE_SWU ?= "1" +# Generate the installer image if needed +do_build[depends] += "${@'coreos-image-installer:do_build' if d.getVar('COREOS_IMAGE_GENERATE_INSTALLER') == '1' else ''}" + COREOS_IMAGE_EXTRACLASSES += "${@'coreos-image-uki' if d.getVar('COREOS_IMAGE_GENERATE_UKI') == '1' else ''}" COREOS_IMAGE_EXTRACLASSES += "${@'coreos-image-swupdate' if d.getVar('COREOS_IMAGE_GENERATE_SWU') == '1' else ''}" diff --git a/layers/meta-belden-coreos/conf/distro/belden-coreos.conf b/layers/meta-belden-coreos/conf/distro/belden-coreos.conf index 11944d3..8b22836 100644 --- a/layers/meta-belden-coreos/conf/distro/belden-coreos.conf +++ b/layers/meta-belden-coreos/conf/distro/belden-coreos.conf @@ -78,3 +78,10 @@ INHERIT += "coreos-efi-secureboot" #PREFERRED_PROVIDER_virtual/runc = "crun" PACKAGECONFIG:append:pn-podman = " rootless" DISTRO_FEATURES_DEFAULT += "virtualization seccomp ipv6" + +# CoreOS specific options +# ============================================================================== + +# Distro based on CoreOS can provide their own configuration files for the +# CoreOS installer by overriding this variable +PREFERRED_PROVIDER_coreos-installer-config ??= "coreos-installer-config" diff --git a/layers/meta-belden-coreos/files/sw-description b/layers/meta-belden-coreos/files/sw-description index 29fb378..cbe8f14 100644 --- a/layers/meta-belden-coreos/files/sw-description +++ b/layers/meta-belden-coreos/files/sw-description @@ -12,26 +12,39 @@ software = installed-directly = true; # partlabel are stored inside the GPT partition table. # The partition table is flashed only once and never updated - device = "@@COREOS_DISK_PARTLABEL_LOOKUP_DIRECTORY@@/platform0"; + device = "/dev/disk/by-partlabel/rootfs0"; type = "raw"; sha256 = "$swupdate_get_sha256(@@PN@@-@@MACHINE@@.ext4.zst)"; } + # Don't remove the trailing whitspace on the next line otherwise + # it will not work due to a regex bug in meta-swupdate + $coreos_swupdate_extends(images) ); files: ( { - filename = "@@COREOS_KERNEL0_FILENAME@@"; + filename = "@@COREOS_KERNEL_FILENAME@@"; path = "/KERNEL.EFI"; - device = "@@COREOS_DISK_PARTLABEL_LOOKUP_DIRECTORY@@/boot0"; + device = "/dev/disk/by-partlabel/ebg0"; filesystem = "vfat"; - sha256 = "$swupdate_get_sha256(@@COREOS_KERNEL0_FILENAME@@)"; + sha256 = "$swupdate_get_sha256(@@COREOS_KERNEL_FILENAME@@)"; + }, + { + filename = "@@COREOS_EFIBOOTGUARD_FILENAME@@"; + path = "@@EFIDIR@@/@@EFI_BOOT_IMAGE@@"; + device = "/dev/disk/by-partlabel/efi"; + filesystem = "vfat"; + sha256 = "$swupdate_get_sha256(@@COREOS_EFIBOOTGUARD_FILENAME@@)"; } + # Don't remove the trailing whitspace on the next line otherwise + # it will not work due to a regex bug in meta-swupdate + $coreos_swupdate_extends(files) ); bootenv: ( { name = "kernelparams"; - value = "root=PARTLABEL=platform0 @@APPEND@@"; + value = "coreos.root=rootfs0"; }, { name = "watchdog_timeout_sec"; @@ -39,9 +52,12 @@ software = }, { name = "kernelfile"; - value = "C:BOOT0:KERNEL.EFI"; + value = "C:EBG0:KERNEL.EFI"; } + # Don't remove the trailing whitspace on the next line otherwise + # it will not work due to a regex bug in meta-swupdate + $coreos_swupdate_extends(bootenv) ); } @@ -53,25 +69,38 @@ software = installed-directly = true; # partlabel are stored inside the GPT partition table. # The partition table is flashed only once and never updated - device = "@@COREOS_DISK_PARTLABEL_LOOKUP_DIRECTORY@@/platform1"; + device = "/dev/disk/by-partlabel/rootfs1"; type = "raw"; sha256 = "$swupdate_get_sha256(@@PN@@-@@MACHINE@@.ext4.zst)"; } + # Don't remove the trailing whitspace on the next line otherwise + # it will not work due to a regex bug in meta-swupdate + $coreos_swupdate_extends(images) ); files: ( { - filename = "@@COREOS_KERNEL1_FILENAME@@"; + filename = "@@COREOS_KERNEL_FILENAME@@"; path = "/KERNEL.EFI"; - device = "@@COREOS_DISK_PARTLABEL_LOOKUP_DIRECTORY@@/boot1"; + device = "/dev/disk/by-partlabel/ebg1"; filesystem = "vfat"; - sha256 = "$swupdate_get_sha256(@@COREOS_KERNEL1_FILENAME@@)"; + sha256 = "$swupdate_get_sha256(@@COREOS_KERNEL_FILENAME@@)"; + }, + { + filename = "@@COREOS_EFIBOOTGUARD_FILENAME@@"; + path = "@@EFIDIR@@/@@EFI_BOOT_IMAGE@@"; + device = "/dev/disk/by-partlabel/efi"; + filesystem = "vfat"; + sha256 = "$swupdate_get_sha256(@@COREOS_EFIBOOTGUARD_FILENAME@@)"; } + # Don't remove the trailing whitspace on the next line otherwise + # it will not work due to a regex bug in meta-swupdate + $coreos_swupdate_extends(files) ); bootenv: ( { name = "kernelparams"; - value = "root=PARTLABEL=platform1 @@APPEND@@"; + value = "coreos.root=rootfs1"; }, { name = "watchdog_timeout_sec"; @@ -79,9 +108,12 @@ software = }, { name = "kernelfile"; - value = "C:BOOT1:KERNEL.EFI"; + value = "C:EBG1:KERNEL.EFI"; } + # Don't remove the trailing whitspace on the next line otherwise + # it will not work due to a regex bug in meta-swupdate + $coreos_swupdate_extends(bootenv) ); } } diff --git a/layers/meta-belden-coreos/lib/devtool/coreos-efibootguard.py b/layers/meta-belden-coreos/lib/devtool/coreos-efibootguard.py index c6ffea7..5199e90 100644 --- a/layers/meta-belden-coreos/lib/devtool/coreos-efibootguard.py +++ b/layers/meta-belden-coreos/lib/devtool/coreos-efibootguard.py @@ -272,40 +272,24 @@ def efibootguard_generate_uki(args, config, basepath, workspace): keydir = os.path.relpath(rd.getVar("COREOS_EFI_SECUREBOOT_KEYDIR")) - uki0 = UKIGeneratorArgs( + uki = UKIGeneratorArgs( kernel=kernel, - output=os.path.relpath(rd.getVar("COREOS_KERNEL0")), - cmdline=rd.getVar("COREOS_KERNEL0_CMDLINE"), + output=os.path.relpath(rd.getVar("COREOS_KERNEL")), + cmdline=rd.getVar("COREOS_KERNEL_CMDLINE"), dtb=dtb, stub=stub, - root=rd.getVar("COREOS_PLATFORM0_ROOT"), - build_binary=build_binary, - keydir=keydir, - ) - uki1 = UKIGeneratorArgs( - kernel=kernel, - output=os.path.relpath(rd.getVar("COREOS_KERNEL1")), - cmdline=rd.getVar("COREOS_KERNEL1_CMDLINE"), - dtb=dtb, - stub=stub, - root=rd.getVar("COREOS_PLATFORM1_ROOT"), + root=rd.getVar("COREOS_ROOTFS_ROOT"), build_binary=build_binary, keydir=keydir, ) print(f"Applying passed parameters...") - uki0.process_args(args) - uki1.process_args(args) + uki.process_args(args) - print(f"KERNEL0 image will be generated with the following settings:") - printi(f"{uki0}", 1) - print() - print(f"KERNEL1 image will be generated with the following settings:") - printi(f"{uki1}", 1) + print(f"KERNEL image will be generated with the following settings:") + printi(f"{uki}", 1) print() print(f"Generating the files...") - r = uki0.build_and_sign() - r += uki1.build_and_sign() + return uki0.build_and_sign() - return r diff --git a/layers/meta-belden-coreos/recipes-bsp/efibootguard/efibootguard/0001-coreos-add-a-coreos-specific-rootfs-switch-to-the-UK.patch b/layers/meta-belden-coreos/recipes-bsp/efibootguard/efibootguard/0001-coreos-add-a-coreos-specific-rootfs-switch-to-the-UK.patch new file mode 100644 index 0000000..736ef25 --- /dev/null +++ b/layers/meta-belden-coreos/recipes-bsp/efibootguard/efibootguard/0001-coreos-add-a-coreos-specific-rootfs-switch-to-the-UK.patch @@ -0,0 +1,93 @@ +From 2e8b73826c6ecaf5168002a18282ba7e4ac95e76 Mon Sep 17 00:00:00 2001 +From: Samuel Dolt +Date: Mon, 12 Jun 2023 16:29:49 +0200 +Subject: [PATCH] coreos: add a coreos specific rootfs switch to the UKI stub + +The unified kernel stub can now replace the substring "AUTOLABEL" +in the built-in kernel command line by either rootfs0 and rootfs1 +by looking the LoadOption string passed by ther firmware: +- LoadOptions contain "coreos.root=rootfs0", all occurences of + "AUTOLABEL" are replaced by "rootfs0" +- LoadOptions contain "coreos.root=rootfs1", all occurences of + "AUTOLABEL" are replaced by "rootfs1". +- LoadOptions is empty, the kernel command line will be used as is. + +In all other case, the stub will exist without booting the kernel +with a INVALID PARAMETER error. +--- + kernel-stub/main.c | 55 +++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 50 insertions(+), 5 deletions(-) + +diff --git a/kernel-stub/main.c b/kernel-stub/main.c +index c0be1f6..6f456d3 100644 +--- a/kernel-stub/main.c ++++ b/kernel-stub/main.c +@@ -128,11 +128,6 @@ EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) + error_exit(L"Error getting LoadedImageProtocol", status); + } + +- /* consider zero-termination for string length */ +- if (stub_image->LoadOptionsSize > sizeof(CHAR16)) { +- info(L"WARNING: Passed command line options ignored, only built-in used"); +- } +- + pe_header = get_pe_header(stub_image->ImageBase); + for (n = 0, section = get_sections(pe_header); + n < pe_header->Coff.NumberOfSections; +@@ -161,6 +156,56 @@ EFI_STATUS efi_main(EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table) + kernel_image.LoadOptions = (UINT8 *) stub_image->ImageBase + + cmdline_section->VirtualAddress; + kernel_image.LoadOptionsSize = cmdline_section->VirtualSize; ++ ++ /* CoreOS utilize the option passed from efibootguard to customize the kernel ++ * command line. ++ * ++ * Allowed option are: ++ * 'coreos.root=rootfs0' => replace "AUTOLABEL" with "rootfs0 " in place in the kernel CLI ++ * 'coreos.root=rootfs1' => replace "AUTOLABEL" with "rootfs1 " in place in the kernel CLI ++ * '' => no option passed ++ * ++ * Using another option string will return without booting the kernel ++ * ++ * hint: LoadOptions is a null-terminated wide string ++ * hint: sizeof return the number of byte. StrLen the number of characters ++ */ ++ if (stub_image->LoadOptionsSize > sizeof(CHAR16)) { ++ ++ // !!! symbol and rootfs must have the same length !!! ++ const CHAR16 symbol[] = L"AUTOLABEL"; ++ CHAR16 rootfs[] = L"rootfsX "; ++ ++ if (StrnCmp(L"coreos.root=rootfs0", stub_image->LoadOptions, stub_image->LoadOptionsSize) == 0) { ++ rootfs[6] = L'0'; ++ } else if (StrnCmp(L"coreos.root=rootfs1", stub_image->LoadOptions, stub_image->LoadOptionsSize) == 0) { ++ rootfs[6] = L'1'; ++ } else { ++ error_exit(L"LoadOptions is not valid", EFI_INVALID_PARAMETER); ++ } ++ ++ /* Replace symbol by rootfs (AUTOLABEL by either rootfs0 or rootfs1) */ ++ CHAR16 * str = kernel_image.LoadOptions; ++ UINTN len = kernel_image.LoadOptionsSize; ++ while (*str && len) { ++ ++ /* Ensure that the string still contains enough char for the symbol */ ++ if(len < sizeof(symbol)) { ++ break; ++ } ++ ++ if(StrnCmp(str, &symbol, StrLen(symbol)) == 0) { ++ /* Replace symbol by rootfs, works because symbole and rootfs has the same length */ ++ StrnCpy(str, rootfs, StrLen(rootfs)); ++ } ++ ++ str += 1; ++ len -= sizeof(CHAR16); ++ } ++ ++ } ++ ++ Print(L"Unified kernel stub: Kernel Options: %s\n", kernel_image.LoadOptions); + } + + if (initrd_section) { diff --git a/layers/meta-belden-coreos/recipes-bsp/efibootguard/efibootguard_%.bbappend b/layers/meta-belden-coreos/recipes-bsp/efibootguard/efibootguard_%.bbappend new file mode 100644 index 0000000..682574a --- /dev/null +++ b/layers/meta-belden-coreos/recipes-bsp/efibootguard/efibootguard_%.bbappend @@ -0,0 +1,4 @@ +FILESEXTRAPATHS:prepend := "${THISDIR}/${PN}:" + +SRC_URI += "file://0001-coreos-add-a-coreos-specific-rootfs-switch-to-the-UK.patch" + diff --git a/layers/meta-belden-coreos/recipes-core/images/coreos-image-all-features.bb b/layers/meta-belden-coreos/recipes-core/images/coreos-image-all-features.bb index d87c99f..6cdacc9 100644 --- a/layers/meta-belden-coreos/recipes-core/images/coreos-image-all-features.bb +++ b/layers/meta-belden-coreos/recipes-core/images/coreos-image-all-features.bb @@ -9,4 +9,4 @@ IMAGE_INSTALL:append = " packagegroup-core-full-cmdline" IMAGE_INSTALL:append = "${@bb.utils.contains("IMAGE_FEATURES", "swupdate", " swupdate-www", "", d)}" # development tools -IMAGE_INSTALL:append = " systemd-analyze" \ No newline at end of file +IMAGE_INSTALL:append = " systemd-analyze" diff --git a/layers/meta-belden-coreos/recipes-core/images/coreos-image-installer.bb b/layers/meta-belden-coreos/recipes-core/images/coreos-image-installer.bb new file mode 100644 index 0000000..9db6cc3 --- /dev/null +++ b/layers/meta-belden-coreos/recipes-core/images/coreos-image-installer.bb @@ -0,0 +1,50 @@ +DESCRIPTION = "Initramfs image with the CoreOS emmc installer" + + + +# Don't reboot the device at reboot and don't do A/B switching +BAD_RECOMMENDATIONS = "swupdate-progress swupdate-coreos-config" + +export IMAGE_BASENAME = "${MLPREFIX}${PN}" +IMAGE_NAME_SUFFIX ?= "" +IMAGE_LINGUAS = "" + +LICENSE = "MIT" + +IMAGE_FSTYPES = "cpio.gz" + +# Support for generating a SDCard installer is optional +COREOS_INSTALLER_WKS_FILE ??= "" +WKS_FILE = "${COREOS_INSTALLER_WKS_FILE}" +IMAGE_FSTYPES += "${@'wic.xz wic.bmap' if d.getVar('COREOS_INSTALLER_WKS_FILE') else ''}" +IMAGE_BOOT_FILES = "${COREOS_KERNEL_FILENAME};EFI/BOOT/${EFI_BOOT_IMAGE}" + +COREOS_IMAGE_GENERATE_UKI = "1" + +# Avoid dependancy loop, we are already in an installer image, so we don't need +# to bundle another one +COREOS_IMAGE_GENERATE_INSTALLER = "0" + +# IMGDEPLOYDIR has to be used instead of DEPLOY_DIR_IMAGE here, because it will +# run during image generation +COREOS_UKI_PART_INITRAMFS = "${IMGDEPLOYDIR}/${IMAGE_BASENAME}-${MACHINE}.cpio.gz" +COREOS_IMAGE_GENERATE_SWU = "0" + +# Change generated UKI filename and reset the bundled command line to "APPEND" +# to ensure that root is not set in the kernel command line +COREOS_KERNEL_NAME ?= "coreos-installer-${MACHINE}" +COREOS_KERNEL_CMDLINE ?= "${APPEND}" + +inherit coreos-image + +# Only install a reduced set of package and feature to keep image size small +IMAGE_INSTALL = "packagegroup-coreos-boot coreos-installer swupdate-www util-linux-sfdisk util-linux-fdisk util-linux-cfdisk efibootguard efibootguard-tools" +IMAGE_FEATURES = "debug-tweaks swupdate networkmanager" +NO_RECOMMENDATIONS = "1" + +IMAGE_ROOTFS_SIZE = "8192" +INITRAMFS_MAXSIZE = "976562" +IMAGE_ROOTFS_EXTRA_SPACE = "0" + +# Use the same restriction as initramfs-module-install +COMPATIBLE_HOST = '(x86_64.*|i.86.*|arm.*|aarch64.*)-(linux.*|freebsd.*)' diff --git a/layers/meta-belden-coreos/recipes-core/packagegroups/packagegroup-coreos-swupdate.bb b/layers/meta-belden-coreos/recipes-core/packagegroups/packagegroup-coreos-swupdate.bb index d8429c4..1a8d1a7 100644 --- a/layers/meta-belden-coreos/recipes-core/packagegroups/packagegroup-coreos-swupdate.bb +++ b/layers/meta-belden-coreos/recipes-core/packagegroups/packagegroup-coreos-swupdate.bb @@ -3,14 +3,15 @@ DESCRIPTION = "Install swupdate and related components" inherit packagegroup - PACKAGES = "\ ${PN} \ " RDEPENDS:${PN} = "\ swupdate \ - swupdate-progress \ swupdate-client \ swupdate-lua \ " + +# swupdate-progress will reboot the device at the end of the update +RRECOMMENDS:${PN} = "swupdate-progress" diff --git a/layers/meta-belden-coreos/recipes-coreos/coreos-installer/coreos-installer-config.inc b/layers/meta-belden-coreos/recipes-coreos/coreos-installer/coreos-installer-config.inc new file mode 100644 index 0000000..52e06e0 --- /dev/null +++ b/layers/meta-belden-coreos/recipes-coreos/coreos-installer/coreos-installer-config.inc @@ -0,0 +1,49 @@ +DESCRIPTION = "CoreOS Installer configuration files" +SECTION = "coreos" +LICENSE = "CLOSED" + +# This file can be included by a CoreOS based distro to ship a customized +# version +RPROVIDES:${PN} += "coreos-installer-config" +PROVIDES += "coreos-installer-config" + +# This package is intended to ship machine specific configuration file +# See bbappend in BSP layers +PACKAGE_ARCH = "${MACHINE_ARCH}" + +# If the BSP doesn't provide a machine specific configuration file, this +# package will be empty +ALLOW_EMPTY:${PN} = "1" + +# Don't run default configure and compile task +do_configure[noexex] = "1" + +python do_compile() { + from pathlib import Path + + workdir = Path(d.getVar('WORKDIR', True)) + machine = d.getVar('MACHINE', True) + b = Path(d.getVar('B', True)) + for input_path in workdir.glob(f'{machine}_*.sfdisk'): + output_path = b / input_path.relative_to(workdir) + process_sfdisk_file(d, input_path, output_path) + +} + +def process_sfdisk_file(d, input_path, output_path): + """ + Read the file from input_path and write it to output_path with bitbake + variable expanded + """ + with open(output_path, "w") as output_file: + with open(input_path, "r") as input_file: + for line in input_file.readlines(): + output_file.write(d.expand(line)) + +do_install() { + install -d ${D}${sysconfdir} + + # Install all files for the current machine but don't fail if no file is + # found + install -m 755 ${B}/${MACHINE}_*.sfdisk ${D}${sysconfdir}/ || true +} diff --git a/layers/meta-belden-coreos/recipes-coreos/coreos-installer/coreos-installer-config_1.0.bb b/layers/meta-belden-coreos/recipes-coreos/coreos-installer/coreos-installer-config_1.0.bb new file mode 100644 index 0000000..73c3c5b --- /dev/null +++ b/layers/meta-belden-coreos/recipes-coreos/coreos-installer/coreos-installer-config_1.0.bb @@ -0,0 +1,3 @@ +# Code is in an include file as they can be reused by a CoreOS distro to ship +# an alternative provided for coreos-installer-config using PREFERRED_PROVIDER +require coreos-installer-config.inc diff --git a/layers/meta-belden-coreos/recipes-coreos/coreos-installer/coreos-installer/25-installer-config.sh b/layers/meta-belden-coreos/recipes-coreos/coreos-installer/coreos-installer/25-installer-config.sh new file mode 100644 index 0000000..9a919f3 --- /dev/null +++ b/layers/meta-belden-coreos/recipes-coreos/coreos-installer/coreos-installer/25-installer-config.sh @@ -0,0 +1,50 @@ +#!/usr/bin/env sh + +# Read /etc/hwrevision and turn it into a stripped string +# with the format ${MACHINE}_${VERSION} +HWREVISION=$(tr ' ' '_' < /etc/hwrevision | tr -d '[:space:]') + +# Format the disk +SFDISK_DUMP_FILE="/etc/${HWREVISION}.sfdisk" + +if [ ! -f "${SFDISK_DUMP_FILE}" ] +then + echo "Configuration file ${SFDISK_DUMP_FILE} not found" + exit 1 +fi + +DISK=$(grep "^device:\s" < "${SFDISK_DUMP_FILE}" | cut -d ' ' -f 2) + +echo "Flashing ${SFDISK_DUMP_FILE} to ${DISK}" +cat "${SFDISK_DUMP_FILE}" +sfdisk "${DISK}" < "${SFDISK_DUMP_FILE}" + +# Give the kernel some time to reload the partition +sleep 3 + +# Create EFI and EFIBootGuard partition as FAT16 +mkfs.fat -F 16 -n EFI /dev/disk/by-partlabel/efi +mkfs.fat -F 16 -n EBG0 /dev/disk/by-partlabel/ebg0 +mkfs.fat -F 16 -n EBG1 /dev/disk/by-partlabel/ebg1 + +mkdir -p /mnt/ebg0 +mkdir -p /mnt/ebg1 +mkdir -p /mnt/efi + +mount /dev/disk/by-partlabel/ebg0 /mnt/ebg0 +mount /dev/disk/by-partlabel/ebg1 /mnt/ebg1 +mount /dev/disk/by-partlabel/efi /mnt/efi + +mkdir -p /mnt/efi/EFI/BOOT + +echo -n "EBG0" | iconv -f ascii -t UTF-16LE > /mnt/ebg0/EFILABEL +bg_setenv -f /mnt/ebg0/BGENV.DAT -r 0 -s FAILED + +echo -n "EBG1" | iconv -f ascii -t UTF-16LE > /mnt/ebg1/EFILABEL +bg_setenv -f /mnt/ebg1/BGENV.DAT -r 0 -s FAILED + +umount /mnt/ebg0 +umount /mnt/ebg1 +umount /mnt/efi + +SWUPDATE_ARGS="${SWUPDATE_ARGS} -e stable,copy0" diff --git a/layers/meta-belden-coreos/recipes-coreos/coreos-installer/coreos-installer_1.0.bb b/layers/meta-belden-coreos/recipes-coreos/coreos-installer/coreos-installer_1.0.bb new file mode 100644 index 0000000..43e5bab --- /dev/null +++ b/layers/meta-belden-coreos/recipes-coreos/coreos-installer/coreos-installer_1.0.bb @@ -0,0 +1,24 @@ +DESCRIPTION = "CoreOS Installer scripts" +LICENSE = "CLOSED" +SECTION = "coreos" + +SRC_URI+= " \ + file://25-installer-config.sh \ +" + +# This package ship an alternate configuration for SWUpade to disable A/B +# switching and always flash A +RCONFLICTS:${PN}= "swupdate-coreos-config" + +FILES:${PN} = " \ + ${libdir}/swupdate/conf.d/25-installer-config.sh \ +" + +# glibc-utils provide iconv +# glibc-gconv-utf-16 provide utf-16 support to iconv +RDEPENDS:${PN} = "coreos-installer-config dosfstools util-linux-lsblk util-linux-sfdisk glibc-utils glibc-gconv-utf-16" + +do_install() { + install -d ${D}${libdir}/swupdate/conf.d + install -m 755 ${WORKDIR}/25-installer-config.sh ${D}${libdir}/swupdate/conf.d/ +} diff --git a/layers/meta-belden-coreos/recipes-support/swupdate/swupdate/0001-fs-add-support-to-create-FAT16-partition.patch b/layers/meta-belden-coreos/recipes-support/swupdate/swupdate/0001-fs-add-support-to-create-FAT16-partition.patch deleted file mode 100644 index 8ee78f1..0000000 --- a/layers/meta-belden-coreos/recipes-support/swupdate/swupdate/0001-fs-add-support-to-create-FAT16-partition.patch +++ /dev/null @@ -1,50 +0,0 @@ -From 323c7fdda60758506dea9da6c477e42a0dbe86ca Mon Sep 17 00:00:00 2001 -From: Samuel Dolt -Date: Wed, 22 Feb 2023 13:22:27 +0100 -Subject: [PATCH] fs: add support to create FAT16 partition - -Currently swupdate can create vfat partition using an embedded -copy of the fat_fs library. The partition created by fat_fs is -can be any FAT format (12/16/32) based on the partition size. - -As the partition created by fat_fs was not readable by U-Boot, -this commit add a new "fat16" filesystem type that use the -external binary mkfs.fat to always create FAT16 partition. ---- - fs/diskformat.c | 16 ++++++++++++++++ - 1 file changed, 16 insertions(+) - -diff --git a/fs/diskformat.c b/fs/diskformat.c -index 8d58fc3..f98c9d7 100644 ---- a/fs/diskformat.c -+++ b/fs/diskformat.c -@@ -19,6 +19,21 @@ static inline int ext_mkfs_short(const char *device_name, const char *fstype) - } - #endif - -+int fat_mkfs_extern(const char *device_name, const char *fstype) -+{ -+ char cmd[100] = "mkfs.fat -F "; -+ if(strcmp(fstype, "fat16") == 0){ -+ strcat(cmd, "16 "); -+ } else { -+ ERROR("fat_mkfs_extern: unsupported fstype %s", fstype); -+ return -1; -+ } -+ strncat(cmd, device_name, sizeof(cmd) - strlen(cmd) - 1); -+ -+ TRACE("fat_mkfs_extern: running %s", cmd); -+ return system(cmd); -+} -+ - struct supported_filesystems { - const char *fstype; - int (*mkfs)(const char *device_name, const char *fstype); -@@ -28,6 +43,7 @@ static struct supported_filesystems fs[] = { - #if defined(CONFIG_FAT_FILESYSTEM) - {"vfat", fat_mkfs}, - #endif -+ {"fat16", fat_mkfs_extern}, - #if defined(CONFIG_EXT_FILESYSTEM) - {"ext2", ext_mkfs_short}, - {"ext3", ext_mkfs_short}, diff --git a/layers/meta-belden-coreos/recipes-support/swupdate/swupdate/sw-collections-config.sh b/layers/meta-belden-coreos/recipes-support/swupdate/swupdate/25-sw-collections-config.sh similarity index 89% rename from layers/meta-belden-coreos/recipes-support/swupdate/swupdate/sw-collections-config.sh rename to layers/meta-belden-coreos/recipes-support/swupdate/swupdate/25-sw-collections-config.sh index 1238e9b..c9a0166 100644 --- a/layers/meta-belden-coreos/recipes-support/swupdate/swupdate/sw-collections-config.sh +++ b/layers/meta-belden-coreos/recipes-support/swupdate/swupdate/25-sw-collections-config.sh @@ -17,18 +17,18 @@ echo "Root partition is on device ${DISK_DEVICE_NAME} - type ${DISK_PARTITION_TY if [ "${DISK_PARTITION_TYPE}" == "gpt" ]; then ROOT_PARTLABEL=$(lsblk -dno PARTLABEL "${ROOT_PART}") else - echo "Using MBR disk is less reliable than GPT disk!" - ROOT_PARTLABEL=$(lsblk -dno LABEL "${ROOT_PART}") + echo "Using MBR is not supported" + exit 1 fi echo "Root partition label is ${ROOT_PARTLABEL}" case $ROOT_PARTLABEL in - platform0 ) + rootfs0 ) echo "We are running copy0 -> Use copy1 in the SWU file" SWUPDATE_ARGS="${SWUPDATE_ARGS} -e stable,copy1" ;; - platform1 ) + rootfs1 ) echo "We are running copy1 -> Use copy0 in the SWU file" SWUPDATE_ARGS="${SWUPDATE_ARGS} -e stable,copy0" ;; diff --git a/layers/meta-belden-coreos/recipes-support/swupdate/swupdate/webserver-config.sh b/layers/meta-belden-coreos/recipes-support/swupdate/swupdate/50-webserver-config.sh similarity index 100% rename from layers/meta-belden-coreos/recipes-support/swupdate/swupdate/webserver-config.sh rename to layers/meta-belden-coreos/recipes-support/swupdate/swupdate/50-webserver-config.sh diff --git a/layers/meta-belden-coreos/recipes-support/swupdate/swupdate_%.bbappend b/layers/meta-belden-coreos/recipes-support/swupdate/swupdate_%.bbappend new file mode 100644 index 0000000..96bea30 --- /dev/null +++ b/layers/meta-belden-coreos/recipes-support/swupdate/swupdate_%.bbappend @@ -0,0 +1,43 @@ +# File in the swupdate subdirectory of this recipe should overwrite the +# same file in meta-swupdate +FILESEXTRAPATHS:prepend := "${THISDIR}/swupdate:" + +SRC_URI += "\ + file://50-webserver-config.sh \ + file://25-sw-collections-config.sh \ +" + +PACKAGES =+ "${PN}-coreos-config ${PN}-coreos-installer-config" + + +# Don't use /www as the web root +wwwdir = "${datadir}/swupdate-www" + +# Add the hwrevision files to the main package to prevent +# installation of .swu image built for another machine +FILES:${PN} += "${sysconfdir}/hwrevision" + +# If we install the webserver package, it should be started automatically +FILES:${PN}-www += "${libdir}/swupdate/conf.d/50-webserver-config.sh" + +FILES:${PN}-coreos-config += "${libdir}/swupdate/conf.d/25-sw-collections-config.sh" + +RDEPENDS:${PN}:append = " efibootguard" + +# lsblk is used in sw-collections-config.sh +RDEPENDS:${PN}-coreos-config += "util-linux-lsblk" + +# Recommends by default the configuration used for normal image +# that contain the A/B update path switch +RRECOMMENDS:${PN} += "${PN}-coreos-config" + +# The installer configuration should prevent the normal A/B switch +# configuration to be installed +RCONFLICTS:${PN}-coreos-installer-config = "${PN}-coreos-config" + +do_install:append() { + # Probably replace revision with the value of the device tree + install -m 755 ${WORKDIR}/50-webserver-config.sh ${D}${libdir}/swupdate/conf.d/ + install -m 755 ${WORKDIR}/25-sw-collections-config.sh ${D}${libdir}/swupdate/conf.d/ + echo "${MACHINE} 1.0" > ${D}${sysconfdir}/hwrevision +} diff --git a/layers/meta-belden-coreos/recipes-support/swupdate/swupdate_2022.12.bbappend b/layers/meta-belden-coreos/recipes-support/swupdate/swupdate_2022.12.bbappend deleted file mode 100644 index 95d7c30..0000000 --- a/layers/meta-belden-coreos/recipes-support/swupdate/swupdate_2022.12.bbappend +++ /dev/null @@ -1,36 +0,0 @@ -# File in the swupdate subdirectory of this recipe should overwrite the -# same file in meta-swupdate -FILESEXTRAPATHS:prepend := "${THISDIR}/swupdate:" -RDEPENDS:${PN}:append = " efibootguard" - -SRC_URI += "file://webserver-config.sh \ - file://sw-collections-config.sh \ - file://0001-fs-add-support-to-create-FAT16-partition.patch \ - " - -# 0001-fs-add-support-to-create-FAT16-partition.patch depends on the -# mkfs.fat binary -RDEPENDS:${PN} += "dosfstools" - -# Don't use /www as the web root -wwwdir = "/usr/share/swupdate-www" - -FILES:${PN} += " \ - ${SWUPDATE_SW_VERSIONS_FILE} \ - ${SWUPDATE_HW_COMPATIBILITY_FILE} \ - ${libdir}/swupdate/conf.d/sw-collections-config.sh \ -" - -FILES:${PN}-www += " \ - ${libdir}/swupdate/conf.d/webserver-config.sh \ -" - -do_install:append() { - # Probably replace revision with the value of the device tree - install -m 755 ${WORKDIR}/webserver-config.sh ${D}${libdir}/swupdate/conf.d/ - - install -m 755 ${WORKDIR}/sw-collections-config.sh ${D}${libdir}/swupdate/conf.d/ - echo "${MACHINE} 1.0" > ${D}${SWUPDATE_HW_COMPATIBILITY_FILE} -} - -PR = "r1" \ No newline at end of file diff --git a/layers/meta-belden-marvell-bsp/classes/coreos-image-swupdate-cn913x.bbclass b/layers/meta-belden-marvell-bsp/classes/coreos-image-swupdate-cn913x.bbclass new file mode 100644 index 0000000..88c7432 --- /dev/null +++ b/layers/meta-belden-marvell-bsp/classes/coreos-image-swupdate-cn913x.bbclass @@ -0,0 +1,20 @@ + +SWUPDATE_IMAGES += "flash-image" +SWUPDATE_IMAGES_FSTYPES[flash-image] = ".bin" + +COREOS_SWUPDATE_EXTENDS_FOR:append = "cn913x" + +def coreos_swupdate_extends_images_for_cn913x(d,s): + boot0 = { + "filename" : "flash-image.bin", + "installed-directly" : "true", + "device" : "/dev/disk/by-partlabel/fw0", + "type" : "raw", + "sha256" : swupdate_get_sha256(d, s, "flash-image.bin"), + } + + boot1 = boot0.copy() + boot1["device"] = "/dev/disk/by-partlabel/fw1" + + + return [boot0, boot1] diff --git a/layers/meta-belden-marvell-bsp/conf/machine/cn9130-bldn-mbv.conf b/layers/meta-belden-marvell-bsp/conf/machine/cn9130-bldn-mbv.conf deleted file mode 100644 index aa4fa07..0000000 --- a/layers/meta-belden-marvell-bsp/conf/machine/cn9130-bldn-mbv.conf +++ /dev/null @@ -1,6 +0,0 @@ -#@TYPE: Machine -#@NAME: cn9130-bldn-mbv -#@DESCRIPTION: CN9130 SOM based on Bldn MBV-A/B -# - -require conf/machine/include/cn913x.inc diff --git a/layers/meta-belden-marvell-bsp/conf/machine/cn9131-bldn-mbv.conf b/layers/meta-belden-marvell-bsp/conf/machine/cn9131-bldn-mbv.conf new file mode 100644 index 0000000..4069321 --- /dev/null +++ b/layers/meta-belden-marvell-bsp/conf/machine/cn9131-bldn-mbv.conf @@ -0,0 +1,10 @@ +#@TYPE: Machine +#@NAME: cn9131-bldn-mbv +#@DESCRIPTION: CN9131 SOM based on Bldn MBV-A/B +# + +require conf/machine/include/cn913x.inc + +### Device specific settings +# Needed for phy firmware +MACHINE_EXTRA_RDEPENDS += "linux-firmware-microchip" 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..cf7affe 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 @@ -51,10 +51,13 @@ APPEND += "console=ttyS0,115200" # for a wic image do_image_wic[depends] += "trusted-firmware-a:do_deploy" WKS_FILE = "cn913x-sdcard.wks.in" +COREOS_INSTALLER_WKS_FILE ?= "cn913x-sdcard-installer.wks" IMAGE_FSTYPES += "wic.xz wic.bmap" MACHINE_ESSENTIAL_EXTRA_RDEPENDS += " kernel-modules kernel-devicetree" +COREOS_IMAGE_SWUPDATE_EXTRACLASSES += " coreos-image-swupdate-cn913x" # No watchdog available yet EFIBOOTGUARD_TIMEOUT ?= "0" require conf/machine/include/coreos-generic-features/efi.inc +require conf/machine/include/coreos-generic-features/partitions.inc diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a_2.3-solidrun.bb b/layers/meta-belden-marvell-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a_2.3-solidrun.bb index 81763fc..1df40b7 100644 --- a/layers/meta-belden-marvell-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a_2.3-solidrun.bb +++ b/layers/meta-belden-marvell-bsp/recipes-bsp/trusted-firmware-a/trusted-firmware-a_2.3-solidrun.bb @@ -15,8 +15,8 @@ COMPATIBLE_MACHINE = "cn913x" DEPENDS += "mv-ddr-marvell coreutils-native" -CP_NUM:cn9132 = "3" -CP_NUM:cn9130 = "1" +CP_NUM:cn9131-bldn-mbv = "2" +CP_NUM:cn9130-cf-pro = "1" TFA_PLATFORM = "t9130" TFA_BUILD_TARGET = "all mrvl_flash" @@ -27,4 +27,4 @@ TFA_UBOOT = "1" TFA_UEFI = "0" -EXTRA_OEMAKE += "MV_DDR_PATH=${PKG_CONFIG_SYSROOT_DIR}/usr/src/mv-ddr-marvell CP_NUM=${CP_NUM} SCP_BL2=${WORKDIR}/mrvl_scp_bl2.img" +EXTRA_OEMAKE += "USE_COHERENT_MEM=0 LOG_LEVEL=20 MV_DDR_PATH=${PKG_CONFIG_SYSROOT_DIR}/usr/src/mv-ddr-marvell CP_NUM=${CP_NUM} SCP_BL2=${WORKDIR}/mrvl_scp_bl2.img" diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/0001-Remove-redundant-YYLOC-global-declaration.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/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_2019.10-solidrun/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_2019.10-solidrun/0001-cn9130-fix-compatible-node-inside-dts-pt-2.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/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_2019.10-solidrun/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_2019.10-solidrun/0001-cn9130-fix-compatible-node-inside-dts.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/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_2019.10-solidrun/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_2019.10-solidrun/0001-sr_cn913x_cex7-enable-VERSION_VARIABLE.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/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_2019.10-solidrun/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_2019.10-solidrun/0001-sr_cn913x_cex7-enable-more-image-formats.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/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_2019.10-solidrun/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_2019.10-solidrun/0021-octeontx2_cn913x-increase-CONFIG_SYS_BOOTM_LEN-to-32.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/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_2019.10-solidrun/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/cn913x.cfg b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/cn913x.cfg similarity index 100% rename from layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files/cn913x.cfg rename to layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/cn913x.cfg diff --git a/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/solidrun/0001-cmd-add-tlv_eeprom-command.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/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_2019.10-solidrun/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_2019.10-solidrun/solidrun/0002-cmd-tlv_eeprom.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/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_2019.10-solidrun/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_2019.10-solidrun/solidrun/0003-cmd-tlv_eeprom-remove-use-of-global-variable-current.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/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_2019.10-solidrun/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_2019.10-solidrun/solidrun/0004-cmd-tlv_eeprom-remove-use-of-global-variable-has_bee.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/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_2019.10-solidrun/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_2019.10-solidrun/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_2019.10-solidrun/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_2019.10-solidrun/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_2019.10-solidrun/solidrun/0006-cmd-tlv_eeprom-convert-functions-used-by-command-to-.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/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_2019.10-solidrun/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_2019.10-solidrun/solidrun/0007-cmd-tlv_eeprom-remove-empty-function-implementations.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/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_2019.10-solidrun/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_2019.10-solidrun/solidrun/0008-cmd-tlv_eeprom-split-off-tlv-library-from-command.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/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_2019.10-solidrun/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_2019.10-solidrun/solidrun/0009-lib-tlv_eeprom-add-function-for-reading-one-entry-in.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/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_2019.10-solidrun/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_2019.10-solidrun/solidrun/0010-uboot-marvell-patches.patch b/layers/meta-belden-marvell-bsp/recipes-bsp/u-boot/files_2019.10-solidrun/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_2019.10-solidrun/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", ++ "