Merge remote-tracking branch 'refs/remotes/spacebeaker/master' into rebase

Change-Id: Iccca50f4a4952d56413f60b124e4327a26de663b
diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md
new file mode 100644
index 0000000..03d0a95
--- /dev/null
+++ b/.github/CODE_OF_CONDUCT.md
@@ -0,0 +1,12 @@
+<!--
+     Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+
+     SPDX-License-Identifier: CC-BY-SA-4.0
+-->
+
+# Code of Conduct
+
+This repository and interactions with it fall under the [seL4 Code of Conduct][1] available from the [seL4 website][2].
+
+[1]: https://docs.sel4.systems/processes/conduct.html
+[2]: https://sel4.systems
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
new file mode 100644
index 0000000..d3a12db
--- /dev/null
+++ b/.github/CONTRIBUTING.md
@@ -0,0 +1,44 @@
+<!--
+     Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+
+     SPDX-License-Identifier: CC-BY-SA-4.0
+-->
+
+# Contributions Welcome
+
+Please see the [seL4 contributing guidelines][1] on the [seL4 website][2] for
+details.
+
+[1]: https://docs.sel4.systems/processes/contributing.html
+[2]: https://sel4.systems
+
+
+## Contact
+
+If you have larger changes or additions, it is a good idea to get in contact
+with us as <devel@sel4.systems>, so we can help you get started.
+
+The people responsible for the technical direction, procedures, and quality
+control are the [Technical Steering Committee][3] (TSC) of the seL4
+foundation. You can contact them either on the developer mailing list or on
+directly via email available from their profile pages.
+
+[3]: https://sel4.systems/Foundation/TSC
+
+
+## Developer Certificate of Origin (DCO)
+
+This repository uses the same sign-off process as the Linux kernel. For every
+commit, use
+
+    git commit -s
+
+to add a sign-off line to your commit message, which will come out as:
+
+    Signed-off-by: name <email>
+
+By adding this line, you make the declaration that you have the right to make
+this contribution under the open source license the files use that you changed
+or contributed.
+
+The full text of the declaration is at <https://developercertificate.org>.
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
new file mode 100644
index 0000000..c0f5398
--- /dev/null
+++ b/.github/workflows/pr.yml
@@ -0,0 +1,28 @@
+# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+#
+# SPDX-License-Identifier: BSD-2-Clause
+
+# Actions to run on pull requests
+
+name: PR
+
+on: [pull_request]
+
+jobs:
+  gitlint:
+    name: Gitlint
+    runs-on: ubuntu-latest
+    steps:
+    - uses: seL4/ci-actions/gitlint@master
+
+  whitespace:
+    name: 'Trailing Whitespace'
+    runs-on: ubuntu-latest
+    steps:
+    - uses: seL4/ci-actions/git-diff-check@master
+
+  shell:
+    name: 'Portable Shell'
+    runs-on: ubuntu-latest
+    steps:
+    - uses: seL4/ci-actions/bashisms@master
diff --git a/.github/workflows/prqueue.yml b/.github/workflows/prqueue.yml
new file mode 100644
index 0000000..58992e0
--- /dev/null
+++ b/.github/workflows/prqueue.yml
@@ -0,0 +1,21 @@
+# Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+#
+# SPDX-License-Identifier: BSD-2-Clause
+
+# Queue next PR on pushes to master
+name: PR Queue
+
+on:
+  push:
+    branches:
+      - master
+  workflow_dispatch: {}
+
+jobs:
+  notify:
+    name: Notify PR candidate
+    runs-on: ubuntu-latest
+    steps:
+    - uses: seL4/ci-actions/pr-queue@master
+      with:
+        github_token: ${{ secrets.GITHUB_TOKEN }}
diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
new file mode 100644
index 0000000..76dbb0a
--- /dev/null
+++ b/.github/workflows/push.yml
@@ -0,0 +1,35 @@
+# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+#
+# SPDX-License-Identifier: BSD-2-Clause
+
+# Actions to run on Push and Pull Request
+name: CI
+
+on:
+  push:
+    branches:
+      - master
+  pull_request:
+
+jobs:
+  check:
+    name: License Check
+    runs-on: ubuntu-latest
+    steps:
+    - uses: seL4/ci-actions/license-check@master
+
+  links:
+    name: Links
+    runs-on: ubuntu-latest
+    steps:
+      - uses: seL4/ci-actions/link-check@master
+        with:
+          exclude: js/node_modules
+
+  style:
+    name: Style
+    runs-on: ubuntu-latest
+    steps:
+    - uses: seL4/ci-actions/style@master
+      with:
+        diff_only: true
diff --git a/.github/workflows/sel4test-hw.yml b/.github/workflows/sel4test-hw.yml
new file mode 100644
index 0000000..39ea418
--- /dev/null
+++ b/.github/workflows/sel4test-hw.yml
@@ -0,0 +1,98 @@
+# Copyright 2021, Proofcraft Pty Ltd
+#
+# SPDX-License-Identifier: BSD-2-Clause
+
+# sel4test hardware builds and runs
+#
+# See sel4test-hw/builds.yml in the repo seL4/ci-actions for configs.
+
+name: seL4Test HW
+
+on:
+  # needs PR target for secrets access; guard by requiring label
+  pull_request_target:
+    types: [opened, reopened, synchronize, labeled]
+
+# downgrade permissions to read-only as you would have in a standard PR action
+permissions:
+  contents: read
+
+jobs:
+  hw-build:
+    name: HW Build
+    runs-on: ubuntu-latest
+    if: ${{ github.event_name == 'push' ||
+            github.event_name == 'pull_request_target' &&
+              github.event.action != 'labeled' &&
+              (contains(github.event.pull_request.labels.*.name, 'hw-build') ||
+               contains(github.event.pull_request.labels.*.name, 'hw-test')) ||
+            github.event_name == 'pull_request_target' &&
+              github.event.action == 'labeled' &&
+              (github.event.label.name == 'hw-build' ||
+               github.event.label.name == 'hw-test') }}
+    strategy:
+      fail-fast: false
+      matrix:
+        march: [armv7a, armv8a, nehalem]
+        compiler: [gcc, clang]
+        include:
+          - march: rv64imac
+            compiler: gcc
+    steps:
+    - name: Build
+      uses: seL4/ci-actions/sel4test-hw@master
+      with:
+        march: ${{ matrix.march }}
+        compiler: ${{ matrix.compiler }}
+        sha: ${{ github.event.pull_request.head.sha }}
+    - name: Upload images
+      uses: actions/upload-artifact@v2
+      with:
+        name: images-${{ matrix.march }}-${{ matrix.compiler }}
+        path: '*-images.tar.gz'
+
+  the_matrix:
+    name: Matrix
+    needs: hw-build
+    runs-on: ubuntu-latest
+    outputs:
+      matrix: ${{ steps.matrix.outputs.matrix }}
+    steps:
+    - id: matrix
+      uses: seL4/ci-actions/sel4test-hw-matrix@master
+
+  hw-run:
+    name: HW Run
+    runs-on: ubuntu-latest
+    needs: the_matrix
+    if: ${{ github.repository_owner == 'seL4' &&
+            (github.event_name == 'push' ||
+             github.event_name == 'pull_request_target' &&
+               github.event.action != 'labeled' &&
+               contains(github.event.pull_request.labels.*.name, 'hw-test') ||
+             github.event_name == 'pull_request_target' &&
+               github.event.action == 'labeled' &&
+               github.event.label.name == 'hw-test') }}
+    strategy:
+      fail-fast: false
+      matrix: ${{ fromJson(needs.the_matrix.outputs.matrix) }}
+    steps:
+      - name: Get machine queue
+        uses: actions/checkout@v2
+        with:
+          repository: seL4/machine_queue
+          path: machine_queue
+          token: ${{ secrets.PRIV_REPO_TOKEN }}
+      - name: Download image
+        uses: actions/download-artifact@v2
+        with:
+          name: images-${{ matrix.march }}-${{ matrix.compiler }}
+      - name: Run
+        uses: seL4/ci-actions/sel4test-hw-run@master
+        with:
+          platform: ${{ matrix.platform }}
+          compiler: ${{ matrix.compiler }}
+          mode: ${{ matrix.mode }}
+          index: $${{ strategy.job-index }}
+        env:
+          HW_SSH: ${{ secrets.HW_SSH }}
diff --git a/.github/workflows/sel4test-sim.yml b/.github/workflows/sel4test-sim.yml
new file mode 100644
index 0000000..65c4ffb
--- /dev/null
+++ b/.github/workflows/sel4test-sim.yml
@@ -0,0 +1,33 @@
+# Copyright 2021, Proofcraft Pty Ltd
+#
+# SPDX-License-Identifier: BSD-2-Clause
+
+# sel4test simulation runs
+#
+# See sel4test-sim/builds.yml in the repo seL4/ci-actions for configs.
+
+name: seL4Test Sim
+
+on:
+  push:
+    branches: [master]
+  pull_request:
+
+jobs:
+  simulation:
+    name: Simulation
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        march: [armv7a, armv8a, nehalem, rv32imac, rv64imac]
+        compiler: [gcc, clang]
+        exclude:
+          - march: rv32imac
+            compiler: clang
+          - march: rv64imac
+            compiler: clang
+    steps:
+    - uses: seL4/ci-actions/sel4test-sim@master
+      with:
+        march: ${{ matrix.march }}
+        compiler: ${{ matrix.compiler }}
diff --git a/.github/workflows/trigger.yml b/.github/workflows/trigger.yml
new file mode 100644
index 0000000..8410b7e
--- /dev/null
+++ b/.github/workflows/trigger.yml
@@ -0,0 +1,19 @@
+# Copyright 2021, Proofcraft Pty Ltd
+#
+# SPDX-License-Identifier: BSD-2-Clause
+
+# Trigger repository dispatch on main test repos
+name: Trigger
+
+on:
+  push:
+    branches: [master]
+
+jobs:
+  trigger:
+    name: Repository Dispatch
+    runs-on: ubuntu-latest
+    steps:
+    - uses: seL4/ci-actions/trigger@master
+      with:
+        token: ${{ secrets.PRIV_REPO_TOKEN }}
diff --git a/.licenseignore b/.licenseignore
index 7288d99..83d345d 100644
--- a/.licenseignore
+++ b/.licenseignore
@@ -1,11 +1,6 @@
-LICENSE.txt
-.git/*
-*LICENSE_*.txt
-.licenseignore
-liblwip/include
-liblwip/default_opts
-liblwip/lwip-1.4.1
-libethdrivers/src/plat/zynq7000/uboot
-libethdrivers/src/plat/zynq7000/zynq_gem.h
-libfdt
-.stylefilter
+# Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
+# SPDX-License-Identifier: BSD-2-Clause
+
+# This is for the old D61 license check too that bamboo is still running
+
+libfdt/LICENSE
diff --git a/.stylefilter b/.stylefilter
index 1a22309..4129f38 100644
--- a/.stylefilter
+++ b/.stylefilter
@@ -1,2 +1,8 @@
+# Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
+# SPDX-License-Identifier: BSD-2-Clause
+
 libfdt
 liblwip/default_opts/lwipopts.h
+# Imported sources from zf_log
+libutils/include/utils/zf_log.h
+libutils/src/zf_log.c
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3cd1295..24bfe48 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,13 +1,7 @@
 #
-# Copyright 2017, Data61
-# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-# ABN 41 687 119 230.
+# Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 #
-# This software may be distributed and modified according to the terms of
-# the BSD 2-Clause license. Note that NO WARRANTY is provided.
-# See "LICENSE_BSD2.txt" for details.
-#
-# @TAG(DATA61_BSD)
+# SPDX-License-Identifier: BSD-2-Clause
 #
 
 cmake_minimum_required(VERSION 3.7.2)
diff --git a/Findutil_libs.cmake b/Findutil_libs.cmake
index 73ba91f..ddea21b 100644
--- a/Findutil_libs.cmake
+++ b/Findutil_libs.cmake
@@ -1,13 +1,7 @@
 #
-# Copyright 2019, Data61
-# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-# ABN 41 687 119 230.
+# Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
 #
-# This software may be distributed and modified according to the terms of
-# the BSD 2-Clause license. Note that NO WARRANTY is provided.
-# See "LICENSE_BSD2.txt" for details.
-#
-# @TAG(DATA61_BSD)
+# SPDX-License-Identifier: BSD-2-Clause
 #
 
 set(UTIL_LIBS_DIR "${CMAKE_CURRENT_LIST_DIR}" CACHE STRING "")
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..de4f324
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,22 @@
+<!--
+     Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+
+     SPDX-License-Identifier: CC-BY-SA-4.0
+-->
+
+# License
+
+Please see the individual library directories and source files for the licenses
+that apply to each library.
+
+For licensing an application using the libraries in each repository, you must
+check each library that you link against.
+
+The files in this repository are released under standard open source licenses,
+identified by [SPDX license tags][1]. See the individual file headers for
+details, or use one of the publicly available SPDX tools to generate a bill of
+materials. The directory [`LICENSES`][2] contains the text for all licenses
+that are mentioned by files in this repository.
+
+[1]: https://spdx.org
+[2]: LICENSES/
diff --git a/LICENSE.txt b/LICENSE.txt
deleted file mode 100644
index 64659d8..0000000
--- a/LICENSE.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Please see the individual library directories and source files for the licenses
-that apply to each library.
-
-For licensing an application using the libraries in each repository, you must
-check each library that you link against.
diff --git a/LICENSES/BSD-1-Clause.txt b/LICENSES/BSD-1-Clause.txt
new file mode 100644
index 0000000..3b3c4e8
--- /dev/null
+++ b/LICENSES/BSD-1-Clause.txt
@@ -0,0 +1,19 @@
+Copyright (c) 1995, 1999 Berkeley Software Design, Inc.  All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``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 Berkeley Software Design, Inc. 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.
diff --git a/LICENSES/BSD-2-Clause.txt b/LICENSES/BSD-2-Clause.txt
new file mode 100644
index 0000000..baa80b5
--- /dev/null
+++ b/LICENSES/BSD-2-Clause.txt
@@ -0,0 +1,22 @@
+Copyright (c) <year> <owner> All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. 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.
+
+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.
diff --git a/LICENSES/BSD-3-Clause.txt b/LICENSES/BSD-3-Clause.txt
new file mode 100644
index 0000000..0741db7
--- /dev/null
+++ b/LICENSES/BSD-3-Clause.txt
@@ -0,0 +1,26 @@
+Copyright (c) <year> <owner>. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification,
+are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice,
+this list of conditions and the following disclaimer.
+
+2. 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.
+
+3. Neither the name of the copyright holder 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.
diff --git a/LICENSES/CC-BY-SA-4.0.txt b/LICENSES/CC-BY-SA-4.0.txt
new file mode 100644
index 0000000..4dfebb8
--- /dev/null
+++ b/LICENSES/CC-BY-SA-4.0.txt
@@ -0,0 +1,349 @@
+Creative Commons Attribution-ShareAlike 4.0 International
+
+Creative Commons Corporation (“Creative Commons”) is not a law firm and does
+not provide legal services or legal advice. Distribution of Creative Commons
+public licenses does not create a lawyer-client or other relationship. Creative
+Commons makes its licenses and related information available on an “as-is”
+basis. Creative Commons gives no warranties regarding its licenses, any material
+licensed under their terms and conditions, or any related information. Creative
+Commons disclaims all liability for damages resulting from their use to the
+fullest extent possible.
+
+Using Creative Commons Public Licenses
+
+Creative Commons public licenses provide a standard set of terms and conditions
+that creators and other rights holders may use to share original works of
+authorship and other material subject to copyright and certain other rights
+specified in the public license below. The following considerations are for
+informational purposes only, are not exhaustive, and do not form part of our
+licenses.
+
+Considerations for licensors: Our public licenses are intended for use by
+those authorized to give the public permission to use material in ways otherwise
+restricted by copyright and certain other rights. Our licenses are irrevocable.
+Licensors should read and understand the terms and conditions of the license
+they choose before applying it. Licensors should also secure all rights necessary
+before applying our licenses so that the public can reuse the material as
+expected. Licensors should clearly mark any material not subject to the license.
+This includes other CC-licensed material, or material used under an exception
+or limitation to copyright. More considerations for licensors.
+
+Considerations for the public: By using one of our public licenses, a licensor
+grants the public permission to use the licensed material under specified
+terms and conditions. If the licensor’s permission is not necessary for any
+reason–for example, because of any applicable exception or limitation to copyright–then
+that use is not regulated by the license. Our licenses grant only permissions
+under copyright and certain other rights that a licensor has authority to
+grant. Use of the licensed material may still be restricted for other reasons,
+including because others have copyright or other rights in the material. A
+licensor may make special requests, such as asking that all changes be marked
+or described.
+
+Although not required by our licenses, you are encouraged to respect those
+requests where reasonable. More considerations for the public.
+
+Creative Commons Attribution-ShareAlike 4.0 International Public License
+
+By exercising the Licensed Rights (defined below), You accept and agree to
+be bound by the terms and conditions of this Creative Commons Attribution-ShareAlike
+4.0 International Public License ("Public License"). To the extent this Public
+License may be interpreted as a contract, You are granted the Licensed Rights
+in consideration of Your acceptance of these terms and conditions, and the
+Licensor grants You such rights in consideration of benefits the Licensor
+receives from making the Licensed Material available under these terms and
+conditions.
+
+Section 1 – Definitions.
+
+a.	Adapted Material means material subject to Copyright and Similar Rights
+that is derived from or based upon the Licensed Material and in which the
+Licensed Material is translated, altered, arranged, transformed, or otherwise
+modified in a manner requiring permission under the Copyright and Similar
+Rights held by the Licensor. For purposes of this Public License, where the
+Licensed Material is a musical work, performance, or sound recording, Adapted
+Material is always produced where the Licensed Material is synched in timed
+relation with a moving image.
+
+b.	Adapter's License means the license You apply to Your Copyright and Similar
+Rights in Your contributions to Adapted Material in accordance with the terms
+and conditions of this Public License.
+
+c.	BY-SA Compatible License means a license listed at creativecommons.org/compatiblelicenses,
+approved by Creative Commons as essentially the equivalent of this Public
+License.
+
+d.	Copyright and Similar Rights means copyright and/or similar rights closely
+related to copyright including, without limitation, performance, broadcast,
+sound recording, and Sui Generis Database Rights, without regard to how the
+rights are labeled or categorized. For purposes of this Public License, the
+rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights.
+
+e.	Effective Technological Measures means those measures that, in the absence
+of proper authority, may not be circumvented under laws fulfilling obligations
+under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996,
+and/or similar international agreements.
+
+f.	Exceptions and Limitations means fair use, fair dealing, and/or any other
+exception or limitation to Copyright and Similar Rights that applies to Your
+use of the Licensed Material.
+
+g.	License Elements means the license attributes listed in the name of a Creative
+Commons Public License. The License Elements of this Public License are Attribution
+and ShareAlike.
+
+h.	Licensed Material means the artistic or literary work, database, or other
+material to which the Licensor applied this Public License.
+
+i.	Licensed Rights means the rights granted to You subject to the terms and
+conditions of this Public License, which are limited to all Copyright and
+Similar Rights that apply to Your use of the Licensed Material and that the
+Licensor has authority to license.
+
+j.	Licensor means the individual(s) or entity(ies) granting rights under this
+Public License.
+
+k.	Share means to provide material to the public by any means or process that
+requires permission under the Licensed Rights, such as reproduction, public
+display, public performance, distribution, dissemination, communication, or
+importation, and to make material available to the public including in ways
+that members of the public may access the material from a place and at a time
+individually chosen by them.
+
+l.	Sui Generis Database Rights means rights other than copyright resulting
+from Directive 96/9/EC of the European Parliament and of the Council of 11
+March 1996 on the legal protection of databases, as amended and/or succeeded,
+as well as other essentially equivalent rights anywhere in the world.
+
+m.	You means the individual or entity exercising the Licensed Rights under
+this Public License. Your has a corresponding meaning.
+
+Section 2 – Scope.
+
+     a.	License grant.
+
+1. Subject to the terms and conditions of this Public License, the Licensor
+hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive,
+irrevocable license to exercise the Licensed Rights in the Licensed Material
+to:
+
+A. reproduce and Share the Licensed Material, in whole or in part; and
+
+               B. produce, reproduce, and Share Adapted Material.
+
+2. Exceptions and Limitations. For the avoidance of doubt, where Exceptions
+and Limitations apply to Your use, this Public License does not apply, and
+You do not need to comply with its terms and conditions.
+
+3. Term. The term of this Public License is specified in Section 6(a).
+
+4. Media and formats; technical modifications allowed. The Licensor authorizes
+You to exercise the Licensed Rights in all media and formats whether now known
+or hereafter created, and to make technical modifications necessary to do
+so. The Licensor waives and/or agrees not to assert any right or authority
+to forbid You from making technical modifications necessary to exercise the
+Licensed Rights, including technical modifications necessary to circumvent
+Effective Technological Measures. For purposes of this Public License, simply
+making modifications authorized by this Section 2(a)(4) never produces Adapted
+Material.
+
+          5. Downstream recipients.
+
+A. Offer from the Licensor – Licensed Material. Every recipient of the Licensed
+Material automatically receives an offer from the Licensor to exercise the
+Licensed Rights under the terms and conditions of this Public License.
+
+B. Additional offer from the Licensor – Adapted Material. Every recipient
+of Adapted Material from You automatically receives an offer from the Licensor
+to exercise the Licensed Rights in the Adapted Material under the conditions
+of the Adapter’s License You apply.
+
+C. No downstream restrictions. You may not offer or impose any additional
+or different terms or conditions on, or apply any Effective Technological
+Measures to, the Licensed Material if doing so restricts exercise of the Licensed
+Rights by any recipient of the Licensed Material.
+
+6. No endorsement. Nothing in this Public License constitutes or may be construed
+as permission to assert or imply that You are, or that Your use of the Licensed
+Material is, connected with, or sponsored, endorsed, or granted official status
+by, the Licensor or others designated to receive attribution as provided in
+Section 3(a)(1)(A)(i).
+
+     b.	Other rights.
+
+1. Moral rights, such as the right of integrity, are not licensed under this
+Public License, nor are publicity, privacy, and/or other similar personality
+rights; however, to the extent possible, the Licensor waives and/or agrees
+not to assert any such rights held by the Licensor to the limited extent necessary
+to allow You to exercise the Licensed Rights, but not otherwise.
+
+2. Patent and trademark rights are not licensed under this Public License.
+
+3. To the extent possible, the Licensor waives any right to collect royalties
+from You for the exercise of the Licensed Rights, whether directly or through
+a collecting society under any voluntary or waivable statutory or compulsory
+licensing scheme. In all other cases the Licensor expressly reserves any right
+to collect such royalties.
+
+Section 3 – License Conditions.
+
+Your exercise of the Licensed Rights is expressly made subject to the following
+conditions.
+
+     a.	Attribution.
+
+1. If You Share the Licensed Material (including in modified form), You must:
+
+A. retain the following if it is supplied by the Licensor with the Licensed
+Material:
+
+i.	identification of the creator(s) of the Licensed Material and any others
+designated to receive attribution, in any reasonable manner requested by the
+Licensor (including by pseudonym if designated);
+
+                    ii.	a copyright notice;
+
+                    iii. a notice that refers to this Public License;
+
+                    iv.	a notice that refers to the disclaimer of warranties;
+
+v.	a URI or hyperlink to the Licensed Material to the extent reasonably practicable;
+
+B. indicate if You modified the Licensed Material and retain an indication
+of any previous modifications; and
+
+C. indicate the Licensed Material is licensed under this Public License, and
+include the text of, or the URI or hyperlink to, this Public License.
+
+2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner
+based on the medium, means, and context in which You Share the Licensed Material.
+For example, it may be reasonable to satisfy the conditions by providing a
+URI or hyperlink to a resource that includes the required information.
+
+3. If requested by the Licensor, You must remove any of the information required
+by Section 3(a)(1)(A) to the extent reasonably practicable.
+
+b.	ShareAlike.In addition to the conditions in Section 3(a), if You Share
+Adapted Material You produce, the following conditions also apply.
+
+1. The Adapter’s License You apply must be a Creative Commons license with
+the same License Elements, this version or later, or a BY-SA Compatible License.
+
+2. You must include the text of, or the URI or hyperlink to, the Adapter's
+License You apply. You may satisfy this condition in any reasonable manner
+based on the medium, means, and context in which You Share Adapted Material.
+
+3. You may not offer or impose any additional or different terms or conditions
+on, or apply any Effective Technological Measures to, Adapted Material that
+restrict exercise of the rights granted under the Adapter's License You apply.
+
+Section 4 – Sui Generis Database Rights.
+
+Where the Licensed Rights include Sui Generis Database Rights that apply to
+Your use of the Licensed Material:
+
+a.	for the avoidance of doubt, Section 2(a)(1) grants You the right to extract,
+reuse, reproduce, and Share all or a substantial portion of the contents of
+the database;
+
+b.	if You include all or a substantial portion of the database contents in
+a database in which You have Sui Generis Database Rights, then the database
+in which You have Sui Generis Database Rights (but not its individual contents)
+is Adapted Material, including for purposes of Section 3(b); and
+
+c.	You must comply with the conditions in Section 3(a) if You Share all or
+a substantial portion of the contents of the database.
+For the avoidance of doubt, this Section 4 supplements and does not replace
+Your obligations under this Public License where the Licensed Rights include
+other Copyright and Similar Rights.
+
+Section 5 – Disclaimer of Warranties and Limitation of Liability.
+
+a.	Unless otherwise separately undertaken by the Licensor, to the extent possible,
+the Licensor offers the Licensed Material as-is and as-available, and makes
+no representations or warranties of any kind concerning the Licensed Material,
+whether express, implied, statutory, or other. This includes, without limitation,
+warranties of title, merchantability, fitness for a particular purpose, non-infringement,
+absence of latent or other defects, accuracy, or the presence or absence of
+errors, whether or not known or discoverable. Where disclaimers of warranties
+are not allowed in full or in part, this disclaimer may not apply to You.
+
+b.	To the extent possible, in no event will the Licensor be liable to You
+on any legal theory (including, without limitation, negligence) or otherwise
+for any direct, special, indirect, incidental, consequential, punitive, exemplary,
+or other losses, costs, expenses, or damages arising out of this Public License
+or use of the Licensed Material, even if the Licensor has been advised of
+the possibility of such losses, costs, expenses, or damages. Where a limitation
+of liability is not allowed in full or in part, this limitation may not apply
+to You.
+
+c.	The disclaimer of warranties and limitation of liability provided above
+shall be interpreted in a manner that, to the extent possible, most closely
+approximates an absolute disclaimer and waiver of all liability.
+
+Section 6 – Term and Termination.
+
+a.	This Public License applies for the term of the Copyright and Similar Rights
+licensed here. However, if You fail to comply with this Public License, then
+Your rights under this Public License terminate automatically.
+
+b.	Where Your right to use the Licensed Material has terminated under Section
+6(a), it reinstates:
+
+1. automatically as of the date the violation is cured, provided it is cured
+within 30 days of Your discovery of the violation; or
+
+          2. upon express reinstatement by the Licensor.
+
+c.	For the avoidance of doubt, this Section 6(b) does not affect any right
+the Licensor may have to seek remedies for Your violations of this Public
+License.
+
+d.	For the avoidance of doubt, the Licensor may also offer the Licensed Material
+under separate terms or conditions or stop distributing the Licensed Material
+at any time; however, doing so will not terminate this Public License.
+
+     e.	Sections 1, 5, 6, 7, and 8 survive termination of this Public License.
+
+Section 7 – Other Terms and Conditions.
+
+a.	The Licensor shall not be bound by any additional or different terms or
+conditions communicated by You unless expressly agreed.
+
+b.	Any arrangements, understandings, or agreements regarding the Licensed
+Material not stated herein are separate from and independent of the terms
+and conditions of this Public License.
+
+Section 8 – Interpretation.
+
+a.	For the avoidance of doubt, this Public License does not, and shall not
+be interpreted to, reduce, limit, restrict, or impose conditions on any use
+of the Licensed Material that could lawfully be made without permission under
+this Public License.
+
+b.	To the extent possible, if any provision of this Public License is deemed
+unenforceable, it shall be automatically reformed to the minimum extent necessary
+to make it enforceable. If the provision cannot be reformed, it shall be severed
+from this Public License without affecting the enforceability of the remaining
+terms and conditions.
+
+c.	No term or condition of this Public License will be waived and no failure
+to comply consented to unless expressly agreed to by the Licensor.
+
+d.	Nothing in this Public License constitutes or may be interpreted as a limitation
+upon, or waiver of, any privileges and immunities that apply to the Licensor
+or You, including from the legal processes of any jurisdiction or authority.
+
+Creative Commons is not a party to its public licenses. Notwithstanding, Creative
+Commons may elect to apply one of its public licenses to material it publishes
+and in those instances will be considered the “Licensor.” Except for the limited
+purpose of indicating that material is shared under a Creative Commons public
+license or as otherwise permitted by the Creative Commons policies published
+at creativecommons.org/policies, Creative Commons does not authorize the use
+of the trademark “Creative Commons” or any other trademark or logo of Creative
+Commons without its prior written consent including, without limitation, in
+connection with any unauthorized modifications to any of its public licenses
+or any other arrangements, understandings, or agreements concerning use of
+licensed material. For the avoidance of doubt, this paragraph does not form
+part of the public licenses.
+
+Creative Commons may be contacted at creativecommons.org.
diff --git a/LICENSES/GPL-2.0-only.txt b/LICENSES/GPL-2.0-only.txt
new file mode 100644
index 0000000..3b6070f
--- /dev/null
+++ b/LICENSES/GPL-2.0-only.txt
@@ -0,0 +1,311 @@
+GNU GENERAL PUBLIC LICENSE
+Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share
+and change it. By contrast, the GNU General Public License is intended to
+guarantee your freedom to share and change free software--to make sure the
+software is free for all its users. This General Public License applies to
+most of the Free Software Foundation's software and to any other program whose
+authors commit to using it. (Some other Free Software Foundation software
+is covered by the GNU Lesser General Public License instead.) You can apply
+it to your programs, too.
+
+When we speak of free software, we are referring to freedom, not price. Our
+General Public Licenses are designed to make sure that you have the freedom
+to distribute copies of free software (and charge for this service if you
+wish), that you receive source code or can get it if you want it, that you
+can change the software or use pieces of it in new free programs; and that
+you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to
+deny you these rights or to ask you to surrender the rights. These restrictions
+translate to certain responsibilities for you if you distribute copies of
+the software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or
+for a fee, you must give the recipients all the rights that you have. You
+must make sure that they, too, receive or can get the source code. And you
+must show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2)
+offer you this license which gives you legal permission to copy, distribute
+and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that
+everyone understands that there is no warranty for this free software. If
+the software is modified by someone else and passed on, we want its recipients
+to know that what they have is not the original, so that any problems introduced
+by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents. We
+wish to avoid the danger that redistributors of a free program will individually
+obtain patent licenses, in effect making the program proprietary. To prevent
+this, we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification
+follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License applies to any program or other work which contains a notice
+placed by the copyright holder saying it may be distributed under the terms
+of this General Public License. The "Program", below, refers to any such program
+or work, and a "work based on the Program" means either the Program or any
+derivative work under copyright law: that is to say, a work containing the
+Program or a portion of it, either verbatim or with modifications and/or translated
+into another language. (Hereinafter, translation is included without limitation
+in the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not covered
+by this License; they are outside its scope. The act of running the Program
+is not restricted, and the output from the Program is covered only if its
+contents constitute a work based on the Program (independent of having been
+made by running the Program). Whether that is true depends on what the Program
+does.
+
+1. You may copy and distribute verbatim copies of the Program's source code
+as you receive it, in any medium, provided that you conspicuously and appropriately
+publish on each copy an appropriate copyright notice and disclaimer of warranty;
+keep intact all the notices that refer to this License and to the absence
+of any warranty; and give any other recipients of the Program a copy of this
+License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you
+may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of it,
+thus forming a work based on the Program, and copy and distribute such modifications
+or work under the terms of Section 1 above, provided that you also meet all
+of these conditions:
+
+a) You must cause the modified files to carry prominent notices stating that
+you changed the files and the date of any change.
+
+b) You must cause any work that you distribute or publish, that in whole or
+in part contains or is derived from the Program or any part thereof, to be
+licensed as a whole at no charge to all third parties under the terms of this
+License.
+
+c) If the modified program normally reads commands interactively when run,
+you must cause it, when started running for such interactive use in the most
+ordinary way, to print or display an announcement including an appropriate
+copyright notice and a notice that there is no warranty (or else, saying that
+you provide a warranty) and that users may redistribute the program under
+these conditions, and telling the user how to view a copy of this License.
+(Exception: if the Program itself is interactive but does not normally print
+such an announcement, your work based on the Program is not required to print
+an announcement.)
+
+These requirements apply to the modified work as a whole. If identifiable
+sections of that work are not derived from the Program, and can be reasonably
+considered independent and separate works in themselves, then this License,
+and its terms, do not apply to those sections when you distribute them as
+separate works. But when you distribute the same sections as part of a whole
+which is a work based on the Program, the distribution of the whole must be
+on the terms of this License, whose permissions for other licensees extend
+to the entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise
+the right to control the distribution of derivative or collective works based
+on the Program.
+
+In addition, mere aggregation of another work not based on the Program with
+the Program (or with a work based on the Program) on a volume of a storage
+or distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may copy and distribute the Program (or a work based on it, under Section
+2) in object code or executable form under the terms of Sections 1 and 2 above
+provided that you also do one of the following:
+
+a) Accompany it with the complete corresponding machine-readable source code,
+which must be distributed under the terms of Sections 1 and 2 above on a medium
+customarily used for software interchange; or,
+
+b) Accompany it with a written offer, valid for at least three years, to give
+any third party, for a charge no more than your cost of physically performing
+source distribution, a complete machine-readable copy of the corresponding
+source code, to be distributed under the terms of Sections 1 and 2 above on
+a medium customarily used for software interchange; or,
+
+c) Accompany it with the information you received as to the offer to distribute
+corresponding source code. (This alternative is allowed only for noncommercial
+distribution and only if you received the program in object code or executable
+form with such an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for making
+modifications to it. For an executable work, complete source code means all
+the source code for all modules it contains, plus any associated interface
+definition files, plus the scripts used to control compilation and installation
+of the executable. However, as a special exception, the source code distributed
+need not include anything that is normally distributed (in either source or
+binary form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component itself
+accompanies the executable.
+
+If distribution of executable or object code is made by offering access to
+copy from a designated place, then offering equivalent access to copy the
+source code from the same place counts as distribution of the source code,
+even though third parties are not compelled to copy the source along with
+the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program except
+as expressly provided under this License. Any attempt otherwise to copy, modify,
+sublicense or distribute the Program is void, and will automatically terminate
+your rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses terminated
+so long as such parties remain in full compliance.
+
+5. You are not required to accept this License, since you have not signed
+it. However, nothing else grants you permission to modify or distribute the
+Program or its derivative works. These actions are prohibited by law if you
+do not accept this License. Therefore, by modifying or distributing the Program
+(or any work based on the Program), you indicate your acceptance of this License
+to do so, and all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the Program),
+the recipient automatically receives a license from the original licensor
+to copy, distribute or modify the Program subject to these terms and conditions.
+You may not impose any further restrictions on the recipients' exercise of
+the rights granted herein. You are not responsible for enforcing compliance
+by third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent infringement
+or for any other reason (not limited to patent issues), conditions are imposed
+on you (whether by court order, agreement or otherwise) that contradict the
+conditions of this License, they do not excuse you from the conditions of
+this License. If you cannot distribute so as to satisfy simultaneously your
+obligations under this License and any other pertinent obligations, then as
+a consequence you may not distribute the Program at all. For example, if a
+patent license would not permit royalty-free redistribution of the Program
+by all those who receive copies directly or indirectly through you, then the
+only way you could satisfy both it and this License would be to refrain entirely
+from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply and
+the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents
+or other property right claims or to contest validity of any such claims;
+this section has the sole purpose of protecting the integrity of the free
+software distribution system, which is implemented by public license practices.
+Many people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose
+that choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain
+countries either by patents or by copyrighted interfaces, the original copyright
+holder who places the Program under this License may add an explicit geographical
+distribution limitation excluding those countries, so that distribution is
+permitted only in or among countries not thus excluded. In such case, this
+License incorporates the limitation as if written in the body of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions of
+the General Public License from time to time. Such new versions will be similar
+in spirit to the present version, but may differ in detail to address new
+problems or concerns.
+
+Each version is given a distinguishing version number. If the Program specifies
+a version number of this License which applies to it and "any later version",
+you have the option of following the terms and conditions either of that version
+or of any later version published by the Free Software Foundation. If the
+Program does not specify a version number of this License, you may choose
+any version ever published by the Free Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free programs
+whose distribution conditions are different, write to the author to ask for
+permission. For software which is copyrighted by the Free Software Foundation,
+write to the Free Software Foundation; we sometimes make exceptions for this.
+Our decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing and reuse
+of software generally.
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM
+"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
+OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
+OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
+OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES
+OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH
+HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest possible
+use to the public, the best way to achieve this is to make it free software
+which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program. It is safest to attach
+them to the start of each source file to most effectively convey the exclusion
+of warranty; and each file should have at least the "copyright" line and a
+pointer to where the full notice is found.
+
+one line to give the program's name and an idea of what it does. Copyright
+(C) yyyy name of author
+
+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 (at your option) 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, write to the Free Software Foundation, Inc., 51 Franklin
+Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how
+to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this when
+it starts in an interactive mode:
+
+Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
+with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software,
+and you are welcome to redistribute it under certain conditions; type `show
+c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may be
+called something other than `show w' and `show c'; they could even be mouse-clicks
+or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your school,
+if any, to sign a "copyright disclaimer" for the program, if necessary. Here
+is a sample; alter the names:
+
+Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision'
+(which makes passes at compilers) written by James Hacker.
+
+signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice
diff --git a/LICENSES/GPL-2.0-or-later.txt b/LICENSES/GPL-2.0-or-later.txt
new file mode 100644
index 0000000..3b6070f
--- /dev/null
+++ b/LICENSES/GPL-2.0-or-later.txt
@@ -0,0 +1,311 @@
+GNU GENERAL PUBLIC LICENSE
+Version 2, June 1991
+
+Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
+
+Everyone is permitted to copy and distribute verbatim copies of this license
+document, but changing it is not allowed.
+
+Preamble
+
+The licenses for most software are designed to take away your freedom to share
+and change it. By contrast, the GNU General Public License is intended to
+guarantee your freedom to share and change free software--to make sure the
+software is free for all its users. This General Public License applies to
+most of the Free Software Foundation's software and to any other program whose
+authors commit to using it. (Some other Free Software Foundation software
+is covered by the GNU Lesser General Public License instead.) You can apply
+it to your programs, too.
+
+When we speak of free software, we are referring to freedom, not price. Our
+General Public Licenses are designed to make sure that you have the freedom
+to distribute copies of free software (and charge for this service if you
+wish), that you receive source code or can get it if you want it, that you
+can change the software or use pieces of it in new free programs; and that
+you know you can do these things.
+
+To protect your rights, we need to make restrictions that forbid anyone to
+deny you these rights or to ask you to surrender the rights. These restrictions
+translate to certain responsibilities for you if you distribute copies of
+the software, or if you modify it.
+
+For example, if you distribute copies of such a program, whether gratis or
+for a fee, you must give the recipients all the rights that you have. You
+must make sure that they, too, receive or can get the source code. And you
+must show them these terms so they know their rights.
+
+We protect your rights with two steps: (1) copyright the software, and (2)
+offer you this license which gives you legal permission to copy, distribute
+and/or modify the software.
+
+Also, for each author's protection and ours, we want to make certain that
+everyone understands that there is no warranty for this free software. If
+the software is modified by someone else and passed on, we want its recipients
+to know that what they have is not the original, so that any problems introduced
+by others will not reflect on the original authors' reputations.
+
+Finally, any free program is threatened constantly by software patents. We
+wish to avoid the danger that redistributors of a free program will individually
+obtain patent licenses, in effect making the program proprietary. To prevent
+this, we have made it clear that any patent must be licensed for everyone's
+free use or not licensed at all.
+
+The precise terms and conditions for copying, distribution and modification
+follow.
+
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+0. This License applies to any program or other work which contains a notice
+placed by the copyright holder saying it may be distributed under the terms
+of this General Public License. The "Program", below, refers to any such program
+or work, and a "work based on the Program" means either the Program or any
+derivative work under copyright law: that is to say, a work containing the
+Program or a portion of it, either verbatim or with modifications and/or translated
+into another language. (Hereinafter, translation is included without limitation
+in the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not covered
+by this License; they are outside its scope. The act of running the Program
+is not restricted, and the output from the Program is covered only if its
+contents constitute a work based on the Program (independent of having been
+made by running the Program). Whether that is true depends on what the Program
+does.
+
+1. You may copy and distribute verbatim copies of the Program's source code
+as you receive it, in any medium, provided that you conspicuously and appropriately
+publish on each copy an appropriate copyright notice and disclaimer of warranty;
+keep intact all the notices that refer to this License and to the absence
+of any warranty; and give any other recipients of the Program a copy of this
+License along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and you
+may at your option offer warranty protection in exchange for a fee.
+
+2. You may modify your copy or copies of the Program or any portion of it,
+thus forming a work based on the Program, and copy and distribute such modifications
+or work under the terms of Section 1 above, provided that you also meet all
+of these conditions:
+
+a) You must cause the modified files to carry prominent notices stating that
+you changed the files and the date of any change.
+
+b) You must cause any work that you distribute or publish, that in whole or
+in part contains or is derived from the Program or any part thereof, to be
+licensed as a whole at no charge to all third parties under the terms of this
+License.
+
+c) If the modified program normally reads commands interactively when run,
+you must cause it, when started running for such interactive use in the most
+ordinary way, to print or display an announcement including an appropriate
+copyright notice and a notice that there is no warranty (or else, saying that
+you provide a warranty) and that users may redistribute the program under
+these conditions, and telling the user how to view a copy of this License.
+(Exception: if the Program itself is interactive but does not normally print
+such an announcement, your work based on the Program is not required to print
+an announcement.)
+
+These requirements apply to the modified work as a whole. If identifiable
+sections of that work are not derived from the Program, and can be reasonably
+considered independent and separate works in themselves, then this License,
+and its terms, do not apply to those sections when you distribute them as
+separate works. But when you distribute the same sections as part of a whole
+which is a work based on the Program, the distribution of the whole must be
+on the terms of this License, whose permissions for other licensees extend
+to the entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest your
+rights to work written entirely by you; rather, the intent is to exercise
+the right to control the distribution of derivative or collective works based
+on the Program.
+
+In addition, mere aggregation of another work not based on the Program with
+the Program (or with a work based on the Program) on a volume of a storage
+or distribution medium does not bring the other work under the scope of this
+License.
+
+3. You may copy and distribute the Program (or a work based on it, under Section
+2) in object code or executable form under the terms of Sections 1 and 2 above
+provided that you also do one of the following:
+
+a) Accompany it with the complete corresponding machine-readable source code,
+which must be distributed under the terms of Sections 1 and 2 above on a medium
+customarily used for software interchange; or,
+
+b) Accompany it with a written offer, valid for at least three years, to give
+any third party, for a charge no more than your cost of physically performing
+source distribution, a complete machine-readable copy of the corresponding
+source code, to be distributed under the terms of Sections 1 and 2 above on
+a medium customarily used for software interchange; or,
+
+c) Accompany it with the information you received as to the offer to distribute
+corresponding source code. (This alternative is allowed only for noncommercial
+distribution and only if you received the program in object code or executable
+form with such an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for making
+modifications to it. For an executable work, complete source code means all
+the source code for all modules it contains, plus any associated interface
+definition files, plus the scripts used to control compilation and installation
+of the executable. However, as a special exception, the source code distributed
+need not include anything that is normally distributed (in either source or
+binary form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component itself
+accompanies the executable.
+
+If distribution of executable or object code is made by offering access to
+copy from a designated place, then offering equivalent access to copy the
+source code from the same place counts as distribution of the source code,
+even though third parties are not compelled to copy the source along with
+the object code.
+
+4. You may not copy, modify, sublicense, or distribute the Program except
+as expressly provided under this License. Any attempt otherwise to copy, modify,
+sublicense or distribute the Program is void, and will automatically terminate
+your rights under this License. However, parties who have received copies,
+or rights, from you under this License will not have their licenses terminated
+so long as such parties remain in full compliance.
+
+5. You are not required to accept this License, since you have not signed
+it. However, nothing else grants you permission to modify or distribute the
+Program or its derivative works. These actions are prohibited by law if you
+do not accept this License. Therefore, by modifying or distributing the Program
+(or any work based on the Program), you indicate your acceptance of this License
+to do so, and all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+6. Each time you redistribute the Program (or any work based on the Program),
+the recipient automatically receives a license from the original licensor
+to copy, distribute or modify the Program subject to these terms and conditions.
+You may not impose any further restrictions on the recipients' exercise of
+the rights granted herein. You are not responsible for enforcing compliance
+by third parties to this License.
+
+7. If, as a consequence of a court judgment or allegation of patent infringement
+or for any other reason (not limited to patent issues), conditions are imposed
+on you (whether by court order, agreement or otherwise) that contradict the
+conditions of this License, they do not excuse you from the conditions of
+this License. If you cannot distribute so as to satisfy simultaneously your
+obligations under this License and any other pertinent obligations, then as
+a consequence you may not distribute the Program at all. For example, if a
+patent license would not permit royalty-free redistribution of the Program
+by all those who receive copies directly or indirectly through you, then the
+only way you could satisfy both it and this License would be to refrain entirely
+from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply and
+the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any patents
+or other property right claims or to contest validity of any such claims;
+this section has the sole purpose of protecting the integrity of the free
+software distribution system, which is implemented by public license practices.
+Many people have made generous contributions to the wide range of software
+distributed through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing to
+distribute software through any other system and a licensee cannot impose
+that choice.
+
+This section is intended to make thoroughly clear what is believed to be a
+consequence of the rest of this License.
+
+8. If the distribution and/or use of the Program is restricted in certain
+countries either by patents or by copyrighted interfaces, the original copyright
+holder who places the Program under this License may add an explicit geographical
+distribution limitation excluding those countries, so that distribution is
+permitted only in or among countries not thus excluded. In such case, this
+License incorporates the limitation as if written in the body of this License.
+
+9. The Free Software Foundation may publish revised and/or new versions of
+the General Public License from time to time. Such new versions will be similar
+in spirit to the present version, but may differ in detail to address new
+problems or concerns.
+
+Each version is given a distinguishing version number. If the Program specifies
+a version number of this License which applies to it and "any later version",
+you have the option of following the terms and conditions either of that version
+or of any later version published by the Free Software Foundation. If the
+Program does not specify a version number of this License, you may choose
+any version ever published by the Free Software Foundation.
+
+10. If you wish to incorporate parts of the Program into other free programs
+whose distribution conditions are different, write to the author to ask for
+permission. For software which is copyrighted by the Free Software Foundation,
+write to the Free Software Foundation; we sometimes make exceptions for this.
+Our decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing and reuse
+of software generally.
+
+NO WARRANTY
+
+11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR
+THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE
+STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM
+"AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE
+OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE
+OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA
+OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES
+OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH
+HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+
+How to Apply These Terms to Your New Programs
+
+If you develop a new program, and you want it to be of the greatest possible
+use to the public, the best way to achieve this is to make it free software
+which everyone can redistribute and change under these terms.
+
+To do so, attach the following notices to the program. It is safest to attach
+them to the start of each source file to most effectively convey the exclusion
+of warranty; and each file should have at least the "copyright" line and a
+pointer to where the full notice is found.
+
+one line to give the program's name and an idea of what it does. Copyright
+(C) yyyy name of author
+
+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 (at your option) 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, write to the Free Software Foundation, Inc., 51 Franklin
+Street, Fifth Floor, Boston, MA 02110-1301, USA. Also add information on how
+to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this when
+it starts in an interactive mode:
+
+Gnomovision version 69, Copyright (C) year name of author Gnomovision comes
+with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software,
+and you are welcome to redistribute it under certain conditions; type `show
+c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may be
+called something other than `show w' and `show c'; they could even be mouse-clicks
+or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your school,
+if any, to sign a "copyright disclaimer" for the program, if necessary. Here
+is a sample; alter the names:
+
+Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision'
+(which makes passes at compilers) written by James Hacker.
+
+signature of Ty Coon, 1 April 1989 Ty Coon, President of Vice
diff --git a/LICENSES/IBM-pibs.txt b/LICENSES/IBM-pibs.txt
new file mode 100644
index 0000000..9b9ccd4
--- /dev/null
+++ b/LICENSES/IBM-pibs.txt
@@ -0,0 +1,17 @@
+This source code has been made available to you by IBM on an AS-IS basis.
+Anyone receiving this source is licensed under IBM copyrights to use it in
+any way he or she deems fit, including copying it, modifying it, compiling
+it, and redistributing it either with or without modifications.  No license
+under IBM patents or patent applications is to be implied by the copyright
+license.
+
+Any user of this software should understand that IBM cannot provide technical
+support for this software and will not be responsible for any consequences
+resulting from the use of this software.
+
+Any person who transfers this source code or any derivative work must include
+the IBM copyright notice, this paragraph, and the preceding two paragraphs
+in the transferred software.
+
+COPYRIGHT   I B M   CORPORATION 2002
+LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
diff --git a/LICENSES/MIT.txt b/LICENSES/MIT.txt
new file mode 100644
index 0000000..f0fd20a
--- /dev/null
+++ b/LICENSES/MIT.txt
@@ -0,0 +1,20 @@
+MIT License
+
+Copyright (c) <year> <copyright holders>
+
+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.
diff --git a/README.md b/README.md
index e9d4a35..8d79f80 100644
--- a/README.md
+++ b/README.md
@@ -1,14 +1,9 @@
 <!--
-  Copyright 2017, Data61
-  Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-  ABN 41 687 119 230.
+     Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 
-  This software may be distributed and modified according to the terms of
-  the BSD 2-Clause license. Note that NO WARRANTY is provided.
-  See "LICENSE_BSD2.txt" for details.
-
-  @TAG(DATA61_BSD)
+     SPDX-License-Identifier: CC-BY-SA-4.0
 -->
+
 Collection of OS independent utility libs:
 
 * libcpio - a library for parsing CPIO files.
diff --git a/docs/libplatsupport/fdt.md b/docs/libplatsupport/fdt.md
deleted file mode 100644
index e7ec93e..0000000
--- a/docs/libplatsupport/fdt.md
+++ /dev/null
@@ -1,79 +0,0 @@
-<!--
-  Copyright 2019, Data61
-  Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-  ABN 41 687 119 230.
-
-  This software may be distributed and modified according to the terms of
-  the BSD 2-Clause license. Note that NO WARRANTY is provided.
-  See "LICENSE_BSD2.txt" for details.
-
-  @TAG(DATA61_BSD)
--->
-# FDT
-
-`libplatsupport` provides interfaces and utility functions to interact with the
-flattened device tree (FDT) of a platform.
-
-## `ps_io_fdt`
-
-**[Link to header](https://github.com/seL4/util_libs/blob/master/libplatsupport/include/platsupport/io.h#L387)**
-
-This interface provides an abstraction over a platform's FDT. For now, the
-interface only contains a function to retrieve the FDT of the platform. This
-may seem to be a unnecessary abstraction as we only provide one function, but
-this design allows us to easily extend the functionality if need be in the
-future.
-
-## DTB parsing utility functions
-
-**[Link to header](https://github.com/seL4/util_libs/blob/master/libplatsupport/include/platsupport/fdt.h)**
-
-These utility functions cover the common use cases of using the FDT, for
-example, reading the `regs` and `interrupts/interrupts-extended` properties to
-map registers and allocate hardware interrupts. The functions are designed in
-such a way that it parses the properties and calls a callback on each instance
-in the properties field. The callback would be given information about the
-current instance, the total number of instances and a user-supplied token. It
-could use the information to allocate hardware resources.
-
-To illustrate this process, consider a snippet of the DTS from the TX2.
-
-```
-ahci-sata@3507000 {
-    compatible = "nvidia,tegra186-ahci-sata";
-    reg = < 0x00 0x3507000 0x00 0x2000 0x00 0x3501000 0x00 0x6000 0x00 0x3500000 0x00 0x1000 0x00 0x3a90
-000 0x00 0x10000 >;
-    reg-names = "sata-ahci","sata-config","sata-ipfs","sata-aux";
-    interrupts = < 0x00 0xc5 0x04 >;
-    ...
-};
-```
-
-The parent node of this device describes that the number of address cells and
-size cells is 2. So when we call the register walking function, the function
-would encapsulate the first instance of the register property which is `< 0x00
-0x3507000 0x00 0x2000>` and then call the callback with it. Afterwards, it
-would then call the callback with the next instance `< 0x00 0x3501000 0x00
-0x6000>` and so on.
-
-### Interrupts parsing
-
-A thing to note is that interrupt parsing is a little special. Depending on the
-platform and device, the interrupts property of a device may have a special
-encoding format.
-
-For example, the ARM GIC specifies that each instance takes 3 cells, the first
-cell describes whether or not the interrupt is SPI or PPI, the second cell
-describes the interrupt number, and the third cell desribes the flags of the
-interrupt. Whereas on the GICv3, each instance could take 3 or 4 cells.
-
-The approach that we take when figuring out the interrupt property encoding is
-similar to Linux's approach. We follow the parent node's interrupt controller
-phandle to the interrupt controller node that is responsible for the target
-device. The compatible string of the interrupt controller is then checked to
-find out what type of interrupt controller it is. The parsing is then delegated
-to a parser module which understands the interrupt controller.
-
-You can read more about the interrupt encodings from Linux's interrupt bindings
-documentation
-[here](https://github.com/torvalds/linux/tree/master/Documentation/devicetree/bindings/interrupt-controller).
diff --git a/libcpio/CMakeLists.txt b/libcpio/CMakeLists.txt
index cbc9522..b9eb196 100644
--- a/libcpio/CMakeLists.txt
+++ b/libcpio/CMakeLists.txt
@@ -1,13 +1,7 @@
 #
-# Copyright 2017, Data61
-# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-# ABN 41 687 119 230.
+# Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 #
-# This software may be distributed and modified according to the terms of
-# the BSD 2-Clause license. Note that NO WARRANTY is provided.
-# See "LICENSE_BSD2.txt" for details.
-#
-# @TAG(DATA61_BSD)
+# SPDX-License-Identifier: BSD-2-Clause
 #
 
 cmake_minimum_required(VERSION 3.7.2)
diff --git a/libcpio/LICENSE_BSD2.txt b/libcpio/LICENSE_BSD2.txt
deleted file mode 100644
index 9823020..0000000
--- a/libcpio/LICENSE_BSD2.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Files described as being under the "BSD 2-Clause" license fall under the
-following license.
-
------------------------------------------------------------------------
-
-Copyright (c) 2014 National ICT Australia and other contributors.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-
-2. 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.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
diff --git a/libcpio/include/cpio/cpio.h b/libcpio/include/cpio/cpio.h
index 0bb0095..a0776b0 100644
--- a/libcpio/include/cpio/cpio.h
+++ b/libcpio/include/cpio/cpio.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
@@ -55,7 +49,7 @@
  * @return             The location of the file in memory; NULL if the index
  *                     exceeds the number of files in the CPIO archive.
  */
-void *cpio_get_entry(void *archive, unsigned long len, int index, const char **name, unsigned long *size);
+const void *cpio_get_entry(const void *archive, unsigned long len, int index, const char **name, unsigned long *size);
 
 /**
  * Retrieve file information from a provided file name
@@ -65,7 +59,7 @@
  * @return             The location of the file in memory; NULL if the file
  *                     does not exist.
  */
-void *cpio_get_file(void *archive, unsigned long len, const char *name, unsigned long *size);
+const void *cpio_get_file(const void *archive, unsigned long len, const char *name, unsigned long *size);
 
 /**
  * Retrieves information about the provided CPIO archive
@@ -73,7 +67,7 @@
  * @param[out] info    A CPIO info structure to populate
  * @return             Non-zero on error.
  */
-int cpio_info(void *archive, unsigned long len, struct cpio_info *info);
+int cpio_info(const void *archive, unsigned long len, struct cpio_info *info);
 
 /**
  * Writes the list of file names contained within a CPIO archive into
@@ -82,5 +76,5 @@
  * @param[in] buf      A memory location to store the CPIO file list to
  * @param[in] buf_len  The length of the provided buf
  */
-void cpio_ls(void *archive, unsigned long len, char **buf, unsigned long buf_len);
+void cpio_ls(const void *archive, unsigned long len, char **buf, unsigned long buf_len);
 
diff --git a/libcpio/src/cpio.c b/libcpio/src/cpio.c
index d144d0c..f305752 100644
--- a/libcpio/src/cpio.c
+++ b/libcpio/src/cpio.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <cpio/cpio.h>
@@ -17,10 +11,10 @@
 #endif
 
 struct cpio_header_info {
-    const char *filename;
+    char const *filename;
     unsigned long filesize;
-    void *data;
-    struct cpio_header *next;
+    const void *data;
+    const struct cpio_header *next;
 };
 
 /* Align 'n' up to the value 'align', which must be a power of two. */
@@ -30,7 +24,7 @@
 }
 
 /* Parse an ASCII hex string into an integer. */
-static unsigned long parse_hex_str(char *s, unsigned int max_len)
+static unsigned long parse_hex_str(const char *s, unsigned int max_len)
 {
     unsigned long r = 0;
     unsigned long i;
@@ -75,7 +69,8 @@
  * This is an implementation of string copy because, cpi doesn't want to
  * use string.h.
  */
-static char* cpio_strcpy(char *to, const char *from) {
+static char *cpio_strcpy(char *to, const char *from)
+{
     char *save = to;
     while (*from != 0) {
         *to = *from;
@@ -85,15 +80,17 @@
     return save;
 }
 
-static unsigned int cpio_strlen(const char *str) {
+static unsigned int cpio_strlen(const char *str)
+{
     const char *s;
     for (s = str; *s; ++s) {}
     return (s - str);
 }
 
 /* Calculate the remaining length in a CPIO file after reading a header. */
-static unsigned long cpio_len_next(unsigned long len, void *prev, void *next) {
-    unsigned long diff = (unsigned long) (next - prev);
+static unsigned long cpio_len_next(unsigned long len, const void *prev, const void *next)
+{
+    unsigned long diff = (unsigned long)(next - prev);
     if (len < diff) {
         return 0;
     }
@@ -105,14 +102,14 @@
  *
  * Return -1 if the header is not valid, 1 if it is EOF.
  */
-int cpio_parse_header(struct cpio_header *archive, unsigned long len,
-        struct cpio_header_info *info)
+int cpio_parse_header(const struct cpio_header *archive, unsigned long len,
+                      struct cpio_header_info *info)
 {
     const char *filename;
     unsigned long filesize;
     unsigned long filename_length;
-    void *data;
-    struct cpio_header *next;
+    const void *data;
+    const struct cpio_header *next;
 
     /* Ensure header is accessible */
     if (len < sizeof(struct cpio_header)) {
@@ -141,13 +138,13 @@
 
     /* Ensure filename is not the trailer indicating EOF. */
     if (filename_length >= sizeof(CPIO_FOOTER_MAGIC) && cpio_strncmp(filename,
-                CPIO_FOOTER_MAGIC, sizeof(CPIO_FOOTER_MAGIC)) == 0) {
+                                                                     CPIO_FOOTER_MAGIC, sizeof(CPIO_FOOTER_MAGIC)) == 0) {
         return 1;
     }
 
     /* Find offset to data. */
     data = (void *) align_up((unsigned long) archive + sizeof(struct cpio_header) +
-            filename_length, CPIO_ALIGNMENT);
+                             filename_length, CPIO_ALIGNMENT);
     next = (struct cpio_header *) align_up((unsigned long) data + filesize, CPIO_ALIGNMENT);
 
     if (info) {
@@ -168,9 +165,9 @@
  *
  * Runs in O(n) time.
  */
-void *cpio_get_entry(void *archive, unsigned long len, int n, const char **name, unsigned long *size)
+const void *cpio_get_entry(const void *archive, unsigned long len, int n, const char **name, unsigned long *size)
 {
-    struct cpio_header *header = archive;
+    const struct cpio_header *header = archive;
     struct cpio_header_info header_info;
 
     /* Find n'th entry. */
@@ -200,9 +197,9 @@
  *
  * Runs in O(n) time.
  */
-void *cpio_get_file(void *archive, unsigned long len, const char *name, unsigned long *size)
+const void *cpio_get_file(const void *archive, unsigned long len, const char *name, unsigned long *size)
 {
-    struct cpio_header *header = archive;
+    const struct cpio_header *header = archive;
     struct cpio_header_info header_info;
 
     /* Find n'th entry. */
@@ -224,12 +221,15 @@
     return header_info.data;
 }
 
-int cpio_info(void *archive, unsigned long len, struct cpio_info *info) {
-    struct cpio_header *header;
+int cpio_info(const void *archive, unsigned long len, struct cpio_info *info)
+{
+    const struct cpio_header *header;
     unsigned long current_path_sz;
     struct cpio_header_info header_info;
 
-    if (info == NULL) return 1;
+    if (info == NULL) {
+        return 1;
+    }
     info->file_count = 0;
     info->max_path_sz = 0;
 
@@ -256,15 +256,18 @@
     return 0;
 }
 
-void cpio_ls(void *archive, unsigned long len, char **buf, unsigned long buf_len) {
-    struct cpio_header *header;
+void cpio_ls(const void *archive, unsigned long len, char **buf, unsigned long buf_len)
+{
+    const struct cpio_header *header;
     struct cpio_header_info header_info;
 
     header = archive;
     for (unsigned long i = 0; i < buf_len; i++) {
         int error = cpio_parse_header(header, len, &header_info);
         // Break on an error or nothing left to read.
-        if (error) break;
+        if (error) {
+            break;
+        }
         cpio_strcpy(buf[i], header_info.filename);
         len = cpio_len_next(len, header, header_info.next);
         header = header_info.next;
diff --git a/libelf/CMakeLists.txt b/libelf/CMakeLists.txt
index 624c555..eda7498 100644
--- a/libelf/CMakeLists.txt
+++ b/libelf/CMakeLists.txt
@@ -1,13 +1,7 @@
 #
-# Copyright 2017, Data61
-# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-# ABN 41 687 119 230.
+# Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 #
-# This software may be distributed and modified according to the terms of
-# the BSD 2-Clause license. Note that NO WARRANTY is provided.
-# See "LICENSE_BSD2.txt" for details.
-#
-# @TAG(DATA61_BSD)
+# SPDX-License-Identifier: BSD-2-Clause
 #
 
 cmake_minimum_required(VERSION 3.7.2)
diff --git a/libelf/LICENSE_BSD2.txt b/libelf/LICENSE_BSD2.txt
deleted file mode 100644
index 9823020..0000000
--- a/libelf/LICENSE_BSD2.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Files described as being under the "BSD 2-Clause" license fall under the
-following license.
-
------------------------------------------------------------------------
-
-Copyright (c) 2014 National ICT Australia and other contributors.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-
-2. 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.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
diff --git a/libelf/LICENSE_OZPLB.txt b/libelf/LICENSE_OZPLB.txt
deleted file mode 100644
index 5901a5a..0000000
--- a/libelf/LICENSE_OZPLB.txt
+++ /dev/null
@@ -1,76 +0,0 @@
-Australian Public Licence B (OZPLB)
-
-Version 1-0
-
-Copyright (c) 2004 University of New South Wales
-
-All rights reserved.
-
-Developed by: Operating Systems and Distributed Systems Group (DiSy)
-              University of New South Wales
-              http://www.disy.cse.unsw.edu.au
-
-Permission is granted by University of New South Wales, free of charge, to
-any person obtaining a copy of this software and any associated
-documentation files (the "Software") to deal with the Software without
-restriction, including (without limitation) the rights to use, copy,
-modify, adapt, merge, publish, distribute, communicate to the public,
-sublicense, and/or sell, lend or rent out copies of the Software, and
-to permit persons to whom the Software is furnished to do so, subject
-to the following conditions:
-
-    * Redistributions of source code must retain the above copyright
-      notice, this list of conditions and the following disclaimers.
-
-    * Redistributions in binary form must reproduce the above
-      copyright notice, this list of conditions and the following
-      disclaimers in the documentation and/or other materials provided
-      with the distribution.
-
-    * Neither the name of University of New South Wales, nor the names of its
-      contributors, may be used to endorse or promote products derived
-      from this Software without specific prior written permission.
-
-EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
-PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
-NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
-WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
-BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
-REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
-MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
-THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
-ERRORS, WHETHER OR NOT DISCOVERABLE.
-
-TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
-NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
-THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
-NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
-LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
-OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
-OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
-OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
-CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
-CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
-DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
-CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
-DAMAGES OR OTHER LIABILITY.
-
-If applicable legislation implies representations, warranties, or
-conditions, or imposes obligations or liability on University of New South
-Wales or one of its contributors in respect of the Software that
-cannot be wholly or partly excluded, restricted or modified, the
-liability of University of New South Wales or the contributor is limited, to
-the full extent permitted by the applicable legislation, at its
-option, to:
-a.  in the case of goods, any one or more of the following:
-i.  the replacement of the goods or the supply of equivalent goods;
-ii.  the repair of the goods;
-iii. the payment of the cost of replacing the goods or of acquiring
- equivalent goods;
-iv.  the payment of the cost of having the goods repaired; or
-b.  in the case of services:
-i.  the supplying of the services again; or
-ii.  the payment of the cost of having the services supplied again.
-
-The construction, validity and performance of this licence is governed
-by the laws in force in New South Wales, Australia.
diff --git a/libelf/include/elf/elf.h b/libelf/include/elf/elf.h
index 66ebffa..a19fc7e 100644
--- a/libelf/include/elf/elf.h
+++ b/libelf/include/elf/elf.h
@@ -1,82 +1,7 @@
-/* @LICENSE(UNSW_OZPLB) */
-
 /*
- * Australian Public Licence B (OZPLB)
- *
- * Version 1-0
- *
  * Copyright (c) 1999-2004 University of New South Wales
  *
- * All rights reserved.
- *
- * Developed by: Operating Systems and Distributed Systems Group (DiSy)
- *               University of New South Wales
- *               http://www.disy.cse.unsw.edu.au
- *
- * Permission is granted by University of New South Wales, free of charge, to
- * any person obtaining a copy of this software and any associated
- * documentation files (the "Software") to deal with the Software without
- * restriction, including (without limitation) the rights to use, copy,
- * modify, adapt, merge, publish, distribute, communicate to the public,
- * sublicense, and/or sell, lend or rent out copies of the Software, and
- * to permit persons to whom the Software is furnished to do so, subject
- * to the following conditions:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimers.
- *
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimers in the documentation and/or other materials provided
- *       with the distribution.
- *
- *     * Neither the name of University of New South Wales, nor the names of its
- *       contributors, may be used to endorse or promote products derived
- *       from this Software without specific prior written permission.
- *
- * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
- * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
- * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
- * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
- * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
- * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
- * ERRORS, WHETHER OR NOT DISCOVERABLE.
- *
- * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
- * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
- * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
- * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
- * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
- * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
- * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
- * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
- * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
- * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
- * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
- * DAMAGES OR OTHER LIABILITY.
- *
- * If applicable legislation implies representations, warranties, or
- * conditions, or imposes obligations or liability on University of New South
- * Wales or one of its contributors in respect of the Software that
- * cannot be wholly or partly excluded, restricted or modified, the
- * liability of University of New South Wales or the contributor is limited, to
- * the full extent permitted by the applicable legislation, at its
- * option, to:
- * a.  in the case of goods, any one or more of the following:
- * i.  the replacement of the goods or the supply of equivalent goods;
- * ii.  the repair of the goods;
- * iii. the payment of the cost of replacing the goods or of acquiring
- *  equivalent goods;
- * iv.  the payment of the cost of having the goods repaired; or
- * b.  in the case of services:
- * i.  the supplying of the services again; or
- * ii.  the payment of the cost of having the services supplied again.
- *
- * The construction, validity and performance of this licence is governed
- * by the laws in force in New South Wales, Australia.
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /*
@@ -108,7 +33,7 @@
 #include <elf.h>
 
 struct elf {
-    void *elfFile;
+    void const *elfFile;
     size_t elfSize;
     unsigned char elfClass; /* 32-bit or 64-bit */
 };
@@ -133,7 +58,7 @@
  *
  * \return 0 on success, otherwise < 0
  */
-int elf_newFile(void *file, size_t size, elf_t *res);
+int elf_newFile(const void *file, size_t size, elf_t *res);
 
 /**
  * Initialises and elf_t structure and checks that the ELF file is valid.
@@ -152,7 +77,7 @@
  *
  * \return 0 on success, otherwise < 0
  */
-int elf_newFile_maybe_unsafe(void *file, size_t size, bool check_pht, bool check_st, elf_t *res);
+int elf_newFile_maybe_unsafe(const void *file, size_t size, bool check_pht, bool check_st, elf_t *res);
 
 /**
  * Checks that file starts with the ELF magic number.
@@ -162,7 +87,7 @@
  *
  * \return 0 on success, otherwise < 0
  */
-int elf_check_magic(char *file);
+int elf_check_magic(const char *file);
 
 /**
  * Checks that elfFile points to an ELF file with a valid ELF header.
@@ -180,7 +105,7 @@
  *
  * \return 0 on success, otherwise < 0
  */
-int elf_checkProgramHeaderTable(elf_t *elfFile);
+int elf_checkProgramHeaderTable(const elf_t *elfFile);
 
 /**
  * Checks that elfFile points to an ELF file with a valid section table.
@@ -189,7 +114,7 @@
  *
  * \return 0 on success, otherwise < 0
  */
-int elf_checkSectionTable(elf_t *elfFile);
+int elf_checkSectionTable(const elf_t *elfFile);
 
 /**
  * Find the entry point of an ELF file.
@@ -198,7 +123,7 @@
  *
  * \return The entry point address.
  */
-uintptr_t elf_getEntryPoint(elf_t *elfFile);
+uintptr_t elf_getEntryPoint(const elf_t *elfFile);
 
 /**
  * Determine number of program headers in an ELF file.
@@ -207,7 +132,7 @@
  *
  * \return Number of program headers in the ELF file.
  */
-size_t elf_getNumProgramHeaders(elf_t *elfFile);
+size_t elf_getNumProgramHeaders(const elf_t *elfFile);
 
 /**
  * Determine number of sections in an ELF file.
@@ -216,7 +141,7 @@
  *
  * \return Number of sections in the ELF file.
  */
-size_t elf_getNumSections(elf_t *elfFile);
+size_t elf_getNumSections(const elf_t *elfFile);
 
 /**
  * Get the index of the section header string table of an ELF file.
@@ -225,7 +150,7 @@
  *
  * \return The index of the section header string table.
  */
-size_t elf_getSectionStringTableIndex(elf_t *elf);
+size_t elf_getSectionStringTableIndex(const elf_t *elf);
 
 /**
  * Get a string table section of an ELF file.
@@ -235,7 +160,7 @@
  *
  * \return The string table, or NULL if the section is not a string table.
  */
-const char *elf_getStringTable(elf_t *elfFile, size_t string_segment);
+const char *elf_getStringTable(const elf_t *elfFile, size_t string_segment);
 
 /**
  * Get the string table for section header names.
@@ -244,7 +169,7 @@
  *
  * \return The string table, or NULL if there is no table.
  */
-const char *elf_getSectionStringTable(elf_t *elfFile);
+const char *elf_getSectionStringTable(const elf_t *elfFile);
 
 
 /* Section header functions */
@@ -256,7 +181,7 @@
  *
  * \return The section, or NULL if there is no section.
  */
-void *elf_getSection(elf_t *elfFile, size_t i);
+const void *elf_getSection(const elf_t *elfFile, size_t i);
 
 /**
  * Get the section of an ELF file with a given name.
@@ -267,7 +192,7 @@
  *
  * \return The section, or NULL if there is no section.
  */
-void *elf_getSectionNamed(elf_t *elfFile, const char *str, size_t *i);
+const void *elf_getSectionNamed(const elf_t *elfFile, const char *str, size_t *i);
 
 /**
  * Return the name of a given section.
@@ -277,7 +202,7 @@
  *
  * \return The name of a given section.
  */
-const char *elf_getSectionName(elf_t *elfFile, size_t i);
+const char *elf_getSectionName(const elf_t *elfFile, size_t i);
 
 /**
  * Return the offset to the name of a given section in the section header
@@ -289,7 +214,7 @@
  * \return The offset to the name of a given section in the section header
  * string table.
  */
-size_t elf_getSectionNameOffset(elf_t *elfFile, size_t i);
+size_t elf_getSectionNameOffset(const elf_t *elfFile, size_t i);
 
 /**
  * Return the type of a given section
@@ -299,7 +224,7 @@
  *
  * \return The type of a given section.
  */
-uint32_t elf_getSectionType(elf_t *elfFile, size_t i);
+uint32_t elf_getSectionType(const elf_t *elfFile, size_t i);
 
 /**
  * Return the flags of a given section
@@ -309,7 +234,7 @@
  *
  * \return The flags of a given section.
  */
-size_t elf_getSectionFlags(elf_t *elfFile, size_t i);
+size_t elf_getSectionFlags(const elf_t *elfFile, size_t i);
 
 /**
  * Return the address of a given section
@@ -319,7 +244,7 @@
  *
  * \return The address of a given section.
  */
-uintptr_t elf_getSectionAddr(elf_t *elfFile, size_t i);
+uintptr_t elf_getSectionAddr(const elf_t *elfFile, size_t i);
 
 /**
  * Return the offset of a given section
@@ -329,7 +254,7 @@
  *
  * \return The offset of a given section.
  */
-size_t elf_getSectionOffset(elf_t *elfFile, size_t i);
+size_t elf_getSectionOffset(const elf_t *elfFile, size_t i);
 
 /**
  * Return the size of a given section
@@ -339,7 +264,7 @@
  *
  * \return The size of a given section.
  */
-size_t elf_getSectionSize(elf_t *elfFile, size_t i);
+size_t elf_getSectionSize(const elf_t *elfFile, size_t i);
 
 /**
  * Return the related section index of a given section
@@ -349,7 +274,7 @@
  *
  * \return The related section index of a given section.
  */
-uint32_t elf_getSectionLink(elf_t *elfFile, size_t i);
+uint32_t elf_getSectionLink(const elf_t *elfFile, size_t i);
 
 /**
  * Return extra information of a given section
@@ -359,7 +284,7 @@
  *
  * \return Extra information of a given section.
  */
-uint32_t elf_getSectionInfo(elf_t *elfFile, size_t i);
+uint32_t elf_getSectionInfo(const elf_t *elfFile, size_t i);
 
 /**
  * Return the alignment of a given section
@@ -369,7 +294,7 @@
  *
  * \return The alignment of a given section.
  */
-size_t elf_getSectionAddrAlign(elf_t *elfFile, size_t i);
+size_t elf_getSectionAddrAlign(const elf_t *elfFile, size_t i);
 
 /**
  * Return the entry size of a given section
@@ -379,7 +304,7 @@
  *
  * \return The entry size of a given section.
  */
-size_t elf_getSectionEntrySize(elf_t *elfFile, size_t i);
+size_t elf_getSectionEntrySize(const elf_t *elfFile, size_t i);
 
 
 /* Program header functions */
@@ -392,7 +317,7 @@
  *
  * \return Pointer to the segment data
  */
-void *elf_getProgramSegment(elf_t *elf, size_t ph);
+const void *elf_getProgramSegment(const elf_t *elf, size_t ph);
 
 /**
  * Return the type for a given program header.
@@ -402,7 +327,7 @@
  *
  * \return The type of a given program header.
  */
-uint32_t elf_getProgramHeaderType(elf_t *elfFile, size_t ph);
+uint32_t elf_getProgramHeaderType(const elf_t *elfFile, size_t ph);
 
 /**
  * Return the segment offset for a given program header.
@@ -412,7 +337,7 @@
  *
  * \return The offset of this program header from the start of the file.
  */
-size_t elf_getProgramHeaderOffset(elf_t *elfFile, size_t ph);
+size_t elf_getProgramHeaderOffset(const elf_t *elfFile, size_t ph);
 
 /**
  * Return the base virtual address of given program header.
@@ -422,7 +347,7 @@
  *
  * \return The memory size of the specified program header.
  */
-uintptr_t elf_getProgramHeaderVaddr(elf_t *elfFile, size_t ph);
+uintptr_t elf_getProgramHeaderVaddr(const elf_t *elfFile, size_t ph);
 
 /**
  * Return the base physical address of given program header.
@@ -432,7 +357,7 @@
  *
  * \return The memory size of the specified program header.
  */
-uintptr_t elf_getProgramHeaderPaddr(elf_t *elfFile, size_t ph);
+uintptr_t elf_getProgramHeaderPaddr(const elf_t *elfFile, size_t ph);
 
 /**
  * Return the file size of a given program header.
@@ -442,7 +367,7 @@
  *
  * \return The file size of the specified program header.
  */
-size_t elf_getProgramHeaderFileSize(elf_t *elfFile, size_t ph);
+size_t elf_getProgramHeaderFileSize(const elf_t *elfFile, size_t ph);
 
 /**
  * Return the memory size of a given program header.
@@ -452,7 +377,7 @@
  *
  * \return The memory size of the specified program header.
  */
-size_t elf_getProgramHeaderMemorySize(elf_t *elfFile, size_t ph);
+size_t elf_getProgramHeaderMemorySize(const elf_t *elfFile, size_t ph);
 
 /**
  * Return the flags for a given program header.
@@ -462,7 +387,7 @@
  *
  * \return The flags of a given program header.
  */
-uint32_t elf_getProgramHeaderFlags(elf_t *elfFile, size_t ph);
+uint32_t elf_getProgramHeaderFlags(const elf_t *elfFile, size_t ph);
 
 /**
  * Return the alignment for a given program header.
@@ -472,7 +397,7 @@
  *
  * \return The alignment of the given program header.
  */
-size_t elf_getProgramHeaderAlign(elf_t *elfFile, size_t ph);
+size_t elf_getProgramHeaderAlign(const elf_t *elfFile, size_t ph);
 
 
 /* Utility functions */
@@ -488,20 +413,20 @@
  *
  * \return true on success. false on failure, if for example, it is an invalid ELF file
  */
-int elf_getMemoryBounds(elf_t *elfFile, elf_addr_type_t addr_type, uintptr_t *min, uintptr_t *max);
+int elf_getMemoryBounds(const elf_t *elfFile, elf_addr_type_t addr_type, uintptr_t *min, uintptr_t *max);
 
 /**
  *
  * \return true if the address in in this program header
  */
-int elf_vaddrInProgramHeader(elf_t *elfFile, size_t ph, uintptr_t vaddr);
+int elf_vaddrInProgramHeader(const elf_t *elfFile, size_t ph, uintptr_t vaddr);
 
 /**
  * Return the physical translation of a physical address, with respect
  * to a given program header
  *
  */
-uintptr_t elf_vtopProgramHeader(elf_t *elfFile, size_t ph, uintptr_t vaddr);
+uintptr_t elf_vtopProgramHeader(const elf_t *elfFile, size_t ph, uintptr_t vaddr);
 
 /**
  * Load an ELF file into memory
@@ -521,4 +446,4 @@
  * platform, we assume that any memory addresses are within the first 4GB.
  *
  */
-int elf_loadFile(elf_t *elfFile, elf_addr_type_t addr_type);
+int elf_loadFile(const elf_t *elfFile, elf_addr_type_t addr_type);
diff --git a/libelf/include/elf/elf32.h b/libelf/include/elf/elf32.h
index 9bc6664..28eae29 100644
--- a/libelf/include/elf/elf32.h
+++ b/libelf/include/elf/elf32.h
@@ -1,83 +1,9 @@
-/* @LICENSE(UNSW_OZPLB) */
-
 /*
- * Australian Public Licence B (OZPLB)
+ * Copyright (c) 1999-2004 University of New South Wales
  *
- * Version 1-0
- *
- * Copyright (c) 2004 University of New South Wales
- *
- * All rights reserved.
- *
- * Developed by: Operating Systems and Distributed Systems Group (DiSy)
- *               University of New South Wales
- *               http://www.disy.cse.unsw.edu.au
- *
- * Permission is granted by University of New South Wales, free of charge, to
- * any person obtaining a copy of this software and any associated
- * documentation files (the "Software") to deal with the Software without
- * restriction, including (without limitation) the rights to use, copy,
- * modify, adapt, merge, publish, distribute, communicate to the public,
- * sublicense, and/or sell, lend or rent out copies of the Software, and
- * to permit persons to whom the Software is furnished to do so, subject
- * to the following conditions:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimers.
- *
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimers in the documentation and/or other materials provided
- *       with the distribution.
- *
- *     * Neither the name of University of New South Wales, nor the names of its
- *       contributors, may be used to endorse or promote products derived
- *       from this Software without specific prior written permission.
- *
- * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
- * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
- * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
- * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
- * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
- * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
- * ERRORS, WHETHER OR NOT DISCOVERABLE.
- *
- * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
- * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
- * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
- * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
- * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
- * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
- * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
- * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
- * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
- * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
- * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
- * DAMAGES OR OTHER LIABILITY.
- *
- * If applicable legislation implies representations, warranties, or
- * conditions, or imposes obligations or liability on University of New South
- * Wales or one of its contributors in respect of the Software that
- * cannot be wholly or partly excluded, restricted or modified, the
- * liability of University of New South Wales or the contributor is limited, to
- * the full extent permitted by the applicable legislation, at its
- * option, to:
- * a.  in the case of goods, any one or more of the following:
- * i.  the replacement of the goods or the supply of equivalent goods;
- * ii.  the repair of the goods;
- * iii. the payment of the cost of replacing the goods or of acquiring
- *  equivalent goods;
- * iv.  the payment of the cost of having the goods repaired; or
- * b.  in the case of services:
- * i.  the supplying of the services again; or
- * ii.  the payment of the cost of having the services supplied again.
- *
- * The construction, validity and performance of this licence is governed
- * by the laws in force in New South Wales, Australia.
+ * SPDX-License-Identifier: BSD-2-Clause
  */
+
 #pragma once
 
 #include <stdint.h>
@@ -86,140 +12,140 @@
 /* ELF header functions */
 int elf32_checkFile(elf_t *elf);
 
-int elf32_checkProgramHeaderTable(elf_t *elf);
+int elf32_checkProgramHeaderTable(const elf_t *elf);
 
-int elf32_checkSectionTable(elf_t *elf);
+int elf32_checkSectionTable(const elf_t *elf);
 
-static inline bool elf_isElf32(elf_t *elf)
+static inline bool elf_isElf32(const elf_t *elf)
 {
     return elf->elfClass == ELFCLASS32;
 }
 
-static inline Elf32_Ehdr elf32_getHeader(elf_t *elf)
+static inline Elf32_Ehdr elf32_getHeader(const elf_t *elf)
 {
     return *(Elf32_Ehdr *) elf->elfFile;
 }
 
-static inline uintptr_t elf32_getEntryPoint(elf_t *elf)
+static inline uintptr_t elf32_getEntryPoint(const elf_t *elf)
 {
     return elf32_getHeader(elf).e_entry;
 }
 
-static inline Elf32_Phdr *elf32_getProgramHeaderTable(elf_t *file)
+static inline const Elf32_Phdr *elf32_getProgramHeaderTable(const elf_t *file)
 {
     return file->elfFile + elf32_getHeader(file).e_phoff;
 }
 
-static inline Elf32_Shdr *elf32_getSectionTable(elf_t *elf)
+static inline const Elf32_Shdr *elf32_getSectionTable(const elf_t *elf)
 {
     return elf->elfFile + elf32_getHeader(elf).e_shoff;
 }
 
-static inline size_t elf32_getNumProgramHeaders(elf_t *elf)
+static inline size_t elf32_getNumProgramHeaders(const elf_t *elf)
 {
     return elf32_getHeader(elf).e_phnum;
 }
 
-static inline size_t elf32_getNumSections(elf_t *elf)
+static inline size_t elf32_getNumSections(const elf_t *elf)
 {
     return elf32_getHeader(elf).e_shnum;
 }
 
-static inline size_t elf32_getSectionStringTableIndex(elf_t *elf)
+static inline size_t elf32_getSectionStringTableIndex(const elf_t *elf)
 {
     return elf32_getHeader(elf).e_shstrndx;
 }
 
 
 /* Section header functions */
-static inline size_t elf32_getSectionNameOffset(elf_t *elf, size_t s)
+static inline size_t elf32_getSectionNameOffset(const elf_t *elf, size_t s)
 {
     return elf32_getSectionTable(elf)[s].sh_name;
 }
 
-static inline uint32_t elf32_getSectionType(elf_t *elf, size_t i)
+static inline uint32_t elf32_getSectionType(const elf_t *elf, size_t i)
 {
     return elf32_getSectionTable(elf)[i].sh_type;
 }
 
-static inline size_t elf32_getSectionFlags(elf_t *elf, size_t i)
+static inline size_t elf32_getSectionFlags(const elf_t *elf, size_t i)
 {
     return elf32_getSectionTable(elf)[i].sh_flags;
 }
 
-static inline uintptr_t elf32_getSectionAddr(elf_t *elf, size_t i)
+static inline uintptr_t elf32_getSectionAddr(const elf_t *elf, size_t i)
 {
     return elf32_getSectionTable(elf)[i].sh_addr;
 }
 
-static inline size_t elf32_getSectionOffset(elf_t *elf, size_t i)
+static inline size_t elf32_getSectionOffset(const elf_t *elf, size_t i)
 {
     return elf32_getSectionTable(elf)[i].sh_offset;
 }
 
-static inline size_t elf32_getSectionSize(elf_t *elf, size_t i)
+static inline size_t elf32_getSectionSize(const elf_t *elf, size_t i)
 {
     return elf32_getSectionTable(elf)[i].sh_size;
 }
 
-static inline uint32_t elf32_getSectionLink(elf_t *elf, size_t i)
+static inline uint32_t elf32_getSectionLink(const elf_t *elf, size_t i)
 {
     return elf32_getSectionTable(elf)[i].sh_link;
 }
 
-static inline uint32_t elf32_getSectionInfo(elf_t *elf, size_t i)
+static inline uint32_t elf32_getSectionInfo(const elf_t *elf, size_t i)
 {
     return elf32_getSectionTable(elf)[i].sh_info;
 }
 
-static inline size_t elf32_getSectionAddrAlign(elf_t *elf, size_t i)
+static inline size_t elf32_getSectionAddrAlign(const elf_t *elf, size_t i)
 {
     return elf32_getSectionTable(elf)[i].sh_addralign;
 }
 
-static inline size_t elf32_getSectionEntrySize(elf_t *elf, size_t i)
+static inline size_t elf32_getSectionEntrySize(const elf_t *elf, size_t i)
 {
     return elf32_getSectionTable(elf)[i].sh_entsize;
 }
 
 
 /* Program header functions */
-static inline uint32_t elf32_getProgramHeaderType(elf_t *file, size_t ph)
+static inline uint32_t elf32_getProgramHeaderType(const elf_t *file, size_t ph)
 {
     return elf32_getProgramHeaderTable(file)[ph].p_type;
 }
 
-static inline size_t elf32_getProgramHeaderOffset(elf_t *file, size_t ph)
+static inline size_t elf32_getProgramHeaderOffset(const elf_t *file, size_t ph)
 {
     return elf32_getProgramHeaderTable(file)[ph].p_offset;
 }
 
-static inline uintptr_t elf32_getProgramHeaderVaddr(elf_t *file, size_t ph)
+static inline uintptr_t elf32_getProgramHeaderVaddr(const elf_t *file, size_t ph)
 {
     return elf32_getProgramHeaderTable(file)[ph].p_vaddr;
 }
 
-static inline uintptr_t elf32_getProgramHeaderPaddr(elf_t *file, size_t ph)
+static inline uintptr_t elf32_getProgramHeaderPaddr(const elf_t *file, size_t ph)
 {
     return elf32_getProgramHeaderTable(file)[ph].p_paddr;
 }
 
-static inline size_t elf32_getProgramHeaderFileSize(elf_t *file, size_t ph)
+static inline size_t elf32_getProgramHeaderFileSize(const elf_t *file, size_t ph)
 {
     return elf32_getProgramHeaderTable(file)[ph].p_filesz;
 }
 
-static inline size_t elf32_getProgramHeaderMemorySize(elf_t *file, size_t ph)
+static inline size_t elf32_getProgramHeaderMemorySize(const elf_t *file, size_t ph)
 {
     return elf32_getProgramHeaderTable(file)[ph].p_memsz;
 }
 
-static inline uint32_t elf32_getProgramHeaderFlags(elf_t *file, size_t ph)
+static inline uint32_t elf32_getProgramHeaderFlags(const elf_t *file, size_t ph)
 {
     return elf32_getProgramHeaderTable(file)[ph].p_flags;
 }
 
-static inline size_t elf32_getProgramHeaderAlign(elf_t *file, size_t ph)
+static inline size_t elf32_getProgramHeaderAlign(const elf_t *file, size_t ph)
 {
     return elf32_getProgramHeaderTable(file)[ph].p_align;
 }
diff --git a/libelf/include/elf/elf64.h b/libelf/include/elf/elf64.h
index 79c11dd..f81268e 100644
--- a/libelf/include/elf/elf64.h
+++ b/libelf/include/elf/elf64.h
@@ -1,83 +1,9 @@
-/* @LICENSE(UNSW_OZPLB) */
-
 /*
- * Australian Public Licence B (OZPLB)
+ * Copyright (c) 1999-2004 University of New South Wales
  *
- * Version 1-0
- *
- * Copyright (c) 2004 University of New South Wales
- *
- * All rights reserved.
- *
- * Developed by: Operating Systems and Distributed Systems Group (DiSy)
- *               University of New South Wales
- *               http://www.disy.cse.unsw.edu.au
- *
- * Permission is granted by University of New South Wales, free of charge, to
- * any person obtaining a copy of this software and any associated
- * documentation files (the "Software") to deal with the Software without
- * restriction, including (without limitation) the rights to use, copy,
- * modify, adapt, merge, publish, distribute, communicate to the public,
- * sublicense, and/or sell, lend or rent out copies of the Software, and
- * to permit persons to whom the Software is furnished to do so, subject
- * to the following conditions:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimers.
- *
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimers in the documentation and/or other materials provided
- *       with the distribution.
- *
- *     * Neither the name of University of New South Wales, nor the names of its
- *       contributors, may be used to endorse or promote products derived
- *       from this Software without specific prior written permission.
- *
- * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
- * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
- * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
- * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
- * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
- * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
- * ERRORS, WHETHER OR NOT DISCOVERABLE.
- *
- * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
- * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
- * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
- * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
- * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
- * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
- * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
- * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
- * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
- * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
- * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
- * DAMAGES OR OTHER LIABILITY.
- *
- * If applicable legislation implies representations, warranties, or
- * conditions, or imposes obligations or liability on University of New South
- * Wales or one of its contributors in respect of the Software that
- * cannot be wholly or partly excluded, restricted or modified, the
- * liability of University of New South Wales or the contributor is limited, to
- * the full extent permitted by the applicable legislation, at its
- * option, to:
- * a.  in the case of goods, any one or more of the following:
- * i.  the replacement of the goods or the supply of equivalent goods;
- * ii.  the repair of the goods;
- * iii. the payment of the cost of replacing the goods or of acquiring
- *  equivalent goods;
- * iv.  the payment of the cost of having the goods repaired; or
- * b.  in the case of services:
- * i.  the supplying of the services again; or
- * ii.  the payment of the cost of having the services supplied again.
- *
- * The construction, validity and performance of this licence is governed
- * by the laws in force in New South Wales, Australia.
+ * SPDX-License-Identifier: BSD-2-Clause
  */
+
 #pragma once
 
 #include <stdint.h>
@@ -86,140 +12,140 @@
 /* ELF header functions */
 int elf64_checkFile(elf_t *elf);
 
-int elf64_checkProgramHeaderTable(elf_t *elf);
+int elf64_checkProgramHeaderTable(const elf_t *elf);
 
-int elf64_checkSectionTable(elf_t *elf);
+int elf64_checkSectionTable(const elf_t *elf);
 
-static inline bool elf_isElf64(elf_t *elf)
+static inline bool elf_isElf64(const elf_t *elf)
 {
     return elf->elfClass == ELFCLASS64;
 }
 
-static inline Elf64_Ehdr elf64_getHeader(elf_t *elf)
+static inline Elf64_Ehdr elf64_getHeader(const elf_t *elf)
 {
     return *(Elf64_Ehdr *) elf->elfFile;
 }
 
-static inline uintptr_t elf64_getEntryPoint(elf_t *file)
+static inline uintptr_t elf64_getEntryPoint(const elf_t *file)
 {
     return elf64_getHeader(file).e_entry;
 }
 
-static inline Elf64_Phdr *elf64_getProgramHeaderTable(elf_t *file)
+static inline const Elf64_Phdr *elf64_getProgramHeaderTable(const elf_t *file)
 {
     return file->elfFile + elf64_getHeader(file).e_phoff;
 }
 
-static inline Elf64_Shdr *elf64_getSectionTable(elf_t *file)
+static inline const Elf64_Shdr *elf64_getSectionTable(const elf_t *file)
 {
     return file->elfFile + elf64_getHeader(file).e_shoff;
 }
 
-static inline size_t elf64_getNumProgramHeaders(elf_t *file)
+static inline size_t elf64_getNumProgramHeaders(const elf_t *file)
 {
     return elf64_getHeader(file).e_phnum;
 }
 
-static inline size_t elf64_getNumSections(elf_t *elf)
+static inline size_t elf64_getNumSections(const elf_t *elf)
 {
     return elf64_getHeader(elf).e_shnum;
 }
 
-static inline size_t elf64_getSectionStringTableIndex(elf_t *elf)
+static inline size_t elf64_getSectionStringTableIndex(const elf_t *elf)
 {
     return elf64_getHeader(elf).e_shstrndx;
 }
 
 
 /* Section header functions */
-static inline size_t elf64_getSectionNameOffset(elf_t *elf, size_t s)
+static inline size_t elf64_getSectionNameOffset(const elf_t *elf, size_t s)
 {
     return elf64_getSectionTable(elf)[s].sh_name;
 }
 
-static inline uint32_t elf64_getSectionType(elf_t *file, size_t s)
+static inline uint32_t elf64_getSectionType(const elf_t *file, size_t s)
 {
     return elf64_getSectionTable(file)[s].sh_type;
 }
 
-static inline size_t elf64_getSectionFlags(elf_t *file, size_t s)
+static inline size_t elf64_getSectionFlags(const elf_t *file, size_t s)
 {
     return elf64_getSectionTable(file)[s].sh_flags;
 }
 
-static inline uintptr_t elf64_getSectionAddr(elf_t *elf, size_t i)
+static inline uintptr_t elf64_getSectionAddr(const elf_t *elf, size_t i)
 {
     return elf64_getSectionTable(elf)[i].sh_addr;
 }
 
-static inline size_t elf64_getSectionOffset(elf_t *elf, size_t i)
+static inline size_t elf64_getSectionOffset(const elf_t *elf, size_t i)
 {
     return elf64_getSectionTable(elf)[i].sh_offset;
 }
 
-static inline size_t elf64_getSectionSize(elf_t *elf, size_t i)
+static inline size_t elf64_getSectionSize(const elf_t *elf, size_t i)
 {
     return elf64_getSectionTable(elf)[i].sh_size;
 }
 
-static inline uint32_t elf64_getSectionLink(elf_t *elf, size_t i)
+static inline uint32_t elf64_getSectionLink(const elf_t *elf, size_t i)
 {
     return elf64_getSectionTable(elf)[i].sh_link;
 }
 
-static inline uint32_t elf64_getSectionInfo(elf_t *elf, size_t i)
+static inline uint32_t elf64_getSectionInfo(const elf_t *elf, size_t i)
 {
     return elf64_getSectionTable(elf)[i].sh_info;
 }
 
-static inline size_t elf64_getSectionAddrAlign(elf_t *elf, size_t i)
+static inline size_t elf64_getSectionAddrAlign(const elf_t *elf, size_t i)
 {
     return elf64_getSectionTable(elf)[i].sh_addralign;
 }
 
-static inline size_t elf64_getSectionEntrySize(elf_t *elf, size_t i)
+static inline size_t elf64_getSectionEntrySize(const elf_t *elf, size_t i)
 {
     return elf64_getSectionTable(elf)[i].sh_entsize;
 }
 
 
 /* Program header functions */
-static inline uint32_t elf64_getProgramHeaderType(elf_t *file, size_t ph)
+static inline uint32_t elf64_getProgramHeaderType(const elf_t *file, size_t ph)
 {
     return elf64_getProgramHeaderTable(file)[ph].p_type;
 }
 
-static inline size_t elf64_getProgramHeaderOffset(elf_t *file, size_t ph)
+static inline size_t elf64_getProgramHeaderOffset(const elf_t *file, size_t ph)
 {
     return elf64_getProgramHeaderTable(file)[ph].p_offset;
 }
 
-static inline uintptr_t elf64_getProgramHeaderVaddr(elf_t *file, size_t ph)
+static inline uintptr_t elf64_getProgramHeaderVaddr(const elf_t *file, size_t ph)
 {
     return elf64_getProgramHeaderTable(file)[ph].p_vaddr;
 }
 
-static inline uintptr_t elf64_getProgramHeaderPaddr(elf_t *file, size_t ph)
+static inline uintptr_t elf64_getProgramHeaderPaddr(const elf_t *file, size_t ph)
 {
     return elf64_getProgramHeaderTable(file)[ph].p_paddr;
 }
 
-static inline size_t elf64_getProgramHeaderFileSize(elf_t *file, size_t ph)
+static inline size_t elf64_getProgramHeaderFileSize(const elf_t *file, size_t ph)
 {
     return elf64_getProgramHeaderTable(file)[ph].p_filesz;
 }
 
-static inline size_t elf64_getProgramHeaderMemorySize(elf_t *file, size_t ph)
+static inline size_t elf64_getProgramHeaderMemorySize(const elf_t *file, size_t ph)
 {
     return elf64_getProgramHeaderTable(file)[ph].p_memsz;
 }
 
-static inline uint32_t elf64_getProgramHeaderFlags(elf_t *file, size_t ph)
+static inline uint32_t elf64_getProgramHeaderFlags(const elf_t *file, size_t ph)
 {
     return elf64_getProgramHeaderTable(file)[ph].p_flags;
 }
 
-static inline size_t elf64_getProgramHeaderAlign(elf_t *file, size_t ph)
+static inline size_t elf64_getProgramHeaderAlign(const elf_t *file, size_t ph)
 {
     return elf64_getProgramHeaderTable(file)[ph].p_align;
 }
diff --git a/libelf/src/elf.c b/libelf/src/elf.c
index 8c7712e..ccababd 100644
--- a/libelf/src/elf.c
+++ b/libelf/src/elf.c
@@ -1,83 +1,9 @@
-/* @LICENSE(UNSW_OZPLB) */
-
 /*
- * Australian Public Licence B (OZPLB)
+ * Copyright (c) 1999-2004 University of New South Wales
  *
- * Version 1-0
- *
- * Copyright (c) 2004 University of New South Wales
- *
- * All rights reserved.
- *
- * Developed by: Operating Systems and Distributed Systems Group (DiSy)
- *               University of New South Wales
- *               http://www.disy.cse.unsw.edu.au
- *
- * Permission is granted by University of New South Wales, free of charge, to
- * any person obtaining a copy of this software and any associated
- * documentation files (the "Software") to deal with the Software without
- * restriction, including (without limitation) the rights to use, copy,
- * modify, adapt, merge, publish, distribute, communicate to the public,
- * sublicense, and/or sell, lend or rent out copies of the Software, and
- * to permit persons to whom the Software is furnished to do so, subject
- * to the following conditions:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimers.
- *
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimers in the documentation and/or other materials provided
- *       with the distribution.
- *
- *     * Neither the name of University of New South Wales, nor the names of its
- *       contributors, may be used to endorse or promote products derived
- *       from this Software without specific prior written permission.
- *
- * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
- * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
- * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
- * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
- * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
- * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
- * ERRORS, WHETHER OR NOT DISCOVERABLE.
- *
- * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
- * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
- * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
- * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
- * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
- * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
- * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
- * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
- * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
- * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
- * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
- * DAMAGES OR OTHER LIABILITY.
- *
- * If applicable legislation implies representations, warranties, or
- * conditions, or imposes obligations or liability on University of New South
- * Wales or one of its contributors in respect of the Software that
- * cannot be wholly or partly excluded, restricted or modified, the
- * liability of University of New South Wales or the contributor is limited, to
- * the full extent permitted by the applicable legislation, at its
- * option, to:
- * a.  in the case of goods, any one or more of the following:
- * i.  the replacement of the goods or the supply of equivalent goods;
- * ii.  the repair of the goods;
- * iii. the payment of the cost of replacing the goods or of acquiring
- *  equivalent goods;
- * iv.  the payment of the cost of having the goods repaired; or
- * b.  in the case of services:
- * i.  the supplying of the services again; or
- * ii.  the payment of the cost of having the services supplied again.
- *
- * The construction, validity and performance of this licence is governed
- * by the laws in force in New South Wales, Australia.
+ * SPDX-License-Identifier: BSD-2-Clause
  */
+
 #include <elf/elf.h>
 #include <elf/elf32.h>
 #include <elf/elf64.h>
@@ -85,12 +11,12 @@
 #include <stdio.h>
 
 /* ELF header functions */
-int elf_newFile(void *file, size_t size, elf_t *res)
+int elf_newFile(const void *file, size_t size, elf_t *res)
 {
     return elf_newFile_maybe_unsafe(file, size, true, true, res);
 }
 
-int elf_newFile_maybe_unsafe(void *file, size_t size, bool check_pht, bool check_st, elf_t *res)
+int elf_newFile_maybe_unsafe(const void *file, size_t size, bool check_pht, bool check_st, elf_t *res)
 {
     elf_t new_file = {
         .elfFile = file,
@@ -123,7 +49,7 @@
     return status;
 }
 
-int elf_check_magic(char *file)
+int elf_check_magic(const char *file)
 {
     if (memcmp(file, ELFMAG, SELFMAG) != 0) {
         return -1;
@@ -151,7 +77,7 @@
     return -1;
 }
 
-int elf_checkProgramHeaderTable(elf_t *elfFile)
+int elf_checkProgramHeaderTable(const elf_t *elfFile)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_checkProgramHeaderTable(elfFile);
@@ -160,7 +86,7 @@
     }
 }
 
-int elf_checkSectionTable(elf_t *elfFile)
+int elf_checkSectionTable(const elf_t *elfFile)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_checkSectionTable(elfFile);
@@ -169,7 +95,7 @@
     }
 }
 
-uintptr_t elf_getEntryPoint(elf_t *elfFile)
+uintptr_t elf_getEntryPoint(const elf_t *elfFile)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getEntryPoint(elfFile);
@@ -178,7 +104,7 @@
     }
 }
 
-size_t elf_getNumProgramHeaders(elf_t *elfFile)
+size_t elf_getNumProgramHeaders(const elf_t *elfFile)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getNumProgramHeaders(elfFile);
@@ -187,7 +113,7 @@
     }
 }
 
-size_t elf_getNumSections(elf_t *elfFile)
+size_t elf_getNumSections(const elf_t *elfFile)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getNumSections(elfFile);
@@ -196,7 +122,7 @@
     }
 }
 
-size_t elf_getSectionStringTableIndex(elf_t *elf)
+size_t elf_getSectionStringTableIndex(const elf_t *elf)
 {
     if (elf_isElf32(elf)) {
         return elf32_getSectionStringTableIndex(elf);
@@ -205,7 +131,7 @@
     }
 }
 
-const char *elf_getStringTable(elf_t *elf, size_t string_segment)
+const char *elf_getStringTable(const elf_t *elf, size_t string_segment)
 {
     const char *string_table = elf_getSection(elf, string_segment);
     if (string_table == NULL) {
@@ -224,7 +150,7 @@
     return string_table;
 }
 
-const char *elf_getSectionStringTable(elf_t *elf)
+const char *elf_getSectionStringTable(const elf_t *elf)
 {
     size_t index = elf_getSectionStringTableIndex(elf);
     return elf_getStringTable(elf, index);
@@ -232,7 +158,7 @@
 
 
 /* Section header functions */
-void *elf_getSection(elf_t *elf, size_t i)
+const void *elf_getSection(const elf_t *elf, size_t i)
 {
     if (i == 0 || i >= elf_getNumSections(elf)) {
         return NULL; /* no such section */
@@ -253,7 +179,7 @@
     return elf->elfFile + section_offset;
 }
 
-void *elf_getSectionNamed(elf_t *elfFile, const char *str, size_t *id)
+const void *elf_getSectionNamed(const elf_t *elfFile, const char *str, size_t *id)
 {
     size_t numSections = elf_getNumSections(elfFile);
     for (size_t i = 0; i < numSections; i++) {
@@ -267,7 +193,7 @@
     return NULL;
 }
 
-const char *elf_getSectionName(elf_t *elf, size_t i)
+const char *elf_getSectionName(const elf_t *elf, size_t i)
 {
     size_t str_table_idx = elf_getSectionStringTableIndex(elf);
     const char *str_table = elf_getStringTable(elf, str_table_idx);
@@ -281,7 +207,7 @@
     return str_table + offset;
 }
 
-size_t elf_getSectionNameOffset(elf_t *elfFile, size_t i)
+size_t elf_getSectionNameOffset(const elf_t *elfFile, size_t i)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getSectionNameOffset(elfFile, i);
@@ -290,7 +216,7 @@
     }
 }
 
-uint32_t elf_getSectionType(elf_t *elfFile, size_t i)
+uint32_t elf_getSectionType(const elf_t *elfFile, size_t i)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getSectionType(elfFile, i);
@@ -299,7 +225,7 @@
     }
 }
 
-size_t elf_getSectionFlags(elf_t *elfFile, size_t i)
+size_t elf_getSectionFlags(const elf_t *elfFile, size_t i)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getSectionFlags(elfFile, i);
@@ -308,7 +234,7 @@
     }
 }
 
-uintptr_t elf_getSectionAddr(elf_t *elfFile, size_t i)
+uintptr_t elf_getSectionAddr(const elf_t *elfFile, size_t i)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getSectionAddr(elfFile, i);
@@ -317,7 +243,7 @@
     }
 }
 
-size_t elf_getSectionOffset(elf_t *elfFile, size_t i)
+size_t elf_getSectionOffset(const elf_t *elfFile, size_t i)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getSectionOffset(elfFile, i);
@@ -326,7 +252,7 @@
     }
 }
 
-size_t elf_getSectionSize(elf_t *elfFile, size_t i)
+size_t elf_getSectionSize(const elf_t *elfFile, size_t i)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getSectionSize(elfFile, i);
@@ -335,7 +261,7 @@
     }
 }
 
-uint32_t elf_getSectionLink(elf_t *elfFile, size_t i)
+uint32_t elf_getSectionLink(const elf_t *elfFile, size_t i)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getSectionLink(elfFile, i);
@@ -344,7 +270,7 @@
     }
 }
 
-uint32_t elf_getSectionInfo(elf_t *elfFile, size_t i)
+uint32_t elf_getSectionInfo(const elf_t *elfFile, size_t i)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getSectionInfo(elfFile, i);
@@ -353,7 +279,7 @@
     }
 }
 
-size_t elf_getSectionAddrAlign(elf_t *elfFile, size_t i)
+size_t elf_getSectionAddrAlign(const elf_t *elfFile, size_t i)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getSectionAddrAlign(elfFile, i);
@@ -362,7 +288,7 @@
     }
 }
 
-size_t elf_getSectionEntrySize(elf_t *elfFile, size_t i)
+size_t elf_getSectionEntrySize(const elf_t *elfFile, size_t i)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getSectionEntrySize(elfFile, i);
@@ -373,7 +299,7 @@
 
 
 /* Program headers function */
-void *elf_getProgramSegment(elf_t *elf, size_t ph)
+const void *elf_getProgramSegment(const elf_t *elf, size_t ph)
 {
     size_t offset = elf_getProgramHeaderOffset(elf, ph);
     size_t file_size = elf_getProgramHeaderFileSize(elf, ph);
@@ -386,7 +312,7 @@
     return elf->elfFile + offset;
 }
 
-uint32_t elf_getProgramHeaderType(elf_t *elfFile, size_t ph)
+uint32_t elf_getProgramHeaderType(const elf_t *elfFile, size_t ph)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getProgramHeaderType(elfFile, ph);
@@ -395,7 +321,7 @@
     }
 }
 
-size_t elf_getProgramHeaderOffset(elf_t *elfFile, size_t ph)
+size_t elf_getProgramHeaderOffset(const elf_t *elfFile, size_t ph)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getProgramHeaderOffset(elfFile, ph);
@@ -404,7 +330,7 @@
     }
 }
 
-uintptr_t elf_getProgramHeaderVaddr(elf_t *elfFile, size_t ph)
+uintptr_t elf_getProgramHeaderVaddr(const elf_t *elfFile, size_t ph)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getProgramHeaderVaddr(elfFile, ph);
@@ -413,7 +339,7 @@
     }
 }
 
-uintptr_t elf_getProgramHeaderPaddr(elf_t *elfFile, size_t ph)
+uintptr_t elf_getProgramHeaderPaddr(const elf_t *elfFile, size_t ph)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getProgramHeaderPaddr(elfFile, ph);
@@ -422,7 +348,7 @@
     }
 }
 
-size_t elf_getProgramHeaderFileSize(elf_t *elfFile, size_t ph)
+size_t elf_getProgramHeaderFileSize(const elf_t *elfFile, size_t ph)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getProgramHeaderFileSize(elfFile, ph);
@@ -431,7 +357,7 @@
     }
 }
 
-size_t elf_getProgramHeaderMemorySize(elf_t *elfFile, size_t ph)
+size_t elf_getProgramHeaderMemorySize(const elf_t *elfFile, size_t ph)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getProgramHeaderMemorySize(elfFile, ph);
@@ -440,7 +366,7 @@
     }
 }
 
-uint32_t elf_getProgramHeaderFlags(elf_t *elfFile, size_t ph)
+uint32_t elf_getProgramHeaderFlags(const elf_t *elfFile, size_t ph)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getProgramHeaderFlags(elfFile, ph);
@@ -449,7 +375,7 @@
     }
 }
 
-size_t elf_getProgramHeaderAlign(elf_t *elfFile, size_t ph)
+size_t elf_getProgramHeaderAlign(const elf_t *elfFile, size_t ph)
 {
     if (elf_isElf32(elfFile)) {
         return elf32_getProgramHeaderAlign(elfFile, ph);
@@ -460,7 +386,7 @@
 
 
 /* Utility functions */
-int elf_getMemoryBounds(elf_t *elfFile, elf_addr_type_t addr_type, uintptr_t *min, uintptr_t *max)
+int elf_getMemoryBounds(const elf_t *elfFile, elf_addr_type_t addr_type, uintptr_t *min, uintptr_t *max)
 {
     uintptr_t mem_min = UINTPTR_MAX;
     uintptr_t mem_max = 0;
@@ -494,7 +420,7 @@
     return 1;
 }
 
-int elf_vaddrInProgramHeader(elf_t *elfFile, size_t ph, uintptr_t vaddr)
+int elf_vaddrInProgramHeader(const elf_t *elfFile, size_t ph, uintptr_t vaddr)
 {
     uintptr_t min = elf_getProgramHeaderVaddr(elfFile, ph);
     uintptr_t max = min + elf_getProgramHeaderMemorySize(elfFile, ph);
@@ -505,7 +431,7 @@
     }
 }
 
-uintptr_t elf_vtopProgramHeader(elf_t *elfFile, size_t ph, uintptr_t vaddr)
+uintptr_t elf_vtopProgramHeader(const elf_t *elfFile, size_t ph, uintptr_t vaddr)
 {
     uintptr_t ph_phys = elf_getProgramHeaderPaddr(elfFile, ph);
     uintptr_t ph_virt = elf_getProgramHeaderVaddr(elfFile, ph);
@@ -516,7 +442,7 @@
     return paddr;
 }
 
-int elf_loadFile(elf_t *elf, elf_addr_type_t addr_type)
+int elf_loadFile(const elf_t *elf, elf_addr_type_t addr_type)
 {
     size_t i;
 
diff --git a/libelf/src/elf32.c b/libelf/src/elf32.c
index 544d177..5aea7b1 100644
--- a/libelf/src/elf32.c
+++ b/libelf/src/elf32.c
@@ -1,83 +1,9 @@
-/* @LICENSE(UNSW_OZPLB) */
-
 /*
- * Australian Public Licence B (OZPLB)
+ * Copyright (c) 1999-2004 University of New South Wales
  *
- * Version 1-0
- *
- * Copyright (c) 2004 University of New South Wales
- *
- * All rights reserved.
- *
- * Developed by: Operating Systems and Distributed Systems Group (DiSy)
- *               University of New South Wales
- *               http://www.disy.cse.unsw.edu.au
- *
- * Permission is granted by University of New South Wales, free of charge, to
- * any person obtaining a copy of this software and any associated
- * documentation files (the "Software") to deal with the Software without
- * restriction, including (without limitation) the rights to use, copy,
- * modify, adapt, merge, publish, distribute, communicate to the public,
- * sublicense, and/or sell, lend or rent out copies of the Software, and
- * to permit persons to whom the Software is furnished to do so, subject
- * to the following conditions:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimers.
- *
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimers in the documentation and/or other materials provided
- *       with the distribution.
- *
- *     * Neither the name of University of New South Wales, nor the names of its
- *       contributors, may be used to endorse or promote products derived
- *       from this Software without specific prior written permission.
- *
- * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
- * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
- * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
- * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
- * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
- * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
- * ERRORS, WHETHER OR NOT DISCOVERABLE.
- *
- * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
- * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
- * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
- * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
- * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
- * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
- * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
- * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
- * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
- * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
- * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
- * DAMAGES OR OTHER LIABILITY.
- *
- * If applicable legislation implies representations, warranties, or
- * conditions, or imposes obligations or liability on University of New South
- * Wales or one of its contributors in respect of the Software that
- * cannot be wholly or partly excluded, restricted or modified, the
- * liability of University of New South Wales or the contributor is limited, to
- * the full extent permitted by the applicable legislation, at its
- * option, to:
- * a.  in the case of goods, any one or more of the following:
- * i.  the replacement of the goods or the supply of equivalent goods;
- * ii.  the repair of the goods;
- * iii. the payment of the cost of replacing the goods or of acquiring
- *  equivalent goods;
- * iv.  the payment of the cost of having the goods repaired; or
- * b.  in the case of services:
- * i.  the supplying of the services again; or
- * ii.  the payment of the cost of having the services supplied again.
- *
- * The construction, validity and performance of this licence is governed
- * by the laws in force in New South Wales, Australia.
+ * SPDX-License-Identifier: BSD-2-Clause
  */
+
 #include <elf/elf.h>
 #include <elf/elf32.h>
 #include <inttypes.h>
@@ -94,7 +20,7 @@
         return -1; /* not an ELF file */
     }
 
-    Elf32_Ehdr *header = elf->elfFile;
+    Elf32_Ehdr const *header = elf->elfFile;
     if (header->e_ident[EI_CLASS] != ELFCLASS32) {
         return -1; /* not a 32-bit ELF */
     }
@@ -115,9 +41,9 @@
     return 0; /* elf header looks OK */
 }
 
-int elf32_checkProgramHeaderTable(elf_t *elf)
+int elf32_checkProgramHeaderTable(const elf_t *elf)
 {
-    Elf32_Ehdr *header = elf->elfFile;
+    const Elf32_Ehdr *header = elf->elfFile;
     size_t ph_end = header->e_phoff + header->e_phentsize * header->e_phnum;
     if (elf->elfSize < ph_end || ph_end < header->e_phoff) {
         return -1; /* invalid program header table */
@@ -126,9 +52,9 @@
     return 0;
 }
 
-int elf32_checkSectionTable(elf_t *elf)
+int elf32_checkSectionTable(const elf_t *elf)
 {
-    Elf32_Ehdr *header = elf->elfFile;
+    const Elf32_Ehdr *header = elf->elfFile;
     size_t sh_end = header->e_shoff + header->e_shentsize * header->e_shnum;
     if (elf->elfSize < sh_end || sh_end < header->e_shoff) {
         return -1; /* invalid section header table */
diff --git a/libelf/src/elf64.c b/libelf/src/elf64.c
index 73ee2f0..1568cb1 100644
--- a/libelf/src/elf64.c
+++ b/libelf/src/elf64.c
@@ -1,83 +1,9 @@
-/* @LICENSE(UNSW_OZPLB) */
-
 /*
- * Australian Public Licence B (OZPLB)
+ * Copyright (c) 1999-2004 University of New South Wales
  *
- * Version 1-0
- *
- * Copyright (c) 2004 University of New South Wales
- *
- * All rights reserved.
- *
- * Developed by: Operating Systems and Distributed Systems Group (DiSy)
- *               University of New South Wales
- *               http://www.disy.cse.unsw.edu.au
- *
- * Permission is granted by University of New South Wales, free of charge, to
- * any person obtaining a copy of this software and any associated
- * documentation files (the "Software") to deal with the Software without
- * restriction, including (without limitation) the rights to use, copy,
- * modify, adapt, merge, publish, distribute, communicate to the public,
- * sublicense, and/or sell, lend or rent out copies of the Software, and
- * to permit persons to whom the Software is furnished to do so, subject
- * to the following conditions:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimers.
- *
- *     * Redistributions in binary form must reproduce the above
- *       copyright notice, this list of conditions and the following
- *       disclaimers in the documentation and/or other materials provided
- *       with the distribution.
- *
- *     * Neither the name of University of New South Wales, nor the names of its
- *       contributors, may be used to endorse or promote products derived
- *       from this Software without specific prior written permission.
- *
- * EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
- * PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS", AND
- * NATIONAL ICT AUSTRALIA AND ITS CONTRIBUTORS MAKE NO REPRESENTATIONS,
- * WARRANTIES OR CONDITIONS OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
- * BUT NOT LIMITED TO ANY REPRESENTATIONS, WARRANTIES OR CONDITIONS
- * REGARDING THE CONTENTS OR ACCURACY OF THE SOFTWARE, OR OF TITLE,
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT,
- * THE ABSENCE OF LATENT OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF
- * ERRORS, WHETHER OR NOT DISCOVERABLE.
- *
- * TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT SHALL
- * NATIONAL ICT AUSTRALIA OR ITS CONTRIBUTORS BE LIABLE ON ANY LEGAL
- * THEORY (INCLUDING, WITHOUT LIMITATION, IN AN ACTION OF CONTRACT,
- * NEGLIGENCE OR OTHERWISE) FOR ANY CLAIM, LOSS, DAMAGES OR OTHER
- * LIABILITY, INCLUDING (WITHOUT LIMITATION) LOSS OF PRODUCTION OR
- * OPERATION TIME, LOSS, DAMAGE OR CORRUPTION OF DATA OR RECORDS; OR LOSS
- * OF ANTICIPATED SAVINGS, OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR
- * OTHER ECONOMIC LOSS; OR ANY SPECIAL, INCIDENTAL, INDIRECT,
- * CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES, ARISING OUT OF OR IN
- * CONNECTION WITH THIS LICENCE, THE SOFTWARE OR THE USE OF OR OTHER
- * DEALINGS WITH THE SOFTWARE, EVEN IF NATIONAL ICT AUSTRALIA OR ITS
- * CONTRIBUTORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH CLAIM, LOSS,
- * DAMAGES OR OTHER LIABILITY.
- *
- * If applicable legislation implies representations, warranties, or
- * conditions, or imposes obligations or liability on University of New South
- * Wales or one of its contributors in respect of the Software that
- * cannot be wholly or partly excluded, restricted or modified, the
- * liability of University of New South Wales or the contributor is limited, to
- * the full extent permitted by the applicable legislation, at its
- * option, to:
- * a.  in the case of goods, any one or more of the following:
- * i.  the replacement of the goods or the supply of equivalent goods;
- * ii.  the repair of the goods;
- * iii. the payment of the cost of replacing the goods or of acquiring
- *  equivalent goods;
- * iv.  the payment of the cost of having the goods repaired; or
- * b.  in the case of services:
- * i.  the supplying of the services again; or
- * ii.  the payment of the cost of having the services supplied again.
- *
- * The construction, validity and performance of this licence is governed
- * by the laws in force in New South Wales, Australia.
+ * SPDX-License-Identifier: BSD-2-Clause
  */
+
 #include <elf/elf.h>
 #include <elf/elf64.h>
 #include <inttypes.h>
@@ -98,7 +24,7 @@
         return -1; /* not an ELF file */
     }
 
-    Elf64_Ehdr *header = elf->elfFile;
+    Elf64_Ehdr const *header = elf->elfFile;
     if (header->e_ident[EI_CLASS] != ELFCLASS64) {
         return -1; /* not a 64-bit ELF */
     }
@@ -119,9 +45,9 @@
     return 0; /* elf header looks OK */
 }
 
-int elf64_checkProgramHeaderTable(elf_t *elf)
+int elf64_checkProgramHeaderTable(const elf_t *elf)
 {
-    Elf64_Ehdr *header = elf->elfFile;
+    const Elf64_Ehdr *header = elf->elfFile;
     size_t ph_end = header->e_phoff + header->e_phentsize * header->e_phnum;
     if (elf->elfSize < ph_end || ph_end < header->e_phoff) {
         return -1; /* invalid program header table */
@@ -130,9 +56,9 @@
     return 0;
 }
 
-int elf64_checkSectionTable(elf_t *elf)
+int elf64_checkSectionTable(const elf_t *elf)
 {
-    Elf64_Ehdr *header = elf->elfFile;
+    const Elf64_Ehdr *header = elf->elfFile;
     size_t sh_end = header->e_shoff + header->e_shentsize * header->e_shnum;
     if (elf->elfSize < sh_end || sh_end < header->e_shoff) {
         return -1; /* invalid section header table */
diff --git a/libethdrivers/CMakeLists.txt b/libethdrivers/CMakeLists.txt
index 93b7143..39f3527 100644
--- a/libethdrivers/CMakeLists.txt
+++ b/libethdrivers/CMakeLists.txt
@@ -1,13 +1,7 @@
 #
-# Copyright 2018, Data61
-# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-# ABN 41 687 119 230.
+# Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
 #
-# This software may be distributed and modified according to the terms of
-# the BSD 2-Clause license. Note that NO WARRANTY is provided.
-# See "LICENSE_BSD2.txt" for details.
-#
-# @TAG(DATA61_BSD)
+# SPDX-License-Identifier: BSD-2-Clause
 #
 
 cmake_minimum_required(VERSION 3.8.2)
@@ -110,7 +104,17 @@
 if("${KernelPlatform}" STREQUAL "tx2")
     target_link_libraries(ethdrivers platsupportports)
 endif()
-target_link_libraries(
-    ethdrivers
-    "-Wl,--undefined=tx2_ether_qos_ptr,--undefined=zynq7000_gem_ptr,--undefined=imx_fec_ptr"
+
+# Get the list of driver modules
+string(
+    JOIN
+    ","
+    DriverModules
+    "-Wl"
+    "--undefined=tx_ether_qos_ptr"
+    "--undefined=zynq7000_gem_ptr"
+    "--undefined=imx_fec_ptr"
+    "--undefined=odroidc2_ethernet_ptr"
 )
+
+target_link_libraries(ethdrivers "${DriverModules}")
diff --git a/libethdrivers/LICENSE_GPLv2.txt b/libethdrivers/LICENSE_GPLv2.txt
deleted file mode 100644
index e418701..0000000
--- a/libethdrivers/LICENSE_GPLv2.txt
+++ /dev/null
@@ -1,295 +0,0 @@
-
-Files described as being under the "GNU General Public License version 2"
-or simply the "GPLv2" fall under the following license.
-
-Note that this copyright does not cover user programs that use kernel
-services by normal system calls --- this is merely considered normal use
-of the kernel, and does not fall under the heading of "derived work".
-
-Also note that while the Free Software Foundation owns the copyright to
-the license text below, copyright for the actual files included in this
-project are held by their respective owners, indicated at the top of
-each file.
-
------------------------------------------------------------------------
-
-                    GNU GENERAL PUBLIC LICENSE
-                       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-                            Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-                    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-                            NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-                     END OF TERMS AND CONDITIONS
diff --git a/libethdrivers/include/ethdrivers/am335x.h b/libethdrivers/include/ethdrivers/am335x.h
index c7f6df7..f39a31b 100644
--- a/libethdrivers/include/ethdrivers/am335x.h
+++ b/libethdrivers/include/ethdrivers/am335x.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2016, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2016, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #ifndef __ETHIF_AM335X_DRIVER_H
diff --git a/libethdrivers/include/ethdrivers/helpers.h b/libethdrivers/include/ethdrivers/helpers.h
index b268c64..020f701 100644
--- a/libethdrivers/include/ethdrivers/helpers.h
+++ b/libethdrivers/include/ethdrivers/helpers.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #pragma once
diff --git a/libethdrivers/include/ethdrivers/imx6.h b/libethdrivers/include/ethdrivers/imx6.h
index 3affba5..f3923ff 100644
--- a/libethdrivers/include/ethdrivers/imx6.h
+++ b/libethdrivers/include/ethdrivers/imx6.h
@@ -1,29 +1,10 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #pragma once
 
-#include <platsupport/io.h>
-#include <ethdrivers/raw.h>
-
-#define IMX6_INTERRUPT_ENET 150
-
-/**
- * This function initialises the hardware and conforms to the ethif_driver_init
- * type in raw.h
- * @param[out] eth_driver   Ethernet driver structure to fill out
- * @param[in] io_ops        A structure containing os specific data and
- *                          functions.
- * @param[in] config        Platform Specific configuration data
- */
-int ethif_imx6_init(struct eth_driver *eth_driver, ps_io_ops_t io_ops, void *config);
-
+/* nothing here */
diff --git a/libethdrivers/include/ethdrivers/intel.h b/libethdrivers/include/ethdrivers/intel.h
index ee9b34e..6759b10 100644
--- a/libethdrivers/include/ethdrivers/intel.h
+++ b/libethdrivers/include/ethdrivers/intel.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #pragma once
diff --git a/libethdrivers/include/ethdrivers/lwip.h b/libethdrivers/include/ethdrivers/lwip.h
index 6299099..c31d117 100644
--- a/libethdrivers/include/ethdrivers/lwip.h
+++ b/libethdrivers/include/ethdrivers/lwip.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #pragma once
diff --git a/libethdrivers/include/ethdrivers/odroidc2.h b/libethdrivers/include/ethdrivers/odroidc2.h
new file mode 100644
index 0000000..f22fa97
--- /dev/null
+++ b/libethdrivers/include/ethdrivers/odroidc2.h
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+#pragma once
+
+#include <platsupport/io.h>
+#include <ethdrivers/raw.h>
+
+/**
+ * This function initialises the hardware and conforms to the ethif_driver_init
+ * type in raw.h
+ * @param[out] eth_driver   Ethernet driver structure to fill out
+ * @param[in] io_ops        A structure containing os specific data and
+ *                          functions.
+ * @param[in] config        Platform Specific configuration data
+ */
+int ethif_odroidc2_init(struct eth_driver *eth_driver, ps_io_ops_t io_ops, void *config);
diff --git a/libethdrivers/include/ethdrivers/pico_dev_eth.h b/libethdrivers/include/ethdrivers/pico_dev_eth.h
index cd9342d..7ee9be7 100644
--- a/libethdrivers/include/ethdrivers/pico_dev_eth.h
+++ b/libethdrivers/include/ethdrivers/pico_dev_eth.h
@@ -1,13 +1,7 @@
 /*
- *  Copyright 2017, Data61
- *  Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- *  ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libethdrivers/include/ethdrivers/raw.h b/libethdrivers/include/ethdrivers/raw.h
index 1b3f121..2d2a5a9 100644
--- a/libethdrivers/include/ethdrivers/raw.h
+++ b/libethdrivers/include/ethdrivers/raw.h
@@ -1,13 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #pragma once
@@ -165,7 +160,7 @@
     void *pbuf;
 };
 
-/* Structure for i.MX6, Zynq7000 and Tx2 Drivers
+/* Structure for Zynq7000 and Tx2 Drivers
  * TODO: Move to ARCH Specific Folder
  */
 struct arm_eth_plat_config {
diff --git a/libethdrivers/include/ethdrivers/tx2.h b/libethdrivers/include/ethdrivers/tx2.h
index 8e27401..a980f30 100644
--- a/libethdrivers/include/ethdrivers/tx2.h
+++ b/libethdrivers/include/ethdrivers/tx2.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #pragma once
diff --git a/libethdrivers/include/ethdrivers/virtio/virtio_config.h b/libethdrivers/include/ethdrivers/virtio/virtio_config.h
index f39fdf1..c26b693 100644
--- a/libethdrivers/include/ethdrivers/virtio/virtio_config.h
+++ b/libethdrivers/include/ethdrivers/virtio/virtio_config.h
@@ -1,4 +1,6 @@
-/* @TAG(OTHER_BSD) */
+/* SPDX-License-Identifier: BSD-3-Clause
+   Copyright Linux */
+
 #pragma once
 /* This header, excluding the #ifdef __KERNEL__ part, is BSD licensed so
  * anyone can use the definitions to implement compatible drivers/servers.
diff --git a/libethdrivers/include/ethdrivers/virtio/virtio_net.h b/libethdrivers/include/ethdrivers/virtio/virtio_net.h
index dd7ef72..afc3035 100644
--- a/libethdrivers/include/ethdrivers/virtio/virtio_net.h
+++ b/libethdrivers/include/ethdrivers/virtio/virtio_net.h
@@ -1,4 +1,6 @@
-/* @TAG(OTHER_BSD) */
+/* SPDX-License-Identifier: BSD-3-Clause
+   Copyright Linux */
+
 #pragma once
 /* This header is BSD licensed so anyone can use the definitions to implement
  * compatible drivers/servers.
diff --git a/libethdrivers/include/ethdrivers/virtio/virtio_pci.h b/libethdrivers/include/ethdrivers/virtio/virtio_pci.h
index 2c6c89f..aefa2cb 100644
--- a/libethdrivers/include/ethdrivers/virtio/virtio_pci.h
+++ b/libethdrivers/include/ethdrivers/virtio/virtio_pci.h
@@ -1,4 +1,4 @@
-/* @TAG(CUSTOM) */
+/* SPDX-License-Identifier: BSD-3-Clause */
 /*
  * Virtio PCI driver
  *
diff --git a/libethdrivers/include/ethdrivers/virtio/virtio_ring.h b/libethdrivers/include/ethdrivers/virtio/virtio_ring.h
index e458ad2..14aa609 100644
--- a/libethdrivers/include/ethdrivers/virtio/virtio_ring.h
+++ b/libethdrivers/include/ethdrivers/virtio/virtio_ring.h
@@ -1,4 +1,4 @@
-/* @TAG(CUSTOM) */
+/* SPDX-License-Identifier: BSD-3-Clause */
 #pragma once
 /* An interface for efficient virtio implementation, currently for use by KVM
  * and lguest, but hopefully others soon.  Do NOT change this since it will
diff --git a/libethdrivers/include/ethdrivers/virtio_pci.h b/libethdrivers/include/ethdrivers/virtio_pci.h
index c4f3095..3cb7466 100644
--- a/libethdrivers/include/ethdrivers/virtio_pci.h
+++ b/libethdrivers/include/ethdrivers/virtio_pci.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #pragma once
diff --git a/libethdrivers/include/ethdrivers/zynq7000.h b/libethdrivers/include/ethdrivers/zynq7000.h
index a316e76..acc252d 100644
--- a/libethdrivers/include/ethdrivers/zynq7000.h
+++ b/libethdrivers/include/ethdrivers/zynq7000.h
@@ -1,11 +1,7 @@
 /*
  * Copyright 2017, DornerWorks, Ltd.
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #ifndef __ETHIF_ZYNQ7000_DRIVER_H
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/beaglebone.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/beaglebone.h
index 92484f1..592c433 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/beaglebone.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/beaglebone.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  * \file   beaglebone.h
  *
  * \brief  This file contains prototype declarations of functions which
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/cpsw.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/cpsw.h
index cad673d..412ea9d 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/cpsw.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/cpsw.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//*
+/* SPDX-License-Identifier: BSD-3-Clause */
+
 /**
  *  \file   cpsw.h
  *
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/dmtimer.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/dmtimer.h
index b31f8fc..908a4f5 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/dmtimer.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/dmtimer.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  \file   dmtimer.h
  *
  *  \brief  DMTimer API prototypes and macros.
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/edma.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/edma.h
index b41c089..bd7e85e 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/edma.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/edma.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  \file       edma.h
  *
  *  \brief      This file contains the function prototypes for the device
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_cefuse.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_cefuse.h
index 13c0a79..141f755 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_cefuse.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_cefuse.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  @Component:   CM
  *
  *  @Filename:    ../../CredDataBase/prcmCRED/cm_cefuse_cred.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_device.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_device.h
index 9d87305..c86052a 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_device.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_device.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  @Component:   CM
  *
  *  @Filename:    ../../CredDataBase/prcmCRED/cm_device_cred.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_dpll.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_dpll.h
index 34b6cc5..b7d3c63 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_dpll.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_dpll.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  @Component:   CM
  *
  *  @Filename:    ../../CredDataBase/prcmCRED/cm_dpll_cred.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_gfx.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_gfx.h
index 2522ac5..99468b4 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_gfx.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_gfx.h
@@ -1,4 +1,6 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+
+/**
  *  @Component:   CM
  *
  *  @Filename:    ../../CredDataBase/prcmCRED/cm_gfx_cred.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_mpu.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_mpu.h
index bd0b8c7..da5f6e5 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_mpu.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_mpu.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  @Component:   CM
  *
  *  @Filename:    ../../CredDataBase/prcmCRED/cm_mpu_cred.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_per.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_per.h
index f353919..0b7ef67 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_per.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_per.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  @Component:   CM
  *
  *  @Filename:    ../../CredDataBase/prcmCRED/cm_per_cred.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_rtc.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_rtc.h
index 07d8aa5..89f6f95 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_rtc.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_rtc.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  @Component:   CM
  *
  *  @Filename:    ../../CredDataBase/prcmCRED/cm_rtc_cred.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_wkup.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_wkup.h
index a3de3f6..ab93961 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_wkup.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cm_wkup.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  @Component:   CM
  *
  *  @Filename:    ../../CredDataBase/prcmCRED/cm_wkup_cred.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_control_AM335x.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_control_AM335x.h
index 23cb329..2af4e3c 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_control_AM335x.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_control_AM335x.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  @Component:   CONTROL
  *
  *  @Filename:    ../../CredDataBase/CONTROL_cred.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_ale.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_ale.h
index a925c33..1b16be7 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_ale.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_ale.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  @Component:   CPSW
  *
  *  @Filename:    cpsw_ale_cred.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_cpdma.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_cpdma.h
index 8a4fde9..b5e8705 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_cpdma.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_cpdma.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  @Component:   CPSW
  *
  *  @Filename:    cpsw_CPDMA_cred.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_port.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_port.h
index de9ecf2..8dfba13 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_port.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_port.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  @Component:   CPSW
  *
  *  @Filename:    cpsw_port_cred.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_sl.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_sl.h
index beb0db6..def74a3 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_sl.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_sl.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  @Component:   CPSW
  *
  *  @Filename:    cpsw_sl_cred.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_ss.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_ss.h
index f3882b9..40e3415 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_ss.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_ss.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  @Component:   CPSW
  *
  *  @Filename:    cpsw_ss_cred.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_wr.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_wr.h
index 340fcbf..6cd9068 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_wr.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_cpsw_wr.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause  */
+/**
  *  @Component:   CPSW
  *
  *  @Filename:    cpsw_wr_cred.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_dmtimer.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_dmtimer.h
index 0a3963b..d9db6fd 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_dmtimer.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_dmtimer.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  @Component:   DMTIMER
  *
  *  @Filename:    hw_dmtimer.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_edma3cc.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_edma3cc.h
index 2ddfc6d..1b43da6 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_edma3cc.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_edma3cc.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  * \file  hw_edma3cc.h
  *
  * \brief EDMA3CC register definitions
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_edma3tc.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_edma3tc.h
index 6467a7b..6fa0fab 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_edma3tc.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_edma3tc.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  * \file  hw_edma3tc.h
  *
  * \brief EDMA3TC register definitions
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_intc.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_intc.h
index 6e696f6..961d2f6 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_intc.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_intc.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  @Component:   INTC
  *
  *  @Filename:    intc_header.h
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_mdio.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_mdio.h
index f9bc6db..62a09f5 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_mdio.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_mdio.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  * \file  hw_mdio.h
  *
  * \brief MDIO register definitions
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_types.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_types.h
index 264077c..3d9c961 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_types.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/hw_types.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  * \file  hw_types.h
  *
  * \brief Common type definitions and macros
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/soc_AM335x.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/soc_AM335x.h
index f7b24e9..58d8635 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/soc_AM335x.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/hw/soc_AM335x.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//** ============================================================================
+/* SPDX-License-Identifier: BSD-3-Clause */
+/** ============================================================================
  *   \file  soc_AM33XX.h
  *
  *   \brief This file contains the peripheral information for AM33XX SoC
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/interrupt.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/interrupt.h
index 81ac25a..9a9bae9 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/interrupt.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/interrupt.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  \file   interrupt.h
  *
  *  \brief  Interrupt related API declarations.
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/mdio.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/mdio.h
index d804260..9d7d0ae 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/mdio.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/mdio.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  *  \file   mdio.h
  *
  *  \brief  MDIO APIs and macros.
diff --git a/libethdrivers/plat_include/am335x/ethdrivers/plat/phy.h b/libethdrivers/plat_include/am335x/ethdrivers/plat/phy.h
index 65a501a..40d824c 100644
--- a/libethdrivers/plat_include/am335x/ethdrivers/plat/phy.h
+++ b/libethdrivers/plat_include/am335x/ethdrivers/plat/phy.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  * \file  phy.h
  *
  * \brief Macros and function definitions for EMAC PHY
diff --git a/libethdrivers/plat_include/imx6/ethdrivers/plat/eth_plat.h b/libethdrivers/plat_include/imx6/ethdrivers/plat/eth_plat.h
index ae0e120..eed1098 100644
--- a/libethdrivers/plat_include/imx6/ethdrivers/plat/eth_plat.h
+++ b/libethdrivers/plat_include/imx6/ethdrivers/plat/eth_plat.h
@@ -1,11 +1,40 @@
 /*
  * Copyright 2017, DORNERWORKS
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DORNERWORKS_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
+#pragma once
+
 #include <ethdrivers/imx6.h>
+#include <utils/attribute.h>
+#include <ethdrivers/raw.h>
+#include "../src/plat/imx6/enet.h"
+
+struct enet *get_enet_from_driver(struct eth_driver *driver);
+
+enum {
+    NIC_CONFIG_FORCE_MAC        = 1u << 0, /**< Use MAC from config (if not 0) */
+    NIC_CONFIG_PROMISCUOUS_MODE = 1u << 1, /**< Enable promiscuous mode */
+    NIC_CONFIG_DROP_FRAME_CRC   = 1u << 2, /**< Drop ethernet frame CRC */
+} nic_config_flags_t;
+
+typedef int (*sync_func_t)(void);
+typedef int (*mdio_read_func_t)(uint16_t reg);
+typedef int (*mdio_write_func_t)(uint16_t reg, uint16_t data);
+
+typedef struct {
+    unsigned int phy_address; /**< Address of the PHY chip, 0 for auto-detect */
+    unsigned int id; /**< ID of the enet */
+    unsigned int flags;
+    uint64_t mac; /**< MAC address, 0x0000aabbccddeeff, ignored if 0 */
+    struct {
+        sync_func_t sync; /**< blocks until primary NIC init is finished */
+        mdio_read_func_t mdio_read; /**< primary NIC mdio_read rpc function */
+        mdio_write_func_t mdio_write; /**< primary NIC mdio_write rpc function */
+    } funcs;
+} nic_config_t;
+
+/* this function can be provided so the driver can fetch a configuration */
+WEAK const nic_config_t *get_nic_configuration(void);
diff --git a/libethdrivers/plat_include/zynq7000/ethdrivers/plat/eth_plat.h b/libethdrivers/plat_include/zynq7000/ethdrivers/plat/eth_plat.h
index 524a6d9..ab24322 100644
--- a/libethdrivers/plat_include/zynq7000/ethdrivers/plat/eth_plat.h
+++ b/libethdrivers/plat_include/zynq7000/ethdrivers/plat/eth_plat.h
@@ -1,11 +1,7 @@
 /*
  * Copyright 2017, DORNERWORKS
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DORNERWORKS_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #include <ethdrivers/zynq7000.h>
diff --git a/libethdrivers/src/debug.h b/libethdrivers/src/debug.h
index 26ab75e..6af6863 100644
--- a/libethdrivers/src/debug.h
+++ b/libethdrivers/src/debug.h
@@ -1,33 +1,20 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
+ * SPDX-License-Identifier: GPL-2.0-only
  *
- * @TAG(DATA61_GPL)
+ *
+ * This file uses printf() instead of ZF_LOGx() because it is used for special
+ * debugging purposes only. Re-writing the functions is not worth the effort. It
+ * should happen if the function are used during normal operation also.
  */
 
 #pragma once
 
+#include <stdio.h>
 #include <stdint.h>
 #include <utils/util.h>
-//#define DBG_MAP
-//#define DBG_PKT
-//#define DBG_PRINT_PAYLOAD
-//#define DBG_REG
-//#define DBG_FEC
-//#define DBG_BUF
-//#define DBG_NET
-//#define DBG_CLK
-
-#ifdef DBG_MAP
-#  define MAP_DEBUG(x) do{x;}while(0)
-#else
-#  define MAP_DEBUG(x) do{;}while(0)
-#endif
 
 #ifdef DBG_PKT
 #  define PKT_DEBUG(x) do{x;}while(0)
@@ -38,39 +25,6 @@
 #  define PKT_DEBUG(x) do{;}while(0)
 #endif
 
-#ifdef DBG_FEC
-#define FEC_DEBUG(x) do{x;}while(0)
-#else
-#define FEC_DEBUG(x) do{;}while(0)
-#endif
-
-#ifdef DBG_BUF
-#define BUF_DEBUG(x) do{x;}while(0)
-#else
-#define BUF_DEBUG(x) do{;}while(0)
-#endif
-
-#ifdef DBG_REG
-#define REG_DEBUG(x) do{x;}while(0)
-#else
-#define REG_DEBUG(x) do{;}while(0)
-#endif
-
-#ifdef DBG_NET
-#define NET_DEBUG(x) do{x;}while(0)
-#else
-#define NET_DEBUG(x) do{;}while(0)
-#endif
-
-#ifdef DBG_CLK
-#define CLK_DEBUG(x) do{x;} while(0)
-#else
-#define CLK_DEBUG(x) do{;} while(0)
-#endif
-
-#include <stdio.h>
-#include <stdint.h>
-
 #define COL_NET "\e[1;34m"
 #define COL_IMP "\e[1;31m"
 #define COL_FEC "\e[1;32m"
@@ -80,68 +34,71 @@
 #define COL_PKT "\e[1;36m"
 #define COL_DEF "\e[0;0m"
 
-#define set_colour(x) printf(x);
-
-#define cprintf(col, ...) do { \
-        set_colour(col);       \
-        ZF_LOGD(__VA_ARGS__);  \
-        set_colour(COL_DEF);   \
-        printf("\n");          \
-    }while(0)
-
-#define UNIMPLEMENTED() \
-    do{\
-        ZF_LOGF("unimplemented"); \
-        while(1); \
-    } while(0)
+#define cprintf(col, fmt, ...)  ZF_LOGD( col fmt COL_DEF, __VA_ARGS__)
 
 #ifdef DBG_PKT
 
-static inline void print_mac(uint8_t* mac){
+static inline void print_mac(uint8_t *mac)
+{
     int i;
     printf("%02x", *mac++);
-    for(i = 0; i < 5; i++){
+    for (i = 0; i < 5; i++) {
         printf(":%02x", *mac++);
     }
 }
 
-static inline void
-print_type(uint8_t* p){
+static inline void print_type(uint8_t *p)
+{
     uint32_t type = 0;
     int i;
-    p += 6*2;
-    for(i = 0; i < 2; i++){
+    p += 6 * 2;
+    for (i = 0; i < 2; i++) {
         type = type << 8  | *p++;
     }
-    switch(type){
-    case 0x0806: printf("ARP"); break;
-    case 0x0800: printf(" IP"); break;
-    default: printf("UNKNOWN");
+    switch (type) {
+    case 0x0806:
+        printf("ARP");
+        break;
+    case 0x0800:
+        printf(" IP");
+        break;
+    default:
+        printf("UNKNOWN");
     }
     printf(" (0x%04x)", type);
 }
 
-static inline void print_val(uint8_t* p, int len){
+static inline void print_val(uint8_t *p, int len)
+{
     uint32_t val = 0;
     int i;
-    for(i = 0; i < len; i++){
+    for (i = 0; i < len; i++) {
         val = val << 8 | *p++;
     }
     printf("%d", val);
 }
 
-static inline void print_packet(const char* col, void* packet, int length){
+static inline void print_packet(const char *col, void *packet, int length)
+{
     cprintf(col, "packet 0x%x (%d bytes)", (uint32_t)packet, length);
-    unsigned char* p = packet;
-    printf(" dst MAC : ");  print_mac(p + 0);
-    printf(" src MAC : ");  print_mac(p + 6); printf("\n");
-    printf(" src port: ");  print_val(p +0x22, 2);
-    printf(" dst port: ");  print_val(p +0x24, 2); printf("\n");
-    printf(" type    : "); print_type(p + 0); printf("\n");
+    unsigned char *p = packet;
+    printf(" dst MAC : ");
+    print_mac(p + 0);
+    printf(" src MAC : ");
+    print_mac(p + 6);
+    printf("\n");
+    printf(" src port: ");
+    print_val(p + 0x22, 2);
+    printf(" dst port: ");
+    print_val(p + 0x24, 2);
+    printf("\n");
+    printf(" type    : ");
+    print_type(p + 0);
+    printf("\n");
 #if defined(DBG_PRINT_PAYLOAD)
-    int i,j;
-    for(i=0;i<length;i+=32){
-        for(j=0;j<32 && length > i+j;j++){
+    int i, j;
+    for (i = 0; i < length; i += 32) {
+        for (j = 0; j < 32 && length > i + j; j++) {
             printf("%02x", *p++);
         }
         printf("\n");
diff --git a/libethdrivers/src/helpers.c b/libethdrivers/src/helpers.c
index c59395b..a9a86bd 100644
--- a/libethdrivers/src/helpers.c
+++ b/libethdrivers/src/helpers.c
@@ -1,39 +1,41 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #include <ethdrivers/helpers.h>
 
-dma_addr_t
-dma_alloc_pin(ps_dma_man_t *dma_man, size_t size, int cached, int alignment)
+dma_addr_t dma_alloc_pin(ps_dma_man_t *dma_man, size_t size, int cached, int alignment)
 {
     void *virt = ps_dma_alloc(dma_man, size, alignment, cached, PS_MEM_NORMAL);
     if (!virt) {
-        return (dma_addr_t) {0, 0};
+        ZF_LOGE("ps_dma_alloc() failed for size=%zu, alignment=%d",
+                size, alignment);
+        return (dma_addr_t) {
+            .virt = NULL, .phys = 0
+        };
     }
     uintptr_t phys = ps_dma_pin(dma_man, virt, size);
     if (!phys) {
+        ZF_LOGE("ps_dma_pin() failed for virt=%p, size=%zu", virt, size);
         /* hmm this shouldn't really happen */
         ps_dma_free(dma_man, virt, size);
-        return (dma_addr_t) {0, 0};
+        return (dma_addr_t) {
+            .virt = NULL, .phys = 0
+        };
     }
     if (!cached) {
         /* Prevent any cache bombs */
         ps_dma_cache_clean_invalidate(dma_man, virt, size);
     }
-    return (dma_addr_t) {.virt = virt, .phys = phys};
+    return (dma_addr_t) {
+        .virt = virt, .phys = phys
+    };
 }
 
-void
-dma_unpin_free(ps_dma_man_t *dma_man, void *virt, size_t size)
+void dma_unpin_free(ps_dma_man_t *dma_man, void *virt, size_t size)
 {
     ps_dma_unpin(dma_man, virt, size);
     ps_dma_free(dma_man, virt, size);
diff --git a/libethdrivers/src/lwip.c b/libethdrivers/src/lwip.c
index 221ce62..e45fc3a 100644
--- a/libethdrivers/src/lwip.c
+++ b/libethdrivers/src/lwip.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #include <autoconf.h>
diff --git a/libethdrivers/src/pico_dev_eth.c b/libethdrivers/src/pico_dev_eth.c
index 05b0828..144392d 100644
--- a/libethdrivers/src/pico_dev_eth.c
+++ b/libethdrivers/src/pico_dev_eth.c
@@ -1,13 +1,7 @@
 /*
- *  Copyright 2017, Data61
- *  Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- *  ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <autoconf.h>
diff --git a/libethdrivers/src/plat/am335x/beaglebone.c b/libethdrivers/src/plat/am335x/beaglebone.c
index 25086ef..513ed4d 100644
--- a/libethdrivers/src/plat/am335x/beaglebone.c
+++ b/libethdrivers/src/plat/am335x/beaglebone.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2016, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2016, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #include <ethdrivers/raw.h>
diff --git a/libethdrivers/src/plat/am335x/cpsw.c b/libethdrivers/src/plat/am335x/cpsw.c
index 5a66ae1..509794d 100644
--- a/libethdrivers/src/plat/am335x/cpsw.c
+++ b/libethdrivers/src/plat/am335x/cpsw.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libethdrivers/src/plat/am335x/cpsw/cpswif.c b/libethdrivers/src/plat/am335x/cpsw/cpswif.c
index 0ddb36e..f9320ae 100644
--- a/libethdrivers/src/plat/am335x/cpsw/cpswif.c
+++ b/libethdrivers/src/plat/am335x/cpsw/cpswif.c
@@ -1,4 +1,4 @@
-/* @TAG(CUSTOM) */
+/* SPDX-License-Identifier: BSD-3-Clause */
 
 /**
  * @file - cpswif.c
diff --git a/libethdrivers/src/plat/am335x/cpsw/cpswif.h b/libethdrivers/src/plat/am335x/cpsw/cpswif.h
index b318521..1caec47 100644
--- a/libethdrivers/src/plat/am335x/cpsw/cpswif.h
+++ b/libethdrivers/src/plat/am335x/cpsw/cpswif.h
@@ -1,4 +1,4 @@
-/* @TAG(CUSTOM) */
+/* SPDX-License-Identifier: BSD-3-Clause */
 
 /**
  * @file - cpswif.h
diff --git a/libethdrivers/src/plat/am335x/cpsw_beaglebone.c b/libethdrivers/src/plat/am335x/cpsw_beaglebone.c
index 0dc381d..0ed239f 100644
--- a/libethdrivers/src/plat/am335x/cpsw_beaglebone.c
+++ b/libethdrivers/src/plat/am335x/cpsw_beaglebone.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libethdrivers/src/plat/am335x/edma.c b/libethdrivers/src/plat/am335x/edma.c
index a495ec7..2bcc967 100644
--- a/libethdrivers/src/plat/am335x/edma.c
+++ b/libethdrivers/src/plat/am335x/edma.c
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) *//**
+/* SPDX-License-Identifier: BSD-3-Clause */
+/**
  * \file  edma.c
  *
  * \brief This file contains device abstraction layer APIs for the EDMA device.
diff --git a/libethdrivers/src/plat/am335x/edma_beaglebone.c b/libethdrivers/src/plat/am335x/edma_beaglebone.c
index 6bce062..3d4e425 100644
--- a/libethdrivers/src/plat/am335x/edma_beaglebone.c
+++ b/libethdrivers/src/plat/am335x/edma_beaglebone.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libethdrivers/src/plat/am335x/lwiplib.h b/libethdrivers/src/plat/am335x/lwiplib.h
index 4d8a943..dd1b3ae 100644
--- a/libethdrivers/src/plat/am335x/lwiplib.h
+++ b/libethdrivers/src/plat/am335x/lwiplib.h
@@ -1,4 +1,4 @@
-/* @TAG(CUSTOM) */
+/* SPDX-License-Identifier: BSD-3-Clause */
 
 /**
 *  \file lwiplib.h
diff --git a/libethdrivers/src/plat/am335x/mdio.c b/libethdrivers/src/plat/am335x/mdio.c
index 26f24e6..c1fdd36 100644
--- a/libethdrivers/src/plat/am335x/mdio.c
+++ b/libethdrivers/src/plat/am335x/mdio.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libethdrivers/src/plat/am335x/phy.c b/libethdrivers/src/plat/am335x/phy.c
index 518aaec..4f030c8 100644
--- a/libethdrivers/src/plat/am335x/phy.c
+++ b/libethdrivers/src/plat/am335x/phy.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libethdrivers/src/plat/imx6/enet.c b/libethdrivers/src/plat/imx6/enet.c
index 2207447..1dc1f98 100644
--- a/libethdrivers/src/plat/imx6/enet.c
+++ b/libethdrivers/src/plat/imx6/enet.c
@@ -1,33 +1,22 @@
 /*
  * Copyright 2017, NXP
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #include "enet.h"
-#include <stdint.h>
-#include <assert.h>
 #include "io.h"
 #include <platsupport/clock.h>
 #include "unimplemented.h"
 #include "../../debug.h"
+
+#include <stdint.h>
 #include <stdlib.h>
+#include <assert.h>
 
-#ifdef CONFIG_PLAT_IMX6
-#define IMX6_ENET_PADDR 0x02188000
-#define IMX6_ENET_SIZE  0x00004000
-#endif
 #ifdef CONFIG_PLAT_IMX8MQ_EVK
-#define IMX6_ENET_PADDR 0x30be0000
-#define IMX6_ENET_SIZE  0x10000
-
 #define CCM_PADDR 0x30380000
 #define CCM_SIZE 0x10000
 #endif
@@ -177,15 +166,15 @@
     uint32_t tccr3;  /* 624 Timer Compare Capture Register */
 };
 
-struct enet {
-    void *dummy;
-};
-
 typedef volatile struct enet_regs enet_regs_t;
 
+struct enet {
+    enet_regs_t regs;
+};
+
 static inline enet_regs_t *enet_get_regs(struct enet *enet)
 {
-    return (enet_regs_t *)enet;
+    return &(enet->regs);
 }
 
 /* Ethernet control register */
@@ -261,6 +250,7 @@
 #define PHYOP_REG_SHIFT       18
 #define PHYOP_DATA_SHIFT       0
 
+
 /******************
  *** MDIO clock ***
  ******************/
@@ -295,8 +285,7 @@
     }
 
     regs->mscr = v << 1;
-    CLK_DEBUG(printf("Set MDC frequency to %.1f Mhz (<= 2.5 Mhz)\n",
-                     (float)clk_get_freq(clk) / MHZ));
+    ZF_LOGD("Set MDC frequency to %u Hz (<= 2.5 Mhz)", clk_get_freq(clk));
     return clk_get_freq(clk);
 }
 
@@ -324,7 +313,9 @@
     .child = NULL,
 };
 
+
 #ifdef CONFIG_PLAT_IMX8MQ_EVK
+
 static freq_t _enet_clk_get_freq(clk_t *clk)
 {
     return clk->req_freq;
@@ -343,8 +334,10 @@
     .sibling = NULL,
     .child = NULL,
 };
+
 #endif
 
+
 void enet_set_speed(struct enet *enet, int speed, int full_duplex)
 {
     enet_regs_t *regs = enet_get_regs(enet);
@@ -368,7 +361,7 @@
         rcr |= RCR_RMII_10T;
         break;
     default:
-        printf("Invalid speed\n");
+        ZF_LOGE("Invalid speed");
         assert(0);
         return;
     }
@@ -404,7 +397,8 @@
     return readl(&regs->mmfr) & 0xffff;
 }
 
-int enet_mdio_write(struct enet *enet, uint16_t phy, uint16_t reg, uint16_t data)
+int enet_mdio_write(struct enet *enet, uint16_t phy, uint16_t reg,
+                    uint16_t data)
 {
     enet_regs_t *regs = enet_get_regs(enet);
     uint32_t v;
@@ -422,6 +416,7 @@
 /*******************
  *** ENET driver ***
  *******************/
+
 void enet_rx_enable(struct enet *enet)
 {
     enet_get_regs(enet)->rdar = RDAR_RDAR;
@@ -461,26 +456,33 @@
     regs->ecr &= ~ECR_ETHEREN;
 }
 
-void enet_set_mac(struct enet *enet, unsigned char *mac)
+void enet_set_mac(struct enet *enet, uint64_t mac)
 {
     enet_regs_t *regs = enet_get_regs(enet);
-    regs->palr = mac[0] << 24 | mac[1] << 16 | mac[2] << 8 | mac[3] << 0;
-    regs->paur = mac[4] << 24 | mac[5] << 16 | PAUSE_FRAME_TYPE_FIELD;
+    /* We get the MAC as uint64_t, the value 0x0000<aa><bb><cc><dd><ee><ff>
+     * corresponds to the MAC aa:bb:cc:dd:ee:ff. The registers are set up as
+     *   PALR = 0x<aa><bb><cc><dd>
+     *            MAC byte 0 in bits 31:24
+     *            MAC byte 1 in bits 23:16
+     *            MAC byte 2 in bits 15:8
+     *            MAC byte 3 in bits 7:0
+     *   PAUR = 0x<ee><ff><xxxx>
+     *            MAC byte 4 in bits 31:24
+     *            MAC byte 5 in bits 23:16
+     */
+    regs->palr = (uint32_t)(mac >> 16);
+    regs->paur = (((uint32_t)mac & 0xffff) << 16) | PAUSE_FRAME_TYPE_FIELD;
 }
 
-void enet_get_mac(struct enet *enet, unsigned char *mac)
+uint64_t enet_get_mac(struct enet *enet)
 {
     enet_regs_t *regs = enet_get_regs(enet);
-    uint32_t macl = regs->palr;
-    uint32_t macu = regs->paur;
-
-    /* set MAC hardware address */
-    mac[0] = macl >> 24;
-    mac[1] = macl >> 16;
-    mac[2] = macl >>  8;
-    mac[3] = macl >>  0;
-    mac[4] = macu >> 24;
-    mac[5] = macu >> 16;
+    /* The MAC aa:bb:cc:dd:ee:ff is stored in
+     *   PALR = 0x<aa><bb><cc><dd>
+     *   PAUR = 0x<ee><ff><xxxx>
+     * We return it as uint64_t 0x0000<aa><bb><cc><dd><ee><ff>
+     */
+    return (((uint64_t)regs->palr) << 16) | (regs->paur >> 16);
 }
 
 void enet_enable_events(struct enet *enet, uint32_t mask)
@@ -515,19 +517,30 @@
     regs->rcr &= ~RCR_PROM;
 }
 
-struct enet *
-enet_init(struct desc_data desc_data, ps_io_ops_t *io_ops)
+void enet_crc_strip_enable(struct enet *enet)
 {
-    enet_regs_t *regs;
-    struct enet *ret;
+    enet_regs_t *regs = enet_get_regs(enet);
+    regs->rcr |= RCR_CRCSTRIP;
+}
+
+void enet_crc_strip_disable(struct enet *enet)
+{
+    enet_regs_t *regs = enet_get_regs(enet);
+    regs->rcr &= ~RCR_CRCSTRIP;
+}
+
+struct enet *enet_init(void *mapped_peripheral, uintptr_t tx_phys,
+                       uintptr_t rx_phys, size_t rx_bufsize, uint64_t mac,
+                       ps_io_ops_t *io_ops)
+{
+    assert(mapped_peripheral);
+
     struct clock *enet_clk_ptr = NULL;
 
-    /* Map in the device */
-    regs = RESOURCE(&io_ops->io_mapper, IMX6_ENET);
-    if (regs == NULL) {
-        return NULL;
-    }
-    ret = (struct enet *)regs;
+    /* The enet device is simply the register mapping */
+    struct enet *enet = (struct enet *)mapped_peripheral;
+    enet_regs_t *regs = enet_get_regs(enet);
+
     /* Perform reset */
     regs->ecr = ECR_RESET;
     while (regs->ecr & ECR_RESET);
@@ -537,18 +550,21 @@
     regs->eimr = 0x00000000;
     regs->eir  = 0xffffffff;
 
-#ifdef CONFIG_PLAT_IMX6
+#if defined(CONFIG_PLAT_IMX6)
+
     /* Set the ethernet clock frequency */
     clock_sys_t *clk_sys = malloc(sizeof(clock_sys_t));
     clock_sys_init(io_ops, clk_sys);
     enet_clk_ptr = clk_get_clock(clk_sys, CLK_ENET);
     clk_set_freq(enet_clk_ptr, ENET_FREQ);
-#endif
-#ifdef CONFIG_PLAT_IMX8MQ_EVK
+
+#elif defined(CONFIG_PLAT_IMX8MQ_EVK)
+
     enet_clk_ptr = &enet_clk;
     // TODO Implement an actual clock driver for the imx8mq
     void *clock_base = RESOURCE(&io_ops->io_mapper, CCM);
     if (!clock_base) {
+        ZF_LOGE("clock controller could not be mapped");
         return NULL;
     }
 
@@ -573,15 +589,16 @@
     /* Ungate the clocks now */
     *ccgr_enet_set = 0x3;
     *ccgr_sim_enet_set = 0x3;
+
 #endif
 
     /* Set the MDIO clock frequency */
-    mdc_clk.priv = (void *)enet_get_regs(ret);
+    mdc_clk.priv = (void *)regs;
     clk_register_child(enet_clk_ptr, &mdc_clk);
     clk_set_freq(&mdc_clk, MDC_FREQ);
 
     /* Clear out MIB */
-    enet_clear_mib(ret);
+    enet_clear_mib(enet);
 
     /* Descriptor group and individual hash tables - Not changed on reset */
     regs->iaur = 0;
@@ -590,7 +607,7 @@
     regs->galr = 0;
 
     /* Set MAC and pause frame type field */
-    enet_set_mac(ret, (unsigned char *)"\0\0\0\0\0\0");
+    enet_set_mac(enet, mac);
 
     /* Configure pause frames (continues into MAC registers...) */
     regs->opd = PAUSE_OPCODE_FIELD << 16;
@@ -602,7 +619,7 @@
 
     /* TX inter-packet gap */
     regs->tipg = TIPG;
-    /* Tranmsmit FIFO Watermark register - store and forward */
+    /* Transmit FIFO Watermark register - store and forward */
     regs->tfwr = 0;
 #ifdef STRFWD_BYTES
     if (STRFWD_BYTES > 0) {
@@ -615,17 +632,16 @@
     regs->racc = RACC_LINEDIS;
 
     /* DMA descriptors */
-    regs->tdsr = desc_data.tx_phys;
-    regs->rdsr = desc_data.rx_phys;
-    regs->mrbr = desc_data.rx_bufsize;
+    regs->tdsr = (uint32_t)tx_phys;
+    regs->rdsr = (uint32_t)rx_phys;
+    regs->mrbr = (uint32_t)rx_bufsize;
 
     /* Receive control - Set frame length and RGMII mode */
     regs->rcr = RCR_MAX_FL(FRAME_LEN) | RCR_RGMII_EN | RCR_MII_MODE;
     /* Transmit control - Full duplex mode */
     regs->tcr = TCR_FDEN;
 
-    /* Setup the control path to the phy */
-    return ret;
+    return enet;
 }
 
 /****************************
@@ -634,11 +650,10 @@
 
 static void dump_regs(uint32_t *start, int size)
 {
-    int i, j;
     uint32_t *base = start;
-    for (i = 0; i < size / sizeof(*start);) {
+    for (unsigned int i = 0; i < size / sizeof(*start);) {
         printf("+0x%03x: ", ((uint32_t)(start - base)) * 4);
-        for (j = 0; j < 4; j++, i++, start++) {
+        for (unsigned int j = 0; j < 4; j++, i++, start++) {
             printf("0x%08x ", *start);
         }
         printf("\n");
diff --git a/libethdrivers/src/plat/imx6/enet.h b/libethdrivers/src/plat/imx6/enet.h
index 1db7e66..d836fde 100644
--- a/libethdrivers/src/plat/imx6/enet.h
+++ b/libethdrivers/src/plat/imx6/enet.h
@@ -1,13 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #pragma once
@@ -34,48 +29,50 @@
 
 struct enet;
 
+struct enet *enet_init(
+    void *mapped_peripheral,
+    uintptr_t tx_phys,
+    uintptr_t rx_phys,
+    size_t rx_bufsize,
+    uint64_t mac,
+    ps_io_ops_t *io_ops);
+
 /* Debug */
-void enet_dump_regs(struct enet* enet);
-void enet_clear_mib(struct enet* enet);
-void enet_print_mib(struct enet* enet);
-
-struct desc_data {
-    uint32_t tx_phys;
-    uint32_t rx_phys;
-    uint32_t rx_bufsize;
-};
-
-struct enet * enet_init(struct desc_data desc_data, ps_io_ops_t *io_ops);
+void enet_dump_regs(struct enet *enet);
+void enet_clear_mib(struct enet *enet);
+void enet_print_mib(struct enet *enet);
+void enet_print_state(struct enet *enet);
 
 /* Read and write to the phy over the mdio interface */
-int enet_mdio_read(struct enet * enet, uint16_t phy, uint16_t reg);
-int enet_mdio_write(struct enet * enet, uint16_t phy, uint16_t reg, uint16_t data);
+int enet_mdio_read(struct enet *enet, uint16_t phy, uint16_t reg);
+int enet_mdio_write(struct enet *enet, uint16_t phy, uint16_t reg, uint16_t data);
 
-void enet_enable(struct enet* enet);
-int enet_enabled(struct enet* enet);
-void enet_disable(struct enet* enet);
+void enet_enable(struct enet *enet);
+void enet_disable(struct enet *enet);
+int enet_enabled(struct enet *enet);
 
-void enet_set_mac(struct enet* enet, unsigned char* mac);
-void enet_get_mac(struct enet* enet, unsigned char* mac);
+void enet_set_mac(struct enet *enet, uint64_t mac);
+uint64_t enet_get_mac(struct enet *enet);
 
-void enet_set_speed(struct enet* enet, int speed, int full_duplex);
+void enet_set_speed(struct enet *enet, int speed, int full_duplex);
+
 /* Clears ievents and returns the original value - before the clear */
-uint32_t enet_clr_events(struct enet* enet, uint32_t clr_bits);
+uint32_t enet_clr_events(struct enet *enet, uint32_t clr_bits);
 /* Sets the event mask */
-void enet_enable_events(struct enet* enet, uint32_t mask_bits);
+void enet_enable_events(struct enet *enet, uint32_t mask_bits);
 /* Returns the value of ievents */
-uint32_t enet_get_events(struct enet* enet);
+uint32_t enet_get_events(struct enet *enet);
 
-void enet_tx_enable(struct enet* enet);
-int enet_tx_enabled(struct enet* enet);
-void enet_rx_enable(struct enet* enet);
-int enet_rx_enabled(struct enet* enet);
+void enet_tx_enable(struct enet *enet);
+int enet_tx_enabled(struct enet *enet);
 
-void enet_set_mdcclk(struct enet * enet, uint32_t fout);
+void enet_rx_enable(struct enet *enet);
+int enet_rx_enabled(struct enet *enet);
+
+void enet_set_mdcclk(struct enet *enet, uint32_t fout);
 uint32_t enet_get_mdcclk(struct enet *imx_eth);
 
-void enet_print_state(struct enet * enet);
-
-void enet_prom_enable(struct enet * enet);
-void enet_prom_disable(struct enet * enet);
-
+void enet_prom_enable(struct enet  *enet);
+void enet_prom_disable(struct enet *enet);
+void enet_crc_strip_enable(struct enet *enet);
+void enet_crc_strip_disable(struct enet *enet);
diff --git a/libethdrivers/src/plat/imx6/imx6.c b/libethdrivers/src/plat/imx6/imx6.c
index 069ace4..9cd257f 100644
--- a/libethdrivers/src/plat/imx6/imx6.c
+++ b/libethdrivers/src/plat/imx6/imx6.c
@@ -1,14 +1,9 @@
 /*
  * Copyright 2017, DornerWorks
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #include <platsupport/driver_module.h>
@@ -17,20 +12,20 @@
 #include <ethdrivers/imx6.h>
 #include <ethdrivers/raw.h>
 #include <ethdrivers/helpers.h>
+#include <ethdrivers/plat/eth_plat.h>
 #include <string.h>
 #include <utils/util.h>
 #include "enet.h"
 #include "ocotp_ctrl.h"
 #include "uboot/fec_mxc.h"
 #include "uboot/miiphy.h"
-#include "uboot/mx6qsabrelite.h"
+#include "uboot/imx_board.h"
 #include "uboot/micrel.h"
 #include "unimplemented.h"
 
-#define DEFAULT_MAC "\x00\x19\xb8\x00\xf0\xa3"
-
-#define BUF_SIZE MAX_PKT_SIZE
-#define DMA_ALIGN 32
+#define IRQ_MASK    (NETIRQ_RXF | NETIRQ_TXF | NETIRQ_EBERR)
+#define BUF_SIZE    MAX_PKT_SIZE
+#define DMA_ALIGN   32
 
 struct descriptor {
     /* NOTE: little endian packing: len before stat */
@@ -46,25 +41,28 @@
     uint32_t phys;
 };
 
-struct imx6_eth_data {
-    struct enet *enet;
-    uintptr_t tx_ring_phys;
-    uintptr_t rx_ring_phys;
-    volatile struct descriptor *tx_ring;
-    volatile struct descriptor *rx_ring;
-    unsigned int rx_size;
-    unsigned int tx_size;
-    void **rx_cookies;                   // Array (of rx_size elements) of type 'void *'
-    unsigned int rx_remain;
-    unsigned int tx_remain;
-    void **tx_cookies;
-    unsigned int *tx_lengths;
-    /* track where the head and tail of the queues are for
-     * enqueueing buffers / checking for completions */
-    unsigned int rdt, rdh, tdt, tdh;
-};
+typedef struct {
+    unsigned int cnt;
+    unsigned int remain;
+    unsigned int tail;
+    unsigned int head;
+    volatile struct descriptor *descr;
+    uintptr_t phys;
+    void **cookies; /* Array with tx/tx size elements of type 'void *' */
+} ring_ctx_t;
 
-int setup_iomux_enet(ps_io_ops_t *io_ops);
+
+/* we basically extend 'struct eth_driver' here */
+typedef struct {
+    struct eth_driver eth_drv;
+    void *mapped_peripheral;
+    irq_id_t irq_id;
+    struct enet *enet;
+    struct phy_device *phy;
+    ring_ctx_t tx;
+    ring_ctx_t rx;
+    unsigned int *tx_lengths;
+} imx6_eth_driver_t;
 
 /* Receive descriptor status */
 #define RXD_EMPTY     BIT(15) /* Buffer has no data. Waiting for reception. */
@@ -93,267 +91,482 @@
 #define TXD_ADDCRC    BIT(10) /* Append a CRC to the end of the frame */
 #define TXD_ADDBADCRC BIT( 9) /* Append a bad CRC to the end of the frame */
 
-static void low_level_init(struct eth_driver *driver, uint8_t *mac, int *mtu)
+static imx6_eth_driver_t *imx6_eth_driver(struct eth_driver *driver)
 {
-    struct imx6_eth_data *dev = (struct imx6_eth_data *)driver->eth_data;
-    enet_get_mac(dev->enet, mac);
-    *mtu = MAX_PKT_SIZE;
+    assert(driver);
+
+    /* we have simply extended the structure */
+    assert(driver == driver->eth_data);
+    return (imx6_eth_driver_t *)driver;
 }
 
-static void fill_rx_bufs(struct eth_driver *driver)
+struct enet *get_enet_from_driver(struct eth_driver *driver)
 {
-    struct imx6_eth_data *dev = (struct imx6_eth_data *)driver->eth_data;
-    __sync_synchronize();
-    while (dev->rx_remain > 0) {
-        /* request a buffer */
-        void *cookie = NULL;
-        int next_rdt = (dev->rdt + 1) % dev->rx_size;
+    assert(driver);
 
-        // This fn ptr is either lwip_allocate_rx_buf or lwip_pbuf_allocate_rx_buf (in src/lwip.c)
-        uintptr_t phys = driver->i_cb.allocate_rx_buf? driver->i_cb.allocate_rx_buf(driver->cb_cookie, BUF_SIZE, &cookie): 0;
-        if (!phys) {
-            // NOTE: This condition could happen if
-            //       CONFIG_LIB_ETHDRIVER_NUM_PREALLOCATED_BUFFERS < CONFIG_LIB_ETHDRIVER_RX_DESC_COUNT
-            break;
-        }
-
-        dev->rx_cookies[dev->rdt] = cookie;
-        dev->rx_ring[dev->rdt].phys = phys;
-        dev->rx_ring[dev->rdt].len = 0;
-
-        __sync_synchronize();
-        dev->rx_ring[dev->rdt].stat = RXD_EMPTY | (next_rdt == 0 ? RXD_WRAP : 0);
-        dev->rdt = next_rdt;
-        dev->rx_remain--;
-    }
-    __sync_synchronize();
-    if (dev->rdt != dev->rdh && !enet_rx_enabled(dev->enet)) {
-        enet_rx_enable(dev->enet);
-    }
+    imx6_eth_driver_t *dev = imx6_eth_driver(driver);
+    assert(dev);
+    return dev->enet;
 }
 
-static void enable_interrupts(struct imx6_eth_data *dev)
+static void get_mac(struct eth_driver *driver, uint8_t *mac)
 {
+    assert(driver);
+    assert(mac);
+
+    imx6_eth_driver_t *dev = imx6_eth_driver(driver);
+    assert(dev);
     struct enet *enet = dev->enet;
     assert(enet);
-    enet_enable_events(enet, 0);
-    enet_clr_events(enet, (uint32_t) ~(NETIRQ_RXF | NETIRQ_TXF | NETIRQ_EBERR));
-    enet_enable_events(enet, (uint32_t) NETIRQ_RXF | NETIRQ_TXF | NETIRQ_EBERR);
+
+    uint64_t mac_u64 = enet_get_mac(enet);
+    /* MAC is big endian u64, 0x0000aabbccddeeff means aa:bb:cc:dd:ee:ff */
+    for (unsigned int i = 0; i < 6; i++) {
+        mac[5 - i] = (uint8_t)mac_u64;
+        mac_u64 >>= 8;
+    }
 }
 
-static void free_desc_ring(struct imx6_eth_data *dev, ps_dma_man_t *dma_man)
+static void low_level_init(struct eth_driver *driver, uint8_t *mac, int *mtu)
 {
-    if (dev->rx_ring) {
-        dma_unpin_free(dma_man, (void *)dev->rx_ring, sizeof(struct descriptor) * dev->rx_size);
-        dev->rx_ring = NULL;
+    assert(driver);
+
+    if (mac) {
+        get_mac(driver, mac);
     }
-    if (dev->tx_ring) {
-        dma_unpin_free(dma_man, (void *)dev->tx_ring, sizeof(struct descriptor) * dev->tx_size);
-        dev->tx_ring = NULL;
+
+    if (mtu) {
+        *mtu = MAX_PKT_SIZE;
     }
-    if (dev->rx_cookies) {
-        free(dev->rx_cookies);
-        dev->rx_cookies = NULL;
+}
+
+static void update_ring_slot(
+    ring_ctx_t *ring,
+    unsigned int idx,
+    uintptr_t phys,
+    uint16_t len,
+    uint16_t stat)
+{
+    volatile struct descriptor *d = &(ring->descr[idx]);
+    d->phys = phys;
+    d->len = len;
+
+    /* Ensure all writes to the descriptor complete, before we set the flags
+     * that makes hardware aware of this slot.
+     */
+    __sync_synchronize();
+
+    d->stat = stat;
+}
+
+static void fill_rx_bufs(imx6_eth_driver_t *dev)
+{
+    assert(dev);
+
+    ring_ctx_t *ring = &(dev->rx);
+
+    void *cb_cookie = dev->eth_drv.cb_cookie;
+    ethif_raw_allocate_rx_buf cb_alloc = dev->eth_drv.i_cb.allocate_rx_buf;
+    if (!cb_alloc) {
+        /* The function may not be set up (yet), in this case we can't do
+         * anything. If lwip is used, this can be either lwip_allocate_rx_buf()
+         * or lwip_pbuf_allocate_rx_buf() from src/lwip.c
+         */
+        ZF_LOGW("callback allocate_rx_buf not set, can't allocate %d buffers",
+                ring->remain);
+    } else {
+        __sync_synchronize();
+        while (ring->remain > 0) {
+            /* request a buffer */
+            void *cookie = NULL;
+            uintptr_t phys = cb_alloc(cb_cookie, BUF_SIZE, &cookie);
+            if (!phys) {
+                /* There are no buffers left. This can happen if the pool is too
+                 * small because CONFIG_LIB_ETHDRIVER_NUM_PREALLOCATED_BUFFERS
+                 * is less than CONFIG_LIB_ETHDRIVER_RX_DESC_COUNT.
+                 */
+                break;
+            }
+            uint16_t stat = RXD_EMPTY;
+            int idx = ring->tail;
+            int new_tail = idx + 1;
+            if (new_tail == ring->cnt) {
+                new_tail = 0;
+                stat |= RXD_WRAP;
+            }
+            ring->cookies[idx] = cookie;
+            update_ring_slot(ring, idx, phys, 0, stat);
+            ring->tail = new_tail;
+            /* There is a race condition if add/remove is not synchronized. */
+            ring->remain--;
+        }
+        __sync_synchronize();
     }
-    if (dev->tx_cookies) {
-        free(dev->tx_cookies);
-        dev->tx_cookies = NULL;
+
+    if (ring->tail != ring->head) {
+        struct enet *enet = dev->enet;
+        assert(enet);
+        if (!enet_rx_enabled(enet)) {
+            enet_rx_enable(enet);
+        }
     }
+}
+
+static void free_desc_ring(imx6_eth_driver_t *dev)
+{
+    assert(dev);
+
+    ps_dma_man_t *dma_man = &(dev->eth_drv.io_ops.dma_manager);
+    assert(dma_man);
+
+    if (dev->rx.descr) {
+        dma_unpin_free(
+            dma_man,
+            (void *)dev->rx.descr,
+            sizeof(struct descriptor) * dev->rx.cnt);
+        dev->rx.descr = NULL;
+    }
+
+    if (dev->tx.descr) {
+        dma_unpin_free(
+            dma_man,
+            (void *)dev->tx.descr,
+            sizeof(struct descriptor) * dev->tx.cnt);
+        dev->tx.descr = NULL;
+    }
+
+    ps_malloc_ops_t *malloc_ops = &(dev->eth_drv.io_ops.malloc_ops);
+    assert(malloc_ops);
+
+    if (dev->rx.cookies) {
+        ps_free(
+            malloc_ops,
+            sizeof(void *) * dev->rx.cnt,
+            dev->rx.cookies);
+        dev->rx.cookies = NULL;
+    }
+
+    if (dev->tx.cookies) {
+        ps_free(
+            malloc_ops,
+            sizeof(void *) * dev->tx.cnt,
+            dev->tx.cookies);
+        dev->tx.cookies = NULL;
+    }
+
     if (dev->tx_lengths) {
-        free(dev->tx_lengths);
+        ps_free(
+            malloc_ops,
+            sizeof(void *) * dev->tx.cnt,
+            dev->tx_lengths);
         dev->tx_lengths = NULL;
     }
 }
 
-static int initialize_desc_ring(struct imx6_eth_data *dev, ps_dma_man_t *dma_man)
+static int setup_desc_ring(imx6_eth_driver_t *dev, ring_ctx_t *ring)
 {
-    dma_addr_t rx_ring = dma_alloc_pin(dma_man, sizeof(struct descriptor) * dev->rx_size, 0, DMA_ALIGN);
-    if (!rx_ring.phys) {
-        LOG_ERROR("Failed to allocate rx_ring");
-        return -1;
-    }
-    dev->rx_ring = rx_ring.virt;
-    dev->rx_ring_phys = rx_ring.phys;
-    dma_addr_t tx_ring = dma_alloc_pin(dma_man, sizeof(struct descriptor) * dev->tx_size, 0, DMA_ALIGN);
-    if (!tx_ring.phys) {
-        LOG_ERROR("Failed to allocate tx_ring");
-        free_desc_ring(dev, dma_man);
-        return -1;
-    }
-    ps_dma_cache_clean_invalidate(dma_man, rx_ring.virt, sizeof(struct descriptor) * dev->rx_size);
-    ps_dma_cache_clean_invalidate(dma_man, tx_ring.virt, sizeof(struct descriptor) * dev->tx_size);
-    dev->rx_cookies = malloc(sizeof(void *) * dev->rx_size);
-    dev->tx_cookies = malloc(sizeof(void *) * dev->tx_size);
-    dev->tx_lengths = malloc(sizeof(unsigned int) * dev->tx_size);
-    if (!dev->rx_cookies || !dev->tx_cookies || !dev->tx_lengths) {
-        if (dev->rx_cookies) {
-            free(dev->rx_cookies);
-        }
-        if (dev->tx_cookies) {
-            free(dev->tx_cookies);
-        }
-        if (dev->tx_lengths) {
-            free(dev->tx_lengths);
-        }
-        LOG_ERROR("Failed to malloc");
-        free_desc_ring(dev, dma_man);
-        return -1;
-    }
-    dev->tx_ring = tx_ring.virt;
-    dev->tx_ring_phys = tx_ring.phys;
-    /* Remaining needs to be 2 less than size as we cannot actually enqueue size many descriptors,
-     * since then the head and tail pointers would be equal, indicating empty. */
-    dev->rx_remain = dev->rx_size - 2;
-    dev->tx_remain = dev->tx_size - 2;
+    assert(dev);
+    assert(ring);
 
-    dev->rdt = dev->rdh = dev->tdt = dev->tdh = 0;
+    /* caller should have zeroed the ring context already.
+     *   memset(ring, 0, sizeof(*ring));
+     */
 
-    /* zero both rings */
-    for (unsigned int i = 0; i < dev->tx_size; i++) {
-        dev->tx_ring[i] = (struct descriptor) {
-            .phys = 0,
-            .len = 0,
-            .stat = (i + 1 == dev->tx_size) ? TXD_WRAP : 0
-        };
+    size_t size = sizeof(struct descriptor) * ring->cnt;
+
+    /* allocate uncached memory, function will also clean an invalidate cache
+     * to for the area internally to save us from surprises
+     */
+    ps_dma_man_t *dma_man = &(dev->eth_drv.io_ops.dma_manager);
+    assert(dma_man);
+    dma_addr_t dma = dma_alloc_pin(
+                         dma_man,
+                         size,
+                         0, // uncached
+                         dev->eth_drv.dma_alignment);
+    if (!dma.phys || !dma.virt) {
+        ZF_LOGE("Faild to allocate %d bytes of DMA memory", size);
+        return -1;
     }
-    for (unsigned int i = 0; i < dev->rx_size; i++) {
-        dev->rx_ring[i] = (struct descriptor) {
-            .phys = 0,
-            .len = 0,
-            .stat = (i + 1 == dev->rx_size) ? RXD_WRAP : 0
-        };
+
+    ZF_LOGE("dma_alloc_pin: %x -> %p, %d descriptors, %d bytes",
+            dma.phys, dma.virt, ring->cnt, size);
+
+    /* zero ring */
+    memset(dma.virt, 0, size);
+
+    ring->phys = dma.phys;
+    ring->descr = dma.virt;
+
+    assert(ring->cnt >= 2);
+    ring->descr[ring->cnt - 1].stat = TXD_WRAP;
+    /* Remaining needs to be 2 less than size as we cannot actually enqueue
+     * size many descriptors, since then the head and tail pointers would be
+     * equal, indicating empty.
+     */
+    ring->remain = ring->cnt - 2;
+
+    ring->tail = 0;
+    ring->head = 0;
+
+    /* allocate and zero memory for cookies */
+    ps_malloc_ops_t *malloc_ops = &(dev->eth_drv.io_ops.malloc_ops);
+    assert(malloc_ops);
+    int ret = ps_calloc(
+                  malloc_ops,
+                  ring->cnt,
+                  sizeof(void *),
+                  (void **) &ring->cookies);
+    if (ret) {
+        ZF_LOGE("Failed to malloc, code %d", ret);
+        return -1;
     }
+
+    /* Ensure operation propagate, so DMA is really set up. */
     __sync_synchronize();
 
     return 0;
 }
 
-static void complete_rx(struct eth_driver *eth_driver)
+static void complete_rx(imx6_eth_driver_t *dev)
 {
-    struct imx6_eth_data *dev = (struct imx6_eth_data *)eth_driver->eth_data;
-    unsigned int rdt = dev->rdt;
-    while (dev->rdh != rdt) {
-        unsigned int status = dev->rx_ring[dev->rdh].stat;
-        /* Ensure no memory references get ordered before we checked the descriptor was written back */
-        __sync_synchronize();
-        if (status & RXD_EMPTY) {
-            /* not complete yet */
+    assert(dev);
+
+    void *cb_cookie = dev->eth_drv.cb_cookie;
+    ethif_raw_rx_complete cb_complete = dev->eth_drv.i_cb.rx_complete;
+    assert(cb_complete);
+
+    ring_ctx_t *ring = &(dev->rx);
+    unsigned int head = ring->head;
+
+    /* Release all descriptors that have data. */
+    while (head != ring->tail) {
+
+        /* The NIC hardware can modify the descriptor any time, 'volatile'
+         * prevents the compiler's optimizer from caching values and enforces
+         * every access happen as stated in the code.
+         */
+        volatile struct descriptor *d = &(ring->descr[head]);
+
+        /* If the slot is still marked as empty we are done. */
+        if (d->stat & RXD_EMPTY) {
+            assert(dev->enet);
+            if (!enet_rx_enabled(dev->enet)) {
+                enet_rx_enable(dev->enet);
+            }
             break;
         }
-        void *cookie = dev->rx_cookies[dev->rdh];
-        unsigned int len = dev->rx_ring[dev->rdh].len;
-        /* update rdh */
-        dev->rdh = (dev->rdh + 1) % dev->rx_size;
-        dev->rx_remain++;
-        /* Give the buffers back */
-        eth_driver->i_cb.rx_complete(eth_driver->cb_cookie, 1, &cookie, &len);
-    }
-    if (dev->rdt != dev->rdh && !enet_rx_enabled(dev->enet)) {
-        enet_rx_enable(dev->enet);
+
+        void *cookie = ring->cookies[head];
+        /* Go to next buffer, handle roll-over. */
+        if (++head == ring->cnt) {
+            head = 0;
+        }
+        ring->head = head;
+
+        /* There is a race condition here if add/remove is not synchronized. */
+        ring->remain++;
+
+        /* Tell the driver it can return the DMA buffer to the pool. */
+        unsigned int len = d->len;
+        cb_complete(cb_cookie, 1, &cookie, &len);
     }
 }
 
-static void complete_tx(struct eth_driver *driver)
+static void complete_tx(imx6_eth_driver_t *dev)
 {
-    struct imx6_eth_data *dev = (struct imx6_eth_data *)driver->eth_data;
-    while (dev->tdh != dev->tdt) {
-        unsigned int i;
-        for (i = 0; i < dev->tx_lengths[dev->tdh]; i++) {
-            if (dev->tx_ring[(i + dev->tdh) % dev->tx_size].stat & TXD_READY) {
-                /* not all parts complete */
+    assert(dev);
+
+    void *cb_cookie = dev->eth_drv.cb_cookie;
+    ethif_raw_tx_complete cb_complete = dev->eth_drv.i_cb.tx_complete;
+    assert(cb_complete);
+
+    unsigned int cnt_org;
+    void *cookie;
+    ring_ctx_t *ring = &(dev->tx);
+    unsigned int head = ring->head;
+    unsigned int cnt = 0;
+
+    while (head != ring->tail) {
+
+        if (0 == cnt) {
+            cnt = dev->tx_lengths[head];
+            if ((0 == cnt) || (cnt > dev->tx.cnt)) {
+                /* We are not supposed to read 0 here. */
+                ZF_LOGE("complete_tx with cnt=%u at head %u", cnt, head);
                 return;
             }
+            cnt_org = cnt;
+            cookie = ring->cookies[head];
         }
-        /* do not let memory loads happen before our checking of the descriptor write back */
-        __sync_synchronize();
-        /* increase where we believe tdh to be */
-        void *cookie = dev->tx_cookies[dev->tdh];
-        dev->tx_remain += dev->tx_lengths[dev->tdh];
-        dev->tdh = (dev->tdh + dev->tx_lengths[dev->tdh]) % dev->tx_size;
-        /* give the buffer back */
-        driver->i_cb.tx_complete(driver->cb_cookie, cookie);
+
+        /* The NIC hardware can modify the descriptor any time, 'volatile'
+         * prevents the compiler's optimizer from caching values and enforces
+         * every access happens as stated in the code.
+         */
+        volatile struct descriptor *d = &(ring->descr[head]);
+
+        /* If this buffer was not sent, we can't release any buffer. */
+        if (d->stat & TXD_READY) {
+            assert(dev->enet);
+            if (!enet_tx_enabled(dev->enet)) {
+                enet_tx_enable(dev->enet);
+            }
+            return;
+        }
+
+        /* Go to next buffer, handle roll-over. */
+        if (++head == dev->tx.cnt) {
+            head = 0;
+        }
+
+        if (0 == --cnt) {
+            ring->head = head;
+            /* race condition if add/remove is not synchronized. */
+            ring->remain += cnt_org;
+            /* give the buffer back */
+            cb_complete(cb_cookie, cookie);
+        }
+
     }
-    if (dev->tdh != dev->tdt && !enet_tx_enabled(dev->enet)) {
-        enet_tx_enable(dev->enet);
+
+    /* The only reason to arrive here is when head equals tails. If cnt is not
+     * zero, then there is some kind of overflow or data corruption. The number
+     * of tx descriptors holding data can't exceed the space in the ring.
+     */
+    if (0 != cnt) {
+        ZF_LOGE("head at %u reached tail, but cnt=%u", head, cnt);
+        assert(0);
     }
 }
 
-static void print_state(struct eth_driver *eth_driver)
+static void print_state(struct eth_driver *driver)
 {
-    struct imx6_eth_data *eth_data = (struct imx6_eth_data *)eth_driver->eth_data;
-    enet_print_mib(eth_data->enet);
+    assert(driver);
+
+    imx6_eth_driver_t *dev = imx6_eth_driver(driver);
+    struct enet *enet = dev->enet;
+    assert(enet);
+
+    enet_print_mib(enet);
 }
 
 static void handle_irq(struct eth_driver *driver, int irq)
 {
-    struct imx6_eth_data *eth_data = (struct imx6_eth_data *)driver->eth_data;
-    struct enet *enet = eth_data->enet;
-    uint32_t e;
-    e = enet_clr_events(enet, NETIRQ_RXF | NETIRQ_TXF | NETIRQ_EBERR);
+    assert(driver);
+
+    imx6_eth_driver_t *dev = imx6_eth_driver(driver);
+    assert(dev);
+    struct enet *enet = dev->enet;
+    assert(enet);
+
+    uint32_t e = enet_clr_events(enet, IRQ_MASK);
     if (e & NETIRQ_TXF) {
-        complete_tx(driver);
+        complete_tx(dev);
     }
     if (e & NETIRQ_RXF) {
-        complete_rx(driver);
-        fill_rx_bufs(driver);
+        complete_rx(dev);
+        fill_rx_bufs(dev);
     }
     if (e & NETIRQ_EBERR) {
-        printf("Error: System bus/uDMA\n");
-        //ethif_print_state(netif_get_eth_driver(netif));
+        ZF_LOGE("Error: System bus/uDMA");
+        // ethif_print_state(netif_get_eth_driver(netif));
         assert(0);
         while (1);
     }
 }
 
 /* This is a platsuport IRQ interface IRQ handler wrapper for handle_irq() */
-static void eth_irq_handle(void *data, ps_irq_acknowledge_fn_t acknowledge_fn, void *ack_data)
+static void eth_irq_handle(void *ctx, ps_irq_acknowledge_fn_t acknowledge_fn,
+                           void *ack_data)
 {
-    ZF_LOGF_IF(data == NULL, "Passed in NULL for the data");
-    struct eth_driver *driver = data;
+    if (!ctx) {
+        ZF_LOGE("IRQ handler got ctx=NULL");
+        assert(0);
+        return;
+    }
+
+    struct eth_driver *driver = (struct eth_driver *)ctx;
 
     /* handle_irq doesn't really expect an IRQ number */
     handle_irq(driver, 0);
 
-    int error = acknowledge_fn(ack_data);
-    if (error) {
-        LOG_ERROR("Failed to acknowledge the Ethernet device's IRQ");
+    int ret = acknowledge_fn(ack_data);
+    if (ret) {
+        ZF_LOGE("Failed to acknowledge the Ethernet device's IRQ, code %d", ret);
     }
 }
 
 static void raw_poll(struct eth_driver *driver)
 {
-    complete_rx(driver);
-    complete_tx(driver);
-    fill_rx_bufs(driver);
+    assert(driver);
+
+    imx6_eth_driver_t *dev = imx6_eth_driver(driver);
+    assert(dev);
+
+    // TODO: If the interrupts are still enabled, there could be race here. The
+    //       caller must ensure this can't happen.
+    complete_rx(dev);
+    complete_tx(dev);
+    fill_rx_bufs(dev);
 }
 
-static int raw_tx(struct eth_driver *driver, unsigned int num, uintptr_t *phys, unsigned int *len, void *cookie)
+static int raw_tx(struct eth_driver *driver, unsigned int num, uintptr_t *phys,
+                  unsigned int *len, void *cookie)
 {
-    struct imx6_eth_data *dev = (struct imx6_eth_data *)driver->eth_data;
-    struct enet *enet = dev->enet;
+    if (0 == num) {
+        ZF_LOGW("raw_tx() called with num=0");
+        return ETHIF_TX_ENQUEUED;
+    }
+
+    assert(driver);
+
+    imx6_eth_driver_t *dev = imx6_eth_driver(driver);
+    assert(dev);
+
+    ring_ctx_t *ring = &(dev->tx);
+
     /* Ensure we have room */
-    if (dev->tx_remain < num) {
-        /* try and complete some */
-        complete_tx(driver);
-        if (dev->tx_remain < num) {
+    if (ring->remain < num) {
+        /* not enough room, try to complete some and check again */
+        complete_tx(dev);
+        unsigned int rem = ring->remain;
+        if (rem < num) {
+            ZF_LOGE("TX queue lacks space, has %d, need %d", rem, num);
             return ETHIF_TX_FAILED;
         }
     }
-    unsigned int i;
+
     __sync_synchronize();
-    for (i = 0; i < num; i++) {
-        unsigned int ring = (dev->tdt + i) % dev->tx_size;
-        dev->tx_ring[ring].len = len[i];
-        dev->tx_ring[ring].phys = phys[i];
-        __sync_synchronize();
-        dev->tx_ring[ring].stat = TXD_READY | (ring + 1 == dev->tx_size ? TXD_WRAP : 0) | (i + 1 == num ? TXD_ADDCRC |
-                                                                                           TXD_LAST : 0);
+
+    unsigned int tail = ring->tail;
+    unsigned int tail_new = tail;
+
+    unsigned int i = num;
+    while (i-- > 0) {
+        uint16_t stat = TXD_READY;
+        if (0 == i) {
+            stat |= TXD_ADDCRC | TXD_LAST;
+        }
+
+        unsigned int idx = tail_new;
+        if (++tail_new == dev->tx.cnt) {
+            tail_new = 0;
+            stat |= TXD_WRAP;
+        }
+        update_ring_slot(ring, idx, *phys++, *len++, stat);
     }
-    dev->tx_cookies[dev->tdt] = cookie;
-    dev->tx_lengths[dev->tdt] = num;
-    dev->tdt = (dev->tdt + num) % dev->tx_size;
-    dev->tx_remain -= num;
+
+    ring->cookies[tail] = cookie;
+    dev->tx_lengths[tail] = num;
+    ring->tail = tail_new;
+    /* There is a race condition here if add/remove is not synchronized. */
+    ring->remain -= num;
+
     __sync_synchronize();
+
+    struct enet *enet = dev->enet;
+    assert(enet);
     if (!enet_tx_enabled(enet)) {
         enet_tx_enable(enet);
     }
@@ -361,160 +574,270 @@
     return ETHIF_TX_ENQUEUED;
 }
 
-static void get_mac(struct eth_driver *driver, uint8_t *mac)
+static uint64_t obtain_mac(const nic_config_t *nic_config,
+                           ps_io_mapper_t *io_mapper)
 {
-    struct enet *enet = ((struct imx6_eth_data *)driver->eth_data)->enet;
-    enet_get_mac(enet, (unsigned char *)mac);
+    unsigned int enet_id = nic_config ? nic_config->id : 0;
+    uint64_t cfg_mac = nic_config ? nic_config->mac : 0;
+    unsigned int doForceMac = nic_config && (nic_config->flags & NIC_CONFIG_FORCE_MAC);
+
+    if (doForceMac && (0 != cfg_mac)) {
+        ZF_LOGI("config: overwriting default MAC");
+        return cfg_mac;
+    }
+
+    struct ocotp *ocotp = ocotp_init(io_mapper);
+    if (!ocotp) {
+        ZF_LOGE("Failed to initialize OCOTP to read MAC");
+    } else {
+        uint64_t ocotp_mac = ocotp_get_mac(ocotp, enet_id);
+        ocotp_free(ocotp, io_mapper);
+        if (0 != ocotp_mac) {
+            ZF_LOGI("taking MAC #%u from OCOTP", enet_id);
+            return ocotp_mac;
+        }
+
+#ifdef CONFIG_PLAT_IMX6SX
+
+        if (1 == enet_id) {
+            ZF_LOGI("IMX6SX: no MAC for enet2 in OCOTP, use enet1 MAC + 1");
+            ocotp_mac = ocotp_get_mac(ocotp, 0);
+            if (0 != ocotp_mac) {
+                /* The uint64_t is 0x0000<aa><bb><cc><dd><ee><ff> for the MAC
+                 * aa:bb:cc:dd:ee:ff, where aa:bb:cc is the OUI and dd:ee:ff is
+                 * and ID. Leave OUI as it is and increment the ID by one with
+                 * roll over handling.
+                 */
+                uint32_t oui = ocotp_mac >> 24;
+                uint32_t id = ocotp_mac & 0xffffff;
+                return ((uint64_t)oui << 24) | ((id + 1) & 0xffffff);
+            }
+
+            ZF_LOGI("IMX6SX: no MAC for enet1 in OCOTP");
+        }
+
+#endif /* CONFIG_PLAT_IMX6SX */
+
+    }
+
+    /* no MAC from OCOTP, try using MAC config */
+    if (0 != cfg_mac) {
+        ZF_LOGI("no MAC in OCOTP, taking MAC from config");
+        return cfg_mac;
+    }
+
+    ZF_LOGE("Failed to get MAC from OCOTP or config");
+    return 0;
 }
 
-static struct raw_iface_funcs iface_fns = {
-    .raw_handleIRQ = handle_irq,
-    .print_state = print_state,
-    .low_level_init = low_level_init,
-    .raw_tx = raw_tx,
-    .raw_poll = raw_poll,
-    .get_mac = get_mac
-};
-
-int ethif_imx6_init(struct eth_driver *eth_driver, ps_io_ops_t io_ops, void *config)
+static int init_device(imx6_eth_driver_t *dev, const nic_config_t *nic_config)
 {
-    struct ocotp *ocotp = NULL;
-    int err;
-    struct enet *enet;
-    struct imx6_eth_data *eth_data = NULL;
-    uint8_t mac[6];
+    assert(dev);
 
-    if (config == NULL) {
-        LOG_ERROR("Cannot get platform info; Passed in Config Pointer NULL");
+    int ret;
+
+    uint64_t mac = obtain_mac(nic_config, &(dev->eth_drv.io_ops.io_mapper));
+    if (0 == mac) {
+        ZF_LOGE("Failed to obtain a MAC");
+        return -1;
+    }
+
+    ZF_LOGI("using MAC: %02x:%02x:%02x:%02x:%02x:%02x",
+            (uint8_t)(mac >> 40),
+            (uint8_t)(mac >> 32),
+            (uint8_t)(mac >> 24),
+            (uint8_t)(mac >> 16),
+            (uint8_t)(mac >> 8),
+            (uint8_t)(mac));
+
+    ret = setup_desc_ring(dev, &(dev->rx));
+    if (ret) {
+        ZF_LOGE("Failed to allocate rx_ring, code %d", ret);
         goto error;
     }
 
-    struct arm_eth_plat_config *plat_config = (struct arm_eth_plat_config *)config;
-
-    eth_data = (struct imx6_eth_data *)malloc(sizeof(struct imx6_eth_data));
-    if (eth_data == NULL) {
-        LOG_ERROR("Failed to allocate eth data struct");
+    ret = setup_desc_ring(dev, &(dev->tx));
+    if (ret) {
+        ZF_LOGE("Failed to allocate tx_ring, code %d", ret);
         goto error;
     }
 
-    eth_data->tx_size = CONFIG_LIB_ETHDRIVER_RX_DESC_COUNT;
-    eth_data->rx_size = CONFIG_LIB_ETHDRIVER_TX_DESC_COUNT;
-    eth_driver->eth_data = eth_data;
-    eth_driver->dma_alignment = DMA_ALIGN;
-    eth_driver->i_fn = iface_fns;
-
-    err = initialize_desc_ring(eth_data, &io_ops.dma_manager);
-    if (err) {
-        LOG_ERROR("Failed to allocate descriptor rings");
+    ps_malloc_ops_t *malloc_ops = &(dev->eth_drv.io_ops.malloc_ops);
+    assert(malloc_ops);
+    ret = ps_calloc(
+              malloc_ops,
+              dev->tx.cnt,
+              sizeof(unsigned int),
+              (void **)&dev->tx_lengths);
+    if (ret) {
+        ZF_LOGE("Failed to malloc, code %d", ret);
         goto error;
     }
+    /* ring got allocated, need to free it on error */
+
+    unsigned int enet_id = nic_config ? nic_config->id : 0;
+
+    /* Initialise ethernet pins, also does a PHY reset */
+    if (0 != enet_id) {
+        ZF_LOGI("skipping IOMUX setup for ENET id=%d", enet_id);
+    } else {
+        ret = setup_iomux_enet(&(dev->eth_drv.io_ops));
+        if (ret) {
+            ZF_LOGE("Failed to setup IOMUX for ENET id=%d, code %d",
+                    enet_id, ret);
+            goto error;
+        }
+    }
 
-    /* initialise the eFuse controller so we can get a MAC address */
-    ocotp = ocotp_init(&io_ops.io_mapper);
-    if (!ocotp) {
-        LOG_ERROR("Failed to initialize ocotp");
-        goto error;
-    }
-    /* Initialise ethernet pins */
-    err = setup_iomux_enet(&io_ops);
-    if (err) {
-        LOG_ERROR("Failed to setup iomux enet");
-        goto error;
-    }
-    /* Initialise the phy library */
-    miiphy_init();
-    /* Initialise the phy */
-    phy_micrel_init();
-    /* Initialise the RGMII interface */
-    enet = enet_init((struct desc_data) {
-        .tx_phys = eth_data->tx_ring_phys, .rx_phys = eth_data->rx_ring_phys, .rx_bufsize = BUF_SIZE
-    }, &io_ops);
-    if (!enet) {
-        LOG_ERROR("Failed to initialize RGMII");
+    /* Initialise the RGMII interface, clears and masks all interrupts */
+    dev->enet = enet_init(
+                    dev->mapped_peripheral,
+                    dev->tx.phys,
+                    dev->rx.phys,
+                    BUF_SIZE,
+                    mac,
+                    &(dev->eth_drv.io_ops));
+    if (!dev->enet) {
+        ZF_LOGE("Failed to initialize RGMII");
         /* currently no way to properly clean up enet */
         assert(!"enet cannot be cleaned up");
         goto error;
     }
-    eth_data->enet = enet;
 
-    if (plat_config->prom_mode) {
-        enet_prom_enable(enet);
+    /* Remove CRC (FCS) from ethernet frames when passing it to upper layers,
+     * because the NIC hardware would discard frames with an invalid checksum
+     * anyway by default. Usually, there not much practical gain in keeping it.
+     */
+    bool do_strip_crc = nic_config &&
+                        (nic_config->flags & NIC_CONFIG_DROP_FRAME_CRC);
+    ZF_LOGI("config: CRC stripping %s", do_strip_crc ? "ON" : "OFF");
+    if (do_strip_crc) {
+        enet_crc_strip_enable(dev->enet);
     } else {
-        enet_prom_disable(enet);
+        enet_crc_strip_disable(dev->enet);
     }
 
-    if (ocotp == NULL || ocotp_get_mac(ocotp, mac)) {
-        memcpy(mac, DEFAULT_MAC, 6);
+    /* Non-Promiscuous mode means that only traffic relevant for us is made
+     * visible by the hardware, everything else is discarded automatically. We
+     * will only see packets addressed to our MAC and broadcast/multicast
+     * packets. This is usually all that is needed unless the upper layer
+     * implements functionality beyond a "normal" application scope, e.g.
+     * switching or monitoring.
+     */
+    bool do_promiscuous_mode = nic_config &&
+                               (nic_config->flags & NIC_CONFIG_PROMISCUOUS_MODE);
+    ZF_LOGI("config: promiscuous mode %s", do_promiscuous_mode ? "ON" : "OFF");
+    if (do_promiscuous_mode) {
+        enet_prom_enable(dev->enet);
+    } else {
+        enet_prom_disable(dev->enet);
     }
 
-    enet_set_mac(enet, mac);
+    /* Initialise the phy library */
+    miiphy_init();
+    /* Initialise the phy */
+#if defined(CONFIG_PLAT_SABRE) || defined(CONFIG_PLAT_WANDQ)
+    phy_micrel_init();
+#elif defined(CONFIG_PLAT_NITROGEN6SX)
+    phy_atheros_init();
+#else
+#error "unsupported board"
+#endif
 
     /* Connect the phy to the ethernet controller */
-    unsigned phy_mask = 0xffffffff;
-    if (fec_init(phy_mask, enet)) {
-        LOG_ERROR("Failed to initialize fec");
+    unsigned int phy_mask = 0xffffffff;
+    if (nic_config && (0 != nic_config->phy_address)) {
+        ZF_LOGI("config: using PHY at address %d", nic_config->phy_address);
+        phy_mask = BIT(nic_config->phy_address);
+    }
+    /* ENET1 has an MDIO interface, for ENET2 we use callbacks */
+    dev->phy = fec_init(
+                   phy_mask,
+                   (0 == enet_id) ? dev->enet : NULL,
+                   nic_config);
+    if (!dev->phy) {
+        ZF_LOGE("Failed to initialize fec");
         goto error;
     }
 
-    /* Start the controller */
-    enet_enable(enet);
+    enet_set_speed(
+        dev->enet,
+        dev->phy->speed,
+        (dev->phy->duplex == DUPLEX_FULL) ? 1 : 0);
 
-    fill_rx_bufs(eth_driver);
-    enable_interrupts(eth_data);
+    ZF_LOGI("Link speed: %d Mbps, %s-duplex",
+            dev->phy->speed,
+            (dev->phy->duplex == DUPLEX_FULL) ? "full" : "half");
+
+    /* Start the controller, all interrupts are still masked here */
+    enet_enable(dev->enet);
+
+    /* This could also enable receiving, so the controller must be enabled. */
+    fill_rx_bufs(dev);
+
+    /* Ensure no unused interrupts are pending. */
+    enet_clr_events(dev->enet, ~((uint32_t)IRQ_MASK));
+
+    /* Enable interrupts for the events we care about. This unmask them, some
+     * could already be pending here and trigger immediately.
+     */
+    enet_enable_events(dev->enet, IRQ_MASK);
 
     /* done */
     return 0;
+
 error:
-    if (ocotp) {
-        ocotp_free(ocotp, &io_ops.io_mapper);
-    }
-    if (eth_data) {
-        free(eth_data);
-    }
-    free_desc_ring(eth_data, &io_ops.dma_manager);
+    /* ToDo: free dev->phydev if set */
+    free_desc_ring(dev);
     return -1;
 }
 
-typedef struct {
-    void *addr;
-    ps_io_ops_t *io_ops;
-    struct eth_driver *eth_driver;
-    int irq_id;
-} callback_args_t;
-
-static int allocate_register_callback(pmem_region_t pmem, unsigned curr_num, size_t num_regs, void *token)
+static int allocate_register_callback(pmem_region_t pmem, unsigned curr_num,
+                                      size_t num_regs, void *token)
 {
-    if (token == NULL) {
-        ZF_LOGE("Expected a token!");
-        return -EINVAL;
+    assert(token);
+    imx6_eth_driver_t *dev = (imx6_eth_driver_t *)token;
+
+    /* we support only one peripheral, ignore others gracefully */
+    if (curr_num != 0) {
+        ZF_LOGW("Ignoring peripheral register bank #%d at 0x%"PRIx64,
+                curr_num, pmem.base_addr);
+        return 0;
     }
 
-    callback_args_t *args = token;
-    if (curr_num == 0) {
-        args->addr = ps_pmem_map(args->io_ops, pmem, false, PS_MEM_NORMAL);
-        if (!args->addr) {
-            ZF_LOGE("Failed to map the Ethernet device");
-            return -EIO;
-        }
+    dev->mapped_peripheral = ps_pmem_map(
+                                 &(dev->eth_drv.io_ops),
+                                 pmem,
+                                 false,
+                                 PS_MEM_NORMAL);
+    if (!dev->mapped_peripheral) {
+        ZF_LOGE("Failed to map the Ethernet device");
+        return -EIO;
     }
 
     return 0;
 }
 
-static int allocate_irq_callback(ps_irq_t irq, unsigned curr_num, size_t num_irqs, void *token)
+static int allocate_irq_callback(ps_irq_t irq, unsigned curr_num,
+                                 size_t num_irqs, void *token)
 {
-    if (token == NULL) {
-        ZF_LOGE("Expected a token!");
-        return -EINVAL;
+    assert(token);
+    imx6_eth_driver_t *dev = (imx6_eth_driver_t *)token;
+
+    unsigned target_num = config_set(CONFIG_PLAT_IMX8MQ_EVK) ? 2 : 0;
+    if (curr_num != target_num) {
+        ZF_LOGW("Ignoring interrupt #%d with value %d", curr_num, irq);
+        return 0;
     }
 
-    callback_args_t *args = token;
-    if (curr_num == 0) {
-        args->irq_id = ps_irq_register(&args->io_ops->irq_ops, irq, eth_irq_handle, args->eth_driver);
-        if (args->irq_id < 0) {
-            ZF_LOGE("Failed to register the Ethernet device's IRQ");
-            return -EIO;
-        }
+    dev->irq_id = ps_irq_register(
+                      &(dev->eth_drv.io_ops.irq_ops),
+                      irq,
+                      eth_irq_handle,
+                      dev);
+    if (dev->irq_id < 0) {
+        ZF_LOGE("Failed to register the Ethernet device's IRQ");
+        return -EIO;
     }
 
     return 0;
@@ -522,60 +845,137 @@
 
 int ethif_imx_init_module(ps_io_ops_t *io_ops, const char *device_path)
 {
-    struct arm_eth_plat_config plat_config;
-    struct eth_driver *eth_driver;
+    int ret;
+    imx6_eth_driver_t *driver = NULL;
 
-    int error = ps_calloc(&io_ops->malloc_ops, 1, sizeof(*eth_driver), (void **) &eth_driver);
-    if (error) {
-        ZF_LOGE("Failed to allocate memory for the Ethernet driver");
-        return -ENOMEM;
+    /* get a configuration if function is implemented */
+    const nic_config_t *nic_config = NULL;
+    if (get_nic_configuration) {
+        ZF_LOGI("calling get_nic_configuration()");
+        /* we can get NULL here, if somebody implements this function but does
+         * not give us a config. It's a bit odd, but valid.
+         */
+        nic_config = get_nic_configuration();
+        if (nic_config && nic_config->funcs.sync) {
+            ZF_LOGI("Waiting for primary NIC to finish initialization");
+            ret = nic_config->funcs.sync();
+            if (ret) {
+                ZF_LOGE("pirmary NIC sync failed,  code %d", ret);
+                return -ENODEV;
+            }
+            ZF_LOGI("primary NIC init done, run secondary NIC init");
+        }
     }
 
+    ret = ps_calloc(
+              &io_ops->malloc_ops,
+              1,
+              sizeof(*driver),
+              (void **) &driver);
+    if (ret) {
+        ZF_LOGE("Failed to allocate memory for the Ethernet driver, code %d", ret);
+        ret = -ENOMEM;
+        goto error;
+    }
+
+    driver->eth_drv.i_fn = (struct raw_iface_funcs) {
+        .raw_handleIRQ   = handle_irq,
+        .print_state     = print_state,
+        .low_level_init  = low_level_init,
+        .raw_tx          = raw_tx,
+        .raw_poll        = raw_poll,
+        .get_mac         = get_mac
+    };
+
+    driver->eth_drv.eth_data = driver; /* use simply extend the structure */
+    driver->eth_drv.io_ops = *io_ops;
+    driver->eth_drv.dma_alignment = DMA_ALIGN;
+    driver->tx.cnt = CONFIG_LIB_ETHDRIVER_TX_DESC_COUNT;
+    driver->rx.cnt = CONFIG_LIB_ETHDRIVER_RX_DESC_COUNT;
+
     ps_fdt_cookie_t *cookie = NULL;
-    callback_args_t args = { .io_ops = io_ops, .eth_driver = eth_driver };
-    error = ps_fdt_read_path(&io_ops->io_fdt, &io_ops->malloc_ops, device_path, &cookie);
-    if (error) {
-        ZF_LOGE("Failed to read the path of the Ethernet device");
-        return -ENODEV;
+    ret = ps_fdt_read_path(
+              &io_ops->io_fdt,
+              &io_ops->malloc_ops,
+              device_path,
+              &cookie);
+    if (ret) {
+        ZF_LOGE("Failed to read the path of the Ethernet device, code %d", ret);
+        ret = -ENODEV;
+        goto error;
     }
 
-    error = ps_fdt_walk_registers(&io_ops->io_fdt, cookie, allocate_register_callback, &args);
-    if (error) {
-        ZF_LOGE("Failed to walk the Ethernet device's registers and allocate them");
-        return -ENODEV;
+    ret = ps_fdt_walk_registers(
+              &io_ops->io_fdt,
+              cookie,
+              allocate_register_callback,
+              driver);
+    if (ret) {
+        ZF_LOGE("Failed to walk the Ethernet device's registers and allocate them, code %d", ret);
+        ret = -ENODEV;
+        goto error;
     }
 
-    error = ps_fdt_walk_irqs(&io_ops->io_fdt, cookie, allocate_irq_callback, &args);
-    if (error) {
-        ZF_LOGE("Failed to walk the Ethernet device's IRQs and allocate them");
-        return -ENODEV;
+    ret = ps_fdt_walk_irqs(
+              &io_ops->io_fdt,
+              cookie,
+              allocate_irq_callback,
+              driver);
+    if (ret) {
+        ZF_LOGE("Failed to walk the Ethernet device's IRQs and allocate them, code %d", ret);
+        ret = -ENODEV;
+        goto error;
     }
 
-    error = ps_fdt_cleanup_cookie(&io_ops->malloc_ops, cookie);
-    if (error) {
-        ZF_LOGE("Failed to free the cookie used to allocate resources");
-        return -ENODEV;
+    ret = ps_fdt_cleanup_cookie(&io_ops->malloc_ops, cookie);
+    if (ret) {
+        ZF_LOGE("Failed to free the cookie used to allocate resources, code %d", ret);
+        ret = -ENODEV;
+        goto error;
     }
 
-    /* Setup the config and hand initialisation off to the proper
-     * initialisation method */
-    plat_config.buffer_addr = args.addr;
-    plat_config.prom_mode = 1;
-
-    error = ethif_imx6_init(eth_driver, *io_ops, &plat_config);
-    if (error) {
-        ZF_LOGE("Failed to initialise the Ethernet driver");
-        return -ENODEV;
+    ret = init_device(driver, nic_config);
+    if (ret) {
+        ZF_LOGE("Failed to initialise the Ethernet driver, code %d", ret);
+        ret = -ENODEV;
+        goto error;
     }
 
-    return ps_interface_register(&io_ops->interface_registration_ops, PS_ETHERNET_INTERFACE, eth_driver, NULL);
+    ret = ps_interface_register(
+              &io_ops->interface_registration_ops,
+              PS_ETHERNET_INTERFACE,
+              driver,
+              NULL);
+    if (ret) {
+        ZF_LOGE("Failed to register Ethernet driver interface, code %d", ret);
+        ret = -ENODEV;
+        goto error;
+    }
+
+    return 0;
+
+error:
+    ZF_LOGI("Cleaning up failed driver initialization");
+
+    if (driver) {
+        ps_free(&io_ops->malloc_ops, sizeof(*driver), driver);
+    }
+
+    return ret;
+
 }
 
 static const char *compatible_strings[] = {
     /* Other i.MX platforms may also be compatible but the platforms that have
-     * been tested are the SABRE Lite (i.MX6Quad) and i.MX8MQ Evaluation Kit */
+     * been tested are:
+     *   - SABRE Lite (i.MX6Quad)
+     *   - Nitrogen6_SoloX (i.MX6SoloX)
+     *   - i.MX8MQ Evaluation Kit
+     */
     "fsl,imx6q-fec",
+    "fsl,imx6sx-fec",
     "fsl,imx8mq-fec",
     NULL
 };
+
 PS_DRIVER_MODULE_DEFINE(imx_fec, compatible_strings, ethif_imx_init_module);
diff --git a/libethdrivers/src/plat/imx6/io.h b/libethdrivers/src/plat/imx6/io.h
index 0a9d6c9..548611f 100644
--- a/libethdrivers/src/plat/imx6/io.h
+++ b/libethdrivers/src/plat/imx6/io.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #pragma once
diff --git a/libethdrivers/src/plat/imx6/ocotp_ctrl.c b/libethdrivers/src/plat/imx6/ocotp_ctrl.c
index 7be5b45..9f4d46e 100644
--- a/libethdrivers/src/plat/imx6/ocotp_ctrl.c
+++ b/libethdrivers/src/plat/imx6/ocotp_ctrl.c
@@ -1,13 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 /* Author Alex Kroh */
@@ -22,15 +17,19 @@
  * CCM_CGR2[CG6]
  */
 
-#ifdef CONFIG_PLAT_IMX6
+#if defined(CONFIG_PLAT_IMX6)
+
 #define IMX6_OCOTP_PADDR   0x021BC000
 #define IMX6_OCOTP_SIZE    0x00004000
-#endif
-#ifdef CONFIG_PLAT_IMX8MQ_EVK
+
+#elif defined(CONFIG_PLAT_IMX8MQ_EVK)
+
 #define IMX6_OCOTP_PADDR   0x30350000
 #define IMX6_OCOTP_SIZE    0x00010000
+
 #endif
 
+
 #define TIMING_WAIT(x)       ((x) << 22)
 #define TIMING_SREAD(x)      ((x) << 16)
 #define TIMING_RELAX(x)      ((x) << 12)
@@ -143,7 +142,12 @@
     uint32_t res35[3];
     uint32_t mac1;            /* 630 */
     uint32_t res36[3];
+#ifdef CONFIG_PLAT_IMX6SX
+    uint32_t mac2;            /* 640 */
+    uint32_t res37[7];
+#else
     uint32_t res37[8];
+#endif
     uint32_t gp0;             /* 660 */
     uint32_t res38[3];
     uint32_t gp1;             /* 670 */
@@ -169,8 +173,7 @@
     return (ocotp_regs_t *)ocotp;
 }
 
-struct ocotp *
-ocotp_init(ps_io_mapper_t *io_mapper)
+struct ocotp *ocotp_init(ps_io_mapper_t *io_mapper)
 {
     return (struct ocotp *)RESOURCE(io_mapper, IMX6_OCOTP);
 }
@@ -180,26 +183,64 @@
     UNRESOURCE(io_mapper, IMX6_OCOTP, ocotp);
 }
 
-int ocotp_get_mac(struct ocotp *ocotp, unsigned char *mac)
+uint64_t ocotp_get_mac(struct ocotp *ocotp, unsigned int id)
 {
-    ocotp_regs_t *regs;
-    uint32_t mac0;
-    uint32_t mac1;
     assert(ocotp);
+    ocotp_regs_t *regs = ocotp_get_regs(ocotp);
 
-    regs = ocotp_get_regs(ocotp);
-    mac0 = regs->mac0;
-    mac1 = regs->mac1;
-    if (mac0 | mac1) {
-        mac[0] = (mac1 >>  8) & 0xff;
-        mac[1] = (mac1 >>  0) & 0xff;
+    /* i.MX6 dual/quad has one ENET device, i.MX6 Solo X has two. OCOTP usage
+     * is defined in the TRM as:
+     *     0x620 - 0x630[15:0]:   MAC1_ADDR
+     *     0x630[31:16] - 0x640:  MAC2_ADDR
+     * Which means if OCOTP was raw memory the MACs
+     *   ENET1: <aa>:<bb>:<cc>:<dd>:<ee>:<ff>
+     *   ENET2: <gg>:<hh>:<ii>:<jj>:<kk>:<ll>
+     * are stored as
+     *     0x620:  <ff> <ee> <dd> <cc>  xx xx xx xx  xx xx xx xx  xx xx xx xx
+     *     0x630:  <bb> <aa> <ll> <kk>  xx xx xx xx  xx xx xx xx  xx xx xx xx
+     *     0x640:  <jj> <ii> <hh> <gg>  xx xx xx xx  xx xx xx xx  xx xx xx xx
+     * Reading the OCOTP contents as little endian uint32_t gives
+     *     mac0 = 0x<cc><dd><ee><ff>
+     *     mac1 = 0x<kk><ll><aa><bb>
+     *     mac2 = 0x<gg><hh><ii><jj>
+     * We return the MAC as uint64_t
+     *     ENET1: 0x0000<aa><bb><cc><dd><ee><ff>
+     *     ENET2: 0x0000<gg><hh><ii><jj><kk><ll>
+     */
 
-        mac[2] = (mac0 >> 24) & 0xff;
-        mac[3] = (mac0 >> 16) & 0xff;
-        mac[4] = (mac0 >>  8) & 0xff;
-        mac[5] = (mac0 >>  0) & 0xff;
+    uint64_t mac = 0;
+
+    switch (id) {
+    case 0:
+        /* 0x0000<aa><bb><cc><dd><ee><ff> */
+        mac = ((uint64_t)((uint16_t)regs->mac1) << 32) | regs->mac0;
+        break;
+
+#ifdef CONFIG_PLAT_IMX6SX
+
+    case 1:
+        /* 0x0000<gg><hh><ii><jj><kk><ll> */
+        mac = ((uint64_t)regs->mac2 << 16) | (regs->mac1 >> 16);
+        break;
+
+#endif
+
+    default:
+        ZF_LOGE("Unsupported MAC ID %u", id);
         return 0;
-    } else {
-        return -1;
+
+    } /* switch (id) */
+
+    /* at least one bit must be set in the MAC to consider it valid */
+    if (0 == mac) {
+        ZF_LOGE("no MAC in OCOTP for id %d", id);
+        return 0;
     }
+
+    ZF_LOGI("OCOTP MAC #%u: %02x:%02x:%02x:%02x:%02x:%02x",
+            id, (uint8_t)(mac >> 40), (uint8_t)(mac >> 32),
+            (uint8_t)(mac >> 24), (uint8_t)(mac >> 16), (uint8_t)(mac >> 8),
+            (uint8_t)mac);
+
+    return mac;
 }
diff --git a/libethdrivers/src/plat/imx6/ocotp_ctrl.h b/libethdrivers/src/plat/imx6/ocotp_ctrl.h
index 9c2788d..b332902 100644
--- a/libethdrivers/src/plat/imx6/ocotp_ctrl.h
+++ b/libethdrivers/src/plat/imx6/ocotp_ctrl.h
@@ -1,13 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #pragma once
@@ -19,5 +14,4 @@
 struct ocotp *ocotp_init(ps_io_mapper_t *io_mapper);
 void ocotp_free(struct ocotp *ocotp, ps_io_mapper_t *io_mapper);
 
-int ocotp_get_mac(struct ocotp* ocotp, unsigned char *mac);
-
+uint64_t ocotp_get_mac(struct ocotp *ocotp, unsigned int id);
diff --git a/libethdrivers/src/plat/imx6/uboot/atheros.c b/libethdrivers/src/plat/imx6/uboot/atheros.c
new file mode 100644
index 0000000..fb44a72
--- /dev/null
+++ b/libethdrivers/src/plat/imx6/uboot/atheros.c
@@ -0,0 +1,114 @@
+/*
+ * Atheros PHY drivers
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ *
+ * Copyright 2011, 2013 Freescale Semiconductor, Inc.
+ * author Andy Fleming
+ * Copyright 2020, HENSOLDT Cyber GmbH
+ */
+
+#include "common.h"
+#include "phy.h"
+
+
+static int ar8021_config(struct phy_device *phydev)
+{
+    phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
+    phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x3D47);
+
+    phydev->supported = phydev->drv->features;
+    return 0;
+}
+
+static int ar8035_config(struct phy_device *phydev)
+{
+    int regval;
+
+    phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x0007);
+    phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x8016);
+    phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4007);
+
+    regval = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
+    phy_write(phydev, MDIO_DEVAD_NONE, 0xe, (regval | 0x0018));
+
+    phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
+
+    regval = phy_read(phydev, MDIO_DEVAD_NONE, 0x1e);
+    phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, (regval | 0x0100));
+
+    if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
+        (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) {
+        /* select debug reg 5 */
+        phy_write(phydev, MDIO_DEVAD_NONE, 0x1D, 0x5);
+        /* enable tx delay */
+        phy_write(phydev, MDIO_DEVAD_NONE, 0x1E, 0x0100);
+    }
+
+    if ((phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
+        (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID)) {
+        /* select debug reg 0 */
+        phy_write(phydev, MDIO_DEVAD_NONE, 0x1D, 0x0);
+        /* enable rx delay */
+        phy_write(phydev, MDIO_DEVAD_NONE, 0x1E, 0x8000);
+    }
+
+    unsigned ctrl1000 = 0;
+    unsigned features = phydev->drv->features;
+
+    if (features & SUPPORTED_1000baseT_Half) {
+        ctrl1000 |= ADVERTISE_1000HALF;
+
+    }
+
+    if (features & SUPPORTED_1000baseT_Full) {
+        ctrl1000 |= ADVERTISE_1000FULL;
+    }
+
+    phydev->advertising = phydev->supported = features;
+    phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000);
+    genphy_config_aneg(phydev);
+    genphy_restart_aneg(phydev);
+
+    return 0;
+}
+
+static struct phy_driver AR8021_driver =  {
+    .name = "AR8021",
+    .uid = 0x4dd040,
+    .mask = 0x4ffff0,
+    .features = PHY_GBIT_FEATURES,
+    .config = ar8021_config,
+    .startup = genphy_startup,
+    .shutdown = genphy_shutdown,
+};
+
+static struct phy_driver AR8031_driver =  {
+    .name = "AR8031/AR8033",
+    .uid = 0x4dd074,
+    .mask = 0xffffffef,
+    .features = PHY_GBIT_FEATURES,
+    .config = ar8035_config,
+    .startup = genphy_startup,
+    .shutdown = genphy_shutdown,
+};
+
+static struct phy_driver AR8035_driver =  {
+    .name = "AR8035",
+    .uid = 0x4dd072,
+    .mask = 0xffffffef,
+    .features = PHY_GBIT_FEATURES,
+    .config = ar8035_config,
+    .startup = genphy_startup,
+    .shutdown = genphy_shutdown,
+};
+
+int phy_atheros_init(void)
+{
+    // printf("Called phy_atheros_init()\n");
+    phy_register(&AR8021_driver);
+    phy_register(&AR8031_driver);
+    phy_register(&AR8035_driver);
+
+    return 0;
+}
diff --git a/libethdrivers/src/plat/imx6/uboot/bitops.h b/libethdrivers/src/plat/imx6/uboot/bitops.h
deleted file mode 100644
index 791fb04..0000000
--- a/libethdrivers/src/plat/imx6/uboot/bitops.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * @TAG(OTHER_GPL)
- */
-
-#pragma once
-
-#include "../unimplemented.h"
-
-/*
- * ffs: find first bit set. This is defined the same way as
- * the libc and compiler builtin ffs routines, therefore
- * differs in spirit from the above ffz (man ffs).
- */
-
-static inline int generic_ffs(int x)
-{
-	int r = 1;
-
-	if (!x)
-		return 0;
-	if (!(x & 0xffff)) {
-		x >>= 16;
-		r += 16;
-	}
-	if (!(x & 0xff)) {
-		x >>= 8;
-		r += 8;
-	}
-	if (!(x & 0xf)) {
-		x >>= 4;
-		r += 4;
-	}
-	if (!(x & 3)) {
-		x >>= 2;
-		r += 2;
-	}
-	if (!(x & 1)) {
-		x >>= 1;
-		r += 1;
-	}
-	return r;
-}
-
-#ifndef PLATFORM_FFS
-# define ffs generic_ffs
-#endif
diff --git a/libethdrivers/src/plat/imx6/uboot/common.h b/libethdrivers/src/plat/imx6/uboot/common.h
index 1ebc86a..3f6e300 100644
--- a/libethdrivers/src/plat/imx6/uboot/common.h
+++ b/libethdrivers/src/plat/imx6/uboot/common.h
@@ -1,13 +1,12 @@
 /*
- * @TAG(OTHER_GPL)
- */
-
-/*
- * (C) Copyright 2000-2009
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Common definition
  *
- * See file CREDITS for list of people who contributed to this
- * project.
+ * (C) Copyright 2000-2009 Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Copyright 2020, HENSOLDT Cyber GmbH
+ *
+ * See file U-Boot CREDITS for list of people who contributed to this project.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -16,7 +15,7 @@
  *
  * 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
+ * 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
@@ -24,60 +23,25 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
  */
+
 #pragma once
 
-#undef	_LINUX_CONFIG_H
-#define _LINUX_CONFIG_H 1	/* avoid reading Linux autoconf.h file	*/
-
+#include <autoconf.h>
+#include <utils/gen_config.h>
 #include <utils/arith.h>
-
-#include "mx6qsabrelite.h"
 #include "../unimplemented.h"
 
-#ifdef CONFIG_POST
-#define CONFIG_HAS_POST
-#ifndef CONFIG_POST_ALT_LIST
-#define CONFIG_POST_STD_LIST
-#endif
-#endif
+/* configuration */
+#define CONFIG_PHYLIB
 
-#ifdef CONFIG_INIT_CRITICAL
-#error CONFIG_INIT_CRITICAL is deprecated!
-#error Read section CONFIG_SKIP_LOWLEVEL_INIT in README.
-#endif
-
-#define roundup(x, y)		((((x) + ((y) - 1)) / (y)) * (y))
-
-#define __ALIGN_MASK(x,mask)	(((x)+(mask))&~(mask))
-
-#ifdef ETH_DEBUG
-#define _DEBUG	1
-#else
-#define _DEBUG	1
-#endif
-
-/*
- * Output a debug text when condition "cond" is met. The "cond" should be
- * computed by a preprocessor in the best case, allowing for the best
- * optimization.
- */
-#define debug_cond(cond, fmt, args...)		\
-	do {					\
-		if (cond)			\
-			printf(fmt, ##args);	\
-	} while (0)
-
-#define debug(fmt, args...)			\
-	debug_cond(_DEBUG, fmt, ##args)
 
 /**
  * container_of - cast a member of a structure out to the containing structure
- * @ptr:	the pointer to the member.
- * @type:	the type of the container struct this is embedded in.
- * @member:	the name of the member within the struct.
+ * @ptr:    the pointer to the member.
+ * @type:   the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
  *
  */
-#define container_of(ptr, type, member) ({			\
-	const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
-	(type *)( (char *)__mptr - offsetof(type,member) );})
-
+#define container_of(ptr, type, member) ({          \
+    const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+    (type *)( (char *)__mptr - offsetof(type,member) );})
diff --git a/libethdrivers/src/plat/imx6/uboot/config.h b/libethdrivers/src/plat/imx6/uboot/config.h
deleted file mode 100644
index 5a8b472..0000000
--- a/libethdrivers/src/plat/imx6/uboot/config.h
+++ /dev/null
@@ -1,7 +0,0 @@
-/*
- * @TAG(OTHER_GPL)
- */
-
-#pragma once
-
-#include "mx6qsabrelite.h"
diff --git a/libethdrivers/src/plat/imx6/uboot/ethtool.h b/libethdrivers/src/plat/imx6/uboot/ethtool.h
index 4d88e82..8ba0bfd 100644
--- a/libethdrivers/src/plat/imx6/uboot/ethtool.h
+++ b/libethdrivers/src/plat/imx6/uboot/ethtool.h
@@ -1,5 +1,5 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 /*
diff --git a/libethdrivers/src/plat/imx6/uboot/fec_mxc.c b/libethdrivers/src/plat/imx6/uboot/fec_mxc.c
index c06820a..fe724bb 100644
--- a/libethdrivers/src/plat/imx6/uboot/fec_mxc.c
+++ b/libethdrivers/src/plat/imx6/uboot/fec_mxc.c
@@ -1,14 +1,13 @@
 /*
- * @TAG(OTHER_GPL)
- */
-
-/*
  * (C) Copyright 2009 Ilya Yanok, Emcraft Systems Ltd <yanok@emcraft.com>
  * (C) Copyright 2008,2009 Eric Jarrige <eric.jarrige@armadeus.org>
  * (C) Copyright 2008 Armadeus Systems nc
  * (C) Copyright 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
  * (C) Copyright 2007 Pengutronix, Juergen Beisert <j.beisert@pengutronix.de>
  * (C) Copyright 2018, NXP
+ * (C) Copyright 2020, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -28,142 +27,191 @@
 
 #include "common.h"
 #include "miiphy.h"
-#include "fec_mxc.h"
-
-#include "imx-regs.h"
-#include "../io.h"
-
 #include "micrel.h"
+#include "fec_mxc.h"
+#include "../io.h"
+#include "../enet.h"
+#include "../ocotp_ctrl.h"
+#include <utils/attribute.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
-#include "../enet.h"
-#include "../ocotp_ctrl.h"
-/*
- * Timeout the transfer after 5 mS. This is usually a bit more, since
- * the code in the tightloops this timeout is used in adds some overhead.
- */
-#define FEC_XFER_TIMEOUT    5000
-
-#ifndef CONFIG_MII
-#error "CONFIG_MII has to be defined!"
-#endif
-
-#ifndef CONFIG_FEC_XCV_TYPE
-#define CONFIG_FEC_XCV_TYPE MII100
-#endif
 
 #undef DEBUG
 
-int fec_phy_read(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr)
+static int fec_phy_read(struct mii_dev *bus, int phyAddr, UNUSED int dev_addr,
+                        int regAddr)
 {
-    return enet_mdio_read((struct enet *)bus->priv, phyAddr, regAddr);
+    struct enet *enet = (struct enet *)bus->priv;
+    assert(enet);
+    return enet_mdio_read(enet, phyAddr, regAddr);
 }
 
-int fec_phy_write(struct mii_dev *bus, int phyAddr, int dev_addr, int regAddr,
-                  uint16_t data)
+static int fec_phy_write(struct mii_dev *bus, int phyAddr, UNUSED int dev_addr,
+                         int regAddr, uint16_t data)
 {
-    return enet_mdio_write((struct enet *)bus->priv, phyAddr, regAddr, data);
+    struct enet *enet = (struct enet *)bus->priv;
+    assert(enet);
+    return enet_mdio_write(enet, phyAddr, regAddr, data);
 }
 
-/**
- * Halt the FEC engine
- * @param[in] dev Our device to handle
- */
-void fec_halt(struct eth_device *dev)
+int cb_phy_read(
+    struct mii_dev *bus,
+    UNUSED int phyAddr,
+    UNUSED int dev_addr,
+    int regAddr)
 {
-#if 0
-    struct fec_priv *fec = (struct fec_priv *)dev->priv;
-    int counter = 0xffff;
-    /* issue graceful stop command to the FEC transmitter if necessary */
-    writel(FEC_TCNTRL_GTS | readl(&fec->eth->x_cntrl), &fec->eth->x_cntrl);
-    /* wait for graceful stop to register */
-    while ((counter--) && (!(readl(&fec->eth->ievent) & FEC_IEVENT_GRA))) {
-        udelay(1);
-    }
-    writel(readl(&fec->eth->ecntrl) & ~FEC_ECNTRL_ETHER_EN, &fec->eth->ecntrl);
-    fec->rbd_index = 0;
-    fec->tbd_index = 0;
-#else
-    assert(!"unimplemented");
-#endif
-}
-int fec_init(unsigned phy_mask, struct enet *enet)
-{
-    struct eth_device *edev;
-    struct phy_device *phydev;
-    struct mii_dev *bus;
-    int ret = 0;
-    struct eth_device _eth;
-    /* create and fill edev struct */
-    edev = &_eth;
-    memset(edev, 0, sizeof(*edev));
-
-    edev->priv = (void *)enet;
-    edev->write_hwaddr = NULL;
-
-    /* Alocate the mdio bus */
-    bus = mdio_alloc();
-    if (!bus) {
+    nic_config_t *nic_config = (nic_config_t *)bus->priv;
+    if ((!nic_config) || (!nic_config->funcs.mdio_read)) {
+        ZF_LOGE("mdio_read() from nic_config not set");
+        assert(nic_config); // we should never be here if nic_config is NULL
         return -1;
     }
-    bus->read = fec_phy_read;
-    bus->write = fec_phy_write;
-    bus->priv = enet;
-    strcpy(bus->name, edev->name);
+    return nic_config->funcs.mdio_read(regAddr);
+}
+
+int cb_phy_write(
+    struct mii_dev *bus,
+    UNUSED int phyAddr,
+    UNUSED int dev_addr,
+    int regAddr,
+    uint16_t data)
+{
+    nic_config_t *nic_config = (nic_config_t *)bus->priv;
+    if ((!nic_config) || (!nic_config->funcs.mdio_write)) {
+        ZF_LOGE("mdio_write() from nic_config not set");
+        assert(nic_config); // we should never be here if nic_config is NULL
+        return -1;
+    }
+
+    return nic_config->funcs.mdio_write(regAddr, data);
+}
+
+/*
+ * Halting the FEC engine could can be done with:
+ *   issue graceful stop command
+ *      writel(FEC_TCNTRL_GTS | readl(eth->x_cntrl), eth->x_cntrl);
+ *   wait (with timeout) for graceful stop to register
+ *      counter = 0xffff
+ *      while ((counter--) && (!(readl(eth->ievent) & FEC_IEVENT_GRA))) {
+ *         udelay(1);
+ *      }
+ *   issue disable command and clerar FEV
+ *      writel(readl(eth->ecntrl) & ~FEC_ECNTRL_ETHER_EN, eth->ecntrl);
+ *      fec->rbd_index = 0;
+ *      fec->tbd_index = 0;
+ */
+
+struct phy_device *fec_init(unsigned int phy_mask, struct enet *enet,
+                            const nic_config_t *nic_config)
+{
+    int ret;
+
+    /* Allocate the mdio bus */
+    struct mii_dev *bus = mdio_alloc();
+    if (!bus) {
+        ZF_LOGE("Could not allocate MDIO");
+        return NULL;
+    }
+
+#ifdef CONFIG_PLAT_IMX6SX
+    // on the i.MX6 SoloX Nitrogen board, both PHYs are connected to enet1's
+    // MDIO, while enet2's MDIO pins are used for other I/O purposes.
+    strncpy(bus->name, "MDIO-ENET1", sizeof(bus->name));
+#else
+    strncpy(bus->name, "MDIO", sizeof(bus->name));
+#endif
+
+    /* if we don't have direct access to MDIO, use the callbacks from config */
+    if (!enet && !nic_config) {
+        ZF_LOGE("Neither ENET nor nic_config is set, can't access MDIO");
+        free(bus);
+        return NULL;
+    }
+
+    bus->priv = enet ? enet : (struct enet *)nic_config;
+    bus->read = enet ? fec_phy_read : cb_phy_read;
+    bus->write = enet ? fec_phy_write : cb_phy_write;
+
     ret = mdio_register(bus);
     if (ret) {
+        ZF_LOGE("Could not register MDIO, code %d", ret);
         free(bus);
-        return -1;
+        return NULL;
     }
 
-    /****** Configure phy ******/
-    phydev = phy_connect_by_mask(bus, phy_mask, edev, PHY_INTERFACE_MODE_RGMII);
+    /* Configure PHY with a dummy edev, because it is never used. All that
+     * happens is that the name is printed */
+    static struct eth_device dummy_eth_dev = { .name = "DUMMY-EDEV" };
+    struct phy_device *phydev = phy_connect_by_mask(
+                                    bus,
+                                    phy_mask,
+                                    &dummy_eth_dev,
+                                    PHY_INTERFACE_MODE_RGMII);
     if (!phydev) {
-        return -1;
+        ZF_LOGE("Could not connect to PHY");
+        return NULL;
     }
 
-    if (config_set(CONFIG_PLAT_IMX8MQ_EVK)) {
-        /* enable rgmii rxc skew and phy mode select to RGMII copper */
-        phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f);
-        phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8);
-        phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
-        phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
+#if defined(CONFIG_PLAT_IMX8MQ_EVK)
 
-        if (phydev->drv->config) {
-            phydev->drv->config(phydev);
-        }
+    /* enable rgmii rxc skew and phy mode select to RGMII copper */
+    phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f);
+    phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8);
+    phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05);
+    phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100);
 
-        if (phydev->drv->startup) {
-            phydev->drv->startup(phydev);
-        }
-    } else if (config_set(CONFIG_PLAT_IMX6)) {
+#elif defined(CONFIG_PLAT_SABRE)
+
+    if (0x00221610 == (phydev->phy_id & 0xfffffff0)) { /* ignore silicon rev */
         /* min rx data delay */
         ksz9021_phy_extended_write(phydev, MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0);
         /* min tx data delay */
         ksz9021_phy_extended_write(phydev, MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, 0x0);
         /* max rx/tx clock delay, min rx/tx control */
         ksz9021_phy_extended_write(phydev, MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0xf0f0);
-        ksz9021_config(phydev);
-
-        /* Start up the PHY */
-        ret = ksz9021_startup(phydev);
-        if (ret) {
-            printf("Could not initialize PHY %s\n", phydev->dev->name);
-            return ret;
-        }
-
-    }
-
-    printf("\n  * Link speed: %4i Mbps, ", phydev->speed);
-    if (phydev->duplex == DUPLEX_FULL) {
-        enet_set_speed(enet, phydev->speed, 1);
-        printf("full-duplex *\n");
+    } else if (0x0007c0d1 == phydev->phy_id) {
+        /* seems we are running on QEMU, no special init for the emulated PHY */
     } else {
-        enet_set_speed(enet, phydev->speed, 0);
-        printf("half-duplex *\n");
+        ZF_LOGW("SABRE: unexpected PHY with ID 0x%x", phydev->phy_id);
     }
 
-    udelay(100000);
-    return 0;
+#elif defined(CONFIG_PLAT_NITROGEN6SX)
+
+    if (0x004dd072 == phydev->phy_id) {
+        /* Disable Ar803x PHY SmartEEE feature, it causes link status glitches
+         * that result in the ethernet link going down and up.
+         */
+        phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x3);
+        phy_write(phydev, MDIO_DEVAD_NONE, 0xe, 0x805d);
+        phy_write(phydev, MDIO_DEVAD_NONE, 0xd, 0x4003);
+        int val = phy_read(phydev, MDIO_DEVAD_NONE, 0xe);
+        phy_write(phydev, MDIO_DEVAD_NONE, 0xe, val & ~(1 << 8));
+    } else {
+        ZF_LOGW("NITROGEN6SX: unexpected PHY with ID 0x%x", phydev->phy_id);
+    }
+
+#else
+#error "unsupported platform"
+#endif
+
+    if (phydev->drv->config) {
+        ret = phydev->drv->config(phydev);
+        if (ret) {
+            ZF_LOGE("Could not configure PHY '%s', code %d",
+                    phydev->dev->name, ret);
+            return NULL;
+        }
+    }
+
+    if (phydev->drv->startup) {
+        ret = phydev->drv->startup(phydev);
+        if (ret) {
+            ZF_LOGE("Could not init PHY '%s', code %d",
+                    phydev->dev->name, ret);
+            return NULL;
+        }
+    }
+
+    return phydev;
 }
diff --git a/libethdrivers/src/plat/imx6/uboot/fec_mxc.h b/libethdrivers/src/plat/imx6/uboot/fec_mxc.h
index 89ef35a..22f4f32 100644
--- a/libethdrivers/src/plat/imx6/uboot/fec_mxc.h
+++ b/libethdrivers/src/plat/imx6/uboot/fec_mxc.h
@@ -1,19 +1,16 @@
 /*
- * @TAG(OTHER_GPL)
- */
-
-/*
+ * This file is based on mpc4200fec.h from Motorola
+ *
+ * (C) Copyright 2000, Motorola, Inc.
+ * (C) Copyright 2003, Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  * (C) Copyright 2009 Ilya Yanok, Emcraft Systems Ltd <yanok@emcraft.com>
  * (C) Copyright 2008 Armadeus Systems, nc
  * (C) Copyright 2008 Eric Jarrige <eric.jarrige@armadeus.org>
  * (C) Copyright 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
  * (C) Copyright 2007 Pengutronix, Juergen Beisert <j.beisert@pengutronix.de>
+ * (C) Copyright 2020, HENSOLDT Cyber GmbH
  *
- * (C) Copyright 2003
- * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
- *
- * This file is based on mpc4200fec.h
- * (C) Copyright Motorola, Inc., 2000
+ * SPDX-License-Identifier: GPL-2.0-or-later
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -34,55 +31,39 @@
 
 #pragma once
 
+#include <ethdrivers/plat/eth_plat.h>
 #include "../enet.h"
 
-#define PKTSIZE			1518
-#define PKTSIZE_ALIGN		1536
+#define PKTSIZE         1518
+#define PKTSIZE_ALIGN   1536
 
 struct eth_device {
-	char name[16];
-	unsigned char enetaddr[6];
-	int iobase;
-	int state;
-	struct fec_priv *priv;
-        int (*write_hwaddr)(struct eth_device *dev);
+    char name[16];
 };
 
-int fec_init(unsigned phy_mask, struct enet* enet);
+struct phy_device *fec_init(unsigned phy_mask, struct enet *enet,
+                            const nic_config_t *nic_config);
 
-#define FEC_RCNTRL_MAX_FL_SHIFT		16
-#define FEC_RCNTRL_LOOP			0x00000001
-#define FEC_RCNTRL_DRT			0x00000002
-#define FEC_RCNTRL_MII_MODE		0x00000004
-#define FEC_RCNTRL_PROM			0x00000008
-#define FEC_RCNTRL_BC_REJ		0x00000010
-#define FEC_RCNTRL_FCE			0x00000020
-#define FEC_RCNTRL_RGMII		0x00000040
-#define FEC_RCNTRL_RMII			0x00000100
-#define FEC_RCNTRL_RMII_10T		0x00000200
+#define FEC_RCNTRL_MAX_FL_SHIFT     16
+#define FEC_RCNTRL_LOOP             0x00000001
+#define FEC_RCNTRL_DRT              0x00000002
+#define FEC_RCNTRL_MII_MODE         0x00000004
+#define FEC_RCNTRL_PROM             0x00000008
+#define FEC_RCNTRL_BC_REJ           0x00000010
+#define FEC_RCNTRL_FCE              0x00000020
+#define FEC_RCNTRL_RGMII            0x00000040
+#define FEC_RCNTRL_RMII             0x00000100
+#define FEC_RCNTRL_RMII_10T         0x00000200
 
-#define FEC_TCNTRL_GTS			0x00000001
-#define FEC_TCNTRL_HBC			0x00000002
-#define FEC_TCNTRL_FDEN			0x00000004
-#define FEC_TCNTRL_TFC_PAUSE		0x00000008
-#define FEC_TCNTRL_RFC_PAUSE		0x00000010
+#define FEC_TCNTRL_GTS              0x00000001
+#define FEC_TCNTRL_HBC              0x00000002
+#define FEC_TCNTRL_FDEN             0x00000004
+#define FEC_TCNTRL_TFC_PAUSE        0x00000008
+#define FEC_TCNTRL_RFC_PAUSE        0x00000010
 
-#define FEC_ECNTRL_RESET		0x00000001	/* reset the FEC */
-#define FEC_ECNTRL_ETHER_EN		0x00000002	/* enable the FEC */
-#define FEC_ECNTRL_SPEED		0x00000020
-#define FEC_ECNTRL_DBSWAP		0x00000100
+#define FEC_ECNTRL_RESET            0x00000001  /* reset the FEC */
+#define FEC_ECNTRL_ETHER_EN         0x00000002  /* enable the FEC */
+#define FEC_ECNTRL_SPEED            0x00000020
+#define FEC_ECNTRL_DBSWAP           0x00000100
 
-#define FEC_X_WMRK_STRFWD		0x00000100
-
-/**
- * @brief i.MX27-FEC private structure
- */
-struct fec_priv {
-#ifdef CONFIG_PHYLIB
-	int phy_mask;
-	struct phy_device *phydev;
-#else
-	int phy_id;
-	int (*mii_postcall)(int);
-#endif
-};
+#define FEC_X_WMRK_STRFWD           0x00000100
diff --git a/libethdrivers/src/plat/imx6/uboot/gpio.h b/libethdrivers/src/plat/imx6/uboot/gpio.h
index a6a67e3..bc51f71 100644
--- a/libethdrivers/src/plat/imx6/uboot/gpio.h
+++ b/libethdrivers/src/plat/imx6/uboot/gpio.h
@@ -1,79 +1,14 @@
 /*
- * @TAG(OTHER_GPL)
- */
-
-/*
- * Copyright (C) 2011
- * Stefano Babic, DENX Software Engineering, <sbabic@denx.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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 (at your option) 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#pragma once
-
-#include <platsupport/io.h>
-
-/*
- * Copyright (C) 2011
- * Stefano Babic, DENX Software Engineering, <sbabic@denx.de>
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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 (at your option) 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#ifndef __ASM_ARCH_IMX_GPIO_H
-#define __ASM_ARCH_IMX_GPIO_H
-
-#if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
-#include <stdint.h>
-/* GPIO registers */
-struct gpio_regs {
-	uint32_t gpio_dr;	/* data */
-	uint32_t gpio_dir;	/* direction */
-	uint32_t gpio_psr;	/* pad satus */
-};
-#endif
-
-#define IMX_GPIO_NR(port, index)		((((port)-1)*32)+((index)&31))
-
-#endif
-
-/*
  * Copyright (c) 2011 The Chromium OS Authors.
  * Copyright (c) 2011, NVIDIA Corp. All rights reserved.
- * See file CREDITS for list of people who contributed to this
- * project.
+ * Copyright (C) 2011 Stefano Babic, DENX Software Engineering, <sbabic@denx.de>
+ * Copyright 2020, HENSOLDT Cyber GmbH
+ *
+ * This file is taken from U-Boot. See U-Boot CREDITS for list of people who
+ * contributed to the U-Boot project. It is a modified variant of the generic
+ * GPIO API for U-Boot
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -89,13 +24,8 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
- */
-
-#ifndef _ASM_GENERIC_GPIO_H_
-#define _ASM_GENERIC_GPIO_H_
-
-/*
- * Generic GPIO API for U-Boot
+ *
+ *------------------------------------------------------------------------------
  *
  * GPIOs are numbered from 0 to GPIO_COUNT-1 which value is defined
  * by the SOC/architecture.
@@ -109,14 +39,28 @@
  * In some cases the operation may fail, for example if the GPIO number
  * is out of range, or the GPIO is not available because its pin is
  * being used by another function. In that case, functions may return
- * an error value of -1.
+ * an error value of -1.*
  */
 
+#pragma once
+
+#include <platsupport/io.h>
+#include <stdint.h>
+
+/* GPIO registers */
+struct gpio_regs {
+    uint32_t gpio_dr;   /* data */
+    uint32_t gpio_dir;  /* direction */
+    uint32_t gpio_psr;  /* pad satus */
+};
+
+#define IMX_GPIO_NR(port, index)        ((((port)-1)*32)+((index)&31))
+
 /**
  * Request ownership of a GPIO.
  *
- * @param gpio	GPIO number
- * @param label	Name given to the GPIO
+ * @param gpio  GPIO number
+ * @param label Name given to the GPIO
  * @return 0 if ok, -1 on error
  */
 int gpio_request(unsigned gpio, const char *label);
@@ -124,7 +68,7 @@
 /**
  * Stop using the GPIO.  This function should not alter pin configuration.
  *
- * @param gpio	GPIO number
+ * @param gpio  GPIO number
  * @return 0 if ok, -1 on error
  */
 int gpio_free(unsigned gpio);
@@ -132,7 +76,7 @@
 /**
  * Make a GPIO an input.
  *
- * @param gpio	GPIO number
+ * @param gpio  GPIO number
  * @return 0 if ok, -1 on error
  */
 int gpio_direction_input(unsigned gpio, ps_io_ops_t *io_ops);
@@ -140,8 +84,8 @@
 /**
  * Make a GPIO an output, and set its value.
  *
- * @param gpio	GPIO number
- * @param value	GPIO value (0 for low or 1 for high)
+ * @param gpio  GPIO number
+ * @param value GPIO value (0 for low or 1 for high)
  * @return 0 if ok, -1 on error
  */
 int gpio_direction_output(unsigned gpio, int value, ps_io_ops_t *io_ops);
@@ -150,7 +94,7 @@
  * Get a GPIO's value. This will work whether the GPIO is an input
  * or an output.
  *
- * @param gpio	GPIO number
+ * @param gpio  GPIO number
  * @return 0 if low, 1 if high, -1 on error
  */
 int gpio_get_value(unsigned gpio);
@@ -159,8 +103,8 @@
  * Set an output GPIO's value. The GPIO must already be an output or
  * this function may have no effect.
  *
- * @param gpio	GPIO number
- * @param value	GPIO value (0 for low or 1 for high)
+ * @param gpio  GPIO number
+ * @param value GPIO value (0 for low or 1 for high)
  * @return 0 if ok, -1 on error
  */
 int gpio_set_value(unsigned gpio, int value);
@@ -169,10 +113,8 @@
  * Request a gpio. This should be called before any of the other functions
  * are used on this gpio.
  *
- * @param gp	GPIO number
- * @param label	User label for this GPIO
+ * @param gp    GPIO number
+ * @param label User label for this GPIO
  * @return 0 if ok, -1 on error
  */
 int gpio_request(unsigned gpio, const char *label);
-#endif	/* _ASM_GENERIC_GPIO_H_ */
-
diff --git a/libethdrivers/src/plat/imx6/uboot/imx-regs.h b/libethdrivers/src/plat/imx6/uboot/imx-regs.h
index 47bcf1b..e395cdc 100644
--- a/libethdrivers/src/plat/imx6/uboot/imx-regs.h
+++ b/libethdrivers/src/plat/imx6/uboot/imx-regs.h
@@ -1,9 +1,10 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 /*
  * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2020, HENSOLDT Cyber GmbH
  *
  * 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
@@ -22,14 +23,19 @@
 
 #pragma once
 
+#include <autoconf.h>
 #include <stdint.h>
 
 #define ARCH_MXC
 
-#define CONFIG_SYS_CACHELINE_SIZE	32
+#define CONFIG_SYS_CACHELINE_SIZE       32
 
 #define ROMCP_ARB_BASE_ADDR             0x00000000
 #define ROMCP_ARB_END_ADDR              0x000FFFFF
+
+
+#if defined(CONFIG_PLAT_IMX6DQ)
+
 #define CAAM_ARB_BASE_ADDR              0x00100000
 #define CAAM_ARB_END_ADDR               0x00103FFF
 #define APBH_DMA_ARB_BASE_ADDR          0x00110000
@@ -43,25 +49,96 @@
 #define DTCP_ARB_BASE_ADDR              0x00138000
 #define DTCP_ARB_END_ADDR               0x0013BFFF
 
+#elif defined(CONFIG_PLAT_IMX6SX)
+
+#define CAAM_ARB_BASE_ADDR              0x00100000
+#define CAAM_ARB_END_ADDR               0x00107FFF
+#define GPU_ARB_BASE_ADDR               0x01800000
+#define GPU_ARB_END_ADDR                0x01803FFF
+#define APBH_DMA_ARB_BASE_ADDR          0x01804000
+#define APBH_DMA_ARB_END_ADDR           0x0180BFFF
+#define M4_BOOTROM_BASE_ADDR            0x007F8000
+
+#else
+#error "unknown i.MX6 SOC"
+#endif
+
+
+#define MXS_APBH_BASE                   APBH_DMA_ARB_BASE_ADDR
+#define MXS_GPMI_BASE                   (APBH_DMA_ARB_BASE_ADDR + 0x02000)
+#define MXS_BCH_BASE                    (APBH_DMA_ARB_BASE_ADDR + 0x04000)
+
 /* GPV - PL301 configuration ports */
-#define GPV2_BASE_ADDR			0x00200000
-#define GPV3_BASE_ADDR			0x00300000
-#define GPV4_BASE_ADDR			0x00800000
-#define IRAM_BASE_ADDR			0x00900000
+
+#if defined(CONFIG_PLAT_IMX6DQ)
+
+#define GPV2_BASE_ADDR                  0x00200000
+#define GPV3_BASE_ADDR                  0x00300000
+#define GPV4_BASE_ADDR                  0x00800000
+
+#elif defined(CONFIG_PLAT_IMX6SX)
+
+#define GPV2_BASE_ADDR                  0x00D00000
+#define GPV3_BASE_ADDR                  0x00E00000
+#define GPV4_BASE_ADDR                  0x00F00000
+#define GPV5_BASE_ADDR                  0x01000000
+#define GPV6_BASE_ADDR                  0x01100000
+
+#else
+#error "unknown i.MX6 SOC"
+#endif
+
+
+#define IRAM_BASE_ADDR                  0x00900000
+
+#if defined(CONFIG_PLAT_IMX6DQ)
+#define IRAM_SIZE                       0x00020000
+#elif defined(CONFIG_PLAT_IMX6SX)
+#define IRAM_SIZE                       0x00040000
+#else
+#error "unknown i.MX6 SOC"
+#endif
+
+
 #define SCU_BASE_ADDR                   0x00A00000
 #define IC_INTERFACES_BASE_ADDR         0x00A00100
 #define GLOBAL_TIMER_BASE_ADDR          0x00A00200
 #define PRIVATE_TIMERS_WD_BASE_ADDR     0x00A00600
 #define IC_DISTRIBUTOR_BASE_ADDR        0x00A01000
+#define L2_PL310_BASE                   0x00A02000
 #define GPV0_BASE_ADDR                  0x00B00000
 #define GPV1_BASE_ADDR                  0x00C00000
+
+
+#if defined(CONFIG_PLAT_IMX6DQ)
+
 #define PCIE_ARB_BASE_ADDR              0x01000000
 #define PCIE_ARB_END_ADDR               0x01FFFFFF
 
+#elif defined(CONFIG_PLAT_IMX6SX)
+
+#define PCIE_ARB_BASE_ADDR              0x08000000
+#define PCIE_ARB_END_ADDR               0x08FFFFFF
+
+#else
+#error "unknown i.MX6 SOC"
+#endif
+
+
 #define AIPS1_ARB_BASE_ADDR             0x02000000
 #define AIPS1_ARB_END_ADDR              0x020FFFFF
 #define AIPS2_ARB_BASE_ADDR             0x02100000
 #define AIPS2_ARB_END_ADDR              0x021FFFFF
+
+#if defined(CONFIG_PLAT_IMX6SX)
+/* AIPS3 exists  on i.MX6SX */
+#define AIPS3_ARB_BASE_ADDR             0x02200000
+#define AIPS3_ARB_END_ADDR              0x022FFFFF
+#endif
+
+
+#if defined(CONFIG_PLAT_IMX6DQ)
+
 #define SATA_ARB_BASE_ADDR              0x02200000
 #define SATA_ARB_END_ADDR               0x02203FFF
 #define OPENVG_ARB_BASE_ADDR            0x02204000
@@ -80,32 +157,66 @@
 #define MMDC1_ARB_BASE_ADDR             0x80000000
 #define MMDC1_ARB_END_ADDR              0xFFFFFFFF
 
-#define IPU_SOC_BASE_ADDR		IPU1_ARB_BASE_ADDR
-#define IPU_SOC_OFFSET			0x00200000
+#define IPU_SOC_BASE_ADDR               IPU1_ARB_BASE_ADDR
+#define IPU_SOC_OFFSET                  0x00200000
+
+#elif defined(CONFIG_PLAT_IMX6SX)
+
+#define WEIM_ARB_BASE_ADDR              0x50000000
+#define WEIM_ARB_END_ADDR               0x57FFFFFF
+#define QSPI0_AMBA_BASE                 0x60000000
+#define QSPI0_AMBA_END                  0x6FFFFFFF
+#define QSPI1_AMBA_BASE                 0x70000000
+#define QSPI1_AMBA_END                  0x7FFFFFFF
+#define MMDC0_ARB_BASE_ADDR             0x80000000
+#define MMDC0_ARB_END_ADDR              0xBFFFFFFF
+#define MMDC1_ARB_BASE_ADDR             0xC0000000
+#define MMDC1_ARB_END_ADDR              0xFFFFFFFF
+
+#else
+#error "unknown i.MX6 SOC"
+#endif
 
 /* Defines for Blocks connected via AIPS (SkyBlue) */
 #define ATZ1_BASE_ADDR              AIPS1_ARB_BASE_ADDR
 #define ATZ2_BASE_ADDR              AIPS2_ARB_BASE_ADDR
+#if defined(CONFIG_PLAT_IMX6SX)
+/* ATZ3/AIPS3 exists  on i.MX6SX */
+#define ATZ3_BASE_ADDR              AIPS3_ARB_BASE_ADDR
+#endif
+
 #define AIPS1_BASE_ADDR             AIPS1_ON_BASE_ADDR
 #define AIPS2_BASE_ADDR             AIPS2_ON_BASE_ADDR
+#if defined(CONFIG_PLAT_IMX6SX)
+/* AIPS3 exists  on i.MX6SX */
+#define AIPS3_BASE_ADDR             AIPS3_ON_BASE_ADDR
+#endif
 
 #define SPDIF_BASE_ADDR             (ATZ1_BASE_ADDR + 0x04000)
 #define ECSPI1_BASE_ADDR            (ATZ1_BASE_ADDR + 0x08000)
 #define ECSPI2_BASE_ADDR            (ATZ1_BASE_ADDR + 0x0C000)
 #define ECSPI3_BASE_ADDR            (ATZ1_BASE_ADDR + 0x10000)
 #define ECSPI4_BASE_ADDR            (ATZ1_BASE_ADDR + 0x14000)
+
+#if defined(CONFIG_PLAT_IMX6DQ)
 #define ECSPI5_BASE_ADDR            (ATZ1_BASE_ADDR + 0x18000)
+#endif
+
 #define UART1_BASE                  (ATZ1_BASE_ADDR + 0x20000)
 #define ESAI1_BASE_ADDR             (ATZ1_BASE_ADDR + 0x24000)
 #define SSI1_BASE_ADDR              (ATZ1_BASE_ADDR + 0x28000)
 #define SSI2_BASE_ADDR              (ATZ1_BASE_ADDR + 0x2C000)
 #define SSI3_BASE_ADDR              (ATZ1_BASE_ADDR + 0x30000)
 #define ASRC_BASE_ADDR              (ATZ1_BASE_ADDR + 0x34000)
+
+#if defined(CONFIG_PLAT_IMX6DQ)
 #define SPBA_BASE_ADDR              (ATZ1_BASE_ADDR + 0x3C000)
 #define VPU_BASE_ADDR               (ATZ1_BASE_ADDR + 0x40000)
-#define AIPS1_ON_BASE_ADDR          (ATZ1_BASE_ADDR + 0x7C000)
+#endif
 
+#define AIPS1_ON_BASE_ADDR          (ATZ1_BASE_ADDR + 0x7C000)
 #define AIPS1_OFF_BASE_ADDR         (ATZ1_BASE_ADDR + 0x80000)
+
 #define PWM1_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x0000)
 #define PWM2_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x4000)
 #define PWM3_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x8000)
@@ -133,14 +244,36 @@
 #define SRC_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x58000)
 #define GPC_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x5C000)
 #define IOMUXC_BASE_ADDR            (AIPS1_OFF_BASE_ADDR + 0x60000)
+
+
+#if defined(CONFIG_PLAT_IMX6DQ)
+
 #define DCIC1_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x64000)
 #define DCIC2_BASE_ADDR             (AIPS1_OFF_BASE_ADDR + 0x68000)
 #define DMA_REQ_PORT_HOST_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x6C000)
 
+#elif defined(CONFIG_PLAT_IMX6SX)
+
+#define CANFD1_BASE_ADDR            (AIPS1_OFF_BASE_ADDR + 0x68000)
+#define SDMA_BASE_ADDR              (AIPS1_OFF_BASE_ADDR + 0x6C000)
+#define CANFD2_BASE_ADDR            (AIPS1_OFF_BASE_ADDR + 0x70000)
+#define SEMAPHORE1_BASE_ADDR        (AIPS1_OFF_BASE_ADDR + 0x74000)
+#define SEMAPHORE2_BASE_ADDR        (AIPS1_OFF_BASE_ADDR + 0x78000)
+#define RDC_BASE_ADDR               (AIPS1_OFF_BASE_ADDR + 0x7C000)
+
+#else
+#error "unknown i.MX6 SOC"
+#endif
+
+
 #define AIPS2_ON_BASE_ADDR          (ATZ2_BASE_ADDR + 0x7C000)
 #define AIPS2_OFF_BASE_ADDR         (ATZ2_BASE_ADDR + 0x80000)
 #define CAAM_BASE_ADDR              (ATZ2_BASE_ADDR)
-#define ARM_BASE_ADDR		    (ATZ2_BASE_ADDR + 0x40000)
+#define ARM_BASE_ADDR               (ATZ2_BASE_ADDR + 0x40000)
+
+#define CONFIG_SYS_FSL_SEC_ADDR     CAAM_BASE_ADDR
+#define CONFIG_SYS_FSL_JR0_ADDR     (CAAM_BASE_ADDR + 0x1000)
+
 #define USBOH3_PL301_BASE_ADDR      (AIPS2_OFF_BASE_ADDR + 0x0000)
 #define USBOH3_USB_BASE_ADDR        (AIPS2_OFF_BASE_ADDR + 0x4000)
 #define ENET_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x8000)
@@ -154,12 +287,22 @@
 #define I2C3_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x28000)
 #define ROMCP_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x2C000)
 #define MMDC_P0_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x30000)
+
+#ifdef CONFIG_PLAT_IMX6SX
+#define ENET2_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x34000)
+#endif
+
 #define MMDC_P1_BASE_ADDR           (AIPS2_OFF_BASE_ADDR + 0x34000)
 #define WEIM_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x38000)
 #define OCOTP_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x3C000)
+#define IMX_IIM_BASE                OCOTP_BASE_ADDR
 #define CSU_BASE_ADDR               (AIPS2_OFF_BASE_ADDR + 0x40000)
 #define IP2APB_PERFMON1_BASE_ADDR   (AIPS2_OFF_BASE_ADDR + 0x44000)
 #define IP2APB_PERFMON2_BASE_ADDR   (AIPS2_OFF_BASE_ADDR + 0x48000)
+
+
+#if defined(CONFIG_PLAT_IMX6DQ)
+
 #define IP2APB_PERFMON3_BASE_ADDR   (AIPS2_OFF_BASE_ADDR + 0x4C000)
 #define IP2APB_TZASC1_BASE_ADDR     (AIPS2_OFF_BASE_ADDR + 0x50000)
 #define IP2APB_TZASC2_BASE_ADDR     (AIPS2_OFF_BASE_ADDR + 0x54000)
@@ -167,457 +310,510 @@
 #define MIPI_CSI2_BASE_ADDR         (AIPS2_OFF_BASE_ADDR + 0x5C000)
 #define MIPI_DSI_BASE_ADDR          (AIPS2_OFF_BASE_ADDR + 0x60000)
 #define VDOA_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x64000)
+
+#elif defined(CONFIG_PLAT_IMX6SX)
+
+#define DEBUG_MONITOR_BASE_ADDR     (AIPS2_OFF_BASE_ADDR + 0x4C000)
+#define IP2APB_TZASC1_BASE_ADDR     (AIPS2_OFF_BASE_ADDR + 0x50000)
+#define SAI1_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x54000)
+#define AUDMUX_BASE_ADDR            (AIPS2_OFF_BASE_ADDR + 0x58000)
+#define SAI2_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x5C000)
+#define QSPI0_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x60000)
+#define QSPI1_BASE_ADDR             (AIPS2_OFF_BASE_ADDR + 0x64000)
+
+#else
+#error "unknown i.MX6 SOC"
+#endif
+
+
 #define UART2_BASE                  (AIPS2_OFF_BASE_ADDR + 0x68000)
 #define UART3_BASE                  (AIPS2_OFF_BASE_ADDR + 0x6C000)
 #define UART4_BASE                  (AIPS2_OFF_BASE_ADDR + 0x70000)
 #define UART5_BASE                  (AIPS2_OFF_BASE_ADDR + 0x74000)
+#define I2C4_BASE_ADDR              (AIPS2_OFF_BASE_ADDR + 0x78000)
 #define IP2APB_USBPHY1_BASE_ADDR    (AIPS2_OFF_BASE_ADDR + 0x78000)
 #define IP2APB_USBPHY2_BASE_ADDR    (AIPS2_OFF_BASE_ADDR + 0x7C000)
 
+#if defined(CONFIG_PLAT_IMX6SX)
+/* ATZ3/AIPS3 exists  on i.MX6SX */
+
+#define AIPS3_ON_BASE_ADDR          (ATZ3_BASE_ADDR + 0x7C000)
+#define AIPS3_OFF_BASE_ADDR         (ATZ3_BASE_ADDR + 0x80000)
+
+#define GIS_BASE_ADDR               (AIPS3_ARB_BASE_ADDR + 0x04000)
+#define DCIC1_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x0C000)
+#define DCIC2_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x10000)
+#define CSI1_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x14000)
+#define PXP_BASE_ADDR               (AIPS3_ARB_BASE_ADDR + 0x18000)
+#define CSI2_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x1C000)
+#define LCDIF1_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x20000)
+#define LCDIF2_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x24000)
+#define VADC_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x28000)
+#define VDEC_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x2C000)
+#define SPBA_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x3C000)
+#define AIPS3_CONFIG_BASE_ADDR      (AIPS3_ARB_BASE_ADDR + 0x7C000)
+#define ADC1_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x80000)
+#define ADC2_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0x84000)
+#define WDOG3_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x88000)
+#define ECSPI5_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x8C000)
+#define HS_BASE_ADDR                (AIPS3_ARB_BASE_ADDR + 0x90000)
+#define MU_MCU_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x94000)
+#define CANFD_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0x98000)
+#define MU_DSP_BASE_ADDR            (AIPS3_ARB_BASE_ADDR + 0x9C000)
+#define UART6_BASE_ADDR             (AIPS3_ARB_BASE_ADDR + 0xA0000)
+#define PWM5_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0xA4000)
+#define PWM6_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0xA8000)
+#define PWM7_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0xAC000)
+#define PWM8_BASE_ADDR              (AIPS3_ARB_BASE_ADDR + 0xB0000)
+
+#endif /* defined(CONFIG_PLAT_IMX6SX) */
+
+
 #define CHIP_REV_1_0                 0x10
-#define IRAM_SIZE                    0x00040000
-#define IMX_IIM_BASE                 OCOTP_BASE_ADDR
+
 #define FEC_QUIRK_ENET_MAC
 
+
 #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
 
 /* System Reset Controller (SRC) */
 struct src {
-	uint32_t	scr;
-	uint32_t	sbmr1;
-	uint32_t	srsr;
-	uint32_t	reserved1[2];
-	uint32_t	sisr;
-	uint32_t	simr;
-	uint32_t     sbmr2;
-	uint32_t     gpr1;
-	uint32_t     gpr2;
-	uint32_t     gpr3;
-	uint32_t     gpr4;
-	uint32_t     gpr5;
-	uint32_t     gpr6;
-	uint32_t     gpr7;
-	uint32_t     gpr8;
-	uint32_t     gpr9;
-	uint32_t     gpr10;
+    uint32_t    scr;
+    uint32_t    sbmr1;
+    uint32_t    srsr;
+    uint32_t    reserved1[2];
+    uint32_t    sisr;
+    uint32_t    simr;
+    uint32_t    sbmr2;
+    uint32_t    gpr1;
+    uint32_t    gpr2;
+    uint32_t    gpr3;
+    uint32_t    gpr4;
+    uint32_t    gpr5;
+    uint32_t    gpr6;
+    uint32_t    gpr7;
+    uint32_t    gpr8;
+    uint32_t    gpr9;
+    uint32_t    gpr10;
 };
 
 /* OCOTP Registers */
 struct ocotp_regs {
-	uint32_t	reserved[0x198];
-	uint32_t	gp1;	/* 0x660 */
+    uint32_t    reserved[0x198];
+    uint32_t    gp1;    /* 0x660 */
 };
 
 /* GPR3 bitfields */
-#define IOMUXC_GPR3_GPU_DBG_OFFSET		29
-#define IOMUXC_GPR3_GPU_DBG_MASK		(3<<IOMUXC_GPR3_GPU_DBG_OFFSET)
-#define IOMUXC_GPR3_BCH_WR_CACHE_CTL_OFFSET	28
-#define IOMUXC_GPR3_BCH_WR_CACHE_CTL_MASK	(1<<IOMUXC_GPR3_BCH_WR_CACHE_CTL_OFFSET)
-#define IOMUXC_GPR3_BCH_RD_CACHE_CTL_OFFSET	27
-#define IOMUXC_GPR3_BCH_RD_CACHE_CTL_MASK	(1<<IOMUXC_GPR3_BCH_RD_CACHE_CTL_OFFSET)
-#define IOMUXC_GPR3_uSDHCx_WR_CACHE_CTL_OFFSET	26
-#define IOMUXC_GPR3_uSDHCx_WR_CACHE_CTL_MASK	(1<<IOMUXC_GPR3_uSDHCx_WR_CACHE_CTL_OFFSET)
-#define IOMUXC_GPR3_uSDHCx_RD_CACHE_CTL_OFFSET	25
-#define IOMUXC_GPR3_uSDHCx_RD_CACHE_CTL_MASK	(1<<IOMUXC_GPR3_uSDHCx_RD_CACHE_CTL_OFFSET)
-#define IOMUXC_GPR3_OCRAM_CTL_OFFSET		21
-#define IOMUXC_GPR3_OCRAM_CTL_MASK		(0xf<<IOMUXC_GPR3_OCRAM_CTL_OFFSET)
-#define IOMUXC_GPR3_OCRAM_STATUS_OFFSET		17
-#define IOMUXC_GPR3_OCRAM_STATUS_MASK		(0xf<<IOMUXC_GPR3_OCRAM_STATUS_OFFSET)
-#define IOMUXC_GPR3_CORE3_DBG_ACK_EN_OFFSET	16
-#define IOMUXC_GPR3_CORE3_DBG_ACK_EN_MASK	(1<<IOMUXC_GPR3_CORE3_DBG_ACK_EN_OFFSET)
-#define IOMUXC_GPR3_CORE2_DBG_ACK_EN_OFFSET	15
-#define IOMUXC_GPR3_CORE2_DBG_ACK_EN_MASK	(1<<IOMUXC_GPR3_CORE2_DBG_ACK_EN_OFFSET)
-#define IOMUXC_GPR3_CORE1_DBG_ACK_EN_OFFSET	14
-#define IOMUXC_GPR3_CORE1_DBG_ACK_EN_MASK	(1<<IOMUXC_GPR3_CORE1_DBG_ACK_EN_OFFSET)
-#define IOMUXC_GPR3_CORE0_DBG_ACK_EN_OFFSET	13
-#define IOMUXC_GPR3_CORE0_DBG_ACK_EN_MASK	(1<<IOMUXC_GPR3_CORE0_DBG_ACK_EN_OFFSET)
-#define IOMUXC_GPR3_TZASC2_BOOT_LOCK_OFFSET	12
-#define IOMUXC_GPR3_TZASC2_BOOT_LOCK_MASK	(1<<IOMUXC_GPR3_TZASC2_BOOT_LOCK_OFFSET)
-#define IOMUXC_GPR3_TZASC1_BOOT_LOCK_OFFSET	11
-#define IOMUXC_GPR3_TZASC1_BOOT_LOCK_MASK	(1<<IOMUXC_GPR3_TZASC1_BOOT_LOCK_OFFSET)
-#define IOMUXC_GPR3_IPU_DIAG_OFFSET		10
-#define IOMUXC_GPR3_IPU_DIAG_MASK		(1<<IOMUXC_GPR3_IPU_DIAG_OFFSET)
+#define IOMUXC_GPR3_GPU_DBG_OFFSET              29
+#define IOMUXC_GPR3_GPU_DBG_MASK                (3<<IOMUXC_GPR3_GPU_DBG_OFFSET)
+#define IOMUXC_GPR3_BCH_WR_CACHE_CTL_OFFSET     28
+#define IOMUXC_GPR3_BCH_WR_CACHE_CTL_MASK       (1<<IOMUXC_GPR3_BCH_WR_CACHE_CTL_OFFSET)
+#define IOMUXC_GPR3_BCH_RD_CACHE_CTL_OFFSET     27
+#define IOMUXC_GPR3_BCH_RD_CACHE_CTL_MASK       (1<<IOMUXC_GPR3_BCH_RD_CACHE_CTL_OFFSET)
+#define IOMUXC_GPR3_uSDHCx_WR_CACHE_CTL_OFFSET  26
+#define IOMUXC_GPR3_uSDHCx_WR_CACHE_CTL_MASK    (1<<IOMUXC_GPR3_uSDHCx_WR_CACHE_CTL_OFFSET)
+#define IOMUXC_GPR3_uSDHCx_RD_CACHE_CTL_OFFSET  25
+#define IOMUXC_GPR3_uSDHCx_RD_CACHE_CTL_MASK    (1<<IOMUXC_GPR3_uSDHCx_RD_CACHE_CTL_OFFSET)
+#define IOMUXC_GPR3_OCRAM_CTL_OFFSET            21
+#define IOMUXC_GPR3_OCRAM_CTL_MASK              (0xf<<IOMUXC_GPR3_OCRAM_CTL_OFFSET)
+#define IOMUXC_GPR3_OCRAM_STATUS_OFFSET         17
+#define IOMUXC_GPR3_OCRAM_STATUS_MASK           (0xf<<IOMUXC_GPR3_OCRAM_STATUS_OFFSET)
+#define IOMUXC_GPR3_CORE3_DBG_ACK_EN_OFFSET     16
+#define IOMUXC_GPR3_CORE3_DBG_ACK_EN_MASK       (1<<IOMUXC_GPR3_CORE3_DBG_ACK_EN_OFFSET)
+#define IOMUXC_GPR3_CORE2_DBG_ACK_EN_OFFSET     15
+#define IOMUXC_GPR3_CORE2_DBG_ACK_EN_MASK       (1<<IOMUXC_GPR3_CORE2_DBG_ACK_EN_OFFSET)
+#define IOMUXC_GPR3_CORE1_DBG_ACK_EN_OFFSET     14
+#define IOMUXC_GPR3_CORE1_DBG_ACK_EN_MASK       (1<<IOMUXC_GPR3_CORE1_DBG_ACK_EN_OFFSET)
+#define IOMUXC_GPR3_CORE0_DBG_ACK_EN_OFFSET     13
+#define IOMUXC_GPR3_CORE0_DBG_ACK_EN_MASK       (1<<IOMUXC_GPR3_CORE0_DBG_ACK_EN_OFFSET)
+#define IOMUXC_GPR3_TZASC2_BOOT_LOCK_OFFSET     12
+#define IOMUXC_GPR3_TZASC2_BOOT_LOCK_MASK       (1<<IOMUXC_GPR3_TZASC2_BOOT_LOCK_OFFSET)
+#define IOMUXC_GPR3_TZASC1_BOOT_LOCK_OFFSET     11
+#define IOMUXC_GPR3_TZASC1_BOOT_LOCK_MASK       (1<<IOMUXC_GPR3_TZASC1_BOOT_LOCK_OFFSET)
+#define IOMUXC_GPR3_IPU_DIAG_OFFSET             10
+#define IOMUXC_GPR3_IPU_DIAG_MASK               (1<<IOMUXC_GPR3_IPU_DIAG_OFFSET)
 
-#define IOMUXC_GPR3_MUX_SRC_IPU1_DI0	0
-#define IOMUXC_GPR3_MUX_SRC_IPU1_DI1	1
-#define IOMUXC_GPR3_MUX_SRC_IPU2_DI0	2
-#define IOMUXC_GPR3_MUX_SRC_IPU2_DI1	3
+#define IOMUXC_GPR3_MUX_SRC_IPU1_DI0    0
+#define IOMUXC_GPR3_MUX_SRC_IPU1_DI1    1
+#define IOMUXC_GPR3_MUX_SRC_IPU2_DI0    2
+#define IOMUXC_GPR3_MUX_SRC_IPU2_DI1    3
 
-#define IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET	8
-#define IOMUXC_GPR3_LVDS1_MUX_CTL_MASK		(3<<IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET)
+#define IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET    8
+#define IOMUXC_GPR3_LVDS1_MUX_CTL_MASK      (3<<IOMUXC_GPR3_LVDS1_MUX_CTL_OFFSET)
 
-#define IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET	6
-#define IOMUXC_GPR3_LVDS0_MUX_CTL_MASK		(3<<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET)
+#define IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET    6
+#define IOMUXC_GPR3_LVDS0_MUX_CTL_MASK      (3<<IOMUXC_GPR3_LVDS0_MUX_CTL_OFFSET)
 
-#define IOMUXC_GPR3_MIPI_MUX_CTL_OFFSET		4
-#define IOMUXC_GPR3_MIPI_MUX_CTL_MASK		(3<<IOMUXC_GPR3_MIPI_MUX_CTL_OFFSET)
+#define IOMUXC_GPR3_MIPI_MUX_CTL_OFFSET     4
+#define IOMUXC_GPR3_MIPI_MUX_CTL_MASK       (3<<IOMUXC_GPR3_MIPI_MUX_CTL_OFFSET)
 
-#define IOMUXC_GPR3_HDMI_MUX_CTL_OFFSET		2
-#define IOMUXC_GPR3_HDMI_MUX_CTL_MASK		(3<<IOMUXC_GPR3_HDMI_MUX_CTL_OFFSET)
+#define IOMUXC_GPR3_HDMI_MUX_CTL_OFFSET     2
+#define IOMUXC_GPR3_HDMI_MUX_CTL_MASK       (3<<IOMUXC_GPR3_HDMI_MUX_CTL_OFFSET)
 
 struct iomuxc {
-	uint32_t gpr[14];
-	uint32_t omux[5];
-	/* mux and pad registers */
+    uint32_t gpr[14];
+    uint32_t omux[5];
+    /* mux and pad registers */
 };
 
-#define IOMUXC_GPR2_COUNTER_RESET_VAL_OFFSET		20
-#define IOMUXC_GPR2_COUNTER_RESET_VAL_MASK		(3<<IOMUXC_GPR2_COUNTER_RESET_VAL_OFFSET)
-#define IOMUXC_GPR2_LVDS_CLK_SHIFT_OFFSET		16
-#define IOMUXC_GPR2_LVDS_CLK_SHIFT_MASK			(7<<IOMUXC_GPR2_LVDS_CLK_SHIFT_OFFSET)
+#define IOMUXC_GPR2_COUNTER_RESET_VAL_OFFSET    20
+#define IOMUXC_GPR2_COUNTER_RESET_VAL_MASK      (3<<IOMUXC_GPR2_COUNTER_RESET_VAL_OFFSET)
+#define IOMUXC_GPR2_LVDS_CLK_SHIFT_OFFSET       16
+#define IOMUXC_GPR2_LVDS_CLK_SHIFT_MASK         (7<<IOMUXC_GPR2_LVDS_CLK_SHIFT_OFFSET)
 
-#define IOMUXC_GPR2_BGREF_RRMODE_OFFSET			15
-#define IOMUXC_GPR2_BGREF_RRMODE_MASK			(1<<IOMUXC_GPR2_BGREF_RRMODE_OFFSET)
-#define IOMUXC_GPR2_BGREF_RRMODE_INTERNAL_RES		(1<<IOMUXC_GPR2_BGREF_RRMODE_OFFSET)
-#define IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES		(0<<IOMUXC_GPR2_BGREF_RRMODE_OFFSET)
-#define IOMUXC_GPR2_VSYNC_ACTIVE_HIGH	0
-#define IOMUXC_GPR2_VSYNC_ACTIVE_LOW	1
+#define IOMUXC_GPR2_BGREF_RRMODE_OFFSET         15
+#define IOMUXC_GPR2_BGREF_RRMODE_MASK           (1<<IOMUXC_GPR2_BGREF_RRMODE_OFFSET)
+#define IOMUXC_GPR2_BGREF_RRMODE_INTERNAL_RES   (1<<IOMUXC_GPR2_BGREF_RRMODE_OFFSET)
+#define IOMUXC_GPR2_BGREF_RRMODE_EXTERNAL_RES   (0<<IOMUXC_GPR2_BGREF_RRMODE_OFFSET)
 
-#define IOMUXC_GPR2_DI1_VS_POLARITY_OFFSET		10
-#define IOMUXC_GPR2_DI1_VS_POLARITY_MASK		(1<<IOMUXC_GPR2_DI1_VS_POLARITY_OFFSET)
-#define IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH		(IOMUXC_GPR2_VSYNC_ACTIVE_HIGH<<IOMUXC_GPR2_DI1_VS_POLARITY_OFFSET)
-#define IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW		(IOMUXC_GPR2_VSYNC_ACTIVE_LOW<<IOMUXC_GPR2_DI1_VS_POLARITY_OFFSET)
+#define IOMUXC_GPR2_VSYNC_ACTIVE_HIGH           0
+#define IOMUXC_GPR2_VSYNC_ACTIVE_LOW            1
 
-#define IOMUXC_GPR2_DI0_VS_POLARITY_OFFSET		9
-#define IOMUXC_GPR2_DI0_VS_POLARITY_MASK		(1<<IOMUXC_GPR2_DI0_VS_POLARITY_OFFSET)
-#define IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_HIGH		(IOMUXC_GPR2_VSYNC_ACTIVE_HIGH<<IOMUXC_GPR2_DI0_VS_POLARITY_OFFSET)
-#define IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW		(IOMUXC_GPR2_VSYNC_ACTIVE_LOW<<IOMUXC_GPR2_DI0_VS_POLARITY_OFFSET)
+#define IOMUXC_GPR2_DI1_VS_POLARITY_OFFSET      10
+#define IOMUXC_GPR2_DI1_VS_POLARITY_MASK        (1<<IOMUXC_GPR2_DI1_VS_POLARITY_OFFSET)
+#define IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_HIGH (IOMUXC_GPR2_VSYNC_ACTIVE_HIGH<<IOMUXC_GPR2_DI1_VS_POLARITY_OFFSET)
+#define IOMUXC_GPR2_DI1_VS_POLARITY_ACTIVE_LOW  (IOMUXC_GPR2_VSYNC_ACTIVE_LOW<<IOMUXC_GPR2_DI1_VS_POLARITY_OFFSET)
 
-#define IOMUXC_GPR2_BITMAP_SPWG	0
-#define IOMUXC_GPR2_BITMAP_JEIDA	1
+#define IOMUXC_GPR2_DI0_VS_POLARITY_OFFSET      9
+#define IOMUXC_GPR2_DI0_VS_POLARITY_MASK        (1<<IOMUXC_GPR2_DI0_VS_POLARITY_OFFSET)
+#define IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_HIGH (IOMUXC_GPR2_VSYNC_ACTIVE_HIGH<<IOMUXC_GPR2_DI0_VS_POLARITY_OFFSET)
+#define IOMUXC_GPR2_DI0_VS_POLARITY_ACTIVE_LOW  (IOMUXC_GPR2_VSYNC_ACTIVE_LOW<<IOMUXC_GPR2_DI0_VS_POLARITY_OFFSET)
 
-#define IOMUXC_GPR2_BIT_MAPPING_CH1_OFFSET		8
-#define IOMUXC_GPR2_BIT_MAPPING_CH1_MASK		(1<<IOMUXC_GPR2_BIT_MAPPING_CH1_OFFSET)
-#define IOMUXC_GPR2_BIT_MAPPING_CH1_JEIDA		(IOMUXC_GPR2_BITMAP_JEIDA<<IOMUXC_GPR2_BIT_MAPPING_CH1_OFFSET)
-#define IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG		(IOMUXC_GPR2_BITMAP_SPWG<<IOMUXC_GPR2_BIT_MAPPING_CH1_OFFSET)
+#define IOMUXC_GPR2_BITMAP_SPWG                 0
+#define IOMUXC_GPR2_BITMAP_JEIDA                1
 
-#define IOMUXC_GPR2_DATA_WIDTH_18	0
-#define IOMUXC_GPR2_DATA_WIDTH_24	1
+#define IOMUXC_GPR2_BIT_MAPPING_CH1_OFFSET      8
+#define IOMUXC_GPR2_BIT_MAPPING_CH1_MASK        (1<<IOMUXC_GPR2_BIT_MAPPING_CH1_OFFSET)
+#define IOMUXC_GPR2_BIT_MAPPING_CH1_JEIDA       (IOMUXC_GPR2_BITMAP_JEIDA<<IOMUXC_GPR2_BIT_MAPPING_CH1_OFFSET)
+#define IOMUXC_GPR2_BIT_MAPPING_CH1_SPWG        (IOMUXC_GPR2_BITMAP_SPWG<<IOMUXC_GPR2_BIT_MAPPING_CH1_OFFSET)
 
-#define IOMUXC_GPR2_DATA_WIDTH_CH1_OFFSET		7
-#define IOMUXC_GPR2_DATA_WIDTH_CH1_MASK			(1<<IOMUXC_GPR2_DATA_WIDTH_CH1_OFFSET)
-#define IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT		(IOMUXC_GPR2_DATA_WIDTH_18<<IOMUXC_GPR2_DATA_WIDTH_CH1_OFFSET)
-#define IOMUXC_GPR2_DATA_WIDTH_CH1_24BIT		(IOMUXC_GPR2_DATA_WIDTH_24<<IOMUXC_GPR2_DATA_WIDTH_CH1_OFFSET)
+#define IOMUXC_GPR2_DATA_WIDTH_18               0
+#define IOMUXC_GPR2_DATA_WIDTH_24               1
 
-#define IOMUXC_GPR2_BIT_MAPPING_CH0_OFFSET		6
-#define IOMUXC_GPR2_BIT_MAPPING_CH0_MASK		(1<<IOMUXC_GPR2_BIT_MAPPING_CH0_OFFSET)
-#define IOMUXC_GPR2_BIT_MAPPING_CH0_JEIDA		(IOMUXC_GPR2_BITMAP_JEIDA<<IOMUXC_GPR2_BIT_MAPPING_CH0_OFFSET)
-#define IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG		(IOMUXC_GPR2_BITMAP_SPWG<<IOMUXC_GPR2_BIT_MAPPING_CH0_OFFSET)
+#define IOMUXC_GPR2_DATA_WIDTH_CH1_OFFSET       7
+#define IOMUXC_GPR2_DATA_WIDTH_CH1_MASK         (1<<IOMUXC_GPR2_DATA_WIDTH_CH1_OFFSET)
+#define IOMUXC_GPR2_DATA_WIDTH_CH1_18BIT        (IOMUXC_GPR2_DATA_WIDTH_18<<IOMUXC_GPR2_DATA_WIDTH_CH1_OFFSET)
+#define IOMUXC_GPR2_DATA_WIDTH_CH1_24BIT        (IOMUXC_GPR2_DATA_WIDTH_24<<IOMUXC_GPR2_DATA_WIDTH_CH1_OFFSET)
 
-#define IOMUXC_GPR2_DATA_WIDTH_CH0_OFFSET		5
-#define IOMUXC_GPR2_DATA_WIDTH_CH0_MASK			(1<<IOMUXC_GPR2_DATA_WIDTH_CH0_OFFSET)
-#define IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT		(IOMUXC_GPR2_DATA_WIDTH_18<<IOMUXC_GPR2_DATA_WIDTH_CH0_OFFSET)
-#define IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT		(IOMUXC_GPR2_DATA_WIDTH_24<<IOMUXC_GPR2_DATA_WIDTH_CH0_OFFSET)
+#define IOMUXC_GPR2_BIT_MAPPING_CH0_OFFSET      6
+#define IOMUXC_GPR2_BIT_MAPPING_CH0_MASK        (1<<IOMUXC_GPR2_BIT_MAPPING_CH0_OFFSET)
+#define IOMUXC_GPR2_BIT_MAPPING_CH0_JEIDA       (IOMUXC_GPR2_BITMAP_JEIDA<<IOMUXC_GPR2_BIT_MAPPING_CH0_OFFSET)
+#define IOMUXC_GPR2_BIT_MAPPING_CH0_SPWG        (IOMUXC_GPR2_BITMAP_SPWG<<IOMUXC_GPR2_BIT_MAPPING_CH0_OFFSET)
 
-#define IOMUXC_GPR2_SPLIT_MODE_EN_OFFSET		4
-#define IOMUXC_GPR2_SPLIT_MODE_EN_MASK			(1<<IOMUXC_GPR2_SPLIT_MODE_EN_OFFSET)
+#define IOMUXC_GPR2_DATA_WIDTH_CH0_OFFSET       5
+#define IOMUXC_GPR2_DATA_WIDTH_CH0_MASK         (1<<IOMUXC_GPR2_DATA_WIDTH_CH0_OFFSET)
+#define IOMUXC_GPR2_DATA_WIDTH_CH0_18BIT        (IOMUXC_GPR2_DATA_WIDTH_18<<IOMUXC_GPR2_DATA_WIDTH_CH0_OFFSET)
+#define IOMUXC_GPR2_DATA_WIDTH_CH0_24BIT        (IOMUXC_GPR2_DATA_WIDTH_24<<IOMUXC_GPR2_DATA_WIDTH_CH0_OFFSET)
 
-#define IOMUXC_GPR2_MODE_DISABLED	0
-#define IOMUXC_GPR2_MODE_ENABLED_DI0	1
-#define IOMUXC_GPR2_MODE_ENABLED_DI1	2
+#define IOMUXC_GPR2_SPLIT_MODE_EN_OFFSET        4
+#define IOMUXC_GPR2_SPLIT_MODE_EN_MASK          (1<<IOMUXC_GPR2_SPLIT_MODE_EN_OFFSET)
 
-#define IOMUXC_GPR2_LVDS_CH1_MODE_OFFSET		2
-#define IOMUXC_GPR2_LVDS_CH1_MODE_MASK			(3<<IOMUXC_GPR2_LVDS_CH1_MODE_OFFSET)
-#define IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED		(IOMUXC_GPR2_MODE_DISABLED<<IOMUXC_GPR2_LVDS_CH1_MODE_OFFSET)
-#define IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0		(IOMUXC_GPR2_MODE_ENABLED_DI0<<IOMUXC_GPR2_LVDS_CH1_MODE_OFFSET)
-#define IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI1		(IOMUXC_GPR2_MODE_ENABLED_DI1<<IOMUXC_GPR2_LVDS_CH1_MODE_OFFSET)
+#define IOMUXC_GPR2_MODE_DISABLED               0
+#define IOMUXC_GPR2_MODE_ENABLED_DI0            1
+#define IOMUXC_GPR2_MODE_ENABLED_DI1            2
 
-#define IOMUXC_GPR2_LVDS_CH0_MODE_OFFSET		0
-#define IOMUXC_GPR2_LVDS_CH0_MODE_MASK			(3<<IOMUXC_GPR2_LVDS_CH0_MODE_OFFSET)
-#define IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED		(IOMUXC_GPR2_MODE_DISABLED<<IOMUXC_GPR2_LVDS_CH0_MODE_OFFSET)
-#define IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0		(IOMUXC_GPR2_MODE_ENABLED_DI0<<IOMUXC_GPR2_LVDS_CH0_MODE_OFFSET)
-#define IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI1		(IOMUXC_GPR2_MODE_ENABLED_DI1<<IOMUXC_GPR2_LVDS_CH0_MODE_OFFSET)
+#define IOMUXC_GPR2_LVDS_CH1_MODE_OFFSET        2
+#define IOMUXC_GPR2_LVDS_CH1_MODE_MASK          (3<<IOMUXC_GPR2_LVDS_CH1_MODE_OFFSET)
+#define IOMUXC_GPR2_LVDS_CH1_MODE_DISABLED      (IOMUXC_GPR2_MODE_DISABLED<<IOMUXC_GPR2_LVDS_CH1_MODE_OFFSET)
+#define IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI0   (IOMUXC_GPR2_MODE_ENABLED_DI0<<IOMUXC_GPR2_LVDS_CH1_MODE_OFFSET)
+#define IOMUXC_GPR2_LVDS_CH1_MODE_ENABLED_DI1   (IOMUXC_GPR2_MODE_ENABLED_DI1<<IOMUXC_GPR2_LVDS_CH1_MODE_OFFSET)
+
+#define IOMUXC_GPR2_LVDS_CH0_MODE_OFFSET        0
+#define IOMUXC_GPR2_LVDS_CH0_MODE_MASK          (3<<IOMUXC_GPR2_LVDS_CH0_MODE_OFFSET)
+#define IOMUXC_GPR2_LVDS_CH0_MODE_DISABLED      (IOMUXC_GPR2_MODE_DISABLED<<IOMUXC_GPR2_LVDS_CH0_MODE_OFFSET)
+#define IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI0   (IOMUXC_GPR2_MODE_ENABLED_DI0<<IOMUXC_GPR2_LVDS_CH0_MODE_OFFSET)
+#define IOMUXC_GPR2_LVDS_CH0_MODE_ENABLED_DI1   (IOMUXC_GPR2_MODE_ENABLED_DI1<<IOMUXC_GPR2_LVDS_CH0_MODE_OFFSET)
 
 /* ECSPI registers */
 struct cspi_regs {
-	uint32_t rxdata;
-	uint32_t txdata;
-	uint32_t ctrl;
-	uint32_t cfg;
-	uint32_t intr;
-	uint32_t dma;
-	uint32_t stat;
-	uint32_t period;
+    uint32_t rxdata;
+    uint32_t txdata;
+    uint32_t ctrl;
+    uint32_t cfg;
+    uint32_t intr;
+    uint32_t dma;
+    uint32_t stat;
+    uint32_t period;
 };
 
 /*
  * CSPI register definitions
  */
 #define MXC_ECSPI
-#define MXC_CSPICTRL_EN		(BIT(0))
-#define MXC_CSPICTRL_MODE	(BIT(1))
-#define MXC_CSPICTRL_XCH	(BIT(2))
-#define MXC_CSPICTRL_CHIPSELECT(x)	(((x) & 0x3) << 12)
-#define MXC_CSPICTRL_BITCOUNT(x)	(((x) & 0xfff) << 20)
-#define MXC_CSPICTRL_PREDIV(x)	(((x) & 0xF) << 12)
-#define MXC_CSPICTRL_POSTDIV(x)	(((x) & 0xF) << 8)
-#define MXC_CSPICTRL_SELCHAN(x)	(((x) & 0x3) << 18)
-#define MXC_CSPICTRL_MAXBITS	0xfff
-#define MXC_CSPICTRL_TC		(BIT(7))
-#define MXC_CSPICTRL_RXOVF	(BIT(6))
-#define MXC_CSPIPERIOD_32KHZ	(BIT(15))
-#define MAX_SPI_BYTES	32
+#define MXC_CSPICTRL_EN             (BIT(0))
+#define MXC_CSPICTRL_MODE           (BIT(1))
+#define MXC_CSPICTRL_XCH            (BIT(2))
+#define MXC_CSPICTRL_CHIPSELECT(x)  (((x) & 0x3) << 12)
+#define MXC_CSPICTRL_BITCOUNT(x)    (((x) & 0xfff) << 20)
+#define MXC_CSPICTRL_PREDIV(x)      (((x) & 0xF) << 12)
+#define MXC_CSPICTRL_POSTDIV(x)     (((x) & 0xF) << 8)
+#define MXC_CSPICTRL_SELCHAN(x)     (((x) & 0x3) << 18)
+#define MXC_CSPICTRL_MAXBITS        0xfff
+#define MXC_CSPICTRL_TC             (BIT(7))
+#define MXC_CSPICTRL_RXOVF          (BIT(6))
+#define MXC_CSPIPERIOD_32KHZ        (BIT(15))
+#define MAX_SPI_BYTES               32
 
 /* Bit position inside CTRL register to be associated with SS */
-#define MXC_CSPICTRL_CHAN	18
+#define MXC_CSPICTRL_CHAN   18
 
 /* Bit position inside CON register to be associated with SS */
-#define MXC_CSPICON_POL		4
-#define MXC_CSPICON_PHA		0
-#define MXC_CSPICON_SSPOL	12
+#define MXC_CSPICON_POL     4
+#define MXC_CSPICON_PHA     0
+#define MXC_CSPICON_SSPOL   12
 #define MXC_SPI_BASE_ADDRESSES \
-	ECSPI1_BASE_ADDR, \
-	ECSPI2_BASE_ADDR, \
-	ECSPI3_BASE_ADDR, \
-	ECSPI4_BASE_ADDR, \
-	ECSPI5_BASE_ADDR
+    ECSPI1_BASE_ADDR, \
+    ECSPI2_BASE_ADDR, \
+    ECSPI3_BASE_ADDR, \
+    ECSPI4_BASE_ADDR, \
+    ECSPI5_BASE_ADDR
 
 struct iim_regs {
-	uint32_t	ctrl;
-	uint32_t	ctrl_set;
-	uint32_t     ctrl_clr;
-	uint32_t	ctrl_tog;
-	uint32_t	timing;
-	uint32_t     rsvd0[3];
-	uint32_t     data;
-	uint32_t     rsvd1[3];
-	uint32_t     read_ctrl;
-	uint32_t     rsvd2[3];
-	uint32_t     fuse_data;
-	uint32_t     rsvd3[3];
-	uint32_t     sticky;
-	uint32_t     rsvd4[3];
-	uint32_t     scs;
-	uint32_t     scs_set;
-	uint32_t     scs_clr;
-	uint32_t     scs_tog;
-	uint32_t     crc_addr;
-	uint32_t     rsvd5[3];
-	uint32_t     crc_value;
-	uint32_t     rsvd6[3];
-	uint32_t     version;
-	uint32_t     rsvd7[0xdb];
+    uint32_t    ctrl;
+    uint32_t    ctrl_set;
+    uint32_t    ctrl_clr;
+    uint32_t    ctrl_tog;
+    uint32_t    timing;
+    uint32_t    rsvd0[3];
+    uint32_t    data;
+    uint32_t    rsvd1[3];
+    uint32_t    read_ctrl;
+    uint32_t    rsvd2[3];
+    uint32_t    fuse_data;
+    uint32_t    rsvd3[3];
+    uint32_t    sticky;
+    uint32_t    rsvd4[3];
+    uint32_t    scs;
+    uint32_t    scs_set;
+    uint32_t    scs_clr;
+    uint32_t    scs_tog;
+    uint32_t    crc_addr;
+    uint32_t    rsvd5[3];
+    uint32_t    crc_value;
+    uint32_t    rsvd6[3];
+    uint32_t    version;
+    uint32_t    rsvd7[0xdb];
 
-	struct fuse_bank {
-		uint32_t	fuse_regs[0x20];
-	} bank[15];
+    struct fuse_bank {
+        uint32_t    fuse_regs[0x20];
+    } bank[15];
 };
 
 struct fuse_bank4_regs {
-	uint32_t	sjc_resp_low;
-	uint32_t     rsvd0[3];
-	uint32_t     sjc_resp_high;
-	uint32_t     rsvd1[3];
-	uint32_t	mac_addr_low;
-	uint32_t     rsvd2[3];
-	uint32_t     mac_addr_high;
-	uint32_t	rsvd3[0x13];
+    uint32_t    sjc_resp_low;
+    uint32_t    rsvd0[3];
+    uint32_t    sjc_resp_high;
+    uint32_t    rsvd1[3];
+    uint32_t    mac_addr_low;
+    uint32_t    rsvd2[3];
+    uint32_t    mac_addr_high;
+    uint32_t    rsvd3[0x13];
 };
 
 struct aipstz_regs {
-	uint32_t	mprot0;
-	uint32_t	mprot1;
-	uint32_t	rsvd[0xe];
-	uint32_t	opacr0;
-	uint32_t	opacr1;
-	uint32_t	opacr2;
-	uint32_t	opacr3;
-	uint32_t	opacr4;
+    uint32_t    mprot0;
+    uint32_t    mprot1;
+    uint32_t    rsvd[0xe];
+    uint32_t    opacr0;
+    uint32_t    opacr1;
+    uint32_t    opacr2;
+    uint32_t    opacr3;
+    uint32_t    opacr4;
 };
 
 struct anatop_regs {
-	uint32_t	pll_sys;		/* 0x000 */
-	uint32_t	pll_sys_set;		/* 0x004 */
-	uint32_t	pll_sys_clr;		/* 0x008 */
-	uint32_t	pll_sys_tog;		/* 0x00c */
-	uint32_t	usb1_pll_480_ctrl;	/* 0x010 */
-	uint32_t	usb1_pll_480_ctrl_set;	/* 0x014 */
-	uint32_t	usb1_pll_480_ctrl_clr;	/* 0x018 */
-	uint32_t	usb1_pll_480_ctrl_tog;	/* 0x01c */
-	uint32_t	usb2_pll_480_ctrl;	/* 0x020 */
-	uint32_t	usb2_pll_480_ctrl_set;	/* 0x024 */
-	uint32_t	usb2_pll_480_ctrl_clr;	/* 0x028 */
-	uint32_t	usb2_pll_480_ctrl_tog;	/* 0x02c */
-	uint32_t	pll_528;		/* 0x030 */
-	uint32_t	pll_528_set;		/* 0x034 */
-	uint32_t	pll_528_clr;		/* 0x038 */
-	uint32_t	pll_528_tog;		/* 0x03c */
-	uint32_t	pll_528_ss;		/* 0x040 */
-	uint32_t	rsvd0[3];
-	uint32_t	pll_528_num;		/* 0x050 */
-	uint32_t	rsvd1[3];
-	uint32_t	pll_528_denom;		/* 0x060 */
-	uint32_t	rsvd2[3];
-	uint32_t	pll_audio;		/* 0x070 */
-	uint32_t	pll_audio_set;		/* 0x074 */
-	uint32_t	pll_audio_clr;		/* 0x078 */
-	uint32_t	pll_audio_tog;		/* 0x07c */
-	uint32_t	pll_audio_num;		/* 0x080 */
-	uint32_t	rsvd3[3];
-	uint32_t	pll_audio_denom;	/* 0x090 */
-	uint32_t	rsvd4[3];
-	uint32_t	pll_video;		/* 0x0a0 */
-	uint32_t	pll_video_set;		/* 0x0a4 */
-	uint32_t	pll_video_clr;		/* 0x0a8 */
-	uint32_t	pll_video_tog;		/* 0x0ac */
-	uint32_t	pll_video_num;		/* 0x0b0 */
-	uint32_t	rsvd5[3];
-	uint32_t	pll_video_denom;	/* 0x0c0 */
-	uint32_t	rsvd6[3];
-	uint32_t	pll_mlb;		/* 0x0d0 */
-	uint32_t	pll_mlb_set;		/* 0x0d4 */
-	uint32_t	pll_mlb_clr;		/* 0x0d8 */
-	uint32_t	pll_mlb_tog;		/* 0x0dc */
-	uint32_t	pll_enet;		/* 0x0e0 */
-	uint32_t	pll_enet_set;		/* 0x0e4 */
-	uint32_t	pll_enet_clr;		/* 0x0e8 */
-	uint32_t	pll_enet_tog;		/* 0x0ec */
-	uint32_t	pfd_480;		/* 0x0f0 */
-	uint32_t	pfd_480_set;		/* 0x0f4 */
-	uint32_t	pfd_480_clr;		/* 0x0f8 */
-	uint32_t	pfd_480_tog;		/* 0x0fc */
-	uint32_t	pfd_528;		/* 0x100 */
-	uint32_t	pfd_528_set;		/* 0x104 */
-	uint32_t	pfd_528_clr;		/* 0x108 */
-	uint32_t	pfd_528_tog;		/* 0x10c */
-	uint32_t	reg_1p1;		/* 0x110 */
-	uint32_t	reg_1p1_set;		/* 0x114 */
-	uint32_t	reg_1p1_clr;		/* 0x118 */
-	uint32_t	reg_1p1_tog;		/* 0x11c */
-	uint32_t	reg_3p0;		/* 0x120 */
-	uint32_t	reg_3p0_set;		/* 0x124 */
-	uint32_t	reg_3p0_clr;		/* 0x128 */
-	uint32_t	reg_3p0_tog;		/* 0x12c */
-	uint32_t	reg_2p5;		/* 0x130 */
-	uint32_t	reg_2p5_set;		/* 0x134 */
-	uint32_t	reg_2p5_clr;		/* 0x138 */
-	uint32_t	reg_2p5_tog;		/* 0x13c */
-	uint32_t	reg_core;		/* 0x140 */
-	uint32_t	reg_core_set;		/* 0x144 */
-	uint32_t	reg_core_clr;		/* 0x148 */
-	uint32_t	reg_core_tog;		/* 0x14c */
-	uint32_t	ana_misc0;		/* 0x150 */
-	uint32_t	ana_misc0_set;		/* 0x154 */
-	uint32_t	ana_misc0_clr;		/* 0x158 */
-	uint32_t	ana_misc0_tog;		/* 0x15c */
-	uint32_t	ana_misc1;		/* 0x160 */
-	uint32_t	ana_misc1_set;		/* 0x164 */
-	uint32_t	ana_misc1_clr;		/* 0x168 */
-	uint32_t	ana_misc1_tog;		/* 0x16c */
-	uint32_t	ana_misc2;		/* 0x170 */
-	uint32_t	ana_misc2_set;		/* 0x174 */
-	uint32_t	ana_misc2_clr;		/* 0x178 */
-	uint32_t	ana_misc2_tog;		/* 0x17c */
-	uint32_t	tempsense0;		/* 0x180 */
-	uint32_t	tempsense0_set;		/* 0x184 */
-	uint32_t	tempsense0_clr;		/* 0x188 */
-	uint32_t	tempsense0_tog;		/* 0x18c */
-	uint32_t	tempsense1;		/* 0x190 */
-	uint32_t	tempsense1_set;		/* 0x194 */
-	uint32_t	tempsense1_clr;		/* 0x198 */
-	uint32_t	tempsense1_tog;		/* 0x19c */
-	uint32_t	usb1_vbus_detect;	/* 0x1a0 */
-	uint32_t	usb1_vbus_detect_set;	/* 0x1a4 */
-	uint32_t	usb1_vbus_detect_clr;	/* 0x1a8 */
-	uint32_t	usb1_vbus_detect_tog;	/* 0x1ac */
-	uint32_t	usb1_chrg_detect;	/* 0x1b0 */
-	uint32_t	usb1_chrg_detect_set;	/* 0x1b4 */
-	uint32_t	usb1_chrg_detect_clr;	/* 0x1b8 */
-	uint32_t	usb1_chrg_detect_tog;	/* 0x1bc */
-	uint32_t	usb1_vbus_det_stat;	/* 0x1c0 */
-	uint32_t	usb1_vbus_det_stat_set;	/* 0x1c4 */
-	uint32_t	usb1_vbus_det_stat_clr;	/* 0x1c8 */
-	uint32_t	usb1_vbus_det_stat_tog;	/* 0x1cc */
-	uint32_t	usb1_chrg_det_stat;	/* 0x1d0 */
-	uint32_t	usb1_chrg_det_stat_set;	/* 0x1d4 */
-	uint32_t	usb1_chrg_det_stat_clr;	/* 0x1d8 */
-	uint32_t	usb1_chrg_det_stat_tog;	/* 0x1dc */
-	uint32_t	usb1_loopback;		/* 0x1e0 */
-	uint32_t	usb1_loopback_set;	/* 0x1e4 */
-	uint32_t	usb1_loopback_clr;	/* 0x1e8 */
-	uint32_t	usb1_loopback_tog;	/* 0x1ec */
-	uint32_t	usb1_misc;		/* 0x1f0 */
-	uint32_t	usb1_misc_set;		/* 0x1f4 */
-	uint32_t	usb1_misc_clr;		/* 0x1f8 */
-	uint32_t	usb1_misc_tog;		/* 0x1fc */
-	uint32_t	usb2_vbus_detect;	/* 0x200 */
-	uint32_t	usb2_vbus_detect_set;	/* 0x204 */
-	uint32_t	usb2_vbus_detect_clr;	/* 0x208 */
-	uint32_t	usb2_vbus_detect_tog;	/* 0x20c */
-	uint32_t	usb2_chrg_detect;	/* 0x210 */
-	uint32_t	usb2_chrg_detect_set;	/* 0x214 */
-	uint32_t	usb2_chrg_detect_clr;	/* 0x218 */
-	uint32_t	usb2_chrg_detect_tog;	/* 0x21c */
-	uint32_t	usb2_vbus_det_stat;	/* 0x220 */
-	uint32_t	usb2_vbus_det_stat_set;	/* 0x224 */
-	uint32_t	usb2_vbus_det_stat_clr;	/* 0x228 */
-	uint32_t	usb2_vbus_det_stat_tog;	/* 0x22c */
-	uint32_t	usb2_chrg_det_stat;	/* 0x230 */
-	uint32_t	usb2_chrg_det_stat_set;	/* 0x234 */
-	uint32_t	usb2_chrg_det_stat_clr;	/* 0x238 */
-	uint32_t	usb2_chrg_det_stat_tog;	/* 0x23c */
-	uint32_t	usb2_loopback;		/* 0x240 */
-	uint32_t	usb2_loopback_set;	/* 0x244 */
-	uint32_t	usb2_loopback_clr;	/* 0x248 */
-	uint32_t	usb2_loopback_tog;	/* 0x24c */
-	uint32_t	usb2_misc;		/* 0x250 */
-	uint32_t	usb2_misc_set;		/* 0x254 */
-	uint32_t	usb2_misc_clr;		/* 0x258 */
-	uint32_t	usb2_misc_tog;		/* 0x25c */
-	uint32_t	digprog;		/* 0x260 */
-	uint32_t	reserved1[7];
-	uint32_t	digprog_sololite;	/* 0x280 */
+    uint32_t    pll_sys;                /* 0x000 */
+    uint32_t    pll_sys_set;            /* 0x004 */
+    uint32_t    pll_sys_clr;            /* 0x008 */
+    uint32_t    pll_sys_tog;            /* 0x00c */
+    uint32_t    usb1_pll_480_ctrl;      /* 0x010 */
+    uint32_t    usb1_pll_480_ctrl_set;  /* 0x014 */
+    uint32_t    usb1_pll_480_ctrl_clr;  /* 0x018 */
+    uint32_t    usb1_pll_480_ctrl_tog;  /* 0x01c */
+    uint32_t    usb2_pll_480_ctrl;      /* 0x020 */
+    uint32_t    usb2_pll_480_ctrl_set;  /* 0x024 */
+    uint32_t    usb2_pll_480_ctrl_clr;  /* 0x028 */
+    uint32_t    usb2_pll_480_ctrl_tog;  /* 0x02c */
+    uint32_t    pll_528;                /* 0x030 */
+    uint32_t    pll_528_set;            /* 0x034 */
+    uint32_t    pll_528_clr;            /* 0x038 */
+    uint32_t    pll_528_tog;            /* 0x03c */
+    uint32_t    pll_528_ss;             /* 0x040 */
+    uint32_t    rsvd0[3];
+    uint32_t    pll_528_num;            /* 0x050 */
+    uint32_t    rsvd1[3];
+    uint32_t    pll_528_denom;          /* 0x060 */
+    uint32_t    rsvd2[3];
+    uint32_t    pll_audio;              /* 0x070 */
+    uint32_t    pll_audio_set;          /* 0x074 */
+    uint32_t    pll_audio_clr;          /* 0x078 */
+    uint32_t    pll_audio_tog;          /* 0x07c */
+    uint32_t    pll_audio_num;          /* 0x080 */
+    uint32_t    rsvd3[3];
+    uint32_t    pll_audio_denom;        /* 0x090 */
+    uint32_t    rsvd4[3];
+    uint32_t    pll_video;              /* 0x0a0 */
+    uint32_t    pll_video_set;          /* 0x0a4 */
+    uint32_t    pll_video_clr;          /* 0x0a8 */
+    uint32_t    pll_video_tog;          /* 0x0ac */
+    uint32_t    pll_video_num;          /* 0x0b0 */
+    uint32_t    rsvd5[3];
+    uint32_t    pll_video_denom;        /* 0x0c0 */
+    uint32_t    rsvd6[3];
+    uint32_t    pll_mlb;                /* 0x0d0 */
+    uint32_t    pll_mlb_set;            /* 0x0d4 */
+    uint32_t    pll_mlb_clr;            /* 0x0d8 */
+    uint32_t    pll_mlb_tog;            /* 0x0dc */
+    uint32_t    pll_enet;               /* 0x0e0 */
+    uint32_t    pll_enet_set;           /* 0x0e4 */
+    uint32_t    pll_enet_clr;           /* 0x0e8 */
+    uint32_t    pll_enet_tog;           /* 0x0ec */
+    uint32_t    pfd_480;                /* 0x0f0 */
+    uint32_t    pfd_480_set;            /* 0x0f4 */
+    uint32_t    pfd_480_clr;            /* 0x0f8 */
+    uint32_t    pfd_480_tog;            /* 0x0fc */
+    uint32_t    pfd_528;                /* 0x100 */
+    uint32_t    pfd_528_set;            /* 0x104 */
+    uint32_t    pfd_528_clr;            /* 0x108 */
+    uint32_t    pfd_528_tog;            /* 0x10c */
+    uint32_t    reg_1p1;                /* 0x110 */
+    uint32_t    reg_1p1_set;            /* 0x114 */
+    uint32_t    reg_1p1_clr;            /* 0x118 */
+    uint32_t    reg_1p1_tog;            /* 0x11c */
+    uint32_t    reg_3p0;                /* 0x120 */
+    uint32_t    reg_3p0_set;            /* 0x124 */
+    uint32_t    reg_3p0_clr;            /* 0x128 */
+    uint32_t    reg_3p0_tog;            /* 0x12c */
+    uint32_t    reg_2p5;                /* 0x130 */
+    uint32_t    reg_2p5_set;            /* 0x134 */
+    uint32_t    reg_2p5_clr;            /* 0x138 */
+    uint32_t    reg_2p5_tog;            /* 0x13c */
+    uint32_t    reg_core;               /* 0x140 */
+    uint32_t    reg_core_set;           /* 0x144 */
+    uint32_t    reg_core_clr;           /* 0x148 */
+    uint32_t    reg_core_tog;           /* 0x14c */
+    uint32_t    ana_misc0;              /* 0x150 */
+    uint32_t    ana_misc0_set;          /* 0x154 */
+    uint32_t    ana_misc0_clr;          /* 0x158 */
+    uint32_t    ana_misc0_tog;          /* 0x15c */
+    uint32_t    ana_misc1;              /* 0x160 */
+    uint32_t    ana_misc1_set;          /* 0x164 */
+    uint32_t    ana_misc1_clr;          /* 0x168 */
+    uint32_t    ana_misc1_tog;          /* 0x16c */
+    uint32_t    ana_misc2;              /* 0x170 */
+    uint32_t    ana_misc2_set;          /* 0x174 */
+    uint32_t    ana_misc2_clr;          /* 0x178 */
+    uint32_t    ana_misc2_tog;          /* 0x17c */
+    uint32_t    tempsense0;             /* 0x180 */
+    uint32_t    tempsense0_set;         /* 0x184 */
+    uint32_t    tempsense0_clr;         /* 0x188 */
+    uint32_t    tempsense0_tog;         /* 0x18c */
+    uint32_t    tempsense1;             /* 0x190 */
+    uint32_t    tempsense1_set;         /* 0x194 */
+    uint32_t    tempsense1_clr;         /* 0x198 */
+    uint32_t    tempsense1_tog;         /* 0x19c */
+    uint32_t    usb1_vbus_detect;       /* 0x1a0 */
+    uint32_t    usb1_vbus_detect_set;   /* 0x1a4 */
+    uint32_t    usb1_vbus_detect_clr;   /* 0x1a8 */
+    uint32_t    usb1_vbus_detect_tog;   /* 0x1ac */
+    uint32_t    usb1_chrg_detect;       /* 0x1b0 */
+    uint32_t    usb1_chrg_detect_set;   /* 0x1b4 */
+    uint32_t    usb1_chrg_detect_clr;   /* 0x1b8 */
+    uint32_t    usb1_chrg_detect_tog;   /* 0x1bc */
+    uint32_t    usb1_vbus_det_stat;     /* 0x1c0 */
+    uint32_t    usb1_vbus_det_stat_set; /* 0x1c4 */
+    uint32_t    usb1_vbus_det_stat_clr; /* 0x1c8 */
+    uint32_t    usb1_vbus_det_stat_tog; /* 0x1cc */
+    uint32_t    usb1_chrg_det_stat;     /* 0x1d0 */
+    uint32_t    usb1_chrg_det_stat_set; /* 0x1d4 */
+    uint32_t    usb1_chrg_det_stat_clr; /* 0x1d8 */
+    uint32_t    usb1_chrg_det_stat_tog; /* 0x1dc */
+    uint32_t    usb1_loopback;          /* 0x1e0 */
+    uint32_t    usb1_loopback_set;      /* 0x1e4 */
+    uint32_t    usb1_loopback_clr;      /* 0x1e8 */
+    uint32_t    usb1_loopback_tog;      /* 0x1ec */
+    uint32_t    usb1_misc;              /* 0x1f0 */
+    uint32_t    usb1_misc_set;          /* 0x1f4 */
+    uint32_t    usb1_misc_clr;          /* 0x1f8 */
+    uint32_t    usb1_misc_tog;          /* 0x1fc */
+    uint32_t    usb2_vbus_detect;       /* 0x200 */
+    uint32_t    usb2_vbus_detect_set;   /* 0x204 */
+    uint32_t    usb2_vbus_detect_clr;   /* 0x208 */
+    uint32_t    usb2_vbus_detect_tog;   /* 0x20c */
+    uint32_t    usb2_chrg_detect;       /* 0x210 */
+    uint32_t    usb2_chrg_detect_set;   /* 0x214 */
+    uint32_t    usb2_chrg_detect_clr;   /* 0x218 */
+    uint32_t    usb2_chrg_detect_tog;   /* 0x21c */
+    uint32_t    usb2_vbus_det_stat;     /* 0x220 */
+    uint32_t    usb2_vbus_det_stat_set; /* 0x224 */
+    uint32_t    usb2_vbus_det_stat_clr; /* 0x228 */
+    uint32_t    usb2_vbus_det_stat_tog; /* 0x22c */
+    uint32_t    usb2_chrg_det_stat;     /* 0x230 */
+    uint32_t    usb2_chrg_det_stat_set; /* 0x234 */
+    uint32_t    usb2_chrg_det_stat_clr; /* 0x238 */
+    uint32_t    usb2_chrg_det_stat_tog; /* 0x23c */
+    uint32_t    usb2_loopback;          /* 0x240 */
+    uint32_t    usb2_loopback_set;      /* 0x244 */
+    uint32_t    usb2_loopback_clr;      /* 0x248 */
+    uint32_t    usb2_loopback_tog;      /* 0x24c */
+    uint32_t    usb2_misc;              /* 0x250 */
+    uint32_t    usb2_misc_set;          /* 0x254 */
+    uint32_t    usb2_misc_clr;          /* 0x258 */
+    uint32_t    usb2_misc_tog;          /* 0x25c */
+    uint32_t    digprog;                /* 0x260 */
+    uint32_t    reserved1[7];
+    uint32_t    digprog_sololite;       /* 0x280 */
 };
 
-#define ANATOP_PFD_480_PFD0_FRAC_SHIFT		0
-#define ANATOP_PFD_480_PFD0_FRAC_MASK		(0x3f<<ANATOP_PFD_480_PFD0_FRAC_SHIFT)
-#define ANATOP_PFD_480_PFD0_STABLE_SHIFT	6
-#define ANATOP_PFD_480_PFD0_STABLE_MASK		(1<<ANATOP_PFD_480_PFD0_STABLE_SHIFT)
-#define ANATOP_PFD_480_PFD0_CLKGATE_SHIFT	7
-#define ANATOP_PFD_480_PFD0_CLKGATE_MASK	(1<<ANATOP_PFD_480_PFD0_CLKGATE_SHIFT)
-#define ANATOP_PFD_480_PFD1_FRAC_SHIFT		8
-#define ANATOP_PFD_480_PFD1_FRAC_MASK		(0x3f<<ANATOP_PFD_480_PFD1_FRAC_SHIFT)
-#define ANATOP_PFD_480_PFD1_STABLE_SHIFT	14
-#define ANATOP_PFD_480_PFD1_STABLE_MASK		(1<<ANATOP_PFD_480_PFD1_STABLE_SHIFT)
-#define ANATOP_PFD_480_PFD1_CLKGATE_SHIFT	15
-#define ANATOP_PFD_480_PFD1_CLKGATE_MASK	(0x3f<<ANATOP_PFD_480_PFD1_CLKGATE_SHIFT)
-#define ANATOP_PFD_480_PFD2_FRAC_SHIFT		16
-#define ANATOP_PFD_480_PFD2_FRAC_MASK		(1<<ANATOP_PFD_480_PFD2_FRAC_SHIFT)
-#define ANATOP_PFD_480_PFD2_STABLE_SHIFT	22
-#define ANATOP_PFD_480_PFD2_STABLE_MASK	(1<<ANATOP_PFD_480_PFD2_STABLE_SHIFT)
-#define ANATOP_PFD_480_PFD2_CLKGATE_SHIFT	23
-#define ANATOP_PFD_480_PFD2_CLKGATE_MASK	(0x3f<<ANATOP_PFD_480_PFD2_CLKGATE_SHIFT)
-#define ANATOP_PFD_480_PFD3_FRAC_SHIFT		24
-#define ANATOP_PFD_480_PFD3_FRAC_MASK		(1<<ANATOP_PFD_480_PFD3_FRAC_SHIFT)
-#define ANATOP_PFD_480_PFD3_STABLE_SHIFT	30
-#define ANATOP_PFD_480_PFD3_STABLE_MASK		(1<<ANATOP_PFD_480_PFD3_STABLE_SHIFT)
-#define ANATOP_PFD_480_PFD3_CLKGATE_SHIFT	31
+#define ANATOP_PFD_480_PFD0_FRAC_SHIFT      0
+#define ANATOP_PFD_480_PFD0_FRAC_MASK       (0x3f<<ANATOP_PFD_480_PFD0_FRAC_SHIFT)
+#define ANATOP_PFD_480_PFD0_STABLE_SHIFT    6
+#define ANATOP_PFD_480_PFD0_STABLE_MASK     (1<<ANATOP_PFD_480_PFD0_STABLE_SHIFT)
+#define ANATOP_PFD_480_PFD0_CLKGATE_SHIFT   7
+#define ANATOP_PFD_480_PFD0_CLKGATE_MASK    (1<<ANATOP_PFD_480_PFD0_CLKGATE_SHIFT)
+#define ANATOP_PFD_480_PFD1_FRAC_SHIFT      8
+#define ANATOP_PFD_480_PFD1_FRAC_MASK       (0x3f<<ANATOP_PFD_480_PFD1_FRAC_SHIFT)
+#define ANATOP_PFD_480_PFD1_STABLE_SHIFT    14
+#define ANATOP_PFD_480_PFD1_STABLE_MASK     (1<<ANATOP_PFD_480_PFD1_STABLE_SHIFT)
+#define ANATOP_PFD_480_PFD1_CLKGATE_SHIFT   15
+#define ANATOP_PFD_480_PFD1_CLKGATE_MASK    (0x3f<<ANATOP_PFD_480_PFD1_CLKGATE_SHIFT)
+#define ANATOP_PFD_480_PFD2_FRAC_SHIFT      16
+#define ANATOP_PFD_480_PFD2_FRAC_MASK       (1<<ANATOP_PFD_480_PFD2_FRAC_SHIFT)
+#define ANATOP_PFD_480_PFD2_STABLE_SHIFT    22
+#define ANATOP_PFD_480_PFD2_STABLE_MASK     (1<<ANATOP_PFD_480_PFD2_STABLE_SHIFT)
+#define ANATOP_PFD_480_PFD2_CLKGATE_SHIFT   23
+#define ANATOP_PFD_480_PFD2_CLKGATE_MASK    (0x3f<<ANATOP_PFD_480_PFD2_CLKGATE_SHIFT)
+#define ANATOP_PFD_480_PFD3_FRAC_SHIFT      24
+#define ANATOP_PFD_480_PFD3_FRAC_MASK       (1<<ANATOP_PFD_480_PFD3_FRAC_SHIFT)
+#define ANATOP_PFD_480_PFD3_STABLE_SHIFT    30
+#define ANATOP_PFD_480_PFD3_STABLE_MASK     (1<<ANATOP_PFD_480_PFD3_STABLE_SHIFT)
+#define ANATOP_PFD_480_PFD3_CLKGATE_SHIFT   31
 
 struct iomuxc_base_regs {
-	uint32_t     gpr[14];        /* 0x000 */
-	uint32_t     obsrv[5];       /* 0x038 */
-	uint32_t     swmux_ctl[197]; /* 0x04c */
-	uint32_t     swpad_ctl[250]; /* 0x360 */
-	uint32_t     swgrp[26];      /* 0x748 */
-	uint32_t     daisy[104];     /* 0x7b0..94c */
+    uint32_t    gpr[14];        /* 0x000 */
+    uint32_t    obsrv[5];       /* 0x038 */
+    uint32_t    swmux_ctl[197]; /* 0x04c */
+    uint32_t    swpad_ctl[250]; /* 0x360 */
+    uint32_t    swgrp[26];      /* 0x748 */
+    uint32_t    daisy[104];     /* 0x7b0..94c */
 };
 
-#define BP_OCOTP_CTRL_WR_UNLOCK		16
-#define BM_OCOTP_CTRL_WR_UNLOCK		0xFFFF0000
-#define BV_OCOTP_CTRL_WR_UNLOCK__KEY	0x3E77
-#define BM_OCOTP_CTRL_RELOAD_SHADOWS	0x00000400
-#define BM_OCOTP_CTRL_ERROR		0x00000200
-#define BM_OCOTP_CTRL_BUSY		0x00000100
-#define BP_OCOTP_CTRL_ADDR		0
-#define BM_OCOTP_CTRL_ADDR		0x0000007F
+#define BP_OCOTP_CTRL_WR_UNLOCK         16
+#define BM_OCOTP_CTRL_WR_UNLOCK         0xFFFF0000
+#define BV_OCOTP_CTRL_WR_UNLOCK__KEY    0x3E77
+#define BM_OCOTP_CTRL_RELOAD_SHADOWS    0x00000400
+#define BM_OCOTP_CTRL_ERROR             0x00000200
+#define BM_OCOTP_CTRL_BUSY              0x00000100
+#define BP_OCOTP_CTRL_ADDR              0
+#define BM_OCOTP_CTRL_ADDR              0x0000007F
 
-#define BP_OCOTP_TIMING_STROBE_READ	16
-#define BM_OCOTP_TIMING_STROBE_READ	0x003F0000
-#define BP_OCOTP_TIMING_RELAX		12
-#define BM_OCOTP_TIMING_RELAX		0x0000F000
+#define BP_OCOTP_TIMING_STROBE_READ     16
+#define BM_OCOTP_TIMING_STROBE_READ     0x003F0000
+#define BP_OCOTP_TIMING_RELAX           12
+#define BM_OCOTP_TIMING_RELAX           0x0000F000
 #define BP_OCOTP_TIMING_STROBE_PROG     0
-#define BM_OCOTP_TIMING_STROBE_PROG	0x00000FFF
+#define BM_OCOTP_TIMING_STROBE_PROG     0x00000FFF
 
-#define BM_OCOTP_READ_CTRL_READ_FUSE	0x00000001
+#define BM_OCOTP_READ_CTRL_READ_FUSE    0x00000001
 
 #endif /* __ASSEMBLER__*/
diff --git a/libethdrivers/src/plat/imx6/uboot/imx6dq_pins.h b/libethdrivers/src/plat/imx6/uboot/imx6dq_pins.h
new file mode 100644
index 0000000..000430e
--- /dev/null
+++ b/libethdrivers/src/plat/imx6/uboot/imx6dq_pins.h
@@ -0,0 +1,1632 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2020, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#pragma once
+
+#include "imx_pins.h"
+
+#ifndef CONFIG_PLAT_IMX6DQ
+/* all definitions here are for the i.MX6 Dual/Quad SoC */
+#error "CONFIG_PLAT_IMX6DQ not defined, check settings"
+#endif
+
+enum {
+    MX6Q_PAD_SD2_DAT1__USDHC2_DAT1              = IOMUX_PAD(0x0360, 0x004C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT1__ECSPI5_SS0               = IOMUX_PAD(0x0360, 0x004C, 1, 0x0834, 0, 0),
+    MX6Q_PAD_SD2_DAT1__WEIM_WEIM_CS_2           = IOMUX_PAD(0x0360, 0x004C, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS         = IOMUX_PAD(0x0360, 0x004C, 3, 0x07C8, 0, 0),
+    MX6Q_PAD_SD2_DAT1__KPP_COL_7                = IOMUX_PAD(0x0360, 0x004C, 4, 0x08F0, 0, 0),
+    MX6Q_PAD_SD2_DAT1__GPIO_1_14                = IOMUX_PAD(0x0360, 0x004C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT1__CCM_WAIT                 = IOMUX_PAD(0x0360, 0x004C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT1__ANATOP_TESTO_0           = IOMUX_PAD(0x0360, 0x004C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT2__USDHC2_DAT2              = IOMUX_PAD(0x0364, 0x0050, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT2__ECSPI5_SS1               = IOMUX_PAD(0x0364, 0x0050, 1, 0x0838, 0, 0),
+    MX6Q_PAD_SD2_DAT2__WEIM_WEIM_CS_3           = IOMUX_PAD(0x0364, 0x0050, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD          = IOMUX_PAD(0x0364, 0x0050, 3, 0x07B8, 0, 0),
+    MX6Q_PAD_SD2_DAT2__KPP_ROW_6                = IOMUX_PAD(0x0364, 0x0050, 4, 0x08F8, 0, 0),
+    MX6Q_PAD_SD2_DAT2__GPIO_1_13                = IOMUX_PAD(0x0364, 0x0050, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT2__CCM_STOP                 = IOMUX_PAD(0x0364, 0x0050, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT2__ANATOP_TESTO_1           = IOMUX_PAD(0x0364, 0x0050, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT0__USDHC2_DAT0              = IOMUX_PAD(0x0368, 0x0054, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT0__ECSPI5_MISO              = IOMUX_PAD(0x0368, 0x0054, 1, 0x082C, 0, 0),
+    MX6Q_PAD_SD2_DAT0__AUDMUX_AUD4_RXD          = IOMUX_PAD(0x0368, 0x0054, 3, 0x07B4, 0, 0),
+    MX6Q_PAD_SD2_DAT0__KPP_ROW_7                = IOMUX_PAD(0x0368, 0x0054, 4, 0x08FC, 0, 0),
+    MX6Q_PAD_SD2_DAT0__GPIO_1_15                = IOMUX_PAD(0x0368, 0x0054, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT0__DCIC2_DCIC_OUT           = IOMUX_PAD(0x0368, 0x0054, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT0__TESTO_2                  = IOMUX_PAD(0x0368, 0x0054, 7, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TXC__USBOH3_H2_DATA          = IOMUX_PAD(0x036C, 0x0058, 0, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC          = IOMUX_PAD(0x036C, 0x0058, 1, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TXC__SPDIF_SPDIF_EXTCLK      = IOMUX_PAD(0x036C, 0x0058, 2, 0x0918, 0, 0),
+    MX6Q_PAD_RGMII_TXC__GPIO_6_19               = IOMUX_PAD(0x036C, 0x0058, 5, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TXC__MIPI_CORE_DPHY_IN_0     = IOMUX_PAD(0x036C, 0x0058, 6, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TXC__ANATOP_24M_OUT          = IOMUX_PAD(0x036C, 0x0058, 7, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD0__MIPI_HSI_CRL_TX_RDY     = IOMUX_PAD(0x0370, 0x005C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0          = IOMUX_PAD(0x0370, 0x005C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD0__GPIO_6_20               = IOMUX_PAD(0x0370, 0x005C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD0__MIPI_CORE_DPHY_IN_1     = IOMUX_PAD(0x0370, 0x005C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD1__MIPI_HSI_CRL_RX_FLG     = IOMUX_PAD(0x0374, 0x0060, 0, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1          = IOMUX_PAD(0x0374, 0x0060, 1, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD1__GPIO_6_21               = IOMUX_PAD(0x0374, 0x0060, 5, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD1__MIPI_CORE_DPHY_IN_2     = IOMUX_PAD(0x0374, 0x0060, 6, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD1__CCM_PLL3_BYP            = IOMUX_PAD(0x0374, 0x0060, 7, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD2__MIPI_HSI_CRL_RX_DTA     = IOMUX_PAD(0x0378, 0x0064, 0, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2          = IOMUX_PAD(0x0378, 0x0064, 1, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD2__GPIO_6_22               = IOMUX_PAD(0x0378, 0x0064, 5, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD2__MIPI_CORE_DPHY_IN_3     = IOMUX_PAD(0x0378, 0x0064, 6, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD2__CCM_PLL2_BYP            = IOMUX_PAD(0x0378, 0x0064, 7, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD3__MIPI_HSI_CRL_RX_WAK     = IOMUX_PAD(0x037C, 0x0068, 0, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3          = IOMUX_PAD(0x037C, 0x0068, 1, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD3__GPIO_6_23               = IOMUX_PAD(0x037C, 0x0068, 5, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TD3__MIPI_CORE_DPHY_IN_4     = IOMUX_PAD(0x037C, 0x0068, 6, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RX_CTL__USBOH3_H3_DATA       = IOMUX_PAD(0x0380, 0x006C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL         = IOMUX_PAD(0x0380, 0x006C, 1, 0x0858, 0, 0),
+    MX6Q_PAD_RGMII_RX_CTL__GPIO_6_24            = IOMUX_PAD(0x0380, 0x006C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RX_CTL__MIPI_DPHY_IN_5       = IOMUX_PAD(0x0380, 0x006C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RD0__MIPI_HSI_CRL_RX_RDY     = IOMUX_PAD(0x0384, 0x0070, 0, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0          = IOMUX_PAD(0x0384, 0x0070, 1, 0x0848, 0, 0),
+    MX6Q_PAD_RGMII_RD0__GPIO_6_25               = IOMUX_PAD(0x0384, 0x0070, 5, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RD0__MIPI_CORE_DPHY_IN_6     = IOMUX_PAD(0x0384, 0x0070, 6, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE     = IOMUX_PAD(0x0388, 0x0074, 0, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TX_CTL__RGMII_TX_CTL         = IOMUX_PAD(0x0388, 0x0074, 1, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TX_CTL__GPIO_6_26            = IOMUX_PAD(0x0388, 0x0074, 5, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TX_CTL__CORE_DPHY_IN_7       = IOMUX_PAD(0x0388, 0x0074, 6, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_TX_CTL__ANATOP_REF_OUT       = IOMUX_PAD(0x0388, 0x0074, 7, 0x083C, 0, 0),
+    MX6Q_PAD_RGMII_RD1__MIPI_HSI_CTRL_TX_FL     = IOMUX_PAD(0x038C, 0x0078, 0, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1          = IOMUX_PAD(0x038C, 0x0078, 1, 0x084C, 0, 0),
+    MX6Q_PAD_RGMII_RD1__GPIO_6_27               = IOMUX_PAD(0x038C, 0x0078, 5, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RD1__CORE_DPHY_TEST_IN_8     = IOMUX_PAD(0x038C, 0x0078, 6, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RD1__SJC_FAIL                = IOMUX_PAD(0x038C, 0x0078, 7, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RD2__MIPI_HSI_CRL_TX_DTA     = IOMUX_PAD(0x0390, 0x007C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2          = IOMUX_PAD(0x0390, 0x007C, 1, 0x0850, 0, 0),
+    MX6Q_PAD_RGMII_RD2__GPIO_6_28               = IOMUX_PAD(0x0390, 0x007C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RD2__MIPI_CORE_DPHY_IN_9     = IOMUX_PAD(0x0390, 0x007C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RD3__MIPI_HSI_CRL_TX_WAK     = IOMUX_PAD(0x0394, 0x0080, 0, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3          = IOMUX_PAD(0x0394, 0x0080, 1, 0x0854, 0, 0),
+    MX6Q_PAD_RGMII_RD3__GPIO_6_29               = IOMUX_PAD(0x0394, 0x0080, 5, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RD3__MIPI_CORE_DPHY_IN10     = IOMUX_PAD(0x0394, 0x0080, 6, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE        = IOMUX_PAD(0x0398, 0x0084, 0, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC          = IOMUX_PAD(0x0398, 0x0084, 1, 0x0844, 0, 0),
+    MX6Q_PAD_RGMII_RXC__GPIO_6_30               = IOMUX_PAD(0x0398, 0x0084, 5, 0x0000, 0, 0),
+    MX6Q_PAD_RGMII_RXC__MIPI_CORE_DPHY_IN11     = IOMUX_PAD(0x0398, 0x0084, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A25__WEIM_WEIM_A_25            = IOMUX_PAD(0x039C, 0x0088, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A25__ECSPI4_SS1                = IOMUX_PAD(0x039C, 0x0088, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A25__ECSPI2_RDY                = IOMUX_PAD(0x039C, 0x0088, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A25__IPU1_DI1_PIN12            = IOMUX_PAD(0x039C, 0x0088, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A25__IPU1_DI0_D1_CS            = IOMUX_PAD(0x039C, 0x0088, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A25__GPIO_5_2                  = IOMUX_PAD(0x039C, 0x0088, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A25__HDMI_TX_CEC_LINE          = IOMUX_PAD(0x039C, 0x0088, 6, 0x088C, 0, 0),
+    MX6Q_PAD_EIM_A25__PL301_PER1_HBURST_0       = IOMUX_PAD(0x039C, 0x0088, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB2__WEIM_WEIM_EB_2            = IOMUX_PAD(0x03A0, 0x008C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB2__ECSPI1_SS0                = IOMUX_PAD(0x03A0, 0x008C, 1, 0x0800, 0, 0),
+    MX6Q_PAD_EIM_EB2__CCM_DI1_EXT_CLK           = IOMUX_PAD(0x03A0, 0x008C, 2, 0x07EC, 0, 0),
+    MX6Q_PAD_EIM_EB2__IPU2_CSI1_D_19            = IOMUX_PAD(0x03A0, 0x008C, 3, 0x08D4, 0, 0),
+    MX6Q_PAD_EIM_EB2__HDMI_TX_DDC_SCL           = IOMUX_PAD(0x03A0, 0x008C, 4, 0x0890, 0, 0),
+    MX6Q_PAD_EIM_EB2__GPIO_2_30                 = IOMUX_PAD(0x03A0, 0x008C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB2__I2C2_SCL                  = IOMUX_PAD(0x03A0, 0x008C, 22, 0x08A0, 0, 0),
+    MX6Q_PAD_EIM_EB2__SRC_BT_CFG_30             = IOMUX_PAD(0x03A0, 0x008C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D16__WEIM_WEIM_D_16            = IOMUX_PAD(0x03A4, 0x0090, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D16__ECSPI1_SCLK               = IOMUX_PAD(0x03A4, 0x0090, 1, 0x07F4, 0, 0),
+    MX6Q_PAD_EIM_D16__IPU1_DI0_PIN5             = IOMUX_PAD(0x03A4, 0x0090, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D16__IPU2_CSI1_D_18            = IOMUX_PAD(0x03A4, 0x0090, 3, 0x08D0, 0, 0),
+    MX6Q_PAD_EIM_D16__HDMI_TX_DDC_SDA           = IOMUX_PAD(0x03A4, 0x0090, 4, 0x0894, 0, 0),
+    MX6Q_PAD_EIM_D16__GPIO_3_16                 = IOMUX_PAD(0x03A4, 0x0090, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D16__I2C2_SDA                  = IOMUX_PAD(0x03A4, 0x0090, 22, 0x08A4, 0, 0),
+    MX6Q_PAD_EIM_D17__WEIM_WEIM_D_17            = IOMUX_PAD(0x03A8, 0x0094, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D17__ECSPI1_MISO               = IOMUX_PAD(0x03A8, 0x0094, 1, 0x07F8, 0, 0),
+    MX6Q_PAD_EIM_D17__IPU1_DI0_PIN6             = IOMUX_PAD(0x03A8, 0x0094, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D17__IPU2_CSI1_PIXCLK          = IOMUX_PAD(0x03A8, 0x0094, 3, 0x08E0, 0, 0),
+    MX6Q_PAD_EIM_D17__DCIC1_DCIC_OUT            = IOMUX_PAD(0x03A8, 0x0094, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D17__GPIO_3_17                 = IOMUX_PAD(0x03A8, 0x0094, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D17__I2C3_SCL                  = IOMUX_PAD(0x03A8, 0x0094, 22, 0x08A8, 0, 0),
+    MX6Q_PAD_EIM_D17__PL301_PER1_HBURST_1       = IOMUX_PAD(0x03A8, 0x0094, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D18__WEIM_WEIM_D_18            = IOMUX_PAD(0x03AC, 0x0098, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D18__ECSPI1_MOSI               = IOMUX_PAD(0x03AC, 0x0098, 1, 0x07FC, 0, 0),
+    MX6Q_PAD_EIM_D18__IPU1_DI0_PIN7             = IOMUX_PAD(0x03AC, 0x0098, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D18__IPU2_CSI1_D_17            = IOMUX_PAD(0x03AC, 0x0098, 3, 0x08CC, 0, 0),
+    MX6Q_PAD_EIM_D18__IPU1_DI1_D0_CS            = IOMUX_PAD(0x03AC, 0x0098, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D18__GPIO_3_18                 = IOMUX_PAD(0x03AC, 0x0098, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D18__I2C3_SDA                  = IOMUX_PAD(0x03AC, 0x0098, 22, 0x08AC, 0, 0),
+    MX6Q_PAD_EIM_D18__PL301_PER1_HBURST_2       = IOMUX_PAD(0x03AC, 0x0098, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D19__WEIM_WEIM_D_19            = IOMUX_PAD(0x03B0, 0x009C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D19__ECSPI1_SS1                = IOMUX_PAD(0x03B0, 0x009C, 1, 0x0804, 0, 0),
+    MX6Q_PAD_EIM_D19__IPU1_DI0_PIN8             = IOMUX_PAD(0x03B0, 0x009C, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D19__IPU2_CSI1_D_16            = IOMUX_PAD(0x03B0, 0x009C, 3, 0x08C8, 0, 0),
+    MX6Q_PAD_EIM_D19__UART1_CTS                 = IOMUX_PAD(0x03B0, 0x009C, 4, 0x091C, 0, 0),
+    MX6Q_PAD_EIM_D19__GPIO_3_19                 = IOMUX_PAD(0x03B0, 0x009C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D19__EPIT1_EPITO               = IOMUX_PAD(0x03B0, 0x009C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D19__PL301MX6QPER1_HRESP       = IOMUX_PAD(0x03B0, 0x009C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D20__WEIM_WEIM_D_20            = IOMUX_PAD(0x03B4, 0x00A0, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D20__ECSPI4_SS0                = IOMUX_PAD(0x03B4, 0x00A0, 1, 0x0824, 0, 0),
+    MX6Q_PAD_EIM_D20__IPU1_DI0_PIN16            = IOMUX_PAD(0x03B4, 0x00A0, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D20__IPU2_CSI1_D_15            = IOMUX_PAD(0x03B4, 0x00A0, 3, 0x08C4, 0, 0),
+    MX6Q_PAD_EIM_D20__UART1_CTS                 = IOMUX_PAD(0x03B4, 0x00A0, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D20__UART1_RTS                 = IOMUX_PAD(0x03B4, 0x00A0, 4, 0x091C, 1, 0),
+    MX6Q_PAD_EIM_D20__GPIO_3_20                 = IOMUX_PAD(0x03B4, 0x00A0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D20__EPIT2_EPITO               = IOMUX_PAD(0x03B4, 0x00A0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D21__WEIM_WEIM_D_21            = IOMUX_PAD(0x03B8, 0x00A4, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D21__ECSPI4_SCLK               = IOMUX_PAD(0x03B8, 0x00A4, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D21__IPU1_DI0_PIN17            = IOMUX_PAD(0x03B8, 0x00A4, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D21__IPU2_CSI1_D_11            = IOMUX_PAD(0x03B8, 0x00A4, 3, 0x08B4, 0, 0),
+    MX6Q_PAD_EIM_D21__USBOH3_USBOTG_OC          = IOMUX_PAD(0x03B8, 0x00A4, 4, 0x0944, 0, 0),
+    MX6Q_PAD_EIM_D21__GPIO_3_21                 = IOMUX_PAD(0x03B8, 0x00A4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D21__I2C1_SCL                  = IOMUX_PAD(0x03B8, 0x00A4, 22, 0x0898, 0, 0),
+    MX6Q_PAD_EIM_D21__SPDIF_IN1                 = IOMUX_PAD(0x03B8, 0x00A4, 7, 0x0914, 0, 0),
+    MX6Q_PAD_EIM_D22__WEIM_WEIM_D_22            = IOMUX_PAD(0x03BC, 0x00A8, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D22__ECSPI4_MISO               = IOMUX_PAD(0x03BC, 0x00A8, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D22__IPU1_DI0_PIN1             = IOMUX_PAD(0x03BC, 0x00A8, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D22__IPU2_CSI1_D_10            = IOMUX_PAD(0x03BC, 0x00A8, 3, 0x08B0, 0, 0),
+    MX6Q_PAD_EIM_D22__USBOH3_USBOTG_PWR         = IOMUX_PAD(0x03BC, 0x00A8, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D22__GPIO_3_22                 = IOMUX_PAD(0x03BC, 0x00A8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D22__SPDIF_OUT1                = IOMUX_PAD(0x03BC, 0x00A8, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D22__PL301MX6QPER1_HWRITE      = IOMUX_PAD(0x03BC, 0x00A8, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D23__WEIM_WEIM_D_23            = IOMUX_PAD(0x03C0, 0x00AC, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D23__IPU1_DI0_D0_CS            = IOMUX_PAD(0x03C0, 0x00AC, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D23__UART3_CTS                 = IOMUX_PAD(0x03C0, 0x00AC, 2, 0x092C, 0, 0),
+    MX6Q_PAD_EIM_D23__UART1_DCD                 = IOMUX_PAD(0x03C0, 0x00AC, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D23__IPU2_CSI1_DATA_EN         = IOMUX_PAD(0x03C0, 0x00AC, 4, 0x08D8, 0, 0),
+    MX6Q_PAD_EIM_D23__GPIO_3_23                 = IOMUX_PAD(0x03C0, 0x00AC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D23__IPU1_DI1_PIN2             = IOMUX_PAD(0x03C0, 0x00AC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D23__IPU1_DI1_PIN14            = IOMUX_PAD(0x03C0, 0x00AC, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB3__WEIM_WEIM_EB_3            = IOMUX_PAD(0x03C4, 0x00B0, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB3__ECSPI4_RDY                = IOMUX_PAD(0x03C4, 0x00B0, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB3__UART3_CTS                 = IOMUX_PAD(0x03C4, 0x00B0, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB3__UART3_RTS                 = IOMUX_PAD(0x03C4, 0x00B0, 2, 0x092C, 1, 0),
+    MX6Q_PAD_EIM_EB3__UART1_RI                  = IOMUX_PAD(0x03C4, 0x00B0, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB3__IPU2_CSI1_HSYNC           = IOMUX_PAD(0x03C4, 0x00B0, 4, 0x08DC, 0, 0),
+    MX6Q_PAD_EIM_EB3__GPIO_2_31                 = IOMUX_PAD(0x03C4, 0x00B0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB3__IPU1_DI1_PIN3             = IOMUX_PAD(0x03C4, 0x00B0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB3__SRC_BT_CFG_31             = IOMUX_PAD(0x03C4, 0x00B0, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D24__WEIM_WEIM_D_24            = IOMUX_PAD(0x03C8, 0x00B4, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D24__ECSPI4_SS2                = IOMUX_PAD(0x03C8, 0x00B4, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D24__UART3_TXD                 = IOMUX_PAD(0x03C8, 0x00B4, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D24__UART3_TXD_RXD             = IOMUX_PAD(0x03C8, 0x00B4, 2, 0x0930, 0, 0),
+    MX6Q_PAD_EIM_D24__ECSPI1_SS2                = IOMUX_PAD(0x03C8, 0x00B4, 3, 0x0808, 0, 0),
+    MX6Q_PAD_EIM_D24__ECSPI2_SS2                = IOMUX_PAD(0x03C8, 0x00B4, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D24__GPIO_3_24                 = IOMUX_PAD(0x03C8, 0x00B4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D24__AUDMUX_AUD5_RXFS          = IOMUX_PAD(0x03C8, 0x00B4, 6, 0x07D8, 0, 0),
+    MX6Q_PAD_EIM_D24__UART1_DTR                 = IOMUX_PAD(0x03C8, 0x00B4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D25__WEIM_WEIM_D_25            = IOMUX_PAD(0x03CC, 0x00B8, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D25__ECSPI4_SS3                = IOMUX_PAD(0x03CC, 0x00B8, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D25__UART3_RXD                 = IOMUX_PAD(0x03CC, 0x00B8, 2, 0x0930, 1, 0),
+    MX6Q_PAD_EIM_D25__ECSPI1_SS3                = IOMUX_PAD(0x03CC, 0x00B8, 3, 0x080C, 0, 0),
+    MX6Q_PAD_EIM_D25__ECSPI2_SS3                = IOMUX_PAD(0x03CC, 0x00B8, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D25__GPIO_3_25                 = IOMUX_PAD(0x03CC, 0x00B8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D25__AUDMUX_AUD5_RXC           = IOMUX_PAD(0x03CC, 0x00B8, 6, 0x07D4, 0, 0),
+    MX6Q_PAD_EIM_D25__UART1_DSR                 = IOMUX_PAD(0x03CC, 0x00B8, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D26__WEIM_WEIM_D_26            = IOMUX_PAD(0x03D0, 0x00BC, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D26__IPU1_DI1_PIN11            = IOMUX_PAD(0x03D0, 0x00BC, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D26__IPU1_CSI0_D_1             = IOMUX_PAD(0x03D0, 0x00BC, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D26__IPU2_CSI1_D_14            = IOMUX_PAD(0x03D0, 0x00BC, 3, 0x08C0, 0, 0),
+    MX6Q_PAD_EIM_D26__UART2_TXD                 = IOMUX_PAD(0x03D0, 0x00BC, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D26__UART2_TXD_RXD             = IOMUX_PAD(0x03D0, 0x00BC, 4, 0x0928, 0, 0),
+    MX6Q_PAD_EIM_D26__GPIO_3_26                 = IOMUX_PAD(0x03D0, 0x00BC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D26__IPU1_SISG_2               = IOMUX_PAD(0x03D0, 0x00BC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D26__IPU1_DISP1_DAT_22         = IOMUX_PAD(0x03D0, 0x00BC, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D27__WEIM_WEIM_D_27            = IOMUX_PAD(0x03D4, 0x00C0, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D27__IPU1_DI1_PIN13            = IOMUX_PAD(0x03D4, 0x00C0, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D27__IPU1_CSI0_D_0             = IOMUX_PAD(0x03D4, 0x00C0, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D27__IPU2_CSI1_D_13            = IOMUX_PAD(0x03D4, 0x00C0, 3, 0x08BC, 0, 0),
+    MX6Q_PAD_EIM_D27__UART2_RXD                 = IOMUX_PAD(0x03D4, 0x00C0, 4, 0x0928, 1, 0),
+    MX6Q_PAD_EIM_D27__GPIO_3_27                 = IOMUX_PAD(0x03D4, 0x00C0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D27__IPU1_SISG_3               = IOMUX_PAD(0x03D4, 0x00C0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D27__IPU1_DISP1_DAT_23         = IOMUX_PAD(0x03D4, 0x00C0, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D28__WEIM_WEIM_D_28            = IOMUX_PAD(0x03D8, 0x00C4, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D28__I2C1_SDA                  = IOMUX_PAD(0x03D8, 0x00C4, 17, 0x089C, 0, 0),
+    MX6Q_PAD_EIM_D28__ECSPI4_MOSI               = IOMUX_PAD(0x03D8, 0x00C4, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D28__IPU2_CSI1_D_12            = IOMUX_PAD(0x03D8, 0x00C4, 3, 0x08B8, 0, 0),
+    MX6Q_PAD_EIM_D28__UART2_CTS                 = IOMUX_PAD(0x03D8, 0x00C4, 4, 0x0924, 0, 0),
+    MX6Q_PAD_EIM_D28__GPIO_3_28                 = IOMUX_PAD(0x03D8, 0x00C4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D28__IPU1_EXT_TRIG             = IOMUX_PAD(0x03D8, 0x00C4, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D28__IPU1_DI0_PIN13            = IOMUX_PAD(0x03D8, 0x00C4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D29__WEIM_WEIM_D_29            = IOMUX_PAD(0x03DC, 0x00C8, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D29__IPU1_DI1_PIN15            = IOMUX_PAD(0x03DC, 0x00C8, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D29__ECSPI4_SS0                = IOMUX_PAD(0x03DC, 0x00C8, 2, 0x0824, 1, 0),
+    MX6Q_PAD_EIM_D29__UART2_CTS                 = IOMUX_PAD(0x03DC, 0x00C8, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D29__UART2_RTS                 = IOMUX_PAD(0x03DC, 0x00C8, 4, 0x0924, 1, 0),
+    MX6Q_PAD_EIM_D29__GPIO_3_29                 = IOMUX_PAD(0x03DC, 0x00C8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D29__IPU2_CSI1_VSYNC           = IOMUX_PAD(0x03DC, 0x00C8, 6, 0x08E4, 0, 0),
+    MX6Q_PAD_EIM_D29__IPU1_DI0_PIN14            = IOMUX_PAD(0x03DC, 0x00C8, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D30__WEIM_WEIM_D_30            = IOMUX_PAD(0x03E0, 0x00CC, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D30__IPU1_DISP1_DAT_21         = IOMUX_PAD(0x03E0, 0x00CC, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D30__IPU1_DI0_PIN11            = IOMUX_PAD(0x03E0, 0x00CC, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D30__IPU1_CSI0_D_3             = IOMUX_PAD(0x03E0, 0x00CC, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D30__UART3_CTS                 = IOMUX_PAD(0x03E0, 0x00CC, 4, 0x092C, 2, 0),
+    MX6Q_PAD_EIM_D30__GPIO_3_30                 = IOMUX_PAD(0x03E0, 0x00CC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D30__USBOH3_USBH1_OC           = IOMUX_PAD(0x03E0, 0x00CC, 6, 0x0948, 0, 0),
+    MX6Q_PAD_EIM_D30__PL301MX6QPER1_HPROT_0     = IOMUX_PAD(0x03E0, 0x00CC, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D31__WEIM_WEIM_D_31            = IOMUX_PAD(0x03E4, 0x00D0, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D31__IPU1_DISP1_DAT_20         = IOMUX_PAD(0x03E4, 0x00D0, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D31__IPU1_DI0_PIN12            = IOMUX_PAD(0x03E4, 0x00D0, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D31__IPU1_CSI0_D_2             = IOMUX_PAD(0x03E4, 0x00D0, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D31__UART3_CTS                 = IOMUX_PAD(0x03E4, 0x00D0, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D31__UART3_RTS                 = IOMUX_PAD(0x03E4, 0x00D0, 4, 0x092C, 3, 0),
+    MX6Q_PAD_EIM_D31__GPIO_3_31                 = IOMUX_PAD(0x03E4, 0x00D0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D31__USBOH3_USBH1_PWR          = IOMUX_PAD(0x03E4, 0x00D0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_D31__PL301MX6QPER1_HPROT_1     = IOMUX_PAD(0x03E4, 0x00D0, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A24__WEIM_WEIM_A_24            = IOMUX_PAD(0x03E8, 0x00D4, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A24__IPU1_DISP1_DAT_19         = IOMUX_PAD(0x03E8, 0x00D4, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A24__IPU2_CSI1_D_19            = IOMUX_PAD(0x03E8, 0x00D4, 2, 0x08D4, 1, 0),
+    MX6Q_PAD_EIM_A24__IPU2_SISG_2               = IOMUX_PAD(0x03E8, 0x00D4, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A24__IPU1_SISG_2               = IOMUX_PAD(0x03E8, 0x00D4, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A24__GPIO_5_4                  = IOMUX_PAD(0x03E8, 0x00D4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A24__PL301MX6QPER1_HPROT_2     = IOMUX_PAD(0x03E8, 0x00D4, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A24__SRC_BT_CFG_24             = IOMUX_PAD(0x03E8, 0x00D4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A23__WEIM_WEIM_A_23            = IOMUX_PAD(0x03EC, 0x00D8, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A23__IPU1_DISP1_DAT_18         = IOMUX_PAD(0x03EC, 0x00D8, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A23__IPU2_CSI1_D_18            = IOMUX_PAD(0x03EC, 0x00D8, 2, 0x08D0, 1, 0),
+    MX6Q_PAD_EIM_A23__IPU2_SISG_3               = IOMUX_PAD(0x03EC, 0x00D8, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A23__IPU1_SISG_3               = IOMUX_PAD(0x03EC, 0x00D8, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A23__GPIO_6_6                  = IOMUX_PAD(0x03EC, 0x00D8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A23__PL301MX6QPER1_HPROT_3     = IOMUX_PAD(0x03EC, 0x00D8, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A23__SRC_BT_CFG_23             = IOMUX_PAD(0x03EC, 0x00D8, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A22__WEIM_WEIM_A_22            = IOMUX_PAD(0x03F0, 0x00DC, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A22__IPU1_DISP1_DAT_17         = IOMUX_PAD(0x03F0, 0x00DC, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A22__IPU2_CSI1_D_17            = IOMUX_PAD(0x03F0, 0x00DC, 2, 0x08CC, 1, 0),
+    MX6Q_PAD_EIM_A22__GPIO_2_16                 = IOMUX_PAD(0x03F0, 0x00DC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A22__TPSMP_HDATA_0             = IOMUX_PAD(0x03F0, 0x00DC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A22__SRC_BT_CFG_22             = IOMUX_PAD(0x03F0, 0x00DC, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A21__WEIM_WEIM_A_21            = IOMUX_PAD(0x03F4, 0x00E0, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A21__IPU1_DISP1_DAT_16         = IOMUX_PAD(0x03F4, 0x00E0, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A21__IPU2_CSI1_D_16            = IOMUX_PAD(0x03F4, 0x00E0, 2, 0x08C8, 1, 0),
+    MX6Q_PAD_EIM_A21__RESERVED_RESERVED         = IOMUX_PAD(0x03F4, 0x00E0, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A21__MIPI_CORE_DPHY_OUT_18     = IOMUX_PAD(0x03F4, 0x00E0, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A21__GPIO_2_17                 = IOMUX_PAD(0x03F4, 0x00E0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A21__TPSMP_HDATA_1             = IOMUX_PAD(0x03F4, 0x00E0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A21__SRC_BT_CFG_21             = IOMUX_PAD(0x03F4, 0x00E0, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A20__WEIM_WEIM_A_20            = IOMUX_PAD(0x03F8, 0x00E4, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A20__IPU1_DISP1_DAT_15         = IOMUX_PAD(0x03F8, 0x00E4, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A20__IPU2_CSI1_D_15            = IOMUX_PAD(0x03F8, 0x00E4, 2, 0x08C4, 1, 0),
+    MX6Q_PAD_EIM_A20__RESERVED_RESERVED         = IOMUX_PAD(0x03F8, 0x00E4, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A20__MIPI_CORE_DPHY_OUT_19     = IOMUX_PAD(0x03F8, 0x00E4, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A20__GPIO_2_18                 = IOMUX_PAD(0x03F8, 0x00E4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A20__TPSMP_HDATA_2             = IOMUX_PAD(0x03F8, 0x00E4, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A20__SRC_BT_CFG_20             = IOMUX_PAD(0x03F8, 0x00E4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A19__WEIM_WEIM_A_19            = IOMUX_PAD(0x03FC, 0x00E8, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A19__IPU1_DISP1_DAT_14         = IOMUX_PAD(0x03FC, 0x00E8, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A19__IPU2_CSI1_D_14            = IOMUX_PAD(0x03FC, 0x00E8, 2, 0x08C0, 1, 0),
+    MX6Q_PAD_EIM_A19__RESERVED_RESERVED         = IOMUX_PAD(0x03FC, 0x00E8, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A19__MIPI_CORE_DPHY_OUT_20     = IOMUX_PAD(0x03FC, 0x00E8, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A19__GPIO_2_19                 = IOMUX_PAD(0x03FC, 0x00E8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A19__TPSMP_HDATA_3             = IOMUX_PAD(0x03FC, 0x00E8, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A19__SRC_BT_CFG_19             = IOMUX_PAD(0x03FC, 0x00E8, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A18__WEIM_WEIM_A_18            = IOMUX_PAD(0x0400, 0x00EC, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A18__IPU1_DISP1_DAT_13         = IOMUX_PAD(0x0400, 0x00EC, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A18__IPU2_CSI1_D_13            = IOMUX_PAD(0x0400, 0x00EC, 2, 0x08BC, 1, 0),
+    MX6Q_PAD_EIM_A18__RESERVED_RESERVED         = IOMUX_PAD(0x0400, 0x00EC, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A18__MIPI_CORE_DPHY_OUT_21     = IOMUX_PAD(0x0400, 0x00EC, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A18__GPIO_2_20                 = IOMUX_PAD(0x0400, 0x00EC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A18__TPSMP_HDATA_4             = IOMUX_PAD(0x0400, 0x00EC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A18__SRC_BT_CFG_18             = IOMUX_PAD(0x0400, 0x00EC, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A17__WEIM_WEIM_A_17            = IOMUX_PAD(0x0404, 0x00F0, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A17__IPU1_DISP1_DAT_12         = IOMUX_PAD(0x0404, 0x00F0, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A17__IPU2_CSI1_D_12            = IOMUX_PAD(0x0404, 0x00F0, 2, 0x08B8, 1, 0),
+    MX6Q_PAD_EIM_A17__RESERVED_RESERVED         = IOMUX_PAD(0x0404, 0x00F0, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A17__MIPI_CORE_DPHY_OUT_22     = IOMUX_PAD(0x0404, 0x00F0, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A17__GPIO_2_21                 = IOMUX_PAD(0x0404, 0x00F0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A17__TPSMP_HDATA_5             = IOMUX_PAD(0x0404, 0x00F0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A17__SRC_BT_CFG_17             = IOMUX_PAD(0x0404, 0x00F0, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A16__WEIM_WEIM_A_16            = IOMUX_PAD(0x0408, 0x00F4, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A16__IPU1_DI1_DISP_CLK         = IOMUX_PAD(0x0408, 0x00F4, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A16__IPU2_CSI1_PIXCLK          = IOMUX_PAD(0x0408, 0x00F4, 2, 0x08E0, 1, 0),
+    MX6Q_PAD_EIM_A16__MIPI_CORE_DPHY_OUT_23     = IOMUX_PAD(0x0408, 0x00F4, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A16__GPIO_2_22                 = IOMUX_PAD(0x0408, 0x00F4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A16__TPSMP_HDATA_6             = IOMUX_PAD(0x0408, 0x00F4, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_A16__SRC_BT_CFG_16             = IOMUX_PAD(0x0408, 0x00F4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_CS0__WEIM_WEIM_CS_0            = IOMUX_PAD(0x040C, 0x00F8, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_CS0__IPU1_DI1_PIN5             = IOMUX_PAD(0x040C, 0x00F8, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_CS0__ECSPI2_SCLK               = IOMUX_PAD(0x040C, 0x00F8, 2, 0x0810, 0, 0),
+    MX6Q_PAD_EIM_CS0__MIPI_CORE_DPHY_OUT_24     = IOMUX_PAD(0x040C, 0x00F8, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_CS0__GPIO_2_23                 = IOMUX_PAD(0x040C, 0x00F8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_CS0__TPSMP_HDATA_7             = IOMUX_PAD(0x040C, 0x00F8, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_CS1__WEIM_WEIM_CS_1            = IOMUX_PAD(0x0410, 0x00FC, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_CS1__IPU1_DI1_PIN6             = IOMUX_PAD(0x0410, 0x00FC, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_CS1__ECSPI2_MOSI               = IOMUX_PAD(0x0410, 0x00FC, 2, 0x0818, 0, 0),
+    MX6Q_PAD_EIM_CS1__MIPI_CORE_DPHY_OUT_25     = IOMUX_PAD(0x0410, 0x00FC, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_CS1__GPIO_2_24                 = IOMUX_PAD(0x0410, 0x00FC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_CS1__TPSMP_HDATA_8             = IOMUX_PAD(0x0410, 0x00FC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_OE__WEIM_WEIM_OE               = IOMUX_PAD(0x0414, 0x0100, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_OE__IPU1_DI1_PIN7              = IOMUX_PAD(0x0414, 0x0100, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_OE__ECSPI2_MISO                = IOMUX_PAD(0x0414, 0x0100, 2, 0x0814, 0, 0),
+    MX6Q_PAD_EIM_OE__MIPI_CORE_DPHY_OUT_26      = IOMUX_PAD(0x0414, 0x0100, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_OE__GPIO_2_25                  = IOMUX_PAD(0x0414, 0x0100, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_OE__TPSMP_HDATA_9              = IOMUX_PAD(0x0414, 0x0100, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_RW__WEIM_WEIM_RW               = IOMUX_PAD(0x0418, 0x0104, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_RW__IPU1_DI1_PIN8              = IOMUX_PAD(0x0418, 0x0104, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_RW__ECSPI2_SS0                 = IOMUX_PAD(0x0418, 0x0104, 2, 0x081C, 0, 0),
+    MX6Q_PAD_EIM_RW__MIPI_CORE_DPHY_OUT_27      = IOMUX_PAD(0x0418, 0x0104, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_RW__GPIO_2_26                  = IOMUX_PAD(0x0418, 0x0104, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_RW__TPSMP_HDATA_10             = IOMUX_PAD(0x0418, 0x0104, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_RW__SRC_BT_CFG_29              = IOMUX_PAD(0x0418, 0x0104, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_LBA__WEIM_WEIM_LBA             = IOMUX_PAD(0x041C, 0x0108, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_LBA__IPU1_DI1_PIN17            = IOMUX_PAD(0x041C, 0x0108, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_LBA__ECSPI2_SS1                = IOMUX_PAD(0x041C, 0x0108, 2, 0x0820, 0, 0),
+    MX6Q_PAD_EIM_LBA__GPIO_2_27                 = IOMUX_PAD(0x041C, 0x0108, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_LBA__TPSMP_HDATA_11            = IOMUX_PAD(0x041C, 0x0108, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_LBA__SRC_BT_CFG_26             = IOMUX_PAD(0x041C, 0x0108, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB0__WEIM_WEIM_EB_0            = IOMUX_PAD(0x0420, 0x010C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB0__IPU1_DISP1_DAT_11         = IOMUX_PAD(0x0420, 0x010C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB0__IPU2_CSI1_D_11            = IOMUX_PAD(0x0420, 0x010C, 2, 0x08B4, 1, 0),
+    MX6Q_PAD_EIM_EB0__MIPI_CORE_DPHY_OUT_0      = IOMUX_PAD(0x0420, 0x010C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB0__CCM_PMIC_RDY              = IOMUX_PAD(0x0420, 0x010C, 4, 0x07F0, 0, 0),
+    MX6Q_PAD_EIM_EB0__GPIO_2_28                 = IOMUX_PAD(0x0420, 0x010C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB0__TPSMP_HDATA_12            = IOMUX_PAD(0x0420, 0x010C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB0__SRC_BT_CFG_27             = IOMUX_PAD(0x0420, 0x010C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB1__WEIM_WEIM_EB_1            = IOMUX_PAD(0x0424, 0x0110, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB1__IPU1_DISP1_DAT_10         = IOMUX_PAD(0x0424, 0x0110, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB1__IPU2_CSI1_D_10            = IOMUX_PAD(0x0424, 0x0110, 2, 0x08B0, 1, 0),
+    MX6Q_PAD_EIM_EB1__MIPI_CORE_DPHY__OUT_1     = IOMUX_PAD(0x0424, 0x0110, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB1__GPIO_2_29                 = IOMUX_PAD(0x0424, 0x0110, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB1__TPSMP_HDATA_13            = IOMUX_PAD(0x0424, 0x0110, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_EB1__SRC_BT_CFG_28             = IOMUX_PAD(0x0424, 0x0110, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA0__WEIM_WEIM_DA_A_0          = IOMUX_PAD(0x0428, 0x0114, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA0__IPU1_DISP1_DAT_9          = IOMUX_PAD(0x0428, 0x0114, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA0__IPU2_CSI1_D_9             = IOMUX_PAD(0x0428, 0x0114, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA0__MIPI_CORE_DPHY__OUT_2     = IOMUX_PAD(0x0428, 0x0114, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA0__GPIO_3_0                  = IOMUX_PAD(0x0428, 0x0114, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA0__TPSMP_HDATA_14            = IOMUX_PAD(0x0428, 0x0114, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA0__SRC_BT_CFG_0              = IOMUX_PAD(0x0428, 0x0114, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA1__WEIM_WEIM_DA_A_1          = IOMUX_PAD(0x042C, 0x0118, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA1__IPU1_DISP1_DAT_8          = IOMUX_PAD(0x042C, 0x0118, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA1__IPU2_CSI1_D_8             = IOMUX_PAD(0x042C, 0x0118, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA1__MIPI_CORE_DPHY_OUT_3      = IOMUX_PAD(0x042C, 0x0118, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA1__USBPHY1_TX_LS_MODE        = IOMUX_PAD(0x042C, 0x0118, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA1__GPIO_3_1                  = IOMUX_PAD(0x042C, 0x0118, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA1__TPSMP_HDATA_15            = IOMUX_PAD(0x042C, 0x0118, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA1__SRC_BT_CFG_1              = IOMUX_PAD(0x042C, 0x0118, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA2__WEIM_WEIM_DA_A_2          = IOMUX_PAD(0x0430, 0x011C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA2__IPU1_DISP1_DAT_7          = IOMUX_PAD(0x0430, 0x011C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA2__IPU2_CSI1_D_7             = IOMUX_PAD(0x0430, 0x011C, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA2__MIPI_CORE_DPHY_OUT_4      = IOMUX_PAD(0x0430, 0x011C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA2__USBPHY1_TX_HS_MODE        = IOMUX_PAD(0x0430, 0x011C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA2__GPIO_3_2                  = IOMUX_PAD(0x0430, 0x011C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA2__TPSMP_HDATA_16            = IOMUX_PAD(0x0430, 0x011C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA2__SRC_BT_CFG_2              = IOMUX_PAD(0x0430, 0x011C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA3__WEIM_WEIM_DA_A_3          = IOMUX_PAD(0x0434, 0x0120, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA3__IPU1_DISP1_DAT_6          = IOMUX_PAD(0x0434, 0x0120, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA3__IPU2_CSI1_D_6             = IOMUX_PAD(0x0434, 0x0120, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA3__MIPI_CORE_DPHY_OUT_5      = IOMUX_PAD(0x0434, 0x0120, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA3__USBPHY1_TX_HIZ            = IOMUX_PAD(0x0434, 0x0120, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA3__GPIO_3_3                  = IOMUX_PAD(0x0434, 0x0120, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA3__TPSMP_HDATA_17            = IOMUX_PAD(0x0434, 0x0120, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA3__SRC_BT_CFG_3              = IOMUX_PAD(0x0434, 0x0120, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA4__WEIM_WEIM_DA_A_4          = IOMUX_PAD(0x0438, 0x0124, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA4__IPU1_DISP1_DAT_5          = IOMUX_PAD(0x0438, 0x0124, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA4__IPU2_CSI1_D_5             = IOMUX_PAD(0x0438, 0x0124, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA4__MIPI_CORE_DPHY_OUT_6      = IOMUX_PAD(0x0438, 0x0124, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA4__ANATOP_USBPHY1_TX_EN      = IOMUX_PAD(0x0438, 0x0124, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA4__GPIO_3_4                  = IOMUX_PAD(0x0438, 0x0124, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA4__TPSMP_HDATA_18            = IOMUX_PAD(0x0438, 0x0124, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA4__SRC_BT_CFG_4              = IOMUX_PAD(0x0438, 0x0124, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA5__WEIM_WEIM_DA_A_5          = IOMUX_PAD(0x043C, 0x0128, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA5__IPU1_DISP1_DAT_4          = IOMUX_PAD(0x043C, 0x0128, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA5__IPU2_CSI1_D_4             = IOMUX_PAD(0x043C, 0x0128, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA5__MIPI_CORE_DPHY_OUT_7      = IOMUX_PAD(0x043C, 0x0128, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA5__ANATOP_USBPHY1_TX_DP      = IOMUX_PAD(0x043C, 0x0128, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA5__GPIO_3_5                  = IOMUX_PAD(0x043C, 0x0128, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA5__TPSMP_HDATA_19            = IOMUX_PAD(0x043C, 0x0128, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA5__SRC_BT_CFG_5              = IOMUX_PAD(0x043C, 0x0128, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA6__WEIM_WEIM_DA_A_6          = IOMUX_PAD(0x0440, 0x012C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA6__IPU1_DISP1_DAT_3          = IOMUX_PAD(0x0440, 0x012C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA6__IPU2_CSI1_D_3             = IOMUX_PAD(0x0440, 0x012C, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA6__MIPI_CORE_DPHY_OUT_8      = IOMUX_PAD(0x0440, 0x012C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA6__ANATOP_USBPHY1_TX_DN      = IOMUX_PAD(0x0440, 0x012C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA6__GPIO_3_6                  = IOMUX_PAD(0x0440, 0x012C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA6__TPSMP_HDATA_20            = IOMUX_PAD(0x0440, 0x012C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA6__SRC_BT_CFG_6              = IOMUX_PAD(0x0440, 0x012C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA7__WEIM_WEIM_DA_A_7          = IOMUX_PAD(0x0444, 0x0130, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA7__IPU1_DISP1_DAT_2          = IOMUX_PAD(0x0444, 0x0130, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA7__IPU2_CSI1_D_2             = IOMUX_PAD(0x0444, 0x0130, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA7__MIPI_CORE_DPHY_OUT_9      = IOMUX_PAD(0x0444, 0x0130, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA7__GPIO_3_7                  = IOMUX_PAD(0x0444, 0x0130, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA7__TPSMP_HDATA_21            = IOMUX_PAD(0x0444, 0x0130, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA7__SRC_BT_CFG_7              = IOMUX_PAD(0x0444, 0x0130, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA8__WEIM_WEIM_DA_A_8          = IOMUX_PAD(0x0448, 0x0134, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA8__IPU1_DISP1_DAT_1          = IOMUX_PAD(0x0448, 0x0134, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA8__IPU2_CSI1_D_1             = IOMUX_PAD(0x0448, 0x0134, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA8__MIPI_CORE_DPHY_OUT_10     = IOMUX_PAD(0x0448, 0x0134, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA8__GPIO_3_8                  = IOMUX_PAD(0x0448, 0x0134, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA8__TPSMP_HDATA_22            = IOMUX_PAD(0x0448, 0x0134, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA8__SRC_BT_CFG_8              = IOMUX_PAD(0x0448, 0x0134, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA9__WEIM_WEIM_DA_A_9          = IOMUX_PAD(0x044C, 0x0138, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA9__IPU1_DISP1_DAT_0          = IOMUX_PAD(0x044C, 0x0138, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA9__IPU2_CSI1_D_0             = IOMUX_PAD(0x044C, 0x0138, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA9__MIPI_CORE_DPHY_OUT_11     = IOMUX_PAD(0x044C, 0x0138, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA9__GPIO_3_9                  = IOMUX_PAD(0x044C, 0x0138, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA9__TPSMP_HDATA_23            = IOMUX_PAD(0x044C, 0x0138, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA9__SRC_BT_CFG_9              = IOMUX_PAD(0x044C, 0x0138, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA10__WEIM_WEIM_DA_A_10        = IOMUX_PAD(0x0450, 0x013C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA10__IPU1_DI1_PIN15           = IOMUX_PAD(0x0450, 0x013C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA10__IPU2_CSI1_DATA_EN        = IOMUX_PAD(0x0450, 0x013C, 2, 0x08D8, 1, 0),
+    MX6Q_PAD_EIM_DA10__MIPI_CORE_DPHY_OUT12     = IOMUX_PAD(0x0450, 0x013C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA10__GPIO_3_10                = IOMUX_PAD(0x0450, 0x013C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA10__TPSMP_HDATA_24           = IOMUX_PAD(0x0450, 0x013C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA10__SRC_BT_CFG_10            = IOMUX_PAD(0x0450, 0x013C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA11__WEIM_WEIM_DA_A_11        = IOMUX_PAD(0x0454, 0x0140, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA11__IPU1_DI1_PIN2            = IOMUX_PAD(0x0454, 0x0140, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA11__IPU2_CSI1_HSYNC          = IOMUX_PAD(0x0454, 0x0140, 2, 0x08DC, 1, 0),
+    MX6Q_PAD_EIM_DA11__MIPI_CORE_DPHY_OUT13     = IOMUX_PAD(0x0454, 0x0140, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA11__SDMA_DBG_EVT_CHN_6       = IOMUX_PAD(0x0454, 0x0140, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA11__GPIO_3_11                = IOMUX_PAD(0x0454, 0x0140, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA11__TPSMP_HDATA_25           = IOMUX_PAD(0x0454, 0x0140, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA11__SRC_BT_CFG_11            = IOMUX_PAD(0x0454, 0x0140, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA12__WEIM_WEIM_DA_A_12        = IOMUX_PAD(0x0458, 0x0144, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA12__IPU1_DI1_PIN3            = IOMUX_PAD(0x0458, 0x0144, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA12__IPU2_CSI1_VSYNC          = IOMUX_PAD(0x0458, 0x0144, 2, 0x08E4, 1, 0),
+    MX6Q_PAD_EIM_DA12__MIPI_CORE_DPHY_OUT14     = IOMUX_PAD(0x0458, 0x0144, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA12__SDMA_DEBUG_EVT_CHN_3     = IOMUX_PAD(0x0458, 0x0144, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA12__GPIO_3_12                = IOMUX_PAD(0x0458, 0x0144, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA12__TPSMP_HDATA_26           = IOMUX_PAD(0x0458, 0x0144, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA12__SRC_BT_CFG_12            = IOMUX_PAD(0x0458, 0x0144, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA13__WEIM_WEIM_DA_A_13        = IOMUX_PAD(0x045C, 0x0148, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA13__IPU1_DI1_D0_CS           = IOMUX_PAD(0x045C, 0x0148, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA13__CCM_DI1_EXT_CLK          = IOMUX_PAD(0x045C, 0x0148, 2, 0x07EC, 1, 0),
+    MX6Q_PAD_EIM_DA13__MIPI_CORE_DPHY_OUT15     = IOMUX_PAD(0x045C, 0x0148, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA13__SDMA_DEBUG_EVT_CHN_4     = IOMUX_PAD(0x045C, 0x0148, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA13__GPIO_3_13                = IOMUX_PAD(0x045C, 0x0148, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA13__TPSMP_HDATA_27           = IOMUX_PAD(0x045C, 0x0148, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA13__SRC_BT_CFG_13            = IOMUX_PAD(0x045C, 0x0148, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA14__WEIM_WEIM_DA_A_14        = IOMUX_PAD(0x0460, 0x014C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA14__IPU1_DI1_D1_CS           = IOMUX_PAD(0x0460, 0x014C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA14__CCM_DI0_EXT_CLK          = IOMUX_PAD(0x0460, 0x014C, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA14__MIPI_CORE_DPHY_OUT16     = IOMUX_PAD(0x0460, 0x014C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA14__SDMA_DEBUG_EVT_CHN_5     = IOMUX_PAD(0x0460, 0x014C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA14__GPIO_3_14                = IOMUX_PAD(0x0460, 0x014C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA14__TPSMP_HDATA_28           = IOMUX_PAD(0x0460, 0x014C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA14__SRC_BT_CFG_14            = IOMUX_PAD(0x0460, 0x014C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA15__WEIM_WEIM_DA_A_15        = IOMUX_PAD(0x0464, 0x0150, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA15__IPU1_DI1_PIN1            = IOMUX_PAD(0x0464, 0x0150, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA15__IPU1_DI1_PIN4            = IOMUX_PAD(0x0464, 0x0150, 2, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA15__MIPI_CORE_DPHY_OUT17     = IOMUX_PAD(0x0464, 0x0150, 3, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA15__GPIO_3_15                = IOMUX_PAD(0x0464, 0x0150, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA15__TPSMP_HDATA_29           = IOMUX_PAD(0x0464, 0x0150, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_DA15__SRC_BT_CFG_15            = IOMUX_PAD(0x0464, 0x0150, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_WAIT__WEIM_WEIM_WAIT           = IOMUX_PAD(0x0468, 0x0154, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_WAIT__WEIM_WEIM_DTACK_B        = IOMUX_PAD(0x0468, 0x0154, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_WAIT__GPIO_5_0                 = IOMUX_PAD(0x0468, 0x0154, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_WAIT__TPSMP_HDATA_30           = IOMUX_PAD(0x0468, 0x0154, 6, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_WAIT__SRC_BT_CFG_25            = IOMUX_PAD(0x0468, 0x0154, 7, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_BCLK__WEIM_WEIM_BCLK           = IOMUX_PAD(0x046C, 0x0158, 0, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_BCLK__IPU1_DI1_PIN16           = IOMUX_PAD(0x046C, 0x0158, 1, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_BCLK__GPIO_6_31                = IOMUX_PAD(0x046C, 0x0158, 5, 0x0000, 0, 0),
+    MX6Q_PAD_EIM_BCLK__TPSMP_HDATA_31           = IOMUX_PAD(0x046C, 0x0158, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK    = IOMUX_PAD(0x0470, 0x015C, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DI0_DISP_CLK__IPU2_DI0_DISP_CLK    = IOMUX_PAD(0x0470, 0x015C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_DISP_CLK__MIPI_CR_DPY_OT28     = IOMUX_PAD(0x0470, 0x015C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_DISP_CLK__SDMA_DBG_CR_STA0     = IOMUX_PAD(0x0470, 0x015C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_DISP_CLK__GPIO_4_16            = IOMUX_PAD(0x0470, 0x015C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_DISP_CLK__MMDC_DEBUG_0         = IOMUX_PAD(0x0470, 0x015C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15          = IOMUX_PAD(0x0474, 0x0160, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DI0_PIN15__IPU2_DI0_PIN15          = IOMUX_PAD(0x0474, 0x0160, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN15__AUDMUX_AUD6_TXC         = IOMUX_PAD(0x0474, 0x0160, 2, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN15__MIPI_CR_DPHY_OUT_29     = IOMUX_PAD(0x0474, 0x0160, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN15__SDMA_DBG_CORE_STA_1     = IOMUX_PAD(0x0474, 0x0160, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN15__GPIO_4_17               = IOMUX_PAD(0x0474, 0x0160, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN15__MMDC_MMDC_DEBUG_1       = IOMUX_PAD(0x0474, 0x0160, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2            = IOMUX_PAD(0x0478, 0x0164, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DI0_PIN2__IPU2_DI0_PIN2            = IOMUX_PAD(0x0478, 0x0164, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN2__AUDMUX_AUD6_TXD          = IOMUX_PAD(0x0478, 0x0164, 2, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN2__MIPI_CR_DPHY_OUT_30      = IOMUX_PAD(0x0478, 0x0164, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN2__SDMA_DBG_CORE_STA_2      = IOMUX_PAD(0x0478, 0x0164, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN2__GPIO_4_18                = IOMUX_PAD(0x0478, 0x0164, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN2__MMDC_DEBUG_2             = IOMUX_PAD(0x0478, 0x0164, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN2__PL301_PER1_HADDR_9       = IOMUX_PAD(0x0478, 0x0164, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3            = IOMUX_PAD(0x047C, 0x0168, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DI0_PIN3__IPU2_DI0_PIN3            = IOMUX_PAD(0x047C, 0x0168, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN3__AUDMUX_AUD6_TXFS         = IOMUX_PAD(0x047C, 0x0168, 2, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN3__MIPI_CORE_DPHY_OUT31     = IOMUX_PAD(0x047C, 0x0168, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN3__SDMA_DBG_CORE_STA_3      = IOMUX_PAD(0x047C, 0x0168, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN3__GPIO_4_19                = IOMUX_PAD(0x047C, 0x0168, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN3__MMDC_MMDC_DEBUG_3        = IOMUX_PAD(0x047C, 0x0168, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN3__PL301_PER1_HADDR_10      = IOMUX_PAD(0x047C, 0x0168, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN4__IPU1_DI0_PIN4            = IOMUX_PAD(0x0480, 0x016C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN4__IPU2_DI0_PIN4            = IOMUX_PAD(0x0480, 0x016C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN4__AUDMUX_AUD6_RXD          = IOMUX_PAD(0x0480, 0x016C, 2, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN4__USDHC1_WP                = IOMUX_PAD(0x0480, 0x016C, 3, 0x094C, 0, 0),
+    MX6Q_PAD_DI0_PIN4__SDMA_DEBUG_YIELD         = IOMUX_PAD(0x0480, 0x016C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN4__GPIO_4_20                = IOMUX_PAD(0x0480, 0x016C, 5, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DI0_PIN4__MMDC_MMDC_DEBUG_4        = IOMUX_PAD(0x0480, 0x016C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DI0_PIN4__PL301_PER1_HADDR_11      = IOMUX_PAD(0x0480, 0x016C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0       = IOMUX_PAD(0x0484, 0x0170, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT0__IPU2_DISP0_DAT_0       = IOMUX_PAD(0x0484, 0x0170, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT0__ECSPI3_SCLK            = IOMUX_PAD(0x0484, 0x0170, 2, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT0__USDHC1_USDHC_DBG_0     = IOMUX_PAD(0x0484, 0x0170, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT0__SDMA_DBG_CORE_RUN      = IOMUX_PAD(0x0484, 0x0170, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT0__GPIO_4_21              = IOMUX_PAD(0x0484, 0x0170, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT0__MMDC_MMDC_DEBUG_5      = IOMUX_PAD(0x0484, 0x0170, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1       = IOMUX_PAD(0x0488, 0x0174, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT1__IPU2_DISP0_DAT_1       = IOMUX_PAD(0x0488, 0x0174, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT1__ECSPI3_MOSI            = IOMUX_PAD(0x0488, 0x0174, 2, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT1__USDHC1_USDHC_DBG_1     = IOMUX_PAD(0x0488, 0x0174, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT1__SDMA_DBG_EVT_CHNSL     = IOMUX_PAD(0x0488, 0x0174, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT1__GPIO_4_22              = IOMUX_PAD(0x0488, 0x0174, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT1__MMDC_DEBUG_6           = IOMUX_PAD(0x0488, 0x0174, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT1__PL301_PER1_HADR_12     = IOMUX_PAD(0x0488, 0x0174, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2       = IOMUX_PAD(0x048C, 0x0178, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT2__IPU2_DISP0_DAT_2       = IOMUX_PAD(0x048C, 0x0178, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT2__ECSPI3_MISO            = IOMUX_PAD(0x048C, 0x0178, 2, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT2__USDHC1_USDHC_DBG_2     = IOMUX_PAD(0x048C, 0x0178, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT2__SDMA_DEBUG_MODE        = IOMUX_PAD(0x048C, 0x0178, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT2__GPIO_4_23              = IOMUX_PAD(0x048C, 0x0178, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT2__MMDC_DEBUG_7           = IOMUX_PAD(0x048C, 0x0178, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT2__PL301_PER1_HADR_13     = IOMUX_PAD(0x048C, 0x0178, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3       = IOMUX_PAD(0x0490, 0x017C, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT3__IPU2_DISP0_DAT_3       = IOMUX_PAD(0x0490, 0x017C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT3__ECSPI3_SS0             = IOMUX_PAD(0x0490, 0x017C, 2, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT3__USDHC1_USDHC_DBG_3     = IOMUX_PAD(0x0490, 0x017C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT3__SDMA_DBG_BUS_ERROR     = IOMUX_PAD(0x0490, 0x017C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT3__GPIO_4_24              = IOMUX_PAD(0x0490, 0x017C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT3__MMDC_MMDC_DBG_8        = IOMUX_PAD(0x0490, 0x017C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT3__PL301_PER1_HADR_14     = IOMUX_PAD(0x0490, 0x017C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4       = IOMUX_PAD(0x0494, 0x0180, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT4__IPU2_DISP0_DAT_4       = IOMUX_PAD(0x0494, 0x0180, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT4__ECSPI3_SS1             = IOMUX_PAD(0x0494, 0x0180, 2, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT4__USDHC1_USDHC_DBG_4     = IOMUX_PAD(0x0494, 0x0180, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT4__SDMA_DEBUG_BUS_RWB     = IOMUX_PAD(0x0494, 0x0180, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT4__GPIO_4_25              = IOMUX_PAD(0x0494, 0x0180, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT4__MMDC_MMDC_DEBUG_9      = IOMUX_PAD(0x0494, 0x0180, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT4__PL301_PER1_HADR_15     = IOMUX_PAD(0x0494, 0x0180, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5       = IOMUX_PAD(0x0498, 0x0184, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT5__IPU2_DISP0_DAT_5       = IOMUX_PAD(0x0498, 0x0184, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT5__ECSPI3_SS2             = IOMUX_PAD(0x0498, 0x0184, 2, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT5__AUDMUX_AUD6_RXFS       = IOMUX_PAD(0x0498, 0x0184, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT5__SDMA_DBG_MCH_DMBUS     = IOMUX_PAD(0x0498, 0x0184, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT5__GPIO_4_26              = IOMUX_PAD(0x0498, 0x0184, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT5__MMDC_DEBUG_10          = IOMUX_PAD(0x0498, 0x0184, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT5__PL301_PER1_HADR_16     = IOMUX_PAD(0x0498, 0x0184, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6       = IOMUX_PAD(0x049C, 0x0188, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT6__IPU2_DISP0_DAT_6       = IOMUX_PAD(0x049C, 0x0188, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT6__ECSPI3_SS3             = IOMUX_PAD(0x049C, 0x0188, 2, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT6__AUDMUX_AUD6_RXC        = IOMUX_PAD(0x049C, 0x0188, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT6__SDMA_DBG_RTBUF_WRT     = IOMUX_PAD(0x049C, 0x0188, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT6__GPIO_4_27              = IOMUX_PAD(0x049C, 0x0188, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT6__MMDC_DEBUG_11          = IOMUX_PAD(0x049C, 0x0188, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT6__PL301_PER1_HADR_17     = IOMUX_PAD(0x049C, 0x0188, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7       = IOMUX_PAD(0x04A0, 0x018C, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT7__IPU2_DISP0_DAT_7       = IOMUX_PAD(0x04A0, 0x018C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT7__ECSPI3_RDY             = IOMUX_PAD(0x04A0, 0x018C, 2, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT7__USDHC1_USDHC_DBG_5     = IOMUX_PAD(0x04A0, 0x018C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT7__SDMA_DBG_EVT_CHN_0     = IOMUX_PAD(0x04A0, 0x018C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT7__GPIO_4_28              = IOMUX_PAD(0x04A0, 0x018C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT7__MMDC_DEBUG_12          = IOMUX_PAD(0x04A0, 0x018C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT7__PL301_PER1_HADR_18     = IOMUX_PAD(0x04A0, 0x018C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8       = IOMUX_PAD(0x04A4, 0x0190, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT8__IPU2_DISP0_DAT_8       = IOMUX_PAD(0x04A4, 0x0190, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT8__PWM1_PWMO              = IOMUX_PAD(0x04A4, 0x0190, 2, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT8__WDOG1_WDOG_B           = IOMUX_PAD(0x04A4, 0x0190, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT8__SDMA_DBG_EVT_CHN_1     = IOMUX_PAD(0x04A4, 0x0190, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT8__GPIO_4_29              = IOMUX_PAD(0x04A4, 0x0190, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT8__MMDC_DEBUG_13          = IOMUX_PAD(0x04A4, 0x0190, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT8__PL301_PER1_HADR_19     = IOMUX_PAD(0x04A4, 0x0190, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9       = IOMUX_PAD(0x04A8, 0x0194, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT9__IPU2_DISP0_DAT_9       = IOMUX_PAD(0x04A8, 0x0194, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT9__PWM2_PWMO              = IOMUX_PAD(0x04A8, 0x0194, 2, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT9__WDOG2_WDOG_B           = IOMUX_PAD(0x04A8, 0x0194, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT9__SDMA_DBG_EVT_CHN_2     = IOMUX_PAD(0x04A8, 0x0194, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT9__GPIO_4_30              = IOMUX_PAD(0x04A8, 0x0194, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT9__MMDC_DEBUG_14          = IOMUX_PAD(0x04A8, 0x0194, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT9__PL301_PER1_HADR_20     = IOMUX_PAD(0x04A8, 0x0194, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10     = IOMUX_PAD(0x04AC, 0x0198, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT10__IPU2_DISP0_DAT_10     = IOMUX_PAD(0x04AC, 0x0198, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT10__USDHC1_DBG_6          = IOMUX_PAD(0x04AC, 0x0198, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT10__SDMA_DBG_EVT_CHN3     = IOMUX_PAD(0x04AC, 0x0198, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT10__GPIO_4_31             = IOMUX_PAD(0x04AC, 0x0198, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT10__MMDC_DEBUG_15         = IOMUX_PAD(0x04AC, 0x0198, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT10__PL301_PER1_HADR21     = IOMUX_PAD(0x04AC, 0x0198, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11     = IOMUX_PAD(0x04B0, 0x019C, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT11__IPU2_DISP0_DAT_11     = IOMUX_PAD(0x04B0, 0x019C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT11__USDHC1_USDHC_DBG7     = IOMUX_PAD(0x04B0, 0x019C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT11__SDMA_DBG_EVT_CHN4     = IOMUX_PAD(0x04B0, 0x019C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT11__GPIO_5_5              = IOMUX_PAD(0x04B0, 0x019C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT11__MMDC_DEBUG_16         = IOMUX_PAD(0x04B0, 0x019C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT11__PL301_PER1_HADR22     = IOMUX_PAD(0x04B0, 0x019C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12     = IOMUX_PAD(0x04B4, 0x01A0, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT12__IPU2_DISP0_DAT_12     = IOMUX_PAD(0x04B4, 0x01A0, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT12__RESERVED_RESERVED     = IOMUX_PAD(0x04B4, 0x01A0, 3, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT12__SDMA_DBG_EVT_CHN5     = IOMUX_PAD(0x04B4, 0x01A0, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT12__GPIO_5_6              = IOMUX_PAD(0x04B4, 0x01A0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT12__MMDC_DEBUG_17         = IOMUX_PAD(0x04B4, 0x01A0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT12__PL301_PER1_HADR23     = IOMUX_PAD(0x04B4, 0x01A0, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13     = IOMUX_PAD(0x04B8, 0x01A4, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT13__IPU2_DISP0_DAT_13     = IOMUX_PAD(0x04B8, 0x01A4, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT13__AUDMUX_AUD5_RXFS      = IOMUX_PAD(0x04B8, 0x01A4, 3, 0x07D8, 1, 0),
+    MX6Q_PAD_DISP0_DAT13__SDMA_DBG_EVT_CHN0     = IOMUX_PAD(0x04B8, 0x01A4, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT13__GPIO_5_7              = IOMUX_PAD(0x04B8, 0x01A4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT13__MMDC_DEBUG_18         = IOMUX_PAD(0x04B8, 0x01A4, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT13__PL301_PER1_HADR24     = IOMUX_PAD(0x04B8, 0x01A4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14     = IOMUX_PAD(0x04BC, 0x01A8, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT14__IPU2_DISP0_DAT_14     = IOMUX_PAD(0x04BC, 0x01A8, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT14__AUDMUX_AUD5_RXC       = IOMUX_PAD(0x04BC, 0x01A8, 3, 0x07D4, 1, 0),
+    MX6Q_PAD_DISP0_DAT14__SDMA_DBG_EVT_CHN1     = IOMUX_PAD(0x04BC, 0x01A8, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT14__GPIO_5_8              = IOMUX_PAD(0x04BC, 0x01A8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT14__MMDC_DEBUG_19         = IOMUX_PAD(0x04BC, 0x01A8, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15     = IOMUX_PAD(0x04C0, 0x01AC, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT15__IPU2_DISP0_DAT_15     = IOMUX_PAD(0x04C0, 0x01AC, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT15__ECSPI1_SS1            = IOMUX_PAD(0x04C0, 0x01AC, 2, 0x0804, 1, 0),
+    MX6Q_PAD_DISP0_DAT15__ECSPI2_SS1            = IOMUX_PAD(0x04C0, 0x01AC, 3, 0x0820, 1, 0),
+    MX6Q_PAD_DISP0_DAT15__SDMA_DBG_EVT_CHN2     = IOMUX_PAD(0x04C0, 0x01AC, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT15__GPIO_5_9              = IOMUX_PAD(0x04C0, 0x01AC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT15__MMDC_DEBUG_20         = IOMUX_PAD(0x04C0, 0x01AC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT15__PL301_PER1_HADR25     = IOMUX_PAD(0x04C0, 0x01AC, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16     = IOMUX_PAD(0x04C4, 0x01B0, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT16__IPU2_DISP0_DAT_16     = IOMUX_PAD(0x04C4, 0x01B0, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT16__ECSPI2_MOSI           = IOMUX_PAD(0x04C4, 0x01B0, 2, 0x0818, 1, 0),
+    MX6Q_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC       = IOMUX_PAD(0x04C4, 0x01B0, 3, 0x07DC, 0, 0),
+    MX6Q_PAD_DISP0_DAT16__SDMA_EXT_EVENT_0      = IOMUX_PAD(0x04C4, 0x01B0, 4, 0x090C, 0, 0),
+    MX6Q_PAD_DISP0_DAT16__GPIO_5_10             = IOMUX_PAD(0x04C4, 0x01B0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT16__MMDC_DEBUG_21         = IOMUX_PAD(0x04C4, 0x01B0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT16__PL301_PER1_HADR26     = IOMUX_PAD(0x04C4, 0x01B0, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17     = IOMUX_PAD(0x04C8, 0x01B4, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT17__IPU2_DISP0_DAT_17     = IOMUX_PAD(0x04C8, 0x01B4, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT17__ECSPI2_MISO           = IOMUX_PAD(0x04C8, 0x01B4, 2, 0x0814, 1, 0),
+    MX6Q_PAD_DISP0_DAT17__AUDMUX_AUD5_TXD       = IOMUX_PAD(0x04C8, 0x01B4, 3, 0x07D0, 0, 0),
+    MX6Q_PAD_DISP0_DAT17__SDMA_EXT_EVENT_1      = IOMUX_PAD(0x04C8, 0x01B4, 4, 0x0910, 0, 0),
+    MX6Q_PAD_DISP0_DAT17__GPIO_5_11             = IOMUX_PAD(0x04C8, 0x01B4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT17__MMDC_DEBUG_22         = IOMUX_PAD(0x04C8, 0x01B4, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT17__PL301_PER1_HADR27     = IOMUX_PAD(0x04C8, 0x01B4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18     = IOMUX_PAD(0x04CC, 0x01B8, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT18__IPU2_DISP0_DAT_18     = IOMUX_PAD(0x04CC, 0x01B8, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT18__ECSPI2_SS0            = IOMUX_PAD(0x04CC, 0x01B8, 2, 0x081C, 1, 0),
+    MX6Q_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS      = IOMUX_PAD(0x04CC, 0x01B8, 3, 0x07E0, 0, 0),
+    MX6Q_PAD_DISP0_DAT18__AUDMUX_AUD4_RXFS      = IOMUX_PAD(0x04CC, 0x01B8, 4, 0x07C0, 0, 0),
+    MX6Q_PAD_DISP0_DAT18__GPIO_5_12             = IOMUX_PAD(0x04CC, 0x01B8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT18__MMDC_DEBUG_23         = IOMUX_PAD(0x04CC, 0x01B8, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT18__WEIM_WEIM_CS_2        = IOMUX_PAD(0x04CC, 0x01B8, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19     = IOMUX_PAD(0x04D0, 0x01BC, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT19__IPU2_DISP0_DAT_19     = IOMUX_PAD(0x04D0, 0x01BC, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT19__ECSPI2_SCLK           = IOMUX_PAD(0x04D0, 0x01BC, 2, 0x0810, 1, 0),
+    MX6Q_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD       = IOMUX_PAD(0x04D0, 0x01BC, 3, 0x07CC, 0, 0),
+    MX6Q_PAD_DISP0_DAT19__AUDMUX_AUD4_RXC       = IOMUX_PAD(0x04D0, 0x01BC, 4, 0x07BC, 0, 0),
+    MX6Q_PAD_DISP0_DAT19__GPIO_5_13             = IOMUX_PAD(0x04D0, 0x01BC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT19__MMDC_DEBUG_24         = IOMUX_PAD(0x04D0, 0x01BC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT19__WEIM_WEIM_CS_3        = IOMUX_PAD(0x04D0, 0x01BC, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20     = IOMUX_PAD(0x04D4, 0x01C0, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT20__IPU2_DISP0_DAT_20     = IOMUX_PAD(0x04D4, 0x01C0, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT20__ECSPI1_SCLK           = IOMUX_PAD(0x04D4, 0x01C0, 2, 0x07F4, 1, 0),
+    MX6Q_PAD_DISP0_DAT20__AUDMUX_AUD4_TXC       = IOMUX_PAD(0x04D4, 0x01C0, 3, 0x07C4, 0, 0),
+    MX6Q_PAD_DISP0_DAT20__SDMA_DBG_EVT_CHN7     = IOMUX_PAD(0x04D4, 0x01C0, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT20__GPIO_5_14             = IOMUX_PAD(0x04D4, 0x01C0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT20__MMDC_DEBUG_25         = IOMUX_PAD(0x04D4, 0x01C0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT20__PL301_PER1_HADR28     = IOMUX_PAD(0x04D4, 0x01C0, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21     = IOMUX_PAD(0x04D8, 0x01C4, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT21__IPU2_DISP0_DAT_21     = IOMUX_PAD(0x04D8, 0x01C4, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT21__ECSPI1_MOSI           = IOMUX_PAD(0x04D8, 0x01C4, 2, 0x07FC, 1, 0),
+    MX6Q_PAD_DISP0_DAT21__AUDMUX_AUD4_TXD       = IOMUX_PAD(0x04D8, 0x01C4, 3, 0x07B8, 1, 0),
+    MX6Q_PAD_DISP0_DAT21__SDMA_DBG_BUS_DEV0     = IOMUX_PAD(0x04D8, 0x01C4, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT21__GPIO_5_15             = IOMUX_PAD(0x04D8, 0x01C4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT21__MMDC_DEBUG_26         = IOMUX_PAD(0x04D8, 0x01C4, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT21__PL301_PER1_HADR29     = IOMUX_PAD(0x04D8, 0x01C4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22     = IOMUX_PAD(0x04DC, 0x01C8, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT22__IPU2_DISP0_DAT_22     = IOMUX_PAD(0x04DC, 0x01C8, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT22__ECSPI1_MISO           = IOMUX_PAD(0x04DC, 0x01C8, 2, 0x07F8, 1, 0),
+    MX6Q_PAD_DISP0_DAT22__AUDMUX_AUD4_TXFS      = IOMUX_PAD(0x04DC, 0x01C8, 3, 0x07C8, 1, 0),
+    MX6Q_PAD_DISP0_DAT22__SDMA_DBG_BUS_DEV1     = IOMUX_PAD(0x04DC, 0x01C8, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT22__GPIO_5_16             = IOMUX_PAD(0x04DC, 0x01C8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT22__MMDC_DEBUG_27         = IOMUX_PAD(0x04DC, 0x01C8, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT22__PL301_PER1_HADR30     = IOMUX_PAD(0x04DC, 0x01C8, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23     = IOMUX_PAD(0x04E0, 0x01CC, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
+    MX6Q_PAD_DISP0_DAT23__IPU2_DISP0_DAT_23     = IOMUX_PAD(0x04E0, 0x01CC, 1, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT23__ECSPI1_SS0            = IOMUX_PAD(0x04E0, 0x01CC, 2, 0x0800, 1, 0),
+    MX6Q_PAD_DISP0_DAT23__AUDMUX_AUD4_RXD       = IOMUX_PAD(0x04E0, 0x01CC, 3, 0x07B4, 1, 0),
+    MX6Q_PAD_DISP0_DAT23__SDMA_DBG_BUS_DEV2     = IOMUX_PAD(0x04E0, 0x01CC, 4, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT23__GPIO_5_17             = IOMUX_PAD(0x04E0, 0x01CC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT23__MMDC_DEBUG_28         = IOMUX_PAD(0x04E0, 0x01CC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_DISP0_DAT23__PL301_PER1_HADR31     = IOMUX_PAD(0x04E0, 0x01CC, 7, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_MDIO__RESERVED_RESERVED       = IOMUX_PAD(0x04E4, 0x01D0, 0, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_MDIO__ENET_MDIO               = IOMUX_PAD(0x04E4, 0x01D0, 1, 0x0840, 0, 0),
+    MX6Q_PAD_ENET_MDIO__ESAI1_SCKR              = IOMUX_PAD(0x04E4, 0x01D0, 2, 0x086C, 0, 0),
+    MX6Q_PAD_ENET_MDIO__SDMA_DEBUG_BUS_DEV3     = IOMUX_PAD(0x04E4, 0x01D0, 3, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_MDIO__ENET_1588_EVT1_OUT      = IOMUX_PAD(0x04E4, 0x01D0, 4, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_MDIO__GPIO_1_22               = IOMUX_PAD(0x04E4, 0x01D0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_MDIO__SPDIF_PLOCK             = IOMUX_PAD(0x04E4, 0x01D0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_REF_CLK__RESERVED_RSRVED      = IOMUX_PAD(0x04E8, 0x01D4, 0, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK          = IOMUX_PAD(0x04E8, 0x01D4, 1, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_REF_CLK__ESAI1_FSR            = IOMUX_PAD(0x04E8, 0x01D4, 2, 0x085C, 0, 0),
+    MX6Q_PAD_ENET_REF_CLK__SDMA_DBGBUS_DEV4     = IOMUX_PAD(0x04E8, 0x01D4, 3, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_REF_CLK__GPIO_1_23            = IOMUX_PAD(0x04E8, 0x01D4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_REF_CLK__SPDIF_SRCLK          = IOMUX_PAD(0x04E8, 0x01D4, 6, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_REF_CLK__USBPHY1_RX_SQH       = IOMUX_PAD(0x04E8, 0x01D4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_RX_ER__ENET_RX_ER             = IOMUX_PAD(0x04EC, 0x01D8, 1, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_RX_ER__ESAI1_HCKR             = IOMUX_PAD(0x04EC, 0x01D8, 2, 0x0864, 0, 0),
+    MX6Q_PAD_ENET_RX_ER__SPDIF_IN1              = IOMUX_PAD(0x04EC, 0x01D8, 3, 0x0914, 1, 0),
+    MX6Q_PAD_ENET_RX_ER__ENET_1588_EVT2_OUT     = IOMUX_PAD(0x04EC, 0x01D8, 4, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_RX_ER__GPIO_1_24              = IOMUX_PAD(0x04EC, 0x01D8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_RX_ER__PHY_TDI                = IOMUX_PAD(0x04EC, 0x01D8, 6, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_RX_ER__USBPHY1_RX_HS_RXD      = IOMUX_PAD(0x04EC, 0x01D8, 7, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_CRS_DV__RESERVED_RSRVED       = IOMUX_PAD(0x04F0, 0x01DC, 0, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_CRS_DV__ENET_RX_EN            = IOMUX_PAD(0x04F0, 0x01DC, 1, 0x0858, 1, 0),
+    MX6Q_PAD_ENET_CRS_DV__ESAI1_SCKT            = IOMUX_PAD(0x04F0, 0x01DC, 2, 0x0870, 0, 0),
+    MX6Q_PAD_ENET_CRS_DV__SPDIF_EXTCLK          = IOMUX_PAD(0x04F0, 0x01DC, 3, 0x0918, 1, 0),
+    MX6Q_PAD_ENET_CRS_DV__GPIO_1_25             = IOMUX_PAD(0x04F0, 0x01DC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_CRS_DV__PHY_TDO               = IOMUX_PAD(0x04F0, 0x01DC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_CRS_DV__USBPHY1_RX_FS_RXD     = IOMUX_PAD(0x04F0, 0x01DC, 7, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_RXD1__MLB_MLBSIG              = IOMUX_PAD(0x04F4, 0x01E0, 0, 0x0908, 0, 0),
+    MX6Q_PAD_ENET_RXD1__ENET_RDATA_1            = IOMUX_PAD(0x04F4, 0x01E0, 1, 0x084C, 1, 0),
+    MX6Q_PAD_ENET_RXD1__ESAI1_FST               = IOMUX_PAD(0x04F4, 0x01E0, 2, 0x0860, 0, 0),
+    MX6Q_PAD_ENET_RXD1__ENET_1588_EVT3_OUT      = IOMUX_PAD(0x04F4, 0x01E0, 4, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_RXD1__GPIO_1_26               = IOMUX_PAD(0x04F4, 0x01E0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_RXD1__PHY_TCK                 = IOMUX_PAD(0x04F4, 0x01E0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_RXD1__USBPHY1_RX_DISCON       = IOMUX_PAD(0x04F4, 0x01E0, 7, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_RXD0__OSC32K_32K_OUT          = IOMUX_PAD(0x04F8, 0x01E4, 0, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_RXD0__ENET_RDATA_0            = IOMUX_PAD(0x04F8, 0x01E4, 1, 0x0848, 1, 0),
+    MX6Q_PAD_ENET_RXD0__ESAI1_HCKT              = IOMUX_PAD(0x04F8, 0x01E4, 2, 0x0868, 0, 0),
+    MX6Q_PAD_ENET_RXD0__SPDIF_OUT1              = IOMUX_PAD(0x04F8, 0x01E4, 3, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_RXD0__GPIO_1_27               = IOMUX_PAD(0x04F8, 0x01E4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_RXD0__PHY_TMS                 = IOMUX_PAD(0x04F8, 0x01E4, 6, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_RXD0__USBPHY1_PLL_CK20DIV     = IOMUX_PAD(0x04F8, 0x01E4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_TX_EN__RESERVED_RSRVED        = IOMUX_PAD(0x04FC, 0x01E8, 0, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_TX_EN__ENET_TX_EN             = IOMUX_PAD(0x04FC, 0x01E8, 1, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_TX_EN__ESAI1_TX3_RX2          = IOMUX_PAD(0x04FC, 0x01E8, 2, 0x0880, 0, 0),
+    MX6Q_PAD_ENET_TX_EN__GPIO_1_28              = IOMUX_PAD(0x04FC, 0x01E8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_TX_EN__SATA_PHY_TDI           = IOMUX_PAD(0x04FC, 0x01E8, 6, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_TX_EN__USBPHY2_RX_SQH         = IOMUX_PAD(0x04FC, 0x01E8, 7, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_TXD1__MLB_MLBCLK              = IOMUX_PAD(0x0500, 0x01EC, 0, 0x0900, 0, 0),
+    MX6Q_PAD_ENET_TXD1__ENET_TDATA_1            = IOMUX_PAD(0x0500, 0x01EC, 1, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_TXD1__ESAI1_TX2_RX3           = IOMUX_PAD(0x0500, 0x01EC, 2, 0x087C, 0, 0),
+    MX6Q_PAD_ENET_TXD1__ENET_1588_EVENT0_IN     = IOMUX_PAD(0x0500, 0x01EC, 4, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_TXD1__GPIO_1_29               = IOMUX_PAD(0x0500, 0x01EC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_TXD1__SATA_PHY_TDO            = IOMUX_PAD(0x0500, 0x01EC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_TXD1__USBPHY2_RX_HS_RXD       = IOMUX_PAD(0x0500, 0x01EC, 7, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_TXD0__RESERVED_RSRVED         = IOMUX_PAD(0x0504, 0x01F0, 0, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_TXD0__ENET_TDATA_0            = IOMUX_PAD(0x0504, 0x01F0, 1, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_TXD0__ESAI1_TX4_RX1           = IOMUX_PAD(0x0504, 0x01F0, 2, 0x0884, 0, 0),
+    MX6Q_PAD_ENET_TXD0__GPIO_1_30               = IOMUX_PAD(0x0504, 0x01F0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_TXD0__SATA_PHY_TCK            = IOMUX_PAD(0x0504, 0x01F0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_TXD0__USBPHY2_RX_FS_RXD       = IOMUX_PAD(0x0504, 0x01F0, 7, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_MDC__MLB_MLBDAT               = IOMUX_PAD(0x0508, 0x01F4, 0, 0x0904, 0, 0),
+    MX6Q_PAD_ENET_MDC__ENET_MDC                 = IOMUX_PAD(0x0508, 0x01F4, 1, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_MDC__ESAI1_TX5_RX0            = IOMUX_PAD(0x0508, 0x01F4, 2, 0x0888, 0, 0),
+    MX6Q_PAD_ENET_MDC__ENET_1588_EVENT1_IN      = IOMUX_PAD(0x0508, 0x01F4, 4, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_MDC__GPIO_1_31                = IOMUX_PAD(0x0508, 0x01F4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_MDC__SATA_PHY_TMS             = IOMUX_PAD(0x0508, 0x01F4, 6, 0x0000, 0, 0),
+    MX6Q_PAD_ENET_MDC__USBPHY2_RX_DISCON        = IOMUX_PAD(0x0508, 0x01F4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D40__MMDC_DRAM_D_40           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D41__MMDC_DRAM_D_41           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D42__MMDC_DRAM_D_42           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D43__MMDC_DRAM_D_43           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D44__MMDC_DRAM_D_44           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D45__MMDC_DRAM_D_45           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D46__MMDC_DRAM_D_46           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D47__MMDC_DRAM_D_47           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDQS5__MMDC_DRAM_SDQS_5       = IOMUX_PAD(0x050C, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_DQM5__MMDC_DRAM_DQM_5         = IOMUX_PAD(0x0510, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D32__MMDC_DRAM_D_32           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D33__MMDC_DRAM_D_33           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D34__MMDC_DRAM_D_34           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D35__MMDC_DRAM_D_35           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D36__MMDC_DRAM_D_36           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D37__MMDC_DRAM_D_37           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D38__MMDC_DRAM_D_38           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D39__MMDC_DRAM_D_39           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_DQM4__MMDC_DRAM_DQM_4         = IOMUX_PAD(0x0514, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDQS4__MMDC_DRAM_SDQS_4       = IOMUX_PAD(0x0518, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D24__MMDC_DRAM_D_24           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D25__MMDC_DRAM_D_25           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D26__MMDC_DRAM_D_26           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D27__MMDC_DRAM_D_27           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D28__MMDC_DRAM_D_28           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D29__MMDC_DRAM_D_29           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDQS3__MMDC_DRAM_SDQS_3       = IOMUX_PAD(0x051C, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D30__MMDC_DRAM_D_30           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D31__MMDC_DRAM_D_31           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_DQM3__MMDC_DRAM_DQM_3         = IOMUX_PAD(0x0520, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D16__MMDC_DRAM_D_16           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D17__MMDC_DRAM_D_17           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D18__MMDC_DRAM_D_18           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D19__MMDC_DRAM_D_19           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D20__MMDC_DRAM_D_20           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D21__MMDC_DRAM_D_21           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D22__MMDC_DRAM_D_22           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDQS2__MMDC_DRAM_SDQS_2       = IOMUX_PAD(0x0524, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D23__MMDC_DRAM_D_23           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_DQM2__MMDC_DRAM_DQM_2         = IOMUX_PAD(0x0528, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_A0__MMDC_DRAM_A_0             = IOMUX_PAD(0x052C, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_A1__MMDC_DRAM_A_1             = IOMUX_PAD(0x0530, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_A2__MMDC_DRAM_A_2             = IOMUX_PAD(0x0534, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_A3__MMDC_DRAM_A_3             = IOMUX_PAD(0x0538, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_A4__MMDC_DRAM_A_4             = IOMUX_PAD(0x053C, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_A5__MMDC_DRAM_A_5             = IOMUX_PAD(0x0540, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_A6__MMDC_DRAM_A_6             = IOMUX_PAD(0x0544, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_A7__MMDC_DRAM_A_7             = IOMUX_PAD(0x0548, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_A8__MMDC_DRAM_A_8             = IOMUX_PAD(0x054C, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_A9__MMDC_DRAM_A_9             = IOMUX_PAD(0x0550, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_A10__MMDC_DRAM_A_10           = IOMUX_PAD(0x0554, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_A11__MMDC_DRAM_A_11           = IOMUX_PAD(0x0558, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_A12__MMDC_DRAM_A_12           = IOMUX_PAD(0x055C, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_A13__MMDC_DRAM_A_13           = IOMUX_PAD(0x0560, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_A14__MMDC_DRAM_A_14           = IOMUX_PAD(0x0564, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_A15__MMDC_DRAM_A_15           = IOMUX_PAD(0x0568, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_CAS__MMDC_DRAM_CAS            = IOMUX_PAD(0x056C, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_CS0__MMDC_DRAM_CS_0           = IOMUX_PAD(0x0570, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_CS1__MMDC_DRAM_CS_1           = IOMUX_PAD(0x0574, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_RAS__MMDC_DRAM_RAS            = IOMUX_PAD(0x0578, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_RESET__MMDC_DRAM_RESET        = IOMUX_PAD(0x057C, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDBA0__MMDC_DRAM_SDBA_0       = IOMUX_PAD(0x0580, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDBA1__MMDC_DRAM_SDBA_1       = IOMUX_PAD(0x0584, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDCLK_0__MMDC_DRAM_SDCLK0     = IOMUX_PAD(0x0588, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDBA2__MMDC_DRAM_SDBA_2       = IOMUX_PAD(0x058C, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDCKE0__MMDC_DRAM_SDCKE_0     = IOMUX_PAD(0x0590, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDCLK_1__MMDC_DRAM_SDCLK1     = IOMUX_PAD(0x0594, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDCKE1__MMDC_DRAM_SDCKE_1     = IOMUX_PAD(0x0598, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDODT0__MMDC_DRAM_ODT_0       = IOMUX_PAD(0x059C, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDODT1__MMDC_DRAM_ODT_1       = IOMUX_PAD(0x05A0, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDWE__MMDC_DRAM_SDWE          = IOMUX_PAD(0x05A4, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D0__MMDC_DRAM_D_0             = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D1__MMDC_DRAM_D_1             = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D2__MMDC_DRAM_D_2             = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D3__MMDC_DRAM_D_3             = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D4__MMDC_DRAM_D_4             = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D5__MMDC_DRAM_D_5             = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDQS0__MMDC_DRAM_SDQS_0       = IOMUX_PAD(0x05A8, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D6__MMDC_DRAM_D_6             = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D7__MMDC_DRAM_D_7             = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_DQM0__MMDC_DRAM_DQM_0         = IOMUX_PAD(0x05AC, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D8__MMDC_DRAM_D_8             = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D9__MMDC_DRAM_D_9             = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D10__MMDC_DRAM_D_10           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D11__MMDC_DRAM_D_11           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D12__MMDC_DRAM_D_12           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D13__MMDC_DRAM_D_13           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D14__MMDC_DRAM_D_14           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDQS1__MMDC_DRAM_SDQS_1       = IOMUX_PAD(0x05B0, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D15__MMDC_DRAM_D_15           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_DQM1__MMDC_DRAM_DQM_1         = IOMUX_PAD(0x05B4, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D48__MMDC_DRAM_D_48           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D49__MMDC_DRAM_D_49           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D50__MMDC_DRAM_D_50           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D51__MMDC_DRAM_D_51           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D52__MMDC_DRAM_D_52           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D53__MMDC_DRAM_D_53           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D54__MMDC_DRAM_D_54           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D55__MMDC_DRAM_D_55           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDQS6__MMDC_DRAM_SDQS_6       = IOMUX_PAD(0x05B8, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_DQM6__MMDC_DRAM_DQM_6         = IOMUX_PAD(0x05BC, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D56__MMDC_DRAM_D_56           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_SDQS7__MMDC_DRAM_SDQS_7       = IOMUX_PAD(0x05C0, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D57__MMDC_DRAM_D_57           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D58__MMDC_DRAM_D_58           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D59__MMDC_DRAM_D_59           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D60__MMDC_DRAM_D_60           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_DQM7__MMDC_DRAM_DQM_7         = IOMUX_PAD(0x05C4, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D61__MMDC_DRAM_D_61           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D62__MMDC_DRAM_D_62           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_DRAM_D63__MMDC_DRAM_D_63           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL0__ECSPI1_SCLK              = IOMUX_PAD(0x05C8, 0x01F8, 0, 0x07F4, 2, 0),
+    MX6Q_PAD_KEY_COL0__ENET_RDATA_3             = IOMUX_PAD(0x05C8, 0x01F8, 1, 0x0854, 1, 0),
+    MX6Q_PAD_KEY_COL0__AUDMUX_AUD5_TXC          = IOMUX_PAD(0x05C8, 0x01F8, 2, 0x07DC, 1, 0),
+    MX6Q_PAD_KEY_COL0__KPP_COL_0                = IOMUX_PAD(0x05C8, 0x01F8, 3, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL0__UART4_TXD                = IOMUX_PAD(0x05C8, 0x01F8, 4, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL0__UART4_TXD_RXD            = IOMUX_PAD(0x05C8, 0x01F8, 4, 0x0938, 0, 0),
+    MX6Q_PAD_KEY_COL0__GPIO_4_6                 = IOMUX_PAD(0x05C8, 0x01F8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL0__DCIC1_DCIC_OUT           = IOMUX_PAD(0x05C8, 0x01F8, 6, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL0__SRC_ANY_PU_RST           = IOMUX_PAD(0x05C8, 0x01F8, 7, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW0__ECSPI1_MOSI              = IOMUX_PAD(0x05CC, 0x01FC, 0, 0x07FC, 2, 0),
+    MX6Q_PAD_KEY_ROW0__ENET_TDATA_3             = IOMUX_PAD(0x05CC, 0x01FC, 1, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW0__AUDMUX_AUD5_TXD          = IOMUX_PAD(0x05CC, 0x01FC, 2, 0x07D0, 1, 0),
+    MX6Q_PAD_KEY_ROW0__KPP_ROW_0                = IOMUX_PAD(0x05CC, 0x01FC, 3, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW0__UART4_RXD                = IOMUX_PAD(0x05CC, 0x01FC, 4, 0x0938, 1, 0),
+    MX6Q_PAD_KEY_ROW0__GPIO_4_7                 = IOMUX_PAD(0x05CC, 0x01FC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW0__DCIC2_DCIC_OUT           = IOMUX_PAD(0x05CC, 0x01FC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW0__PL301_PER1_HADR_0        = IOMUX_PAD(0x05CC, 0x01FC, 7, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL1__ECSPI1_MISO              = IOMUX_PAD(0x05D0, 0x0200, 0, 0x07F8, 2, 0),
+    MX6Q_PAD_KEY_COL1__ENET_MDIO                = IOMUX_PAD(0x05D0, 0x0200, 1, 0x0840, 1, 0),
+    MX6Q_PAD_KEY_COL1__AUDMUX_AUD5_TXFS         = IOMUX_PAD(0x05D0, 0x0200, 2, 0x07E0, 1, 0),
+    MX6Q_PAD_KEY_COL1__KPP_COL_1                = IOMUX_PAD(0x05D0, 0x0200, 3, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL1__UART5_TXD                = IOMUX_PAD(0x05D0, 0x0200, 4, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL1__UART5_TXD_RXD            = IOMUX_PAD(0x05D0, 0x0200, 4, 0x0940, 0, 0),
+    MX6Q_PAD_KEY_COL1__GPIO_4_8                 = IOMUX_PAD(0x05D0, 0x0200, 5, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL1__USDHC1_VSELECT           = IOMUX_PAD(0x05D0, 0x0200, 6, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL1__PL301MX_PER1_HADR_1      = IOMUX_PAD(0x05D0, 0x0200, 7, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW1__ECSPI1_SS0               = IOMUX_PAD(0x05D4, 0x0204, 0, 0x0800, 2, 0),
+    MX6Q_PAD_KEY_ROW1__ENET_COL                 = IOMUX_PAD(0x05D4, 0x0204, 1, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW1__AUDMUX_AUD5_RXD          = IOMUX_PAD(0x05D4, 0x0204, 2, 0x07CC, 1, 0),
+    MX6Q_PAD_KEY_ROW1__KPP_ROW_1                = IOMUX_PAD(0x05D4, 0x0204, 3, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW1__UART5_RXD                = IOMUX_PAD(0x05D4, 0x0204, 4, 0x0940, 1, 0),
+    MX6Q_PAD_KEY_ROW1__GPIO_4_9                 = IOMUX_PAD(0x05D4, 0x0204, 5, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW1__USDHC2_VSELECT           = IOMUX_PAD(0x05D4, 0x0204, 6, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW1__PL301_PER1_HADDR_2       = IOMUX_PAD(0x05D4, 0x0204, 7, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL2__ECSPI1_SS1               = IOMUX_PAD(0x05D8, 0x0208, 0, 0x0804, 2, 0),
+    MX6Q_PAD_KEY_COL2__ENET_RDATA_2             = IOMUX_PAD(0x05D8, 0x0208, 1, 0x0850, 1, 0),
+    MX6Q_PAD_KEY_COL2__CAN1_TXCAN               = IOMUX_PAD(0x05D8, 0x0208, 2, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL2__KPP_COL_2                = IOMUX_PAD(0x05D8, 0x0208, 3, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL2__ENET_MDC                 = IOMUX_PAD(0x05D8, 0x0208, 4, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL2__GPIO_4_10                = IOMUX_PAD(0x05D8, 0x0208, 5, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL2__USBOH3_H1_PWRCTL_WKP     = IOMUX_PAD(0x05D8, 0x0208, 6, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL2__PL301_PER1_HADDR_3       = IOMUX_PAD(0x05D8, 0x0208, 7, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW2__ECSPI1_SS2               = IOMUX_PAD(0x05DC, 0x020C, 0, 0x0808, 1, 0),
+    MX6Q_PAD_KEY_ROW2__ENET_TDATA_2             = IOMUX_PAD(0x05DC, 0x020C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW2__CAN1_RXCAN               = IOMUX_PAD(0x05DC, 0x020C, 2, 0x07E4, 0, 0),
+    MX6Q_PAD_KEY_ROW2__KPP_ROW_2                = IOMUX_PAD(0x05DC, 0x020C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW2__USDHC2_VSELECT           = IOMUX_PAD(0x05DC, 0x020C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW2__GPIO_4_11                = IOMUX_PAD(0x05DC, 0x020C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW2__HDMI_TX_CEC_LINE         = IOMUX_PAD(0x05DC, 0x020C, 6, 0x088C, 1, 0),
+    MX6Q_PAD_KEY_ROW2__PL301_PER1_HADR_4        = IOMUX_PAD(0x05DC, 0x020C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL3__ECSPI1_SS3               = IOMUX_PAD(0x05E0, 0x0210, 0, 0x080C, 1, 0),
+    MX6Q_PAD_KEY_COL3__ENET_CRS                 = IOMUX_PAD(0x05E0, 0x0210, 1, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL3__HDMI_TX_DDC_SCL          = IOMUX_PAD(0x05E0, 0x0210, 2, 0x0890, 1, 0),
+    MX6Q_PAD_KEY_COL3__KPP_COL_3                = IOMUX_PAD(0x05E0, 0x0210, 3, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL3__I2C2_SCL                 = IOMUX_PAD(0x05E0, 0x0210, 20, 0x08A0, 1, 0),
+    MX6Q_PAD_KEY_COL3__GPIO_4_12                = IOMUX_PAD(0x05E0, 0x0210, 5, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL3__SPDIF_IN1                = IOMUX_PAD(0x05E0, 0x0210, 6, 0x0914, 2, 0),
+    MX6Q_PAD_KEY_COL3__PL301_PER1_HADR_5        = IOMUX_PAD(0x05E0, 0x0210, 7, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW3__OSC32K_32K_OUT           = IOMUX_PAD(0x05E4, 0x0214, 0, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW3__ASRC_ASRC_EXT_CLK        = IOMUX_PAD(0x05E4, 0x0214, 1, 0x07B0, 0, 0),
+    MX6Q_PAD_KEY_ROW3__HDMI_TX_DDC_SDA          = IOMUX_PAD(0x05E4, 0x0214, 2, 0x0894, 1, 0),
+    MX6Q_PAD_KEY_ROW3__KPP_ROW_3                = IOMUX_PAD(0x05E4, 0x0214, 3, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW3__I2C2_SDA                 = IOMUX_PAD(0x05E4, 0x0214, 20, 0x08A4, 1, 0),
+    MX6Q_PAD_KEY_ROW3__GPIO_4_13                = IOMUX_PAD(0x05E4, 0x0214, 5, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW3__USDHC1_VSELECT           = IOMUX_PAD(0x05E4, 0x0214, 6, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW3__PL301_PER1_HADR_6        = IOMUX_PAD(0x05E4, 0x0214, 7, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL4__CAN2_TXCAN               = IOMUX_PAD(0x05E8, 0x0218, 0, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL4__IPU1_SISG_4              = IOMUX_PAD(0x05E8, 0x0218, 1, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL4__USBOH3_USBOTG_OC         = IOMUX_PAD(0x05E8, 0x0218, 2, 0x0944, 1, 0),
+    MX6Q_PAD_KEY_COL4__KPP_COL_4                = IOMUX_PAD(0x05E8, 0x0218, 3, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL4__UART5_CTS                = IOMUX_PAD(0x05E8, 0x0218, 4, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL4__UART5_RTS                = IOMUX_PAD(0x05E8, 0x0218, 4, 0x093C, 0, 0),
+    MX6Q_PAD_KEY_COL4__GPIO_4_14                = IOMUX_PAD(0x05E8, 0x0218, 5, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL4__MMDC_DEBUG_49            = IOMUX_PAD(0x05E8, 0x0218, 6, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_COL4__PL301_PER1_HADDR_7       = IOMUX_PAD(0x05E8, 0x0218, 7, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW4__CAN2_RXCAN               = IOMUX_PAD(0x05EC, 0x021C, 0, 0x07E8, 0, 0),
+    MX6Q_PAD_KEY_ROW4__IPU1_SISG_5              = IOMUX_PAD(0x05EC, 0x021C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW4__USBOH3_USBOTG_PWR        = IOMUX_PAD(0x05EC, 0x021C, 2, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW4__KPP_ROW_4                = IOMUX_PAD(0x05EC, 0x021C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW4__UART5_CTS                = IOMUX_PAD(0x05EC, 0x021C, 4, 0x093C, 1, 0),
+    MX6Q_PAD_KEY_ROW4__GPIO_4_15                = IOMUX_PAD(0x05EC, 0x021C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW4__MMDC_DEBUG_50            = IOMUX_PAD(0x05EC, 0x021C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_KEY_ROW4__PL301_PER1_HADR_8        = IOMUX_PAD(0x05EC, 0x021C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_0__CCM_CLKO                   = IOMUX_PAD(0x05F0, 0x0220, 0, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_0__KPP_COL_5                  = IOMUX_PAD(0x05F0, 0x0220, 2, 0x08E8, 0, 0),
+    MX6Q_PAD_GPIO_0__ASRC_ASRC_EXT_CLK          = IOMUX_PAD(0x05F0, 0x0220, 3, 0x07B0, 1, 0),
+    MX6Q_PAD_GPIO_0__EPIT1_EPITO                = IOMUX_PAD(0x05F0, 0x0220, 4, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_0__GPIO_1_0                   = IOMUX_PAD(0x05F0, 0x0220, 5, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_0__USBOH3_USBH1_PWR           = IOMUX_PAD(0x05F0, 0x0220, 6, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_0__SNVS_HP_WRAP_SNVS_VIO5     = IOMUX_PAD(0x05F0, 0x0220, 7, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_1__ESAI1_SCKR                 = IOMUX_PAD(0x05F4, 0x0224, 0, 0x086C, 1, 0),
+    MX6Q_PAD_GPIO_1__WDOG2_WDOG_B               = IOMUX_PAD(0x05F4, 0x0224, 1, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_1__KPP_ROW_5                  = IOMUX_PAD(0x05F4, 0x0224, 2, 0x08F4, 0, 0),
+    MX6Q_PAD_GPIO_1__PWM2_PWMO                  = IOMUX_PAD(0x05F4, 0x0224, 4, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_1__GPIO_1_1                   = IOMUX_PAD(0x05F4, 0x0224, 5, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_1__USDHC1_CD                  = IOMUX_PAD(0x05F4, 0x0224, 6, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_1__SRC_TESTER_ACK             = IOMUX_PAD(0x05F4, 0x0224, 7, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_9__ESAI1_FSR                  = IOMUX_PAD(0x05F8, 0x0228, 0, 0x085C, 1, 0),
+    MX6Q_PAD_GPIO_9__WDOG1_WDOG_B               = IOMUX_PAD(0x05F8, 0x0228, 1, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_9__KPP_COL_6                  = IOMUX_PAD(0x05F8, 0x0228, 2, 0x08EC, 0, 0),
+    MX6Q_PAD_GPIO_9__CCM_REF_EN_B               = IOMUX_PAD(0x05F8, 0x0228, 3, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_9__PWM1_PWMO                  = IOMUX_PAD(0x05F8, 0x0228, 4, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_9__GPIO_1_9                   = IOMUX_PAD(0x05F8, 0x0228, 5, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_9__USDHC1_WP                  = IOMUX_PAD(0x05F8, 0x0228, 6, 0x094C, 1, 0),
+    MX6Q_PAD_GPIO_9__SRC_EARLY_RST              = IOMUX_PAD(0x05F8, 0x0228, 7, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_3__ESAI1_HCKR                 = IOMUX_PAD(0x05FC, 0x022C, 0, 0x0864, 1, 0),
+    MX6Q_PAD_GPIO_3__OBSERVE_MUX_INT_OUT0       = IOMUX_PAD(0x05FC, 0x022C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_3__I2C3_SCL                   = IOMUX_PAD(0x05FC, 0x022C, 18, 0x08A8, 1, 0),
+    MX6Q_PAD_GPIO_3__ANATOP_24M_OUT             = IOMUX_PAD(0x05FC, 0x022C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_3__CCM_CLKO2                  = IOMUX_PAD(0x05FC, 0x022C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_3__GPIO_1_3                   = IOMUX_PAD(0x05FC, 0x022C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_3__USBOH3_USBH1_OC            = IOMUX_PAD(0x05FC, 0x022C, 6, 0x0948, 1, 0),
+    MX6Q_PAD_GPIO_3__MLB_MLBCLK                 = IOMUX_PAD(0x05FC, 0x022C, 7, 0x0900, 1, 0),
+    MX6Q_PAD_GPIO_6__ESAI1_SCKT                 = IOMUX_PAD(0x0600, 0x0230, 0, 0x0870, 1, 0),
+    MX6Q_PAD_GPIO_6__OBSERVE_MUX_INT_OUT1       = IOMUX_PAD(0x0600, 0x0230, 1, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_6__I2C3_SDA                   = IOMUX_PAD(0x0600, 0x0230, 18, 0x08AC, 1, 0),
+    MX6Q_PAD_GPIO_6__CCM_CCM_OUT_0              = IOMUX_PAD(0x0600, 0x0230, 3, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_6__CSU_CSU_INT_DEB            = IOMUX_PAD(0x0600, 0x0230, 4, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_6__GPIO_1_6                   = IOMUX_PAD(0x0600, 0x0230, 5, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_6__USDHC2_LCTL                = IOMUX_PAD(0x0600, 0x0230, 6, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_6__MLB_MLBSIG                 = IOMUX_PAD(0x0600, 0x0230, 7, 0x0908, 1, 0),
+    MX6Q_PAD_GPIO_2__ESAI1_FST                  = IOMUX_PAD(0x0604, 0x0234, 0, 0x0860, 1, 0),
+    MX6Q_PAD_GPIO_2__OBSERVE_MUX_INT_OUT2       = IOMUX_PAD(0x0604, 0x0234, 1, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_2__KPP_ROW_6                  = IOMUX_PAD(0x0604, 0x0234, 2, 0x08F8, 1, 0),
+    MX6Q_PAD_GPIO_2__CCM_CCM_OUT_1              = IOMUX_PAD(0x0604, 0x0234, 3, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_2__CSU_CSU_ALARM_AUT_0        = IOMUX_PAD(0x0604, 0x0234, 4, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_2__GPIO_1_2                   = IOMUX_PAD(0x0604, 0x0234, 5, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_2__USDHC2_WP                  = IOMUX_PAD(0x0604, 0x0234, 6, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_2__MLB_MLBDAT                 = IOMUX_PAD(0x0604, 0x0234, 7, 0x0904, 1, 0),
+    MX6Q_PAD_GPIO_4__ESAI1_HCKT                 = IOMUX_PAD(0x0608, 0x0238, 0, 0x0868, 1, 0),
+    MX6Q_PAD_GPIO_4__OBSERVE_MUX_INT_OUT3       = IOMUX_PAD(0x0608, 0x0238, 1, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_4__KPP_COL_7                  = IOMUX_PAD(0x0608, 0x0238, 2, 0x08F0, 1, 0),
+    MX6Q_PAD_GPIO_4__CCM_CCM_OUT_2              = IOMUX_PAD(0x0608, 0x0238, 3, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_4__CSU_CSU_ALARM_AUT_1        = IOMUX_PAD(0x0608, 0x0238, 4, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_4__GPIO_1_4                   = IOMUX_PAD(0x0608, 0x0238, 5, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_4__USDHC2_CD                  = IOMUX_PAD(0x0608, 0x0238, 6, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_4__OCOTP_CRL_WRAR_FUSE_LA     = IOMUX_PAD(0x0608, 0x0238, 7, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_5__ESAI1_TX2_RX3              = IOMUX_PAD(0x060C, 0x023C, 0, 0x087C, 1, 0),
+    MX6Q_PAD_GPIO_5__OBSERVE_MUX_INT_OUT4       = IOMUX_PAD(0x060C, 0x023C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_5__KPP_ROW_7                  = IOMUX_PAD(0x060C, 0x023C, 2, 0x08FC, 1, 0),
+    MX6Q_PAD_GPIO_5__CCM_CLKO                   = IOMUX_PAD(0x060C, 0x023C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2        = IOMUX_PAD(0x060C, 0x023C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_5__GPIO_1_5                   = IOMUX_PAD(0x060C, 0x023C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_5__I2C3_SCL                   = IOMUX_PAD(0x060C, 0x023C, 22, 0x08A8, 2, 0),
+    MX6Q_PAD_GPIO_5__CHEETAH_EVENTI             = IOMUX_PAD(0x060C, 0x023C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_7__ESAI1_TX4_RX1              = IOMUX_PAD(0x0610, 0x0240, 0, 0x0884, 1, 0),
+    MX6Q_PAD_GPIO_7__ECSPI5_RDY                 = IOMUX_PAD(0x0610, 0x0240, 1, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_7__EPIT1_EPITO                = IOMUX_PAD(0x0610, 0x0240, 2, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_7__CAN1_TXCAN                 = IOMUX_PAD(0x0610, 0x0240, 3, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_7__UART2_TXD                  = IOMUX_PAD(0x0610, 0x0240, 4, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_7__UART2_TXD_RXD              = IOMUX_PAD(0x0610, 0x0240, 4, 0x0928, 2, 0),
+    MX6Q_PAD_GPIO_7__GPIO_1_7                   = IOMUX_PAD(0x0610, 0x0240, 5, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_7__SPDIF_PLOCK                = IOMUX_PAD(0x0610, 0x0240, 6, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_7__USBOH3_OTGUSB_HST_MODE     = IOMUX_PAD(0x0610, 0x0240, 7, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_8__ESAI1_TX5_RX0              = IOMUX_PAD(0x0614, 0x0244, 0, 0x0888, 1, 0),
+    MX6Q_PAD_GPIO_8__ANATOP_ANATOP_32K_OUT      = IOMUX_PAD(0x0614, 0x0244, 1, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_8__EPIT2_EPITO                = IOMUX_PAD(0x0614, 0x0244, 2, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_8__CAN1_RXCAN                 = IOMUX_PAD(0x0614, 0x0244, 3, 0x07E4, 1, 0),
+    MX6Q_PAD_GPIO_8__UART2_RXD                  = IOMUX_PAD(0x0614, 0x0244, 4, 0x0928, 3, 0),
+    MX6Q_PAD_GPIO_8__GPIO_1_8                   = IOMUX_PAD(0x0614, 0x0244, 5, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_8__SPDIF_SRCLK                = IOMUX_PAD(0x0614, 0x0244, 6, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_8__USBOH3_OTG_PWRCTL_WAK      = IOMUX_PAD(0x0614, 0x0244, 7, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_16__ESAI1_TX3_RX2             = IOMUX_PAD(0x0618, 0x0248, 0, 0x0880, 1, 0),
+    MX6Q_PAD_GPIO_16__ENET_1588_EVENT2_IN       = IOMUX_PAD(0x0618, 0x0248, 1, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_16__ENET_ETHERNET_REF_OUT     = IOMUX_PAD(0x0618, 0x0248, 2, 0x083C, 1, 0),
+    MX6Q_PAD_GPIO_16__USDHC1_LCTL               = IOMUX_PAD(0x0618, 0x0248, 3, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_16__SPDIF_IN1                 = IOMUX_PAD(0x0618, 0x0248, 4, 0x0914, 3, 0),
+    MX6Q_PAD_GPIO_16__GPIO_7_11                 = IOMUX_PAD(0x0618, 0x0248, 5, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_16__I2C3_SDA                  = IOMUX_PAD(0x0618, 0x0248, 22, 0x08AC, 2, 0),
+    MX6Q_PAD_GPIO_16__SJC_DE_B                  = IOMUX_PAD(0x0618, 0x0248, 7, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_17__ESAI1_TX0                 = IOMUX_PAD(0x061C, 0x024C, 0, 0x0874, 0, 0),
+    MX6Q_PAD_GPIO_17__ENET_1588_EVENT3_IN       = IOMUX_PAD(0x061C, 0x024C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_17__CCM_PMIC_RDY              = IOMUX_PAD(0x061C, 0x024C, 2, 0x07F0, 1, 0),
+    MX6Q_PAD_GPIO_17__SDMA_SDMA_EXT_EVENT_0     = IOMUX_PAD(0x061C, 0x024C, 3, 0x090C, 1, 0),
+    MX6Q_PAD_GPIO_17__SPDIF_OUT1                = IOMUX_PAD(0x061C, 0x024C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_17__GPIO_7_12                 = IOMUX_PAD(0x061C, 0x024C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_17__SJC_JTAG_ACT              = IOMUX_PAD(0x061C, 0x024C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_18__ESAI1_TX1                 = IOMUX_PAD(0x0620, 0x0250, 0, 0x0878, 0, 0),
+    MX6Q_PAD_GPIO_18__ENET_RX_CLK               = IOMUX_PAD(0x0620, 0x0250, 1, 0x0844, 1, 0),
+    MX6Q_PAD_GPIO_18__USDHC3_VSELECT            = IOMUX_PAD(0x0620, 0x0250, 2, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_18__SDMA_SDMA_EXT_EVENT_1     = IOMUX_PAD(0x0620, 0x0250, 3, 0x0910, 1, 0),
+    MX6Q_PAD_GPIO_18__ASRC_ASRC_EXT_CLK         = IOMUX_PAD(0x0620, 0x0250, 4, 0x07B0, 2, 0),
+    MX6Q_PAD_GPIO_18__GPIO_7_13                 = IOMUX_PAD(0x0620, 0x0250, 5, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_18__SNVS_HP_WRA_SNVS_VIO5     = IOMUX_PAD(0x0620, 0x0250, 6, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_18__SRC_SYSTEM_RST            = IOMUX_PAD(0x0620, 0x0250, 7, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_19__KPP_COL_5                 = IOMUX_PAD(0x0624, 0x0254, 0, 0x08E8, 1, 0),
+    MX6Q_PAD_GPIO_19__ENET_1588_EVENT0_OUT      = IOMUX_PAD(0x0624, 0x0254, 1, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_19__SPDIF_OUT1                = IOMUX_PAD(0x0624, 0x0254, 2, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_19__CCM_CLKO                  = IOMUX_PAD(0x0624, 0x0254, 3, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_19__ECSPI1_RDY                = IOMUX_PAD(0x0624, 0x0254, 4, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_19__GPIO_4_5                  = IOMUX_PAD(0x0624, 0x0254, 5, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_19__ENET_TX_ER                = IOMUX_PAD(0x0624, 0x0254, 6, 0x0000, 0, 0),
+    MX6Q_PAD_GPIO_19__SRC_INT_BOOT              = IOMUX_PAD(0x0624, 0x0254, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK      = IOMUX_PAD(0x0628, 0x0258, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_PIXCLK__PCIE_CTRL_MUX_12      = IOMUX_PAD(0x0628, 0x0258, 2, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_PIXCLK__SDMA_DEBUG_PC_0       = IOMUX_PAD(0x0628, 0x0258, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_PIXCLK__GPIO_5_18             = IOMUX_PAD(0x0628, 0x0258, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_PIXCLK___MMDC_DEBUG_29        = IOMUX_PAD(0x0628, 0x0258, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_PIXCLK__CHEETAH_EVENTO        = IOMUX_PAD(0x0628, 0x0258, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC         = IOMUX_PAD(0x062C, 0x025C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_MCLK__PCIE_CTRL_MUX_13        = IOMUX_PAD(0x062C, 0x025C, 2, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_MCLK__CCM_CLKO                = IOMUX_PAD(0x062C, 0x025C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_MCLK__SDMA_DEBUG_PC_1         = IOMUX_PAD(0x062C, 0x025C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_MCLK__GPIO_5_19               = IOMUX_PAD(0x062C, 0x025C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_MCLK__MMDC_MMDC_DEBUG_30      = IOMUX_PAD(0x062C, 0x025C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_MCLK__CHEETAH_TRCTL           = IOMUX_PAD(0x062C, 0x025C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DATA_EN__IPU1_CSI0_DA_EN      = IOMUX_PAD(0x0630, 0x0260, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DATA_EN__WEIM_WEIM_D_0        = IOMUX_PAD(0x0630, 0x0260, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DATA_EN__PCIE_CTRL_MUX_14     = IOMUX_PAD(0x0630, 0x0260, 2, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DATA_EN__SDMA_DEBUG_PC_2      = IOMUX_PAD(0x0630, 0x0260, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DATA_EN__GPIO_5_20            = IOMUX_PAD(0x0630, 0x0260, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DATA_EN__MMDC_DEBUG_31        = IOMUX_PAD(0x0630, 0x0260, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DATA_EN__CHEETAH_TRCLK        = IOMUX_PAD(0x0630, 0x0260, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC        = IOMUX_PAD(0x0634, 0x0264, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_VSYNC__WEIM_WEIM_D_1          = IOMUX_PAD(0x0634, 0x0264, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_VSYNC__PCIE_CTRL_MUX_15       = IOMUX_PAD(0x0634, 0x0264, 2, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_VSYNC__SDMA_DEBUG_PC_3        = IOMUX_PAD(0x0634, 0x0264, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_VSYNC__GPIO_5_21              = IOMUX_PAD(0x0634, 0x0264, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_VSYNC__MMDC_DEBUG_32          = IOMUX_PAD(0x0634, 0x0264, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_VSYNC__CHEETAH_TRACE_0        = IOMUX_PAD(0x0634, 0x0264, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT4__IPU1_CSI0_D_4           = IOMUX_PAD(0x0638, 0x0268, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT4__WEIM_WEIM_D_2           = IOMUX_PAD(0x0638, 0x0268, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT4__ECSPI1_SCLK             = IOMUX_PAD(0x0638, 0x0268, 2, 0x07F4, 3, 0),
+    MX6Q_PAD_CSI0_DAT4__KPP_COL_5               = IOMUX_PAD(0x0638, 0x0268, 3, 0x08E8, 2, 0),
+    MX6Q_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC         = IOMUX_PAD(0x0638, 0x0268, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT4__GPIO_5_22               = IOMUX_PAD(0x0638, 0x0268, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT4__MMDC_DEBUG_43           = IOMUX_PAD(0x0638, 0x0268, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT4__CHEETAH_TRACE_1         = IOMUX_PAD(0x0638, 0x0268, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT5__IPU1_CSI0_D_5           = IOMUX_PAD(0x063C, 0x026C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT5__WEIM_WEIM_D_3           = IOMUX_PAD(0x063C, 0x026C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT5__ECSPI1_MOSI             = IOMUX_PAD(0x063C, 0x026C, 2, 0x07FC, 3, 0),
+    MX6Q_PAD_CSI0_DAT5__KPP_ROW_5               = IOMUX_PAD(0x063C, 0x026C, 3, 0x08F4, 1, 0),
+    MX6Q_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD         = IOMUX_PAD(0x063C, 0x026C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT5__GPIO_5_23               = IOMUX_PAD(0x063C, 0x026C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT5__MMDC_MMDC_DEBUG_44      = IOMUX_PAD(0x063C, 0x026C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT5__CHEETAH_TRACE_2         = IOMUX_PAD(0x063C, 0x026C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT6__IPU1_CSI0_D_6           = IOMUX_PAD(0x0640, 0x0270, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT6__WEIM_WEIM_D_4           = IOMUX_PAD(0x0640, 0x0270, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT6__ECSPI1_MISO             = IOMUX_PAD(0x0640, 0x0270, 2, 0x07F8, 3, 0),
+    MX6Q_PAD_CSI0_DAT6__KPP_COL_6               = IOMUX_PAD(0x0640, 0x0270, 3, 0x08EC, 1, 0),
+    MX6Q_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS        = IOMUX_PAD(0x0640, 0x0270, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT6__GPIO_5_24               = IOMUX_PAD(0x0640, 0x0270, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT6__MMDC_MMDC_DEBUG_45      = IOMUX_PAD(0x0640, 0x0270, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT6__CHEETAH_TRACE_3         = IOMUX_PAD(0x0640, 0x0270, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT7__IPU1_CSI0_D_7           = IOMUX_PAD(0x0644, 0x0274, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT7__WEIM_WEIM_D_5           = IOMUX_PAD(0x0644, 0x0274, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT7__ECSPI1_SS0              = IOMUX_PAD(0x0644, 0x0274, 2, 0x0800, 3, 0),
+    MX6Q_PAD_CSI0_DAT7__KPP_ROW_6               = IOMUX_PAD(0x0644, 0x0274, 3, 0x08F8, 2, 0),
+    MX6Q_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD         = IOMUX_PAD(0x0644, 0x0274, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT7__GPIO_5_25               = IOMUX_PAD(0x0644, 0x0274, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT7__MMDC_MMDC_DEBUG_46      = IOMUX_PAD(0x0644, 0x0274, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT7__CHEETAH_TRACE_4         = IOMUX_PAD(0x0644, 0x0274, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT8__IPU1_CSI0_D_8           = IOMUX_PAD(0x0648, 0x0278, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT8__WEIM_WEIM_D_6           = IOMUX_PAD(0x0648, 0x0278, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT8__ECSPI2_SCLK             = IOMUX_PAD(0x0648, 0x0278, 2, 0x0810, 2, 0),
+    MX6Q_PAD_CSI0_DAT8__KPP_COL_7               = IOMUX_PAD(0x0648, 0x0278, 3, 0x08F0, 2, 0),
+    MX6Q_PAD_CSI0_DAT8__I2C1_SDA                = IOMUX_PAD(0x0648, 0x0278, 20, 0x089C, 1, 0),
+    MX6Q_PAD_CSI0_DAT8__GPIO_5_26               = IOMUX_PAD(0x0648, 0x0278, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT8__MMDC_MMDC_DEBUG_47      = IOMUX_PAD(0x0648, 0x0278, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT8__CHEETAH_TRACE_5         = IOMUX_PAD(0x0648, 0x0278, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT9__IPU1_CSI0_D_9           = IOMUX_PAD(0x064C, 0x027C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT9__WEIM_WEIM_D_7           = IOMUX_PAD(0x064C, 0x027C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT9__ECSPI2_MOSI             = IOMUX_PAD(0x064C, 0x027C, 2, 0x0818, 2, 0),
+    MX6Q_PAD_CSI0_DAT9__KPP_ROW_7               = IOMUX_PAD(0x064C, 0x027C, 3, 0x08FC, 2, 0),
+    MX6Q_PAD_CSI0_DAT9__I2C1_SCL                = IOMUX_PAD(0x064C, 0x027C, 20, 0x0898, 1, 0),
+    MX6Q_PAD_CSI0_DAT9__GPIO_5_27               = IOMUX_PAD(0x064C, 0x027C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT9__MMDC_MMDC_DEBUG_48      = IOMUX_PAD(0x064C, 0x027C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT9__CHEETAH_TRACE_6         = IOMUX_PAD(0x064C, 0x027C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT10__IPU1_CSI0_D_10         = IOMUX_PAD(0x0650, 0x0280, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT10__AUDMUX_AUD3_RXC        = IOMUX_PAD(0x0650, 0x0280, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT10__ECSPI2_MISO            = IOMUX_PAD(0x0650, 0x0280, 2, 0x0814, 2, 0),
+    MX6Q_PAD_CSI0_DAT10__UART1_TXD              = IOMUX_PAD(0x0650, 0x0280, 3, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT10__UART1_TXD_RXD          = IOMUX_PAD(0x0650, 0x0280, 3, 0x0920, 0, 0),
+    MX6Q_PAD_CSI0_DAT10__SDMA_DEBUG_PC_4        = IOMUX_PAD(0x0650, 0x0280, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT10__GPIO_5_28              = IOMUX_PAD(0x0650, 0x0280, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT10__MMDC_MMDC_DEBUG_33     = IOMUX_PAD(0x0650, 0x0280, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT10__CHEETAH_TRACE_7        = IOMUX_PAD(0x0650, 0x0280, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT11__IPU1_CSI0_D_11         = IOMUX_PAD(0x0654, 0x0284, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT11__AUDMUX_AUD3_RXFS       = IOMUX_PAD(0x0654, 0x0284, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT11__ECSPI2_SS0             = IOMUX_PAD(0x0654, 0x0284, 2, 0x081C, 2, 0),
+    MX6Q_PAD_CSI0_DAT11__UART1_RXD              = IOMUX_PAD(0x0654, 0x0284, 3, 0x0920, 1, 0),
+    MX6Q_PAD_CSI0_DAT11__SDMA_DEBUG_PC_5        = IOMUX_PAD(0x0654, 0x0284, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT11__GPIO_5_29              = IOMUX_PAD(0x0654, 0x0284, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT11__MMDC_MMDC_DEBUG_34     = IOMUX_PAD(0x0654, 0x0284, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT11__CHEETAH_TRACE_8        = IOMUX_PAD(0x0654, 0x0284, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12         = IOMUX_PAD(0x0658, 0x0288, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT12__WEIM_WEIM_D_8          = IOMUX_PAD(0x0658, 0x0288, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT12__PCIE_CTRL_MUX_16       = IOMUX_PAD(0x0658, 0x0288, 2, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT12__UART4_TXD              = IOMUX_PAD(0x0658, 0x0288, 3, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT12__UART4_TXD_RXD          = IOMUX_PAD(0x0658, 0x0288, 3, 0x0938, 2, 0),
+    MX6Q_PAD_CSI0_DAT12__SDMA_DEBUG_PC_6        = IOMUX_PAD(0x0658, 0x0288, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT12__GPIO_5_30              = IOMUX_PAD(0x0658, 0x0288, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT12__MMDC_MMDC_DEBUG_35     = IOMUX_PAD(0x0658, 0x0288, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT12__CHEETAH_TRACE_9        = IOMUX_PAD(0x0658, 0x0288, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13         = IOMUX_PAD(0x065C, 0x028C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT13__WEIM_WEIM_D_9          = IOMUX_PAD(0x065C, 0x028C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT13__PCIE_CTRL_MUX_17       = IOMUX_PAD(0x065C, 0x028C, 2, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT13__UART4_RXD              = IOMUX_PAD(0x065C, 0x028C, 3, 0x0938, 3, 0),
+    MX6Q_PAD_CSI0_DAT13__SDMA_DEBUG_PC_7        = IOMUX_PAD(0x065C, 0x028C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT13__GPIO_5_31              = IOMUX_PAD(0x065C, 0x028C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT13__MMDC_MMDC_DEBUG_36     = IOMUX_PAD(0x065C, 0x028C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT13__CHEETAH_TRACE_10       = IOMUX_PAD(0x065C, 0x028C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14         = IOMUX_PAD(0x0660, 0x0290, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT14__WEIM_WEIM_D_10         = IOMUX_PAD(0x0660, 0x0290, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT14__PCIE_CTRL_MUX_18       = IOMUX_PAD(0x0660, 0x0290, 2, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT14__UART5_TXD              = IOMUX_PAD(0x0660, 0x0290, 3, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT14__UART5_TXD_RXD          = IOMUX_PAD(0x0660, 0x0290, 3, 0x0940, 2, 0),
+    MX6Q_PAD_CSI0_DAT14__SDMA_DEBUG_PC_8        = IOMUX_PAD(0x0660, 0x0290, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT14__GPIO_6_0               = IOMUX_PAD(0x0660, 0x0290, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT14__MMDC_MMDC_DEBUG_37     = IOMUX_PAD(0x0660, 0x0290, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT14__CHEETAH_TRACE_11       = IOMUX_PAD(0x0660, 0x0290, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15         = IOMUX_PAD(0x0664, 0x0294, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT15__WEIM_WEIM_D_11         = IOMUX_PAD(0x0664, 0x0294, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT15__PCIE_CTRL_MUX_19       = IOMUX_PAD(0x0664, 0x0294, 2, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT15__UART5_RXD              = IOMUX_PAD(0x0664, 0x0294, 3, 0x0940, 3, 0),
+    MX6Q_PAD_CSI0_DAT15__SDMA_DEBUG_PC_9        = IOMUX_PAD(0x0664, 0x0294, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT15__GPIO_6_1               = IOMUX_PAD(0x0664, 0x0294, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT15__MMDC_MMDC_DEBUG_38     = IOMUX_PAD(0x0664, 0x0294, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT15__CHEETAH_TRACE_12       = IOMUX_PAD(0x0664, 0x0294, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16         = IOMUX_PAD(0x0668, 0x0298, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT16__WEIM_WEIM_D_12         = IOMUX_PAD(0x0668, 0x0298, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT16__PCIE_CTRL_MUX_20       = IOMUX_PAD(0x0668, 0x0298, 2, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT16__UART4_CTS              = IOMUX_PAD(0x0668, 0x0298, 3, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT16__UART4_RTS              = IOMUX_PAD(0x0668, 0x0298, 3, 0x0934, 0, 0),
+    MX6Q_PAD_CSI0_DAT16__SDMA_DEBUG_PC_10       = IOMUX_PAD(0x0668, 0x0298, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT16__GPIO_6_2               = IOMUX_PAD(0x0668, 0x0298, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT16__MMDC_MMDC_DEBUG_39     = IOMUX_PAD(0x0668, 0x0298, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT16__CHEETAH_TRACE_13       = IOMUX_PAD(0x0668, 0x0298, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17         = IOMUX_PAD(0x066C, 0x029C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT17__WEIM_WEIM_D_13         = IOMUX_PAD(0x066C, 0x029C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT17__PCIE_CTRL_MUX_21       = IOMUX_PAD(0x066C, 0x029C, 2, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT17__UART4_CTS              = IOMUX_PAD(0x066C, 0x029C, 3, 0x0934, 1, 0),
+    MX6Q_PAD_CSI0_DAT17__SDMA_DEBUG_PC_11       = IOMUX_PAD(0x066C, 0x029C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT17__GPIO_6_3               = IOMUX_PAD(0x066C, 0x029C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT17__MMDC_MMDC_DEBUG_40     = IOMUX_PAD(0x066C, 0x029C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT17__CHEETAH_TRACE_14       = IOMUX_PAD(0x066C, 0x029C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18         = IOMUX_PAD(0x0670, 0x02A0, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT18__WEIM_WEIM_D_14         = IOMUX_PAD(0x0670, 0x02A0, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT18__PCIE_CTRL_MUX_22       = IOMUX_PAD(0x0670, 0x02A0, 2, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT18__UART5_CTS              = IOMUX_PAD(0x0670, 0x02A0, 3, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT18__UART5_RTS              = IOMUX_PAD(0x0670, 0x02A0, 3, 0x093C, 2, 0),
+    MX6Q_PAD_CSI0_DAT18__SDMA_DEBUG_PC_12       = IOMUX_PAD(0x0670, 0x02A0, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT18__GPIO_6_4               = IOMUX_PAD(0x0670, 0x02A0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT18__MMDC_MMDC_DEBUG_41     = IOMUX_PAD(0x0670, 0x02A0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT18__CHEETAH_TRACE_15       = IOMUX_PAD(0x0670, 0x02A0, 7, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19         = IOMUX_PAD(0x0674, 0x02A4, 0, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT19__WEIM_WEIM_D_15         = IOMUX_PAD(0x0674, 0x02A4, 1, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT19__PCIE_CTRL_MUX_23       = IOMUX_PAD(0x0674, 0x02A4, 2, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT19__UART5_CTS              = IOMUX_PAD(0x0674, 0x02A4, 3, 0x093C, 3, 0),
+    MX6Q_PAD_CSI0_DAT19__SDMA_DEBUG_PC_13       = IOMUX_PAD(0x0674, 0x02A4, 4, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT19__GPIO_6_5               = IOMUX_PAD(0x0674, 0x02A4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT19__MMDC_MMDC_DEBUG_42     = IOMUX_PAD(0x0674, 0x02A4, 6, 0x0000, 0, 0),
+    MX6Q_PAD_CSI0_DAT19__ANATOP_TESTO_9         = IOMUX_PAD(0x0674, 0x02A4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_JTAG_TMS__SJC_TMS                  = IOMUX_PAD(0x0678, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_JTAG_MOD__SJC_MOD                  = IOMUX_PAD(0x067C, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_JTAG_TRSTB__SJC_TRSTB              = IOMUX_PAD(0x0680, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_JTAG_TDI__SJC_TDI                  = IOMUX_PAD(0x0684, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_JTAG_TCK__SJC_TCK                  = IOMUX_PAD(0x0688, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_JTAG_TDO__SJC_TDO                  = IOMUX_PAD(0x068C, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3         = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2         = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK         = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1         = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0         = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3         = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK         = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2         = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1         = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0         = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_TAMPER__SNVS_LP_WRAP_SNVS_TD1      = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_PMIC_ON_REQ__SNVS_LPWRAP_WKALM     = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_PMIC_STBY_REQ__CCM_PMIC_STBYRQ     = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_POR_B__SRC_POR_B                   = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_BOOT_MODE1__SRC_BOOT_MODE_1        = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_RESET_IN_B__SRC_RESET_B            = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_BOOT_MODE0__SRC_BOOT_MODE_0        = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_TEST_MODE__TCU_TEST_MODE           = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT7__USDHC3_DAT7              = IOMUX_PAD(0x0690, 0x02A8, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT7__UART1_TXD                = IOMUX_PAD(0x0690, 0x02A8, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT7__UART1_TXD_RXD            = IOMUX_PAD(0x0690, 0x02A8, 1, 0x0920, 2, 0),
+    MX6Q_PAD_SD3_DAT7__PCIE_CTRL_MUX_24         = IOMUX_PAD(0x0690, 0x02A8, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT7__USBOH3_UH3_DFD_OUT_0     = IOMUX_PAD(0x0690, 0x02A8, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT7__USBOH3_UH2_DFD_OUT_0     = IOMUX_PAD(0x0690, 0x02A8, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT7__GPIO_6_17                = IOMUX_PAD(0x0690, 0x02A8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT7__MIPI_CORE_DPHY_IN_12     = IOMUX_PAD(0x0690, 0x02A8, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT7__USBPHY2_CLK20DIV         = IOMUX_PAD(0x0690, 0x02A8, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT6__USDHC3_DAT6              = IOMUX_PAD(0x0694, 0x02AC, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT6__UART1_RXD                = IOMUX_PAD(0x0694, 0x02AC, 1, 0x0920, 3, 0),
+    MX6Q_PAD_SD3_DAT6__PCIE_CTRL_MUX_25         = IOMUX_PAD(0x0694, 0x02AC, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT6__USBOH3_UH3_DFD_OUT_1     = IOMUX_PAD(0x0694, 0x02AC, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT6__USBOH3_UH2_DFD_OUT_1     = IOMUX_PAD(0x0694, 0x02AC, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT6__GPIO_6_18                = IOMUX_PAD(0x0694, 0x02AC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT6__MIPI_CORE_DPHY_IN_13     = IOMUX_PAD(0x0694, 0x02AC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT6__ANATOP_TESTO_10          = IOMUX_PAD(0x0694, 0x02AC, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT5__USDHC3_DAT5              = IOMUX_PAD(0x0698, 0x02B0, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT5__UART2_TXD                = IOMUX_PAD(0x0698, 0x02B0, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT5__UART2_TXD_RXD            = IOMUX_PAD(0x0698, 0x02B0, 1, 0x0928, 4, 0),
+    MX6Q_PAD_SD3_DAT5__PCIE_CTRL_MUX_26         = IOMUX_PAD(0x0698, 0x02B0, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT5__USBOH3_UH3_DFD_OUT_2     = IOMUX_PAD(0x0698, 0x02B0, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT5__USBOH3_UH2_DFD_OUT_2     = IOMUX_PAD(0x0698, 0x02B0, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT5__GPIO_7_0                 = IOMUX_PAD(0x0698, 0x02B0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT5__MIPI_CORE_DPHY_IN_14     = IOMUX_PAD(0x0698, 0x02B0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT5__ANATOP_TESTO_11          = IOMUX_PAD(0x0698, 0x02B0, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT4__USDHC3_DAT4              = IOMUX_PAD(0x069C, 0x02B4, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT4__UART2_RXD                = IOMUX_PAD(0x069C, 0x02B4, 1, 0x0928, 5, 0),
+    MX6Q_PAD_SD3_DAT4__PCIE_CTRL_MUX_27         = IOMUX_PAD(0x069C, 0x02B4, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT4__USBOH3_UH3_DFD_OUT_3     = IOMUX_PAD(0x069C, 0x02B4, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT4__USBOH3_UH2_DFD_OUT_3     = IOMUX_PAD(0x069C, 0x02B4, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT4__GPIO_7_1                 = IOMUX_PAD(0x069C, 0x02B4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT4__MIPI_CORE_DPHY_IN_15     = IOMUX_PAD(0x069C, 0x02B4, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT4__ANATOP_TESTO_12          = IOMUX_PAD(0x069C, 0x02B4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_CMD__USDHC3_CMD                = IOMUX_PAD(0x06A0, 0x02B8, 16, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_CMD__UART2_CTS                 = IOMUX_PAD(0x06A0, 0x02B8, 1, 0x0924, 2, 0),
+    MX6Q_PAD_SD3_CMD__CAN1_TXCAN                = IOMUX_PAD(0x06A0, 0x02B8, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_CMD__USBOH3_UH3_DFD_OUT_4      = IOMUX_PAD(0x06A0, 0x02B8, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_CMD__USBOH3_UH2_DFD_OUT_4      = IOMUX_PAD(0x06A0, 0x02B8, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_CMD__GPIO_7_2                  = IOMUX_PAD(0x06A0, 0x02B8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_CMD__MIPI_CORE_DPHY_IN_16      = IOMUX_PAD(0x06A0, 0x02B8, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_CMD__ANATOP_TESTO_13           = IOMUX_PAD(0x06A0, 0x02B8, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_CLK__USDHC3_CLK                = IOMUX_PAD(0x06A4, 0x02BC, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_CLK__UART2_CTS                 = IOMUX_PAD(0x06A4, 0x02BC, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_CLK__UART2_RTS                 = IOMUX_PAD(0x06A4, 0x02BC, 1, 0x0924, 3, 0),
+    MX6Q_PAD_SD3_CLK__CAN1_RXCAN                = IOMUX_PAD(0x06A4, 0x02BC, 2, 0x07E4, 2, 0),
+    MX6Q_PAD_SD3_CLK__USBOH3_UH3_DFD_OUT_5      = IOMUX_PAD(0x06A4, 0x02BC, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_CLK__USBOH3_UH2_DFD_OUT_5      = IOMUX_PAD(0x06A4, 0x02BC, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_CLK__GPIO_7_3                  = IOMUX_PAD(0x06A4, 0x02BC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_CLK__MIPI_CORE_DPHY_IN_17      = IOMUX_PAD(0x06A4, 0x02BC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_CLK__ANATOP_TESTO_14           = IOMUX_PAD(0x06A4, 0x02BC, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT0__USDHC3_DAT0              = IOMUX_PAD(0x06A8, 0x02C0, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT0__UART1_CTS                = IOMUX_PAD(0x06A8, 0x02C0, 1, 0x091C, 2, 0),
+    MX6Q_PAD_SD3_DAT0__CAN2_TXCAN               = IOMUX_PAD(0x06A8, 0x02C0, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT0__USBOH3_UH3_DFD_OUT_6     = IOMUX_PAD(0x06A8, 0x02C0, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT0__USBOH3_UH2_DFD_OUT_6     = IOMUX_PAD(0x06A8, 0x02C0, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT0__GPIO_7_4                 = IOMUX_PAD(0x06A8, 0x02C0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT0__MIPI_CORE_DPHY_IN_18     = IOMUX_PAD(0x06A8, 0x02C0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT0__ANATOP_TESTO_15          = IOMUX_PAD(0x06A8, 0x02C0, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT1__USDHC3_DAT1              = IOMUX_PAD(0x06AC, 0x02C4, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT1__UART1_CTS                = IOMUX_PAD(0x06AC, 0x02C4, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT1__UART1_RTS                = IOMUX_PAD(0x06AC, 0x02C4, 1, 0x091C, 3, 0),
+    MX6Q_PAD_SD3_DAT1__CAN2_RXCAN               = IOMUX_PAD(0x06AC, 0x02C4, 2, 0x07E8, 1, 0),
+    MX6Q_PAD_SD3_DAT1__USBOH3_UH3_DFD_OUT_7     = IOMUX_PAD(0x06AC, 0x02C4, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT1__USBOH3_UH2_DFD_OUT_7     = IOMUX_PAD(0x06AC, 0x02C4, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT1__GPIO_7_5                 = IOMUX_PAD(0x06AC, 0x02C4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT1__MIPI_CORE_DPHY_IN_19     = IOMUX_PAD(0x06AC, 0x02C4, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT1__ANATOP_TESTI_0           = IOMUX_PAD(0x06AC, 0x02C4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT2__USDHC3_DAT2              = IOMUX_PAD(0x06B0, 0x02C8, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT2__PCIE_CTRL_MUX_28         = IOMUX_PAD(0x06B0, 0x02C8, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT2__USBOH3_UH3_DFD_OUT_8     = IOMUX_PAD(0x06B0, 0x02C8, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT2__USBOH3_UH2_DFD_OUT_8     = IOMUX_PAD(0x06B0, 0x02C8, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT2__GPIO_7_6                 = IOMUX_PAD(0x06B0, 0x02C8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT2__MIPI_CORE_DPHY_IN_20     = IOMUX_PAD(0x06B0, 0x02C8, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT2__ANATOP_TESTI_1           = IOMUX_PAD(0x06B0, 0x02C8, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT3__USDHC3_DAT3              = IOMUX_PAD(0x06B4, 0x02CC, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT3__UART3_CTS                = IOMUX_PAD(0x06B4, 0x02CC, 1, 0x092C, 4, 0),
+    MX6Q_PAD_SD3_DAT3__PCIE_CTRL_MUX_29         = IOMUX_PAD(0x06B4, 0x02CC, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT3__USBOH3_UH3_DFD_OUT_9     = IOMUX_PAD(0x06B4, 0x02CC, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT3__USBOH3_UH2_DFD_OUT_9     = IOMUX_PAD(0x06B4, 0x02CC, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT3__GPIO_7_7                 = IOMUX_PAD(0x06B4, 0x02CC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT3__MIPI_CORE_DPHY_IN_21     = IOMUX_PAD(0x06B4, 0x02CC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_DAT3__ANATOP_TESTI_2           = IOMUX_PAD(0x06B4, 0x02CC, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_RST__USDHC3_RST                = IOMUX_PAD(0x06B8, 0x02D0, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_RST__UART3_CTS                 = IOMUX_PAD(0x06B8, 0x02D0, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_RST__UART3_RTS                 = IOMUX_PAD(0x06B8, 0x02D0, 1, 0x092C, 5, 0),
+    MX6Q_PAD_SD3_RST__PCIE_CTRL_MUX_30          = IOMUX_PAD(0x06B8, 0x02D0, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_RST__USBOH3_UH3_DFD_OUT_10     = IOMUX_PAD(0x06B8, 0x02D0, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_RST__USBOH3_UH2_DFD_OUT_10     = IOMUX_PAD(0x06B8, 0x02D0, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_RST__GPIO_7_8                  = IOMUX_PAD(0x06B8, 0x02D0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_RST__MIPI_CORE_DPHY_IN_22      = IOMUX_PAD(0x06B8, 0x02D0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD3_RST__ANATOP_ANATOP_TESTI_3     = IOMUX_PAD(0x06B8, 0x02D0, 7, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CLE__RAWNAND_CLE             = IOMUX_PAD(0x06BC, 0x02D4, 0, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CLE__IPU2_SISG_4             = IOMUX_PAD(0x06BC, 0x02D4, 1, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CLE__PCIE_CTRL_MUX_31        = IOMUX_PAD(0x06BC, 0x02D4, 2, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CLE__USBOH3_UH3_DFD_OT11     = IOMUX_PAD(0x06BC, 0x02D4, 3, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CLE__USBOH3_UH2_DFD_OT11     = IOMUX_PAD(0x06BC, 0x02D4, 4, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CLE__GPIO_6_7                = IOMUX_PAD(0x06BC, 0x02D4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CLE__MIPI_CORE_DPHY_IN23     = IOMUX_PAD(0x06BC, 0x02D4, 6, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CLE__TPSMP_HTRANS_0          = IOMUX_PAD(0x06BC, 0x02D4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_ALE__RAWNAND_ALE             = IOMUX_PAD(0x06C0, 0x02D8, 0, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_ALE__USDHC4_RST              = IOMUX_PAD(0x06C0, 0x02D8, 1, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_ALE__PCIE_CTRL_MUX_0         = IOMUX_PAD(0x06C0, 0x02D8, 2, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_ALE__USBOH3_UH3_DFD_OT12     = IOMUX_PAD(0x06C0, 0x02D8, 3, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_ALE__USBOH3_UH2_DFD_OT12     = IOMUX_PAD(0x06C0, 0x02D8, 4, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_ALE__GPIO_6_8                = IOMUX_PAD(0x06C0, 0x02D8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_ALE__MIPI_CR_DPHY_IN_24      = IOMUX_PAD(0x06C0, 0x02D8, 6, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_ALE__TPSMP_HTRANS_1          = IOMUX_PAD(0x06C0, 0x02D8, 7, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN         = IOMUX_PAD(0x06C4, 0x02DC, 0, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_WP_B__IPU2_SISG_5            = IOMUX_PAD(0x06C4, 0x02DC, 1, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_WP_B__PCIE_CTRL__MUX_1       = IOMUX_PAD(0x06C4, 0x02DC, 2, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_WP_B__USBOH3_UH3_DFDOT13     = IOMUX_PAD(0x06C4, 0x02DC, 3, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_WP_B__USBOH3_UH2_DFDOT13     = IOMUX_PAD(0x06C4, 0x02DC, 4, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_WP_B__GPIO_6_9               = IOMUX_PAD(0x06C4, 0x02DC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_WP_B__MIPI_CR_DPHY_OUT32     = IOMUX_PAD(0x06C4, 0x02DC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_WP_B__PL301_PER1_HSIZE_0     = IOMUX_PAD(0x06C4, 0x02DC, 7, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_RB0__RAWNAND_READY0          = IOMUX_PAD(0x06C8, 0x02E0, 0, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_RB0__IPU2_DI0_PIN1           = IOMUX_PAD(0x06C8, 0x02E0, 1, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_RB0__PCIE_CTRL_MUX_2         = IOMUX_PAD(0x06C8, 0x02E0, 2, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_RB0__USBOH3_UH3_DFD_OT14     = IOMUX_PAD(0x06C8, 0x02E0, 3, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_RB0__USBOH3_UH2_DFD_OT14     = IOMUX_PAD(0x06C8, 0x02E0, 4, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_RB0__GPIO_6_10               = IOMUX_PAD(0x06C8, 0x02E0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_RB0__MIPI_CR_DPHY_OUT_33     = IOMUX_PAD(0x06C8, 0x02E0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_RB0__PL301_PER1_HSIZE_1      = IOMUX_PAD(0x06C8, 0x02E0, 7, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS0__RAWNAND_CE0N            = IOMUX_PAD(0x06CC, 0x02E4, 0, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS0__USBOH3_UH3_DFD_OT15     = IOMUX_PAD(0x06CC, 0x02E4, 3, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS0__USBOH3_UH2_DFD_OT15     = IOMUX_PAD(0x06CC, 0x02E4, 4, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS0__GPIO_6_11               = IOMUX_PAD(0x06CC, 0x02E4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS0__PL301_PER1_HSIZE_2      = IOMUX_PAD(0x06CC, 0x02E4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS1__RAWNAND_CE1N            = IOMUX_PAD(0x06D0, 0x02E8, 0, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS1__USDHC4_VSELECT          = IOMUX_PAD(0x06D0, 0x02E8, 1, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS1__USDHC3_VSELECT          = IOMUX_PAD(0x06D0, 0x02E8, 2, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS1__PCIE_CTRL_MUX_3         = IOMUX_PAD(0x06D0, 0x02E8, 4, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS1__GPIO_6_14               = IOMUX_PAD(0x06D0, 0x02E8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS1__PL301_PER1_HRDYOUT      = IOMUX_PAD(0x06D0, 0x02E8, 7, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS2__RAWNAND_CE2N            = IOMUX_PAD(0x06D4, 0x02EC, 0, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS2__IPU1_SISG_0             = IOMUX_PAD(0x06D4, 0x02EC, 1, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS2__ESAI1_TX0               = IOMUX_PAD(0x06D4, 0x02EC, 2, 0x0874, 1, 0),
+    MX6Q_PAD_NANDF_CS2__WEIM_WEIM_CRE           = IOMUX_PAD(0x06D4, 0x02EC, 3, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS2__CCM_CLKO2               = IOMUX_PAD(0x06D4, 0x02EC, 4, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS2__GPIO_6_15               = IOMUX_PAD(0x06D4, 0x02EC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS2__IPU2_SISG_0             = IOMUX_PAD(0x06D4, 0x02EC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS3__RAWNAND_CE3N            = IOMUX_PAD(0x06D8, 0x02F0, 0, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS3__IPU1_SISG_1             = IOMUX_PAD(0x06D8, 0x02F0, 1, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS3__ESAI1_TX1               = IOMUX_PAD(0x06D8, 0x02F0, 2, 0x0878, 1, 0),
+    MX6Q_PAD_NANDF_CS3__WEIM_WEIM_A_26          = IOMUX_PAD(0x06D8, 0x02F0, 3, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS3__PCIE_CTRL_MUX_4         = IOMUX_PAD(0x06D8, 0x02F0, 4, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS3__GPIO_6_16               = IOMUX_PAD(0x06D8, 0x02F0, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS3__IPU2_SISG_1             = IOMUX_PAD(0x06D8, 0x02F0, 6, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_CS3__TPSMP_CLK               = IOMUX_PAD(0x06D8, 0x02F0, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_CMD__USDHC4_CMD                = IOMUX_PAD(0x06DC, 0x02F4, 16, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_CMD__RAWNAND_RDN               = IOMUX_PAD(0x06DC, 0x02F4, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_CMD__UART3_TXD                 = IOMUX_PAD(0x06DC, 0x02F4, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_CMD__UART3_TXD_RXD             = IOMUX_PAD(0x06DC, 0x02F4, 2, 0x0930, 2, 0),
+    MX6Q_PAD_SD4_CMD__PCIE_CTRL_MUX_5           = IOMUX_PAD(0x06DC, 0x02F4, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_CMD__GPIO_7_9                  = IOMUX_PAD(0x06DC, 0x02F4, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_CMD__TPSMP_HDATA_DIR           = IOMUX_PAD(0x06DC, 0x02F4, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_CLK__USDHC4_CLK                = IOMUX_PAD(0x06E0, 0x02F8, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_CLK__RAWNAND_WRN               = IOMUX_PAD(0x06E0, 0x02F8, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_CLK__UART3_RXD                 = IOMUX_PAD(0x06E0, 0x02F8, 2, 0x0930, 3, 0),
+    MX6Q_PAD_SD4_CLK__PCIE_CTRL_MUX_6           = IOMUX_PAD(0x06E0, 0x02F8, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_CLK__GPIO_7_10                 = IOMUX_PAD(0x06E0, 0x02F8, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D0__RAWNAND_D0               = IOMUX_PAD(0x06E4, 0x02FC, 0, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D0__USDHC1_DAT4              = IOMUX_PAD(0x06E4, 0x02FC, 1, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D0__GPU3D_GPU_DBG_OUT_0      = IOMUX_PAD(0x06E4, 0x02FC, 2, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D0__USBOH3_UH2_DFD_OUT16     = IOMUX_PAD(0x06E4, 0x02FC, 3, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D0__USBOH3_UH3_DFD_OUT16     = IOMUX_PAD(0x06E4, 0x02FC, 4, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D0__GPIO_2_0                 = IOMUX_PAD(0x06E4, 0x02FC, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D0__IPU1_IPU_DIAG_BUS_0      = IOMUX_PAD(0x06E4, 0x02FC, 6, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D0__IPU2_IPU_DIAG_BUS_0      = IOMUX_PAD(0x06E4, 0x02FC, 7, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D1__RAWNAND_D1               = IOMUX_PAD(0x06E8, 0x0300, 0, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D1__USDHC1_DAT5              = IOMUX_PAD(0x06E8, 0x0300, 1, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D1__GPU3D_GPU_DEBUG_OUT1     = IOMUX_PAD(0x06E8, 0x0300, 2, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D1__USBOH3_UH2_DFD_OUT17     = IOMUX_PAD(0x06E8, 0x0300, 3, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D1__USBOH3_UH3_DFD_OUT17     = IOMUX_PAD(0x06E8, 0x0300, 4, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D1__GPIO_2_1                 = IOMUX_PAD(0x06E8, 0x0300, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D1__IPU1_IPU_DIAG_BUS_1      = IOMUX_PAD(0x06E8, 0x0300, 6, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D1__IPU2_IPU_DIAG_BUS_1      = IOMUX_PAD(0x06E8, 0x0300, 7, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D2__RAWNAND_D2               = IOMUX_PAD(0x06EC, 0x0304, 0, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D2__USDHC1_DAT6              = IOMUX_PAD(0x06EC, 0x0304, 1, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D2__GPU3D_GPU_DBG_OUT_2      = IOMUX_PAD(0x06EC, 0x0304, 2, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D2__USBOH3_UH2_DFD_OUT18     = IOMUX_PAD(0x06EC, 0x0304, 3, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D2__USBOH3_UH3_DFD_OUT18     = IOMUX_PAD(0x06EC, 0x0304, 4, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D2__GPIO_2_2                 = IOMUX_PAD(0x06EC, 0x0304, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D2__IPU1_IPU_DIAG_BUS_2      = IOMUX_PAD(0x06EC, 0x0304, 6, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D2__IPU2_IPU_DIAG_BUS_2      = IOMUX_PAD(0x06EC, 0x0304, 7, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D3__RAWNAND_D3               = IOMUX_PAD(0x06F0, 0x0308, 0, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D3__USDHC1_DAT7              = IOMUX_PAD(0x06F0, 0x0308, 1, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D3__GPU3D_GPU_DBG_OUT_3      = IOMUX_PAD(0x06F0, 0x0308, 2, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D3__USBOH3_UH2_DFD_OUT19     = IOMUX_PAD(0x06F0, 0x0308, 3, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D3__USBOH3_UH3_DFD_OUT19     = IOMUX_PAD(0x06F0, 0x0308, 4, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D3__GPIO_2_3                 = IOMUX_PAD(0x06F0, 0x0308, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D3__IPU1_IPU_DIAG_BUS_3      = IOMUX_PAD(0x06F0, 0x0308, 6, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D3__IPU2_IPU_DIAG_BUS_3      = IOMUX_PAD(0x06F0, 0x0308, 7, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D4__RAWNAND_D4               = IOMUX_PAD(0x06F4, 0x030C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D4__USDHC2_DAT4              = IOMUX_PAD(0x06F4, 0x030C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D4__GPU3D_GPU_DBG_OUT_4      = IOMUX_PAD(0x06F4, 0x030C, 2, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D4__USBOH3_UH2_DFD_OUT20     = IOMUX_PAD(0x06F4, 0x030C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D4__USBOH3_UH3_DFD_OUT20     = IOMUX_PAD(0x06F4, 0x030C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D4__GPIO_2_4                 = IOMUX_PAD(0x06F4, 0x030C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D4__IPU1_IPU_DIAG_BUS_4      = IOMUX_PAD(0x06F4, 0x030C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D4__IPU2_IPU_DIAG_BUS_4      = IOMUX_PAD(0x06F4, 0x030C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D5__RAWNAND_D5               = IOMUX_PAD(0x06F8, 0x0310, 0, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D5__USDHC2_DAT5              = IOMUX_PAD(0x06F8, 0x0310, 1, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D5__GPU3D_GPU_DBG_OUT_5      = IOMUX_PAD(0x06F8, 0x0310, 2, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D5__USBOH3_UH2_DFD_OUT21     = IOMUX_PAD(0x06F8, 0x0310, 3, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D5__USBOH3_UH3_DFD_OUT21     = IOMUX_PAD(0x06F8, 0x0310, 4, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D5__GPIO_2_5                 = IOMUX_PAD(0x06F8, 0x0310, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D5__IPU1_IPU_DIAG_BUS_5      = IOMUX_PAD(0x06F8, 0x0310, 6, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D5__IPU2_IPU_DIAG_BUS_5      = IOMUX_PAD(0x06F8, 0x0310, 7, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D6__RAWNAND_D6               = IOMUX_PAD(0x06FC, 0x0314, 0, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D6__USDHC2_DAT6              = IOMUX_PAD(0x06FC, 0x0314, 1, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D6__GPU3D_GPU_DBG_OUT_6      = IOMUX_PAD(0x06FC, 0x0314, 2, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D6__USBOH3_UH2_DFD_OUT22     = IOMUX_PAD(0x06FC, 0x0314, 3, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D6__USBOH3_UH3_DFD_OUT22     = IOMUX_PAD(0x06FC, 0x0314, 4, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D6__GPIO_2_6                 = IOMUX_PAD(0x06FC, 0x0314, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D6__IPU1_IPU_DIAG_BUS_6      = IOMUX_PAD(0x06FC, 0x0314, 6, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D6__IPU2_IPU_DIAG_BUS_6      = IOMUX_PAD(0x06FC, 0x0314, 7, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D7__RAWNAND_D7               = IOMUX_PAD(0x0700, 0x0318, 0, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D7__USDHC2_DAT7              = IOMUX_PAD(0x0700, 0x0318, 1, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D7__GPU3D_GPU_DBG_OUT_7      = IOMUX_PAD(0x0700, 0x0318, 2, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D7__USBOH3_UH2_DFD_OUT23     = IOMUX_PAD(0x0700, 0x0318, 3, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D7__USBOH3_UH3_DFD_OUT23     = IOMUX_PAD(0x0700, 0x0318, 4, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D7__GPIO_2_7                 = IOMUX_PAD(0x0700, 0x0318, 5, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D7__IPU1_IPU_DIAG_BUS_7      = IOMUX_PAD(0x0700, 0x0318, 6, 0x0000, 0, 0),
+    MX6Q_PAD_NANDF_D7__IPU2_IPU_DIAG_BUS_7      = IOMUX_PAD(0x0700, 0x0318, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT0__RAWNAND_D8               = IOMUX_PAD(0x0704, 0x031C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT0__USDHC4_DAT0              = IOMUX_PAD(0x0704, 0x031C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT0__RAWNAND_DQS              = IOMUX_PAD(0x0704, 0x031C, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT0__USBOH3_UH2_DFD_OUT24     = IOMUX_PAD(0x0704, 0x031C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT0__USBOH3_UH3_DFD_OUT24     = IOMUX_PAD(0x0704, 0x031C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT0__GPIO_2_8                 = IOMUX_PAD(0x0704, 0x031C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT0__IPU1_IPU_DIAG_BUS_8      = IOMUX_PAD(0x0704, 0x031C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT0__IPU2_IPU_DIAG_BUS_8      = IOMUX_PAD(0x0704, 0x031C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT1__RAWNAND_D9               = IOMUX_PAD(0x0708, 0x0320, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT1__USDHC4_DAT1              = IOMUX_PAD(0x0708, 0x0320, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT1__PWM3_PWMO                = IOMUX_PAD(0x0708, 0x0320, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT1__USBOH3_UH2_DFD_OUT25     = IOMUX_PAD(0x0708, 0x0320, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT1__USBOH3_UH3_DFD_OUT25     = IOMUX_PAD(0x0708, 0x0320, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT1__GPIO_2_9                 = IOMUX_PAD(0x0708, 0x0320, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT1__IPU1_IPU_DIAG_BUS_9      = IOMUX_PAD(0x0708, 0x0320, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT1__IPU2_IPU_DIAG_BUS_9      = IOMUX_PAD(0x0708, 0x0320, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT2__RAWNAND_D10              = IOMUX_PAD(0x070C, 0x0324, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT2__USDHC4_DAT2              = IOMUX_PAD(0x070C, 0x0324, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT2__PWM4_PWMO                = IOMUX_PAD(0x070C, 0x0324, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT2__USBOH3_UH2_DFD_OUT26     = IOMUX_PAD(0x070C, 0x0324, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT2__USBOH3_UH3_DFD_OUT26     = IOMUX_PAD(0x070C, 0x0324, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT2__GPIO_2_10                = IOMUX_PAD(0x070C, 0x0324, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT2__IPU1_IPU_DIAG_BUS_10     = IOMUX_PAD(0x070C, 0x0324, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT2__IPU2_IPU_DIAG_BUS_10     = IOMUX_PAD(0x070C, 0x0324, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT3__RAWNAND_D11              = IOMUX_PAD(0x0710, 0x0328, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT3__USDHC4_DAT3              = IOMUX_PAD(0x0710, 0x0328, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT3__USBOH3_UH2_DFD_OUT27     = IOMUX_PAD(0x0710, 0x0328, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT3__USBOH3_UH3_DFD_OUT27     = IOMUX_PAD(0x0710, 0x0328, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT3__GPIO_2_11                = IOMUX_PAD(0x0710, 0x0328, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT3__IPU1_IPU_DIAG_BUS_11     = IOMUX_PAD(0x0710, 0x0328, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT3__IPU2_IPU_DIAG_BUS_11     = IOMUX_PAD(0x0710, 0x0328, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT4__RAWNAND_D12              = IOMUX_PAD(0x0714, 0x032C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT4__USDHC4_DAT4              = IOMUX_PAD(0x0714, 0x032C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT4__UART2_RXD                = IOMUX_PAD(0x0714, 0x032C, 2, 0x0928, 6, 0),
+    MX6Q_PAD_SD4_DAT4__USBOH3_UH2_DFD_OUT28     = IOMUX_PAD(0x0714, 0x032C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT4__USBOH3_UH3_DFD_OUT28     = IOMUX_PAD(0x0714, 0x032C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT4__GPIO_2_12                = IOMUX_PAD(0x0714, 0x032C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT4__IPU1_IPU_DIAG_BUS_12     = IOMUX_PAD(0x0714, 0x032C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT4__IPU2_IPU_DIAG_BUS_12     = IOMUX_PAD(0x0714, 0x032C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT5__RAWNAND_D13              = IOMUX_PAD(0x0718, 0x0330, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT5__USDHC4_DAT5              = IOMUX_PAD(0x0718, 0x0330, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT5__UART2_CTS                = IOMUX_PAD(0x0718, 0x0330, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT5__UART2_RTS                = IOMUX_PAD(0x0718, 0x0330, 2, 0x0924, 4, 0),
+    MX6Q_PAD_SD4_DAT5__USBOH3_UH2_DFD_OUT29     = IOMUX_PAD(0x0718, 0x0330, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT5__USBOH3_UH3_DFD_OUT29     = IOMUX_PAD(0x0718, 0x0330, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT5__GPIO_2_13                = IOMUX_PAD(0x0718, 0x0330, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT5__IPU1_IPU_DIAG_BUS_13     = IOMUX_PAD(0x0718, 0x0330, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT5__IPU2_IPU_DIAG_BUS_13     = IOMUX_PAD(0x0718, 0x0330, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT6__RAWNAND_D14              = IOMUX_PAD(0x071C, 0x0334, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT6__USDHC4_DAT6              = IOMUX_PAD(0x071C, 0x0334, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT6__UART2_CTS                = IOMUX_PAD(0x071C, 0x0334, 2, 0x0924, 5, 0),
+    MX6Q_PAD_SD4_DAT6__USBOH3_UH2_DFD_OUT30     = IOMUX_PAD(0x071C, 0x0334, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT6__USBOH3_UH3_DFD_OUT30     = IOMUX_PAD(0x071C, 0x0334, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT6__GPIO_2_14                = IOMUX_PAD(0x071C, 0x0334, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT6__IPU1_IPU_DIAG_BUS_14     = IOMUX_PAD(0x071C, 0x0334, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT6__IPU2_IPU_DIAG_BUS_14     = IOMUX_PAD(0x071C, 0x0334, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT7__RAWNAND_D15              = IOMUX_PAD(0x0720, 0x0338, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT7__USDHC4_DAT7              = IOMUX_PAD(0x0720, 0x0338, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT7__UART2_TXD                = IOMUX_PAD(0x0720, 0x0338, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT7__UART2_TXD_RXD            = IOMUX_PAD(0x0720, 0x0338, 2, 0x0928, 7, 0),
+    MX6Q_PAD_SD4_DAT7__USBOH3_UH2_DFD_OUT31     = IOMUX_PAD(0x0720, 0x0338, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT7__USBOH3_UH3_DFD_OUT31     = IOMUX_PAD(0x0720, 0x0338, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT7__GPIO_2_15                = IOMUX_PAD(0x0720, 0x0338, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT7__IPU1_IPU_DIAG_BUS_15     = IOMUX_PAD(0x0720, 0x0338, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD4_DAT7__IPU2_IPU_DIAG_BUS_15     = IOMUX_PAD(0x0720, 0x0338, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT1__USDHC1_DAT1              = IOMUX_PAD(0x0724, 0x033C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT1__ECSPI5_SS0               = IOMUX_PAD(0x0724, 0x033C, 1, 0x0834, 1, 0),
+    MX6Q_PAD_SD1_DAT1__PWM3_PWMO                = IOMUX_PAD(0x0724, 0x033C, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT1__GPT_CAPIN2               = IOMUX_PAD(0x0724, 0x033C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT1__PCIE_CTRL_MUX_7          = IOMUX_PAD(0x0724, 0x033C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT1__GPIO_1_17                = IOMUX_PAD(0x0724, 0x033C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT1__HDMI_TX_OPHYDTB_0        = IOMUX_PAD(0x0724, 0x033C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT1__ANATOP_TESTO_8           = IOMUX_PAD(0x0724, 0x033C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT0__USDHC1_DAT0              = IOMUX_PAD(0x0728, 0x0340, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT0__ECSPI5_MISO              = IOMUX_PAD(0x0728, 0x0340, 1, 0x082C, 1, 0),
+    MX6Q_PAD_SD1_DAT0__CAAM_WRAP_RNG_OSCOBS     = IOMUX_PAD(0x0728, 0x0340, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT0__GPT_CAPIN1               = IOMUX_PAD(0x0728, 0x0340, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT0__PCIE_CTRL_MUX_8          = IOMUX_PAD(0x0728, 0x0340, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT0__GPIO_1_16                = IOMUX_PAD(0x0728, 0x0340, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT0__HDMI_TX_OPHYDTB_1        = IOMUX_PAD(0x0728, 0x0340, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT0__ANATOP_TESTO_7           = IOMUX_PAD(0x0728, 0x0340, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT3__USDHC1_DAT3              = IOMUX_PAD(0x072C, 0x0344, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT3__ECSPI5_SS2               = IOMUX_PAD(0x072C, 0x0344, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT3__GPT_CMPOUT3              = IOMUX_PAD(0x072C, 0x0344, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT3__PWM1_PWMO                = IOMUX_PAD(0x072C, 0x0344, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT3__WDOG2_WDOG_B             = IOMUX_PAD(0x072C, 0x0344, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT3__GPIO_1_21                = IOMUX_PAD(0x072C, 0x0344, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT3__WDOG2_WDOG_RST_B_DEB     = IOMUX_PAD(0x072C, 0x0344, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT3__ANATOP_TESTO_6           = IOMUX_PAD(0x072C, 0x0344, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_CMD__USDHC1_CMD                = IOMUX_PAD(0x0730, 0x0348, 16, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_CMD__ECSPI5_MOSI               = IOMUX_PAD(0x0730, 0x0348, 1, 0x0830, 0, 0),
+    MX6Q_PAD_SD1_CMD__PWM4_PWMO                 = IOMUX_PAD(0x0730, 0x0348, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_CMD__GPT_CMPOUT1               = IOMUX_PAD(0x0730, 0x0348, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_CMD__GPIO_1_18                 = IOMUX_PAD(0x0730, 0x0348, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_CMD__ANATOP_TESTO_5            = IOMUX_PAD(0x0730, 0x0348, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT2__USDHC1_DAT2              = IOMUX_PAD(0x0734, 0x034C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT2__ECSPI5_SS1               = IOMUX_PAD(0x0734, 0x034C, 1, 0x0838, 1, 0),
+    MX6Q_PAD_SD1_DAT2__GPT_CMPOUT2              = IOMUX_PAD(0x0734, 0x034C, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT2__PWM2_PWMO                = IOMUX_PAD(0x0734, 0x034C, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT2__WDOG1_WDOG_B             = IOMUX_PAD(0x0734, 0x034C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT2__GPIO_1_19                = IOMUX_PAD(0x0734, 0x034C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT2__WDOG1_WDOG_RST_B_DEB     = IOMUX_PAD(0x0734, 0x034C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_DAT2__ANATOP_TESTO_4           = IOMUX_PAD(0x0734, 0x034C, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_CLK__USDHC1_CLK                = IOMUX_PAD(0x0738, 0x0350, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_CLK__ECSPI5_SCLK               = IOMUX_PAD(0x0738, 0x0350, 1, 0x0828, 0, 0),
+    MX6Q_PAD_SD1_CLK__OSC32K_32K_OUT            = IOMUX_PAD(0x0738, 0x0350, 2, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_CLK__GPT_CLKIN                 = IOMUX_PAD(0x0738, 0x0350, 3, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_CLK__GPIO_1_20                 = IOMUX_PAD(0x0738, 0x0350, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_CLK__PHY_DTB_0                 = IOMUX_PAD(0x0738, 0x0350, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD1_CLK__SATA_PHY_DTB_0            = IOMUX_PAD(0x0738, 0x0350, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_CLK__USDHC2_CLK                = IOMUX_PAD(0x073C, 0x0354, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_CLK__ECSPI5_SCLK               = IOMUX_PAD(0x073C, 0x0354, 1, 0x0828, 1, 0),
+    MX6Q_PAD_SD2_CLK__KPP_COL_5                 = IOMUX_PAD(0x073C, 0x0354, 2, 0x08E8, 3, 0),
+    MX6Q_PAD_SD2_CLK__AUDMUX_AUD4_RXFS          = IOMUX_PAD(0x073C, 0x0354, 3, 0x07C0, 1, 0),
+    MX6Q_PAD_SD2_CLK__PCIE_CTRL_MUX_9           = IOMUX_PAD(0x073C, 0x0354, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_CLK__GPIO_1_10                 = IOMUX_PAD(0x073C, 0x0354, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_CLK__PHY_DTB_1                 = IOMUX_PAD(0x073C, 0x0354, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_CLK__SATA_PHY_DTB_1            = IOMUX_PAD(0x073C, 0x0354, 7, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_CMD__USDHC2_CMD                = IOMUX_PAD(0x0740, 0x0358, 16, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_CMD__ECSPI5_MOSI               = IOMUX_PAD(0x0740, 0x0358, 1, 0x0830, 1, 0),
+    MX6Q_PAD_SD2_CMD__KPP_ROW_5                 = IOMUX_PAD(0x0740, 0x0358, 2, 0x08F4, 2, 0),
+    MX6Q_PAD_SD2_CMD__AUDMUX_AUD4_RXC           = IOMUX_PAD(0x0740, 0x0358, 3, 0x07BC, 1, 0),
+    MX6Q_PAD_SD2_CMD__PCIE_CTRL_MUX_10          = IOMUX_PAD(0x0740, 0x0358, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_CMD__GPIO_1_11                 = IOMUX_PAD(0x0740, 0x0358, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT3__USDHC2_DAT3              = IOMUX_PAD(0x0744, 0x035C, 0, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT3__ECSPI5_SS3               = IOMUX_PAD(0x0744, 0x035C, 1, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT3__KPP_COL_6                = IOMUX_PAD(0x0744, 0x035C, 2, 0x08EC, 2, 0),
+    MX6Q_PAD_SD2_DAT3__AUDMUX_AUD4_TXC          = IOMUX_PAD(0x0744, 0x035C, 3, 0x07C4, 1, 0),
+    MX6Q_PAD_SD2_DAT3__PCIE_CTRL_MUX_11         = IOMUX_PAD(0x0744, 0x035C, 4, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT3__GPIO_1_12                = IOMUX_PAD(0x0744, 0x035C, 5, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT3__SJC_DONE                 = IOMUX_PAD(0x0744, 0x035C, 6, 0x0000, 0, 0),
+    MX6Q_PAD_SD2_DAT3__ANATOP_TESTO_3           = IOMUX_PAD(0x0744, 0x035C, 7, 0x0000, 0, 0),
+};
diff --git a/libethdrivers/src/plat/imx6/uboot/imx6sx_pins.h b/libethdrivers/src/plat/imx6/uboot/imx6sx_pins.h
new file mode 100644
index 0000000..9efc6e3
--- /dev/null
+++ b/libethdrivers/src/plat/imx6/uboot/imx6sx_pins.h
@@ -0,0 +1,1687 @@
+/*
+ * Copyright (C) 2014 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2020, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * content derived from <u-boot>/arch/arm/include/asm/arch-mx6/mx6sx_pins.h
+ */
+
+#pragma once
+
+#include "imx_pins.h"
+
+#ifndef CONFIG_PLAT_IMX6SX
+/* all definitions here are for the i.MX6 SoloX SoC */
+#error "CONFIG_PLAT_IMX6SX not defined, check settings"
+#endif
+
+/* For some configurations IOMUX_CONFIG_SION must explicitly be set, seems this
+ * is necessary for I2C to work properly. See patch "mx6sx enable SION for i2c
+ * pin mux" for u-boot's arch/arm/include/asm/arch-mx6/mx6sx_pins.h from
+ * https://lists.denx.de/pipermail/u-boot/2015-May/214514.html
+ */
+
+enum {
+    MX6SX_PAD_GPIO1_IO00__I2C1_SCL                           = IOMUX_PAD(0x035C, 0x0014, IOMUX_CONFIG_SION | 0, 0x07A8, 1, 0),
+    MX6SX_PAD_GPIO1_IO00__USDHC1_VSELECT                     = IOMUX_PAD(0x035C, 0x0014, 1, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO00__SPDIF_LOCK                         = IOMUX_PAD(0x035C, 0x0014, 2, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO00__CCM_WAIT                           = IOMUX_PAD(0x035C, 0x0014, 3, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO00__WDOG1_WDOG_ANY                     = IOMUX_PAD(0x035C, 0x0014, 4, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO00__GPIO1_IO_0                         = IOMUX_PAD(0x035C, 0x0014, 5, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO00__SNVS_HP_WRAPPER_VIO_5              = IOMUX_PAD(0x035C, 0x0014, 6, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO00__PHY_DTB_1                          = IOMUX_PAD(0x035C, 0x0014, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_GPIO1_IO01__I2C1_SDA                           = IOMUX_PAD(0x0360, 0x0018, IOMUX_CONFIG_SION | 0, 0x07AC, 1, 0),
+    MX6SX_PAD_GPIO1_IO01__USDHC1_RESET_B                     = IOMUX_PAD(0x0360, 0x0018, 1, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO01__SPDIF_SR_CLK                       = IOMUX_PAD(0x0360, 0x0018, 2, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO01__CCM_STOP                           = IOMUX_PAD(0x0360, 0x0018, 3, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO01__WDOG3_WDOG_B                       = IOMUX_PAD(0x0360, 0x0018, 4, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO01__GPIO1_IO_1                         = IOMUX_PAD(0x0360, 0x0018, 5, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO01__SNVS_HP_WRAPPER_VIO_5_CTL          = IOMUX_PAD(0x0360, 0x0018, 6, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO01__PHY_DTB_0                          = IOMUX_PAD(0x0360, 0x0018, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_GPIO1_IO02__I2C2_SCL                           = IOMUX_PAD(0x0364, 0x001C, IOMUX_CONFIG_SION | 0, 0x07B0, 1, 0),
+    MX6SX_PAD_GPIO1_IO02__USDHC1_CD_B                        = IOMUX_PAD(0x0364, 0x001C, 1, 0x0864, 1, 0),
+    MX6SX_PAD_GPIO1_IO02__CSI2_MCLK                          = IOMUX_PAD(0x0364, 0x001C, 2, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO02__CCM_DI0_EXT_CLK                    = IOMUX_PAD(0x0364, 0x001C, 3, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO02__WDOG1_WDOG_B                       = IOMUX_PAD(0x0364, 0x001C, 4, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO02__GPIO1_IO_2                         = IOMUX_PAD(0x0364, 0x001C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO02__CCM_REF_EN_B                       = IOMUX_PAD(0x0364, 0x001C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO02__PHY_TDI                            = IOMUX_PAD(0x0364, 0x001C, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_GPIO1_IO03__I2C2_SDA                           = IOMUX_PAD(0x0368, 0x0020, IOMUX_CONFIG_SION | 0, 0x07B4, 1, 0),
+    MX6SX_PAD_GPIO1_IO03__USDHC1_WP                          = IOMUX_PAD(0x0368, 0x0020, 1, 0x0868, 1, 0),
+    MX6SX_PAD_GPIO1_IO03__ENET1_REF_CLK_25M                  = IOMUX_PAD(0x0368, 0x0020, 2, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO03__CCM_DI1_EXT_CLK                    = IOMUX_PAD(0x0368, 0x0020, 3, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO03__WDOG2_WDOG_B                       = IOMUX_PAD(0x0368, 0x0020, 4, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO03__GPIO1_IO_3                         = IOMUX_PAD(0x0368, 0x0020, 5, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO03__CCM_PLL3_BYP                       = IOMUX_PAD(0x0368, 0x0020, 6, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO03__PHY_TCK                            = IOMUX_PAD(0x0368, 0x0020, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_GPIO1_IO04__UART1_TX                           = IOMUX_PAD(0x036C, 0x0024, 0, 0x0830, 0, 0),
+    MX6SX_PAD_GPIO1_IO04__USDHC2_RESET_B                     = IOMUX_PAD(0x036C, 0x0024, 1, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO04__ENET1_MDC                          = IOMUX_PAD(0x036C, 0x0024, 2, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO04__OSC32K_32K_OUT                     = IOMUX_PAD(0x036C, 0x0024, 3, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO04__ENET2_REF_CLK2                     = IOMUX_PAD(0x036C, 0x0024, 4, 0x076C, 0, 0),
+    MX6SX_PAD_GPIO1_IO04__GPIO1_IO_4                         = IOMUX_PAD(0x036C, 0x0024, 5, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO04__CCM_PLL2_BYP                       = IOMUX_PAD(0x036C, 0x0024, 6, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO04__PHY_TMS                            = IOMUX_PAD(0x036C, 0x0024, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_GPIO1_IO05__UART1_RX                           = IOMUX_PAD(0x0370, 0x0028, 0, 0x0830, 1, 0),
+    MX6SX_PAD_GPIO1_IO05__USDHC2_VSELECT                     = IOMUX_PAD(0x0370, 0x0028, 1, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO05__ENET1_MDIO                         = IOMUX_PAD(0x0370, 0x0028, 2, 0x0764, 0, 0),
+    MX6SX_PAD_GPIO1_IO05__ASRC_ASRC_EXT_CLK                  = IOMUX_PAD(0x0370, 0x0028, 3, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO05__ENET1_REF_CLK1                     = IOMUX_PAD(0x0370, 0x0028, 4, 0x0760, 0, 0),
+    MX6SX_PAD_GPIO1_IO05__GPIO1_IO_5                         = IOMUX_PAD(0x0370, 0x0028, 5, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO05__SRC_TESTER_ACK                     = IOMUX_PAD(0x0370, 0x0028, 6, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO05__PHY_TDO                            = IOMUX_PAD(0x0370, 0x0028, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_GPIO1_IO06__UART2_TX                           = IOMUX_PAD(0x0374, 0x002C, 0, 0x0838, 0, 0),
+    MX6SX_PAD_GPIO1_IO06__USDHC2_CD_B                        = IOMUX_PAD(0x0374, 0x002C, 1, 0x086C, 1, 0),
+    MX6SX_PAD_GPIO1_IO06__ENET2_MDC                          = IOMUX_PAD(0x0374, 0x002C, 2, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO06__CSI1_MCLK                          = IOMUX_PAD(0x0374, 0x002C, 3, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO06__UART1_RTS_B                        = IOMUX_PAD(0x0374, 0x002C, 4, 0x082C, 0, 0),
+    MX6SX_PAD_GPIO1_IO06__GPIO1_IO_6                         = IOMUX_PAD(0x0374, 0x002C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO06__SRC_ANY_PU_RESET                   = IOMUX_PAD(0x0374, 0x002C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO06__OCOTP_CTRL_WRAPPER_FUSE_LATCHED    = IOMUX_PAD(0x0374, 0x002C, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_GPIO1_IO07__UART2_RX                           = IOMUX_PAD(0x0378, 0x0030, 0, 0x0838, 1, 0),
+    MX6SX_PAD_GPIO1_IO07__USDHC2_WP                          = IOMUX_PAD(0x0378, 0x0030, 1, 0x0870, 1, 0),
+    MX6SX_PAD_GPIO1_IO07__ENET2_MDIO                         = IOMUX_PAD(0x0378, 0x0030, 2, 0x0770, 0, 0),
+    MX6SX_PAD_GPIO1_IO07__AUDMUX_MCLK                        = IOMUX_PAD(0x0378, 0x0030, 3, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO07__UART1_CTS_B                        = IOMUX_PAD(0x0378, 0x0030, 4, 0x082C, 1, 0),
+    MX6SX_PAD_GPIO1_IO07__GPIO1_IO_7                         = IOMUX_PAD(0x0378, 0x0030, 5, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO07__SRC_EARLY_RESET                    = IOMUX_PAD(0x0378, 0x0030, 6, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO07__DCIC2_OUT                          = IOMUX_PAD(0x0378, 0x0030, 7, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO07__VDEC_DEBUG_44                      = IOMUX_PAD(0x0378, 0x0030, 8, 0x0000, 0, 0),
+
+    MX6SX_PAD_GPIO1_IO08__USB_OTG1_OC                        = IOMUX_PAD(0x037C, 0x0034, 0, 0x0860, 0, 0),
+    MX6SX_PAD_GPIO1_IO08__WDOG1_WDOG_B                       = IOMUX_PAD(0x037C, 0x0034, 1, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO08__SDMA_EXT_EVENT_0                   = IOMUX_PAD(0x037C, 0x0034, 2, 0x081C, 0, 0),
+    MX6SX_PAD_GPIO1_IO08__CCM_PMIC_RDY                       = IOMUX_PAD(0x037C, 0x0034, 3, 0x069C, 1, 0),
+    MX6SX_PAD_GPIO1_IO08__UART2_RTS_B                        = IOMUX_PAD(0x037C, 0x0034, 4, 0x0834, 0, 0),
+    MX6SX_PAD_GPIO1_IO08__GPIO1_IO_8                         = IOMUX_PAD(0x037C, 0x0034, 5, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO08__SRC_SYSTEM_RESET                   = IOMUX_PAD(0x037C, 0x0034, 6, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO08__DCIC1_OUT                          = IOMUX_PAD(0x037C, 0x0034, 7, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO08__VDEC_DEBUG_43                      = IOMUX_PAD(0x037C, 0x0034, 8, 0x0000, 0, 0),
+
+    MX6SX_PAD_GPIO1_IO09__USB_OTG1_PWR                       = IOMUX_PAD(0x0380, 0x0038, 0, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO09__WDOG2_WDOG_B                       = IOMUX_PAD(0x0380, 0x0038, 1, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO09__SDMA_EXT_EVENT_1                   = IOMUX_PAD(0x0380, 0x0038, 2, 0x0820, 0, 0),
+    MX6SX_PAD_GPIO1_IO09__CCM_OUT0                           = IOMUX_PAD(0x0380, 0x0038, 3, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO09__UART2_CTS_B                        = IOMUX_PAD(0x0380, 0x0038, 4, 0x0834, 1, 0),
+    MX6SX_PAD_GPIO1_IO09__GPIO1_IO_9                         = IOMUX_PAD(0x0380, 0x0038, 5, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO09__SRC_INT_BOOT                       = IOMUX_PAD(0x0380, 0x0038, 6, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO09__OBSERVE_MUX_OUT_4                  = IOMUX_PAD(0x0380, 0x0038, 7, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO09__VDEC_DEBUG_42                      = IOMUX_PAD(0x0380, 0x0038, 8, 0x0000, 0, 0),
+
+    MX6SX_PAD_GPIO1_IO10__ANATOP_OTG1_ID                     = IOMUX_PAD(0x0384, 0x003C, 0, 0x0624, 0, 0),
+    MX6SX_PAD_GPIO1_IO10__SPDIF_EXT_CLK                      = IOMUX_PAD(0x0384, 0x003C, 1, 0x0828, 0, 0),
+    MX6SX_PAD_GPIO1_IO10__PWM1_OUT                           = IOMUX_PAD(0x0384, 0x003C, 2, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO10__CCM_OUT1                           = IOMUX_PAD(0x0384, 0x003C, 3, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO10__CSI1_FIELD                         = IOMUX_PAD(0x0384, 0x003C, 4, 0x070C, 1, 0),
+    MX6SX_PAD_GPIO1_IO10__GPIO1_IO_10                        = IOMUX_PAD(0x0384, 0x003C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO10__CSU_CSU_INT_DEB                    = IOMUX_PAD(0x0384, 0x003C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO10__OBSERVE_MUX_OUT_3                  = IOMUX_PAD(0x0384, 0x003C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO10__VDEC_DEBUG_41                      = IOMUX_PAD(0x0384, 0x003C, 8, 0x0000, 0, 0),
+
+    MX6SX_PAD_GPIO1_IO11__USB_OTG2_OC                        = IOMUX_PAD(0x0388, 0x0040, 0, 0x085C, 0, 0),
+    MX6SX_PAD_GPIO1_IO11__SPDIF_IN                           = IOMUX_PAD(0x0388, 0x0040, 1, 0x0824, 2, 0),
+    MX6SX_PAD_GPIO1_IO11__PWM2_OUT                           = IOMUX_PAD(0x0388, 0x0040, 2, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO11__CCM_CLKO1                          = IOMUX_PAD(0x0388, 0x0040, 3, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO11__MLB_DATA                           = IOMUX_PAD(0x0388, 0x0040, 4, 0x07EC, 0, 0),
+    MX6SX_PAD_GPIO1_IO11__GPIO1_IO_11                        = IOMUX_PAD(0x0388, 0x0040, 5, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO11__CSU_CSU_ALARM_AUT_0                = IOMUX_PAD(0x0388, 0x0040, 6, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO11__OBSERVE_MUX_OUT_2                  = IOMUX_PAD(0x0388, 0x0040, 7, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO11__VDEC_DEBUG_40                      = IOMUX_PAD(0x0388, 0x0040, 8, 0x0000, 0, 0),
+
+    MX6SX_PAD_GPIO1_IO12__USB_OTG2_PWR                       = IOMUX_PAD(0x038C, 0x0044, 0, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO12__SPDIF_OUT                          = IOMUX_PAD(0x038C, 0x0044, 1, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO12__PWM3_OUT                           = IOMUX_PAD(0x038C, 0x0044, 2, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO12__CCM_CLKO2                          = IOMUX_PAD(0x038C, 0x0044, 3, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO12__MLB_CLK                            = IOMUX_PAD(0x038C, 0x0044, 4, 0x07E8, 0, 0),
+    MX6SX_PAD_GPIO1_IO12__GPIO1_IO_12                        = IOMUX_PAD(0x038C, 0x0044, 5, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO12__CSU_CSU_ALARM_AUT_1                = IOMUX_PAD(0x038C, 0x0044, 6, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO12__OBSERVE_MUX_OUT_1                  = IOMUX_PAD(0x038C, 0x0044, 7, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO12__VDEC_DEBUG_39                      = IOMUX_PAD(0x038C, 0x0044, 8, 0x0000, 0, 0),
+
+    MX6SX_PAD_GPIO1_IO13__WDOG1_WDOG_ANY                     = IOMUX_PAD(0x0390, 0x0048, 0, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO13__ANATOP_OTG2_ID                     = IOMUX_PAD(0x0390, 0x0048, 1, 0x0628, 0, 0),
+    MX6SX_PAD_GPIO1_IO13__PWM4_OUT                           = IOMUX_PAD(0x0390, 0x0048, 2, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO13__CCM_OUT2                           = IOMUX_PAD(0x0390, 0x0048, 3, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO13__MLB_SIG                            = IOMUX_PAD(0x0390, 0x0048, 4, 0x07F0, 0, 0),
+    MX6SX_PAD_GPIO1_IO13__GPIO1_IO_13                        = IOMUX_PAD(0x0390, 0x0048, 5, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO13__CSU_CSU_ALARM_AUT_2                = IOMUX_PAD(0x0390, 0x0048, 6, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO13__OBSERVE_MUX_OUT_0                  = IOMUX_PAD(0x0390, 0x0048, 7, 0x0000, 0, 0),
+    MX6SX_PAD_GPIO1_IO13__VDEC_DEBUG_38                      = IOMUX_PAD(0x0390, 0x0048, 8, 0x0000, 0, 0),
+
+    MX6SX_PAD_CSI_DATA00__CSI1_DATA_2                        = IOMUX_PAD(0x0394, 0x004C, 0, 0x06A8, 0, 0),
+    MX6SX_PAD_CSI_DATA00__ESAI_TX_CLK                        = IOMUX_PAD(0x0394, 0x004C, 1, 0x078C, 1, 0),
+    MX6SX_PAD_CSI_DATA00__AUDMUX_AUD6_TXC                    = IOMUX_PAD(0x0394, 0x004C, 2, 0x0684, 1, 0),
+    MX6SX_PAD_CSI_DATA00__I2C1_SCL                           = IOMUX_PAD(0x0394, 0x004C, IOMUX_CONFIG_SION | 3, 0x07A8, 0, 0),
+    MX6SX_PAD_CSI_DATA00__UART6_RI_B                         = IOMUX_PAD(0x0394, 0x004C, 4, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA00__GPIO1_IO_14                        = IOMUX_PAD(0x0394, 0x004C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA00__WEIM_DATA_23                       = IOMUX_PAD(0x0394, 0x004C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA00__SAI1_TX_BCLK                       = IOMUX_PAD(0x0394, 0x004C, 7, 0x0800, 0, 0),
+    MX6SX_PAD_CSI_DATA00__VADC_DATA_4                        = IOMUX_PAD(0x0394, 0x004C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA00__MMDC_DEBUG_37                      = IOMUX_PAD(0x0394, 0x004C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_CSI_DATA01__CSI1_DATA_3                        = IOMUX_PAD(0x0398, 0x0050, 0, 0x06AC, 0, 0),
+    MX6SX_PAD_CSI_DATA01__ESAI_TX_FS                         = IOMUX_PAD(0x0398, 0x0050, 1, 0x077C, 1, 0),
+    MX6SX_PAD_CSI_DATA01__AUDMUX_AUD6_TXFS                   = IOMUX_PAD(0x0398, 0x0050, 2, 0x0688, 1, 0),
+    MX6SX_PAD_CSI_DATA01__I2C1_SDA                           = IOMUX_PAD(0x0398, 0x0050, IOMUX_CONFIG_SION | 3, 0x07AC, 0, 0),
+    MX6SX_PAD_CSI_DATA01__UART6_DSR_B                        = IOMUX_PAD(0x0398, 0x0050, 4, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA01__GPIO1_IO_15                        = IOMUX_PAD(0x0398, 0x0050, 5, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA01__WEIM_DATA_22                       = IOMUX_PAD(0x0398, 0x0050, 6, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA01__SAI1_TX_SYNC                       = IOMUX_PAD(0x0398, 0x0050, 7, 0x0804, 0, 0),
+    MX6SX_PAD_CSI_DATA01__VADC_DATA_5                        = IOMUX_PAD(0x0398, 0x0050, 8, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA01__MMDC_DEBUG_38                      = IOMUX_PAD(0x0398, 0x0050, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_CSI_DATA02__CSI1_DATA_4                        = IOMUX_PAD(0x039C, 0x0054, 0, 0x06B0, 0, 0),
+    MX6SX_PAD_CSI_DATA02__ESAI_RX_CLK                        = IOMUX_PAD(0x039C, 0x0054, 1, 0x0788, 1, 0),
+    MX6SX_PAD_CSI_DATA02__AUDMUX_AUD6_RXC                    = IOMUX_PAD(0x039C, 0x0054, 2, 0x067C, 1, 0),
+    MX6SX_PAD_CSI_DATA02__KPP_COL_5                          = IOMUX_PAD(0x039C, 0x0054, 3, 0x07C8, 0, 0),
+    MX6SX_PAD_CSI_DATA02__UART6_DTR_B                        = IOMUX_PAD(0x039C, 0x0054, 4, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA02__GPIO1_IO_16                        = IOMUX_PAD(0x039C, 0x0054, 5, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA02__WEIM_DATA_21                       = IOMUX_PAD(0x039C, 0x0054, 6, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA02__SAI1_RX_BCLK                       = IOMUX_PAD(0x039C, 0x0054, 7, 0x07F4, 0, 0),
+    MX6SX_PAD_CSI_DATA02__VADC_DATA_6                        = IOMUX_PAD(0x039C, 0x0054, 8, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA02__MMDC_DEBUG_39                      = IOMUX_PAD(0x039C, 0x0054, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_CSI_DATA03__CSI1_DATA_5                        = IOMUX_PAD(0x03A0, 0x0058, 0, 0x06B4, 0, 0),
+    MX6SX_PAD_CSI_DATA03__ESAI_RX_FS                         = IOMUX_PAD(0x03A0, 0x0058, 1, 0x0778, 1, 0),
+    MX6SX_PAD_CSI_DATA03__AUDMUX_AUD6_RXFS                   = IOMUX_PAD(0x03A0, 0x0058, 2, 0x0680, 1, 0),
+    MX6SX_PAD_CSI_DATA03__KPP_ROW_5                          = IOMUX_PAD(0x03A0, 0x0058, 3, 0x07D4, 0, 0),
+    MX6SX_PAD_CSI_DATA03__UART6_DCD_B                        = IOMUX_PAD(0x03A0, 0x0058, 4, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA03__GPIO1_IO_17                        = IOMUX_PAD(0x03A0, 0x0058, 5, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA03__WEIM_DATA_20                       = IOMUX_PAD(0x03A0, 0x0058, 6, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA03__SAI1_RX_SYNC                       = IOMUX_PAD(0x03A0, 0x0058, 7, 0x07FC, 0, 0),
+    MX6SX_PAD_CSI_DATA03__VADC_DATA_7                        = IOMUX_PAD(0x03A0, 0x0058, 8, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA03__MMDC_DEBUG_40                      = IOMUX_PAD(0x03A0, 0x0058, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_CSI_DATA04__CSI1_DATA_6                        = IOMUX_PAD(0x03A4, 0x005C, 0, 0x06B8, 0, 0),
+    MX6SX_PAD_CSI_DATA04__ESAI_TX1                           = IOMUX_PAD(0x03A4, 0x005C, 1, 0x0794, 1, 0),
+    MX6SX_PAD_CSI_DATA04__SPDIF_OUT                          = IOMUX_PAD(0x03A4, 0x005C, 2, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA04__KPP_COL_6                          = IOMUX_PAD(0x03A4, 0x005C, 3, 0x07CC, 0, 0),
+    MX6SX_PAD_CSI_DATA04__UART6_RX                           = IOMUX_PAD(0x03A4, 0x005C, 4, 0x0858, 0, 0),
+    MX6SX_PAD_CSI_DATA04__GPIO1_IO_18                        = IOMUX_PAD(0x03A4, 0x005C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA04__WEIM_DATA_19                       = IOMUX_PAD(0x03A4, 0x005C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA04__PWM5_OUT                           = IOMUX_PAD(0x03A4, 0x005C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA04__VADC_DATA_8                        = IOMUX_PAD(0x03A4, 0x005C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA04__MMDC_DEBUG_41                      = IOMUX_PAD(0x03A4, 0x005C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_CSI_DATA05__CSI1_DATA_7                        = IOMUX_PAD(0x03A8, 0x0060, 0, 0x06BC, 0, 0),
+    MX6SX_PAD_CSI_DATA05__ESAI_TX4_RX1                       = IOMUX_PAD(0x03A8, 0x0060, 1, 0x07A0, 1, 0),
+    MX6SX_PAD_CSI_DATA05__SPDIF_IN                           = IOMUX_PAD(0x03A8, 0x0060, 2, 0x0824, 1, 0),
+    MX6SX_PAD_CSI_DATA05__KPP_ROW_6                          = IOMUX_PAD(0x03A8, 0x0060, 3, 0x07D8, 0, 0),
+    MX6SX_PAD_CSI_DATA05__UART6_TX                           = IOMUX_PAD(0x03A8, 0x0060, 4, 0x0858, 1, 0),
+    MX6SX_PAD_CSI_DATA05__GPIO1_IO_19                        = IOMUX_PAD(0x03A8, 0x0060, 5, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA05__WEIM_DATA_18                       = IOMUX_PAD(0x03A8, 0x0060, 6, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA05__PWM6_OUT                           = IOMUX_PAD(0x03A8, 0x0060, 7, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA05__VADC_DATA_9                        = IOMUX_PAD(0x03A8, 0x0060, 8, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA05__MMDC_DEBUG_42                      = IOMUX_PAD(0x03A8, 0x0060, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_CSI_DATA06__CSI1_DATA_8                        = IOMUX_PAD(0x03AC, 0x0064, 0, 0x06C0, 0, 0),
+    MX6SX_PAD_CSI_DATA06__ESAI_TX2_RX3                       = IOMUX_PAD(0x03AC, 0x0064, 1, 0x0798, 1, 0),
+    MX6SX_PAD_CSI_DATA06__I2C4_SCL                           = IOMUX_PAD(0x03AC, 0x0064, IOMUX_CONFIG_SION | 2, 0x07C0, 2, 0),
+    MX6SX_PAD_CSI_DATA06__KPP_COL_7                          = IOMUX_PAD(0x03AC, 0x0064, 3, 0x07D0, 0, 0),
+    MX6SX_PAD_CSI_DATA06__UART6_RTS_B                        = IOMUX_PAD(0x03AC, 0x0064, 4, 0x0854, 0, 0),
+    MX6SX_PAD_CSI_DATA06__GPIO1_IO_20                        = IOMUX_PAD(0x03AC, 0x0064, 5, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA06__WEIM_DATA_17                       = IOMUX_PAD(0x03AC, 0x0064, 6, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA06__DCIC2_OUT                          = IOMUX_PAD(0x03AC, 0x0064, 7, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA06__VADC_DATA_10                       = IOMUX_PAD(0x03AC, 0x0064, 8, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA06__MMDC_DEBUG_43                      = IOMUX_PAD(0x03AC, 0x0064, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_CSI_DATA07__CSI1_DATA_9                        = IOMUX_PAD(0x03B0, 0x0068, 0, 0x06C4, 0, 0),
+    MX6SX_PAD_CSI_DATA07__ESAI_TX3_RX2                       = IOMUX_PAD(0x03B0, 0x0068, 1, 0x079C, 1, 0),
+    MX6SX_PAD_CSI_DATA07__I2C4_SDA                           = IOMUX_PAD(0x03B0, 0x0068, IOMUX_CONFIG_SION | 2, 0x07C4, 2, 0),
+    MX6SX_PAD_CSI_DATA07__KPP_ROW_7                          = IOMUX_PAD(0x03B0, 0x0068, 3, 0x07DC, 0, 0),
+    MX6SX_PAD_CSI_DATA07__UART6_CTS_B                        = IOMUX_PAD(0x03B0, 0x0068, 4, 0x0854, 1, 0),
+    MX6SX_PAD_CSI_DATA07__GPIO1_IO_21                        = IOMUX_PAD(0x03B0, 0x0068, 5, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA07__WEIM_DATA_16                       = IOMUX_PAD(0x03B0, 0x0068, 6, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA07__DCIC1_OUT                          = IOMUX_PAD(0x03B0, 0x0068, 7, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA07__VADC_DATA_11                       = IOMUX_PAD(0x03B0, 0x0068, 8, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_DATA07__MMDC_DEBUG_44                      = IOMUX_PAD(0x03B0, 0x0068, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_CSI_HSYNC__CSI1_HSYNC                          = IOMUX_PAD(0x03B4, 0x006C, 0, 0x0700, 0, 0),
+    MX6SX_PAD_CSI_HSYNC__ESAI_TX0                            = IOMUX_PAD(0x03B4, 0x006C, 1, 0x0790, 1, 0),
+    MX6SX_PAD_CSI_HSYNC__AUDMUX_AUD6_TXD                     = IOMUX_PAD(0x03B4, 0x006C, 2, 0x0678, 1, 0),
+    MX6SX_PAD_CSI_HSYNC__UART4_RTS_B                         = IOMUX_PAD(0x03B4, 0x006C, 3, 0x0844, 2, 0),
+    MX6SX_PAD_CSI_HSYNC__MQS_LEFT                            = IOMUX_PAD(0x03B4, 0x006C, 4, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_HSYNC__GPIO1_IO_22                         = IOMUX_PAD(0x03B4, 0x006C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_HSYNC__WEIM_DATA_25                        = IOMUX_PAD(0x03B4, 0x006C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_HSYNC__SAI1_TX_DATA_0                      = IOMUX_PAD(0x03B4, 0x006C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_HSYNC__VADC_DATA_2                         = IOMUX_PAD(0x03B4, 0x006C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_HSYNC__MMDC_DEBUG_35                       = IOMUX_PAD(0x03B4, 0x006C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_CSI_MCLK__CSI1_MCLK                            = IOMUX_PAD(0x03B8, 0x0070, 0, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_MCLK__ESAI_TX_HF_CLK                       = IOMUX_PAD(0x03B8, 0x0070, 1, 0x0784, 1, 0),
+    MX6SX_PAD_CSI_MCLK__OSC32K_32K_OUT                       = IOMUX_PAD(0x03B8, 0x0070, 2, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_MCLK__UART4_RX                             = IOMUX_PAD(0x03B8, 0x0070, 3, 0x0848, 2, 0),
+    MX6SX_PAD_CSI_MCLK__ANATOP_32K_OUT                       = IOMUX_PAD(0x03B8, 0x0070, 4, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_MCLK__GPIO1_IO_23                          = IOMUX_PAD(0x03B8, 0x0070, 5, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_MCLK__WEIM_DATA_26                         = IOMUX_PAD(0x03B8, 0x0070, 6, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_MCLK__CSI1_FIELD                           = IOMUX_PAD(0x03B8, 0x0070, 7, 0x070C, 0, 0),
+    MX6SX_PAD_CSI_MCLK__VADC_DATA_1                          = IOMUX_PAD(0x03B8, 0x0070, 8, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_MCLK__MMDC_DEBUG_34                        = IOMUX_PAD(0x03B8, 0x0070, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_CSI_PIXCLK__CSI1_PIXCLK                        = IOMUX_PAD(0x03BC, 0x0074, 0, 0x0704, 0, 0),
+    MX6SX_PAD_CSI_PIXCLK__ESAI_RX_HF_CLK                     = IOMUX_PAD(0x03BC, 0x0074, 1, 0x0780, 1, 0),
+    MX6SX_PAD_CSI_PIXCLK__AUDMUX_MCLK                        = IOMUX_PAD(0x03BC, 0x0074, 2, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_PIXCLK__UART4_TX                           = IOMUX_PAD(0x03BC, 0x0074, 3, 0x0848, 3, 0),
+    MX6SX_PAD_CSI_PIXCLK__ANATOP_24M_OUT                     = IOMUX_PAD(0x03BC, 0x0074, 4, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_PIXCLK__GPIO1_IO_24                        = IOMUX_PAD(0x03BC, 0x0074, 5, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_PIXCLK__WEIM_DATA_27                       = IOMUX_PAD(0x03BC, 0x0074, 6, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_PIXCLK__ESAI_TX_HF_CLK                     = IOMUX_PAD(0x03BC, 0x0074, 7, 0x0784, 2, 0),
+    MX6SX_PAD_CSI_PIXCLK__VADC_CLK                           = IOMUX_PAD(0x03BC, 0x0074, 8, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_PIXCLK__MMDC_DEBUG_33                      = IOMUX_PAD(0x03BC, 0x0074, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_CSI_VSYNC__CSI1_VSYNC                          = IOMUX_PAD(0x03C0, 0x0078, 0, 0x0708, 0, 0),
+    MX6SX_PAD_CSI_VSYNC__ESAI_TX5_RX0                        = IOMUX_PAD(0x03C0, 0x0078, 1, 0x07A4, 1, 0),
+    MX6SX_PAD_CSI_VSYNC__AUDMUX_AUD6_RXD                     = IOMUX_PAD(0x03C0, 0x0078, 2, 0x0674, 1, 0),
+    MX6SX_PAD_CSI_VSYNC__UART4_CTS_B                         = IOMUX_PAD(0x03C0, 0x0078, 3, 0x0844, 3, 0),
+    MX6SX_PAD_CSI_VSYNC__MQS_RIGHT                           = IOMUX_PAD(0x03C0, 0x0078, 4, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_VSYNC__GPIO1_IO_25                         = IOMUX_PAD(0x03C0, 0x0078, 5, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_VSYNC__WEIM_DATA_24                        = IOMUX_PAD(0x03C0, 0x0078, 6, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_VSYNC__SAI1_RX_DATA_0                      = IOMUX_PAD(0x03C0, 0x0078, 7, 0x07F8, 0, 0),
+    MX6SX_PAD_CSI_VSYNC__VADC_DATA_3                         = IOMUX_PAD(0x03C0, 0x0078, 8, 0x0000, 0, 0),
+    MX6SX_PAD_CSI_VSYNC__MMDC_DEBUG_36                       = IOMUX_PAD(0x03C0, 0x0078, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_ENET1_COL__ENET1_COL                           = IOMUX_PAD(0x03C4, 0x007C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_COL__ENET2_MDC                           = IOMUX_PAD(0x03C4, 0x007C, 1, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_COL__AUDMUX_AUD4_TXC                     = IOMUX_PAD(0x03C4, 0x007C, 2, 0x0654, 1, 0),
+    MX6SX_PAD_ENET1_COL__UART1_RI_B                          = IOMUX_PAD(0x03C4, 0x007C, 3, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_COL__SPDIF_EXT_CLK                       = IOMUX_PAD(0x03C4, 0x007C, 4, 0x0828, 1, 0),
+    MX6SX_PAD_ENET1_COL__GPIO2_IO_0                          = IOMUX_PAD(0x03C4, 0x007C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_COL__CSI2_DATA_23                        = IOMUX_PAD(0x03C4, 0x007C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_COL__LCDIF2_DATA_16                      = IOMUX_PAD(0x03C4, 0x007C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_COL__VDEC_DEBUG_37                       = IOMUX_PAD(0x03C4, 0x007C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_COL__PCIE_CTRL_DEBUG_31                  = IOMUX_PAD(0x03C4, 0x007C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_ENET1_CRS__ENET1_CRS                           = IOMUX_PAD(0x03C8, 0x0080, 0, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_CRS__ENET2_MDIO                          = IOMUX_PAD(0x03C8, 0x0080, 1, 0x0770, 1, 0),
+    MX6SX_PAD_ENET1_CRS__AUDMUX_AUD4_TXD                     = IOMUX_PAD(0x03C8, 0x0080, 2, 0x0648, 1, 0),
+    MX6SX_PAD_ENET1_CRS__UART1_DCD_B                         = IOMUX_PAD(0x03C8, 0x0080, 3, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_CRS__SPDIF_LOCK                          = IOMUX_PAD(0x03C8, 0x0080, 4, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_CRS__GPIO2_IO_1                          = IOMUX_PAD(0x03C8, 0x0080, 5, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_CRS__CSI2_DATA_22                        = IOMUX_PAD(0x03C8, 0x0080, 6, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_CRS__LCDIF2_DATA_17                      = IOMUX_PAD(0x03C8, 0x0080, 7, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_CRS__VDEC_DEBUG_36                       = IOMUX_PAD(0x03C8, 0x0080, 8, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_CRS__PCIE_CTRL_DEBUG_30                  = IOMUX_PAD(0x03C8, 0x0080, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_ENET1_MDC__ENET1_MDC                           = IOMUX_PAD(0x03CC, 0x0084, 0, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_MDC__ENET2_MDC                           = IOMUX_PAD(0x03CC, 0x0084, 1, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_MDC__AUDMUX_AUD3_RXFS                    = IOMUX_PAD(0x03CC, 0x0084, 2, 0x0638, 1, 0),
+    MX6SX_PAD_ENET1_MDC__ANATOP_24M_OUT                      = IOMUX_PAD(0x03CC, 0x0084, 3, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_MDC__EPIT2_OUT                           = IOMUX_PAD(0x03CC, 0x0084, 4, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_MDC__GPIO2_IO_2                          = IOMUX_PAD(0x03CC, 0x0084, 5, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_MDC__USB_OTG1_PWR                        = IOMUX_PAD(0x03CC, 0x0084, 6, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_MDC__PWM7_OUT                            = IOMUX_PAD(0x03CC, 0x0084, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_ENET1_MDIO__ENET1_MDIO                         = IOMUX_PAD(0x03D0, 0x0088, 0, 0x0764, 1, 0),
+    MX6SX_PAD_ENET1_MDIO__ENET2_MDIO                         = IOMUX_PAD(0x03D0, 0x0088, 1, 0x0770, 2, 0),
+    MX6SX_PAD_ENET1_MDIO__AUDMUX_MCLK                        = IOMUX_PAD(0x03D0, 0x0088, 2, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_MDIO__OSC32K_32K_OUT                     = IOMUX_PAD(0x03D0, 0x0088, 3, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_MDIO__EPIT1_OUT                          = IOMUX_PAD(0x03D0, 0x0088, 4, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_MDIO__GPIO2_IO_3                         = IOMUX_PAD(0x03D0, 0x0088, 5, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_MDIO__USB_OTG1_OC                        = IOMUX_PAD(0x03D0, 0x0088, 6, 0x0860, 1, 0),
+    MX6SX_PAD_ENET1_MDIO__PWM8_OUT                           = IOMUX_PAD(0x03D0, 0x0088, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_ENET1_RX_CLK__ENET1_RX_CLK                     = IOMUX_PAD(0x03D4, 0x008C, 0, 0x0768, 0, 0),
+    MX6SX_PAD_ENET1_RX_CLK__ENET1_REF_CLK_25M                = IOMUX_PAD(0x03D4, 0x008C, 1, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_RX_CLK__AUDMUX_AUD4_TXFS                 = IOMUX_PAD(0x03D4, 0x008C, 2, 0x0658, 1, 0),
+    MX6SX_PAD_ENET1_RX_CLK__UART1_DSR_B                      = IOMUX_PAD(0x03D4, 0x008C, 3, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_RX_CLK__SPDIF_OUT                        = IOMUX_PAD(0x03D4, 0x008C, 4, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_RX_CLK__GPIO2_IO_4                       = IOMUX_PAD(0x03D4, 0x008C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_RX_CLK__CSI2_DATA_21                     = IOMUX_PAD(0x03D4, 0x008C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_RX_CLK__LCDIF2_DATA_18                   = IOMUX_PAD(0x03D4, 0x008C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_RX_CLK__VDEC_DEBUG_35                    = IOMUX_PAD(0x03D4, 0x008C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_RX_CLK__PCIE_CTRL_DEBUG_29               = IOMUX_PAD(0x03D4, 0x008C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_ENET1_TX_CLK__ENET1_TX_CLK                     = IOMUX_PAD(0x03D8, 0x0090, 0, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_TX_CLK__ENET1_REF_CLK1                   = IOMUX_PAD(0x03D8, 0x0090, 1, 0x0760, 1, 0),
+    MX6SX_PAD_ENET1_TX_CLK__AUDMUX_AUD4_RXD                  = IOMUX_PAD(0x03D8, 0x0090, 2, 0x0644, 1, 0),
+    MX6SX_PAD_ENET1_TX_CLK__UART1_DTR_B                      = IOMUX_PAD(0x03D8, 0x0090, 3, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_TX_CLK__SPDIF_SR_CLK                     = IOMUX_PAD(0x03D8, 0x0090, 4, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_TX_CLK__GPIO2_IO_5                       = IOMUX_PAD(0x03D8, 0x0090, 5, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_TX_CLK__CSI2_DATA_20                     = IOMUX_PAD(0x03D8, 0x0090, 6, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_TX_CLK__LCDIF2_DATA_19                   = IOMUX_PAD(0x03D8, 0x0090, 7, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_TX_CLK__VDEC_DEBUG_34                    = IOMUX_PAD(0x03D8, 0x0090, 8, 0x0000, 0, 0),
+    MX6SX_PAD_ENET1_TX_CLK__PCIE_CTRL_DEBUG_28               = IOMUX_PAD(0x03D8, 0x0090, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_ENET2_COL__ENET2_COL                           = IOMUX_PAD(0x03DC, 0x0094, 0, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_COL__ENET1_MDC                           = IOMUX_PAD(0x03DC, 0x0094, 1, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_COL__AUDMUX_AUD4_RXC                     = IOMUX_PAD(0x03DC, 0x0094, 2, 0x064C, 1, 0),
+    MX6SX_PAD_ENET2_COL__UART1_RX                            = IOMUX_PAD(0x03DC, 0x0094, 3, 0x0830, 2, 0),
+    MX6SX_PAD_ENET2_COL__SPDIF_IN                            = IOMUX_PAD(0x03DC, 0x0094, 4, 0x0824, 3, 0),
+    MX6SX_PAD_ENET2_COL__GPIO2_IO_6                          = IOMUX_PAD(0x03DC, 0x0094, 5, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_COL__ANATOP_OTG1_ID                      = IOMUX_PAD(0x03DC, 0x0094, 6, 0x0624, 1, 0),
+    MX6SX_PAD_ENET2_COL__LCDIF2_DATA_20                      = IOMUX_PAD(0x03DC, 0x0094, 7, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_COL__VDEC_DEBUG_33                       = IOMUX_PAD(0x03DC, 0x0094, 8, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_COL__PCIE_CTRL_DEBUG_27                  = IOMUX_PAD(0x03DC, 0x0094, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_ENET2_CRS__ENET2_CRS                           = IOMUX_PAD(0x03E0, 0x0098, 0, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_CRS__ENET1_MDIO                          = IOMUX_PAD(0x03E0, 0x0098, 1, 0x0764, 2, 0),
+    MX6SX_PAD_ENET2_CRS__AUDMUX_AUD4_RXFS                    = IOMUX_PAD(0x03E0, 0x0098, 2, 0x0650, 1, 0),
+    MX6SX_PAD_ENET2_CRS__UART1_TX                            = IOMUX_PAD(0x03E0, 0x0098, 3, 0x0830, 3, 0),
+    MX6SX_PAD_ENET2_CRS__MLB_SIG                             = IOMUX_PAD(0x03E0, 0x0098, 4, 0x07F0, 1, 0),
+    MX6SX_PAD_ENET2_CRS__GPIO2_IO_7                          = IOMUX_PAD(0x03E0, 0x0098, 5, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_CRS__ANATOP_OTG2_ID                      = IOMUX_PAD(0x03E0, 0x0098, 6, 0x0628, 1, 0),
+    MX6SX_PAD_ENET2_CRS__LCDIF2_DATA_21                      = IOMUX_PAD(0x03E0, 0x0098, 7, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_CRS__VDEC_DEBUG_32                       = IOMUX_PAD(0x03E0, 0x0098, 8, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_CRS__PCIE_CTRL_DEBUG_26                  = IOMUX_PAD(0x03E0, 0x0098, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_ENET2_RX_CLK__ENET2_RX_CLK                     = IOMUX_PAD(0x03E4, 0x009C, 0, 0x0774, 0, 0),
+    MX6SX_PAD_ENET2_RX_CLK__ENET2_REF_CLK_25M                = IOMUX_PAD(0x03E4, 0x009C, 1, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_RX_CLK__I2C3_SCL                         = IOMUX_PAD(0x03E4, 0x009C, IOMUX_CONFIG_SION | 2, 0x07B8, 1, 0),
+    MX6SX_PAD_ENET2_RX_CLK__UART1_RTS_B                      = IOMUX_PAD(0x03E4, 0x009C, 3, 0x082C, 2, 0),
+    MX6SX_PAD_ENET2_RX_CLK__MLB_DATA                         = IOMUX_PAD(0x03E4, 0x009C, 4, 0x07EC, 1, 0),
+    MX6SX_PAD_ENET2_RX_CLK__GPIO2_IO_8                       = IOMUX_PAD(0x03E4, 0x009C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_RX_CLK__USB_OTG2_OC                      = IOMUX_PAD(0x03E4, 0x009C, 6, 0x085C, 1, 0),
+    MX6SX_PAD_ENET2_RX_CLK__LCDIF2_DATA_22                   = IOMUX_PAD(0x03E4, 0x009C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_RX_CLK__VDEC_DEBUG_31                    = IOMUX_PAD(0x03E4, 0x009C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_RX_CLK__PCIE_CTRL_DEBUG_25               = IOMUX_PAD(0x03E4, 0x009C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_ENET2_TX_CLK__ENET2_TX_CLK                     = IOMUX_PAD(0x03E8, 0x00A0, 0, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_TX_CLK__ENET2_REF_CLK2                   = IOMUX_PAD(0x03E8, 0x00A0, 1, 0x076C, 1, 0),
+    MX6SX_PAD_ENET2_TX_CLK__I2C3_SDA                         = IOMUX_PAD(0x03E8, 0x00A0, IOMUX_CONFIG_SION | 2, 0x07BC, 1, 0),
+    MX6SX_PAD_ENET2_TX_CLK__UART1_CTS_B                      = IOMUX_PAD(0x03E8, 0x00A0, 3, 0x082C, 3, 0),
+    MX6SX_PAD_ENET2_TX_CLK__MLB_CLK                          = IOMUX_PAD(0x03E8, 0x00A0, 4, 0x07E8, 1, 0),
+    MX6SX_PAD_ENET2_TX_CLK__GPIO2_IO_9                       = IOMUX_PAD(0x03E8, 0x00A0, 5, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_TX_CLK__USB_OTG2_PWR                     = IOMUX_PAD(0x03E8, 0x00A0, 6, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_TX_CLK__LCDIF2_DATA_23                   = IOMUX_PAD(0x03E8, 0x00A0, 7, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_TX_CLK__VDEC_DEBUG_30                    = IOMUX_PAD(0x03E8, 0x00A0, 8, 0x0000, 0, 0),
+    MX6SX_PAD_ENET2_TX_CLK__PCIE_CTRL_DEBUG_24               = IOMUX_PAD(0x03E8, 0x00A0, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_KEY_COL0__KPP_COL_0                            = IOMUX_PAD(0x03EC, 0x00A4, 0, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL0__USDHC3_CD_B                          = IOMUX_PAD(0x03EC, 0x00A4, 1, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL0__UART6_RTS_B                          = IOMUX_PAD(0x03EC, 0x00A4, 2, 0x0854, 2, 0),
+    MX6SX_PAD_KEY_COL0__ECSPI1_SCLK                          = IOMUX_PAD(0x03EC, 0x00A4, 3, 0x0710, 0, 0),
+    MX6SX_PAD_KEY_COL0__AUDMUX_AUD5_TXC                      = IOMUX_PAD(0x03EC, 0x00A4, 4, 0x066C, 0, 0),
+    MX6SX_PAD_KEY_COL0__GPIO2_IO_10                          = IOMUX_PAD(0x03EC, 0x00A4, 5, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL0__SDMA_EXT_EVENT_1                     = IOMUX_PAD(0x03EC, 0x00A4, 6, 0x0820, 1, 0),
+    MX6SX_PAD_KEY_COL0__SAI2_TX_BCLK                         = IOMUX_PAD(0x03EC, 0x00A4, 7, 0x0814, 0, 0),
+    MX6SX_PAD_KEY_COL0__VADC_DATA_0                          = IOMUX_PAD(0x03EC, 0x00A4, 8, 0x0000, 0, 0),
+
+    MX6SX_PAD_KEY_COL1__KPP_COL_1                            = IOMUX_PAD(0x03F0, 0x00A8, 0, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL1__USDHC3_RESET_B                       = IOMUX_PAD(0x03F0, 0x00A8, 1, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL1__UART6_TX                             = IOMUX_PAD(0x03F0, 0x00A8, 2, 0x0858, 2, 0),
+    MX6SX_PAD_KEY_COL1__ECSPI1_MISO                          = IOMUX_PAD(0x03F0, 0x00A8, 3, 0x0714, 0, 0),
+    MX6SX_PAD_KEY_COL1__AUDMUX_AUD5_TXFS                     = IOMUX_PAD(0x03F0, 0x00A8, 4, 0x0670, 0, 0),
+    MX6SX_PAD_KEY_COL1__GPIO2_IO_11                          = IOMUX_PAD(0x03F0, 0x00A8, 5, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL1__USDHC3_RESET                         = IOMUX_PAD(0x03F0, 0x00A8, 6, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL1__SAI2_TX_SYNC                         = IOMUX_PAD(0x03F0, 0x00A8, 7, 0x0818, 0, 0),
+
+    MX6SX_PAD_KEY_COL2__KPP_COL_2                            = IOMUX_PAD(0x03F4, 0x00AC, 0, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL2__USDHC4_CD_B                          = IOMUX_PAD(0x03F4, 0x00AC, 1, 0x0874, 1, 0),
+    MX6SX_PAD_KEY_COL2__UART5_RTS_B                          = IOMUX_PAD(0x03F4, 0x00AC, 2, 0x084C, 2, 0),
+    MX6SX_PAD_KEY_COL2__CAN1_TX                              = IOMUX_PAD(0x03F4, 0x00AC, 3, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL2__CANFD_TX1                            = IOMUX_PAD(0x03F4, 0x00AC, 4, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL2__GPIO2_IO_12                          = IOMUX_PAD(0x03F4, 0x00AC, 5, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL2__WEIM_DATA_30                         = IOMUX_PAD(0x03F4, 0x00AC, 6, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL2__ECSPI1_RDY                           = IOMUX_PAD(0x03F4, 0x00AC, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_KEY_COL3__KPP_COL_3                            = IOMUX_PAD(0x03F8, 0x00B0, 0, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL3__USDHC4_LCTL                          = IOMUX_PAD(0x03F8, 0x00B0, 1, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL3__UART5_TX                             = IOMUX_PAD(0x03F8, 0x00B0, 2, 0x0850, 2, 0),
+    MX6SX_PAD_KEY_COL3__CAN2_TX                              = IOMUX_PAD(0x03F8, 0x00B0, 3, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL3__CANFD_TX2                            = IOMUX_PAD(0x03F8, 0x00B0, 4, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL3__GPIO2_IO_13                          = IOMUX_PAD(0x03F8, 0x00B0, 5, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL3__WEIM_DATA_28                         = IOMUX_PAD(0x03F8, 0x00B0, 6, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL3__ECSPI1_SS2                           = IOMUX_PAD(0x03F8, 0x00B0, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_KEY_COL4__KPP_COL_4                            = IOMUX_PAD(0x03FC, 0x00B4, 0, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL4__ENET2_MDC                            = IOMUX_PAD(0x03FC, 0x00B4, 1, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL4__I2C3_SCL                             = IOMUX_PAD(0x03FC, 0x00B4, IOMUX_CONFIG_SION | 2, 0x07B8, 2, 0),
+    MX6SX_PAD_KEY_COL4__USDHC2_LCTL                          = IOMUX_PAD(0x03FC, 0x00B4, 3, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL4__AUDMUX_AUD5_RXC                      = IOMUX_PAD(0x03FC, 0x00B4, 4, 0x0664, 0, 0),
+    MX6SX_PAD_KEY_COL4__GPIO2_IO_14                          = IOMUX_PAD(0x03FC, 0x00B4, 5, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL4__WEIM_CRE                             = IOMUX_PAD(0x03FC, 0x00B4, 6, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_COL4__SAI2_RX_BCLK                         = IOMUX_PAD(0x03FC, 0x00B4, 7, 0x0808, 0, 0),
+
+    MX6SX_PAD_KEY_ROW0__KPP_ROW_0                            = IOMUX_PAD(0x0400, 0x00B8, 0, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW0__USDHC3_WP                            = IOMUX_PAD(0x0400, 0x00B8, 1, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW0__UART6_CTS_B                          = IOMUX_PAD(0x0400, 0x00B8, 2, 0x0854, 3, 0),
+    MX6SX_PAD_KEY_ROW0__ECSPI1_MOSI                          = IOMUX_PAD(0x0400, 0x00B8, 3, 0x0718, 0, 0),
+    MX6SX_PAD_KEY_ROW0__AUDMUX_AUD5_TXD                      = IOMUX_PAD(0x0400, 0x00B8, 4, 0x0660, 0, 0),
+    MX6SX_PAD_KEY_ROW0__GPIO2_IO_15                          = IOMUX_PAD(0x0400, 0x00B8, 5, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW0__SDMA_EXT_EVENT_0                     = IOMUX_PAD(0x0400, 0x00B8, 6, 0x081C, 1, 0),
+    MX6SX_PAD_KEY_ROW0__SAI2_TX_DATA_0                       = IOMUX_PAD(0x0400, 0x00B8, 7, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW0__GPU_IDLE                             = IOMUX_PAD(0x0400, 0x00B8, 8, 0x0000, 0, 0),
+
+    MX6SX_PAD_KEY_ROW1__KPP_ROW_1                            = IOMUX_PAD(0x0404, 0x00BC, 0, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW1__USDHC4_VSELECT                       = IOMUX_PAD(0x0404, 0x00BC, 1, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW1__UART6_RX                             = IOMUX_PAD(0x0404, 0x00BC, 2, 0x0858, 3, 0),
+    MX6SX_PAD_KEY_ROW1__ECSPI1_SS0                           = IOMUX_PAD(0x0404, 0x00BC, 3, 0x071C, 0, 0),
+    MX6SX_PAD_KEY_ROW1__AUDMUX_AUD5_RXD                      = IOMUX_PAD(0x0404, 0x00BC, 4, 0x065C, 0, 0),
+    MX6SX_PAD_KEY_ROW1__GPIO2_IO_16                          = IOMUX_PAD(0x0404, 0x00BC, 5, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW1__WEIM_DATA_31                         = IOMUX_PAD(0x0404, 0x00BC, 6, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW1__SAI2_RX_DATA_0                       = IOMUX_PAD(0x0404, 0x00BC, 7, 0x080C, 0, 0),
+    MX6SX_PAD_KEY_ROW1__M4_NMI                               = IOMUX_PAD(0x0404, 0x00BC, 8, 0x0000, 0, 0),
+
+    MX6SX_PAD_KEY_ROW2__KPP_ROW_2                            = IOMUX_PAD(0x0408, 0x00C0, 0, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW2__USDHC4_WP                            = IOMUX_PAD(0x0408, 0x00C0, 1, 0x0878, 1, 0),
+    MX6SX_PAD_KEY_ROW2__UART5_CTS_B                          = IOMUX_PAD(0x0408, 0x00C0, 2, 0x084C, 3, 0),
+    MX6SX_PAD_KEY_ROW2__CAN1_RX                              = IOMUX_PAD(0x0408, 0x00C0, 3, 0x068C, 1, 0),
+    MX6SX_PAD_KEY_ROW2__CANFD_RX1                            = IOMUX_PAD(0x0408, 0x00C0, 4, 0x0694, 1, 0),
+    MX6SX_PAD_KEY_ROW2__GPIO2_IO_17                          = IOMUX_PAD(0x0408, 0x00C0, 5, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW2__WEIM_DATA_29                         = IOMUX_PAD(0x0408, 0x00C0, 6, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW2__ECSPI1_SS3                           = IOMUX_PAD(0x0408, 0x00C0, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_KEY_ROW3__KPP_ROW_3                            = IOMUX_PAD(0x040C, 0x00C4, 0, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW3__USDHC3_LCTL                          = IOMUX_PAD(0x040C, 0x00C4, 1, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW3__UART5_RX                             = IOMUX_PAD(0x040C, 0x00C4, 2, 0x0850, 3, 0),
+    MX6SX_PAD_KEY_ROW3__CAN2_RX                              = IOMUX_PAD(0x040C, 0x00C4, 3, 0x0690, 1, 0),
+    MX6SX_PAD_KEY_ROW3__CANFD_RX2                            = IOMUX_PAD(0x040C, 0x00C4, 4, 0x0698, 1, 0),
+    MX6SX_PAD_KEY_ROW3__GPIO2_IO_18                          = IOMUX_PAD(0x040C, 0x00C4, 5, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW3__WEIM_DTACK_B                         = IOMUX_PAD(0x040C, 0x00C4, 6, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW3__ECSPI1_SS1                           = IOMUX_PAD(0x040C, 0x00C4, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_KEY_ROW4__KPP_ROW_4                            = IOMUX_PAD(0x0410, 0x00C8, 0, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW4__ENET2_MDIO                           = IOMUX_PAD(0x0410, 0x00C8, 1, 0x0770, 3, 0),
+    MX6SX_PAD_KEY_ROW4__I2C3_SDA                             = IOMUX_PAD(0x0410, 0x00C8, IOMUX_CONFIG_SION | 2, 0x07BC, 2, 0),
+    MX6SX_PAD_KEY_ROW4__USDHC1_LCTL                          = IOMUX_PAD(0x0410, 0x00C8, 3, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW4__AUDMUX_AUD5_RXFS                     = IOMUX_PAD(0x0410, 0x00C8, 4, 0x0668, 0, 0),
+    MX6SX_PAD_KEY_ROW4__GPIO2_IO_19                          = IOMUX_PAD(0x0410, 0x00C8, 5, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW4__WEIM_ACLK_FREERUN                    = IOMUX_PAD(0x0410, 0x00C8, 6, 0x0000, 0, 0),
+    MX6SX_PAD_KEY_ROW4__SAI2_RX_SYNC                         = IOMUX_PAD(0x0410, 0x00C8, 7, 0x0810, 0, 0),
+
+    MX6SX_PAD_LCD1_CLK__LCDIF1_CLK                           = IOMUX_PAD(0x0414, 0x00CC, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_CLK__LCDIF1_WR_RWN                        = IOMUX_PAD(0x0414, 0x00CC, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_CLK__AUDMUX_AUD3_RXC                      = IOMUX_PAD(0x0414, 0x00CC, 2, 0x0634, 1, 0),
+    MX6SX_PAD_LCD1_CLK__ENET1_1588_EVENT2_IN                 = IOMUX_PAD(0x0414, 0x00CC, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_CLK__CSI1_DATA_16                         = IOMUX_PAD(0x0414, 0x00CC, 4, 0x06DC, 0, 0),
+    MX6SX_PAD_LCD1_CLK__GPIO3_IO_0                           = IOMUX_PAD(0x0414, 0x00CC, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_CLK__USDHC1_WP                            = IOMUX_PAD(0x0414, 0x00CC, 6, 0x0868, 0, 0),
+    MX6SX_PAD_LCD1_CLK__SIM_M_HADDR_16                       = IOMUX_PAD(0x0414, 0x00CC, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_CLK__VADC_TEST_0                          = IOMUX_PAD(0x0414, 0x00CC, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_CLK__MMDC_DEBUG_0                         = IOMUX_PAD(0x0414, 0x00CC, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA00__LCDIF1_DATA_0                     = IOMUX_PAD(0x0418, 0x00D0, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA00__WEIM_CS1_B                        = IOMUX_PAD(0x0418, 0x00D0, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA00__M4_TRACE_0                        = IOMUX_PAD(0x0418, 0x00D0, 2, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA00__KITTEN_TRACE_0                    = IOMUX_PAD(0x0418, 0x00D0, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA00__CSI1_DATA_20                      = IOMUX_PAD(0x0418, 0x00D0, 4, 0x06EC, 0, 0),
+    MX6SX_PAD_LCD1_DATA00__GPIO3_IO_1                        = IOMUX_PAD(0x0418, 0x00D0, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA00__SRC_BT_CFG_0                      = IOMUX_PAD(0x0418, 0x00D0, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA00__SIM_M_HADDR_21                    = IOMUX_PAD(0x0418, 0x00D0, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA00__VADC_TEST_5                       = IOMUX_PAD(0x0418, 0x00D0, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA00__MMDC_DEBUG_5                      = IOMUX_PAD(0x0418, 0x00D0, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA01__LCDIF1_DATA_1                     = IOMUX_PAD(0x041C, 0x00D4, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA01__WEIM_CS2_B                        = IOMUX_PAD(0x041C, 0x00D4, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA01__M4_TRACE_1                        = IOMUX_PAD(0x041C, 0x00D4, 2, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA01__KITTEN_TRACE_1                    = IOMUX_PAD(0x041C, 0x00D4, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA01__CSI1_DATA_21                      = IOMUX_PAD(0x041C, 0x00D4, 4, 0x06F0, 0, 0),
+    MX6SX_PAD_LCD1_DATA01__GPIO3_IO_2                        = IOMUX_PAD(0x041C, 0x00D4, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA01__SRC_BT_CFG_1                      = IOMUX_PAD(0x041C, 0x00D4, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA01__SIM_M_HADDR_22                    = IOMUX_PAD(0x041C, 0x00D4, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA01__VADC_TEST_6                       = IOMUX_PAD(0x041C, 0x00D4, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA01__MMDC_DEBUG_6                      = IOMUX_PAD(0x041C, 0x00D4, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA02__LCDIF1_DATA_2                     = IOMUX_PAD(0x0420, 0x00D8, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA02__WEIM_CS3_B                        = IOMUX_PAD(0x0420, 0x00D8, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA02__M4_TRACE_2                        = IOMUX_PAD(0x0420, 0x00D8, 2, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA02__KITTEN_TRACE_2                    = IOMUX_PAD(0x0420, 0x00D8, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA02__CSI1_DATA_22                      = IOMUX_PAD(0x0420, 0x00D8, 4, 0x06F4, 0, 0),
+    MX6SX_PAD_LCD1_DATA02__GPIO3_IO_3                        = IOMUX_PAD(0x0420, 0x00D8, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA02__SRC_BT_CFG_2                      = IOMUX_PAD(0x0420, 0x00D8, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA02__SIM_M_HADDR_23                    = IOMUX_PAD(0x0420, 0x00D8, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA02__VADC_TEST_7                       = IOMUX_PAD(0x0420, 0x00D8, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA02__MMDC_DEBUG_7                      = IOMUX_PAD(0x0420, 0x00D8, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA03__LCDIF1_DATA_3                     = IOMUX_PAD(0x0424, 0x00DC, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA03__WEIM_ADDR_24                      = IOMUX_PAD(0x0424, 0x00DC, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA03__M4_TRACE_3                        = IOMUX_PAD(0x0424, 0x00DC, 2, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA03__KITTEN_TRACE_3                    = IOMUX_PAD(0x0424, 0x00DC, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA03__CSI1_DATA_23                      = IOMUX_PAD(0x0424, 0x00DC, 4, 0x06F8, 0, 0),
+    MX6SX_PAD_LCD1_DATA03__GPIO3_IO_4                        = IOMUX_PAD(0x0424, 0x00DC, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA03__SRC_BT_CFG_3                      = IOMUX_PAD(0x0424, 0x00DC, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA03__SIM_M_HADDR_24                    = IOMUX_PAD(0x0424, 0x00DC, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA03__VADC_TEST_8                       = IOMUX_PAD(0x0424, 0x00DC, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA03__MMDC_DEBUG_8                      = IOMUX_PAD(0x0424, 0x00DC, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA04__LCDIF1_DATA_4                     = IOMUX_PAD(0x0428, 0x00E0, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA04__WEIM_ADDR_25                      = IOMUX_PAD(0x0428, 0x00E0, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA04__KITTEN_TRACE_4                    = IOMUX_PAD(0x0428, 0x00E0, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA04__CSI1_VSYNC                        = IOMUX_PAD(0x0428, 0x00E0, 4, 0x0708, 1, 0),
+    MX6SX_PAD_LCD1_DATA04__GPIO3_IO_5                        = IOMUX_PAD(0x0428, 0x00E0, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA04__SRC_BT_CFG_4                      = IOMUX_PAD(0x0428, 0x00E0, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA04__SIM_M_HADDR_25                    = IOMUX_PAD(0x0428, 0x00E0, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA04__VADC_TEST_9                       = IOMUX_PAD(0x0428, 0x00E0, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA04__MMDC_DEBUG_9                      = IOMUX_PAD(0x0428, 0x00E0, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA05__LCDIF1_DATA_5                     = IOMUX_PAD(0x042C, 0x00E4, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA05__WEIM_ADDR_26                      = IOMUX_PAD(0x042C, 0x00E4, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA05__KITTEN_TRACE_5                    = IOMUX_PAD(0x042C, 0x00E4, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA05__CSI1_HSYNC                        = IOMUX_PAD(0x042C, 0x00E4, 4, 0x0700, 1, 0),
+    MX6SX_PAD_LCD1_DATA05__GPIO3_IO_6                        = IOMUX_PAD(0x042C, 0x00E4, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA05__SRC_BT_CFG_5                      = IOMUX_PAD(0x042C, 0x00E4, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA05__SIM_M_HADDR_26                    = IOMUX_PAD(0x042C, 0x00E4, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA05__VADC_TEST_10                      = IOMUX_PAD(0x042C, 0x00E4, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA05__MMDC_DEBUG_10                     = IOMUX_PAD(0x042C, 0x00E4, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA06__LCDIF1_DATA_6                     = IOMUX_PAD(0x0430, 0x00E8, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA06__WEIM_EB_B_2                       = IOMUX_PAD(0x0430, 0x00E8, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA06__KITTEN_TRACE_6                    = IOMUX_PAD(0x0430, 0x00E8, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA06__CSI1_PIXCLK                       = IOMUX_PAD(0x0430, 0x00E8, 4, 0x0704, 1, 0),
+    MX6SX_PAD_LCD1_DATA06__GPIO3_IO_7                        = IOMUX_PAD(0x0430, 0x00E8, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA06__SRC_BT_CFG_6                      = IOMUX_PAD(0x0430, 0x00E8, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA06__SIM_M_HADDR_27                    = IOMUX_PAD(0x0430, 0x00E8, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA06__VADC_TEST_11                      = IOMUX_PAD(0x0430, 0x00E8, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA06__MMDC_DEBUG_11                     = IOMUX_PAD(0x0430, 0x00E8, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA07__LCDIF1_DATA_7                     = IOMUX_PAD(0x0434, 0x00EC, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA07__WEIM_EB_B_3                       = IOMUX_PAD(0x0434, 0x00EC, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA07__KITTEN_TRACE_7                    = IOMUX_PAD(0x0434, 0x00EC, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA07__CSI1_MCLK                         = IOMUX_PAD(0x0434, 0x00EC, 4, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA07__GPIO3_IO_8                        = IOMUX_PAD(0x0434, 0x00EC, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA07__SRC_BT_CFG_7                      = IOMUX_PAD(0x0434, 0x00EC, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA07__SIM_M_HADDR_28                    = IOMUX_PAD(0x0434, 0x00EC, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA07__VADC_TEST_12                      = IOMUX_PAD(0x0434, 0x00EC, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA07__MMDC_DEBUG_12                     = IOMUX_PAD(0x0434, 0x00EC, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA08__LCDIF1_DATA_8                     = IOMUX_PAD(0x0438, 0x00F0, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA08__WEIM_AD_8                         = IOMUX_PAD(0x0438, 0x00F0, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA08__KITTEN_TRACE_8                    = IOMUX_PAD(0x0438, 0x00F0, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA08__CSI1_DATA_9                       = IOMUX_PAD(0x0438, 0x00F0, 4, 0x06C4, 1, 0),
+    MX6SX_PAD_LCD1_DATA08__GPIO3_IO_9                        = IOMUX_PAD(0x0438, 0x00F0, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA08__SRC_BT_CFG_8                      = IOMUX_PAD(0x0438, 0x00F0, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA08__SIM_M_HADDR_29                    = IOMUX_PAD(0x0438, 0x00F0, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA08__VADC_TEST_13                      = IOMUX_PAD(0x0438, 0x00F0, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA08__MMDC_DEBUG_13                     = IOMUX_PAD(0x0438, 0x00F0, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA09__LCDIF1_DATA_9                     = IOMUX_PAD(0x043C, 0x00F4, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA09__WEIM_AD_9                         = IOMUX_PAD(0x043C, 0x00F4, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA09__KITTEN_TRACE_9                    = IOMUX_PAD(0x043C, 0x00F4, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA09__CSI1_DATA_8                       = IOMUX_PAD(0x043C, 0x00F4, 4, 0x06C0, 1, 0),
+    MX6SX_PAD_LCD1_DATA09__GPIO3_IO_10                       = IOMUX_PAD(0x043C, 0x00F4, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA09__SRC_BT_CFG_9                      = IOMUX_PAD(0x043C, 0x00F4, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA09__SIM_M_HADDR_30                    = IOMUX_PAD(0x043C, 0x00F4, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA09__VADC_TEST_14                      = IOMUX_PAD(0x043C, 0x00F4, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA09__MMDC_DEBUG_14                     = IOMUX_PAD(0x043C, 0x00F4, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA10__LCDIF1_DATA_10                    = IOMUX_PAD(0x0440, 0x00F8, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA10__WEIM_AD_10                        = IOMUX_PAD(0x0440, 0x00F8, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA10__KITTEN_TRACE_10                   = IOMUX_PAD(0x0440, 0x00F8, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA10__CSI1_DATA_7                       = IOMUX_PAD(0x0440, 0x00F8, 4, 0x06BC, 1, 0),
+    MX6SX_PAD_LCD1_DATA10__GPIO3_IO_11                       = IOMUX_PAD(0x0440, 0x00F8, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA10__SRC_BT_CFG_10                     = IOMUX_PAD(0x0440, 0x00F8, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA10__SIM_M_HADDR_31                    = IOMUX_PAD(0x0440, 0x00F8, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA10__VADC_TEST_15                      = IOMUX_PAD(0x0440, 0x00F8, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA10__MMDC_DEBUG_15                     = IOMUX_PAD(0x0440, 0x00F8, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA11__LCDIF1_DATA_11                    = IOMUX_PAD(0x0444, 0x00FC, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA11__WEIM_AD_11                        = IOMUX_PAD(0x0444, 0x00FC, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA11__KITTEN_TRACE_11                   = IOMUX_PAD(0x0444, 0x00FC, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA11__CSI1_DATA_6                       = IOMUX_PAD(0x0444, 0x00FC, 4, 0x06B8, 1, 0),
+    MX6SX_PAD_LCD1_DATA11__GPIO3_IO_12                       = IOMUX_PAD(0x0444, 0x00FC, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA11__SRC_BT_CFG_11                     = IOMUX_PAD(0x0444, 0x00FC, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA11__SIM_M_HBURST_0                    = IOMUX_PAD(0x0444, 0x00FC, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA11__VADC_TEST_16                      = IOMUX_PAD(0x0444, 0x00FC, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA11__MMDC_DEBUG_16                     = IOMUX_PAD(0x0444, 0x00FC, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA12__LCDIF1_DATA_12                    = IOMUX_PAD(0x0448, 0x0100, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA12__WEIM_AD_12                        = IOMUX_PAD(0x0448, 0x0100, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA12__KITTEN_TRACE_12                   = IOMUX_PAD(0x0448, 0x0100, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA12__CSI1_DATA_5                       = IOMUX_PAD(0x0448, 0x0100, 4, 0x06B4, 1, 0),
+    MX6SX_PAD_LCD1_DATA12__GPIO3_IO_13                       = IOMUX_PAD(0x0448, 0x0100, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA12__SRC_BT_CFG_12                     = IOMUX_PAD(0x0448, 0x0100, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA12__SIM_M_HBURST_1                    = IOMUX_PAD(0x0448, 0x0100, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA12__VADC_TEST_17                      = IOMUX_PAD(0x0448, 0x0100, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA12__MMDC_DEBUG_17                     = IOMUX_PAD(0x0448, 0x0100, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA13__LCDIF1_DATA_13                    = IOMUX_PAD(0x044C, 0x0104, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA13__WEIM_AD_13                        = IOMUX_PAD(0x044C, 0x0104, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA13__KITTEN_TRACE_13                   = IOMUX_PAD(0x044C, 0x0104, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA13__CSI1_DATA_4                       = IOMUX_PAD(0x044C, 0x0104, 4, 0x06B0, 1, 0),
+    MX6SX_PAD_LCD1_DATA13__GPIO3_IO_14                       = IOMUX_PAD(0x044C, 0x0104, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA13__SRC_BT_CFG_13                     = IOMUX_PAD(0x044C, 0x0104, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA13__SIM_M_HBURST_2                    = IOMUX_PAD(0x044C, 0x0104, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA13__VADC_TEST_18                      = IOMUX_PAD(0x044C, 0x0104, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA13__MMDC_DEBUG_18                     = IOMUX_PAD(0x044C, 0x0104, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA14__LCDIF1_DATA_14                    = IOMUX_PAD(0x0450, 0x0108, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA14__WEIM_AD_14                        = IOMUX_PAD(0x0450, 0x0108, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA14__KITTEN_TRACE_14                   = IOMUX_PAD(0x0450, 0x0108, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA14__CSI1_DATA_3                       = IOMUX_PAD(0x0450, 0x0108, 4, 0x06AC, 1, 0),
+    MX6SX_PAD_LCD1_DATA14__GPIO3_IO_15                       = IOMUX_PAD(0x0450, 0x0108, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA14__SRC_BT_CFG_14                     = IOMUX_PAD(0x0450, 0x0108, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA14__SIM_M_HMASTLOCK                   = IOMUX_PAD(0x0450, 0x0108, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA14__VADC_TEST_19                      = IOMUX_PAD(0x0450, 0x0108, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA14__MMDC_DEBUG_19                     = IOMUX_PAD(0x0450, 0x0108, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA15__LCDIF1_DATA_15                    = IOMUX_PAD(0x0454, 0x010C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA15__WEIM_AD_15                        = IOMUX_PAD(0x0454, 0x010C, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA15__KITTEN_TRACE_15                   = IOMUX_PAD(0x0454, 0x010C, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA15__CSI1_DATA_2                       = IOMUX_PAD(0x0454, 0x010C, 4, 0x06A8, 1, 0),
+    MX6SX_PAD_LCD1_DATA15__GPIO3_IO_16                       = IOMUX_PAD(0x0454, 0x010C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA15__SRC_BT_CFG_15                     = IOMUX_PAD(0x0454, 0x010C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA15__SIM_M_HPROT_0                     = IOMUX_PAD(0x0454, 0x010C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA15__VDEC_DEBUG_0                      = IOMUX_PAD(0x0454, 0x010C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA15__MMDC_DEBUG_20                     = IOMUX_PAD(0x0454, 0x010C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA16__LCDIF1_DATA_16                    = IOMUX_PAD(0x0458, 0x0110, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA16__WEIM_ADDR_16                      = IOMUX_PAD(0x0458, 0x0110, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA16__M4_TRACE_CLK                      = IOMUX_PAD(0x0458, 0x0110, 2, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA16__KITTEN_TRACE_CLK                  = IOMUX_PAD(0x0458, 0x0110, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA16__CSI1_DATA_1                       = IOMUX_PAD(0x0458, 0x0110, 4, 0x06A4, 0, 0),
+    MX6SX_PAD_LCD1_DATA16__GPIO3_IO_17                       = IOMUX_PAD(0x0458, 0x0110, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA16__SRC_BT_CFG_24                     = IOMUX_PAD(0x0458, 0x0110, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA16__SIM_M_HPROT_1                     = IOMUX_PAD(0x0458, 0x0110, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA16__VDEC_DEBUG_1                      = IOMUX_PAD(0x0458, 0x0110, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA16__MMDC_DEBUG_21                     = IOMUX_PAD(0x0458, 0x0110, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA17__LCDIF1_DATA_17                    = IOMUX_PAD(0x045C, 0x0114, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA17__WEIM_ADDR_17                      = IOMUX_PAD(0x045C, 0x0114, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA17__KITTEN_TRACE_CTL                  = IOMUX_PAD(0x045C, 0x0114, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA17__CSI1_DATA_0                       = IOMUX_PAD(0x045C, 0x0114, 4, 0x06A0, 0, 0),
+    MX6SX_PAD_LCD1_DATA17__GPIO3_IO_18                       = IOMUX_PAD(0x045C, 0x0114, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA17__SRC_BT_CFG_25                     = IOMUX_PAD(0x045C, 0x0114, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA17__SIM_M_HPROT_2                     = IOMUX_PAD(0x045C, 0x0114, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA17__VDEC_DEBUG_2                      = IOMUX_PAD(0x045C, 0x0114, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA17__MMDC_DEBUG_22                     = IOMUX_PAD(0x045C, 0x0114, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA18__LCDIF1_DATA_18                    = IOMUX_PAD(0x0460, 0x0118, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA18__WEIM_ADDR_18                      = IOMUX_PAD(0x0460, 0x0118, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA18__M4_EVENTO                         = IOMUX_PAD(0x0460, 0x0118, 2, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA18__KITTEN_EVENTO                     = IOMUX_PAD(0x0460, 0x0118, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA18__CSI1_DATA_15                      = IOMUX_PAD(0x0460, 0x0118, 4, 0x06D8, 0, 0),
+    MX6SX_PAD_LCD1_DATA18__GPIO3_IO_19                       = IOMUX_PAD(0x0460, 0x0118, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA18__SRC_BT_CFG_26                     = IOMUX_PAD(0x0460, 0x0118, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA18__SIM_M_HPROT_3                     = IOMUX_PAD(0x0460, 0x0118, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA18__VDEC_DEBUG_3                      = IOMUX_PAD(0x0460, 0x0118, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA18__MMDC_DEBUG_23                     = IOMUX_PAD(0x0460, 0x0118, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA19__LCDIF1_DATA_19                    = IOMUX_PAD(0x0464, 0x011C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA19__WEIM_ADDR_19                      = IOMUX_PAD(0x0464, 0x011C, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA19__M4_TRACE_SWO                      = IOMUX_PAD(0x0464, 0x011C, 2, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA19__CSI1_DATA_14                      = IOMUX_PAD(0x0464, 0x011C, 4, 0x06D4, 0, 0),
+    MX6SX_PAD_LCD1_DATA19__GPIO3_IO_20                       = IOMUX_PAD(0x0464, 0x011C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA19__SRC_BT_CFG_27                     = IOMUX_PAD(0x0464, 0x011C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA19__SIM_M_HREADYOUT                   = IOMUX_PAD(0x0464, 0x011C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA19__VDEC_DEBUG_4                      = IOMUX_PAD(0x0464, 0x011C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA19__MMDC_DEBUG_24                     = IOMUX_PAD(0x0464, 0x011C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA20__LCDIF1_DATA_20                    = IOMUX_PAD(0x0468, 0x0120, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA20__WEIM_ADDR_20                      = IOMUX_PAD(0x0468, 0x0120, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA20__PWM8_OUT                          = IOMUX_PAD(0x0468, 0x0120, 2, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA20__ENET1_1588_EVENT2_OUT             = IOMUX_PAD(0x0468, 0x0120, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA20__CSI1_DATA_13                      = IOMUX_PAD(0x0468, 0x0120, 4, 0x06D0, 0, 0),
+    MX6SX_PAD_LCD1_DATA20__GPIO3_IO_21                       = IOMUX_PAD(0x0468, 0x0120, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA20__SRC_BT_CFG_28                     = IOMUX_PAD(0x0468, 0x0120, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA20__SIM_M_HRESP                       = IOMUX_PAD(0x0468, 0x0120, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA20__VDEC_DEBUG_5                      = IOMUX_PAD(0x0468, 0x0120, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA20__MMDC_DEBUG_25                     = IOMUX_PAD(0x0468, 0x0120, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA21__LCDIF1_DATA_21                    = IOMUX_PAD(0x046C, 0x0124, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA21__WEIM_ADDR_21                      = IOMUX_PAD(0x046C, 0x0124, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA21__PWM7_OUT                          = IOMUX_PAD(0x046C, 0x0124, 2, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA21__ENET1_1588_EVENT3_OUT             = IOMUX_PAD(0x046C, 0x0124, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA21__CSI1_DATA_12                      = IOMUX_PAD(0x046C, 0x0124, 4, 0x06CC, 0, 0),
+    MX6SX_PAD_LCD1_DATA21__GPIO3_IO_22                       = IOMUX_PAD(0x046C, 0x0124, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA21__SRC_BT_CFG_29                     = IOMUX_PAD(0x046C, 0x0124, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA21__SIM_M_HSIZE_0                     = IOMUX_PAD(0x046C, 0x0124, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA21__VDEC_DEBUG_6                      = IOMUX_PAD(0x046C, 0x0124, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA21__MMDC_DEBUG_26                     = IOMUX_PAD(0x046C, 0x0124, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA22__LCDIF1_DATA_22                    = IOMUX_PAD(0x0470, 0x0128, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA22__WEIM_ADDR_22                      = IOMUX_PAD(0x0470, 0x0128, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA22__PWM6_OUT                          = IOMUX_PAD(0x0470, 0x0128, 2, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA22__ENET2_1588_EVENT2_OUT             = IOMUX_PAD(0x0470, 0x0128, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA22__CSI1_DATA_11                      = IOMUX_PAD(0x0470, 0x0128, 4, 0x06C8, 0, 0),
+    MX6SX_PAD_LCD1_DATA22__GPIO3_IO_23                       = IOMUX_PAD(0x0470, 0x0128, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA22__SRC_BT_CFG_30                     = IOMUX_PAD(0x0470, 0x0128, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA22__SIM_M_HSIZE_1                     = IOMUX_PAD(0x0470, 0x0128, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA22__VDEC_DEBUG_7                      = IOMUX_PAD(0x0470, 0x0128, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA22__MMDC_DEBUG_27                     = IOMUX_PAD(0x0470, 0x0128, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_DATA23__LCDIF1_DATA_23                    = IOMUX_PAD(0x0474, 0x012C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA23__WEIM_ADDR_23                      = IOMUX_PAD(0x0474, 0x012C, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA23__PWM5_OUT                          = IOMUX_PAD(0x0474, 0x012C, 2, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA23__ENET2_1588_EVENT3_OUT             = IOMUX_PAD(0x0474, 0x012C, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA23__CSI1_DATA_10                      = IOMUX_PAD(0x0474, 0x012C, 4, 0x06FC, 0, 0),
+    MX6SX_PAD_LCD1_DATA23__GPIO3_IO_24                       = IOMUX_PAD(0x0474, 0x012C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA23__SRC_BT_CFG_31                     = IOMUX_PAD(0x0474, 0x012C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA23__SIM_M_HSIZE_2                     = IOMUX_PAD(0x0474, 0x012C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA23__VDEC_DEBUG_8                      = IOMUX_PAD(0x0474, 0x012C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_DATA23__MMDC_DEBUG_28                     = IOMUX_PAD(0x0474, 0x012C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_ENABLE__LCDIF1_ENABLE                     = IOMUX_PAD(0x0478, 0x0130, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_ENABLE__LCDIF1_RD_E                       = IOMUX_PAD(0x0478, 0x0130, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_ENABLE__AUDMUX_AUD3_TXC                   = IOMUX_PAD(0x0478, 0x0130, 2, 0x063C, 1, 0),
+    MX6SX_PAD_LCD1_ENABLE__ENET1_1588_EVENT3_IN              = IOMUX_PAD(0x0478, 0x0130, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_ENABLE__CSI1_DATA_17                      = IOMUX_PAD(0x0478, 0x0130, 4, 0x06E0, 0, 0),
+    MX6SX_PAD_LCD1_ENABLE__GPIO3_IO_25                       = IOMUX_PAD(0x0478, 0x0130, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_ENABLE__USDHC1_CD_B                       = IOMUX_PAD(0x0478, 0x0130, 6, 0x0864, 0, 0),
+    MX6SX_PAD_LCD1_ENABLE__SIM_M_HADDR_17                    = IOMUX_PAD(0x0478, 0x0130, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_ENABLE__VADC_TEST_1                       = IOMUX_PAD(0x0478, 0x0130, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_ENABLE__MMDC_DEBUG_1                      = IOMUX_PAD(0x0478, 0x0130, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_HSYNC__LCDIF1_HSYNC                       = IOMUX_PAD(0x047C, 0x0134, 0, 0x07E0, 0, 0),
+    MX6SX_PAD_LCD1_HSYNC__LCDIF1_RS                          = IOMUX_PAD(0x047C, 0x0134, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_HSYNC__AUDMUX_AUD3_TXD                    = IOMUX_PAD(0x047C, 0x0134, 2, 0x0630, 1, 0),
+    MX6SX_PAD_LCD1_HSYNC__ENET2_1588_EVENT2_IN               = IOMUX_PAD(0x047C, 0x0134, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_HSYNC__CSI1_DATA_18                       = IOMUX_PAD(0x047C, 0x0134, 4, 0x06E4, 0, 0),
+    MX6SX_PAD_LCD1_HSYNC__GPIO3_IO_26                        = IOMUX_PAD(0x047C, 0x0134, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_HSYNC__USDHC2_WP                          = IOMUX_PAD(0x047C, 0x0134, 6, 0x0870, 0, 0),
+    MX6SX_PAD_LCD1_HSYNC__SIM_M_HADDR_18                     = IOMUX_PAD(0x047C, 0x0134, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_HSYNC__VADC_TEST_2                        = IOMUX_PAD(0x047C, 0x0134, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_HSYNC__MMDC_DEBUG_2                       = IOMUX_PAD(0x047C, 0x0134, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_RESET__LCDIF1_RESET                       = IOMUX_PAD(0x0480, 0x0138, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_RESET__LCDIF1_CS                          = IOMUX_PAD(0x0480, 0x0138, 1, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_RESET__AUDMUX_AUD3_RXD                    = IOMUX_PAD(0x0480, 0x0138, 2, 0x062C, 1, 0),
+    MX6SX_PAD_LCD1_RESET__KITTEN_EVENTI                      = IOMUX_PAD(0x0480, 0x0138, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_RESET__M4_EVENTI                          = IOMUX_PAD(0x0480, 0x0138, 4, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_RESET__GPIO3_IO_27                        = IOMUX_PAD(0x0480, 0x0138, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_RESET__CCM_PMIC_RDY                       = IOMUX_PAD(0x0480, 0x0138, 6, 0x069C, 0, 0),
+    MX6SX_PAD_LCD1_RESET__SIM_M_HADDR_20                     = IOMUX_PAD(0x0480, 0x0138, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_RESET__VADC_TEST_4                        = IOMUX_PAD(0x0480, 0x0138, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_RESET__MMDC_DEBUG_4                       = IOMUX_PAD(0x0480, 0x0138, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_LCD1_VSYNC__LCDIF1_VSYNC                       = IOMUX_PAD(0x0484, 0x013C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_VSYNC__LCDIF1_BUSY                        = IOMUX_PAD(0x0484, 0x013C, 1, 0x07E0, 1, 0),
+    MX6SX_PAD_LCD1_VSYNC__AUDMUX_AUD3_TXFS                   = IOMUX_PAD(0x0484, 0x013C, 2, 0x0640, 1, 0),
+    MX6SX_PAD_LCD1_VSYNC__ENET2_1588_EVENT3_IN               = IOMUX_PAD(0x0484, 0x013C, 3, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_VSYNC__CSI1_DATA_19                       = IOMUX_PAD(0x0484, 0x013C, 4, 0x06E8, 0, 0),
+    MX6SX_PAD_LCD1_VSYNC__GPIO3_IO_28                        = IOMUX_PAD(0x0484, 0x013C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_VSYNC__USDHC2_CD_B                        = IOMUX_PAD(0x0484, 0x013C, 6, 0x086C, 0, 0),
+    MX6SX_PAD_LCD1_VSYNC__SIM_M_HADDR_19                     = IOMUX_PAD(0x0484, 0x013C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_VSYNC__VADC_TEST_3                        = IOMUX_PAD(0x0484, 0x013C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_LCD1_VSYNC__MMDC_DEBUG_3                       = IOMUX_PAD(0x0484, 0x013C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_NAND_ALE__RAWNAND_ALE                          = IOMUX_PAD(0x0488, 0x0140, 0, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_ALE__I2C3_SDA                             = IOMUX_PAD(0x0488, 0x0140, IOMUX_CONFIG_SION | 1, 0x07BC, 0, 0),
+    MX6SX_PAD_NAND_ALE__QSPI2_A_SS0_B                        = IOMUX_PAD(0x0488, 0x0140, 2, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_ALE__ECSPI2_SS0                           = IOMUX_PAD(0x0488, 0x0140, 3, 0x072C, 0, 0),
+    MX6SX_PAD_NAND_ALE__ESAI_TX3_RX2                         = IOMUX_PAD(0x0488, 0x0140, 4, 0x079C, 0, 0),
+    MX6SX_PAD_NAND_ALE__GPIO4_IO_0                           = IOMUX_PAD(0x0488, 0x0140, 5, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_ALE__WEIM_CS0_B                           = IOMUX_PAD(0x0488, 0x0140, 6, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_ALE__TPSMP_HDATA_0                        = IOMUX_PAD(0x0488, 0x0140, 7, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_ALE__ANATOP_USBPHY1_TSTI_TX_EN            = IOMUX_PAD(0x0488, 0x0140, 8, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_ALE__SDMA_DEBUG_PC_12                     = IOMUX_PAD(0x0488, 0x0140, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_NAND_CE0_B__RAWNAND_CE0_B                      = IOMUX_PAD(0x048C, 0x0144, 0, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CE0_B__USDHC2_VSELECT                     = IOMUX_PAD(0x048C, 0x0144, 1, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CE0_B__QSPI2_A_DATA_2                     = IOMUX_PAD(0x048C, 0x0144, 2, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CE0_B__AUDMUX_AUD4_TXC                    = IOMUX_PAD(0x048C, 0x0144, 3, 0x0654, 0, 0),
+    MX6SX_PAD_NAND_CE0_B__ESAI_TX_CLK                        = IOMUX_PAD(0x048C, 0x0144, 4, 0x078C, 0, 0),
+    MX6SX_PAD_NAND_CE0_B__GPIO4_IO_1                         = IOMUX_PAD(0x048C, 0x0144, 5, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CE0_B__WEIM_LBA_B                         = IOMUX_PAD(0x048C, 0x0144, 6, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CE0_B__TPSMP_HDATA_3                      = IOMUX_PAD(0x048C, 0x0144, 7, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CE0_B__ANATOP_USBPHY1_TSTI_TX_HIZ         = IOMUX_PAD(0x048C, 0x0144, 8, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CE0_B__SDMA_DEBUG_PC_9                    = IOMUX_PAD(0x048C, 0x0144, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_NAND_CE1_B__RAWNAND_CE1_B                      = IOMUX_PAD(0x0490, 0x0148, 0, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CE1_B__USDHC3_RESET_B                     = IOMUX_PAD(0x0490, 0x0148, 1, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CE1_B__QSPI2_A_DATA_3                     = IOMUX_PAD(0x0490, 0x0148, 2, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CE1_B__AUDMUX_AUD4_TXD                    = IOMUX_PAD(0x0490, 0x0148, 3, 0x0648, 0, 0),
+    MX6SX_PAD_NAND_CE1_B__ESAI_TX0                           = IOMUX_PAD(0x0490, 0x0148, 4, 0x0790, 0, 0),
+    MX6SX_PAD_NAND_CE1_B__GPIO4_IO_2                         = IOMUX_PAD(0x0490, 0x0148, 5, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CE1_B__WEIM_OE                            = IOMUX_PAD(0x0490, 0x0148, 6, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CE1_B__TPSMP_HDATA_4                      = IOMUX_PAD(0x0490, 0x0148, 7, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CE1_B__ANATOP_USBPHY1_TSTI_TX_LS_MODE     = IOMUX_PAD(0x0490, 0x0148, 8, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CE1_B__SDMA_DEBUG_PC_8                    = IOMUX_PAD(0x0490, 0x0148, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_NAND_CLE__RAWNAND_CLE                          = IOMUX_PAD(0x0494, 0x014C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CLE__I2C3_SCL                             = IOMUX_PAD(0x0494, 0x014C, IOMUX_CONFIG_SION | 1, 0x07B8, 0, 0),
+    MX6SX_PAD_NAND_CLE__QSPI2_A_SCLK                         = IOMUX_PAD(0x0494, 0x014C, 2, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CLE__ECSPI2_SCLK                          = IOMUX_PAD(0x0494, 0x014C, 3, 0x0720, 0, 0),
+    MX6SX_PAD_NAND_CLE__ESAI_TX2_RX3                         = IOMUX_PAD(0x0494, 0x014C, 4, 0x0798, 0, 0),
+    MX6SX_PAD_NAND_CLE__GPIO4_IO_3                           = IOMUX_PAD(0x0494, 0x014C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CLE__WEIM_BCLK                            = IOMUX_PAD(0x0494, 0x014C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CLE__TPSMP_CLK                            = IOMUX_PAD(0x0494, 0x014C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CLE__ANATOP_USBPHY1_TSTI_TX_DP            = IOMUX_PAD(0x0494, 0x014C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_CLE__SDMA_DEBUG_PC_13                     = IOMUX_PAD(0x0494, 0x014C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_NAND_DATA00__RAWNAND_DATA00                    = IOMUX_PAD(0x0498, 0x0150, 0, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA00__USDHC1_DATA4                      = IOMUX_PAD(0x0498, 0x0150, 1, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA00__QSPI2_B_DATA_1                    = IOMUX_PAD(0x0498, 0x0150, 2, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA00__ECSPI5_MISO                       = IOMUX_PAD(0x0498, 0x0150, 3, 0x0754, 0, 0),
+    MX6SX_PAD_NAND_DATA00__ESAI_RX_CLK                       = IOMUX_PAD(0x0498, 0x0150, 4, 0x0788, 0, 0),
+    MX6SX_PAD_NAND_DATA00__GPIO4_IO_4                        = IOMUX_PAD(0x0498, 0x0150, 5, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA00__WEIM_AD_0                         = IOMUX_PAD(0x0498, 0x0150, 6, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA00__TPSMP_HDATA_7                     = IOMUX_PAD(0x0498, 0x0150, 7, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA00__ANATOP_USBPHY1_TSTO_RX_DISCON_DET = IOMUX_PAD(0x0498, 0x0150, 8, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA00__SDMA_DEBUG_EVT_CHN_LINES_5        = IOMUX_PAD(0x0498, 0x0150, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_NAND_DATA01__RAWNAND_DATA01                    = IOMUX_PAD(0x049C, 0x0154, 0, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA01__USDHC1_DATA5                      = IOMUX_PAD(0x049C, 0x0154, 1, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA01__QSPI2_B_DATA_0                    = IOMUX_PAD(0x049C, 0x0154, 2, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA01__ECSPI5_MOSI                       = IOMUX_PAD(0x049C, 0x0154, 3, 0x0758, 0, 0),
+    MX6SX_PAD_NAND_DATA01__ESAI_RX_FS                        = IOMUX_PAD(0x049C, 0x0154, 4, 0x0778, 0, 0),
+    MX6SX_PAD_NAND_DATA01__GPIO4_IO_5                        = IOMUX_PAD(0x049C, 0x0154, 5, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA01__WEIM_AD_1                         = IOMUX_PAD(0x049C, 0x0154, 6, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA01__TPSMP_HDATA_8                     = IOMUX_PAD(0x049C, 0x0154, 7, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA01__ANATOP_USBPHY1_TSTO_RX_HS_RXD     = IOMUX_PAD(0x049C, 0x0154, 8, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA01__SDMA_DEBUG_EVT_CHN_LINES_4        = IOMUX_PAD(0x049C, 0x0154, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_NAND_DATA02__RAWNAND_DATA02                    = IOMUX_PAD(0x04A0, 0x0158, 0, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA02__USDHC1_DATA6                      = IOMUX_PAD(0x04A0, 0x0158, 1, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA02__QSPI2_B_SCLK                      = IOMUX_PAD(0x04A0, 0x0158, 2, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA02__ECSPI5_SCLK                       = IOMUX_PAD(0x04A0, 0x0158, 3, 0x0750, 0, 0),
+    MX6SX_PAD_NAND_DATA02__ESAI_TX_HF_CLK                    = IOMUX_PAD(0x04A0, 0x0158, 4, 0x0784, 0, 0),
+    MX6SX_PAD_NAND_DATA02__GPIO4_IO_6                        = IOMUX_PAD(0x04A0, 0x0158, 5, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA02__WEIM_AD_2                         = IOMUX_PAD(0x04A0, 0x0158, 6, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA02__TPSMP_HDATA_9                     = IOMUX_PAD(0x04A0, 0x0158, 7, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA02__ANATOP_USBPHY2_TSTO_PLL_CLK20DIV  = IOMUX_PAD(0x04A0, 0x0158, 8, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA02__SDMA_DEBUG_EVT_CHN_LINES_3        = IOMUX_PAD(0x04A0, 0x0158, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_NAND_DATA03__RAWNAND_DATA03                    = IOMUX_PAD(0x04A4, 0x015C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA03__USDHC1_DATA7                      = IOMUX_PAD(0x04A4, 0x015C, 1, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA03__QSPI2_B_SS0_B                     = IOMUX_PAD(0x04A4, 0x015C, 2, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA03__ECSPI5_SS0                        = IOMUX_PAD(0x04A4, 0x015C, 3, 0x075C, 0, 0),
+    MX6SX_PAD_NAND_DATA03__ESAI_RX_HF_CLK                    = IOMUX_PAD(0x04A4, 0x015C, 4, 0x0780, 0, 0),
+    MX6SX_PAD_NAND_DATA03__GPIO4_IO_7                        = IOMUX_PAD(0x04A4, 0x015C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA03__WEIM_AD_3                         = IOMUX_PAD(0x04A4, 0x015C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA03__TPSMP_HDATA_10                    = IOMUX_PAD(0x04A4, 0x015C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA03__ANATOP_USBPHY1_TSTO_RX_SQUELCH    = IOMUX_PAD(0x04A4, 0x015C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA03__SDMA_DEBUG_EVT_CHN_LINES_6        = IOMUX_PAD(0x04A4, 0x015C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_NAND_DATA04__RAWNAND_DATA04                    = IOMUX_PAD(0x04A8, 0x0160, 0, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA04__USDHC2_DATA4                      = IOMUX_PAD(0x04A8, 0x0160, 1, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA04__QSPI2_B_SS1_B                     = IOMUX_PAD(0x04A8, 0x0160, 2, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA04__UART3_RTS_B                       = IOMUX_PAD(0x04A8, 0x0160, 3, 0x083C, 0, 0),
+    MX6SX_PAD_NAND_DATA04__AUDMUX_AUD4_RXFS                  = IOMUX_PAD(0x04A8, 0x0160, 4, 0x0650, 0, 0),
+    MX6SX_PAD_NAND_DATA04__GPIO4_IO_8                        = IOMUX_PAD(0x04A8, 0x0160, 5, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA04__WEIM_AD_4                         = IOMUX_PAD(0x04A8, 0x0160, 6, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA04__TPSMP_HDATA_11                    = IOMUX_PAD(0x04A8, 0x0160, 7, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA04__ANATOP_USBPHY2_TSTO_RX_SQUELCH    = IOMUX_PAD(0x04A8, 0x0160, 8, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA04__SDMA_DEBUG_CORE_STATE_0           = IOMUX_PAD(0x04A8, 0x0160, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_NAND_DATA05__RAWNAND_DATA05                    = IOMUX_PAD(0x04AC, 0x0164, 0, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA05__USDHC2_DATA5                      = IOMUX_PAD(0x04AC, 0x0164, 1, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA05__QSPI2_B_DQS                       = IOMUX_PAD(0x04AC, 0x0164, 2, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA05__UART3_CTS_B                       = IOMUX_PAD(0x04AC, 0x0164, 3, 0x083C, 1, 0),
+    MX6SX_PAD_NAND_DATA05__AUDMUX_AUD4_RXC                   = IOMUX_PAD(0x04AC, 0x0164, 4, 0x064C, 0, 0),
+    MX6SX_PAD_NAND_DATA05__GPIO4_IO_9                        = IOMUX_PAD(0x04AC, 0x0164, 5, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA05__WEIM_AD_5                         = IOMUX_PAD(0x04AC, 0x0164, 6, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA05__TPSMP_HDATA_12                    = IOMUX_PAD(0x04AC, 0x0164, 7, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA05__ANATOP_USBPHY2_TSTO_RX_DISCON_DET = IOMUX_PAD(0x04AC, 0x0164, 8, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA05__SDMA_DEBUG_CORE_STATE_1           = IOMUX_PAD(0x04AC, 0x0164, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_NAND_DATA06__RAWNAND_DATA06                    = IOMUX_PAD(0x04B0, 0x0168, 0, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA06__USDHC2_DATA6                      = IOMUX_PAD(0x04B0, 0x0168, 1, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA06__QSPI2_A_SS1_B                     = IOMUX_PAD(0x04B0, 0x0168, 2, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA06__UART3_RX                          = IOMUX_PAD(0x04B0, 0x0168, 3, 0x0840, 0, 0),
+    MX6SX_PAD_NAND_DATA06__PWM3_OUT                          = IOMUX_PAD(0x04B0, 0x0168, 4, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA06__GPIO4_IO_10                       = IOMUX_PAD(0x04B0, 0x0168, 5, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA06__WEIM_AD_6                         = IOMUX_PAD(0x04B0, 0x0168, 6, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA06__TPSMP_HDATA_13                    = IOMUX_PAD(0x04B0, 0x0168, 7, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA06__ANATOP_USBPHY2_TSTO_RX_FS_RXD     = IOMUX_PAD(0x04B0, 0x0168, 8, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA06__SDMA_DEBUG_CORE_STATE_2           = IOMUX_PAD(0x04B0, 0x0168, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_NAND_DATA07__RAWNAND_DATA07                    = IOMUX_PAD(0x04B4, 0x016C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA07__USDHC2_DATA7                      = IOMUX_PAD(0x04B4, 0x016C, 1, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA07__QSPI2_A_DQS                       = IOMUX_PAD(0x04B4, 0x016C, 2, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA07__UART3_TX                          = IOMUX_PAD(0x04B4, 0x016C, 3, 0x0840, 1, 0),
+    MX6SX_PAD_NAND_DATA07__PWM4_OUT                          = IOMUX_PAD(0x04B4, 0x016C, 4, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA07__GPIO4_IO_11                       = IOMUX_PAD(0x04B4, 0x016C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA07__WEIM_AD_7                         = IOMUX_PAD(0x04B4, 0x016C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA07__TPSMP_HDATA_14                    = IOMUX_PAD(0x04B4, 0x016C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA07__ANATOP_USBPHY1_TSTO_RX_FS_RXD     = IOMUX_PAD(0x04B4, 0x016C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_DATA07__SDMA_DEBUG_CORE_STATE_3           = IOMUX_PAD(0x04B4, 0x016C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_NAND_RE_B__RAWNAND_RE_B                        = IOMUX_PAD(0x04B8, 0x0170, 0, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_RE_B__USDHC2_RESET_B                      = IOMUX_PAD(0x04B8, 0x0170, 1, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_RE_B__QSPI2_B_DATA_3                      = IOMUX_PAD(0x04B8, 0x0170, 2, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_RE_B__AUDMUX_AUD4_TXFS                    = IOMUX_PAD(0x04B8, 0x0170, 3, 0x0658, 0, 0),
+    MX6SX_PAD_NAND_RE_B__ESAI_TX_FS                          = IOMUX_PAD(0x04B8, 0x0170, 4, 0x077C, 0, 0),
+    MX6SX_PAD_NAND_RE_B__GPIO4_IO_12                         = IOMUX_PAD(0x04B8, 0x0170, 5, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_RE_B__WEIM_RW                             = IOMUX_PAD(0x04B8, 0x0170, 6, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_RE_B__TPSMP_HDATA_5                       = IOMUX_PAD(0x04B8, 0x0170, 7, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_RE_B__ANATOP_USBPHY2_TSTO_RX_HS_RXD       = IOMUX_PAD(0x04B8, 0x0170, 8, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_RE_B__SDMA_DEBUG_PC_7                     = IOMUX_PAD(0x04B8, 0x0170, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_NAND_READY_B__RAWNAND_READY_B                  = IOMUX_PAD(0x04BC, 0x0174, 0, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_READY_B__USDHC1_VSELECT                   = IOMUX_PAD(0x04BC, 0x0174, 1, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_READY_B__QSPI2_A_DATA_1                   = IOMUX_PAD(0x04BC, 0x0174, 2, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_READY_B__ECSPI2_MISO                      = IOMUX_PAD(0x04BC, 0x0174, 3, 0x0724, 0, 0),
+    MX6SX_PAD_NAND_READY_B__ESAI_TX1                         = IOMUX_PAD(0x04BC, 0x0174, 4, 0x0794, 0, 0),
+    MX6SX_PAD_NAND_READY_B__GPIO4_IO_13                      = IOMUX_PAD(0x04BC, 0x0174, 5, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_READY_B__WEIM_EB_B_1                      = IOMUX_PAD(0x04BC, 0x0174, 6, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_READY_B__TPSMP_HDATA_2                    = IOMUX_PAD(0x04BC, 0x0174, 7, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_READY_B__ANATOP_USBPHY1_TSTI_TX_DN        = IOMUX_PAD(0x04BC, 0x0174, 8, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_READY_B__SDMA_DEBUG_PC_10                 = IOMUX_PAD(0x04BC, 0x0174, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_NAND_WE_B__RAWNAND_WE_B                        = IOMUX_PAD(0x04C0, 0x0178, 0, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_WE_B__USDHC4_VSELECT                      = IOMUX_PAD(0x04C0, 0x0178, 1, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_WE_B__QSPI2_B_DATA_2                      = IOMUX_PAD(0x04C0, 0x0178, 2, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_WE_B__AUDMUX_AUD4_RXD                     = IOMUX_PAD(0x04C0, 0x0178, 3, 0x0644, 0, 0),
+    MX6SX_PAD_NAND_WE_B__ESAI_TX5_RX0                        = IOMUX_PAD(0x04C0, 0x0178, 4, 0x07A4, 0, 0),
+    MX6SX_PAD_NAND_WE_B__GPIO4_IO_14                         = IOMUX_PAD(0x04C0, 0x0178, 5, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_WE_B__WEIM_WAIT                           = IOMUX_PAD(0x04C0, 0x0178, 6, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_WE_B__TPSMP_HDATA_6                       = IOMUX_PAD(0x04C0, 0x0178, 7, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_WE_B__ANATOP_USBPHY1_TSTO_PLL_CLK20DIV    = IOMUX_PAD(0x04C0, 0x0178, 8, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_WE_B__SDMA_DEBUG_PC_6                     = IOMUX_PAD(0x04C0, 0x0178, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_NAND_WP_B__RAWNAND_WP_B                        = IOMUX_PAD(0x04C4, 0x017C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_WP_B__USDHC1_RESET_B                      = IOMUX_PAD(0x04C4, 0x017C, 1, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_WP_B__QSPI2_A_DATA_0                      = IOMUX_PAD(0x04C4, 0x017C, 2, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_WP_B__ECSPI2_MOSI                         = IOMUX_PAD(0x04C4, 0x017C, 3, 0x0728, 0, 0),
+    MX6SX_PAD_NAND_WP_B__ESAI_TX4_RX1                        = IOMUX_PAD(0x04C4, 0x017C, 4, 0x07A0, 0, 0),
+    MX6SX_PAD_NAND_WP_B__GPIO4_IO_15                         = IOMUX_PAD(0x04C4, 0x017C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_WP_B__WEIM_EB_B_0                         = IOMUX_PAD(0x04C4, 0x017C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_WP_B__TPSMP_HDATA_1                       = IOMUX_PAD(0x04C4, 0x017C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_WP_B__ANATOP_USBPHY1_TSTI_TX_HS_MODE      = IOMUX_PAD(0x04C4, 0x017C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_NAND_WP_B__SDMA_DEBUG_PC_11                    = IOMUX_PAD(0x04C4, 0x017C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_QSPI1A_DATA0__QSPI1_A_DATA_0                   = IOMUX_PAD(0x04C8, 0x0180, 0, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA0__USB_OTG2_OC                      = IOMUX_PAD(0x04C8, 0x0180, 1, 0x085C, 2, 0),
+    MX6SX_PAD_QSPI1A_DATA0__ECSPI1_MOSI                      = IOMUX_PAD(0x04C8, 0x0180, 2, 0x0718, 1, 0),
+    MX6SX_PAD_QSPI1A_DATA0__ESAI_TX4_RX1                     = IOMUX_PAD(0x04C8, 0x0180, 3, 0x07A0, 2, 0),
+    MX6SX_PAD_QSPI1A_DATA0__CSI1_DATA_14                     = IOMUX_PAD(0x04C8, 0x0180, 4, 0x06D4, 1, 0),
+    MX6SX_PAD_QSPI1A_DATA0__GPIO4_IO_16                      = IOMUX_PAD(0x04C8, 0x0180, 5, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA0__WEIM_DATA_6                      = IOMUX_PAD(0x04C8, 0x0180, 6, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA0__SIM_M_HADDR_3                    = IOMUX_PAD(0x04C8, 0x0180, 7, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA0__SDMA_DEBUG_BUS_DEVICE_3          = IOMUX_PAD(0x04C8, 0x0180, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_QSPI1A_DATA1__QSPI1_A_DATA_1                   = IOMUX_PAD(0x04CC, 0x0184, 0, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA1__ANATOP_OTG1_ID                   = IOMUX_PAD(0x04CC, 0x0184, 1, 0x0624, 2, 0),
+    MX6SX_PAD_QSPI1A_DATA1__ECSPI1_MISO                      = IOMUX_PAD(0x04CC, 0x0184, 2, 0x0714, 1, 0),
+    MX6SX_PAD_QSPI1A_DATA1__ESAI_TX1                         = IOMUX_PAD(0x04CC, 0x0184, 3, 0x0794, 2, 0),
+    MX6SX_PAD_QSPI1A_DATA1__CSI1_DATA_13                     = IOMUX_PAD(0x04CC, 0x0184, 4, 0x06D0, 1, 0),
+    MX6SX_PAD_QSPI1A_DATA1__GPIO4_IO_17                      = IOMUX_PAD(0x04CC, 0x0184, 5, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA1__WEIM_DATA_5                      = IOMUX_PAD(0x04CC, 0x0184, 6, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA1__SIM_M_HADDR_4                    = IOMUX_PAD(0x04CC, 0x0184, 7, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA1__SDMA_DEBUG_PC_0                  = IOMUX_PAD(0x04CC, 0x0184, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_QSPI1A_DATA2__QSPI1_A_DATA_2                   = IOMUX_PAD(0x04D0, 0x0188, 0, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA2__USB_OTG1_PWR                     = IOMUX_PAD(0x04D0, 0x0188, 1, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA2__ECSPI5_SS1                       = IOMUX_PAD(0x04D0, 0x0188, 2, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA2__ESAI_TX_CLK                      = IOMUX_PAD(0x04D0, 0x0188, 3, 0x078C, 2, 0),
+    MX6SX_PAD_QSPI1A_DATA2__CSI1_DATA_12                     = IOMUX_PAD(0x04D0, 0x0188, 4, 0x06CC, 1, 0),
+    MX6SX_PAD_QSPI1A_DATA2__GPIO4_IO_18                      = IOMUX_PAD(0x04D0, 0x0188, 5, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA2__WEIM_DATA_4                      = IOMUX_PAD(0x04D0, 0x0188, 6, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA2__SIM_M_HADDR_6                    = IOMUX_PAD(0x04D0, 0x0188, 7, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA2__SDMA_DEBUG_PC_1                  = IOMUX_PAD(0x04D0, 0x0188, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_QSPI1A_DATA3__QSPI1_A_DATA_3                   = IOMUX_PAD(0x04D4, 0x018C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA3__USB_OTG1_OC                      = IOMUX_PAD(0x04D4, 0x018C, 1, 0x0860, 2, 0),
+    MX6SX_PAD_QSPI1A_DATA3__ECSPI5_SS2                       = IOMUX_PAD(0x04D4, 0x018C, 2, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA3__ESAI_TX0                         = IOMUX_PAD(0x04D4, 0x018C, 3, 0x0790, 2, 0),
+    MX6SX_PAD_QSPI1A_DATA3__CSI1_DATA_11                     = IOMUX_PAD(0x04D4, 0x018C, 4, 0x06C8, 1, 0),
+    MX6SX_PAD_QSPI1A_DATA3__GPIO4_IO_19                      = IOMUX_PAD(0x04D4, 0x018C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA3__WEIM_DATA_3                      = IOMUX_PAD(0x04D4, 0x018C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA3__SIM_M_HADDR_7                    = IOMUX_PAD(0x04D4, 0x018C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DATA3__SDMA_DEBUG_PC_2                  = IOMUX_PAD(0x04D4, 0x018C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_QSPI1A_DQS__QSPI1_A_DQS                        = IOMUX_PAD(0x04D8, 0x0190, 0, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DQS__CAN2_TX                            = IOMUX_PAD(0x04D8, 0x0190, 1, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DQS__CANFD_TX2                          = IOMUX_PAD(0x04D8, 0x0190, 2, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DQS__ECSPI5_MOSI                        = IOMUX_PAD(0x04D8, 0x0190, 3, 0x0758, 1, 0),
+    MX6SX_PAD_QSPI1A_DQS__CSI1_DATA_15                       = IOMUX_PAD(0x04D8, 0x0190, 4, 0x06D8, 1, 0),
+    MX6SX_PAD_QSPI1A_DQS__GPIO4_IO_20                        = IOMUX_PAD(0x04D8, 0x0190, 5, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DQS__WEIM_DATA_7                        = IOMUX_PAD(0x04D8, 0x0190, 6, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DQS__SIM_M_HADDR_13                     = IOMUX_PAD(0x04D8, 0x0190, 7, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_DQS__SDMA_DEBUG_BUS_DEVICE_4            = IOMUX_PAD(0x04D8, 0x0190, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_QSPI1A_SCLK__QSPI1_A_SCLK                      = IOMUX_PAD(0x04DC, 0x0194, 0, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_SCLK__ANATOP_OTG2_ID                    = IOMUX_PAD(0x04DC, 0x0194, 1, 0x0628, 2, 0),
+    MX6SX_PAD_QSPI1A_SCLK__ECSPI1_SCLK                       = IOMUX_PAD(0x04DC, 0x0194, 2, 0x0710, 1, 0),
+    MX6SX_PAD_QSPI1A_SCLK__ESAI_TX2_RX3                      = IOMUX_PAD(0x04DC, 0x0194, 3, 0x0798, 2, 0),
+    MX6SX_PAD_QSPI1A_SCLK__CSI1_DATA_1                       = IOMUX_PAD(0x04DC, 0x0194, 4, 0x06A4, 1, 0),
+    MX6SX_PAD_QSPI1A_SCLK__GPIO4_IO_21                       = IOMUX_PAD(0x04DC, 0x0194, 5, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_SCLK__WEIM_DATA_0                       = IOMUX_PAD(0x04DC, 0x0194, 6, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_SCLK__SIM_M_HADDR_0                     = IOMUX_PAD(0x04DC, 0x0194, 7, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_SCLK__SDMA_DEBUG_PC_5                   = IOMUX_PAD(0x04DC, 0x0194, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_QSPI1A_SS0_B__QSPI1_A_SS0_B                    = IOMUX_PAD(0x04E0, 0x0198, 0, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_SS0_B__USB_OTG2_PWR                     = IOMUX_PAD(0x04E0, 0x0198, 1, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_SS0_B__ECSPI1_SS0                       = IOMUX_PAD(0x04E0, 0x0198, 2, 0x071C, 1, 0),
+    MX6SX_PAD_QSPI1A_SS0_B__ESAI_TX3_RX2                     = IOMUX_PAD(0x04E0, 0x0198, 3, 0x079C, 2, 0),
+    MX6SX_PAD_QSPI1A_SS0_B__CSI1_DATA_0                      = IOMUX_PAD(0x04E0, 0x0198, 4, 0x06A0, 1, 0),
+    MX6SX_PAD_QSPI1A_SS0_B__GPIO4_IO_22                      = IOMUX_PAD(0x04E0, 0x0198, 5, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_SS0_B__WEIM_DATA_1                      = IOMUX_PAD(0x04E0, 0x0198, 6, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_SS0_B__SIM_M_HADDR_1                    = IOMUX_PAD(0x04E0, 0x0198, 7, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_SS0_B__SDMA_DEBUG_PC_4                  = IOMUX_PAD(0x04E0, 0x0198, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_QSPI1A_SS1_B__QSPI1_A_SS1_B                    = IOMUX_PAD(0x04E4, 0x019C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_SS1_B__CAN1_RX                          = IOMUX_PAD(0x04E4, 0x019C, 1, 0x068C, 2, 0),
+    MX6SX_PAD_QSPI1A_SS1_B__CANFD_RX1                        = IOMUX_PAD(0x04E4, 0x019C, 2, 0x0694, 2, 0),
+    MX6SX_PAD_QSPI1A_SS1_B__ECSPI5_MISO                      = IOMUX_PAD(0x04E4, 0x019C, 3, 0x0754, 1, 0),
+    MX6SX_PAD_QSPI1A_SS1_B__CSI1_DATA_10                     = IOMUX_PAD(0x04E4, 0x019C, 4, 0x06FC, 1, 0),
+    MX6SX_PAD_QSPI1A_SS1_B__GPIO4_IO_23                      = IOMUX_PAD(0x04E4, 0x019C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_SS1_B__WEIM_DATA_2                      = IOMUX_PAD(0x04E4, 0x019C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_SS1_B__SIM_M_HADDR_12                   = IOMUX_PAD(0x04E4, 0x019C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1A_SS1_B__SDMA_DEBUG_PC_3                  = IOMUX_PAD(0x04E4, 0x019C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_QSPI1B_DATA0__QSPI1_B_DATA_0                   = IOMUX_PAD(0x04E8, 0x01A0, 0, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DATA0__UART3_CTS_B                      = IOMUX_PAD(0x04E8, 0x01A0, 1, 0x083C, 4, 0),
+    MX6SX_PAD_QSPI1B_DATA0__ECSPI3_MOSI                      = IOMUX_PAD(0x04E8, 0x01A0, 2, 0x0738, 1, 0),
+    MX6SX_PAD_QSPI1B_DATA0__ESAI_RX_FS                       = IOMUX_PAD(0x04E8, 0x01A0, 3, 0x0778, 2, 0),
+    MX6SX_PAD_QSPI1B_DATA0__CSI1_DATA_22                     = IOMUX_PAD(0x04E8, 0x01A0, 4, 0x06F4, 1, 0),
+    MX6SX_PAD_QSPI1B_DATA0__GPIO4_IO_24                      = IOMUX_PAD(0x04E8, 0x01A0, 5, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DATA0__WEIM_DATA_14                     = IOMUX_PAD(0x04E8, 0x01A0, 6, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DATA0__SIM_M_HADDR_9                    = IOMUX_PAD(0x04E8, 0x01A0, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_QSPI1B_DATA1__QSPI1_B_DATA_1                   = IOMUX_PAD(0x04EC, 0x01A4, 0, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DATA1__UART3_RTS_B                      = IOMUX_PAD(0x04EC, 0x01A4, 1, 0x083C, 5, 0),
+    MX6SX_PAD_QSPI1B_DATA1__ECSPI3_MISO                      = IOMUX_PAD(0x04EC, 0x01A4, 2, 0x0734, 1, 0),
+    MX6SX_PAD_QSPI1B_DATA1__ESAI_RX_CLK                      = IOMUX_PAD(0x04EC, 0x01A4, 3, 0x0788, 2, 0),
+    MX6SX_PAD_QSPI1B_DATA1__CSI1_DATA_21                     = IOMUX_PAD(0x04EC, 0x01A4, 4, 0x06F0, 1, 0),
+    MX6SX_PAD_QSPI1B_DATA1__GPIO4_IO_25                      = IOMUX_PAD(0x04EC, 0x01A4, 5, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DATA1__WEIM_DATA_13                     = IOMUX_PAD(0x04EC, 0x01A4, 6, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DATA1__SIM_M_HADDR_8                    = IOMUX_PAD(0x04EC, 0x01A4, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_QSPI1B_DATA2__QSPI1_B_DATA_2                   = IOMUX_PAD(0x04F0, 0x01A8, 0, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DATA2__I2C2_SDA                         = IOMUX_PAD(0x04F0, 0x01A8, IOMUX_CONFIG_SION | 1, 0x07B4, 2, 0),
+    MX6SX_PAD_QSPI1B_DATA2__ECSPI5_RDY                       = IOMUX_PAD(0x04F0, 0x01A8, 2, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DATA2__ESAI_TX5_RX0                     = IOMUX_PAD(0x04F0, 0x01A8, 3, 0x07A4, 2, 0),
+    MX6SX_PAD_QSPI1B_DATA2__CSI1_DATA_20                     = IOMUX_PAD(0x04F0, 0x01A8, 4, 0x06EC, 1, 0),
+    MX6SX_PAD_QSPI1B_DATA2__GPIO4_IO_26                      = IOMUX_PAD(0x04F0, 0x01A8, 5, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DATA2__WEIM_DATA_12                     = IOMUX_PAD(0x04F0, 0x01A8, 6, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DATA2__SIM_M_HADDR_5                    = IOMUX_PAD(0x04F0, 0x01A8, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_QSPI1B_DATA3__QSPI1_B_DATA_3                   = IOMUX_PAD(0x04F4, 0x01AC, 0, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DATA3__I2C2_SCL                         = IOMUX_PAD(0x04F4, 0x01AC, IOMUX_CONFIG_SION | 1, 0x07B0, 2, 0),
+    MX6SX_PAD_QSPI1B_DATA3__ECSPI5_SS3                       = IOMUX_PAD(0x04F4, 0x01AC, 2, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DATA3__ESAI_TX_FS                       = IOMUX_PAD(0x04F4, 0x01AC, 3, 0x077C, 2, 0),
+    MX6SX_PAD_QSPI1B_DATA3__CSI1_DATA_19                     = IOMUX_PAD(0x04F4, 0x01AC, 4, 0x06E8, 1, 0),
+    MX6SX_PAD_QSPI1B_DATA3__GPIO4_IO_27                      = IOMUX_PAD(0x04F4, 0x01AC, 5, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DATA3__WEIM_DATA_11                     = IOMUX_PAD(0x04F4, 0x01AC, 6, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DATA3__SIM_M_HADDR_2                    = IOMUX_PAD(0x04F4, 0x01AC, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_QSPI1B_DQS__QSPI1_B_DQS                        = IOMUX_PAD(0x04F8, 0x01B0, 0, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DQS__CAN1_TX                            = IOMUX_PAD(0x04F8, 0x01B0, 1, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DQS__CANFD_TX1                          = IOMUX_PAD(0x04F8, 0x01B0, 2, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DQS__ECSPI5_SS0                         = IOMUX_PAD(0x04F8, 0x01B0, 3, 0x075C, 1, 0),
+    MX6SX_PAD_QSPI1B_DQS__CSI1_DATA_23                       = IOMUX_PAD(0x04F8, 0x01B0, 4, 0x06F8, 1, 0),
+    MX6SX_PAD_QSPI1B_DQS__GPIO4_IO_28                        = IOMUX_PAD(0x04F8, 0x01B0, 5, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DQS__WEIM_DATA_15                       = IOMUX_PAD(0x04F8, 0x01B0, 6, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_DQS__SIM_M_HADDR_15                     = IOMUX_PAD(0x04F8, 0x01B0, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_QSPI1B_SCLK__QSPI1_B_SCLK                      = IOMUX_PAD(0x04FC, 0x01B4, 0, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_SCLK__UART3_RX                          = IOMUX_PAD(0x04FC, 0x01B4, 1, 0x0840, 4, 0),
+    MX6SX_PAD_QSPI1B_SCLK__ECSPI3_SCLK                       = IOMUX_PAD(0x04FC, 0x01B4, 2, 0x0730, 1, 0),
+    MX6SX_PAD_QSPI1B_SCLK__ESAI_RX_HF_CLK                    = IOMUX_PAD(0x04FC, 0x01B4, 3, 0x0780, 2, 0),
+    MX6SX_PAD_QSPI1B_SCLK__CSI1_DATA_16                      = IOMUX_PAD(0x04FC, 0x01B4, 4, 0x06DC, 1, 0),
+    MX6SX_PAD_QSPI1B_SCLK__GPIO4_IO_29                       = IOMUX_PAD(0x04FC, 0x01B4, 5, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_SCLK__WEIM_DATA_8                       = IOMUX_PAD(0x04FC, 0x01B4, 6, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_SCLK__SIM_M_HADDR_11                    = IOMUX_PAD(0x04FC, 0x01B4, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_QSPI1B_SS0_B__QSPI1_B_SS0_B                    = IOMUX_PAD(0x0500, 0x01B8, 0, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_SS0_B__UART3_TX                         = IOMUX_PAD(0x0500, 0x01B8, 1, 0x0840, 5, 0),
+    MX6SX_PAD_QSPI1B_SS0_B__ECSPI3_SS0                       = IOMUX_PAD(0x0500, 0x01B8, 2, 0x073C, 1, 0),
+    MX6SX_PAD_QSPI1B_SS0_B__ESAI_TX_HF_CLK                   = IOMUX_PAD(0x0500, 0x01B8, 3, 0x0784, 3, 0),
+    MX6SX_PAD_QSPI1B_SS0_B__CSI1_DATA_17                     = IOMUX_PAD(0x0500, 0x01B8, 4, 0x06E0, 1, 0),
+    MX6SX_PAD_QSPI1B_SS0_B__GPIO4_IO_30                      = IOMUX_PAD(0x0500, 0x01B8, 5, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_SS0_B__WEIM_DATA_9                      = IOMUX_PAD(0x0500, 0x01B8, 6, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_SS0_B__SIM_M_HADDR_10                   = IOMUX_PAD(0x0500, 0x01B8, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_QSPI1B_SS1_B__QSPI1_B_SS1_B                    = IOMUX_PAD(0x0504, 0x01BC, 0, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_SS1_B__CAN2_RX                          = IOMUX_PAD(0x0504, 0x01BC, 1, 0x0690, 2, 0),
+    MX6SX_PAD_QSPI1B_SS1_B__CANFD_RX2                        = IOMUX_PAD(0x0504, 0x01BC, 2, 0x0698, 2, 0),
+    MX6SX_PAD_QSPI1B_SS1_B__ECSPI5_SCLK                      = IOMUX_PAD(0x0504, 0x01BC, 3, 0x0750, 1, 0),
+    MX6SX_PAD_QSPI1B_SS1_B__CSI1_DATA_18                     = IOMUX_PAD(0x0504, 0x01BC, 4, 0x06E4, 1, 0),
+    MX6SX_PAD_QSPI1B_SS1_B__GPIO4_IO_31                      = IOMUX_PAD(0x0504, 0x01BC, 5, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_SS1_B__WEIM_DATA_10                     = IOMUX_PAD(0x0504, 0x01BC, 6, 0x0000, 0, 0),
+    MX6SX_PAD_QSPI1B_SS1_B__SIM_M_HADDR_14                   = IOMUX_PAD(0x0504, 0x01BC, 7, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII1_RD0__ENET1_RX_DATA_0                    = IOMUX_PAD(0x0508, 0x01C0, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD0__GPIO5_IO_0                         = IOMUX_PAD(0x0508, 0x01C0, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD0__CSI2_DATA_10                       = IOMUX_PAD(0x0508, 0x01C0, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD0__ANATOP_TESTI_0                     = IOMUX_PAD(0x0508, 0x01C0, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD0__RAWNAND_TESTER_TRIGGER             = IOMUX_PAD(0x0508, 0x01C0, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD0__PCIE_CTRL_DEBUG_0                  = IOMUX_PAD(0x0508, 0x01C0, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII1_RD1__ENET1_RX_DATA_1                    = IOMUX_PAD(0x050C, 0x01C4, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD1__GPIO5_IO_1                         = IOMUX_PAD(0x050C, 0x01C4, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD1__CSI2_DATA_11                       = IOMUX_PAD(0x050C, 0x01C4, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD1__ANATOP_TESTI_1                     = IOMUX_PAD(0x050C, 0x01C4, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD1__USDHC1_TESTER_TRIGGER              = IOMUX_PAD(0x050C, 0x01C4, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD1__PCIE_CTRL_DEBUG_1                  = IOMUX_PAD(0x050C, 0x01C4, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII1_RD2__ENET1_RX_DATA_2                    = IOMUX_PAD(0x0510, 0x01C8, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD2__GPIO5_IO_2                         = IOMUX_PAD(0x0510, 0x01C8, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD2__CSI2_DATA_12                       = IOMUX_PAD(0x0510, 0x01C8, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD2__ANATOP_TESTI_2                     = IOMUX_PAD(0x0510, 0x01C8, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD2__USDHC2_TESTER_TRIGGER              = IOMUX_PAD(0x0510, 0x01C8, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD2__PCIE_CTRL_DEBUG_2                  = IOMUX_PAD(0x0510, 0x01C8, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII1_RD3__ENET1_RX_DATA_3                    = IOMUX_PAD(0x0514, 0x01CC, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD3__GPIO5_IO_3                         = IOMUX_PAD(0x0514, 0x01CC, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD3__CSI2_DATA_13                       = IOMUX_PAD(0x0514, 0x01CC, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD3__ANATOP_TESTI_3                     = IOMUX_PAD(0x0514, 0x01CC, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD3__USDHC3_TESTER_TRIGGER              = IOMUX_PAD(0x0514, 0x01CC, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RD3__PCIE_CTRL_DEBUG_3                  = IOMUX_PAD(0x0514, 0x01CC, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII1_RX_CTL__ENET1_RX_EN                     = IOMUX_PAD(0x0518, 0x01D0, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RX_CTL__GPIO5_IO_4                      = IOMUX_PAD(0x0518, 0x01D0, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RX_CTL__CSI2_DATA_14                    = IOMUX_PAD(0x0518, 0x01D0, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RX_CTL__ANATOP_TESTO_0                  = IOMUX_PAD(0x0518, 0x01D0, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RX_CTL__USDHC4_TESTER_TRIGGER           = IOMUX_PAD(0x0518, 0x01D0, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RX_CTL__PCIE_CTRL_DEBUG_4               = IOMUX_PAD(0x0518, 0x01D0, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII1_RXC__ENET1_RX_CLK                       = IOMUX_PAD(0x051C, 0x01D4, 0, 0x0768, 1, 0),
+    MX6SX_PAD_RGMII1_RXC__ENET1_RX_ER                        = IOMUX_PAD(0x051C, 0x01D4, 1, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RXC__GPIO5_IO_5                         = IOMUX_PAD(0x051C, 0x01D4, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RXC__CSI2_DATA_15                       = IOMUX_PAD(0x051C, 0x01D4, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RXC__ANATOP_TESTO_1                     = IOMUX_PAD(0x051C, 0x01D4, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RXC__ECSPI1_TESTER_TRIGGER              = IOMUX_PAD(0x051C, 0x01D4, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_RXC__PCIE_CTRL_DEBUG_5                  = IOMUX_PAD(0x051C, 0x01D4, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII1_TD0__ENET1_TX_DATA_0                    = IOMUX_PAD(0x0520, 0x01D8, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD0__SAI2_RX_SYNC                       = IOMUX_PAD(0x0520, 0x01D8, 2, 0x0810, 1, 0),
+    MX6SX_PAD_RGMII1_TD0__GPIO5_IO_6                         = IOMUX_PAD(0x0520, 0x01D8, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD0__CSI2_DATA_16                       = IOMUX_PAD(0x0520, 0x01D8, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD0__ANATOP_TESTO_2                     = IOMUX_PAD(0x0520, 0x01D8, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD0__ECSPI2_TESTER_TRIGGER              = IOMUX_PAD(0x0520, 0x01D8, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD0__PCIE_CTRL_DEBUG_6                  = IOMUX_PAD(0x0520, 0x01D8, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII1_TD1__ENET1_TX_DATA_1                    = IOMUX_PAD(0x0524, 0x01DC, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD1__SAI2_RX_BCLK                       = IOMUX_PAD(0x0524, 0x01DC, 2, 0x0808, 1, 0),
+    MX6SX_PAD_RGMII1_TD1__GPIO5_IO_7                         = IOMUX_PAD(0x0524, 0x01DC, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD1__CSI2_DATA_17                       = IOMUX_PAD(0x0524, 0x01DC, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD1__ANATOP_TESTO_3                     = IOMUX_PAD(0x0524, 0x01DC, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD1__ECSPI3_TESTER_TRIGGER              = IOMUX_PAD(0x0524, 0x01DC, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD1__PCIE_CTRL_DEBUG_7                  = IOMUX_PAD(0x0524, 0x01DC, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII1_TD2__ENET1_TX_DATA_2                    = IOMUX_PAD(0x0528, 0x01E0, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD2__SAI2_TX_SYNC                       = IOMUX_PAD(0x0528, 0x01E0, 2, 0x0818, 1, 0),
+    MX6SX_PAD_RGMII1_TD2__GPIO5_IO_8                         = IOMUX_PAD(0x0528, 0x01E0, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD2__CSI2_DATA_18                       = IOMUX_PAD(0x0528, 0x01E0, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD2__ANATOP_TESTO_4                     = IOMUX_PAD(0x0528, 0x01E0, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD2__ECSPI4_TESTER_TRIGGER              = IOMUX_PAD(0x0528, 0x01E0, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD2__PCIE_CTRL_DEBUG_8                  = IOMUX_PAD(0x0528, 0x01E0, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII1_TD3__ENET1_TX_DATA_3                    = IOMUX_PAD(0x052C, 0x01E4, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD3__SAI2_TX_BCLK                       = IOMUX_PAD(0x052C, 0x01E4, 2, 0x0814, 1, 0),
+    MX6SX_PAD_RGMII1_TD3__GPIO5_IO_9                         = IOMUX_PAD(0x052C, 0x01E4, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD3__CSI2_DATA_19                       = IOMUX_PAD(0x052C, 0x01E4, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD3__ANATOP_TESTO_5                     = IOMUX_PAD(0x052C, 0x01E4, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD3__ECSPI5_TESTER_TRIGGER              = IOMUX_PAD(0x052C, 0x01E4, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TD3__PCIE_CTRL_DEBUG_9                  = IOMUX_PAD(0x052C, 0x01E4, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII1_TX_CTL__ENET1_TX_EN                     = IOMUX_PAD(0x0530, 0x01E8, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TX_CTL__SAI2_RX_DATA_0                  = IOMUX_PAD(0x0530, 0x01E8, 2, 0x080C, 1, 0),
+    MX6SX_PAD_RGMII1_TX_CTL__GPIO5_IO_10                     = IOMUX_PAD(0x0530, 0x01E8, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TX_CTL__CSI2_DATA_0                     = IOMUX_PAD(0x0530, 0x01E8, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TX_CTL__ANATOP_TESTO_6                  = IOMUX_PAD(0x0530, 0x01E8, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TX_CTL__QSPI1_TESTER_TRIGGER            = IOMUX_PAD(0x0530, 0x01E8, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TX_CTL__PCIE_CTRL_DEBUG_10              = IOMUX_PAD(0x0530, 0x01E8, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII1_TXC__ENET1_RGMII_TXC                    = IOMUX_PAD(0x0534, 0x01EC, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TXC__ENET1_TX_ER                        = IOMUX_PAD(0x0534, 0x01EC, 1, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TXC__SAI2_TX_DATA_0                     = IOMUX_PAD(0x0534, 0x01EC, 2, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TXC__GPIO5_IO_11                        = IOMUX_PAD(0x0534, 0x01EC, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TXC__CSI2_DATA_1                        = IOMUX_PAD(0x0534, 0x01EC, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TXC__ANATOP_TESTO_7                     = IOMUX_PAD(0x0534, 0x01EC, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TXC__QSPI2_TESTER_TRIGGER               = IOMUX_PAD(0x0534, 0x01EC, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII1_TXC__PCIE_CTRL_DEBUG_11                 = IOMUX_PAD(0x0534, 0x01EC, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII2_RD0__ENET2_RX_DATA_0                    = IOMUX_PAD(0x0538, 0x01F0, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD0__PWM4_OUT                           = IOMUX_PAD(0x0538, 0x01F0, 2, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD0__GPIO5_IO_12                        = IOMUX_PAD(0x0538, 0x01F0, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD0__CSI2_DATA_2                        = IOMUX_PAD(0x0538, 0x01F0, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD0__ANATOP_TESTO_8                     = IOMUX_PAD(0x0538, 0x01F0, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD0__VDEC_DEBUG_18                      = IOMUX_PAD(0x0538, 0x01F0, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD0__PCIE_CTRL_DEBUG_12                 = IOMUX_PAD(0x0538, 0x01F0, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII2_RD1__ENET2_RX_DATA_1                    = IOMUX_PAD(0x053C, 0x01F4, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD1__PWM3_OUT                           = IOMUX_PAD(0x053C, 0x01F4, 2, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD1__GPIO5_IO_13                        = IOMUX_PAD(0x053C, 0x01F4, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD1__CSI2_DATA_3                        = IOMUX_PAD(0x053C, 0x01F4, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD1__ANATOP_TESTO_9                     = IOMUX_PAD(0x053C, 0x01F4, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD1__VDEC_DEBUG_19                      = IOMUX_PAD(0x053C, 0x01F4, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD1__PCIE_CTRL_DEBUG_13                 = IOMUX_PAD(0x053C, 0x01F4, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII2_RD2__ENET2_RX_DATA_2                    = IOMUX_PAD(0x0540, 0x01F8, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD2__PWM2_OUT                           = IOMUX_PAD(0x0540, 0x01F8, 2, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD2__GPIO5_IO_14                        = IOMUX_PAD(0x0540, 0x01F8, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD2__CSI2_DATA_4                        = IOMUX_PAD(0x0540, 0x01F8, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD2__ANATOP_TESTO_10                    = IOMUX_PAD(0x0540, 0x01F8, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD2__VDEC_DEBUG_20                      = IOMUX_PAD(0x0540, 0x01F8, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD2__PCIE_CTRL_DEBUG_14                 = IOMUX_PAD(0x0540, 0x01F8, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII2_RD3__ENET2_RX_DATA_3                    = IOMUX_PAD(0x0544, 0x01FC, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD3__PWM1_OUT                           = IOMUX_PAD(0x0544, 0x01FC, 2, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD3__GPIO5_IO_15                        = IOMUX_PAD(0x0544, 0x01FC, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD3__CSI2_DATA_5                        = IOMUX_PAD(0x0544, 0x01FC, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD3__ANATOP_TESTO_11                    = IOMUX_PAD(0x0544, 0x01FC, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD3__VDEC_DEBUG_21                      = IOMUX_PAD(0x0544, 0x01FC, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RD3__PCIE_CTRL_DEBUG_15                 = IOMUX_PAD(0x0544, 0x01FC, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII2_RX_CTL__ENET2_RX_EN                     = IOMUX_PAD(0x0548, 0x0200, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RX_CTL__GPIO5_IO_16                     = IOMUX_PAD(0x0548, 0x0200, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RX_CTL__CSI2_DATA_6                     = IOMUX_PAD(0x0548, 0x0200, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RX_CTL__ANATOP_TESTO_12                 = IOMUX_PAD(0x0548, 0x0200, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RX_CTL__VDEC_DEBUG_22                   = IOMUX_PAD(0x0548, 0x0200, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RX_CTL__PCIE_CTRL_DEBUG_16              = IOMUX_PAD(0x0548, 0x0200, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII2_RXC__ENET2_RX_CLK                       = IOMUX_PAD(0x054C, 0x0204, 0, 0x0774, 1, 0),
+    MX6SX_PAD_RGMII2_RXC__ENET2_RX_ER                        = IOMUX_PAD(0x054C, 0x0204, 1, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RXC__GPIO5_IO_17                        = IOMUX_PAD(0x054C, 0x0204, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RXC__CSI2_DATA_7                        = IOMUX_PAD(0x054C, 0x0204, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RXC__ANATOP_TESTO_13                    = IOMUX_PAD(0x054C, 0x0204, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RXC__VDEC_DEBUG_23                      = IOMUX_PAD(0x054C, 0x0204, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_RXC__PCIE_CTRL_DEBUG_17                 = IOMUX_PAD(0x054C, 0x0204, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII2_TD0__ENET2_TX_DATA_0                    = IOMUX_PAD(0x0550, 0x0208, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD0__SAI1_RX_SYNC                       = IOMUX_PAD(0x0550, 0x0208, 2, 0x07FC, 1, 0),
+    MX6SX_PAD_RGMII2_TD0__PWM8_OUT                           = IOMUX_PAD(0x0550, 0x0208, 3, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD0__GPIO5_IO_18                        = IOMUX_PAD(0x0550, 0x0208, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD0__CSI2_DATA_8                        = IOMUX_PAD(0x0550, 0x0208, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD0__ANATOP_TESTO_14                    = IOMUX_PAD(0x0550, 0x0208, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD0__VDEC_DEBUG_24                      = IOMUX_PAD(0x0550, 0x0208, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD0__PCIE_CTRL_DEBUG_18                 = IOMUX_PAD(0x0550, 0x0208, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII2_TD1__ENET2_TX_DATA_1                    = IOMUX_PAD(0x0554, 0x020C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD1__SAI1_RX_BCLK                       = IOMUX_PAD(0x0554, 0x020C, 2, 0x07F4, 1, 0),
+    MX6SX_PAD_RGMII2_TD1__PWM7_OUT                           = IOMUX_PAD(0x0554, 0x020C, 3, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD1__GPIO5_IO_19                        = IOMUX_PAD(0x0554, 0x020C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD1__CSI2_DATA_9                        = IOMUX_PAD(0x0554, 0x020C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD1__ANATOP_TESTO_15                    = IOMUX_PAD(0x0554, 0x020C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD1__VDEC_DEBUG_25                      = IOMUX_PAD(0x0554, 0x020C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD1__PCIE_CTRL_DEBUG_19                 = IOMUX_PAD(0x0554, 0x020C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII2_TD2__ENET2_TX_DATA_2                    = IOMUX_PAD(0x0558, 0x0210, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD2__SAI1_TX_SYNC                       = IOMUX_PAD(0x0558, 0x0210, 2, 0x0804, 1, 0),
+    MX6SX_PAD_RGMII2_TD2__PWM6_OUT                           = IOMUX_PAD(0x0558, 0x0210, 3, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD2__GPIO5_IO_20                        = IOMUX_PAD(0x0558, 0x0210, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD2__CSI2_VSYNC                         = IOMUX_PAD(0x0558, 0x0210, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD2__SJC_FAIL                           = IOMUX_PAD(0x0558, 0x0210, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD2__VDEC_DEBUG_26                      = IOMUX_PAD(0x0558, 0x0210, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD2__PCIE_CTRL_DEBUG_20                 = IOMUX_PAD(0x0558, 0x0210, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII2_TD3__ENET2_TX_DATA_3                    = IOMUX_PAD(0x055C, 0x0214, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD3__SAI1_TX_BCLK                       = IOMUX_PAD(0x055C, 0x0214, 2, 0x0800, 1, 0),
+    MX6SX_PAD_RGMII2_TD3__PWM5_OUT                           = IOMUX_PAD(0x055C, 0x0214, 3, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD3__GPIO5_IO_21                        = IOMUX_PAD(0x055C, 0x0214, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD3__CSI2_HSYNC                         = IOMUX_PAD(0x055C, 0x0214, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD3__SJC_JTAG_ACT                       = IOMUX_PAD(0x055C, 0x0214, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD3__VDEC_DEBUG_27                      = IOMUX_PAD(0x055C, 0x0214, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TD3__PCIE_CTRL_DEBUG_21                 = IOMUX_PAD(0x055C, 0x0214, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII2_TX_CTL__ENET2_TX_EN                     = IOMUX_PAD(0x0560, 0x0218, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TX_CTL__SAI1_RX_DATA_0                  = IOMUX_PAD(0x0560, 0x0218, 2, 0x07F8, 1, 0),
+    MX6SX_PAD_RGMII2_TX_CTL__GPIO5_IO_22                     = IOMUX_PAD(0x0560, 0x0218, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TX_CTL__CSI2_FIELD                      = IOMUX_PAD(0x0560, 0x0218, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TX_CTL__SJC_DE_B                        = IOMUX_PAD(0x0560, 0x0218, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TX_CTL__VDEC_DEBUG_28                   = IOMUX_PAD(0x0560, 0x0218, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TX_CTL__PCIE_CTRL_DEBUG_22              = IOMUX_PAD(0x0560, 0x0218, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_RGMII2_TXC__ENET2_RGMII_TXC                    = IOMUX_PAD(0x0564, 0x021C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TXC__ENET2_TX_ER                        = IOMUX_PAD(0x0564, 0x021C, 1, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TXC__SAI1_TX_DATA_0                     = IOMUX_PAD(0x0564, 0x021C, 2, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TXC__GPIO5_IO_23                        = IOMUX_PAD(0x0564, 0x021C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TXC__CSI2_PIXCLK                        = IOMUX_PAD(0x0564, 0x021C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TXC__SJC_DONE                           = IOMUX_PAD(0x0564, 0x021C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TXC__VDEC_DEBUG_29                      = IOMUX_PAD(0x0564, 0x021C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_RGMII2_TXC__PCIE_CTRL_DEBUG_23                 = IOMUX_PAD(0x0564, 0x021C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD1_CLK__USDHC1_CLK                            = IOMUX_PAD(0x0568, 0x0220, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_CLK__AUDMUX_AUD5_RXFS                      = IOMUX_PAD(0x0568, 0x0220, 1, 0x0668, 1, 0),
+    MX6SX_PAD_SD1_CLK__WDOG2_WDOG_B                          = IOMUX_PAD(0x0568, 0x0220, 2, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_CLK__GPT_CLK                               = IOMUX_PAD(0x0568, 0x0220, 3, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_CLK__WDOG2_WDOG_RST_B_DEB                  = IOMUX_PAD(0x0568, 0x0220, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_CLK__GPIO6_IO_0                            = IOMUX_PAD(0x0568, 0x0220, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_CLK__ENET2_1588_EVENT1_OUT                 = IOMUX_PAD(0x0568, 0x0220, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_CLK__CCM_OUT1                              = IOMUX_PAD(0x0568, 0x0220, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_CLK__VADC_ADC_PROC_CLK                     = IOMUX_PAD(0x0568, 0x0220, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_CLK__MMDC_DEBUG_45                         = IOMUX_PAD(0x0568, 0x0220, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD1_CMD__USDHC1_CMD                            = IOMUX_PAD(0x056C, 0x0224, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_CMD__AUDMUX_AUD5_RXC                       = IOMUX_PAD(0x056C, 0x0224, 1, 0x0664, 1, 0),
+    MX6SX_PAD_SD1_CMD__WDOG1_WDOG_B                          = IOMUX_PAD(0x056C, 0x0224, 2, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_CMD__GPT_COMPARE1                          = IOMUX_PAD(0x056C, 0x0224, 3, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_CMD__WDOG1_WDOG_RST_B_DEB                  = IOMUX_PAD(0x056C, 0x0224, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_CMD__GPIO6_IO_1                            = IOMUX_PAD(0x056C, 0x0224, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_CMD__ENET2_1588_EVENT1_IN                  = IOMUX_PAD(0x056C, 0x0224, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_CMD__CCM_CLKO1                             = IOMUX_PAD(0x056C, 0x0224, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_CMD__VADC_EXT_SYSCLK                       = IOMUX_PAD(0x056C, 0x0224, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_CMD__MMDC_DEBUG_46                         = IOMUX_PAD(0x056C, 0x0224, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD1_DATA0__USDHC1_DATA0                        = IOMUX_PAD(0x0570, 0x0228, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA0__AUDMUX_AUD5_RXD                     = IOMUX_PAD(0x0570, 0x0228, 1, 0x065C, 1, 0),
+    MX6SX_PAD_SD1_DATA0__CAAM_WRAPPER_RNG_OSC_OBS            = IOMUX_PAD(0x0570, 0x0228, 2, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA0__GPT_CAPTURE1                        = IOMUX_PAD(0x0570, 0x0228, 3, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA0__UART2_RX                            = IOMUX_PAD(0x0570, 0x0228, 4, 0x0838, 2, 0),
+    MX6SX_PAD_SD1_DATA0__GPIO6_IO_2                          = IOMUX_PAD(0x0570, 0x0228, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA0__ENET1_1588_EVENT1_IN                = IOMUX_PAD(0x0570, 0x0228, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA0__CCM_OUT2                            = IOMUX_PAD(0x0570, 0x0228, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA0__VADC_CLAMP_UP                       = IOMUX_PAD(0x0570, 0x0228, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA0__MMDC_DEBUG_48                       = IOMUX_PAD(0x0570, 0x0228, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD1_DATA1__USDHC1_DATA1                        = IOMUX_PAD(0x0574, 0x022C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA1__AUDMUX_AUD5_TXC                     = IOMUX_PAD(0x0574, 0x022C, 1, 0x066C, 1, 0),
+    MX6SX_PAD_SD1_DATA1__PWM4_OUT                            = IOMUX_PAD(0x0574, 0x022C, 2, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA1__GPT_CAPTURE2                        = IOMUX_PAD(0x0574, 0x022C, 3, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA1__UART2_TX                            = IOMUX_PAD(0x0574, 0x022C, 4, 0x0838, 3, 0),
+    MX6SX_PAD_SD1_DATA1__GPIO6_IO_3                          = IOMUX_PAD(0x0574, 0x022C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA1__ENET1_1588_EVENT1_OUT               = IOMUX_PAD(0x0574, 0x022C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA1__CCM_CLKO2                           = IOMUX_PAD(0x0574, 0x022C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA1__VADC_CLAMP_DOWN                     = IOMUX_PAD(0x0574, 0x022C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA1__MMDC_DEBUG_47                       = IOMUX_PAD(0x0574, 0x022C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD1_DATA2__USDHC1_DATA2                        = IOMUX_PAD(0x0578, 0x0230, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA2__AUDMUX_AUD5_TXFS                    = IOMUX_PAD(0x0578, 0x0230, 1, 0x0670, 1, 0),
+    MX6SX_PAD_SD1_DATA2__PWM3_OUT                            = IOMUX_PAD(0x0578, 0x0230, 2, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA2__GPT_COMPARE2                        = IOMUX_PAD(0x0578, 0x0230, 3, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA2__UART2_CTS_B                         = IOMUX_PAD(0x0578, 0x0230, 4, 0x0834, 2, 0),
+    MX6SX_PAD_SD1_DATA2__GPIO6_IO_4                          = IOMUX_PAD(0x0578, 0x0230, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA2__ECSPI4_RDY                          = IOMUX_PAD(0x0578, 0x0230, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA2__CCM_OUT0                            = IOMUX_PAD(0x0578, 0x0230, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA2__VADC_EXT_PD_N                       = IOMUX_PAD(0x0578, 0x0230, 8, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD1_DATA3__USDHC1_DATA3                        = IOMUX_PAD(0x057C, 0x0234, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA3__AUDMUX_AUD5_TXD                     = IOMUX_PAD(0x057C, 0x0234, 1, 0x0660, 1, 0),
+    MX6SX_PAD_SD1_DATA3__AUDMUX_AUD5_RXD                     = IOMUX_PAD(0x057C, 0x0234, 2, 0x065C, 2, 0),
+    MX6SX_PAD_SD1_DATA3__GPT_COMPARE3                        = IOMUX_PAD(0x057C, 0x0234, 3, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA3__UART2_RTS_B                         = IOMUX_PAD(0x057C, 0x0234, 4, 0x0834, 3, 0),
+    MX6SX_PAD_SD1_DATA3__GPIO6_IO_5                          = IOMUX_PAD(0x057C, 0x0234, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA3__ECSPI4_SS1                          = IOMUX_PAD(0x057C, 0x0234, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD1_DATA3__CCM_PMIC_RDY                        = IOMUX_PAD(0x057C, 0x0234, 7, 0x069C, 2, 0),
+    MX6SX_PAD_SD1_DATA3__VADC_RST_N                          = IOMUX_PAD(0x057C, 0x0234, 8, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD2_CLK__USDHC2_CLK                            = IOMUX_PAD(0x0580, 0x0238, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_CLK__AUDMUX_AUD6_RXFS                      = IOMUX_PAD(0x0580, 0x0238, 1, 0x0680, 2, 0),
+    MX6SX_PAD_SD2_CLK__KPP_COL_5                             = IOMUX_PAD(0x0580, 0x0238, 2, 0x07C8, 1, 0),
+    MX6SX_PAD_SD2_CLK__ECSPI4_SCLK                           = IOMUX_PAD(0x0580, 0x0238, 3, 0x0740, 1, 0),
+    MX6SX_PAD_SD2_CLK__MLB_SIG                               = IOMUX_PAD(0x0580, 0x0238, 4, 0x07F0, 2, 0),
+    MX6SX_PAD_SD2_CLK__GPIO6_IO_6                            = IOMUX_PAD(0x0580, 0x0238, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_CLK__MQS_RIGHT                             = IOMUX_PAD(0x0580, 0x0238, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_CLK__WDOG1_WDOG_ANY                        = IOMUX_PAD(0x0580, 0x0238, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_CLK__VADC_CLAMP_CURRENT_5                  = IOMUX_PAD(0x0580, 0x0238, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_CLK__MMDC_DEBUG_29                         = IOMUX_PAD(0x0580, 0x0238, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD2_CMD__USDHC2_CMD                            = IOMUX_PAD(0x0584, 0x023C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_CMD__AUDMUX_AUD6_RXC                       = IOMUX_PAD(0x0584, 0x023C, 1, 0x067C, 2, 0),
+    MX6SX_PAD_SD2_CMD__KPP_ROW_5                             = IOMUX_PAD(0x0584, 0x023C, 2, 0x07D4, 1, 0),
+    MX6SX_PAD_SD2_CMD__ECSPI4_MOSI                           = IOMUX_PAD(0x0584, 0x023C, 3, 0x0748, 1, 0),
+    MX6SX_PAD_SD2_CMD__MLB_CLK                               = IOMUX_PAD(0x0584, 0x023C, 4, 0x07E8, 2, 0),
+    MX6SX_PAD_SD2_CMD__GPIO6_IO_7                            = IOMUX_PAD(0x0584, 0x023C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_CMD__MQS_LEFT                              = IOMUX_PAD(0x0584, 0x023C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_CMD__WDOG3_WDOG_B                          = IOMUX_PAD(0x0584, 0x023C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_CMD__VADC_CLAMP_CURRENT_4                  = IOMUX_PAD(0x0584, 0x023C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_CMD__MMDC_DEBUG_30                         = IOMUX_PAD(0x0584, 0x023C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD2_DATA0__USDHC2_DATA0                        = IOMUX_PAD(0x0588, 0x0240, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA0__AUDMUX_AUD6_RXD                     = IOMUX_PAD(0x0588, 0x0240, 1, 0x0674, 2, 0),
+    MX6SX_PAD_SD2_DATA0__KPP_ROW_7                           = IOMUX_PAD(0x0588, 0x0240, 2, 0x07DC, 1, 0),
+    MX6SX_PAD_SD2_DATA0__PWM1_OUT                            = IOMUX_PAD(0x0588, 0x0240, 3, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA0__I2C4_SDA                            = IOMUX_PAD(0x0588, 0x0240, IOMUX_CONFIG_SION | 4, 0x07C4, 3, 0),
+    MX6SX_PAD_SD2_DATA0__GPIO6_IO_8                          = IOMUX_PAD(0x0588, 0x0240, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA0__ECSPI4_SS3                          = IOMUX_PAD(0x0588, 0x0240, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA0__UART4_RX                            = IOMUX_PAD(0x0588, 0x0240, 7, 0x0848, 4, 0),
+    MX6SX_PAD_SD2_DATA0__VADC_CLAMP_CURRENT_0                = IOMUX_PAD(0x0588, 0x0240, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA0__MMDC_DEBUG_50                       = IOMUX_PAD(0x0588, 0x0240, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD2_DATA1__USDHC2_DATA1                        = IOMUX_PAD(0x058C, 0x0244, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA1__AUDMUX_AUD6_TXC                     = IOMUX_PAD(0x058C, 0x0244, 1, 0x0684, 2, 0),
+    MX6SX_PAD_SD2_DATA1__KPP_COL_7                           = IOMUX_PAD(0x058C, 0x0244, 2, 0x07D0, 1, 0),
+    MX6SX_PAD_SD2_DATA1__PWM2_OUT                            = IOMUX_PAD(0x058C, 0x0244, 3, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA1__I2C4_SCL                            = IOMUX_PAD(0x058C, 0x0244, IOMUX_CONFIG_SION | 4, 0x07C0, 3, 0),
+    MX6SX_PAD_SD2_DATA1__GPIO6_IO_9                          = IOMUX_PAD(0x058C, 0x0244, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA1__ECSPI4_SS2                          = IOMUX_PAD(0x058C, 0x0244, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA1__UART4_TX                            = IOMUX_PAD(0x058C, 0x0244, 7, 0x0848, 5, 0),
+    MX6SX_PAD_SD2_DATA1__VADC_CLAMP_CURRENT_1                = IOMUX_PAD(0x058C, 0x0244, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA1__MMDC_DEBUG_49                       = IOMUX_PAD(0x058C, 0x0244, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD2_DATA2__USDHC2_DATA2                        = IOMUX_PAD(0x0590, 0x0248, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA2__AUDMUX_AUD6_TXFS                    = IOMUX_PAD(0x0590, 0x0248, 1, 0x0688, 2, 0),
+    MX6SX_PAD_SD2_DATA2__KPP_ROW_6                           = IOMUX_PAD(0x0590, 0x0248, 2, 0x07D8, 1, 0),
+    MX6SX_PAD_SD2_DATA2__ECSPI4_SS0                          = IOMUX_PAD(0x0590, 0x0248, 3, 0x074C, 1, 0),
+    MX6SX_PAD_SD2_DATA2__SDMA_EXT_EVENT_0                    = IOMUX_PAD(0x0590, 0x0248, 4, 0x081C, 2, 0),
+    MX6SX_PAD_SD2_DATA2__GPIO6_IO_10                         = IOMUX_PAD(0x0590, 0x0248, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA2__SPDIF_OUT                           = IOMUX_PAD(0x0590, 0x0248, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA2__UART6_RX                            = IOMUX_PAD(0x0590, 0x0248, 7, 0x0858, 4, 0),
+    MX6SX_PAD_SD2_DATA2__VADC_CLAMP_CURRENT_2                = IOMUX_PAD(0x0590, 0x0248, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA2__MMDC_DEBUG_32                       = IOMUX_PAD(0x0590, 0x0248, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD2_DATA3__USDHC2_DATA3                        = IOMUX_PAD(0x0594, 0x024C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA3__AUDMUX_AUD6_TXD                     = IOMUX_PAD(0x0594, 0x024C, 1, 0x0678, 2, 0),
+    MX6SX_PAD_SD2_DATA3__KPP_COL_6                           = IOMUX_PAD(0x0594, 0x024C, 2, 0x07CC, 1, 0),
+    MX6SX_PAD_SD2_DATA3__ECSPI4_MISO                         = IOMUX_PAD(0x0594, 0x024C, 3, 0x0744, 1, 0),
+    MX6SX_PAD_SD2_DATA3__MLB_DATA                            = IOMUX_PAD(0x0594, 0x024C, 4, 0x07EC, 2, 0),
+    MX6SX_PAD_SD2_DATA3__GPIO6_IO_11                         = IOMUX_PAD(0x0594, 0x024C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA3__SPDIF_IN                            = IOMUX_PAD(0x0594, 0x024C, 6, 0x0824, 4, 0),
+    MX6SX_PAD_SD2_DATA3__UART6_TX                            = IOMUX_PAD(0x0594, 0x024C, 7, 0x0858, 5, 0),
+    MX6SX_PAD_SD2_DATA3__VADC_CLAMP_CURRENT_3                = IOMUX_PAD(0x0594, 0x024C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD2_DATA3__MMDC_DEBUG_31                       = IOMUX_PAD(0x0594, 0x024C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD3_CLK__USDHC3_CLK                            = IOMUX_PAD(0x0598, 0x0250, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_CLK__UART4_CTS_B                           = IOMUX_PAD(0x0598, 0x0250, 1, 0x0844, 0, 0),
+    MX6SX_PAD_SD3_CLK__ECSPI4_SCLK                           = IOMUX_PAD(0x0598, 0x0250, 2, 0x0740, 0, 0),
+    MX6SX_PAD_SD3_CLK__AUDMUX_AUD6_RXFS                      = IOMUX_PAD(0x0598, 0x0250, 3, 0x0680, 0, 0),
+    MX6SX_PAD_SD3_CLK__LCDIF2_VSYNC                          = IOMUX_PAD(0x0598, 0x0250, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_CLK__GPIO7_IO_0                            = IOMUX_PAD(0x0598, 0x0250, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_CLK__LCDIF2_BUSY                           = IOMUX_PAD(0x0598, 0x0250, 6, 0x07E4, 0, 0),
+    MX6SX_PAD_SD3_CLK__TPSMP_HDATA_29                        = IOMUX_PAD(0x0598, 0x0250, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_CLK__SDMA_DEBUG_EVENT_CHANNEL_5            = IOMUX_PAD(0x0598, 0x0250, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD3_CMD__USDHC3_CMD                            = IOMUX_PAD(0x059C, 0x0254, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_CMD__UART4_TX                              = IOMUX_PAD(0x059C, 0x0254, 1, 0x0848, 0, 0),
+    MX6SX_PAD_SD3_CMD__ECSPI4_MOSI                           = IOMUX_PAD(0x059C, 0x0254, 2, 0x0748, 0, 0),
+    MX6SX_PAD_SD3_CMD__AUDMUX_AUD6_RXC                       = IOMUX_PAD(0x059C, 0x0254, 3, 0x067C, 0, 0),
+    MX6SX_PAD_SD3_CMD__LCDIF2_HSYNC                          = IOMUX_PAD(0x059C, 0x0254, 4, 0x07E4, 1, 0),
+    MX6SX_PAD_SD3_CMD__GPIO7_IO_1                            = IOMUX_PAD(0x059C, 0x0254, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_CMD__LCDIF2_RS                             = IOMUX_PAD(0x059C, 0x0254, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_CMD__TPSMP_HDATA_28                        = IOMUX_PAD(0x059C, 0x0254, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_CMD__SDMA_DEBUG_EVENT_CHANNEL_4            = IOMUX_PAD(0x059C, 0x0254, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD3_DATA0__USDHC3_DATA0                        = IOMUX_PAD(0x05A0, 0x0258, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA0__I2C4_SCL                            = IOMUX_PAD(0x05A0, 0x0258, IOMUX_CONFIG_SION | 1, 0x07C0, 0, 0),
+    MX6SX_PAD_SD3_DATA0__ECSPI2_SS1                          = IOMUX_PAD(0x05A0, 0x0258, 2, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA0__AUDMUX_AUD6_RXD                     = IOMUX_PAD(0x05A0, 0x0258, 3, 0x0674, 0, 0),
+    MX6SX_PAD_SD3_DATA0__LCDIF2_DATA_1                       = IOMUX_PAD(0x05A0, 0x0258, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA0__GPIO7_IO_2                          = IOMUX_PAD(0x05A0, 0x0258, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA0__DCIC1_OUT                           = IOMUX_PAD(0x05A0, 0x0258, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA0__TPSMP_HDATA_30                      = IOMUX_PAD(0x05A0, 0x0258, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA0__GPU_DEBUG_0                         = IOMUX_PAD(0x05A0, 0x0258, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA0__SDMA_DEBUG_EVT_CHN_LINES_0          = IOMUX_PAD(0x05A0, 0x0258, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD3_DATA1__USDHC3_DATA1                        = IOMUX_PAD(0x05A4, 0x025C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA1__I2C4_SDA                            = IOMUX_PAD(0x05A4, 0x025C, IOMUX_CONFIG_SION | 1, 0x07C4, 0, 0),
+    MX6SX_PAD_SD3_DATA1__ECSPI2_SS2                          = IOMUX_PAD(0x05A4, 0x025C, 2, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA1__AUDMUX_AUD6_TXC                     = IOMUX_PAD(0x05A4, 0x025C, 3, 0x0684, 0, 0),
+    MX6SX_PAD_SD3_DATA1__LCDIF2_DATA_0                       = IOMUX_PAD(0x05A4, 0x025C, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA1__GPIO7_IO_3                          = IOMUX_PAD(0x05A4, 0x025C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA1__DCIC2_OUT                           = IOMUX_PAD(0x05A4, 0x025C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA1__TPSMP_HDATA_31                      = IOMUX_PAD(0x05A4, 0x025C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA1__GPU_DEBUG_1                         = IOMUX_PAD(0x05A4, 0x025C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA1__SDMA_DEBUG_EVT_CHN_LINES_1          = IOMUX_PAD(0x05A4, 0x025C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD3_DATA2__USDHC3_DATA2                        = IOMUX_PAD(0x05A8, 0x0260, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA2__UART4_RTS_B                         = IOMUX_PAD(0x05A8, 0x0260, 1, 0x0844, 1, 0),
+    MX6SX_PAD_SD3_DATA2__ECSPI4_SS0                          = IOMUX_PAD(0x05A8, 0x0260, 2, 0x074C, 0, 0),
+    MX6SX_PAD_SD3_DATA2__AUDMUX_AUD6_TXFS                    = IOMUX_PAD(0x05A8, 0x0260, 3, 0x0688, 0, 0),
+    MX6SX_PAD_SD3_DATA2__LCDIF2_CLK                          = IOMUX_PAD(0x05A8, 0x0260, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA2__GPIO7_IO_4                          = IOMUX_PAD(0x05A8, 0x0260, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA2__LCDIF2_WR_RWN                       = IOMUX_PAD(0x05A8, 0x0260, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA2__TPSMP_HDATA_26                      = IOMUX_PAD(0x05A8, 0x0260, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA2__GPU_DEBUG_2                         = IOMUX_PAD(0x05A8, 0x0260, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA2__SDMA_DEBUG_EVENT_CHANNEL_2          = IOMUX_PAD(0x05A8, 0x0260, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD3_DATA3__USDHC3_DATA3                        = IOMUX_PAD(0x05AC, 0x0264, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA3__UART4_RX                            = IOMUX_PAD(0x05AC, 0x0264, 1, 0x0848, 1, 0),
+    MX6SX_PAD_SD3_DATA3__ECSPI4_MISO                         = IOMUX_PAD(0x05AC, 0x0264, 2, 0x0744, 0, 0),
+    MX6SX_PAD_SD3_DATA3__AUDMUX_AUD6_TXD                     = IOMUX_PAD(0x05AC, 0x0264, 3, 0x0678, 0, 0),
+    MX6SX_PAD_SD3_DATA3__LCDIF2_ENABLE                       = IOMUX_PAD(0x05AC, 0x0264, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA3__GPIO7_IO_5                          = IOMUX_PAD(0x05AC, 0x0264, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA3__LCDIF2_RD_E                         = IOMUX_PAD(0x05AC, 0x0264, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA3__TPSMP_HDATA_27                      = IOMUX_PAD(0x05AC, 0x0264, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA3__GPU_DEBUG_3                         = IOMUX_PAD(0x05AC, 0x0264, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA3__SDMA_DEBUG_EVENT_CHANNEL_3          = IOMUX_PAD(0x05AC, 0x0264, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD3_DATA4__USDHC3_DATA4                        = IOMUX_PAD(0x05B0, 0x0268, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA4__CAN2_RX                             = IOMUX_PAD(0x05B0, 0x0268, 1, 0x0690, 0, 0),
+    MX6SX_PAD_SD3_DATA4__CANFD_RX2                           = IOMUX_PAD(0x05B0, 0x0268, 2, 0x0698, 0, 0),
+    MX6SX_PAD_SD3_DATA4__UART3_RX                            = IOMUX_PAD(0x05B0, 0x0268, 3, 0x0840, 2, 0),
+    MX6SX_PAD_SD3_DATA4__LCDIF2_DATA_3                       = IOMUX_PAD(0x05B0, 0x0268, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA4__GPIO7_IO_6                          = IOMUX_PAD(0x05B0, 0x0268, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA4__ENET2_1588_EVENT0_IN                = IOMUX_PAD(0x05B0, 0x0268, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA4__TPSMP_HTRANS_1                      = IOMUX_PAD(0x05B0, 0x0268, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA4__GPU_DEBUG_4                         = IOMUX_PAD(0x05B0, 0x0268, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA4__SDMA_DEBUG_BUS_DEVICE_0             = IOMUX_PAD(0x05B0, 0x0268, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD3_DATA5__USDHC3_DATA5                        = IOMUX_PAD(0x05B4, 0x026C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA5__CAN1_TX                             = IOMUX_PAD(0x05B4, 0x026C, 1, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA5__CANFD_TX1                           = IOMUX_PAD(0x05B4, 0x026C, 2, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA5__UART3_TX                            = IOMUX_PAD(0x05B4, 0x026C, 3, 0x0840, 3, 0),
+    MX6SX_PAD_SD3_DATA5__LCDIF2_DATA_2                       = IOMUX_PAD(0x05B4, 0x026C, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA5__GPIO7_IO_7                          = IOMUX_PAD(0x05B4, 0x026C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA5__ENET2_1588_EVENT0_OUT               = IOMUX_PAD(0x05B4, 0x026C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA5__SIM_M_HWRITE                        = IOMUX_PAD(0x05B4, 0x026C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA5__GPU_DEBUG_5                         = IOMUX_PAD(0x05B4, 0x026C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA5__SDMA_DEBUG_BUS_DEVICE_1             = IOMUX_PAD(0x05B4, 0x026C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD3_DATA6__USDHC3_DATA6                        = IOMUX_PAD(0x05B8, 0x0270, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA6__CAN2_TX                             = IOMUX_PAD(0x05B8, 0x0270, 1, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA6__CANFD_TX2                           = IOMUX_PAD(0x05B8, 0x0270, 2, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA6__UART3_RTS_B                         = IOMUX_PAD(0x05B8, 0x0270, 3, 0x083C, 2, 0),
+    MX6SX_PAD_SD3_DATA6__LCDIF2_DATA_4                       = IOMUX_PAD(0x05B8, 0x0270, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA6__GPIO7_IO_8                          = IOMUX_PAD(0x05B8, 0x0270, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA6__ENET1_1588_EVENT0_OUT               = IOMUX_PAD(0x05B8, 0x0270, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA6__TPSMP_HTRANS_0                      = IOMUX_PAD(0x05B8, 0x0270, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA6__GPU_DEBUG_7                         = IOMUX_PAD(0x05B8, 0x0270, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA6__SDMA_DEBUG_EVT_CHN_LINES_7          = IOMUX_PAD(0x05B8, 0x0270, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD3_DATA7__USDHC3_DATA7                        = IOMUX_PAD(0x05BC, 0x0274, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA7__CAN1_RX                             = IOMUX_PAD(0x05BC, 0x0274, 1, 0x068C, 0, 0),
+    MX6SX_PAD_SD3_DATA7__CANFD_RX1                           = IOMUX_PAD(0x05BC, 0x0274, 2, 0x0694, 0, 0),
+    MX6SX_PAD_SD3_DATA7__UART3_CTS_B                         = IOMUX_PAD(0x05BC, 0x0274, 3, 0x083C, 3, 0),
+    MX6SX_PAD_SD3_DATA7__LCDIF2_DATA_5                       = IOMUX_PAD(0x05BC, 0x0274, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA7__GPIO7_IO_9                          = IOMUX_PAD(0x05BC, 0x0274, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA7__ENET1_1588_EVENT0_IN                = IOMUX_PAD(0x05BC, 0x0274, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA7__TPSMP_HDATA_DIR                     = IOMUX_PAD(0x05BC, 0x0274, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA7__GPU_DEBUG_6                         = IOMUX_PAD(0x05BC, 0x0274, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD3_DATA7__SDMA_DEBUG_EVT_CHN_LINES_2          = IOMUX_PAD(0x05BC, 0x0274, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD4_CLK__USDHC4_CLK                            = IOMUX_PAD(0x05C0, 0x0278, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_CLK__RAWNAND_DATA15                        = IOMUX_PAD(0x05C0, 0x0278, 1, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_CLK__ECSPI2_MISO                           = IOMUX_PAD(0x05C0, 0x0278, 2, 0x0724, 1, 0),
+    MX6SX_PAD_SD4_CLK__AUDMUX_AUD3_RXFS                      = IOMUX_PAD(0x05C0, 0x0278, 3, 0x0638, 0, 0),
+    MX6SX_PAD_SD4_CLK__LCDIF2_DATA_13                        = IOMUX_PAD(0x05C0, 0x0278, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_CLK__GPIO6_IO_12                           = IOMUX_PAD(0x05C0, 0x0278, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_CLK__ECSPI3_SS2                            = IOMUX_PAD(0x05C0, 0x0278, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_CLK__TPSMP_HDATA_20                        = IOMUX_PAD(0x05C0, 0x0278, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_CLK__VDEC_DEBUG_12                         = IOMUX_PAD(0x05C0, 0x0278, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_CLK__SDMA_DEBUG_EVENT_CHANNEL_SEL          = IOMUX_PAD(0x05C0, 0x0278, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD4_CMD__USDHC4_CMD                            = IOMUX_PAD(0x05C4, 0x027C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_CMD__RAWNAND_DATA14                        = IOMUX_PAD(0x05C4, 0x027C, 1, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_CMD__ECSPI2_MOSI                           = IOMUX_PAD(0x05C4, 0x027C, 2, 0x0728, 1, 0),
+    MX6SX_PAD_SD4_CMD__AUDMUX_AUD3_RXC                       = IOMUX_PAD(0x05C4, 0x027C, 3, 0x0634, 0, 0),
+    MX6SX_PAD_SD4_CMD__LCDIF2_DATA_14                        = IOMUX_PAD(0x05C4, 0x027C, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_CMD__GPIO6_IO_13                           = IOMUX_PAD(0x05C4, 0x027C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_CMD__ECSPI3_SS1                            = IOMUX_PAD(0x05C4, 0x027C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_CMD__TPSMP_HDATA_19                        = IOMUX_PAD(0x05C4, 0x027C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_CMD__VDEC_DEBUG_11                         = IOMUX_PAD(0x05C4, 0x027C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_CMD__SDMA_DEBUG_CORE_RUN                   = IOMUX_PAD(0x05C4, 0x027C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD4_DATA0__USDHC4_DATA0                        = IOMUX_PAD(0x05C8, 0x0280, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA0__RAWNAND_DATA10                      = IOMUX_PAD(0x05C8, 0x0280, 1, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA0__ECSPI2_SS0                          = IOMUX_PAD(0x05C8, 0x0280, 2, 0x072C, 1, 0),
+    MX6SX_PAD_SD4_DATA0__AUDMUX_AUD3_RXD                     = IOMUX_PAD(0x05C8, 0x0280, 3, 0x062C, 0, 0),
+    MX6SX_PAD_SD4_DATA0__LCDIF2_DATA_12                      = IOMUX_PAD(0x05C8, 0x0280, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA0__GPIO6_IO_14                         = IOMUX_PAD(0x05C8, 0x0280, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA0__ECSPI3_SS3                          = IOMUX_PAD(0x05C8, 0x0280, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA0__TPSMP_HDATA_21                      = IOMUX_PAD(0x05C8, 0x0280, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA0__VDEC_DEBUG_13                       = IOMUX_PAD(0x05C8, 0x0280, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA0__SDMA_DEBUG_MODE                     = IOMUX_PAD(0x05C8, 0x0280, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD4_DATA1__USDHC4_DATA1                        = IOMUX_PAD(0x05CC, 0x0284, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA1__RAWNAND_DATA11                      = IOMUX_PAD(0x05CC, 0x0284, 1, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA1__ECSPI2_SCLK                         = IOMUX_PAD(0x05CC, 0x0284, 2, 0x0720, 1, 0),
+    MX6SX_PAD_SD4_DATA1__AUDMUX_AUD3_TXC                     = IOMUX_PAD(0x05CC, 0x0284, 3, 0x063C, 0, 0),
+    MX6SX_PAD_SD4_DATA1__LCDIF2_DATA_11                      = IOMUX_PAD(0x05CC, 0x0284, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA1__GPIO6_IO_15                         = IOMUX_PAD(0x05CC, 0x0284, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA1__ECSPI3_RDY                          = IOMUX_PAD(0x05CC, 0x0284, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA1__TPSMP_HDATA_22                      = IOMUX_PAD(0x05CC, 0x0284, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA1__VDEC_DEBUG_14                       = IOMUX_PAD(0x05CC, 0x0284, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA1__SDMA_DEBUG_BUS_ERROR                = IOMUX_PAD(0x05CC, 0x0284, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD4_DATA2__USDHC4_DATA2                        = IOMUX_PAD(0x05D0, 0x0288, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA2__RAWNAND_DATA12                      = IOMUX_PAD(0x05D0, 0x0288, 1, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA2__I2C2_SDA                            = IOMUX_PAD(0x05D0, 0x0288, IOMUX_CONFIG_SION | 2, 0x07B4, 0, 0),
+    MX6SX_PAD_SD4_DATA2__AUDMUX_AUD3_TXFS                    = IOMUX_PAD(0x05D0, 0x0288, 3, 0x0640, 0, 0),
+    MX6SX_PAD_SD4_DATA2__LCDIF2_DATA_10                      = IOMUX_PAD(0x05D0, 0x0288, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA2__GPIO6_IO_16                         = IOMUX_PAD(0x05D0, 0x0288, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA2__ECSPI2_SS3                          = IOMUX_PAD(0x05D0, 0x0288, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA2__TPSMP_HDATA_23                      = IOMUX_PAD(0x05D0, 0x0288, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA2__VDEC_DEBUG_15                       = IOMUX_PAD(0x05D0, 0x0288, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA2__SDMA_DEBUG_BUS_RWB                  = IOMUX_PAD(0x05D0, 0x0288, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD4_DATA3__USDHC4_DATA3                        = IOMUX_PAD(0x05D4, 0x028C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA3__RAWNAND_DATA13                      = IOMUX_PAD(0x05D4, 0x028C, 1, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA3__I2C2_SCL                            = IOMUX_PAD(0x05D4, 0x028C, IOMUX_CONFIG_SION | 2, 0x07B0, 0, 0),
+    MX6SX_PAD_SD4_DATA3__AUDMUX_AUD3_TXD                     = IOMUX_PAD(0x05D4, 0x028C, 3, 0x0630, 0, 0),
+    MX6SX_PAD_SD4_DATA3__LCDIF2_DATA_9                       = IOMUX_PAD(0x05D4, 0x028C, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA3__GPIO6_IO_17                         = IOMUX_PAD(0x05D4, 0x028C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA3__ECSPI2_RDY                          = IOMUX_PAD(0x05D4, 0x028C, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA3__TPSMP_HDATA_24                      = IOMUX_PAD(0x05D4, 0x028C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA3__VDEC_DEBUG_16                       = IOMUX_PAD(0x05D4, 0x028C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA3__SDMA_DEBUG_MATCHED_DMBUS            = IOMUX_PAD(0x05D4, 0x028C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD4_DATA4__USDHC4_DATA4                        = IOMUX_PAD(0x05D8, 0x0290, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA4__RAWNAND_DATA09                      = IOMUX_PAD(0x05D8, 0x0290, 1, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA4__UART5_RX                            = IOMUX_PAD(0x05D8, 0x0290, 2, 0x0850, 0, 0),
+    MX6SX_PAD_SD4_DATA4__ECSPI3_SCLK                         = IOMUX_PAD(0x05D8, 0x0290, 3, 0x0730, 0, 0),
+    MX6SX_PAD_SD4_DATA4__LCDIF2_DATA_8                       = IOMUX_PAD(0x05D8, 0x0290, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA4__GPIO6_IO_18                         = IOMUX_PAD(0x05D8, 0x0290, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA4__SPDIF_OUT                           = IOMUX_PAD(0x05D8, 0x0290, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA4__TPSMP_HDATA_16                      = IOMUX_PAD(0x05D8, 0x0290, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA4__USB_OTG_HOST_MODE                   = IOMUX_PAD(0x05D8, 0x0290, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA4__SDMA_DEBUG_RTBUFFER_WRITE           = IOMUX_PAD(0x05D8, 0x0290, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD4_DATA5__USDHC4_DATA5                        = IOMUX_PAD(0x05DC, 0x0294, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA5__RAWNAND_CE2_B                       = IOMUX_PAD(0x05DC, 0x0294, 1, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA5__UART5_TX                            = IOMUX_PAD(0x05DC, 0x0294, 2, 0x0850, 1, 0),
+    MX6SX_PAD_SD4_DATA5__ECSPI3_MOSI                         = IOMUX_PAD(0x05DC, 0x0294, 3, 0x0738, 0, 0),
+    MX6SX_PAD_SD4_DATA5__LCDIF2_DATA_7                       = IOMUX_PAD(0x05DC, 0x0294, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA5__GPIO6_IO_19                         = IOMUX_PAD(0x05DC, 0x0294, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA5__SPDIF_IN                            = IOMUX_PAD(0x05DC, 0x0294, 6, 0x0824, 0, 0),
+    MX6SX_PAD_SD4_DATA5__TPSMP_HDATA_17                      = IOMUX_PAD(0x05DC, 0x0294, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA5__VDEC_DEBUG_9                        = IOMUX_PAD(0x05DC, 0x0294, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA5__SDMA_DEBUG_EVENT_CHANNEL_0          = IOMUX_PAD(0x05DC, 0x0294, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD4_DATA6__USDHC4_DATA6                        = IOMUX_PAD(0x05E0, 0x0298, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA6__RAWNAND_CE3_B                       = IOMUX_PAD(0x05E0, 0x0298, 1, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA6__UART5_RTS_B                         = IOMUX_PAD(0x05E0, 0x0298, 2, 0x084C, 0, 0),
+    MX6SX_PAD_SD4_DATA6__ECSPI3_MISO                         = IOMUX_PAD(0x05E0, 0x0298, 3, 0x0734, 0, 0),
+    MX6SX_PAD_SD4_DATA6__LCDIF2_DATA_6                       = IOMUX_PAD(0x05E0, 0x0298, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA6__GPIO6_IO_20                         = IOMUX_PAD(0x05E0, 0x0298, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA6__USDHC4_WP                           = IOMUX_PAD(0x05E0, 0x0298, 6, 0x0878, 0, 0),
+    MX6SX_PAD_SD4_DATA6__TPSMP_HDATA_18                      = IOMUX_PAD(0x05E0, 0x0298, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA6__VDEC_DEBUG_10                       = IOMUX_PAD(0x05E0, 0x0298, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA6__SDMA_DEBUG_EVENT_CHANNEL_1          = IOMUX_PAD(0x05E0, 0x0298, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD4_DATA7__USDHC4_DATA7                        = IOMUX_PAD(0x05E4, 0x029C, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA7__RAWNAND_DATA08                      = IOMUX_PAD(0x05E4, 0x029C, 1, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA7__UART5_CTS_B                         = IOMUX_PAD(0x05E4, 0x029C, 2, 0x084C, 1, 0),
+    MX6SX_PAD_SD4_DATA7__ECSPI3_SS0                          = IOMUX_PAD(0x05E4, 0x029C, 3, 0x073C, 0, 0),
+    MX6SX_PAD_SD4_DATA7__LCDIF2_DATA_15                      = IOMUX_PAD(0x05E4, 0x029C, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA7__GPIO6_IO_21                         = IOMUX_PAD(0x05E4, 0x029C, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA7__USDHC4_CD_B                         = IOMUX_PAD(0x05E4, 0x029C, 6, 0x0874, 0, 0),
+    MX6SX_PAD_SD4_DATA7__TPSMP_HDATA_15                      = IOMUX_PAD(0x05E4, 0x029C, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA7__USB_OTG_PWR_WAKE                    = IOMUX_PAD(0x05E4, 0x029C, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_DATA7__SDMA_DEBUG_YIELD                    = IOMUX_PAD(0x05E4, 0x029C, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_SD4_RESET_B__USDHC4_RESET_B                    = IOMUX_PAD(0x05E8, 0x02A0, 0, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_RESET_B__RAWNAND_DQS                       = IOMUX_PAD(0x05E8, 0x02A0, 1, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_RESET_B__USDHC4_RESET                      = IOMUX_PAD(0x05E8, 0x02A0, 2, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_RESET_B__AUDMUX_MCLK                       = IOMUX_PAD(0x05E8, 0x02A0, 3, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_RESET_B__LCDIF2_RESET                      = IOMUX_PAD(0x05E8, 0x02A0, 4, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_RESET_B__GPIO6_IO_22                       = IOMUX_PAD(0x05E8, 0x02A0, 5, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_RESET_B__LCDIF2_CS                         = IOMUX_PAD(0x05E8, 0x02A0, 6, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_RESET_B__TPSMP_HDATA_25                    = IOMUX_PAD(0x05E8, 0x02A0, 7, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_RESET_B__VDEC_DEBUG_17                     = IOMUX_PAD(0x05E8, 0x02A0, 8, 0x0000, 0, 0),
+    MX6SX_PAD_SD4_RESET_B__SDMA_DEBUG_BUS_DEVICE_2           = IOMUX_PAD(0x05E8, 0x02A0, 9, 0x0000, 0, 0),
+
+    MX6SX_PAD_USB_H_DATA__USB_H_DATA                         = IOMUX_PAD(0x05EC, 0x02A4, 0, 0x0000, 0, 0),
+    MX6SX_PAD_USB_H_DATA__PWM2_OUT                           = IOMUX_PAD(0x05EC, 0x02A4, 1, 0x0000, 0, 0),
+    MX6SX_PAD_USB_H_DATA__ANATOP_24M_OUT                     = IOMUX_PAD(0x05EC, 0x02A4, 2, 0x0000, 0, 0),
+    MX6SX_PAD_USB_H_DATA__I2C4_SDA                           = IOMUX_PAD(0x05EC, 0x02A4, IOMUX_CONFIG_SION | 3, 0x07C4, 1, 0),
+    MX6SX_PAD_USB_H_DATA__WDOG3_WDOG_B                       = IOMUX_PAD(0x05EC, 0x02A4, 4, 0x0000, 0, 0),
+    MX6SX_PAD_USB_H_DATA__GPIO7_IO_10                        = IOMUX_PAD(0x05EC, 0x02A4, 5, 0x0000, 0, 0),
+
+    MX6SX_PAD_USB_H_STROBE__USB_H_STROBE                     = IOMUX_PAD(0x05F0, 0x02A8, 0, 0x0000, 0, 0),
+    MX6SX_PAD_USB_H_STROBE__PWM1_OUT                         = IOMUX_PAD(0x05F0, 0x02A8, 1, 0x0000, 0, 0),
+    MX6SX_PAD_USB_H_STROBE__ANATOP_32K_OUT                   = IOMUX_PAD(0x05F0, 0x02A8, 2, 0x0000, 0, 0),
+    MX6SX_PAD_USB_H_STROBE__I2C4_SCL                         = IOMUX_PAD(0x05F0, 0x02A8, IOMUX_CONFIG_SION | 3, 0x07C0, 1, 0),
+    MX6SX_PAD_USB_H_STROBE__WDOG3_WDOG_RST_B_DEB             = IOMUX_PAD(0x05F0, 0x02A8, 4, 0x0000, 0, 0),
+    MX6SX_PAD_USB_H_STROBE__GPIO7_IO_11                      = IOMUX_PAD(0x05F0, 0x02A8, 5, 0x0000, 0, 0),
+};
diff --git a/libethdrivers/src/plat/imx6/uboot/imx8mq_pins.h b/libethdrivers/src/plat/imx6/uboot/imx8mq_pins.h
index ad13d0b..68d8337 100644
--- a/libethdrivers/src/plat/imx6/uboot/imx8mq_pins.h
+++ b/libethdrivers/src/plat/imx6/uboot/imx8mq_pins.h
@@ -1,9 +1,8 @@
 /*
- * @TAG(OTHER_GPL)
- */
-
-/*
  * Copyright (C) 2017 NXP
+ * Copyright (C) 2020, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -23,7 +22,11 @@
 
 #pragma once
 
-#include "mx6qsabrelite.h"
+#include "imx_pins.h"
+
+#ifndef CONFIG_PLAT_IMX8MQ_EVK
+#error "CONFIG_PLAT_IMX8MQ_EVK must be defined to use this file"
+#endif
 
 enum {
     IMX8MQ_PAD_GPIO1_IO00__GPIO1_IO0                    = IOMUX_PAD(0x0290, 0x0028, 0, 0x0000, 0, 0),
diff --git a/libethdrivers/src/plat/imx6/uboot/imx_board.c b/libethdrivers/src/plat/imx6/uboot/imx_board.c
new file mode 100644
index 0000000..3f29c30
--- /dev/null
+++ b/libethdrivers/src/plat/imx6/uboot/imx_board.c
@@ -0,0 +1,422 @@
+/*
+ * based on u-boot-imx6/board/freescale/mx6qsabrelite/mx6qsabrelite.c
+ *
+ * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2018 NXP
+ * Copyright (C) 2020, HENSOLDT Cyber GmbH
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * 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 (at your option) 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include "common.h"
+#include "gpio.h"
+#include "../io.h"
+#include "imx_board.h"
+#include <platsupport/io.h>
+#include <stdio.h>
+
+
+#if defined(CONFIG_PLAT_IMX6)
+
+#if defined(CONFIG_PLAT_IMX6DQ)
+#include "imx6dq_pins.h"
+#elif defined(CONFIG_PLAT_IMX6SX)
+#include "imx6sx_pins.h"
+#else
+#error "unknown i.MX6 SOC"
+#endif
+
+#define IOMUXC_PADDR    0x020E0000
+#define IOMUXC_SIZE     0x4000
+
+#if defined(CONFIG_PLAT_IMX6SX)
+#define IOMUXC_GPR_PADDR    0x020E4000
+#define IOMUXC_GPR_SIZE     0x4000
+#endif
+
+#elif defined(CONFIG_PLAT_IMX8MQ_EVK)
+
+#include "imx8mq_pins.h"
+
+#define IOMUXC_PADDR    0x30330000
+#define IOMUXC_SIZE     0x10000
+
+#else
+#error "unknown i.MX SOC"
+#endif
+
+
+/*
+ * configure pads in the IOMUX
+ */
+static void imx_iomux_v3_setup_multiple_pads(
+    void *base,
+    iomux_v3_cfg_t const *pad_list,
+    unsigned int count)
+{
+    for (unsigned int i = 0; i < count; i++) {
+        iomux_v3_cfg_t pad = pad_list[i];
+
+        // set mode
+        uint32_t mux_ctrl_ofs = (pad & MUX_CTRL_OFS_MASK) >> MUX_CTRL_OFS_SHIFT;
+        if (mux_ctrl_ofs) {
+            uint32_t mux_mode = (pad & MUX_MODE_MASK) >> MUX_MODE_SHIFT;
+            __raw_writel(mux_mode, base + mux_ctrl_ofs);
+        }
+
+        // set input selector
+        uint32_t sel_input_ofs = (pad & MUX_SEL_INPUT_OFS_MASK) >> MUX_SEL_INPUT_OFS_SHIFT;
+        if (sel_input_ofs) {
+            uint32_t sel_input = (pad & MUX_SEL_INPUT_MASK) >> MUX_SEL_INPUT_SHIFT;
+            __raw_writel(sel_input, base + sel_input_ofs);
+        }
+
+        // set pad control
+        uint32_t pad_ctrl_ofs = (pad & MUX_PAD_CTRL_OFS_MASK) >> MUX_PAD_CTRL_OFS_SHIFT;
+        if (pad_ctrl_ofs) {
+            uint32_t pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT;
+            if (!(pad_ctrl & NO_PAD_CTRL)) {
+                __raw_writel(pad_ctrl, base + pad_ctrl_ofs);
+            }
+        }
+    }
+}
+
+#define IMX_IOMUX_V3_SETUP_MULTIPLE_PADS(_base_, ...) \
+    do { \
+        iomux_v3_cfg_t const pad_cfg[] = { __VA_ARGS__ }; \
+        imx_iomux_v3_setup_multiple_pads( \
+            _base_, \
+            pad_cfg, \
+            ARRAY_SIZE(pad_cfg) ); \
+    } while(0)
+
+
+
+int setup_iomux_enet(ps_io_ops_t *io_ops)
+{
+    int ret;
+    void *base;
+    int unmapOnExit = 0;
+
+    if (mux_sys_valid(&io_ops->mux_sys)) {
+        base = mux_sys_get_vaddr(&io_ops->mux_sys);
+    } else {
+        base = RESOURCE(&io_ops->io_mapper, IOMUXC);
+        unmapOnExit = 1;
+    }
+    if (!base) {
+        ZF_LOGE("base is NULL");
+        return 1;
+    }
+
+#if defined(CONFIG_PLAT_IMX8MQ_EVK)
+
+    /* see the IMX8 reference manual for what the options mean,
+     * Section 8.2.4 i.e. IOMUXC_SW_PAD_CTL_PAD_* registers */
+    IMX_IOMUX_V3_SETUP_MULTIPLE_PADS(
+        base,
+        IMX8MQ_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(0x3),
+        IMX8MQ_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(0x23),
+        IMX8MQ_PAD_ENET_TD3__ENET_RGMII_TD3 | MUX_PAD_CTRL(0x1f),
+        IMX8MQ_PAD_ENET_TD2__ENET_RGMII_TD2 | MUX_PAD_CTRL(0x1f),
+        IMX8MQ_PAD_ENET_TD1__ENET_RGMII_TD1 | MUX_PAD_CTRL(0x1f),
+        IMX8MQ_PAD_ENET_TD0__ENET_RGMII_TD0 | MUX_PAD_CTRL(0x1f),
+        IMX8MQ_PAD_ENET_RD3__ENET_RGMII_RD3 | MUX_PAD_CTRL(0x91),
+        IMX8MQ_PAD_ENET_RD2__ENET_RGMII_RD2 | MUX_PAD_CTRL(0x91),
+        IMX8MQ_PAD_ENET_RD1__ENET_RGMII_RD1 | MUX_PAD_CTRL(0x91),
+        IMX8MQ_PAD_ENET_RD0__ENET_RGMII_RD0 | MUX_PAD_CTRL(0x91),
+        IMX8MQ_PAD_ENET_TXC__ENET_RGMII_TXC | MUX_PAD_CTRL(0x1f),
+        IMX8MQ_PAD_ENET_RXC__ENET_RGMII_RXC | MUX_PAD_CTRL(0x91),
+        IMX8MQ_PAD_ENET_TX_CTL__ENET_RGMII_TX_CTL | MUX_PAD_CTRL(0x1f),
+        IMX8MQ_PAD_ENET_RX_CTL__ENET_RGMII_RX_CTL | MUX_PAD_CTRL(0x91),
+        IMX8MQ_PAD_GPIO1_IO09__GPIO1_IO9 | MUX_PAD_CTRL(0x19)
+    );
+    gpio_direction_output(IMX_GPIO_NR(1, 9), 0, io_ops);
+    udelay(500);
+    gpio_direction_output(IMX_GPIO_NR(1, 9), 1, io_ops);
+
+    uint32_t *gpr1 = base + 0x4;
+    /* Change ENET_TX to use internal clocks and not the external clocks */
+    *gpr1 = *gpr1 & ~(BIT(17) | BIT(13));
+
+#elif defined(CONFIG_PLAT_IMX6DQ)
+
+#define ENET_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP | \
+                        PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+
+    /* PHY to GPIO mapping for strapping */
+#define GPIO_NR_PHY_NRST        IMX_GPIO_NR(3, 23) // EIM_D23      to PHY pin 42 nRST
+#define GPIO_NR_PHY_AD2         IMX_GPIO_NR(6, 30) // RGMII_RXC    to PHY pin 35 AD2
+#define GPIO_NR_PHY_MODE0       IMX_GPIO_NR(6, 25) // RGMII_RD0    to PHY pin 32 MODE0
+#define GPIO_NR_PHY_MODE1       IMX_GPIO_NR(6, 27) // RGMII_RD1    to PHY pin 31 MODE1
+#define GPIO_NR_PHY_MODE2       IMX_GPIO_NR(6, 28) // RGMII_RD2    to PHY pin 28 MODE2
+#define GPIO_NR_PHY_MODE3       IMX_GPIO_NR(6, 29) // RGMII_RD3    to PHY pin 27 MODE3
+#define GPIO_NR_PHY_CLK125_EN   IMX_GPIO_NR(6, 24) // RGMII_RX_CTL to PHY pin 33 CLK125_EN
+
+    /* put PHY into reset */
+    gpio_direction_output(GPIO_NR_PHY_NRST,      0, io_ops);
+    /* PHYAD=b00100 */
+    gpio_direction_output(GPIO_NR_PHY_AD2,       1, io_ops);
+    /* MODE=b1111 (RGMII Mode, 10/100/1000 speed, half/full duplex) */
+    gpio_direction_output(GPIO_NR_PHY_MODE0,     1, io_ops);
+    gpio_direction_output(GPIO_NR_PHY_MODE1,     1, io_ops);
+    gpio_direction_output(GPIO_NR_PHY_MODE2,     1, io_ops);
+    gpio_direction_output(GPIO_NR_PHY_MODE3,     1, io_ops);
+    // enable 125MHz clock output
+    gpio_direction_output(GPIO_NR_PHY_CLK125_EN, 1, io_ops);
+
+    /* set pad configuration (after we have set well-defined GPIOs above) */
+    IMX_IOMUX_V3_SETUP_MULTIPLE_PADS(
+        base,
+        MX6Q_PAD_ENET_MDIO__ENET_MDIO       | MUX_PAD_CTRL(ENET_PAD_CTRL),
+        MX6Q_PAD_ENET_MDC__ENET_MDC         | MUX_PAD_CTRL(ENET_PAD_CTRL),
+        MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC  | MUX_PAD_CTRL(ENET_PAD_CTRL),
+        MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0  | MUX_PAD_CTRL(ENET_PAD_CTRL),
+        MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1  | MUX_PAD_CTRL(ENET_PAD_CTRL),
+        MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2  | MUX_PAD_CTRL(ENET_PAD_CTRL),
+        MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3  | MUX_PAD_CTRL(ENET_PAD_CTRL),
+        MX6Q_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
+        MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK  | MUX_PAD_CTRL(ENET_PAD_CTRL),
+        // pad configuration as GPIO for PHY setup
+        MX6Q_PAD_RGMII_RXC__GPIO_6_30       | MUX_PAD_CTRL(NO_PAD_CTRL),
+        MX6Q_PAD_RGMII_RD0__GPIO_6_25       | MUX_PAD_CTRL(NO_PAD_CTRL),
+        MX6Q_PAD_RGMII_RD1__GPIO_6_27       | MUX_PAD_CTRL(NO_PAD_CTRL),
+        MX6Q_PAD_RGMII_RD2__GPIO_6_28       | MUX_PAD_CTRL(NO_PAD_CTRL),
+        MX6Q_PAD_RGMII_RD3__GPIO_6_29       | MUX_PAD_CTRL(NO_PAD_CTRL),
+        MX6Q_PAD_RGMII_RX_CTL__GPIO_6_24    | MUX_PAD_CTRL(NO_PAD_CTRL),
+        MX6Q_PAD_EIM_D23__GPIO_3_23         | MUX_PAD_CTRL(NO_PAD_CTRL),
+    );
+
+    /* Need delay 10ms according to KSZ9021 spec */
+    udelay(1000 * 10);
+    /* release PHY from reset */
+    gpio_set_value(GPIO_NR_PHY_NRST, 1);
+    /* KSZ9021 spec recommends to wait 100us before sending any commands */
+    udelay(100);
+
+    /* reconfigure pins from GPIO for PHY setup to ethernet usage */
+    IMX_IOMUX_V3_SETUP_MULTIPLE_PADS(
+        base,
+        MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC  | MUX_PAD_CTRL(ENET_PAD_CTRL),
+        MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0  | MUX_PAD_CTRL(ENET_PAD_CTRL),
+        MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1  | MUX_PAD_CTRL(ENET_PAD_CTRL),
+        MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2  | MUX_PAD_CTRL(ENET_PAD_CTRL),
+        MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3  | MUX_PAD_CTRL(ENET_PAD_CTRL),
+        MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
+    );
+
+#elif defined(CONFIG_PLAT_IMX6SX)
+
+    /*
+     * default pad configuration for these pins
+     *     PAD_ENETx_MDC
+     *     PAD_ENETx_MDIO
+     *     PAD_ENETx_RX_CLK
+     *     PAD_ENETx_TX_CLK
+     *     PAD_RGMIIx_TD[0-3]
+     *     PAD_RGMIIx_RXC
+     *     PAD_RGMIIx_RX_CTL
+     *     PAD_RGMIIx_RD[0-3]
+     *     PAD_RGMIIx_TXC
+     *     PAD_RGMIIx_TX_CTL
+     *   is
+     *     HYS=0, PUS=00 (100KOHM_PD), PUE=0, PKE=1, ODE=0,
+     *     SPEED=10 (Medium 100 MHz), DSE=110 (40OHM), SRE=0
+     *
+     *  PHY connection
+     *    ENETx_RX_CLK <--> PHY INT
+     *    ENETx_TX_CLK <--> PHY CLK_25M
+     *
+     *  PHY reset
+     *      ENET2_CRS -> nRST of PHY1
+     *      ENET2_COL -> nRST of PHY2
+     *    there is not external pull-up, so GPIO port must enable one
+     *
+     * PHY MDIO
+     *     MDC and MDIO have an internal pull-up when acting as input
+     *     MDIO is an OD-gate, needs an external 1.5k pull-up
+     *     both PHYs are connected to MDIO of ENET1
+     *
+     * PHY strapping pins
+     *   PHYADDRESS[4:0] = 00xxx
+     *       RXD0 (PHYADDRESS0, weak pull-down)        <- RGMIIx_RD0
+     *       RXD1 (PHYADDRESS1, weak pull-down)        <- RGMIIx_RD1
+     *       LED_ACT (PHYADDRESS3, weak pull-up)       <- PHY1: floating, PHY2: 10k pull down
+     *   mode[3:0] = 1100 (RGMII, PLLOFF, INT)
+     *       RX_DV (MODE0, weak pull-down)             <- RGMIIx_RX_CTL
+     *       RXD2 (MODE1, weak pull-down)              <- RGMIIx_RD2
+     *       LED_1000 (MODE2, weak pull up)            <- floating
+     *       RXD3 (MODE3, weak pull-down)              <- RGMIIx_RD3
+     *   IO level 1.8V
+     *       RX_CLK (0=1.5V, 1=1.8V, weak pull-down)   <- RGMIIx_RXC
+     *
+     * The values below  are from u-boot of boundary devices 2020.10. Note that
+     * PUS=00 is PAD_CTL_PUS_100K_DOWN, ie that is used if nothing is set
+     */
+
+#define PAD_CTL_ENET        (PAD_CTL_SPEED_HIGH | PAD_CTL_DSE_48ohm | PAD_CTL_SRE_FAST)
+#define PAD_CTL_ENET_MD     (PAD_CTL_SPEED_MED | PAD_CTL_DSE_120ohm | PAD_CTL_SRE_FAST)
+#define PAD_CTL_GPIO        (PAD_CTL_SPEED_MED | PAD_CTL_DSE_40ohm | PAD_CTL_SRE_SLOW)
+
+#define PAD_CTL_GPIO_IN_WEAK_PD    ( PAD_CTL_GPIO | PAD_CTL_HYS)
+#define PAD_CTL_GPIO_IN_WEAK_PU    ( PAD_CTL_GPIO | PAD_CTL_HYS | PAD_CTL_PUS_100K_UP )
+
+    /* PHY to GPIO mapping. */
+#define GPIO_NR_PHY1_NRST       IMX_GPIO_NR(2, 7)  // uses ENET2_CRS
+#define GPIO_NR_PHY1_ADDR0      IMX_GPIO_NR(5, 0)  // uses RGMII1_RD0
+#define GPIO_NR_PHY1_ADDR1      IMX_GPIO_NR(5, 1)  // uses RGMII1_RD0
+#define GPIO_NR_PHY1_MODE0      IMX_GPIO_NR(5, 4)  // uses RGMII1_RX_CTL
+#define GPIO_NR_PHY1_MODE1      IMX_GPIO_NR(5, 2)  // uses RGMII1_RD2
+#define GPIO_NR_PHY1_MODE3      IMX_GPIO_NR(5, 3)  // uses RGMII1_RD3
+#define GPIO_NR_PHY1_VIO        IMX_GPIO_NR(5, 5)  // uses RGMII1_RXC
+#define GPIO_NR_PHY1_INT        IMX_GPIO_NR(2, 4)  // uses ENET1_RX_CLK
+#define GPIO_NR_PHY1_CLK_25M    IMX_GPIO_NR(2, 5)  // uses ENET1_TX_CLK
+
+#define GPIO_NR_PHY2_NRST       IMX_GPIO_NR(2, 6)  // uses ENET2_COL
+#define GPIO_NR_PHY2_ADDR0      IMX_GPIO_NR(5, 12) // uses RGMII2_RD0
+#define GPIO_NR_PHY2_ADDR1      IMX_GPIO_NR(5, 13) // uses RGMII2_RD0
+#define GPIO_NR_PHY2_MODE0      IMX_GPIO_NR(5, 16) // uses RGMII2_RX_CTL
+#define GPIO_NR_PHY2_MODE1      IMX_GPIO_NR(5, 14) // uses RGMII2_RD2
+#define GPIO_NR_PHY2_MODE3      IMX_GPIO_NR(5, 15) // uses RGMII2_RD3
+#define GPIO_NR_PHY2_VIO        IMX_GPIO_NR(5, 17) // uses RGMII2_RXC
+#define GPIO_NR_PHY2_INT        IMX_GPIO_NR(2, 8)  // uses ENET2_RX_CLK
+#define GPIO_NR_PHY2_CLK_25M    IMX_GPIO_NR(2, 9)  // uses ENET2_TX_CLK
+
+    /* PYH#1 for enet1: put into reset */
+    gpio_direction_output(GPIO_NR_PHY1_NRST,  0, io_ops);
+    /* PHY_ADDR = b00100 (4) */
+    gpio_direction_output(GPIO_NR_PHY1_ADDR0, 0, io_ops);
+    gpio_direction_output(GPIO_NR_PHY1_ADDR1, 0, io_ops);
+    /* MODE = b0011 (RGMII, PLLOFF, INT)*/
+    gpio_direction_output(GPIO_NR_PHY1_MODE0, 0, io_ops);
+    gpio_direction_output(GPIO_NR_PHY1_MODE1, 0, io_ops);
+    gpio_direction_output(GPIO_NR_PHY1_MODE3, 1, io_ops);
+    /* I/O voltage is 1.8V */
+    gpio_direction_output(GPIO_NR_PHY1_VIO,   1, io_ops);
+
+    /* get interrupt from PHY */
+    gpio_direction_input(GPIO_NR_PHY1_INT, io_ops);
+    /* get 25 MHz clock input from PHY */
+    gpio_direction_input(GPIO_NR_PHY1_CLK_25M, io_ops);
+
+    /* PYH#2 for enet2: put into reset */
+    gpio_direction_output(GPIO_NR_PHY2_NRST,  0, io_ops);
+    /* PHYADDR = b00101 (5) */
+    gpio_direction_output(GPIO_NR_PHY2_ADDR0, 1, io_ops);
+    gpio_direction_output(GPIO_NR_PHY2_ADDR1, 0, io_ops);
+    /* MODE = b0011 (RGMII, PLLOFF, INT)*/
+    gpio_direction_output(GPIO_NR_PHY2_MODE0, 0, io_ops);
+    gpio_direction_output(GPIO_NR_PHY2_MODE1, 0, io_ops);
+    gpio_direction_output(GPIO_NR_PHY2_MODE3, 1, io_ops);
+    /* I/O voltage is 1.8V */
+    gpio_direction_output(GPIO_NR_PHY2_VIO,   1, io_ops);
+
+    /* get 25 MHz clock input from PHY */
+    gpio_direction_input(GPIO_NR_PHY2_CLK_25M, io_ops);
+    /* get interrupt from PHY */
+    gpio_direction_input(GPIO_NR_PHY2_INT, io_ops);
+
+    /* set pad configuration (after we have set GPIOs) */
+    IMX_IOMUX_V3_SETUP_MULTIPLE_PADS(
+        base,
+        /* shared mdio */
+        MX6SX_PAD_ENET1_MDC__ENET1_MDC        | MUX_PAD_CTRL(PAD_CTL_ENET_MD | PAD_CTL_PUS_100K_UP),
+        MX6SX_PAD_ENET1_MDIO__ENET1_MDIO      | MUX_PAD_CTRL(PAD_CTL_ENET_MD),
+        /* fec1 */
+        MX6SX_PAD_RGMII1_TD0__ENET1_TX_DATA_0 | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII1_TD1__ENET1_TX_DATA_1 | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII1_TD2__ENET1_TX_DATA_2 | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII1_TD3__ENET1_TX_DATA_3 | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII1_TXC__ENET1_RGMII_TXC | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII1_TX_CTL__ENET1_TX_EN  | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_ENET1_RX_CLK__GPIO2_IO_4    | MUX_PAD_CTRL(PAD_CTL_GPIO_IN_WEAK_PU),
+        MX6SX_PAD_ENET1_TX_CLK__GPIO2_IO_5    | MUX_PAD_CTRL(PAD_CTL_GPIO_IN_WEAK_PU),
+
+        /* PHY Reset */
+        MX6SX_PAD_ENET2_CRS__GPIO2_IO_7       | MUX_PAD_CTRL(PAD_CTL_GPIO),
+        /* PHY strapping input */
+        MX6SX_PAD_RGMII1_RD0__GPIO5_IO_0      | MUX_PAD_CTRL(PAD_CTL_GPIO),
+        MX6SX_PAD_RGMII1_RD1__GPIO5_IO_1      | MUX_PAD_CTRL(PAD_CTL_GPIO),
+        MX6SX_PAD_RGMII1_RD2__GPIO5_IO_2      | MUX_PAD_CTRL(PAD_CTL_GPIO),
+        MX6SX_PAD_RGMII1_RD3__GPIO5_IO_3      | MUX_PAD_CTRL(PAD_CTL_GPIO),
+        MX6SX_PAD_RGMII1_RX_CTL__GPIO5_IO_4   | MUX_PAD_CTRL(PAD_CTL_GPIO),
+        MX6SX_PAD_RGMII1_RXC__GPIO5_IO_5      | MUX_PAD_CTRL(PAD_CTL_GPIO),
+
+        /* fec2 */
+        MX6SX_PAD_RGMII2_TD0__ENET2_TX_DATA_0 | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII2_TD1__ENET2_TX_DATA_1 | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII2_TD2__ENET2_TX_DATA_2 | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII2_TD3__ENET2_TX_DATA_3 | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII2_TXC__ENET2_RGMII_TXC | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII2_TX_CTL__ENET2_TX_EN  | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_ENET2_RX_CLK__GPIO2_IO_8    | MUX_PAD_CTRL(PAD_CTL_GPIO_IN_WEAK_PU),
+        MX6SX_PAD_ENET2_TX_CLK__GPIO2_IO_9    | MUX_PAD_CTRL(PAD_CTL_GPIO_IN_WEAK_PU),
+
+        /* PHY Reset */
+        MX6SX_PAD_ENET2_COL__GPIO2_IO_6       | MUX_PAD_CTRL(PAD_CTL_GPIO),
+        /* PHY strapping input */
+        MX6SX_PAD_RGMII2_RD0__GPIO5_IO_12     | MUX_PAD_CTRL(PAD_CTL_GPIO),
+        MX6SX_PAD_RGMII2_RD1__GPIO5_IO_13     | MUX_PAD_CTRL(PAD_CTL_GPIO),
+        MX6SX_PAD_RGMII2_RD2__GPIO5_IO_14     | MUX_PAD_CTRL(PAD_CTL_GPIO),
+        MX6SX_PAD_RGMII2_RD3__GPIO5_IO_15     | MUX_PAD_CTRL(PAD_CTL_GPIO),
+        MX6SX_PAD_RGMII2_RX_CTL__GPIO5_IO_16  | MUX_PAD_CTRL(PAD_CTL_GPIO),
+        MX6SX_PAD_RGMII2_RXC__GPIO5_IO_17     | MUX_PAD_CTRL(PAD_CTL_GPIO),
+    );
+
+    /* AR8035 PHY specs say clock must be active 1 ms before releasing reset */
+    udelay(1000);
+
+    /* take PHYs out of reset, it will sample the IO pins for strapping*/
+    gpio_set_value(GPIO_NR_PHY1_NRST, 1);
+    gpio_set_value(GPIO_NR_PHY2_NRST, 1);
+
+    /* AR8035 PHY specs don't mention strap hold time, us ms should be safe */
+    udelay(50);
+
+    IMX_IOMUX_V3_SETUP_MULTIPLE_PADS(
+        base,
+        /* enet1 */
+        MX6SX_PAD_RGMII1_RD0__ENET1_RX_DATA_0 | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII1_RD1__ENET1_RX_DATA_1 | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII1_RD2__ENET1_RX_DATA_2 | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII1_RD3__ENET1_RX_DATA_3 | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII1_RX_CTL__ENET1_RX_EN | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII1_RXC__ENET1_RX_CLK | MUX_PAD_CTRL(PAD_CTL_ENET),
+        /* enet2 */
+        MX6SX_PAD_RGMII2_RD0__ENET2_RX_DATA_0 | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII2_RD1__ENET2_RX_DATA_1 | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII2_RD2__ENET2_RX_DATA_2 | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII2_RD3__ENET2_RX_DATA_3 | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII2_RX_CTL__ENET2_RX_EN | MUX_PAD_CTRL(PAD_CTL_ENET),
+        MX6SX_PAD_RGMII2_RXC__ENET2_RX_CLK | MUX_PAD_CTRL(PAD_CTL_ENET),
+    );
+
+#else
+#error "unsupported platform"
+#endif
+
+    if (unmapOnExit) {
+        UNRESOURCE(&io_ops->io_mapper, IOMUXC, base);
+    }
+    return 0;
+}
diff --git a/libethdrivers/src/plat/imx6/uboot/imx_board.h b/libethdrivers/src/plat/imx6/uboot/imx_board.h
new file mode 100644
index 0000000..48cfdcf
--- /dev/null
+++ b/libethdrivers/src/plat/imx6/uboot/imx_board.h
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2020, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <platsupport/io.h>
+
+int setup_iomux_enet(ps_io_ops_t *io_ops);
diff --git a/libethdrivers/src/plat/imx6/uboot/imx_pins.h b/libethdrivers/src/plat/imx6/uboot/imx_pins.h
new file mode 100644
index 0000000..c758ae5
--- /dev/null
+++ b/libethdrivers/src/plat/imx6/uboot/imx_pins.h
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2020, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * 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
+ * (at your option) 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, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#pragma once
+
+#include <utils/util.h>
+#include <stdint.h>
+
+#define NO_PAD_CTRL             BIT(17)
+
+#define PAD_CTL_HYS             BIT(16)
+
+
+#ifdef CONFIG_PLAT_IMX6SX
+
+// according to u-boot, this setting apply to all i.MX6 platforms
+
+#define PAD_CTL_PUS_100K_DOWN   (0 << 14 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_47K_UP      (1 << 14 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_100K_UP     (2 << 14 | PAD_CTL_PUE)
+#define PAD_CTL_PUS_22K_UP      (3 << 14 | PAD_CTL_PUE)
+
+#define PAD_CTL_PUE             ( BIT(13) | PAD_CTL_PKE)
+
+#else
+
+// it's a bit unclear if this just works by chance or some bits do not really
+// matter on some platforms
+
+#define PAD_CTL_PUS_100K_DOWN   (0 << 14)
+#define PAD_CTL_PUS_47K_UP      (1 << 14)
+#define PAD_CTL_PUS_100K_UP     (2 << 14)
+#define PAD_CTL_PUS_22K_UP      (3 << 14)
+
+#define PAD_CTL_PUE             BIT(13)
+
+#endif
+
+
+#define PAD_CTL_PKE             BIT(12)
+
+#define PAD_CTL_ODE             BIT(11)
+
+// u-boot 2018.07; iomux-v3.h has a spacial handling for i.MX6 SoloLite only,
+// #if defined(CONFIG_MX6SL)
+// #define PAD_CTL_SPEED_LOW    (1 << 6)
+// #else
+#define PAD_CTL_SPEED_LOW       (0 << 6)
+// #endif
+#define PAD_CTL_SPEED_MED       (2 << 6)
+#define PAD_CTL_SPEED_HIGH      (3 << 6)
+
+#define PAD_CTL_DSE_DISABLE     (0 << 3)
+#define PAD_CTL_DSE_240ohm      (1 << 3)
+#define PAD_CTL_DSE_120ohm      (2 << 3)
+#define PAD_CTL_DSE_80ohm       (3 << 3)
+#define PAD_CTL_DSE_60ohm       (4 << 3)
+#define PAD_CTL_DSE_48ohm       (5 << 3)
+#define PAD_CTL_DSE_40ohm       (6 << 3)
+#define PAD_CTL_DSE_34ohm       (7 << 3)
+
+#define PAD_CTL_SRE_SLOW        (0 << 0)
+#define PAD_CTL_SRE_FAST        (1 << 0)
+
+#define NO_MUX_I                0
+#define NO_PAD_I                0
+
+typedef uint64_t iomux_v3_cfg_t;
+
+#define MUX_CTRL_OFS_SHIFT          0
+#define MUX_CTRL_OFS(x)             ((iomux_v3_cfg_t)(x) << MUX_CTRL_OFS_SHIFT)
+#define MUX_CTRL_OFS_MASK           MUX_CTRL_OFS(0xfff)
+
+#define MUX_PAD_CTRL_OFS_SHIFT      12
+#define MUX_PAD_CTRL_OFS(x)         ((iomux_v3_cfg_t)(x) << MUX_PAD_CTRL_OFS_SHIFT)
+#define MUX_PAD_CTRL_OFS_MASK       MUX_PAD_CTRL_OFS(0xfff)
+
+#define MUX_SEL_INPUT_OFS_SHIFT     24
+#define MUX_SEL_INPUT_OFS(x)        ((iomux_v3_cfg_t)(x) << MUX_SEL_INPUT_OFS_SHIFT)
+#define MUX_SEL_INPUT_OFS_MASK      MUX_SEL_INPUT_OFS(0xfff)
+
+#define MUX_MODE_SHIFT              36
+#define MUX_MODE(x)                 ((iomux_v3_cfg_t)(x) << MUX_MODE_SHIFT)
+#define MUX_MODE_MASK               MUX_MODE(0x3f)
+
+#define MUX_PAD_CTRL_SHIFT          42
+#define MUX_PAD_CTRL(x)             ((iomux_v3_cfg_t)(x) << MUX_PAD_CTRL_SHIFT)
+#define MUX_PAD_CTRL_MASK           MUX_PAD_CTRL(0x3ffff)
+
+#define MUX_SEL_INPUT_SHIFT         60
+#define MUX_SEL_INPUT(x)            ((iomux_v3_cfg_t)(x) << MUX_SEL_INPUT_SHIFT)
+#define MUX_SEL_INPUT_MASK          MUX_SEL_INPUT(0xf)
+
+#define IOMUX_PAD( \
+            pad_ctrl_ofs, \
+            mux_ctrl_ofs, \
+            mux_mode, \
+            sel_input_ofs,  \
+            sel_input, \
+            pad_ctrl) \
+    ( MUX_CTRL_OFS(mux_ctrl_ofs) | \
+      MUX_PAD_CTRL_OFS(pad_ctrl_ofs) | \
+      MUX_SEL_INPUT_OFS(sel_input_ofs) | \
+      MUX_MODE(mux_mode) | \
+      MUX_PAD_CTRL(pad_ctrl) | \
+      MUX_SEL_INPUT(sel_input) )
+
+#define IOMUX_CONFIG_SION       BIT(4)
diff --git a/libethdrivers/src/plat/imx6/uboot/list.h b/libethdrivers/src/plat/imx6/uboot/list.h
index f7c18cf..cd67487 100644
--- a/libethdrivers/src/plat/imx6/uboot/list.h
+++ b/libethdrivers/src/plat/imx6/uboot/list.h
@@ -1,5 +1,6 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright Linux
  */
 
 #pragma once
diff --git a/libethdrivers/src/plat/imx6/uboot/mdio.h b/libethdrivers/src/plat/imx6/uboot/mdio.h
index 793c916..5ed64d4 100644
--- a/libethdrivers/src/plat/imx6/uboot/mdio.h
+++ b/libethdrivers/src/plat/imx6/uboot/mdio.h
@@ -1,5 +1,5 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 /*
diff --git a/libethdrivers/src/plat/imx6/uboot/micrel.c b/libethdrivers/src/plat/imx6/uboot/micrel.c
index e6f5514..d1ee5b8 100644
--- a/libethdrivers/src/plat/imx6/uboot/micrel.c
+++ b/libethdrivers/src/plat/imx6/uboot/micrel.c
@@ -1,10 +1,11 @@
 /*
- * @TAG(OTHER_GPL)
- */
-
-/*
  * Micrel PHY drivers
  *
+ * Copyright 2010-2011 Freescale Semiconductor, Inc.
+ * author Andy Fleming
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
  * 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
@@ -12,19 +13,15 @@
  *
  * 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
+ * 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, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
- *
- * Copyright 2010-2011 Freescale Semiconductor, Inc.
- * author Andy Fleming
- *
  */
-#include "config.h"
+
 #include "common.h"
 #include "micrel.h"
 #include "phy.h"
@@ -32,81 +29,84 @@
 #define CONFIG_PHY_MICREL_KSZ9021
 
 static struct phy_driver KSZ804_driver = {
-	.name = "Micrel KSZ804",
-	.uid = 0x221510,
-	.mask = 0xfffff0,
-	.features = PHY_BASIC_FEATURES,
-	.config = &genphy_config,
-	.startup = &genphy_startup,
-	.shutdown = &genphy_shutdown,
+    .name = "Micrel KSZ804",
+    .uid = 0x221510,
+    .mask = 0xfffff0,
+    .features = PHY_BASIC_FEATURES,
+    .config = &genphy_config,
+    .startup = &genphy_startup,
+    .shutdown = &genphy_shutdown,
 };
 
 /* ksz9021 PHY Registers */
-#define MII_KSZ9021_EXTENDED_CTRL	0x0b
-#define MII_KSZ9021_EXTENDED_DATAW	0x0c
-#define MII_KSZ9021_EXTENDED_DATAR	0x0d
-#define MII_KSZ9021_PHY_CTL		0x1f
-#define MIIM_KSZ9021_PHYCTL_1000	(BIT(6))
-#define MIIM_KSZ9021_PHYCTL_100		(BIT(5))
-#define MIIM_KSZ9021_PHYCTL_10		(BIT(4))
-#define MIIM_KSZ9021_PHYCTL_DUPLEX	(BIT(3))
+#define MII_KSZ9021_EXTENDED_CTRL   0x0b
+#define MII_KSZ9021_EXTENDED_DATAW  0x0c
+#define MII_KSZ9021_EXTENDED_DATAR  0x0d
+#define MII_KSZ9021_PHY_CTL     0x1f
+#define MIIM_KSZ9021_PHYCTL_1000    (BIT(6))
+#define MIIM_KSZ9021_PHYCTL_100     (BIT(5))
+#define MIIM_KSZ9021_PHYCTL_10      (BIT(4))
+#define MIIM_KSZ9021_PHYCTL_DUPLEX  (BIT(3))
 
-#define CTRL1000_PREFER_MASTER		(BIT(10))
-#define CTRL1000_CONFIG_MASTER		(BIT(11))
-#define CTRL1000_MANUAL_CONFIG		(BIT(12))
+#define CTRL1000_PREFER_MASTER      (BIT(10))
+#define CTRL1000_CONFIG_MASTER      (BIT(11))
+#define CTRL1000_MANUAL_CONFIG      (BIT(12))
 
 int ksz9021_phy_extended_write(struct phy_device *phydev, int regnum, uint16_t val)
 {
-	/* extended registers */
-	phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000);
-	return phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAW, val);
+    /* extended registers */
+    phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum | 0x8000);
+    return phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAW, val);
 }
 
 int ksz9021_phy_extended_read(struct phy_device *phydev, int regnum)
 {
-	/* extended registers */
-	phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum);
-	return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR);
+    /* extended registers */
+    phy_write(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_CTRL, regnum);
+    return phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_EXTENDED_DATAR);
 }
 
 /* Micrel ksz9021 */
 int ksz9021_config(struct phy_device *phydev)
 {
-	unsigned ctrl1000 = 0;
-	const unsigned master = CTRL1000_PREFER_MASTER |
-			CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG;
-	unsigned features = phydev->drv->features;
+    unsigned ctrl1000 = 0;
+    const unsigned master = CTRL1000_PREFER_MASTER |
+                            CTRL1000_CONFIG_MASTER | CTRL1000_MANUAL_CONFIG;
+    unsigned features = phydev->drv->features;
 
-	/* force master mode for 1000BaseT due to chip errata */
-	if (features & SUPPORTED_1000baseT_Half)
-		ctrl1000 |= ADVERTISE_1000HALF | master;
-	if (features & SUPPORTED_1000baseT_Full)
-		ctrl1000 |= ADVERTISE_1000FULL | master;
-	phydev->advertising = phydev->supported = features;
-	phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000);
-	genphy_config_aneg(phydev);
-	genphy_restart_aneg(phydev);
-	return 0;
+    /* force master mode for 1000BaseT due to chip errata */
+    if (features & SUPPORTED_1000baseT_Half) {
+        ctrl1000 |= ADVERTISE_1000HALF | master;
+    }
+    if (features & SUPPORTED_1000baseT_Full) {
+        ctrl1000 |= ADVERTISE_1000FULL | master;
+    }
+    phydev->advertising = phydev->supported = features;
+    phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, ctrl1000);
+    genphy_config_aneg(phydev);
+    genphy_restart_aneg(phydev);
+    return 0;
 }
 
-void print_phyregs(struct phy_device *phydev){
+void print_phyregs(struct phy_device *phydev)
+{
     int i;
     printf("\n\nPHY config\n");
     printf("\n\nIEEE\n");
-    for(i = 0; i < 16; i++){
-	    uint16_t val = phy_read(phydev, MDIO_DEVAD_NONE, i);
+    for (i = 0; i < 16; i++) {
+        uint16_t val = phy_read(phydev, MDIO_DEVAD_NONE, i);
         printf("%3d | 0x%04x\n", i, val);
     }
 
     printf("vendor\n");
-    for(i = 16; i < 32; i++){
-	    uint16_t val = phy_read(phydev, MDIO_DEVAD_NONE, i);
+    for (i = 16; i < 32; i++) {
+        uint16_t val = phy_read(phydev, MDIO_DEVAD_NONE, i);
         printf("%3d | 0x%04x\n", i, val);
     }
 
     printf("extended\n");
-    for(i = 257; i < 264; i++){
-	    uint16_t val = ksz9021_phy_extended_read(phydev, i);
+    for (i = 257; i < 264; i++) {
+        uint16_t val = ksz9021_phy_extended_read(phydev, i);
         printf("%3d | 0x%04x\n", i, val);
     }
     printf("\n\n");
@@ -114,38 +114,38 @@
 
 int ksz9021_startup(struct phy_device *phydev)
 {
-	unsigned phy_ctl;
-	genphy_update_link(phydev);
-	phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_PHY_CTL);
+    unsigned phy_ctl;
+    genphy_update_link(phydev);
+    phy_ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_KSZ9021_PHY_CTL);
 
-	if (phy_ctl & MIIM_KSZ9021_PHYCTL_DUPLEX){
-		phydev->duplex = DUPLEX_FULL;
-	}else{
-		phydev->duplex = DUPLEX_HALF;
+    if (phy_ctl & MIIM_KSZ9021_PHYCTL_DUPLEX) {
+        phydev->duplex = DUPLEX_FULL;
+    } else {
+        phydev->duplex = DUPLEX_HALF;
     }
-	if (phy_ctl & MIIM_KSZ9021_PHYCTL_1000){
-		phydev->speed = SPEED_1000;
-    }else if (phy_ctl & MIIM_KSZ9021_PHYCTL_100){
-		phydev->speed = SPEED_100;
-	}else if (phy_ctl & MIIM_KSZ9021_PHYCTL_10){
-		phydev->speed = SPEED_10;
+    if (phy_ctl & MIIM_KSZ9021_PHYCTL_1000) {
+        phydev->speed = SPEED_1000;
+    } else if (phy_ctl & MIIM_KSZ9021_PHYCTL_100) {
+        phydev->speed = SPEED_100;
+    } else if (phy_ctl & MIIM_KSZ9021_PHYCTL_10) {
+        phydev->speed = SPEED_10;
     }
-	return 0;
+    return 0;
 }
 
 static struct phy_driver ksz9021_driver = {
-	.name = "Micrel ksz9021",
-	.uid  = 0x221610,
-	.mask = 0xfffff0,
-	.features = PHY_GBIT_FEATURES,
-	.config = &ksz9021_config,
-	.startup = &ksz9021_startup,
-	.shutdown = &genphy_shutdown,
+    .name = "Micrel ksz9021",
+    .uid  = 0x221610,
+    .mask = 0xfffff0,
+    .features = PHY_GBIT_FEATURES,
+    .config = &ksz9021_config,
+    .startup = &ksz9021_startup,
+    .shutdown = &genphy_shutdown,
 };
 
 int phy_micrel_init(void)
 {
-	phy_register(&KSZ804_driver);
-	phy_register(&ksz9021_driver);
-	return 0;
+    phy_register(&KSZ804_driver);
+    phy_register(&ksz9021_driver);
+    return 0;
 }
diff --git a/libethdrivers/src/plat/imx6/uboot/micrel.h b/libethdrivers/src/plat/imx6/uboot/micrel.h
index 0512515..0a09e08 100644
--- a/libethdrivers/src/plat/imx6/uboot/micrel.h
+++ b/libethdrivers/src/plat/imx6/uboot/micrel.h
@@ -1,5 +1,6 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  */
 
 #pragma once
diff --git a/libethdrivers/src/plat/imx6/uboot/mii.h b/libethdrivers/src/plat/imx6/uboot/mii.h
index 5302ad3..9921a33 100644
--- a/libethdrivers/src/plat/imx6/uboot/mii.h
+++ b/libethdrivers/src/plat/imx6/uboot/mii.h
@@ -1,5 +1,5 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 /*
diff --git a/libethdrivers/src/plat/imx6/uboot/miiphy.h b/libethdrivers/src/plat/imx6/uboot/miiphy.h
index cca3ba0..d3d38fa 100644
--- a/libethdrivers/src/plat/imx6/uboot/miiphy.h
+++ b/libethdrivers/src/plat/imx6/uboot/miiphy.h
@@ -1,5 +1,5 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 /*----------------------------------------------------------------------------+
diff --git a/libethdrivers/src/plat/imx6/uboot/miiphyutil.c b/libethdrivers/src/plat/imx6/uboot/miiphyutil.c
index bc0b76a..c1fbcb7 100644
--- a/libethdrivers/src/plat/imx6/uboot/miiphyutil.c
+++ b/libethdrivers/src/plat/imx6/uboot/miiphyutil.c
@@ -1,13 +1,13 @@
 /*
- * @TAG(OTHER_GPL)
- */
-
-/*
- * (C) Copyright 2001
- * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
+ * This provides a bit-banged interface to the ethernet MII management
+ * channel.
  *
- * See file CREDITS for list of people who contributed to this
- * project.
+ * (C) Copyright 2001, Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
+ * Copyright (C) 2020, HENSOLDT Cyber GmbH
+ *
+ * See file U-Boot CREDITS for list of people who contributed to this project.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -23,34 +23,17 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
- */
-
-/*
- * This provides a bit-banged interface to the ethernet MII management
- * channel.
+ *
  */
 
 #include "common.h"
 #include "miiphy.h"
 #include "phy.h"
-
 #include "list.h"
 #include "fec_mxc.h"
 #include <stdlib.h>
 #include <string.h>
-#include "../unimplemented.h"
 
-#define BUG_ON(x) do {} while(0)
-
-/* local debug macro */
-#undef MII_DEBUG
-
-#undef debug
-#ifdef MII_DEBUG
-#define debug(fmt, args...)	printf(fmt, ##args)
-#else
-#define debug(fmt, args...)
-#endif /* MII_DEBUG */
 
 static struct list_head mii_devs;
 static struct mii_dev *current_mii;
@@ -60,21 +43,22 @@
  */
 struct mii_dev *miiphy_get_dev_by_name(const char *devname)
 {
-	struct list_head *entry;
-	struct mii_dev *dev;
+    struct list_head *entry;
+    struct mii_dev *dev;
 
-	if (!devname) {
-		printf("NULL device name!\n");
-		return NULL;
-	}
+    if (!devname) {
+        printf("NULL device name!\n");
+        return NULL;
+    }
 
-	list_for_each(entry, &mii_devs) {
-		dev = list_entry(entry, struct mii_dev, link);
-		if (strcmp(dev->name, devname) == 0)
-			return dev;
-	}
+    list_for_each(entry, &mii_devs) {
+        dev = list_entry(entry, struct mii_dev, link);
+        if (strcmp(dev->name, devname) == 0) {
+            return dev;
+        }
+    }
 
-	return NULL;
+    return NULL;
 }
 
 /*****************************************************************************
@@ -83,28 +67,28 @@
  */
 void miiphy_init(void)
 {
-	mii_devs.next = &mii_devs;
-	mii_devs.prev = &mii_devs;
-	current_mii = NULL;
+    mii_devs.next = &mii_devs;
+    mii_devs.prev = &mii_devs;
+    current_mii = NULL;
 }
 
 static int legacy_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
 {
-	unsigned short val;
-	int ret;
-	struct legacy_mii_dev *ldev = bus->priv;
+    unsigned short val;
+    int ret;
+    struct legacy_mii_dev *ldev = bus->priv;
 
-	ret = ldev->read(bus->name, addr, reg, &val);
+    ret = ldev->read(bus->name, addr, reg, &val);
 
-	return ret ? -1 : (int)val;
+    return ret ? -1 : (int)val;
 }
 
 static int legacy_miiphy_write(struct mii_dev *bus, int addr, int devad,
-				int reg, u16 val)
+                               int reg, u16 val)
 {
-	struct legacy_mii_dev *ldev = bus->priv;
+    struct legacy_mii_dev *ldev = bus->priv;
 
-	return ldev->write(bus->name, addr, reg, val);
+    return ldev->write(bus->name, addr, reg, val);
 }
 
 /*****************************************************************************
@@ -113,176 +97,183 @@
  * This API is now deprecated. Please use mdio_alloc and mdio_register, instead.
  */
 void miiphy_register(const char *name,
-		      int (*read)(const char *devname, unsigned char addr,
-				   unsigned char reg, unsigned short *value),
-		      int (*write)(const char *devname, unsigned char addr,
-				    unsigned char reg, unsigned short value))
+                     int (*read)(const char *devname, unsigned char addr,
+                                 unsigned char reg, unsigned short *value),
+                     int (*write)(const char *devname, unsigned char addr,
+                                  unsigned char reg, unsigned short value))
 {
-	struct mii_dev *new_dev;
-	struct legacy_mii_dev *ldev;
+    struct mii_dev *new_dev;
+    struct legacy_mii_dev *ldev;
 
-	BUG_ON(strlen(name) >= MDIO_NAME_LEN);
+    assert(strlen(name) < MDIO_NAME_LEN);
 
-	/* check if we have unique name */
-	new_dev = miiphy_get_dev_by_name(name);
-	if (new_dev) {
-		printf("miiphy_register: non unique device name '%s'\n", name);
-		return;
-	}
+    /* check if we have unique name */
+    new_dev = miiphy_get_dev_by_name(name);
+    if (new_dev) {
+        ZF_LOGE("miiphy_register: non unique device name '%s'", name);
+        return;
+    }
 
-	/* allocate memory */
-	new_dev = mdio_alloc();
-	ldev = malloc(sizeof(*ldev));
+    /* allocate memory */
+    new_dev = mdio_alloc();
+    ldev = malloc(sizeof(*ldev));
 
-	if (new_dev == NULL || ldev == NULL) {
-		printf("miiphy_register: cannot allocate memory for '%s'\n",
-			name);
-		return;
-	}
+    if (new_dev == NULL || ldev == NULL) {
+        ZF_LOGE("miiphy_register: cannot allocate memory for '%s'", name);
+        return;
+    }
 
-	/* initalize mii_dev struct fields */
-	new_dev->read = legacy_miiphy_read;
-	new_dev->write = legacy_miiphy_write;
-	strncpy(new_dev->name, name, MDIO_NAME_LEN);
-	new_dev->name[MDIO_NAME_LEN - 1] = 0;
-	ldev->read = read;
-	ldev->write = write;
-	new_dev->priv = ldev;
+    /* initalize mii_dev struct fields */
+    new_dev->read = legacy_miiphy_read;
+    new_dev->write = legacy_miiphy_write;
+    strncpy(new_dev->name, name, MDIO_NAME_LEN);
+    new_dev->name[MDIO_NAME_LEN - 1] = 0;
+    ldev->read = read;
+    ldev->write = write;
+    new_dev->priv = ldev;
 
-	debug("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n",
-	       new_dev->name, ldev->read, ldev->write);
+    ZF_LOGI("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx",
+            new_dev->name, ldev->read, ldev->write);
 
-	/* add it to the list */
-	list_add_tail(&new_dev->link, &mii_devs);
+    /* add it to the list */
+    list_add_tail(&new_dev->link, &mii_devs);
 
-	if (!current_mii)
-		current_mii = new_dev;
+    if (!current_mii) {
+        current_mii = new_dev;
+    }
 }
 
 struct mii_dev *mdio_alloc(void)
 {
-	struct mii_dev *bus;
+    struct mii_dev *bus;
 
-	bus = malloc(sizeof(*bus));
-	if (!bus)
-		return bus;
+    bus = malloc(sizeof(*bus));
+    if (!bus) {
+        return bus;
+    }
 
-	memset(bus, 0, sizeof(*bus));
+    memset(bus, 0, sizeof(*bus));
 
-	/* initalize mii_dev struct fields */
-	INIT_LIST_HEAD(&bus->link);
+    /* initalize mii_dev struct fields */
+    INIT_LIST_HEAD(&bus->link);
 
-	return bus;
+    return bus;
 }
 
 int mdio_register(struct mii_dev *bus)
 {
-	if (!bus || !bus->name || !bus->read || !bus->write)
-		return -1;
+    if (!bus || !bus->name[0] || !bus->read || !bus->write) {
+        return -1;
+    }
 
-	/* check if we have unique name */
-	if (miiphy_get_dev_by_name(bus->name)) {
-		printf("mdio_register: non unique device name '%s'\n",
-			bus->name);
-		return -1;
-	}
+    /* check if we have unique name */
+    if (miiphy_get_dev_by_name(bus->name)) {
+        ZF_LOGE("mdio_register: non unique device name '%s'", bus->name);
+        return -1;
+    }
 
-	/* add it to the list */
-	list_add_tail(&bus->link, &mii_devs);
+    /* add it to the list */
+    list_add_tail(&bus->link, &mii_devs);
 
-	if (!current_mii)
-		current_mii = bus;
+    if (!current_mii) {
+        current_mii = bus;
+    }
 
-	return 0;
+    return 0;
 }
 
 void mdio_list_devices(void)
 {
-	struct list_head *entry;
+    struct list_head *entry;
 
-	list_for_each(entry, &mii_devs) {
-		int i;
-		struct mii_dev *bus = list_entry(entry, struct mii_dev, link);
+    list_for_each(entry, &mii_devs) {
+        int i;
+        struct mii_dev *bus = list_entry(entry, struct mii_dev, link);
 
-		printf("%s:\n", bus->name);
+        ZF_LOGI("bus '%s':", bus->name);
 
-		for (i = 0; i < PHY_MAX_ADDR; i++) {
-			struct phy_device *phydev = bus->phymap[i];
+        for (i = 0; i < PHY_MAX_ADDR; i++) {
+            struct phy_device *phydev = bus->phymap[i];
 
-			if (phydev) {
-				printf("%d - %s", i, phydev->drv->name);
-
-				if (phydev->dev)
-					printf(" <--> %s\n", phydev->dev->name);
-				else
-					printf("\n");
-			}
-		}
-	}
+            if (phydev) {
+                if (phydev->dev) {
+                    ZF_LOGI("  %d - %s <--> %s",
+                            i, phydev->drv->name, phydev->dev->name);
+                } else {
+                    ZF_LOGI("  %d - %s", i, phydev->drv->name);
+                }
+            }
+        }
+    }
 }
 
 int miiphy_set_current_dev(const char *devname)
 {
-	struct mii_dev *dev;
+    struct mii_dev *dev;
 
-	dev = miiphy_get_dev_by_name(devname);
-	if (dev) {
-		current_mii = dev;
-		return 0;
-	}
+    dev = miiphy_get_dev_by_name(devname);
+    if (dev) {
+        current_mii = dev;
+        return 0;
+    }
 
-	printf("No such device: %s\n", devname);
+    ZF_LOGE("No such device: %s", devname);
 
-	return 1;
+    return 1;
 }
 
 struct mii_dev *mdio_get_current_dev(void)
 {
-	return current_mii;
+    return current_mii;
 }
 
 struct phy_device *mdio_phydev_for_ethname(const char *ethname)
 {
-	struct list_head *entry;
-	struct mii_dev *bus;
+    struct list_head *entry;
+    struct mii_dev *bus;
 
-	list_for_each(entry, &mii_devs) {
-		int i;
-		bus = list_entry(entry, struct mii_dev, link);
+    list_for_each(entry, &mii_devs) {
+        int i;
+        bus = list_entry(entry, struct mii_dev, link);
 
-		for (i = 0; i < PHY_MAX_ADDR; i++) {
-			if (!bus->phymap[i] || !bus->phymap[i]->dev)
-				continue;
+        for (i = 0; i < PHY_MAX_ADDR; i++) {
+            if (!bus->phymap[i] || !bus->phymap[i]->dev) {
+                continue;
+            }
 
-			if (strcmp(bus->phymap[i]->dev->name, ethname) == 0)
-				return bus->phymap[i];
-		}
-	}
+            if (strcmp(bus->phymap[i]->dev->name, ethname) == 0) {
+                return bus->phymap[i];
+            }
+        }
+    }
 
-	printf("%s is not a known ethernet\n", ethname);
-	return NULL;
+    ZF_LOGE("%s is not a known ethernet", ethname);
+    return NULL;
 }
 
 const char *miiphy_get_current_dev(void)
 {
-	if (current_mii)
-		return current_mii->name;
+    if (current_mii) {
+        return current_mii->name;
+    }
 
-	return NULL;
+    return NULL;
 }
 
 static struct mii_dev *miiphy_get_active_dev(const char *devname)
 {
-	/* If the current mii is the one we want, return it */
-	if (current_mii)
-		if (strcmp(current_mii->name, devname) == 0)
-			return current_mii;
+    /* If the current mii is the one we want, return it */
+    if (current_mii)
+        if (strcmp(current_mii->name, devname) == 0) {
+            return current_mii;
+        }
 
-	/* Otherwise, set the active one to the one we want */
-	if (miiphy_set_current_dev(devname))
-		return NULL;
-	else
-		return current_mii;
+    /* Otherwise, set the active one to the one we want */
+    if (miiphy_set_current_dev(devname)) {
+        return NULL;
+    } else {
+        return current_mii;
+    }
 }
 
 /*****************************************************************************
@@ -296,21 +287,23 @@
  *   0 on success
  */
 int miiphy_read(const char *devname, unsigned char addr, unsigned char reg,
-		 unsigned short *value)
+                unsigned short *value)
 {
-	struct mii_dev *bus;
-	int ret;
+    struct mii_dev *bus;
+    int ret;
 
-	bus = miiphy_get_active_dev(devname);
-	if (!bus)
-		return 1;
+    bus = miiphy_get_active_dev(devname);
+    if (!bus) {
+        return 1;
+    }
 
-	ret = bus->read(bus, addr, MDIO_DEVAD_NONE, reg);
-	if (ret < 0)
-		return 1;
+    ret = bus->read(bus, addr, MDIO_DEVAD_NONE, reg);
+    if (ret < 0) {
+        return 1;
+    }
 
-	*value = (unsigned short)ret;
-	return 0;
+    *value = (unsigned short)ret;
+    return 0;
 }
 
 /*****************************************************************************
@@ -324,15 +317,16 @@
  *   0 on success
  */
 int miiphy_write(const char *devname, unsigned char addr, unsigned char reg,
-		  unsigned short value)
+                 unsigned short value)
 {
-	struct mii_dev *bus;
+    struct mii_dev *bus;
 
-	bus = miiphy_get_active_dev(devname);
-	if (bus)
-		return bus->write(bus, addr, MDIO_DEVAD_NONE, reg, value);
+    bus = miiphy_get_active_dev(devname);
+    if (bus) {
+        return bus->write(bus, addr, MDIO_DEVAD_NONE, reg, value);
+    }
 
-	return 1;
+    return 1;
 }
 
 /*****************************************************************************
@@ -341,18 +335,18 @@
  */
 void miiphy_listdev(void)
 {
-	struct list_head *entry;
-	struct mii_dev *dev;
+    struct list_head *entry;
+    struct mii_dev *dev;
 
-	puts("MII devices: ");
-	list_for_each(entry, &mii_devs) {
-		dev = list_entry(entry, struct mii_dev, link);
-		printf("'%s' ", dev->name);
-	}
-	puts("\n");
+    ZF_LOGI("MII devices: ");
+    list_for_each(entry, &mii_devs) {
+        dev = list_entry(entry, struct mii_dev, link);
+        ZF_LOGI("  '%s'", dev->name);
+    }
 
-	if (current_mii)
-		printf("Current device: '%s'\n", current_mii->name);
+    if (current_mii) {
+        ZF_LOGI("Current device: '%s'", current_mii->name);
+    }
 }
 
 /*****************************************************************************
@@ -369,35 +363,35 @@
  *   0 on success
  */
 int miiphy_info(const char *devname, unsigned char addr, unsigned int *oui,
-		 unsigned char *model, unsigned char *rev)
+                unsigned char *model, unsigned char *rev)
 {
-	unsigned int reg = 0;
-	unsigned short tmp;
+    unsigned int reg = 0;
+    unsigned short tmp;
 
-	if (miiphy_read(devname, addr, MII_PHYSID2, &tmp) != 0) {
-		debug("PHY ID register 2 read failed\n");
-		return -1;
-	}
-	reg = tmp;
+    if (miiphy_read(devname, addr, MII_PHYSID2, &tmp) != 0) {
+        ZF_LOGE("PHY ID register 2 read failed");
+        return -1;
+    }
+    reg = tmp;
 
-	debug("MII_PHYSID2 @ 0x%x = 0x%04x\n", addr, reg);
+    ZF_LOGI("MII_PHYSID2 @ 0x%x = 0x%04x", addr, reg);
 
-	if (reg == 0xFFFF) {
-		/* No physical device present at this address */
-		return -1;
-	}
+    if (reg == 0xFFFF) {
+        /* No physical device present at this address */
+        return -1;
+    }
 
-	if (miiphy_read(devname, addr, MII_PHYSID1, &tmp) != 0) {
-		debug("PHY ID register 1 read failed\n");
-		return -1;
-	}
-	reg |= tmp << 16;
-	debug("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg);
+    if (miiphy_read(devname, addr, MII_PHYSID1, &tmp) != 0) {
+        ZF_LOGE("PHY ID register 1 read failed");
+        return -1;
+    }
+    reg |= tmp << 16;
+    ZF_LOGI("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x", addr, reg);
 
-	*oui = (reg >> 10);
-	*model = (unsigned char)((reg >> 4) & 0x0000003F);
-	*rev = (unsigned char)(reg & 0x0000000F);
-	return 0;
+    *oui = (reg >> 10);
+    *model = (unsigned char)((reg >> 4) & 0x0000003F);
+    *rev = (unsigned char)(reg & 0x0000000F);
+    return 0;
 }
 
 #ifndef CONFIG_PHYLIB
@@ -412,40 +406,40 @@
  */
 int miiphy_reset(const char *devname, unsigned char addr)
 {
-	unsigned short reg;
-	int timeout = 500;
+    unsigned short reg;
+    int timeout = 500;
 
-	if (miiphy_read(devname, addr, MII_BMCR, &reg) != 0) {
-		debug("PHY status read failed\n");
-		return -1;
-	}
-	if (miiphy_write(devname, addr, MII_BMCR, reg | BMCR_RESET) != 0) {
-		debug("PHY reset failed\n");
-		return -1;
-	}
+    if (miiphy_read(devname, addr, MII_BMCR, &reg) != 0) {
+        ZF_LOGE("PHY status read failed");
+        return -1;
+    }
+    if (miiphy_write(devname, addr, MII_BMCR, reg | BMCR_RESET) != 0) {
+        ZF_LOGE("PHY reset failed");
+        return -1;
+    }
 #ifdef CONFIG_PHY_RESET_DELAY
-	udelay(CONFIG_PHY_RESET_DELAY);	/* Intel LXT971A needs this */
+    udelay(CONFIG_PHY_RESET_DELAY); /* Intel LXT971A needs this */
 #endif
-	/*
-	 * Poll the control register for the reset bit to go to 0 (it is
-	 * auto-clearing).  This should happen within 0.5 seconds per the
-	 * IEEE spec.
-	 */
-	reg = 0x8000;
-	while (((reg & 0x8000) != 0) && timeout--) {
-		if (miiphy_read(devname, addr, MII_BMCR, &reg) != 0) {
-			debug("PHY status read failed\n");
-			return -1;
-		}
-		udelay(1000);
-	}
-	if ((reg & 0x8000) == 0) {
-		return 0;
-	} else {
-		puts("PHY reset timed out\n");
-		return -1;
-	}
-	return 0;
+    /*
+     * Poll the control register for the reset bit to go to 0 (it is
+     * auto-clearing).  This should happen within 0.5 seconds per the
+     * IEEE spec.
+     */
+    reg = 0x8000;
+    while (((reg & 0x8000) != 0) && timeout--) {
+        if (miiphy_read(devname, addr, MII_BMCR, &reg) != 0) {
+            ZF_LOGE("PHY status read failed");
+            return -1;
+        }
+        udelay(1000);
+    }
+    if ((reg & 0x8000) == 0) {
+        return 0;
+    } else {
+        ZF_LOGE("PHY reset timed out");
+        return -1;
+    }
+    return 0;
 }
 #endif /* !PHYLIB */
 
@@ -455,51 +449,53 @@
  */
 int miiphy_speed(const char *devname, unsigned char addr)
 {
-	u16 bmcr, anlpar;
+    u16 bmcr, anlpar;
 
 #if defined(CONFIG_PHY_GIGE)
-	u16 btsr;
+    u16 btsr;
 
-	/*
-	 * Check for 1000BASE-X.  If it is supported, then assume that the speed
-	 * is 1000.
-	 */
-	if (miiphy_is_1000base_x(devname, addr))
-		return _1000BASET;
+    /*
+     * Check for 1000BASE-X.  If it is supported, then assume that the speed
+     * is 1000.
+     */
+    if (miiphy_is_1000base_x(devname, addr)) {
+        return _1000BASET;
+    }
 
-	/*
-	 * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
-	 */
-	/* Check for 1000BASE-T. */
-	if (miiphy_read(devname, addr, MII_STAT1000, &btsr)) {
-		printf("PHY 1000BT status");
-		goto miiphy_read_failed;
-	}
-	if (btsr != 0xFFFF &&
-			(btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)))
-		return _1000BASET;
+    /*
+     * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
+     */
+    /* Check for 1000BASE-T. */
+    if (miiphy_read(devname, addr, MII_STAT1000, &btsr)) {
+        ZF_LOGI("PHY 1000BT status");
+        goto miiphy_read_failed;
+    }
+    if (btsr != 0xFFFF &&
+        (btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD))) {
+        return _1000BASET;
+    }
 #endif /* CONFIG_PHY_GIGE */
 
-	/* Check Basic Management Control Register first. */
-	if (miiphy_read(devname, addr, MII_BMCR, &bmcr)) {
-		printf("PHY speed");
-		goto miiphy_read_failed;
-	}
-	/* Check if auto-negotiation is on. */
-	if (bmcr & BMCR_ANENABLE) {
-		/* Get auto-negotiation results. */
-		if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
-			printf("PHY AN speed");
-			goto miiphy_read_failed;
-		}
-		return (anlpar & LPA_100) ? _100BASET : _10BASET;
-	}
-	/* Get speed from basic control settings. */
-	return (bmcr & BMCR_SPEED100) ? _100BASET : _10BASET;
+    /* Check Basic Management Control Register first. */
+    if (miiphy_read(devname, addr, MII_BMCR, &bmcr)) {
+        ZF_LOGI("PHY speed");
+        goto miiphy_read_failed;
+    }
+    /* Check if auto-negotiation is on. */
+    if (bmcr & BMCR_ANENABLE) {
+        /* Get auto-negotiation results. */
+        if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
+            ZF_LOGI("PHY AN speed");
+            goto miiphy_read_failed;
+        }
+        return (anlpar & LPA_100) ? _100BASET : _10BASET;
+    }
+    /* Get speed from basic control settings. */
+    return (bmcr & BMCR_SPEED100) ? _100BASET : _10BASET;
 
 miiphy_read_failed:
-	printf(" read failed, assuming 10BASE-T\n");
-	return _10BASET;
+    ZF_LOGE(" read failed, assuming 10BASE-T");
+    return _10BASET;
 }
 
 /*****************************************************************************
@@ -508,57 +504,57 @@
  */
 int miiphy_duplex(const char *devname, unsigned char addr)
 {
-	u16 bmcr, anlpar;
+    u16 bmcr, anlpar;
 
 #if defined(CONFIG_PHY_GIGE)
-	u16 btsr;
+    u16 btsr;
 
-	/* Check for 1000BASE-X. */
-	if (miiphy_is_1000base_x(devname, addr)) {
-		/* 1000BASE-X */
-		if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
-			printf("1000BASE-X PHY AN duplex");
-			goto miiphy_read_failed;
-		}
-	}
-	/*
-	 * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
-	 */
-	/* Check for 1000BASE-T. */
-	if (miiphy_read(devname, addr, MII_STAT1000, &btsr)) {
-		printf("PHY 1000BT status");
-		goto miiphy_read_failed;
-	}
-	if (btsr != 0xFFFF) {
-		if (btsr & PHY_1000BTSR_1000FD) {
-			return FULL;
-		} else if (btsr & PHY_1000BTSR_1000HD) {
-			return HALF;
-		}
-	}
+    /* Check for 1000BASE-X. */
+    if (miiphy_is_1000base_x(devname, addr)) {
+        /* 1000BASE-X */
+        if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
+            ZF_LOGI("1000BASE-X PHY AN duplex");
+            goto miiphy_read_failed;
+        }
+    }
+    /*
+     * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
+     */
+    /* Check for 1000BASE-T. */
+    if (miiphy_read(devname, addr, MII_STAT1000, &btsr)) {
+        ZF_LOGI("PHY 1000BT status");
+        goto miiphy_read_failed;
+    }
+    if (btsr != 0xFFFF) {
+        if (btsr & PHY_1000BTSR_1000FD) {
+            return FULL;
+        } else if (btsr & PHY_1000BTSR_1000HD) {
+            return HALF;
+        }
+    }
 #endif /* CONFIG_PHY_GIGE */
 
-	/* Check Basic Management Control Register first. */
-	if (miiphy_read(devname, addr, MII_BMCR, &bmcr)) {
-		puts("PHY duplex");
-		goto miiphy_read_failed;
-	}
-	/* Check if auto-negotiation is on. */
-	if (bmcr & BMCR_ANENABLE) {
-		/* Get auto-negotiation results. */
-		if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
-			puts("PHY AN duplex");
-			goto miiphy_read_failed;
-		}
-		return (anlpar & (LPA_10FULL | LPA_100FULL)) ?
-		    FULL : HALF;
-	}
-	/* Get speed from basic control settings. */
-	return (bmcr & BMCR_FULLDPLX) ? FULL : HALF;
+    /* Check Basic Management Control Register first. */
+    if (miiphy_read(devname, addr, MII_BMCR, &bmcr)) {
+        ZF_LOGI("PHY duplex");
+        goto miiphy_read_failed;
+    }
+    /* Check if auto-negotiation is on. */
+    if (bmcr & BMCR_ANENABLE) {
+        /* Get auto-negotiation results. */
+        if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
+            ZF_LOGI("PHY AN duplex");
+            goto miiphy_read_failed;
+        }
+        return (anlpar & (LPA_10FULL | LPA_100FULL)) ?
+               FULL : HALF;
+    }
+    /* Get speed from basic control settings. */
+    return (bmcr & BMCR_FULLDPLX) ? FULL : HALF;
 
 miiphy_read_failed:
-	printf(" read failed, assuming half duplex\n");
-	return HALF;
+    ZF_LOGI(" read failed, assuming half duplex");
+    return HALF;
 }
 
 /*****************************************************************************
@@ -569,16 +565,15 @@
 int miiphy_is_1000base_x(const char *devname, unsigned char addr)
 {
 #if defined(CONFIG_PHY_GIGE)
-	u16 exsr;
+    u16 exsr;
 
-	if (miiphy_read(devname, addr, MII_ESTATUS, &exsr)) {
-		printf("PHY extended status read failed, assuming no "
-			"1000BASE-X\n");
-		return 0;
-	}
-	return 0 != (exsr & (ESTATUS_1000XF | ESTATUS_1000XH));
+    if (miiphy_read(devname, addr, MII_ESTATUS, &exsr)) {
+        ZF_LOGI("PHY extended status read failed, assuming no 1000BASE-X");
+        return 0;
+    }
+    return 0 != (exsr & (ESTATUS_1000XF | ESTATUS_1000XH));
 #else
-	return 0;
+    return 0;
 #endif
 }
 
@@ -589,20 +584,20 @@
  */
 int miiphy_link(const char *devname, unsigned char addr)
 {
-	unsigned short reg;
+    unsigned short reg;
 
-	/* dummy read; needed to latch some phys */
-	(void)miiphy_read(devname, addr, MII_BMSR, &reg);
-	if (miiphy_read(devname, addr, MII_BMSR, &reg)) {
-		puts("MII_BMSR read failed, assuming no link\n");
-		return 0;
-	}
+    /* dummy read; needed to latch some phys */
+    (void)miiphy_read(devname, addr, MII_BMSR, &reg);
+    if (miiphy_read(devname, addr, MII_BMSR, &reg)) {
+        ZF_LOGI("MII_BMSR read failed, assuming no link");
+        return 0;
+    }
 
-	/* Determine if a link is active */
-	if ((reg & BMSR_LSTATUS) != 0) {
-		return 1;
-	} else {
-		return 0;
-	}
+    /* Determine if a link is active */
+    if ((reg & BMSR_LSTATUS) != 0) {
+        return 1;
+    } else {
+        return 0;
+    }
 }
 #endif
diff --git a/libethdrivers/src/plat/imx6/uboot/mx6qsabrelite.c b/libethdrivers/src/plat/imx6/uboot/mx6qsabrelite.c
deleted file mode 100644
index f722056..0000000
--- a/libethdrivers/src/plat/imx6/uboot/mx6qsabrelite.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/*
- * @TAG(OTHER_GPL)
- */
-
-/*
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
- * Copyright (C) 2018 NXP
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * 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 (at your option) 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-/*
- * u-boot-imx6/board/freescale/mx6qsabrelite/mx6qsabrelite.c
- */
-
-#include "common.h"
-#include "../io.h"
-#include "imx-regs.h"
-#include <errno.h>
-
-#include "gpio.h"
-#include "mx6x_pins.h"
-#include "imx8mq_pins.h"
-#include "miiphy.h"
-#include "micrel.h"
-#include "mx6qsabrelite.h"
-#include <assert.h>
-#include <utils/util.h>
-#include <platsupport/io.h>
-
-#include <stdio.h>
-
-#ifdef CONFIG_PLAT_IMX6
-#define IOMUXC_PADDR 0x020E0000
-#define IOMUXC_SIZE      0x4000
-#endif
-#ifdef CONFIG_PLAT_IMX8MQ_EVK
-#define IOMUXC_PADDR 0x30330000
-#define IOMUXC_SIZE      0x10000
-#endif
-
-#define ENET_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |     \
-    PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED   |     \
-    PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
-
-static iomux_v3_cfg_t const enet_pads1[] = {
-    MX6Q_PAD_ENET_MDIO__ENET_MDIO       | MUX_PAD_CTRL(ENET_PAD_CTRL),
-    MX6Q_PAD_ENET_MDC__ENET_MDC     | MUX_PAD_CTRL(ENET_PAD_CTRL),
-    MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC  | MUX_PAD_CTRL(ENET_PAD_CTRL),
-    MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0  | MUX_PAD_CTRL(ENET_PAD_CTRL),
-    MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1  | MUX_PAD_CTRL(ENET_PAD_CTRL),
-    MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2  | MUX_PAD_CTRL(ENET_PAD_CTRL),
-    MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3  | MUX_PAD_CTRL(ENET_PAD_CTRL),
-    MX6Q_PAD_RGMII_TX_CTL__RGMII_TX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
-    MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK  | MUX_PAD_CTRL(ENET_PAD_CTRL),
-    /* pin 35 - 1 (PHY_AD2) on reset */
-    MX6Q_PAD_RGMII_RXC__GPIO_6_30       | MUX_PAD_CTRL(NO_PAD_CTRL),
-    /* pin 32 - 1 - (MODE0) all */
-    MX6Q_PAD_RGMII_RD0__GPIO_6_25       | MUX_PAD_CTRL(NO_PAD_CTRL),
-    /* pin 31 - 1 - (MODE1) all */
-    MX6Q_PAD_RGMII_RD1__GPIO_6_27       | MUX_PAD_CTRL(NO_PAD_CTRL),
-    /* pin 28 - 1 - (MODE2) all */
-    MX6Q_PAD_RGMII_RD2__GPIO_6_28       | MUX_PAD_CTRL(NO_PAD_CTRL),
-    /* pin 27 - 1 - (MODE3) all */
-    MX6Q_PAD_RGMII_RD3__GPIO_6_29       | MUX_PAD_CTRL(NO_PAD_CTRL),
-    /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
-    MX6Q_PAD_RGMII_RX_CTL__GPIO_6_24    | MUX_PAD_CTRL(NO_PAD_CTRL),
-    /* pin 42 PHY nRST */
-    MX6Q_PAD_EIM_D23__GPIO_3_23     | MUX_PAD_CTRL(NO_PAD_CTRL),
-};
-
-static iomux_v3_cfg_t const enet_pads2[] = {
-    MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC  | MUX_PAD_CTRL(ENET_PAD_CTRL),
-    MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0  | MUX_PAD_CTRL(ENET_PAD_CTRL),
-    MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1  | MUX_PAD_CTRL(ENET_PAD_CTRL),
-    MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2  | MUX_PAD_CTRL(ENET_PAD_CTRL),
-    MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3  | MUX_PAD_CTRL(ENET_PAD_CTRL),
-    MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL | MUX_PAD_CTRL(ENET_PAD_CTRL),
-};
-
-static iomux_v3_cfg_t const fec1_pads[] = {
-    /* see the IMX8 reference manual for what the options mean,
-     * Section 8.2.4 i.e. IOMUXC_SW_PAD_CTL_PAD_* registers */
-    IMX8MQ_PAD_ENET_MDC__ENET_MDC | MUX_PAD_CTRL(0x3),
-    IMX8MQ_PAD_ENET_MDIO__ENET_MDIO | MUX_PAD_CTRL(0x23),
-    IMX8MQ_PAD_ENET_TD3__ENET_RGMII_TD3 | MUX_PAD_CTRL(0x1f),
-    IMX8MQ_PAD_ENET_TD2__ENET_RGMII_TD2 | MUX_PAD_CTRL(0x1f),
-    IMX8MQ_PAD_ENET_TD1__ENET_RGMII_TD1 | MUX_PAD_CTRL(0x1f),
-    IMX8MQ_PAD_ENET_TD0__ENET_RGMII_TD0 | MUX_PAD_CTRL(0x1f),
-    IMX8MQ_PAD_ENET_RD3__ENET_RGMII_RD3 | MUX_PAD_CTRL(0x91),
-    IMX8MQ_PAD_ENET_RD2__ENET_RGMII_RD2 | MUX_PAD_CTRL(0x91),
-    IMX8MQ_PAD_ENET_RD1__ENET_RGMII_RD1 | MUX_PAD_CTRL(0x91),
-    IMX8MQ_PAD_ENET_RD0__ENET_RGMII_RD0 | MUX_PAD_CTRL(0x91),
-    IMX8MQ_PAD_ENET_TXC__ENET_RGMII_TXC | MUX_PAD_CTRL(0x1f),
-    IMX8MQ_PAD_ENET_RXC__ENET_RGMII_RXC | MUX_PAD_CTRL(0x91),
-    IMX8MQ_PAD_ENET_TX_CTL__ENET_RGMII_TX_CTL | MUX_PAD_CTRL(0x1f),
-    IMX8MQ_PAD_ENET_RX_CTL__ENET_RGMII_RX_CTL | MUX_PAD_CTRL(0x91),
-    IMX8MQ_PAD_GPIO1_IO09__GPIO1_IO9 | MUX_PAD_CTRL(0x19)
-};
-
-/*
- * configures a single pad in the iomuxer
- */
-static int imx_iomux_v3_setup_pad(void *base, iomux_v3_cfg_t pad)
-{
-    uint32_t mux_ctrl_ofs = (pad & MUX_CTRL_OFS_MASK) >> MUX_CTRL_OFS_SHIFT;
-    uint32_t mux_mode = (pad & MUX_MODE_MASK) >> MUX_MODE_SHIFT;
-    uint32_t sel_input_ofs = (pad & MUX_SEL_INPUT_OFS_MASK) >> MUX_SEL_INPUT_OFS_SHIFT;
-    uint32_t sel_input = (pad & MUX_SEL_INPUT_MASK) >> MUX_SEL_INPUT_SHIFT;
-    uint32_t pad_ctrl_ofs = (pad & MUX_PAD_CTRL_OFS_MASK) >> MUX_PAD_CTRL_OFS_SHIFT;
-    uint32_t pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT;
-
-    if (mux_ctrl_ofs) {
-        __raw_writel(mux_mode, base + mux_ctrl_ofs);
-    }
-
-    if (sel_input_ofs) {
-        __raw_writel(sel_input, base + sel_input_ofs);
-    }
-
-    if (!(pad_ctrl & NO_PAD_CTRL) && pad_ctrl_ofs) {
-        __raw_writel(pad_ctrl, base + pad_ctrl_ofs);
-    }
-
-    return 0;
-}
-
-static int imx_iomux_v3_setup_multiple_pads(void *base, iomux_v3_cfg_t const *pad_list,
-                                            unsigned count)
-{
-    iomux_v3_cfg_t const *p = pad_list;
-    int i;
-    int ret;
-
-    for (i = 0; i < count; i++) {
-        ret = imx_iomux_v3_setup_pad(base, *p);
-        if (ret) {
-            return ret;
-        }
-        p++;
-    }
-    return 0;
-}
-
-int setup_iomux_enet(ps_io_ops_t *io_ops)
-{
-    int ret;
-    void *base;
-    int unmapOnExit = 0;
-
-    if (mux_sys_valid(&io_ops->mux_sys)) {
-        base = mux_sys_get_vaddr(&io_ops->mux_sys);
-    } else {
-        base = RESOURCE(&io_ops->io_mapper, IOMUXC);
-        unmapOnExit = 1;
-    }
-    if (!base) {
-        return 1;
-    }
-
-    if (config_set(CONFIG_PLAT_IMX8MQ_EVK)) {
-        ret = imx_iomux_v3_setup_multiple_pads(base, fec1_pads, ARRAY_SIZE(fec1_pads));
-        if (ret) {
-            return ret;
-        }
-        gpio_direction_output(IMX_GPIO_NR(1, 9), 0, io_ops);
-        udelay(500);
-        gpio_direction_output(IMX_GPIO_NR(1, 9), 1, io_ops);
-
-        uint32_t *gpr1 = base + 0x4;
-        // Change ENET_TX to use internal clocks and not the external clocks
-        *gpr1 = *gpr1 & ~(BIT(17) | BIT(13));
-    } else if (config_set(CONFIG_PLAT_IMX6)) {
-        gpio_direction_output(IMX_GPIO_NR(3, 23), 0, io_ops);
-        gpio_direction_output(IMX_GPIO_NR(6, 30), 1, io_ops);
-        gpio_direction_output(IMX_GPIO_NR(6, 25), 1, io_ops);
-        gpio_direction_output(IMX_GPIO_NR(6, 27), 1, io_ops);
-        gpio_direction_output(IMX_GPIO_NR(6, 28), 1, io_ops);
-        gpio_direction_output(IMX_GPIO_NR(6, 29), 1, io_ops);
-        ret = imx_iomux_v3_setup_multiple_pads(base, enet_pads1, ARRAY_SIZE(enet_pads1));
-        if (ret) {
-            return ret;
-        }
-        gpio_direction_output(IMX_GPIO_NR(6, 24), 1, io_ops);
-        /* Need delay 10ms according to KSZ9021 spec */
-        udelay(1000 * 10);
-        gpio_set_value(IMX_GPIO_NR(3, 23), 1);
-
-        ret = imx_iomux_v3_setup_multiple_pads(base, enet_pads2, ARRAY_SIZE(enet_pads2));
-        if (ret) {
-            return ret;
-        }
-    }
-
-    if (unmapOnExit) {
-        UNRESOURCE(&io_ops->io_mapper, IOMUXC, base);
-    }
-    return 0;
-}
diff --git a/libethdrivers/src/plat/imx6/uboot/mx6qsabrelite.h b/libethdrivers/src/plat/imx6/uboot/mx6qsabrelite.h
deleted file mode 100644
index ba4271d..0000000
--- a/libethdrivers/src/plat/imx6/uboot/mx6qsabrelite.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * @TAG(OTHER_GPL)
- */
-
-/*
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
- *
- * Configuration settings for the Freescale i.MX6Q Sabre Lite board.
- *
- * 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 (at your option) 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, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- * MA 02111-1307 USA
- */
-
-#pragma once
-
-#define CONFIG_MX6
-#define CONFIG_MX6Q
-
-#define CONFIG_MACH_TYPE    3769
-
-#include "imx-regs.h"
-#include "gpio.h"
-
-#include <stdint.h>
-
-#define CONFIG_BOARD_EARLY_INIT_F
-#define CONFIG_MISC_INIT_R
-#define CONFIG_MXC_GPIO
-
-#define CONFIG_FEC_MXC
-#define CONFIG_MII
-#define IMX_FEC_BASE            ENET_BASE_ADDR
-#define CONFIG_FEC_XCV_TYPE     RGMII
-#define CONFIG_ETHPRIME         "FEC"
-#define CONFIG_FEC_MXC_PHYMASK      (0xf << 4)  /* scan phy 4,5,6,7 */
-#define CONFIG_PHYLIB
-#define CONFIG_PHY_MICREL
-#define CONFIG_PHY_MICREL_KSZ9021
-
-/* Command definition */
-#include "config.h"
-
-#define CONFIG_MX6
-#define CONFIG_MX6Q
-
-#include "imx-regs.h"
-
-#define CONFIG_BOARD_EARLY_INIT_F
-#define CONFIG_MXC_GPIO
-
-#define CONFIG_MXC_UART
-#define CONFIG_FEC_MXC
-#define CONFIG_MII
-#define IMX_FEC_BASE            ENET_BASE_ADDR
-#define CONFIG_FEC_XCV_TYPE     RGMII
-#define CONFIG_ETHPRIME         "FEC"
-#define CONFIG_FEC_MXC_PHYADDR      1
-
-#define CONFIG_PHYLIB
-#define CONFIG_PHY_ATHEROS
-
-/* Command definition */
-#include "config.h"
-typedef uint64_t iomux_v3_cfg_t;
-
-#define MUX_CTRL_OFS_SHIFT  0
-#define MUX_CTRL_OFS_MASK   ((iomux_v3_cfg_t)0xfff << MUX_CTRL_OFS_SHIFT)
-#define MUX_PAD_CTRL_OFS_SHIFT  12
-#define MUX_PAD_CTRL_OFS_MASK   ((iomux_v3_cfg_t)0xfff << \
-    MUX_PAD_CTRL_OFS_SHIFT)
-#define MUX_SEL_INPUT_OFS_SHIFT 24
-#define MUX_SEL_INPUT_OFS_MASK  ((iomux_v3_cfg_t)0xfff << \
-    MUX_SEL_INPUT_OFS_SHIFT)
-
-#define MUX_MODE_SHIFT      36
-#define MUX_MODE_MASK       ((iomux_v3_cfg_t)0x3f << MUX_MODE_SHIFT)
-#define MUX_PAD_CTRL_SHIFT  42
-#define MUX_PAD_CTRL_MASK   ((iomux_v3_cfg_t)0x3ffff << MUX_PAD_CTRL_SHIFT)
-#define MUX_SEL_INPUT_SHIFT 60
-#define MUX_SEL_INPUT_MASK  ((iomux_v3_cfg_t)0xf << MUX_SEL_INPUT_SHIFT)
-
-#define MUX_PAD_CTRL(x)     ((iomux_v3_cfg_t)(x) << MUX_PAD_CTRL_SHIFT)
-
-#define IOMUX_PAD(pad_ctrl_ofs, mux_ctrl_ofs, mux_mode, sel_input_ofs,  \
-        sel_input, pad_ctrl)                    \
-    (((iomux_v3_cfg_t)(mux_ctrl_ofs) << MUX_CTRL_OFS_SHIFT)     |   \
-    ((iomux_v3_cfg_t)(mux_mode)      << MUX_MODE_SHIFT)         |   \
-    ((iomux_v3_cfg_t)(pad_ctrl_ofs)  << MUX_PAD_CTRL_OFS_SHIFT) |   \
-    ((iomux_v3_cfg_t)(pad_ctrl)      << MUX_PAD_CTRL_SHIFT)     |   \
-    ((iomux_v3_cfg_t)(sel_input_ofs) << MUX_SEL_INPUT_OFS_SHIFT)|   \
-    ((iomux_v3_cfg_t)(sel_input)     << MUX_SEL_INPUT_SHIFT))
-
-#define NO_PAD_CTRL     (BIT(17))
-#define GPIO_PIN_MASK       0x1f
-#define GPIO_PORT_SHIFT     5
-#define GPIO_PORT_MASK      (0x7 << GPIO_PORT_SHIFT)
-#define GPIO_PORTA      (0 << GPIO_PORT_SHIFT)
-#define GPIO_PORTB      (BIT(GPIO_PORT_SHIFT))
-#define GPIO_PORTC      (2 << GPIO_PORT_SHIFT)
-#define GPIO_PORTD      (3 << GPIO_PORT_SHIFT)
-#define GPIO_PORTE      (4 << GPIO_PORT_SHIFT)
-#define GPIO_PORTF      (5 << GPIO_PORT_SHIFT)
-
-#define MUX_CONFIG_SION     (BIT(4))
-
diff --git a/libethdrivers/src/plat/imx6/uboot/mx6x_pins.h b/libethdrivers/src/plat/imx6/uboot/mx6x_pins.h
deleted file mode 100644
index dde7ea0..0000000
--- a/libethdrivers/src/plat/imx6/uboot/mx6x_pins.h
+++ /dev/null
@@ -1,1673 +0,0 @@
-/*
- * @TAG(OTHER_GPL)
- */
-
-/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
- *
- * 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
- * (at your option) 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, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Auto Generate file, please don't edit it
- *
- */
-
-#pragma once
-
-#include "mx6qsabrelite.h"
-
-/* Use to set PAD control */
-#define PAD_CTL_HYS		(BIT(16))
-#define PAD_CTL_PUS_100K_DOWN	(0 << 14)
-#define PAD_CTL_PUS_47K_UP	(BIT(14))
-#define PAD_CTL_PUS_100K_UP	(2 << 14)
-#define PAD_CTL_PUS_22K_UP	(3 << 14)
-
-#define PAD_CTL_PUE		(BIT(13))
-#define PAD_CTL_PKE		(BIT(12))
-#define PAD_CTL_ODE		(BIT(11))
-#define PAD_CTL_SPEED_LOW	(BIT(6))
-#define PAD_CTL_SPEED_MED	(2 << 6)
-#define PAD_CTL_SPEED_HIGH	(3 << 6)
-#define PAD_CTL_DSE_DISABLE	(0 << 3)
-#define PAD_CTL_DSE_240ohm	(BIT(3))
-#define PAD_CTL_DSE_120ohm	(2 << 3)
-#define PAD_CTL_DSE_80ohm	(3 << 3)
-#define PAD_CTL_DSE_60ohm	(4 << 3)
-#define PAD_CTL_DSE_48ohm	(5 << 3)
-#define PAD_CTL_DSE_40ohm	(6 << 3)
-#define PAD_CTL_DSE_34ohm	(7 << 3)
-#define PAD_CTL_SRE_FAST	(BIT(0))
-#define PAD_CTL_SRE_SLOW	(0 << 0)
-
-#define NO_MUX_I                0
-#define NO_PAD_I                0
-
-enum {
-	MX6Q_PAD_SD2_DAT1__USDHC2_DAT1		= IOMUX_PAD(0x0360, 0x004C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT1__ECSPI5_SS0		= IOMUX_PAD(0x0360, 0x004C, 1, 0x0834, 0, 0),
-	MX6Q_PAD_SD2_DAT1__WEIM_WEIM_CS_2	= IOMUX_PAD(0x0360, 0x004C, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS	= IOMUX_PAD(0x0360, 0x004C, 3, 0x07C8, 0, 0),
-	MX6Q_PAD_SD2_DAT1__KPP_COL_7		= IOMUX_PAD(0x0360, 0x004C, 4, 0x08F0, 0, 0),
-	MX6Q_PAD_SD2_DAT1__GPIO_1_14		= IOMUX_PAD(0x0360, 0x004C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT1__CCM_WAIT		= IOMUX_PAD(0x0360, 0x004C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT1__ANATOP_TESTO_0	= IOMUX_PAD(0x0360, 0x004C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT2__USDHC2_DAT2		= IOMUX_PAD(0x0364, 0x0050, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT2__ECSPI5_SS1		= IOMUX_PAD(0x0364, 0x0050, 1, 0x0838, 0, 0),
-	MX6Q_PAD_SD2_DAT2__WEIM_WEIM_CS_3	= IOMUX_PAD(0x0364, 0x0050, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT2__AUDMUX_AUD4_TXD	= IOMUX_PAD(0x0364, 0x0050, 3, 0x07B8, 0, 0),
-	MX6Q_PAD_SD2_DAT2__KPP_ROW_6		= IOMUX_PAD(0x0364, 0x0050, 4, 0x08F8, 0, 0),
-	MX6Q_PAD_SD2_DAT2__GPIO_1_13		= IOMUX_PAD(0x0364, 0x0050, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT2__CCM_STOP		= IOMUX_PAD(0x0364, 0x0050, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT2__ANATOP_TESTO_1	= IOMUX_PAD(0x0364, 0x0050, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT0__USDHC2_DAT0		= IOMUX_PAD(0x0368, 0x0054, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT0__ECSPI5_MISO		= IOMUX_PAD(0x0368, 0x0054, 1, 0x082C, 0, 0),
-	MX6Q_PAD_SD2_DAT0__AUDMUX_AUD4_RXD	= IOMUX_PAD(0x0368, 0x0054, 3, 0x07B4, 0, 0),
-	MX6Q_PAD_SD2_DAT0__KPP_ROW_7		= IOMUX_PAD(0x0368, 0x0054, 4, 0x08FC, 0, 0),
-	MX6Q_PAD_SD2_DAT0__GPIO_1_15		= IOMUX_PAD(0x0368, 0x0054, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT0__DCIC2_DCIC_OUT	= IOMUX_PAD(0x0368, 0x0054, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT0__TESTO_2		= IOMUX_PAD(0x0368, 0x0054, 7, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TXC__USBOH3_H2_DATA	= IOMUX_PAD(0x036C, 0x0058, 0, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC	= IOMUX_PAD(0x036C, 0x0058, 1, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TXC__SPDIF_SPDIF_EXTCLK	= IOMUX_PAD(0x036C, 0x0058, 2, 0x0918, 0, 0),
-	MX6Q_PAD_RGMII_TXC__GPIO_6_19		= IOMUX_PAD(0x036C, 0x0058, 5, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TXC__MIPI_CORE_DPHY_IN_0 = IOMUX_PAD(0x036C, 0x0058, 6, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TXC__ANATOP_24M_OUT	= IOMUX_PAD(0x036C, 0x0058, 7, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD0__MIPI_HSI_CRL_TX_RDY = IOMUX_PAD(0x0370, 0x005C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0	= IOMUX_PAD(0x0370, 0x005C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD0__GPIO_6_20		= IOMUX_PAD(0x0370, 0x005C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD0__MIPI_CORE_DPHY_IN_1 = IOMUX_PAD(0x0370, 0x005C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD1__MIPI_HSI_CRL_RX_FLG = IOMUX_PAD(0x0374, 0x0060, 0, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1	= IOMUX_PAD(0x0374, 0x0060, 1, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD1__GPIO_6_21		= IOMUX_PAD(0x0374, 0x0060, 5, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD1__MIPI_CORE_DPHY_IN_2 = IOMUX_PAD(0x0374, 0x0060, 6, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD1__CCM_PLL3_BYP	= IOMUX_PAD(0x0374, 0x0060, 7, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD2__MIPI_HSI_CRL_RX_DTA = IOMUX_PAD(0x0378, 0x0064, 0, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2	= IOMUX_PAD(0x0378, 0x0064, 1, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD2__GPIO_6_22		= IOMUX_PAD(0x0378, 0x0064, 5, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD2__MIPI_CORE_DPHY_IN_3 = IOMUX_PAD(0x0378, 0x0064, 6, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD2__CCM_PLL2_BYP	= IOMUX_PAD(0x0378, 0x0064, 7, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD3__MIPI_HSI_CRL_RX_WAK = IOMUX_PAD(0x037C, 0x0068, 0, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3	= IOMUX_PAD(0x037C, 0x0068, 1, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD3__GPIO_6_23		= IOMUX_PAD(0x037C, 0x0068, 5, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TD3__MIPI_CORE_DPHY_IN_4 = IOMUX_PAD(0x037C, 0x0068, 6, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RX_CTL__USBOH3_H3_DATA   = IOMUX_PAD(0x0380, 0x006C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL	= IOMUX_PAD(0x0380, 0x006C, 1, 0x0858, 0, 0),
-	MX6Q_PAD_RGMII_RX_CTL__GPIO_6_24	= IOMUX_PAD(0x0380, 0x006C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RX_CTL__MIPI_DPHY_IN_5	= IOMUX_PAD(0x0380, 0x006C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RD0__MIPI_HSI_CRL_RX_RDY = IOMUX_PAD(0x0384, 0x0070, 0, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0      = IOMUX_PAD(0x0384, 0x0070, 1, 0x0848, 0, 0),
-	MX6Q_PAD_RGMII_RD0__GPIO_6_25		= IOMUX_PAD(0x0384, 0x0070, 5, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RD0__MIPI_CORE_DPHY_IN_6 = IOMUX_PAD(0x0384, 0x0070, 6, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE = IOMUX_PAD(0x0388, 0x0074, 0, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TX_CTL__RGMII_TX_CTL	= IOMUX_PAD(0x0388, 0x0074, 1, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TX_CTL__GPIO_6_26	= IOMUX_PAD(0x0388, 0x0074, 5, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TX_CTL__CORE_DPHY_IN_7	= IOMUX_PAD(0x0388, 0x0074, 6, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_TX_CTL__ANATOP_REF_OUT	= IOMUX_PAD(0x0388, 0x0074, 7, 0x083C, 0, 0),
-	MX6Q_PAD_RGMII_RD1__MIPI_HSI_CTRL_TX_FL = IOMUX_PAD(0x038C, 0x0078, 0, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1	= IOMUX_PAD(0x038C, 0x0078, 1, 0x084C, 0, 0),
-	MX6Q_PAD_RGMII_RD1__GPIO_6_27		= IOMUX_PAD(0x038C, 0x0078, 5, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RD1__CORE_DPHY_TEST_IN_8 = IOMUX_PAD(0x038C, 0x0078, 6, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RD1__SJC_FAIL		= IOMUX_PAD(0x038C, 0x0078, 7, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RD2__MIPI_HSI_CRL_TX_DTA = IOMUX_PAD(0x0390, 0x007C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2	= IOMUX_PAD(0x0390, 0x007C, 1, 0x0850, 0, 0),
-	MX6Q_PAD_RGMII_RD2__GPIO_6_28		= IOMUX_PAD(0x0390, 0x007C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RD2__MIPI_CORE_DPHY_IN_9 = IOMUX_PAD(0x0390, 0x007C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RD3__MIPI_HSI_CRL_TX_WAK = IOMUX_PAD(0x0394, 0x0080, 0, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3	= IOMUX_PAD(0x0394, 0x0080, 1, 0x0854, 0, 0),
-	MX6Q_PAD_RGMII_RD3__GPIO_6_29		= IOMUX_PAD(0x0394, 0x0080, 5, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RD3__MIPI_CORE_DPHY_IN10 = IOMUX_PAD(0x0394, 0x0080, 6, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE    = IOMUX_PAD(0x0398, 0x0084, 0, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC	= IOMUX_PAD(0x0398, 0x0084, 1, 0x0844, 0, 0),
-	MX6Q_PAD_RGMII_RXC__GPIO_6_30		= IOMUX_PAD(0x0398, 0x0084, 5, 0x0000, 0, 0),
-	MX6Q_PAD_RGMII_RXC__MIPI_CORE_DPHY_IN11 = IOMUX_PAD(0x0398, 0x0084, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A25__WEIM_WEIM_A_25	= IOMUX_PAD(0x039C, 0x0088, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A25__ECSPI4_SS1		= IOMUX_PAD(0x039C, 0x0088, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A25__ECSPI2_RDY		= IOMUX_PAD(0x039C, 0x0088, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A25__IPU1_DI1_PIN12	= IOMUX_PAD(0x039C, 0x0088, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A25__IPU1_DI0_D1_CS	= IOMUX_PAD(0x039C, 0x0088, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A25__GPIO_5_2		= IOMUX_PAD(0x039C, 0x0088, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A25__HDMI_TX_CEC_LINE	= IOMUX_PAD(0x039C, 0x0088, 6, 0x088C, 0, 0),
-	MX6Q_PAD_EIM_A25__PL301_PER1_HBURST_0	= IOMUX_PAD(0x039C, 0x0088, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB2__WEIM_WEIM_EB_2	= IOMUX_PAD(0x03A0, 0x008C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB2__ECSPI1_SS0		= IOMUX_PAD(0x03A0, 0x008C, 1, 0x0800, 0, 0),
-	MX6Q_PAD_EIM_EB2__CCM_DI1_EXT_CLK	= IOMUX_PAD(0x03A0, 0x008C, 2, 0x07EC, 0, 0),
-	MX6Q_PAD_EIM_EB2__IPU2_CSI1_D_19	= IOMUX_PAD(0x03A0, 0x008C, 3, 0x08D4, 0, 0),
-	MX6Q_PAD_EIM_EB2__HDMI_TX_DDC_SCL	= IOMUX_PAD(0x03A0, 0x008C, 4, 0x0890, 0, 0),
-	MX6Q_PAD_EIM_EB2__GPIO_2_30		= IOMUX_PAD(0x03A0, 0x008C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB2__I2C2_SCL		= IOMUX_PAD(0x03A0, 0x008C, 22, 0x08A0, 0, 0),
-	MX6Q_PAD_EIM_EB2__SRC_BT_CFG_30		= IOMUX_PAD(0x03A0, 0x008C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D16__WEIM_WEIM_D_16	= IOMUX_PAD(0x03A4, 0x0090, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D16__ECSPI1_SCLK		= IOMUX_PAD(0x03A4, 0x0090, 1, 0x07F4, 0, 0),
-	MX6Q_PAD_EIM_D16__IPU1_DI0_PIN5		= IOMUX_PAD(0x03A4, 0x0090, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D16__IPU2_CSI1_D_18	= IOMUX_PAD(0x03A4, 0x0090, 3, 0x08D0, 0, 0),
-	MX6Q_PAD_EIM_D16__HDMI_TX_DDC_SDA	= IOMUX_PAD(0x03A4, 0x0090, 4, 0x0894, 0, 0),
-	MX6Q_PAD_EIM_D16__GPIO_3_16		= IOMUX_PAD(0x03A4, 0x0090, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D16__I2C2_SDA		= IOMUX_PAD(0x03A4, 0x0090, 22, 0x08A4, 0, 0),
-	MX6Q_PAD_EIM_D17__WEIM_WEIM_D_17	= IOMUX_PAD(0x03A8, 0x0094, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D17__ECSPI1_MISO		= IOMUX_PAD(0x03A8, 0x0094, 1, 0x07F8, 0, 0),
-	MX6Q_PAD_EIM_D17__IPU1_DI0_PIN6		= IOMUX_PAD(0x03A8, 0x0094, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D17__IPU2_CSI1_PIXCLK	= IOMUX_PAD(0x03A8, 0x0094, 3, 0x08E0, 0, 0),
-	MX6Q_PAD_EIM_D17__DCIC1_DCIC_OUT	= IOMUX_PAD(0x03A8, 0x0094, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D17__GPIO_3_17		= IOMUX_PAD(0x03A8, 0x0094, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D17__I2C3_SCL		= IOMUX_PAD(0x03A8, 0x0094, 22, 0x08A8, 0, 0),
-	MX6Q_PAD_EIM_D17__PL301_PER1_HBURST_1	= IOMUX_PAD(0x03A8, 0x0094, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D18__WEIM_WEIM_D_18	= IOMUX_PAD(0x03AC, 0x0098, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D18__ECSPI1_MOSI		= IOMUX_PAD(0x03AC, 0x0098, 1, 0x07FC, 0, 0),
-	MX6Q_PAD_EIM_D18__IPU1_DI0_PIN7		= IOMUX_PAD(0x03AC, 0x0098, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D18__IPU2_CSI1_D_17	= IOMUX_PAD(0x03AC, 0x0098, 3, 0x08CC, 0, 0),
-	MX6Q_PAD_EIM_D18__IPU1_DI1_D0_CS	= IOMUX_PAD(0x03AC, 0x0098, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D18__GPIO_3_18		= IOMUX_PAD(0x03AC, 0x0098, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D18__I2C3_SDA		= IOMUX_PAD(0x03AC, 0x0098, 22, 0x08AC, 0, 0),
-	MX6Q_PAD_EIM_D18__PL301_PER1_HBURST_2	= IOMUX_PAD(0x03AC, 0x0098, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D19__WEIM_WEIM_D_19	= IOMUX_PAD(0x03B0, 0x009C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D19__ECSPI1_SS1		= IOMUX_PAD(0x03B0, 0x009C, 1, 0x0804, 0, 0),
-	MX6Q_PAD_EIM_D19__IPU1_DI0_PIN8		= IOMUX_PAD(0x03B0, 0x009C, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D19__IPU2_CSI1_D_16	= IOMUX_PAD(0x03B0, 0x009C, 3, 0x08C8, 0, 0),
-	MX6Q_PAD_EIM_D19__UART1_CTS		= IOMUX_PAD(0x03B0, 0x009C, 4, 0x091C, 0, 0),
-	MX6Q_PAD_EIM_D19__GPIO_3_19		= IOMUX_PAD(0x03B0, 0x009C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D19__EPIT1_EPITO		= IOMUX_PAD(0x03B0, 0x009C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D19__PL301MX6QPER1_HRESP   = IOMUX_PAD(0x03B0, 0x009C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D20__WEIM_WEIM_D_20	= IOMUX_PAD(0x03B4, 0x00A0, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D20__ECSPI4_SS0		= IOMUX_PAD(0x03B4, 0x00A0, 1, 0x0824, 0, 0),
-	MX6Q_PAD_EIM_D20__IPU1_DI0_PIN16	= IOMUX_PAD(0x03B4, 0x00A0, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D20__IPU2_CSI1_D_15	= IOMUX_PAD(0x03B4, 0x00A0, 3, 0x08C4, 0, 0),
-	MX6Q_PAD_EIM_D20__UART1_CTS		= IOMUX_PAD(0x03B4, 0x00A0, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D20__UART1_RTS		= IOMUX_PAD(0x03B4, 0x00A0, 4, 0x091C, 1, 0),
-	MX6Q_PAD_EIM_D20__GPIO_3_20		= IOMUX_PAD(0x03B4, 0x00A0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D20__EPIT2_EPITO		= IOMUX_PAD(0x03B4, 0x00A0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D21__WEIM_WEIM_D_21	= IOMUX_PAD(0x03B8, 0x00A4, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D21__ECSPI4_SCLK		= IOMUX_PAD(0x03B8, 0x00A4, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D21__IPU1_DI0_PIN17	= IOMUX_PAD(0x03B8, 0x00A4, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D21__IPU2_CSI1_D_11	= IOMUX_PAD(0x03B8, 0x00A4, 3, 0x08B4, 0, 0),
-	MX6Q_PAD_EIM_D21__USBOH3_USBOTG_OC	= IOMUX_PAD(0x03B8, 0x00A4, 4, 0x0944, 0, 0),
-	MX6Q_PAD_EIM_D21__GPIO_3_21		= IOMUX_PAD(0x03B8, 0x00A4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D21__I2C1_SCL		= IOMUX_PAD(0x03B8, 0x00A4, 22, 0x0898, 0, 0),
-	MX6Q_PAD_EIM_D21__SPDIF_IN1		= IOMUX_PAD(0x03B8, 0x00A4, 7, 0x0914, 0, 0),
-	MX6Q_PAD_EIM_D22__WEIM_WEIM_D_22	= IOMUX_PAD(0x03BC, 0x00A8, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D22__ECSPI4_MISO		= IOMUX_PAD(0x03BC, 0x00A8, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D22__IPU1_DI0_PIN1		= IOMUX_PAD(0x03BC, 0x00A8, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D22__IPU2_CSI1_D_10	= IOMUX_PAD(0x03BC, 0x00A8, 3, 0x08B0, 0, 0),
-	MX6Q_PAD_EIM_D22__USBOH3_USBOTG_PWR	= IOMUX_PAD(0x03BC, 0x00A8, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D22__GPIO_3_22		= IOMUX_PAD(0x03BC, 0x00A8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D22__SPDIF_OUT1		= IOMUX_PAD(0x03BC, 0x00A8, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D22__PL301MX6QPER1_HWRITE	= IOMUX_PAD(0x03BC, 0x00A8, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D23__WEIM_WEIM_D_23	= IOMUX_PAD(0x03C0, 0x00AC, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D23__IPU1_DI0_D0_CS	= IOMUX_PAD(0x03C0, 0x00AC, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D23__UART3_CTS		= IOMUX_PAD(0x03C0, 0x00AC, 2, 0x092C, 0, 0),
-	MX6Q_PAD_EIM_D23__UART1_DCD		= IOMUX_PAD(0x03C0, 0x00AC, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D23__IPU2_CSI1_DATA_EN	= IOMUX_PAD(0x03C0, 0x00AC, 4, 0x08D8, 0, 0),
-	MX6Q_PAD_EIM_D23__GPIO_3_23		= IOMUX_PAD(0x03C0, 0x00AC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D23__IPU1_DI1_PIN2		= IOMUX_PAD(0x03C0, 0x00AC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D23__IPU1_DI1_PIN14	= IOMUX_PAD(0x03C0, 0x00AC, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB3__WEIM_WEIM_EB_3	= IOMUX_PAD(0x03C4, 0x00B0, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB3__ECSPI4_RDY		= IOMUX_PAD(0x03C4, 0x00B0, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB3__UART3_CTS		= IOMUX_PAD(0x03C4, 0x00B0, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB3__UART3_RTS		= IOMUX_PAD(0x03C4, 0x00B0, 2, 0x092C, 1, 0),
-	MX6Q_PAD_EIM_EB3__UART1_RI		= IOMUX_PAD(0x03C4, 0x00B0, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB3__IPU2_CSI1_HSYNC	= IOMUX_PAD(0x03C4, 0x00B0, 4, 0x08DC, 0, 0),
-	MX6Q_PAD_EIM_EB3__GPIO_2_31		= IOMUX_PAD(0x03C4, 0x00B0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB3__IPU1_DI1_PIN3		= IOMUX_PAD(0x03C4, 0x00B0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB3__SRC_BT_CFG_31		= IOMUX_PAD(0x03C4, 0x00B0, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D24__WEIM_WEIM_D_24	= IOMUX_PAD(0x03C8, 0x00B4, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D24__ECSPI4_SS2		= IOMUX_PAD(0x03C8, 0x00B4, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D24__UART3_TXD		= IOMUX_PAD(0x03C8, 0x00B4, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D24__UART3_TXD_RXD		= IOMUX_PAD(0x03C8, 0x00B4, 2, 0x0930, 0, 0),
-	MX6Q_PAD_EIM_D24__ECSPI1_SS2		= IOMUX_PAD(0x03C8, 0x00B4, 3, 0x0808, 0, 0),
-	MX6Q_PAD_EIM_D24__ECSPI2_SS2		= IOMUX_PAD(0x03C8, 0x00B4, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D24__GPIO_3_24		= IOMUX_PAD(0x03C8, 0x00B4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D24__AUDMUX_AUD5_RXFS	= IOMUX_PAD(0x03C8, 0x00B4, 6, 0x07D8, 0, 0),
-	MX6Q_PAD_EIM_D24__UART1_DTR		= IOMUX_PAD(0x03C8, 0x00B4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D25__WEIM_WEIM_D_25	= IOMUX_PAD(0x03CC, 0x00B8, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D25__ECSPI4_SS3		= IOMUX_PAD(0x03CC, 0x00B8, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D25__UART3_RXD		= IOMUX_PAD(0x03CC, 0x00B8, 2, 0x0930, 1, 0),
-	MX6Q_PAD_EIM_D25__ECSPI1_SS3		= IOMUX_PAD(0x03CC, 0x00B8, 3, 0x080C, 0, 0),
-	MX6Q_PAD_EIM_D25__ECSPI2_SS3		= IOMUX_PAD(0x03CC, 0x00B8, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D25__GPIO_3_25		= IOMUX_PAD(0x03CC, 0x00B8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D25__AUDMUX_AUD5_RXC	= IOMUX_PAD(0x03CC, 0x00B8, 6, 0x07D4, 0, 0),
-	MX6Q_PAD_EIM_D25__UART1_DSR		= IOMUX_PAD(0x03CC, 0x00B8, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D26__WEIM_WEIM_D_26	= IOMUX_PAD(0x03D0, 0x00BC, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D26__IPU1_DI1_PIN11	= IOMUX_PAD(0x03D0, 0x00BC, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D26__IPU1_CSI0_D_1		= IOMUX_PAD(0x03D0, 0x00BC, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D26__IPU2_CSI1_D_14	= IOMUX_PAD(0x03D0, 0x00BC, 3, 0x08C0, 0, 0),
-	MX6Q_PAD_EIM_D26__UART2_TXD		= IOMUX_PAD(0x03D0, 0x00BC, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D26__UART2_TXD_RXD		= IOMUX_PAD(0x03D0, 0x00BC, 4, 0x0928, 0, 0),
-	MX6Q_PAD_EIM_D26__GPIO_3_26		= IOMUX_PAD(0x03D0, 0x00BC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D26__IPU1_SISG_2		= IOMUX_PAD(0x03D0, 0x00BC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D26__IPU1_DISP1_DAT_22	= IOMUX_PAD(0x03D0, 0x00BC, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D27__WEIM_WEIM_D_27	= IOMUX_PAD(0x03D4, 0x00C0, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D27__IPU1_DI1_PIN13	= IOMUX_PAD(0x03D4, 0x00C0, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D27__IPU1_CSI0_D_0		= IOMUX_PAD(0x03D4, 0x00C0, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D27__IPU2_CSI1_D_13	= IOMUX_PAD(0x03D4, 0x00C0, 3, 0x08BC, 0, 0),
-	MX6Q_PAD_EIM_D27__UART2_RXD		= IOMUX_PAD(0x03D4, 0x00C0, 4, 0x0928, 1, 0),
-	MX6Q_PAD_EIM_D27__GPIO_3_27		= IOMUX_PAD(0x03D4, 0x00C0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D27__IPU1_SISG_3		= IOMUX_PAD(0x03D4, 0x00C0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D27__IPU1_DISP1_DAT_23	= IOMUX_PAD(0x03D4, 0x00C0, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D28__WEIM_WEIM_D_28	= IOMUX_PAD(0x03D8, 0x00C4, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D28__I2C1_SDA		= IOMUX_PAD(0x03D8, 0x00C4, 17, 0x089C, 0, 0),
-	MX6Q_PAD_EIM_D28__ECSPI4_MOSI		= IOMUX_PAD(0x03D8, 0x00C4, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D28__IPU2_CSI1_D_12	= IOMUX_PAD(0x03D8, 0x00C4, 3, 0x08B8, 0, 0),
-	MX6Q_PAD_EIM_D28__UART2_CTS		= IOMUX_PAD(0x03D8, 0x00C4, 4, 0x0924, 0, 0),
-	MX6Q_PAD_EIM_D28__GPIO_3_28		= IOMUX_PAD(0x03D8, 0x00C4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D28__IPU1_EXT_TRIG		= IOMUX_PAD(0x03D8, 0x00C4, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D28__IPU1_DI0_PIN13	= IOMUX_PAD(0x03D8, 0x00C4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D29__WEIM_WEIM_D_29	= IOMUX_PAD(0x03DC, 0x00C8, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D29__IPU1_DI1_PIN15	= IOMUX_PAD(0x03DC, 0x00C8, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D29__ECSPI4_SS0		= IOMUX_PAD(0x03DC, 0x00C8, 2, 0x0824, 1, 0),
-	MX6Q_PAD_EIM_D29__UART2_CTS		= IOMUX_PAD(0x03DC, 0x00C8, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D29__UART2_RTS		= IOMUX_PAD(0x03DC, 0x00C8, 4, 0x0924, 1, 0),
-	MX6Q_PAD_EIM_D29__GPIO_3_29		= IOMUX_PAD(0x03DC, 0x00C8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D29__IPU2_CSI1_VSYNC	= IOMUX_PAD(0x03DC, 0x00C8, 6, 0x08E4, 0, 0),
-	MX6Q_PAD_EIM_D29__IPU1_DI0_PIN14	= IOMUX_PAD(0x03DC, 0x00C8, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D30__WEIM_WEIM_D_30	= IOMUX_PAD(0x03E0, 0x00CC, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D30__IPU1_DISP1_DAT_21	= IOMUX_PAD(0x03E0, 0x00CC, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D30__IPU1_DI0_PIN11	= IOMUX_PAD(0x03E0, 0x00CC, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D30__IPU1_CSI0_D_3		= IOMUX_PAD(0x03E0, 0x00CC, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D30__UART3_CTS		= IOMUX_PAD(0x03E0, 0x00CC, 4, 0x092C, 2, 0),
-	MX6Q_PAD_EIM_D30__GPIO_3_30		= IOMUX_PAD(0x03E0, 0x00CC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D30__USBOH3_USBH1_OC	= IOMUX_PAD(0x03E0, 0x00CC, 6, 0x0948, 0, 0),
-	MX6Q_PAD_EIM_D30__PL301MX6QPER1_HPROT_0 = IOMUX_PAD(0x03E0, 0x00CC, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D31__WEIM_WEIM_D_31	= IOMUX_PAD(0x03E4, 0x00D0, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D31__IPU1_DISP1_DAT_20	= IOMUX_PAD(0x03E4, 0x00D0, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D31__IPU1_DI0_PIN12	= IOMUX_PAD(0x03E4, 0x00D0, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D31__IPU1_CSI0_D_2		= IOMUX_PAD(0x03E4, 0x00D0, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D31__UART3_CTS		= IOMUX_PAD(0x03E4, 0x00D0, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D31__UART3_RTS		= IOMUX_PAD(0x03E4, 0x00D0, 4, 0x092C, 3, 0),
-	MX6Q_PAD_EIM_D31__GPIO_3_31		= IOMUX_PAD(0x03E4, 0x00D0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D31__USBOH3_USBH1_PWR	= IOMUX_PAD(0x03E4, 0x00D0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_D31__PL301MX6QPER1_HPROT_1 = IOMUX_PAD(0x03E4, 0x00D0, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A24__WEIM_WEIM_A_24	= IOMUX_PAD(0x03E8, 0x00D4, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A24__IPU1_DISP1_DAT_19	= IOMUX_PAD(0x03E8, 0x00D4, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A24__IPU2_CSI1_D_19	= IOMUX_PAD(0x03E8, 0x00D4, 2, 0x08D4, 1, 0),
-	MX6Q_PAD_EIM_A24__IPU2_SISG_2		= IOMUX_PAD(0x03E8, 0x00D4, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A24__IPU1_SISG_2		= IOMUX_PAD(0x03E8, 0x00D4, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A24__GPIO_5_4		= IOMUX_PAD(0x03E8, 0x00D4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A24__PL301MX6QPER1_HPROT_2 = IOMUX_PAD(0x03E8, 0x00D4, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A24__SRC_BT_CFG_24		= IOMUX_PAD(0x03E8, 0x00D4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A23__WEIM_WEIM_A_23	= IOMUX_PAD(0x03EC, 0x00D8, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A23__IPU1_DISP1_DAT_18	= IOMUX_PAD(0x03EC, 0x00D8, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A23__IPU2_CSI1_D_18	= IOMUX_PAD(0x03EC, 0x00D8, 2, 0x08D0, 1, 0),
-	MX6Q_PAD_EIM_A23__IPU2_SISG_3		= IOMUX_PAD(0x03EC, 0x00D8, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A23__IPU1_SISG_3		= IOMUX_PAD(0x03EC, 0x00D8, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A23__GPIO_6_6		= IOMUX_PAD(0x03EC, 0x00D8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A23__PL301MX6QPER1_HPROT_3	= IOMUX_PAD(0x03EC, 0x00D8, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A23__SRC_BT_CFG_23		= IOMUX_PAD(0x03EC, 0x00D8, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A22__WEIM_WEIM_A_22	= IOMUX_PAD(0x03F0, 0x00DC, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A22__IPU1_DISP1_DAT_17	= IOMUX_PAD(0x03F0, 0x00DC, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A22__IPU2_CSI1_D_17	= IOMUX_PAD(0x03F0, 0x00DC, 2, 0x08CC, 1, 0),
-	MX6Q_PAD_EIM_A22__GPIO_2_16		= IOMUX_PAD(0x03F0, 0x00DC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A22__TPSMP_HDATA_0		= IOMUX_PAD(0x03F0, 0x00DC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A22__SRC_BT_CFG_22		= IOMUX_PAD(0x03F0, 0x00DC, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A21__WEIM_WEIM_A_21	= IOMUX_PAD(0x03F4, 0x00E0, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A21__IPU1_DISP1_DAT_16	= IOMUX_PAD(0x03F4, 0x00E0, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A21__IPU2_CSI1_D_16	= IOMUX_PAD(0x03F4, 0x00E0, 2, 0x08C8, 1, 0),
-	MX6Q_PAD_EIM_A21__RESERVED_RESERVED	= IOMUX_PAD(0x03F4, 0x00E0, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A21__MIPI_CORE_DPHY_OUT_18 = IOMUX_PAD(0x03F4, 0x00E0, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A21__GPIO_2_17		= IOMUX_PAD(0x03F4, 0x00E0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A21__TPSMP_HDATA_1		= IOMUX_PAD(0x03F4, 0x00E0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A21__SRC_BT_CFG_21		= IOMUX_PAD(0x03F4, 0x00E0, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A20__WEIM_WEIM_A_20	= IOMUX_PAD(0x03F8, 0x00E4, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A20__IPU1_DISP1_DAT_15	= IOMUX_PAD(0x03F8, 0x00E4, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A20__IPU2_CSI1_D_15	= IOMUX_PAD(0x03F8, 0x00E4, 2, 0x08C4, 1, 0),
-	MX6Q_PAD_EIM_A20__RESERVED_RESERVED	= IOMUX_PAD(0x03F8, 0x00E4, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A20__MIPI_CORE_DPHY_OUT_19 = IOMUX_PAD(0x03F8, 0x00E4, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A20__GPIO_2_18		= IOMUX_PAD(0x03F8, 0x00E4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A20__TPSMP_HDATA_2		= IOMUX_PAD(0x03F8, 0x00E4, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A20__SRC_BT_CFG_20		= IOMUX_PAD(0x03F8, 0x00E4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A19__WEIM_WEIM_A_19	= IOMUX_PAD(0x03FC, 0x00E8, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A19__IPU1_DISP1_DAT_14	= IOMUX_PAD(0x03FC, 0x00E8, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A19__IPU2_CSI1_D_14	= IOMUX_PAD(0x03FC, 0x00E8, 2, 0x08C0, 1, 0),
-	MX6Q_PAD_EIM_A19__RESERVED_RESERVED	= IOMUX_PAD(0x03FC, 0x00E8, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A19__MIPI_CORE_DPHY_OUT_20 = IOMUX_PAD(0x03FC, 0x00E8, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A19__GPIO_2_19		= IOMUX_PAD(0x03FC, 0x00E8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A19__TPSMP_HDATA_3		= IOMUX_PAD(0x03FC, 0x00E8, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A19__SRC_BT_CFG_19		= IOMUX_PAD(0x03FC, 0x00E8, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A18__WEIM_WEIM_A_18	= IOMUX_PAD(0x0400, 0x00EC, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A18__IPU1_DISP1_DAT_13	= IOMUX_PAD(0x0400, 0x00EC, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A18__IPU2_CSI1_D_13	= IOMUX_PAD(0x0400, 0x00EC, 2, 0x08BC, 1, 0),
-	MX6Q_PAD_EIM_A18__RESERVED_RESERVED	= IOMUX_PAD(0x0400, 0x00EC, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A18__MIPI_CORE_DPHY_OUT_21 = IOMUX_PAD(0x0400, 0x00EC, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A18__GPIO_2_20		= IOMUX_PAD(0x0400, 0x00EC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A18__TPSMP_HDATA_4		= IOMUX_PAD(0x0400, 0x00EC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A18__SRC_BT_CFG_18		= IOMUX_PAD(0x0400, 0x00EC, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A17__WEIM_WEIM_A_17	= IOMUX_PAD(0x0404, 0x00F0, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A17__IPU1_DISP1_DAT_12	= IOMUX_PAD(0x0404, 0x00F0, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A17__IPU2_CSI1_D_12	= IOMUX_PAD(0x0404, 0x00F0, 2, 0x08B8, 1, 0),
-	MX6Q_PAD_EIM_A17__RESERVED_RESERVED	= IOMUX_PAD(0x0404, 0x00F0, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A17__MIPI_CORE_DPHY_OUT_22 = IOMUX_PAD(0x0404, 0x00F0, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A17__GPIO_2_21		= IOMUX_PAD(0x0404, 0x00F0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A17__TPSMP_HDATA_5		= IOMUX_PAD(0x0404, 0x00F0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A17__SRC_BT_CFG_17		= IOMUX_PAD(0x0404, 0x00F0, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A16__WEIM_WEIM_A_16	= IOMUX_PAD(0x0408, 0x00F4, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A16__IPU1_DI1_DISP_CLK	= IOMUX_PAD(0x0408, 0x00F4, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A16__IPU2_CSI1_PIXCLK	= IOMUX_PAD(0x0408, 0x00F4, 2, 0x08E0, 1, 0),
-	MX6Q_PAD_EIM_A16__MIPI_CORE_DPHY_OUT_23 = IOMUX_PAD(0x0408, 0x00F4, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A16__GPIO_2_22		= IOMUX_PAD(0x0408, 0x00F4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A16__TPSMP_HDATA_6		= IOMUX_PAD(0x0408, 0x00F4, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_A16__SRC_BT_CFG_16		= IOMUX_PAD(0x0408, 0x00F4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_CS0__WEIM_WEIM_CS_0	= IOMUX_PAD(0x040C, 0x00F8, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_CS0__IPU1_DI1_PIN5		= IOMUX_PAD(0x040C, 0x00F8, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_CS0__ECSPI2_SCLK		= IOMUX_PAD(0x040C, 0x00F8, 2, 0x0810, 0, 0),
-	MX6Q_PAD_EIM_CS0__MIPI_CORE_DPHY_OUT_24 = IOMUX_PAD(0x040C, 0x00F8, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_CS0__GPIO_2_23		= IOMUX_PAD(0x040C, 0x00F8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_CS0__TPSMP_HDATA_7		= IOMUX_PAD(0x040C, 0x00F8, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_CS1__WEIM_WEIM_CS_1	= IOMUX_PAD(0x0410, 0x00FC, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_CS1__IPU1_DI1_PIN6		= IOMUX_PAD(0x0410, 0x00FC, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_CS1__ECSPI2_MOSI		= IOMUX_PAD(0x0410, 0x00FC, 2, 0x0818, 0, 0),
-	MX6Q_PAD_EIM_CS1__MIPI_CORE_DPHY_OUT_25 = IOMUX_PAD(0x0410, 0x00FC, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_CS1__GPIO_2_24		= IOMUX_PAD(0x0410, 0x00FC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_CS1__TPSMP_HDATA_8		= IOMUX_PAD(0x0410, 0x00FC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_OE__WEIM_WEIM_OE		= IOMUX_PAD(0x0414, 0x0100, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_OE__IPU1_DI1_PIN7		= IOMUX_PAD(0x0414, 0x0100, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_OE__ECSPI2_MISO		= IOMUX_PAD(0x0414, 0x0100, 2, 0x0814, 0, 0),
-	MX6Q_PAD_EIM_OE__MIPI_CORE_DPHY_OUT_26  = IOMUX_PAD(0x0414, 0x0100, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_OE__GPIO_2_25		= IOMUX_PAD(0x0414, 0x0100, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_OE__TPSMP_HDATA_9		= IOMUX_PAD(0x0414, 0x0100, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_RW__WEIM_WEIM_RW		= IOMUX_PAD(0x0418, 0x0104, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_RW__IPU1_DI1_PIN8		= IOMUX_PAD(0x0418, 0x0104, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_RW__ECSPI2_SS0		= IOMUX_PAD(0x0418, 0x0104, 2, 0x081C, 0, 0),
-	MX6Q_PAD_EIM_RW__MIPI_CORE_DPHY_OUT_27  = IOMUX_PAD(0x0418, 0x0104, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_RW__GPIO_2_26		= IOMUX_PAD(0x0418, 0x0104, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_RW__TPSMP_HDATA_10		= IOMUX_PAD(0x0418, 0x0104, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_RW__SRC_BT_CFG_29		= IOMUX_PAD(0x0418, 0x0104, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_LBA__WEIM_WEIM_LBA		= IOMUX_PAD(0x041C, 0x0108, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_LBA__IPU1_DI1_PIN17	= IOMUX_PAD(0x041C, 0x0108, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_LBA__ECSPI2_SS1		= IOMUX_PAD(0x041C, 0x0108, 2, 0x0820, 0, 0),
-	MX6Q_PAD_EIM_LBA__GPIO_2_27		= IOMUX_PAD(0x041C, 0x0108, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_LBA__TPSMP_HDATA_11	= IOMUX_PAD(0x041C, 0x0108, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_LBA__SRC_BT_CFG_26		= IOMUX_PAD(0x041C, 0x0108, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB0__WEIM_WEIM_EB_0	= IOMUX_PAD(0x0420, 0x010C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB0__IPU1_DISP1_DAT_11	= IOMUX_PAD(0x0420, 0x010C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB0__IPU2_CSI1_D_11	= IOMUX_PAD(0x0420, 0x010C, 2, 0x08B4, 1, 0),
-	MX6Q_PAD_EIM_EB0__MIPI_CORE_DPHY_OUT_0  = IOMUX_PAD(0x0420, 0x010C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB0__CCM_PMIC_RDY		= IOMUX_PAD(0x0420, 0x010C, 4, 0x07F0, 0, 0),
-	MX6Q_PAD_EIM_EB0__GPIO_2_28		= IOMUX_PAD(0x0420, 0x010C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB0__TPSMP_HDATA_12	= IOMUX_PAD(0x0420, 0x010C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB0__SRC_BT_CFG_27		= IOMUX_PAD(0x0420, 0x010C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB1__WEIM_WEIM_EB_1	= IOMUX_PAD(0x0424, 0x0110, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB1__IPU1_DISP1_DAT_10	= IOMUX_PAD(0x0424, 0x0110, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB1__IPU2_CSI1_D_10	= IOMUX_PAD(0x0424, 0x0110, 2, 0x08B0, 1, 0),
-	MX6Q_PAD_EIM_EB1__MIPI_CORE_DPHY__OUT_1 = IOMUX_PAD(0x0424, 0x0110, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB1__GPIO_2_29		= IOMUX_PAD(0x0424, 0x0110, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB1__TPSMP_HDATA_13	= IOMUX_PAD(0x0424, 0x0110, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_EB1__SRC_BT_CFG_28		= IOMUX_PAD(0x0424, 0x0110, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA0__WEIM_WEIM_DA_A_0	= IOMUX_PAD(0x0428, 0x0114, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA0__IPU1_DISP1_DAT_9	= IOMUX_PAD(0x0428, 0x0114, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA0__IPU2_CSI1_D_9		= IOMUX_PAD(0x0428, 0x0114, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA0__MIPI_CORE_DPHY__OUT_2	= IOMUX_PAD(0x0428, 0x0114, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA0__GPIO_3_0		= IOMUX_PAD(0x0428, 0x0114, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA0__TPSMP_HDATA_14	= IOMUX_PAD(0x0428, 0x0114, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA0__SRC_BT_CFG_0		= IOMUX_PAD(0x0428, 0x0114, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA1__WEIM_WEIM_DA_A_1	= IOMUX_PAD(0x042C, 0x0118, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA1__IPU1_DISP1_DAT_8	= IOMUX_PAD(0x042C, 0x0118, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA1__IPU2_CSI1_D_8		= IOMUX_PAD(0x042C, 0x0118, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA1__MIPI_CORE_DPHY_OUT_3	= IOMUX_PAD(0x042C, 0x0118, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA1__USBPHY1_TX_LS_MODE	= IOMUX_PAD(0x042C, 0x0118, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA1__GPIO_3_1		= IOMUX_PAD(0x042C, 0x0118, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA1__TPSMP_HDATA_15	= IOMUX_PAD(0x042C, 0x0118, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA1__SRC_BT_CFG_1		= IOMUX_PAD(0x042C, 0x0118, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA2__WEIM_WEIM_DA_A_2	= IOMUX_PAD(0x0430, 0x011C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA2__IPU1_DISP1_DAT_7	= IOMUX_PAD(0x0430, 0x011C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA2__IPU2_CSI1_D_7		= IOMUX_PAD(0x0430, 0x011C, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA2__MIPI_CORE_DPHY_OUT_4  = IOMUX_PAD(0x0430, 0x011C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA2__USBPHY1_TX_HS_MODE	= IOMUX_PAD(0x0430, 0x011C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA2__GPIO_3_2		= IOMUX_PAD(0x0430, 0x011C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA2__TPSMP_HDATA_16	= IOMUX_PAD(0x0430, 0x011C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA2__SRC_BT_CFG_2		= IOMUX_PAD(0x0430, 0x011C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA3__WEIM_WEIM_DA_A_3	= IOMUX_PAD(0x0434, 0x0120, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA3__IPU1_DISP1_DAT_6	= IOMUX_PAD(0x0434, 0x0120, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA3__IPU2_CSI1_D_6		= IOMUX_PAD(0x0434, 0x0120, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA3__MIPI_CORE_DPHY_OUT_5  = IOMUX_PAD(0x0434, 0x0120, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA3__USBPHY1_TX_HIZ        = IOMUX_PAD(0x0434, 0x0120, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA3__GPIO_3_3		= IOMUX_PAD(0x0434, 0x0120, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA3__TPSMP_HDATA_17	= IOMUX_PAD(0x0434, 0x0120, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA3__SRC_BT_CFG_3		= IOMUX_PAD(0x0434, 0x0120, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA4__WEIM_WEIM_DA_A_4	= IOMUX_PAD(0x0438, 0x0124, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA4__IPU1_DISP1_DAT_5	= IOMUX_PAD(0x0438, 0x0124, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA4__IPU2_CSI1_D_5		= IOMUX_PAD(0x0438, 0x0124, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA4__MIPI_CORE_DPHY_OUT_6  = IOMUX_PAD(0x0438, 0x0124, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA4__ANATOP_USBPHY1_TX_EN  = IOMUX_PAD(0x0438, 0x0124, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA4__GPIO_3_4		= IOMUX_PAD(0x0438, 0x0124, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA4__TPSMP_HDATA_18	= IOMUX_PAD(0x0438, 0x0124, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA4__SRC_BT_CFG_4		= IOMUX_PAD(0x0438, 0x0124, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA5__WEIM_WEIM_DA_A_5	= IOMUX_PAD(0x043C, 0x0128, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA5__IPU1_DISP1_DAT_4	= IOMUX_PAD(0x043C, 0x0128, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA5__IPU2_CSI1_D_4		= IOMUX_PAD(0x043C, 0x0128, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA5__MIPI_CORE_DPHY_OUT_7  = IOMUX_PAD(0x043C, 0x0128, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA5__ANATOP_USBPHY1_TX_DP  = IOMUX_PAD(0x043C, 0x0128, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA5__GPIO_3_5		= IOMUX_PAD(0x043C, 0x0128, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA5__TPSMP_HDATA_19	= IOMUX_PAD(0x043C, 0x0128, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA5__SRC_BT_CFG_5		= IOMUX_PAD(0x043C, 0x0128, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA6__WEIM_WEIM_DA_A_6	= IOMUX_PAD(0x0440, 0x012C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA6__IPU1_DISP1_DAT_3	= IOMUX_PAD(0x0440, 0x012C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA6__IPU2_CSI1_D_3		= IOMUX_PAD(0x0440, 0x012C, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA6__MIPI_CORE_DPHY_OUT_8  = IOMUX_PAD(0x0440, 0x012C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA6__ANATOP_USBPHY1_TX_DN  = IOMUX_PAD(0x0440, 0x012C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA6__GPIO_3_6		= IOMUX_PAD(0x0440, 0x012C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA6__TPSMP_HDATA_20	= IOMUX_PAD(0x0440, 0x012C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA6__SRC_BT_CFG_6		= IOMUX_PAD(0x0440, 0x012C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA7__WEIM_WEIM_DA_A_7	= IOMUX_PAD(0x0444, 0x0130, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA7__IPU1_DISP1_DAT_2	= IOMUX_PAD(0x0444, 0x0130, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA7__IPU2_CSI1_D_2		= IOMUX_PAD(0x0444, 0x0130, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA7__MIPI_CORE_DPHY_OUT_9	= IOMUX_PAD(0x0444, 0x0130, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA7__GPIO_3_7		= IOMUX_PAD(0x0444, 0x0130, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA7__TPSMP_HDATA_21	= IOMUX_PAD(0x0444, 0x0130, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA7__SRC_BT_CFG_7		= IOMUX_PAD(0x0444, 0x0130, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA8__WEIM_WEIM_DA_A_8	= IOMUX_PAD(0x0448, 0x0134, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA8__IPU1_DISP1_DAT_1	= IOMUX_PAD(0x0448, 0x0134, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA8__IPU2_CSI1_D_1		= IOMUX_PAD(0x0448, 0x0134, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA8__MIPI_CORE_DPHY_OUT_10 = IOMUX_PAD(0x0448, 0x0134, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA8__GPIO_3_8		= IOMUX_PAD(0x0448, 0x0134, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA8__TPSMP_HDATA_22	= IOMUX_PAD(0x0448, 0x0134, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA8__SRC_BT_CFG_8		= IOMUX_PAD(0x0448, 0x0134, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA9__WEIM_WEIM_DA_A_9	= IOMUX_PAD(0x044C, 0x0138, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA9__IPU1_DISP1_DAT_0	= IOMUX_PAD(0x044C, 0x0138, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA9__IPU2_CSI1_D_0		= IOMUX_PAD(0x044C, 0x0138, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA9__MIPI_CORE_DPHY_OUT_11 = IOMUX_PAD(0x044C, 0x0138, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA9__GPIO_3_9		= IOMUX_PAD(0x044C, 0x0138, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA9__TPSMP_HDATA_23	= IOMUX_PAD(0x044C, 0x0138, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA9__SRC_BT_CFG_9		= IOMUX_PAD(0x044C, 0x0138, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA10__WEIM_WEIM_DA_A_10	= IOMUX_PAD(0x0450, 0x013C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA10__IPU1_DI1_PIN15	= IOMUX_PAD(0x0450, 0x013C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA10__IPU2_CSI1_DATA_EN    = IOMUX_PAD(0x0450, 0x013C, 2, 0x08D8, 1, 0),
-	MX6Q_PAD_EIM_DA10__MIPI_CORE_DPHY_OUT12	= IOMUX_PAD(0x0450, 0x013C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA10__GPIO_3_10		= IOMUX_PAD(0x0450, 0x013C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA10__TPSMP_HDATA_24	= IOMUX_PAD(0x0450, 0x013C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA10__SRC_BT_CFG_10	= IOMUX_PAD(0x0450, 0x013C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA11__WEIM_WEIM_DA_A_11	= IOMUX_PAD(0x0454, 0x0140, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA11__IPU1_DI1_PIN2	= IOMUX_PAD(0x0454, 0x0140, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA11__IPU2_CSI1_HSYNC	= IOMUX_PAD(0x0454, 0x0140, 2, 0x08DC, 1, 0),
-	MX6Q_PAD_EIM_DA11__MIPI_CORE_DPHY_OUT13	= IOMUX_PAD(0x0454, 0x0140, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA11__SDMA_DBG_EVT_CHN_6	= IOMUX_PAD(0x0454, 0x0140, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA11__GPIO_3_11		= IOMUX_PAD(0x0454, 0x0140, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA11__TPSMP_HDATA_25	= IOMUX_PAD(0x0454, 0x0140, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA11__SRC_BT_CFG_11	= IOMUX_PAD(0x0454, 0x0140, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA12__WEIM_WEIM_DA_A_12	= IOMUX_PAD(0x0458, 0x0144, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA12__IPU1_DI1_PIN3	= IOMUX_PAD(0x0458, 0x0144, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA12__IPU2_CSI1_VSYNC	= IOMUX_PAD(0x0458, 0x0144, 2, 0x08E4, 1, 0),
-	MX6Q_PAD_EIM_DA12__MIPI_CORE_DPHY_OUT14	= IOMUX_PAD(0x0458, 0x0144, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA12__SDMA_DEBUG_EVT_CHN_3 = IOMUX_PAD(0x0458, 0x0144, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA12__GPIO_3_12		= IOMUX_PAD(0x0458, 0x0144, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA12__TPSMP_HDATA_26	= IOMUX_PAD(0x0458, 0x0144, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA12__SRC_BT_CFG_12	= IOMUX_PAD(0x0458, 0x0144, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA13__WEIM_WEIM_DA_A_13	= IOMUX_PAD(0x045C, 0x0148, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA13__IPU1_DI1_D0_CS	= IOMUX_PAD(0x045C, 0x0148, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA13__CCM_DI1_EXT_CLK	= IOMUX_PAD(0x045C, 0x0148, 2, 0x07EC, 1, 0),
-	MX6Q_PAD_EIM_DA13__MIPI_CORE_DPHY_OUT15	= IOMUX_PAD(0x045C, 0x0148, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA13__SDMA_DEBUG_EVT_CHN_4 = IOMUX_PAD(0x045C, 0x0148, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA13__GPIO_3_13		= IOMUX_PAD(0x045C, 0x0148, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA13__TPSMP_HDATA_27	= IOMUX_PAD(0x045C, 0x0148, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA13__SRC_BT_CFG_13	= IOMUX_PAD(0x045C, 0x0148, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA14__WEIM_WEIM_DA_A_14	= IOMUX_PAD(0x0460, 0x014C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA14__IPU1_DI1_D1_CS	= IOMUX_PAD(0x0460, 0x014C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA14__CCM_DI0_EXT_CLK	= IOMUX_PAD(0x0460, 0x014C, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA14__MIPI_CORE_DPHY_OUT16	= IOMUX_PAD(0x0460, 0x014C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA14__SDMA_DEBUG_EVT_CHN_5 = IOMUX_PAD(0x0460, 0x014C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA14__GPIO_3_14		= IOMUX_PAD(0x0460, 0x014C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA14__TPSMP_HDATA_28	= IOMUX_PAD(0x0460, 0x014C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA14__SRC_BT_CFG_14	= IOMUX_PAD(0x0460, 0x014C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA15__WEIM_WEIM_DA_A_15	= IOMUX_PAD(0x0464, 0x0150, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA15__IPU1_DI1_PIN1	= IOMUX_PAD(0x0464, 0x0150, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA15__IPU1_DI1_PIN4	= IOMUX_PAD(0x0464, 0x0150, 2, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA15__MIPI_CORE_DPHY_OUT17	= IOMUX_PAD(0x0464, 0x0150, 3, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA15__GPIO_3_15		= IOMUX_PAD(0x0464, 0x0150, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA15__TPSMP_HDATA_29	= IOMUX_PAD(0x0464, 0x0150, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_DA15__SRC_BT_CFG_15	= IOMUX_PAD(0x0464, 0x0150, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_WAIT__WEIM_WEIM_WAIT	= IOMUX_PAD(0x0468, 0x0154, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_WAIT__WEIM_WEIM_DTACK_B	= IOMUX_PAD(0x0468, 0x0154, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_WAIT__GPIO_5_0		= IOMUX_PAD(0x0468, 0x0154, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_WAIT__TPSMP_HDATA_30	= IOMUX_PAD(0x0468, 0x0154, 6, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_WAIT__SRC_BT_CFG_25	= IOMUX_PAD(0x0468, 0x0154, 7, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_BCLK__WEIM_WEIM_BCLK	= IOMUX_PAD(0x046C, 0x0158, 0, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_BCLK__IPU1_DI1_PIN16	= IOMUX_PAD(0x046C, 0x0158, 1, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_BCLK__GPIO_6_31		= IOMUX_PAD(0x046C, 0x0158, 5, 0x0000, 0, 0),
-	MX6Q_PAD_EIM_BCLK__TPSMP_HDATA_31	= IOMUX_PAD(0x046C, 0x0158, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK = IOMUX_PAD(0x0470, 0x015C, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DI0_DISP_CLK__IPU2_DI0_DISP_CLK = IOMUX_PAD(0x0470, 0x015C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_DISP_CLK__MIPI_CR_DPY_OT28 = IOMUX_PAD(0x0470, 0x015C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_DISP_CLK__SDMA_DBG_CR_STA0 = IOMUX_PAD(0x0470, 0x015C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_DISP_CLK__GPIO_4_16	= IOMUX_PAD(0x0470, 0x015C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_DISP_CLK__MMDC_DEBUG_0	= IOMUX_PAD(0x0470, 0x015C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15	= IOMUX_PAD(0x0474, 0x0160, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DI0_PIN15__IPU2_DI0_PIN15	= IOMUX_PAD(0x0474, 0x0160, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN15__AUDMUX_AUD6_TXC	= IOMUX_PAD(0x0474, 0x0160, 2, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN15__MIPI_CR_DPHY_OUT_29 = IOMUX_PAD(0x0474, 0x0160, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN15__SDMA_DBG_CORE_STA_1 = IOMUX_PAD(0x0474, 0x0160, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN15__GPIO_4_17		= IOMUX_PAD(0x0474, 0x0160, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN15__MMDC_MMDC_DEBUG_1	= IOMUX_PAD(0x0474, 0x0160, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2	= IOMUX_PAD(0x0478, 0x0164, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DI0_PIN2__IPU2_DI0_PIN2	= IOMUX_PAD(0x0478, 0x0164, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN2__AUDMUX_AUD6_TXD	= IOMUX_PAD(0x0478, 0x0164, 2, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN2__MIPI_CR_DPHY_OUT_30	= IOMUX_PAD(0x0478, 0x0164, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN2__SDMA_DBG_CORE_STA_2	= IOMUX_PAD(0x0478, 0x0164, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN2__GPIO_4_18		= IOMUX_PAD(0x0478, 0x0164, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN2__MMDC_DEBUG_2		= IOMUX_PAD(0x0478, 0x0164, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN2__PL301_PER1_HADDR_9	= IOMUX_PAD(0x0478, 0x0164, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3	= IOMUX_PAD(0x047C, 0x0168, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DI0_PIN3__IPU2_DI0_PIN3	= IOMUX_PAD(0x047C, 0x0168, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN3__AUDMUX_AUD6_TXFS	= IOMUX_PAD(0x047C, 0x0168, 2, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN3__MIPI_CORE_DPHY_OUT31 = IOMUX_PAD(0x047C, 0x0168, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN3__SDMA_DBG_CORE_STA_3	= IOMUX_PAD(0x047C, 0x0168, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN3__GPIO_4_19		= IOMUX_PAD(0x047C, 0x0168, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN3__MMDC_MMDC_DEBUG_3	= IOMUX_PAD(0x047C, 0x0168, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN3__PL301_PER1_HADDR_10	= IOMUX_PAD(0x047C, 0x0168, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN4__IPU1_DI0_PIN4	= IOMUX_PAD(0x0480, 0x016C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN4__IPU2_DI0_PIN4	= IOMUX_PAD(0x0480, 0x016C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN4__AUDMUX_AUD6_RXD	= IOMUX_PAD(0x0480, 0x016C, 2, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN4__USDHC1_WP		= IOMUX_PAD(0x0480, 0x016C, 3, 0x094C, 0, 0),
-	MX6Q_PAD_DI0_PIN4__SDMA_DEBUG_YIELD	= IOMUX_PAD(0x0480, 0x016C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN4__GPIO_4_20		= IOMUX_PAD(0x0480, 0x016C, 5, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DI0_PIN4__MMDC_MMDC_DEBUG_4	= IOMUX_PAD(0x0480, 0x016C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DI0_PIN4__PL301_PER1_HADDR_11  = IOMUX_PAD(0x0480, 0x016C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0	= IOMUX_PAD(0x0484, 0x0170, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT0__IPU2_DISP0_DAT_0	= IOMUX_PAD(0x0484, 0x0170, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT0__ECSPI3_SCLK	= IOMUX_PAD(0x0484, 0x0170, 2, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT0__USDHC1_USDHC_DBG_0 = IOMUX_PAD(0x0484, 0x0170, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT0__SDMA_DBG_CORE_RUN	= IOMUX_PAD(0x0484, 0x0170, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT0__GPIO_4_21		= IOMUX_PAD(0x0484, 0x0170, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT0__MMDC_MMDC_DEBUG_5	= IOMUX_PAD(0x0484, 0x0170, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1	= IOMUX_PAD(0x0488, 0x0174, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT1__IPU2_DISP0_DAT_1	= IOMUX_PAD(0x0488, 0x0174, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT1__ECSPI3_MOSI	= IOMUX_PAD(0x0488, 0x0174, 2, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT1__USDHC1_USDHC_DBG_1 = IOMUX_PAD(0x0488, 0x0174, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT1__SDMA_DBG_EVT_CHNSL = IOMUX_PAD(0x0488, 0x0174, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT1__GPIO_4_22		= IOMUX_PAD(0x0488, 0x0174, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT1__MMDC_DEBUG_6	= IOMUX_PAD(0x0488, 0x0174, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT1__PL301_PER1_HADR_12 = IOMUX_PAD(0x0488, 0x0174, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2	= IOMUX_PAD(0x048C, 0x0178, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT2__IPU2_DISP0_DAT_2	= IOMUX_PAD(0x048C, 0x0178, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT2__ECSPI3_MISO	= IOMUX_PAD(0x048C, 0x0178, 2, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT2__USDHC1_USDHC_DBG_2 = IOMUX_PAD(0x048C, 0x0178, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT2__SDMA_DEBUG_MODE	= IOMUX_PAD(0x048C, 0x0178, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT2__GPIO_4_23		= IOMUX_PAD(0x048C, 0x0178, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT2__MMDC_DEBUG_7	= IOMUX_PAD(0x048C, 0x0178, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT2__PL301_PER1_HADR_13 = IOMUX_PAD(0x048C, 0x0178, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3	= IOMUX_PAD(0x0490, 0x017C, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT3__IPU2_DISP0_DAT_3	= IOMUX_PAD(0x0490, 0x017C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT3__ECSPI3_SS0		= IOMUX_PAD(0x0490, 0x017C, 2, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT3__USDHC1_USDHC_DBG_3 = IOMUX_PAD(0x0490, 0x017C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT3__SDMA_DBG_BUS_ERROR = IOMUX_PAD(0x0490, 0x017C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT3__GPIO_4_24		= IOMUX_PAD(0x0490, 0x017C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT3__MMDC_MMDC_DBG_8	= IOMUX_PAD(0x0490, 0x017C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT3__PL301_PER1_HADR_14 = IOMUX_PAD(0x0490, 0x017C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4	= IOMUX_PAD(0x0494, 0x0180, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT4__IPU2_DISP0_DAT_4	= IOMUX_PAD(0x0494, 0x0180, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT4__ECSPI3_SS1		= IOMUX_PAD(0x0494, 0x0180, 2, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT4__USDHC1_USDHC_DBG_4	= IOMUX_PAD(0x0494, 0x0180, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT4__SDMA_DEBUG_BUS_RWB = IOMUX_PAD(0x0494, 0x0180, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT4__GPIO_4_25		= IOMUX_PAD(0x0494, 0x0180, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT4__MMDC_MMDC_DEBUG_9	= IOMUX_PAD(0x0494, 0x0180, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT4__PL301_PER1_HADR_15	= IOMUX_PAD(0x0494, 0x0180, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5	= IOMUX_PAD(0x0498, 0x0184, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT5__IPU2_DISP0_DAT_5	= IOMUX_PAD(0x0498, 0x0184, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT5__ECSPI3_SS2		= IOMUX_PAD(0x0498, 0x0184, 2, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT5__AUDMUX_AUD6_RXFS	= IOMUX_PAD(0x0498, 0x0184, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT5__SDMA_DBG_MCH_DMBUS = IOMUX_PAD(0x0498, 0x0184, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT5__GPIO_4_26		= IOMUX_PAD(0x0498, 0x0184, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT5__MMDC_DEBUG_10	= IOMUX_PAD(0x0498, 0x0184, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT5__PL301_PER1_HADR_16 = IOMUX_PAD(0x0498, 0x0184, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6	= IOMUX_PAD(0x049C, 0x0188, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT6__IPU2_DISP0_DAT_6	= IOMUX_PAD(0x049C, 0x0188, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT6__ECSPI3_SS3		= IOMUX_PAD(0x049C, 0x0188, 2, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT6__AUDMUX_AUD6_RXC	= IOMUX_PAD(0x049C, 0x0188, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT6__SDMA_DBG_RTBUF_WRT = IOMUX_PAD(0x049C, 0x0188, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT6__GPIO_4_27		= IOMUX_PAD(0x049C, 0x0188, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT6__MMDC_DEBUG_11	= IOMUX_PAD(0x049C, 0x0188, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT6__PL301_PER1_HADR_17 = IOMUX_PAD(0x049C, 0x0188, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7	= IOMUX_PAD(0x04A0, 0x018C, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT7__IPU2_DISP0_DAT_7	= IOMUX_PAD(0x04A0, 0x018C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT7__ECSPI3_RDY		= IOMUX_PAD(0x04A0, 0x018C, 2, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT7__USDHC1_USDHC_DBG_5 = IOMUX_PAD(0x04A0, 0x018C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT7__SDMA_DBG_EVT_CHN_0 = IOMUX_PAD(0x04A0, 0x018C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT7__GPIO_4_28		= IOMUX_PAD(0x04A0, 0x018C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT7__MMDC_DEBUG_12	= IOMUX_PAD(0x04A0, 0x018C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT7__PL301_PER1_HADR_18 = IOMUX_PAD(0x04A0, 0x018C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8	= IOMUX_PAD(0x04A4, 0x0190, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT8__IPU2_DISP0_DAT_8	= IOMUX_PAD(0x04A4, 0x0190, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT8__PWM1_PWMO		= IOMUX_PAD(0x04A4, 0x0190, 2, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT8__WDOG1_WDOG_B	= IOMUX_PAD(0x04A4, 0x0190, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT8__SDMA_DBG_EVT_CHN_1	= IOMUX_PAD(0x04A4, 0x0190, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT8__GPIO_4_29		= IOMUX_PAD(0x04A4, 0x0190, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT8__MMDC_DEBUG_13	= IOMUX_PAD(0x04A4, 0x0190, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT8__PL301_PER1_HADR_19 = IOMUX_PAD(0x04A4, 0x0190, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9	= IOMUX_PAD(0x04A8, 0x0194, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT9__IPU2_DISP0_DAT_9	= IOMUX_PAD(0x04A8, 0x0194, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT9__PWM2_PWMO		= IOMUX_PAD(0x04A8, 0x0194, 2, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT9__WDOG2_WDOG_B	= IOMUX_PAD(0x04A8, 0x0194, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT9__SDMA_DBG_EVT_CHN_2 = IOMUX_PAD(0x04A8, 0x0194, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT9__GPIO_4_30		= IOMUX_PAD(0x04A8, 0x0194, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT9__MMDC_DEBUG_14	= IOMUX_PAD(0x04A8, 0x0194, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT9__PL301_PER1_HADR_20 = IOMUX_PAD(0x04A8, 0x0194, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10	= IOMUX_PAD(0x04AC, 0x0198, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT10__IPU2_DISP0_DAT_10	= IOMUX_PAD(0x04AC, 0x0198, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT10__USDHC1_DBG_6	= IOMUX_PAD(0x04AC, 0x0198, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT10__SDMA_DBG_EVT_CHN3 = IOMUX_PAD(0x04AC, 0x0198, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT10__GPIO_4_31		= IOMUX_PAD(0x04AC, 0x0198, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT10__MMDC_DEBUG_15	= IOMUX_PAD(0x04AC, 0x0198, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT10__PL301_PER1_HADR21 = IOMUX_PAD(0x04AC, 0x0198, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11	= IOMUX_PAD(0x04B0, 0x019C, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT11__IPU2_DISP0_DAT_11	= IOMUX_PAD(0x04B0, 0x019C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT11__USDHC1_USDHC_DBG7 = IOMUX_PAD(0x04B0, 0x019C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT11__SDMA_DBG_EVT_CHN4 = IOMUX_PAD(0x04B0, 0x019C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT11__GPIO_5_5		= IOMUX_PAD(0x04B0, 0x019C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT11__MMDC_DEBUG_16	= IOMUX_PAD(0x04B0, 0x019C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT11__PL301_PER1_HADR22 = IOMUX_PAD(0x04B0, 0x019C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12	= IOMUX_PAD(0x04B4, 0x01A0, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT12__IPU2_DISP0_DAT_12	= IOMUX_PAD(0x04B4, 0x01A0, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT12__RESERVED_RESERVED	= IOMUX_PAD(0x04B4, 0x01A0, 3, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT12__SDMA_DBG_EVT_CHN5 = IOMUX_PAD(0x04B4, 0x01A0, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT12__GPIO_5_6		= IOMUX_PAD(0x04B4, 0x01A0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT12__MMDC_DEBUG_17	= IOMUX_PAD(0x04B4, 0x01A0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT12__PL301_PER1_HADR23 = IOMUX_PAD(0x04B4, 0x01A0, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13	= IOMUX_PAD(0x04B8, 0x01A4, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT13__IPU2_DISP0_DAT_13	= IOMUX_PAD(0x04B8, 0x01A4, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT13__AUDMUX_AUD5_RXFS	= IOMUX_PAD(0x04B8, 0x01A4, 3, 0x07D8, 1, 0),
-	MX6Q_PAD_DISP0_DAT13__SDMA_DBG_EVT_CHN0 = IOMUX_PAD(0x04B8, 0x01A4, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT13__GPIO_5_7		= IOMUX_PAD(0x04B8, 0x01A4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT13__MMDC_DEBUG_18	= IOMUX_PAD(0x04B8, 0x01A4, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT13__PL301_PER1_HADR24 = IOMUX_PAD(0x04B8, 0x01A4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14	= IOMUX_PAD(0x04BC, 0x01A8, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT14__IPU2_DISP0_DAT_14	= IOMUX_PAD(0x04BC, 0x01A8, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT14__AUDMUX_AUD5_RXC	= IOMUX_PAD(0x04BC, 0x01A8, 3, 0x07D4, 1, 0),
-	MX6Q_PAD_DISP0_DAT14__SDMA_DBG_EVT_CHN1 = IOMUX_PAD(0x04BC, 0x01A8, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT14__GPIO_5_8		= IOMUX_PAD(0x04BC, 0x01A8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT14__MMDC_DEBUG_19	= IOMUX_PAD(0x04BC, 0x01A8, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15	= IOMUX_PAD(0x04C0, 0x01AC, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT15__IPU2_DISP0_DAT_15	= IOMUX_PAD(0x04C0, 0x01AC, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT15__ECSPI1_SS1	= IOMUX_PAD(0x04C0, 0x01AC, 2, 0x0804, 1, 0),
-	MX6Q_PAD_DISP0_DAT15__ECSPI2_SS1	= IOMUX_PAD(0x04C0, 0x01AC, 3, 0x0820, 1, 0),
-	MX6Q_PAD_DISP0_DAT15__SDMA_DBG_EVT_CHN2 = IOMUX_PAD(0x04C0, 0x01AC, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT15__GPIO_5_9		= IOMUX_PAD(0x04C0, 0x01AC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT15__MMDC_DEBUG_20	= IOMUX_PAD(0x04C0, 0x01AC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT15__PL301_PER1_HADR25 = IOMUX_PAD(0x04C0, 0x01AC, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16	= IOMUX_PAD(0x04C4, 0x01B0, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT16__IPU2_DISP0_DAT_16	= IOMUX_PAD(0x04C4, 0x01B0, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT16__ECSPI2_MOSI	= IOMUX_PAD(0x04C4, 0x01B0, 2, 0x0818, 1, 0),
-	MX6Q_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC	= IOMUX_PAD(0x04C4, 0x01B0, 3, 0x07DC, 0, 0),
-	MX6Q_PAD_DISP0_DAT16__SDMA_EXT_EVENT_0	= IOMUX_PAD(0x04C4, 0x01B0, 4, 0x090C, 0, 0),
-	MX6Q_PAD_DISP0_DAT16__GPIO_5_10		= IOMUX_PAD(0x04C4, 0x01B0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT16__MMDC_DEBUG_21	= IOMUX_PAD(0x04C4, 0x01B0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT16__PL301_PER1_HADR26 = IOMUX_PAD(0x04C4, 0x01B0, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17	= IOMUX_PAD(0x04C8, 0x01B4, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT17__IPU2_DISP0_DAT_17	= IOMUX_PAD(0x04C8, 0x01B4, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT17__ECSPI2_MISO	= IOMUX_PAD(0x04C8, 0x01B4, 2, 0x0814, 1, 0),
-	MX6Q_PAD_DISP0_DAT17__AUDMUX_AUD5_TXD	= IOMUX_PAD(0x04C8, 0x01B4, 3, 0x07D0, 0, 0),
-	MX6Q_PAD_DISP0_DAT17__SDMA_EXT_EVENT_1	= IOMUX_PAD(0x04C8, 0x01B4, 4, 0x0910, 0, 0),
-	MX6Q_PAD_DISP0_DAT17__GPIO_5_11		= IOMUX_PAD(0x04C8, 0x01B4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT17__MMDC_DEBUG_22	= IOMUX_PAD(0x04C8, 0x01B4, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT17__PL301_PER1_HADR27	= IOMUX_PAD(0x04C8, 0x01B4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18	= IOMUX_PAD(0x04CC, 0x01B8, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT18__IPU2_DISP0_DAT_18	= IOMUX_PAD(0x04CC, 0x01B8, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT18__ECSPI2_SS0	= IOMUX_PAD(0x04CC, 0x01B8, 2, 0x081C, 1, 0),
-	MX6Q_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS	= IOMUX_PAD(0x04CC, 0x01B8, 3, 0x07E0, 0, 0),
-	MX6Q_PAD_DISP0_DAT18__AUDMUX_AUD4_RXFS	= IOMUX_PAD(0x04CC, 0x01B8, 4, 0x07C0, 0, 0),
-	MX6Q_PAD_DISP0_DAT18__GPIO_5_12		= IOMUX_PAD(0x04CC, 0x01B8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT18__MMDC_DEBUG_23	= IOMUX_PAD(0x04CC, 0x01B8, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT18__WEIM_WEIM_CS_2	= IOMUX_PAD(0x04CC, 0x01B8, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19	= IOMUX_PAD(0x04D0, 0x01BC, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT19__IPU2_DISP0_DAT_19	= IOMUX_PAD(0x04D0, 0x01BC, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT19__ECSPI2_SCLK	= IOMUX_PAD(0x04D0, 0x01BC, 2, 0x0810, 1, 0),
-	MX6Q_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD	= IOMUX_PAD(0x04D0, 0x01BC, 3, 0x07CC, 0, 0),
-	MX6Q_PAD_DISP0_DAT19__AUDMUX_AUD4_RXC	= IOMUX_PAD(0x04D0, 0x01BC, 4, 0x07BC, 0, 0),
-	MX6Q_PAD_DISP0_DAT19__GPIO_5_13		= IOMUX_PAD(0x04D0, 0x01BC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT19__MMDC_DEBUG_24	= IOMUX_PAD(0x04D0, 0x01BC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT19__WEIM_WEIM_CS_3	= IOMUX_PAD(0x04D0, 0x01BC, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20	= IOMUX_PAD(0x04D4, 0x01C0, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT20__IPU2_DISP0_DAT_20	= IOMUX_PAD(0x04D4, 0x01C0, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT20__ECSPI1_SCLK	= IOMUX_PAD(0x04D4, 0x01C0, 2, 0x07F4, 1, 0),
-	MX6Q_PAD_DISP0_DAT20__AUDMUX_AUD4_TXC	= IOMUX_PAD(0x04D4, 0x01C0, 3, 0x07C4, 0, 0),
-	MX6Q_PAD_DISP0_DAT20__SDMA_DBG_EVT_CHN7	= IOMUX_PAD(0x04D4, 0x01C0, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT20__GPIO_5_14		= IOMUX_PAD(0x04D4, 0x01C0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT20__MMDC_DEBUG_25	= IOMUX_PAD(0x04D4, 0x01C0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT20__PL301_PER1_HADR28 = IOMUX_PAD(0x04D4, 0x01C0, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21	= IOMUX_PAD(0x04D8, 0x01C4, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT21__IPU2_DISP0_DAT_21	= IOMUX_PAD(0x04D8, 0x01C4, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT21__ECSPI1_MOSI	= IOMUX_PAD(0x04D8, 0x01C4, 2, 0x07FC, 1, 0),
-	MX6Q_PAD_DISP0_DAT21__AUDMUX_AUD4_TXD	= IOMUX_PAD(0x04D8, 0x01C4, 3, 0x07B8, 1, 0),
-	MX6Q_PAD_DISP0_DAT21__SDMA_DBG_BUS_DEV0 = IOMUX_PAD(0x04D8, 0x01C4, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT21__GPIO_5_15		= IOMUX_PAD(0x04D8, 0x01C4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT21__MMDC_DEBUG_26	= IOMUX_PAD(0x04D8, 0x01C4, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT21__PL301_PER1_HADR29 = IOMUX_PAD(0x04D8, 0x01C4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22	= IOMUX_PAD(0x04DC, 0x01C8, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT22__IPU2_DISP0_DAT_22	= IOMUX_PAD(0x04DC, 0x01C8, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT22__ECSPI1_MISO	= IOMUX_PAD(0x04DC, 0x01C8, 2, 0x07F8, 1, 0),
-	MX6Q_PAD_DISP0_DAT22__AUDMUX_AUD4_TXFS	= IOMUX_PAD(0x04DC, 0x01C8, 3, 0x07C8, 1, 0),
-	MX6Q_PAD_DISP0_DAT22__SDMA_DBG_BUS_DEV1 = IOMUX_PAD(0x04DC, 0x01C8, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT22__GPIO_5_16		= IOMUX_PAD(0x04DC, 0x01C8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT22__MMDC_DEBUG_27	= IOMUX_PAD(0x04DC, 0x01C8, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT22__PL301_PER1_HADR30 = IOMUX_PAD(0x04DC, 0x01C8, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23	= IOMUX_PAD(0x04E0, 0x01CC, 0, 0x0000, 0, PAD_CTL_DSE_120ohm),
-	MX6Q_PAD_DISP0_DAT23__IPU2_DISP0_DAT_23	= IOMUX_PAD(0x04E0, 0x01CC, 1, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT23__ECSPI1_SS0	= IOMUX_PAD(0x04E0, 0x01CC, 2, 0x0800, 1, 0),
-	MX6Q_PAD_DISP0_DAT23__AUDMUX_AUD4_RXD	= IOMUX_PAD(0x04E0, 0x01CC, 3, 0x07B4, 1, 0),
-	MX6Q_PAD_DISP0_DAT23__SDMA_DBG_BUS_DEV2 = IOMUX_PAD(0x04E0, 0x01CC, 4, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT23__GPIO_5_17		= IOMUX_PAD(0x04E0, 0x01CC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT23__MMDC_DEBUG_28	= IOMUX_PAD(0x04E0, 0x01CC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_DISP0_DAT23__PL301_PER1_HADR31	= IOMUX_PAD(0x04E0, 0x01CC, 7, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_MDIO__RESERVED_RESERVED	= IOMUX_PAD(0x04E4, 0x01D0, 0, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_MDIO__ENET_MDIO		= IOMUX_PAD(0x04E4, 0x01D0, 1, 0x0840, 0, 0),
-	MX6Q_PAD_ENET_MDIO__ESAI1_SCKR		= IOMUX_PAD(0x04E4, 0x01D0, 2, 0x086C, 0, 0),
-	MX6Q_PAD_ENET_MDIO__SDMA_DEBUG_BUS_DEV3 = IOMUX_PAD(0x04E4, 0x01D0, 3, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_MDIO__ENET_1588_EVT1_OUT	= IOMUX_PAD(0x04E4, 0x01D0, 4, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_MDIO__GPIO_1_22		= IOMUX_PAD(0x04E4, 0x01D0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_MDIO__SPDIF_PLOCK		= IOMUX_PAD(0x04E4, 0x01D0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_REF_CLK__RESERVED_RSRVED	= IOMUX_PAD(0x04E8, 0x01D4, 0, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK	= IOMUX_PAD(0x04E8, 0x01D4, 1, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_REF_CLK__ESAI1_FSR	= IOMUX_PAD(0x04E8, 0x01D4, 2, 0x085C, 0, 0),
-	MX6Q_PAD_ENET_REF_CLK__SDMA_DBGBUS_DEV4 = IOMUX_PAD(0x04E8, 0x01D4, 3, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_REF_CLK__GPIO_1_23	= IOMUX_PAD(0x04E8, 0x01D4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_REF_CLK__SPDIF_SRCLK	= IOMUX_PAD(0x04E8, 0x01D4, 6, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_REF_CLK__USBPHY1_RX_SQH	= IOMUX_PAD(0x04E8, 0x01D4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_RX_ER__ENET_RX_ER		= IOMUX_PAD(0x04EC, 0x01D8, 1, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_RX_ER__ESAI1_HCKR		= IOMUX_PAD(0x04EC, 0x01D8, 2, 0x0864, 0, 0),
-	MX6Q_PAD_ENET_RX_ER__SPDIF_IN1		= IOMUX_PAD(0x04EC, 0x01D8, 3, 0x0914, 1, 0),
-	MX6Q_PAD_ENET_RX_ER__ENET_1588_EVT2_OUT = IOMUX_PAD(0x04EC, 0x01D8, 4, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_RX_ER__GPIO_1_24		= IOMUX_PAD(0x04EC, 0x01D8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_RX_ER__PHY_TDI		= IOMUX_PAD(0x04EC, 0x01D8, 6, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_RX_ER__USBPHY1_RX_HS_RXD	= IOMUX_PAD(0x04EC, 0x01D8, 7, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_CRS_DV__RESERVED_RSRVED	= IOMUX_PAD(0x04F0, 0x01DC, 0, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_CRS_DV__ENET_RX_EN	= IOMUX_PAD(0x04F0, 0x01DC, 1, 0x0858, 1, 0),
-	MX6Q_PAD_ENET_CRS_DV__ESAI1_SCKT	= IOMUX_PAD(0x04F0, 0x01DC, 2, 0x0870, 0, 0),
-	MX6Q_PAD_ENET_CRS_DV__SPDIF_EXTCLK	= IOMUX_PAD(0x04F0, 0x01DC, 3, 0x0918, 1, 0),
-	MX6Q_PAD_ENET_CRS_DV__GPIO_1_25		= IOMUX_PAD(0x04F0, 0x01DC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_CRS_DV__PHY_TDO		= IOMUX_PAD(0x04F0, 0x01DC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_CRS_DV__USBPHY1_RX_FS_RXD	= IOMUX_PAD(0x04F0, 0x01DC, 7, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_RXD1__MLB_MLBSIG		= IOMUX_PAD(0x04F4, 0x01E0, 0, 0x0908, 0, 0),
-	MX6Q_PAD_ENET_RXD1__ENET_RDATA_1	= IOMUX_PAD(0x04F4, 0x01E0, 1, 0x084C, 1, 0),
-	MX6Q_PAD_ENET_RXD1__ESAI1_FST		= IOMUX_PAD(0x04F4, 0x01E0, 2, 0x0860, 0, 0),
-	MX6Q_PAD_ENET_RXD1__ENET_1588_EVT3_OUT	= IOMUX_PAD(0x04F4, 0x01E0, 4, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_RXD1__GPIO_1_26		= IOMUX_PAD(0x04F4, 0x01E0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_RXD1__PHY_TCK		= IOMUX_PAD(0x04F4, 0x01E0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_RXD1__USBPHY1_RX_DISCON	= IOMUX_PAD(0x04F4, 0x01E0, 7, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_RXD0__OSC32K_32K_OUT	= IOMUX_PAD(0x04F8, 0x01E4, 0, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_RXD0__ENET_RDATA_0	= IOMUX_PAD(0x04F8, 0x01E4, 1, 0x0848, 1, 0),
-	MX6Q_PAD_ENET_RXD0__ESAI1_HCKT		= IOMUX_PAD(0x04F8, 0x01E4, 2, 0x0868, 0, 0),
-	MX6Q_PAD_ENET_RXD0__SPDIF_OUT1		= IOMUX_PAD(0x04F8, 0x01E4, 3, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_RXD0__GPIO_1_27		= IOMUX_PAD(0x04F8, 0x01E4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_RXD0__PHY_TMS		= IOMUX_PAD(0x04F8, 0x01E4, 6, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_RXD0__USBPHY1_PLL_CK20DIV	= IOMUX_PAD(0x04F8, 0x01E4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_TX_EN__RESERVED_RSRVED	= IOMUX_PAD(0x04FC, 0x01E8, 0, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_TX_EN__ENET_TX_EN		= IOMUX_PAD(0x04FC, 0x01E8, 1, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_TX_EN__ESAI1_TX3_RX2	= IOMUX_PAD(0x04FC, 0x01E8, 2, 0x0880, 0, 0),
-	MX6Q_PAD_ENET_TX_EN__GPIO_1_28		= IOMUX_PAD(0x04FC, 0x01E8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_TX_EN__SATA_PHY_TDI	= IOMUX_PAD(0x04FC, 0x01E8, 6, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_TX_EN__USBPHY2_RX_SQH	= IOMUX_PAD(0x04FC, 0x01E8, 7, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_TXD1__MLB_MLBCLK		= IOMUX_PAD(0x0500, 0x01EC, 0, 0x0900, 0, 0),
-	MX6Q_PAD_ENET_TXD1__ENET_TDATA_1	= IOMUX_PAD(0x0500, 0x01EC, 1, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_TXD1__ESAI1_TX2_RX3	= IOMUX_PAD(0x0500, 0x01EC, 2, 0x087C, 0, 0),
-	MX6Q_PAD_ENET_TXD1__ENET_1588_EVENT0_IN	= IOMUX_PAD(0x0500, 0x01EC, 4, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_TXD1__GPIO_1_29		= IOMUX_PAD(0x0500, 0x01EC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_TXD1__SATA_PHY_TDO	= IOMUX_PAD(0x0500, 0x01EC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_TXD1__USBPHY2_RX_HS_RXD	= IOMUX_PAD(0x0500, 0x01EC, 7, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_TXD0__RESERVED_RSRVED	= IOMUX_PAD(0x0504, 0x01F0, 0, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_TXD0__ENET_TDATA_0	= IOMUX_PAD(0x0504, 0x01F0, 1, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_TXD0__ESAI1_TX4_RX1	= IOMUX_PAD(0x0504, 0x01F0, 2, 0x0884, 0, 0),
-	MX6Q_PAD_ENET_TXD0__GPIO_1_30		= IOMUX_PAD(0x0504, 0x01F0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_TXD0__SATA_PHY_TCK	= IOMUX_PAD(0x0504, 0x01F0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_TXD0__USBPHY2_RX_FS_RXD   = IOMUX_PAD(0x0504, 0x01F0, 7, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_MDC__MLB_MLBDAT		= IOMUX_PAD(0x0508, 0x01F4, 0, 0x0904, 0, 0),
-	MX6Q_PAD_ENET_MDC__ENET_MDC		= IOMUX_PAD(0x0508, 0x01F4, 1, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_MDC__ESAI1_TX5_RX0	= IOMUX_PAD(0x0508, 0x01F4, 2, 0x0888, 0, 0),
-	MX6Q_PAD_ENET_MDC__ENET_1588_EVENT1_IN	= IOMUX_PAD(0x0508, 0x01F4, 4, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_MDC__GPIO_1_31		= IOMUX_PAD(0x0508, 0x01F4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_MDC__SATA_PHY_TMS		= IOMUX_PAD(0x0508, 0x01F4, 6, 0x0000, 0, 0),
-	MX6Q_PAD_ENET_MDC__USBPHY2_RX_DISCON	= IOMUX_PAD(0x0508, 0x01F4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D40__MMDC_DRAM_D_40	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D41__MMDC_DRAM_D_41	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D42__MMDC_DRAM_D_42	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D43__MMDC_DRAM_D_43	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D44__MMDC_DRAM_D_44	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D45__MMDC_DRAM_D_45	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D46__MMDC_DRAM_D_46	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D47__MMDC_DRAM_D_47	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDQS5__MMDC_DRAM_SDQS_5	= IOMUX_PAD(0x050C, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_DQM5__MMDC_DRAM_DQM_5	= IOMUX_PAD(0x0510, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D32__MMDC_DRAM_D_32	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D33__MMDC_DRAM_D_33	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D34__MMDC_DRAM_D_34	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D35__MMDC_DRAM_D_35	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D36__MMDC_DRAM_D_36	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D37__MMDC_DRAM_D_37	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D38__MMDC_DRAM_D_38	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D39__MMDC_DRAM_D_39	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_DQM4__MMDC_DRAM_DQM_4	= IOMUX_PAD(0x0514, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDQS4__MMDC_DRAM_SDQS_4	= IOMUX_PAD(0x0518, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D24__MMDC_DRAM_D_24	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D25__MMDC_DRAM_D_25	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D26__MMDC_DRAM_D_26	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D27__MMDC_DRAM_D_27	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D28__MMDC_DRAM_D_28	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D29__MMDC_DRAM_D_29	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDQS3__MMDC_DRAM_SDQS_3	= IOMUX_PAD(0x051C, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D30__MMDC_DRAM_D_30	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D31__MMDC_DRAM_D_31	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_DQM3__MMDC_DRAM_DQM_3	= IOMUX_PAD(0x0520, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D16__MMDC_DRAM_D_16	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D17__MMDC_DRAM_D_17	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D18__MMDC_DRAM_D_18	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D19__MMDC_DRAM_D_19	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D20__MMDC_DRAM_D_20	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D21__MMDC_DRAM_D_21	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D22__MMDC_DRAM_D_22	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDQS2__MMDC_DRAM_SDQS_2	= IOMUX_PAD(0x0524, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D23__MMDC_DRAM_D_23	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_DQM2__MMDC_DRAM_DQM_2	= IOMUX_PAD(0x0528, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_A0__MMDC_DRAM_A_0		= IOMUX_PAD(0x052C, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_A1__MMDC_DRAM_A_1		= IOMUX_PAD(0x0530, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_A2__MMDC_DRAM_A_2		= IOMUX_PAD(0x0534, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_A3__MMDC_DRAM_A_3		= IOMUX_PAD(0x0538, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_A4__MMDC_DRAM_A_4		= IOMUX_PAD(0x053C, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_A5__MMDC_DRAM_A_5		= IOMUX_PAD(0x0540, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_A6__MMDC_DRAM_A_6		= IOMUX_PAD(0x0544, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_A7__MMDC_DRAM_A_7		= IOMUX_PAD(0x0548, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_A8__MMDC_DRAM_A_8		= IOMUX_PAD(0x054C, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_A9__MMDC_DRAM_A_9		= IOMUX_PAD(0x0550, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_A10__MMDC_DRAM_A_10	= IOMUX_PAD(0x0554, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_A11__MMDC_DRAM_A_11	= IOMUX_PAD(0x0558, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_A12__MMDC_DRAM_A_12	= IOMUX_PAD(0x055C, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_A13__MMDC_DRAM_A_13	= IOMUX_PAD(0x0560, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_A14__MMDC_DRAM_A_14	= IOMUX_PAD(0x0564, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_A15__MMDC_DRAM_A_15	= IOMUX_PAD(0x0568, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_CAS__MMDC_DRAM_CAS	= IOMUX_PAD(0x056C, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_CS0__MMDC_DRAM_CS_0	= IOMUX_PAD(0x0570, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_CS1__MMDC_DRAM_CS_1	= IOMUX_PAD(0x0574, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_RAS__MMDC_DRAM_RAS	= IOMUX_PAD(0x0578, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_RESET__MMDC_DRAM_RESET	= IOMUX_PAD(0x057C, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDBA0__MMDC_DRAM_SDBA_0	= IOMUX_PAD(0x0580, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDBA1__MMDC_DRAM_SDBA_1	= IOMUX_PAD(0x0584, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDCLK_0__MMDC_DRAM_SDCLK0	= IOMUX_PAD(0x0588, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDBA2__MMDC_DRAM_SDBA_2	= IOMUX_PAD(0x058C, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDCKE0__MMDC_DRAM_SDCKE_0	= IOMUX_PAD(0x0590, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDCLK_1__MMDC_DRAM_SDCLK1	= IOMUX_PAD(0x0594, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDCKE1__MMDC_DRAM_SDCKE_1	= IOMUX_PAD(0x0598, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDODT0__MMDC_DRAM_ODT_0	= IOMUX_PAD(0x059C, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDODT1__MMDC_DRAM_ODT_1	= IOMUX_PAD(0x05A0, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDWE__MMDC_DRAM_SDWE	= IOMUX_PAD(0x05A4, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D0__MMDC_DRAM_D_0		= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D1__MMDC_DRAM_D_1		= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D2__MMDC_DRAM_D_2		= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D3__MMDC_DRAM_D_3		= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D4__MMDC_DRAM_D_4		= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D5__MMDC_DRAM_D_5		= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDQS0__MMDC_DRAM_SDQS_0	= IOMUX_PAD(0x05A8, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D6__MMDC_DRAM_D_6		= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D7__MMDC_DRAM_D_7		= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_DQM0__MMDC_DRAM_DQM_0	= IOMUX_PAD(0x05AC, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D8__MMDC_DRAM_D_8		= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D9__MMDC_DRAM_D_9		= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D10__MMDC_DRAM_D_10	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D11__MMDC_DRAM_D_11	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D12__MMDC_DRAM_D_12	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D13__MMDC_DRAM_D_13	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D14__MMDC_DRAM_D_14	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDQS1__MMDC_DRAM_SDQS_1	= IOMUX_PAD(0x05B0, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D15__MMDC_DRAM_D_15	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_DQM1__MMDC_DRAM_DQM_1	= IOMUX_PAD(0x05B4, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D48__MMDC_DRAM_D_48	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D49__MMDC_DRAM_D_49	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D50__MMDC_DRAM_D_50	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D51__MMDC_DRAM_D_51	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D52__MMDC_DRAM_D_52	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D53__MMDC_DRAM_D_53	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D54__MMDC_DRAM_D_54	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D55__MMDC_DRAM_D_55	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDQS6__MMDC_DRAM_SDQS_6	= IOMUX_PAD(0x05B8, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_DQM6__MMDC_DRAM_DQM_6	= IOMUX_PAD(0x05BC, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D56__MMDC_DRAM_D_56	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_SDQS7__MMDC_DRAM_SDQS_7	= IOMUX_PAD(0x05C0, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D57__MMDC_DRAM_D_57	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D58__MMDC_DRAM_D_58	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D59__MMDC_DRAM_D_59	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D60__MMDC_DRAM_D_60	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_DQM7__MMDC_DRAM_DQM_7	= IOMUX_PAD(0x05C4, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D61__MMDC_DRAM_D_61	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D62__MMDC_DRAM_D_62	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_DRAM_D63__MMDC_DRAM_D_63	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL0__ECSPI1_SCLK		= IOMUX_PAD(0x05C8, 0x01F8, 0, 0x07F4, 2, 0),
-	MX6Q_PAD_KEY_COL0__ENET_RDATA_3		= IOMUX_PAD(0x05C8, 0x01F8, 1, 0x0854, 1, 0),
-	MX6Q_PAD_KEY_COL0__AUDMUX_AUD5_TXC	= IOMUX_PAD(0x05C8, 0x01F8, 2, 0x07DC, 1, 0),
-	MX6Q_PAD_KEY_COL0__KPP_COL_0		= IOMUX_PAD(0x05C8, 0x01F8, 3, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL0__UART4_TXD		= IOMUX_PAD(0x05C8, 0x01F8, 4, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL0__UART4_TXD_RXD	= IOMUX_PAD(0x05C8, 0x01F8, 4, 0x0938, 0, 0),
-	MX6Q_PAD_KEY_COL0__GPIO_4_6		= IOMUX_PAD(0x05C8, 0x01F8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL0__DCIC1_DCIC_OUT	= IOMUX_PAD(0x05C8, 0x01F8, 6, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL0__SRC_ANY_PU_RST	= IOMUX_PAD(0x05C8, 0x01F8, 7, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW0__ECSPI1_MOSI		= IOMUX_PAD(0x05CC, 0x01FC, 0, 0x07FC, 2, 0),
-	MX6Q_PAD_KEY_ROW0__ENET_TDATA_3		= IOMUX_PAD(0x05CC, 0x01FC, 1, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW0__AUDMUX_AUD5_TXD	= IOMUX_PAD(0x05CC, 0x01FC, 2, 0x07D0, 1, 0),
-	MX6Q_PAD_KEY_ROW0__KPP_ROW_0		= IOMUX_PAD(0x05CC, 0x01FC, 3, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW0__UART4_RXD		= IOMUX_PAD(0x05CC, 0x01FC, 4, 0x0938, 1, 0),
-	MX6Q_PAD_KEY_ROW0__GPIO_4_7		= IOMUX_PAD(0x05CC, 0x01FC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW0__DCIC2_DCIC_OUT	= IOMUX_PAD(0x05CC, 0x01FC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW0__PL301_PER1_HADR_0	= IOMUX_PAD(0x05CC, 0x01FC, 7, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL1__ECSPI1_MISO		= IOMUX_PAD(0x05D0, 0x0200, 0, 0x07F8, 2, 0),
-	MX6Q_PAD_KEY_COL1__ENET_MDIO		= IOMUX_PAD(0x05D0, 0x0200, 1, 0x0840, 1, 0),
-	MX6Q_PAD_KEY_COL1__AUDMUX_AUD5_TXFS	= IOMUX_PAD(0x05D0, 0x0200, 2, 0x07E0, 1, 0),
-	MX6Q_PAD_KEY_COL1__KPP_COL_1		= IOMUX_PAD(0x05D0, 0x0200, 3, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL1__UART5_TXD		= IOMUX_PAD(0x05D0, 0x0200, 4, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL1__UART5_TXD_RXD	= IOMUX_PAD(0x05D0, 0x0200, 4, 0x0940, 0, 0),
-	MX6Q_PAD_KEY_COL1__GPIO_4_8		= IOMUX_PAD(0x05D0, 0x0200, 5, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL1__USDHC1_VSELECT	= IOMUX_PAD(0x05D0, 0x0200, 6, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL1__PL301MX_PER1_HADR_1	= IOMUX_PAD(0x05D0, 0x0200, 7, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW1__ECSPI1_SS0		= IOMUX_PAD(0x05D4, 0x0204, 0, 0x0800, 2, 0),
-	MX6Q_PAD_KEY_ROW1__ENET_COL		= IOMUX_PAD(0x05D4, 0x0204, 1, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW1__AUDMUX_AUD5_RXD	= IOMUX_PAD(0x05D4, 0x0204, 2, 0x07CC, 1, 0),
-	MX6Q_PAD_KEY_ROW1__KPP_ROW_1		= IOMUX_PAD(0x05D4, 0x0204, 3, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW1__UART5_RXD		= IOMUX_PAD(0x05D4, 0x0204, 4, 0x0940, 1, 0),
-	MX6Q_PAD_KEY_ROW1__GPIO_4_9		= IOMUX_PAD(0x05D4, 0x0204, 5, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW1__USDHC2_VSELECT	= IOMUX_PAD(0x05D4, 0x0204, 6, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW1__PL301_PER1_HADDR_2	= IOMUX_PAD(0x05D4, 0x0204, 7, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL2__ECSPI1_SS1		= IOMUX_PAD(0x05D8, 0x0208, 0, 0x0804, 2, 0),
-	MX6Q_PAD_KEY_COL2__ENET_RDATA_2		= IOMUX_PAD(0x05D8, 0x0208, 1, 0x0850, 1, 0),
-	MX6Q_PAD_KEY_COL2__CAN1_TXCAN		= IOMUX_PAD(0x05D8, 0x0208, 2, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL2__KPP_COL_2		= IOMUX_PAD(0x05D8, 0x0208, 3, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL2__ENET_MDC		= IOMUX_PAD(0x05D8, 0x0208, 4, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL2__GPIO_4_10		= IOMUX_PAD(0x05D8, 0x0208, 5, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL2__USBOH3_H1_PWRCTL_WKP = IOMUX_PAD(0x05D8, 0x0208, 6, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL2__PL301_PER1_HADDR_3   = IOMUX_PAD(0x05D8, 0x0208, 7, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW2__ECSPI1_SS2		= IOMUX_PAD(0x05DC, 0x020C, 0, 0x0808, 1, 0),
-	MX6Q_PAD_KEY_ROW2__ENET_TDATA_2		= IOMUX_PAD(0x05DC, 0x020C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW2__CAN1_RXCAN		= IOMUX_PAD(0x05DC, 0x020C, 2, 0x07E4, 0, 0),
-	MX6Q_PAD_KEY_ROW2__KPP_ROW_2		= IOMUX_PAD(0x05DC, 0x020C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW2__USDHC2_VSELECT	= IOMUX_PAD(0x05DC, 0x020C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW2__GPIO_4_11		= IOMUX_PAD(0x05DC, 0x020C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW2__HDMI_TX_CEC_LINE	= IOMUX_PAD(0x05DC, 0x020C, 6, 0x088C, 1, 0),
-	MX6Q_PAD_KEY_ROW2__PL301_PER1_HADR_4    = IOMUX_PAD(0x05DC, 0x020C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL3__ECSPI1_SS3		= IOMUX_PAD(0x05E0, 0x0210, 0, 0x080C, 1, 0),
-	MX6Q_PAD_KEY_COL3__ENET_CRS		= IOMUX_PAD(0x05E0, 0x0210, 1, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL3__HDMI_TX_DDC_SCL	= IOMUX_PAD(0x05E0, 0x0210, 2, 0x0890, 1, 0),
-	MX6Q_PAD_KEY_COL3__KPP_COL_3		= IOMUX_PAD(0x05E0, 0x0210, 3, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL3__I2C2_SCL		= IOMUX_PAD(0x05E0, 0x0210, 20, 0x08A0, 1, 0),
-	MX6Q_PAD_KEY_COL3__GPIO_4_12		= IOMUX_PAD(0x05E0, 0x0210, 5, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL3__SPDIF_IN1		= IOMUX_PAD(0x05E0, 0x0210, 6, 0x0914, 2, 0),
-	MX6Q_PAD_KEY_COL3__PL301_PER1_HADR_5	= IOMUX_PAD(0x05E0, 0x0210, 7, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW3__OSC32K_32K_OUT	= IOMUX_PAD(0x05E4, 0x0214, 0, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW3__ASRC_ASRC_EXT_CLK	= IOMUX_PAD(0x05E4, 0x0214, 1, 0x07B0, 0, 0),
-	MX6Q_PAD_KEY_ROW3__HDMI_TX_DDC_SDA	= IOMUX_PAD(0x05E4, 0x0214, 2, 0x0894, 1, 0),
-	MX6Q_PAD_KEY_ROW3__KPP_ROW_3		= IOMUX_PAD(0x05E4, 0x0214, 3, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW3__I2C2_SDA		= IOMUX_PAD(0x05E4, 0x0214, 20, 0x08A4, 1, 0),
-	MX6Q_PAD_KEY_ROW3__GPIO_4_13		= IOMUX_PAD(0x05E4, 0x0214, 5, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW3__USDHC1_VSELECT	= IOMUX_PAD(0x05E4, 0x0214, 6, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW3__PL301_PER1_HADR_6	= IOMUX_PAD(0x05E4, 0x0214, 7, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL4__CAN2_TXCAN		= IOMUX_PAD(0x05E8, 0x0218, 0, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL4__IPU1_SISG_4		= IOMUX_PAD(0x05E8, 0x0218, 1, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL4__USBOH3_USBOTG_OC	= IOMUX_PAD(0x05E8, 0x0218, 2, 0x0944, 1, 0),
-	MX6Q_PAD_KEY_COL4__KPP_COL_4		= IOMUX_PAD(0x05E8, 0x0218, 3, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL4__UART5_CTS		= IOMUX_PAD(0x05E8, 0x0218, 4, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL4__UART5_RTS		= IOMUX_PAD(0x05E8, 0x0218, 4, 0x093C, 0, 0),
-	MX6Q_PAD_KEY_COL4__GPIO_4_14		= IOMUX_PAD(0x05E8, 0x0218, 5, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL4__MMDC_DEBUG_49	= IOMUX_PAD(0x05E8, 0x0218, 6, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_COL4__PL301_PER1_HADDR_7	= IOMUX_PAD(0x05E8, 0x0218, 7, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW4__CAN2_RXCAN		= IOMUX_PAD(0x05EC, 0x021C, 0, 0x07E8, 0, 0),
-	MX6Q_PAD_KEY_ROW4__IPU1_SISG_5		= IOMUX_PAD(0x05EC, 0x021C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW4__USBOH3_USBOTG_PWR	= IOMUX_PAD(0x05EC, 0x021C, 2, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW4__KPP_ROW_4		= IOMUX_PAD(0x05EC, 0x021C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW4__UART5_CTS		= IOMUX_PAD(0x05EC, 0x021C, 4, 0x093C, 1, 0),
-	MX6Q_PAD_KEY_ROW4__GPIO_4_15		= IOMUX_PAD(0x05EC, 0x021C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW4__MMDC_DEBUG_50	= IOMUX_PAD(0x05EC, 0x021C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_KEY_ROW4__PL301_PER1_HADR_8    = IOMUX_PAD(0x05EC, 0x021C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_0__CCM_CLKO		= IOMUX_PAD(0x05F0, 0x0220, 0, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_0__KPP_COL_5		= IOMUX_PAD(0x05F0, 0x0220, 2, 0x08E8, 0, 0),
-	MX6Q_PAD_GPIO_0__ASRC_ASRC_EXT_CLK	= IOMUX_PAD(0x05F0, 0x0220, 3, 0x07B0, 1, 0),
-	MX6Q_PAD_GPIO_0__EPIT1_EPITO		= IOMUX_PAD(0x05F0, 0x0220, 4, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_0__GPIO_1_0		= IOMUX_PAD(0x05F0, 0x0220, 5, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_0__USBOH3_USBH1_PWR	= IOMUX_PAD(0x05F0, 0x0220, 6, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_0__SNVS_HP_WRAP_SNVS_VIO5 = IOMUX_PAD(0x05F0, 0x0220, 7, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_1__ESAI1_SCKR		= IOMUX_PAD(0x05F4, 0x0224, 0, 0x086C, 1, 0),
-	MX6Q_PAD_GPIO_1__WDOG2_WDOG_B		= IOMUX_PAD(0x05F4, 0x0224, 1, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_1__KPP_ROW_5		= IOMUX_PAD(0x05F4, 0x0224, 2, 0x08F4, 0, 0),
-	MX6Q_PAD_GPIO_1__PWM2_PWMO		= IOMUX_PAD(0x05F4, 0x0224, 4, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_1__GPIO_1_1		= IOMUX_PAD(0x05F4, 0x0224, 5, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_1__USDHC1_CD		= IOMUX_PAD(0x05F4, 0x0224, 6, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_1__SRC_TESTER_ACK		= IOMUX_PAD(0x05F4, 0x0224, 7, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_9__ESAI1_FSR		= IOMUX_PAD(0x05F8, 0x0228, 0, 0x085C, 1, 0),
-	MX6Q_PAD_GPIO_9__WDOG1_WDOG_B		= IOMUX_PAD(0x05F8, 0x0228, 1, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_9__KPP_COL_6		= IOMUX_PAD(0x05F8, 0x0228, 2, 0x08EC, 0, 0),
-	MX6Q_PAD_GPIO_9__CCM_REF_EN_B		= IOMUX_PAD(0x05F8, 0x0228, 3, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_9__PWM1_PWMO		= IOMUX_PAD(0x05F8, 0x0228, 4, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_9__GPIO_1_9		= IOMUX_PAD(0x05F8, 0x0228, 5, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_9__USDHC1_WP		= IOMUX_PAD(0x05F8, 0x0228, 6, 0x094C, 1, 0),
-	MX6Q_PAD_GPIO_9__SRC_EARLY_RST		= IOMUX_PAD(0x05F8, 0x0228, 7, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_3__ESAI1_HCKR		= IOMUX_PAD(0x05FC, 0x022C, 0, 0x0864, 1, 0),
-	MX6Q_PAD_GPIO_3__OBSERVE_MUX_INT_OUT0	= IOMUX_PAD(0x05FC, 0x022C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_3__I2C3_SCL		= IOMUX_PAD(0x05FC, 0x022C, 18, 0x08A8, 1, 0),
-	MX6Q_PAD_GPIO_3__ANATOP_24M_OUT		= IOMUX_PAD(0x05FC, 0x022C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_3__CCM_CLKO2		= IOMUX_PAD(0x05FC, 0x022C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_3__GPIO_1_3		= IOMUX_PAD(0x05FC, 0x022C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_3__USBOH3_USBH1_OC	= IOMUX_PAD(0x05FC, 0x022C, 6, 0x0948, 1, 0),
-	MX6Q_PAD_GPIO_3__MLB_MLBCLK		= IOMUX_PAD(0x05FC, 0x022C, 7, 0x0900, 1, 0),
-	MX6Q_PAD_GPIO_6__ESAI1_SCKT		= IOMUX_PAD(0x0600, 0x0230, 0, 0x0870, 1, 0),
-	MX6Q_PAD_GPIO_6__OBSERVE_MUX_INT_OUT1	= IOMUX_PAD(0x0600, 0x0230, 1, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_6__I2C3_SDA		= IOMUX_PAD(0x0600, 0x0230, 18, 0x08AC, 1, 0),
-	MX6Q_PAD_GPIO_6__CCM_CCM_OUT_0		= IOMUX_PAD(0x0600, 0x0230, 3, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_6__CSU_CSU_INT_DEB	= IOMUX_PAD(0x0600, 0x0230, 4, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_6__GPIO_1_6		= IOMUX_PAD(0x0600, 0x0230, 5, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_6__USDHC2_LCTL		= IOMUX_PAD(0x0600, 0x0230, 6, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_6__MLB_MLBSIG		= IOMUX_PAD(0x0600, 0x0230, 7, 0x0908, 1, 0),
-	MX6Q_PAD_GPIO_2__ESAI1_FST		= IOMUX_PAD(0x0604, 0x0234, 0, 0x0860, 1, 0),
-	MX6Q_PAD_GPIO_2__OBSERVE_MUX_INT_OUT2	= IOMUX_PAD(0x0604, 0x0234, 1, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_2__KPP_ROW_6		= IOMUX_PAD(0x0604, 0x0234, 2, 0x08F8, 1, 0),
-	MX6Q_PAD_GPIO_2__CCM_CCM_OUT_1		= IOMUX_PAD(0x0604, 0x0234, 3, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_2__CSU_CSU_ALARM_AUT_0	= IOMUX_PAD(0x0604, 0x0234, 4, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_2__GPIO_1_2		= IOMUX_PAD(0x0604, 0x0234, 5, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_2__USDHC2_WP		= IOMUX_PAD(0x0604, 0x0234, 6, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_2__MLB_MLBDAT		= IOMUX_PAD(0x0604, 0x0234, 7, 0x0904, 1, 0),
-	MX6Q_PAD_GPIO_4__ESAI1_HCKT		= IOMUX_PAD(0x0608, 0x0238, 0, 0x0868, 1, 0),
-	MX6Q_PAD_GPIO_4__OBSERVE_MUX_INT_OUT3	= IOMUX_PAD(0x0608, 0x0238, 1, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_4__KPP_COL_7		= IOMUX_PAD(0x0608, 0x0238, 2, 0x08F0, 1, 0),
-	MX6Q_PAD_GPIO_4__CCM_CCM_OUT_2		= IOMUX_PAD(0x0608, 0x0238, 3, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_4__CSU_CSU_ALARM_AUT_1	= IOMUX_PAD(0x0608, 0x0238, 4, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_4__GPIO_1_4		= IOMUX_PAD(0x0608, 0x0238, 5, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_4__USDHC2_CD		= IOMUX_PAD(0x0608, 0x0238, 6, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_4__OCOTP_CRL_WRAR_FUSE_LA = IOMUX_PAD(0x0608, 0x0238, 7, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_5__ESAI1_TX2_RX3		= IOMUX_PAD(0x060C, 0x023C, 0, 0x087C, 1, 0),
-	MX6Q_PAD_GPIO_5__OBSERVE_MUX_INT_OUT4	= IOMUX_PAD(0x060C, 0x023C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_5__KPP_ROW_7		= IOMUX_PAD(0x060C, 0x023C, 2, 0x08FC, 1, 0),
-	MX6Q_PAD_GPIO_5__CCM_CLKO		= IOMUX_PAD(0x060C, 0x023C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2	= IOMUX_PAD(0x060C, 0x023C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_5__GPIO_1_5		= IOMUX_PAD(0x060C, 0x023C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_5__I2C3_SCL		= IOMUX_PAD(0x060C, 0x023C, 22, 0x08A8, 2, 0),
-	MX6Q_PAD_GPIO_5__CHEETAH_EVENTI		= IOMUX_PAD(0x060C, 0x023C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_7__ESAI1_TX4_RX1		= IOMUX_PAD(0x0610, 0x0240, 0, 0x0884, 1, 0),
-	MX6Q_PAD_GPIO_7__ECSPI5_RDY		= IOMUX_PAD(0x0610, 0x0240, 1, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_7__EPIT1_EPITO		= IOMUX_PAD(0x0610, 0x0240, 2, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_7__CAN1_TXCAN		= IOMUX_PAD(0x0610, 0x0240, 3, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_7__UART2_TXD		= IOMUX_PAD(0x0610, 0x0240, 4, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_7__UART2_TXD_RXD		= IOMUX_PAD(0x0610, 0x0240, 4, 0x0928, 2, 0),
-	MX6Q_PAD_GPIO_7__GPIO_1_7		= IOMUX_PAD(0x0610, 0x0240, 5, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_7__SPDIF_PLOCK		= IOMUX_PAD(0x0610, 0x0240, 6, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_7__USBOH3_OTGUSB_HST_MODE	= IOMUX_PAD(0x0610, 0x0240, 7, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_8__ESAI1_TX5_RX0		= IOMUX_PAD(0x0614, 0x0244, 0, 0x0888, 1, 0),
-	MX6Q_PAD_GPIO_8__ANATOP_ANATOP_32K_OUT	= IOMUX_PAD(0x0614, 0x0244, 1, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_8__EPIT2_EPITO		= IOMUX_PAD(0x0614, 0x0244, 2, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_8__CAN1_RXCAN		= IOMUX_PAD(0x0614, 0x0244, 3, 0x07E4, 1, 0),
-	MX6Q_PAD_GPIO_8__UART2_RXD		= IOMUX_PAD(0x0614, 0x0244, 4, 0x0928, 3, 0),
-	MX6Q_PAD_GPIO_8__GPIO_1_8		= IOMUX_PAD(0x0614, 0x0244, 5, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_8__SPDIF_SRCLK		= IOMUX_PAD(0x0614, 0x0244, 6, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_8__USBOH3_OTG_PWRCTL_WAK	= IOMUX_PAD(0x0614, 0x0244, 7, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_16__ESAI1_TX3_RX2		= IOMUX_PAD(0x0618, 0x0248, 0, 0x0880, 1, 0),
-	MX6Q_PAD_GPIO_16__ENET_1588_EVENT2_IN	= IOMUX_PAD(0x0618, 0x0248, 1, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_16__ENET_ETHERNET_REF_OUT = IOMUX_PAD(0x0618, 0x0248, 2, 0x083C, 1, 0),
-	MX6Q_PAD_GPIO_16__USDHC1_LCTL		= IOMUX_PAD(0x0618, 0x0248, 3, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_16__SPDIF_IN1		= IOMUX_PAD(0x0618, 0x0248, 4, 0x0914, 3, 0),
-	MX6Q_PAD_GPIO_16__GPIO_7_11		= IOMUX_PAD(0x0618, 0x0248, 5, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_16__I2C3_SDA		= IOMUX_PAD(0x0618, 0x0248, 22, 0x08AC, 2, 0),
-	MX6Q_PAD_GPIO_16__SJC_DE_B		= IOMUX_PAD(0x0618, 0x0248, 7, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_17__ESAI1_TX0		= IOMUX_PAD(0x061C, 0x024C, 0, 0x0874, 0, 0),
-	MX6Q_PAD_GPIO_17__ENET_1588_EVENT3_IN	= IOMUX_PAD(0x061C, 0x024C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_17__CCM_PMIC_RDY		= IOMUX_PAD(0x061C, 0x024C, 2, 0x07F0, 1, 0),
-	MX6Q_PAD_GPIO_17__SDMA_SDMA_EXT_EVENT_0	= IOMUX_PAD(0x061C, 0x024C, 3, 0x090C, 1, 0),
-	MX6Q_PAD_GPIO_17__SPDIF_OUT1		= IOMUX_PAD(0x061C, 0x024C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_17__GPIO_7_12		= IOMUX_PAD(0x061C, 0x024C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_17__SJC_JTAG_ACT		= IOMUX_PAD(0x061C, 0x024C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_18__ESAI1_TX1		= IOMUX_PAD(0x0620, 0x0250, 0, 0x0878, 0, 0),
-	MX6Q_PAD_GPIO_18__ENET_RX_CLK		= IOMUX_PAD(0x0620, 0x0250, 1, 0x0844, 1, 0),
-	MX6Q_PAD_GPIO_18__USDHC3_VSELECT	= IOMUX_PAD(0x0620, 0x0250, 2, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_18__SDMA_SDMA_EXT_EVENT_1 = IOMUX_PAD(0x0620, 0x0250, 3, 0x0910, 1, 0),
-	MX6Q_PAD_GPIO_18__ASRC_ASRC_EXT_CLK	= IOMUX_PAD(0x0620, 0x0250, 4, 0x07B0, 2, 0),
-	MX6Q_PAD_GPIO_18__GPIO_7_13		= IOMUX_PAD(0x0620, 0x0250, 5, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_18__SNVS_HP_WRA_SNVS_VIO5 = IOMUX_PAD(0x0620, 0x0250, 6, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_18__SRC_SYSTEM_RST	= IOMUX_PAD(0x0620, 0x0250, 7, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_19__KPP_COL_5		= IOMUX_PAD(0x0624, 0x0254, 0, 0x08E8, 1, 0),
-	MX6Q_PAD_GPIO_19__ENET_1588_EVENT0_OUT	= IOMUX_PAD(0x0624, 0x0254, 1, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_19__SPDIF_OUT1		= IOMUX_PAD(0x0624, 0x0254, 2, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_19__CCM_CLKO		= IOMUX_PAD(0x0624, 0x0254, 3, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_19__ECSPI1_RDY		= IOMUX_PAD(0x0624, 0x0254, 4, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_19__GPIO_4_5		= IOMUX_PAD(0x0624, 0x0254, 5, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_19__ENET_TX_ER		= IOMUX_PAD(0x0624, 0x0254, 6, 0x0000, 0, 0),
-	MX6Q_PAD_GPIO_19__SRC_INT_BOOT		= IOMUX_PAD(0x0624, 0x0254, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK	= IOMUX_PAD(0x0628, 0x0258, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_PIXCLK__PCIE_CTRL_MUX_12	= IOMUX_PAD(0x0628, 0x0258, 2, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_PIXCLK__SDMA_DEBUG_PC_0	= IOMUX_PAD(0x0628, 0x0258, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_PIXCLK__GPIO_5_18		= IOMUX_PAD(0x0628, 0x0258, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_PIXCLK___MMDC_DEBUG_29	= IOMUX_PAD(0x0628, 0x0258, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_PIXCLK__CHEETAH_EVENTO	= IOMUX_PAD(0x0628, 0x0258, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC	= IOMUX_PAD(0x062C, 0x025C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_MCLK__PCIE_CTRL_MUX_13	= IOMUX_PAD(0x062C, 0x025C, 2, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_MCLK__CCM_CLKO		= IOMUX_PAD(0x062C, 0x025C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_MCLK__SDMA_DEBUG_PC_1	= IOMUX_PAD(0x062C, 0x025C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_MCLK__GPIO_5_19		= IOMUX_PAD(0x062C, 0x025C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_MCLK__MMDC_MMDC_DEBUG_30	= IOMUX_PAD(0x062C, 0x025C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_MCLK__CHEETAH_TRCTL	= IOMUX_PAD(0x062C, 0x025C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DATA_EN__IPU1_CSI0_DA_EN	= IOMUX_PAD(0x0630, 0x0260, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DATA_EN__WEIM_WEIM_D_0	= IOMUX_PAD(0x0630, 0x0260, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DATA_EN__PCIE_CTRL_MUX_14	= IOMUX_PAD(0x0630, 0x0260, 2, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DATA_EN__SDMA_DEBUG_PC_2	= IOMUX_PAD(0x0630, 0x0260, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DATA_EN__GPIO_5_20	= IOMUX_PAD(0x0630, 0x0260, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DATA_EN__MMDC_DEBUG_31	= IOMUX_PAD(0x0630, 0x0260, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DATA_EN__CHEETAH_TRCLK	= IOMUX_PAD(0x0630, 0x0260, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC	= IOMUX_PAD(0x0634, 0x0264, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_VSYNC__WEIM_WEIM_D_1	= IOMUX_PAD(0x0634, 0x0264, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_VSYNC__PCIE_CTRL_MUX_15	= IOMUX_PAD(0x0634, 0x0264, 2, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_VSYNC__SDMA_DEBUG_PC_3	= IOMUX_PAD(0x0634, 0x0264, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_VSYNC__GPIO_5_21		= IOMUX_PAD(0x0634, 0x0264, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_VSYNC__MMDC_DEBUG_32	= IOMUX_PAD(0x0634, 0x0264, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_VSYNC__CHEETAH_TRACE_0	= IOMUX_PAD(0x0634, 0x0264, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT4__IPU1_CSI0_D_4	= IOMUX_PAD(0x0638, 0x0268, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT4__WEIM_WEIM_D_2	= IOMUX_PAD(0x0638, 0x0268, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT4__ECSPI1_SCLK		= IOMUX_PAD(0x0638, 0x0268, 2, 0x07F4, 3, 0),
-	MX6Q_PAD_CSI0_DAT4__KPP_COL_5		= IOMUX_PAD(0x0638, 0x0268, 3, 0x08E8, 2, 0),
-	MX6Q_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC	= IOMUX_PAD(0x0638, 0x0268, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT4__GPIO_5_22		= IOMUX_PAD(0x0638, 0x0268, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT4__MMDC_DEBUG_43	= IOMUX_PAD(0x0638, 0x0268, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT4__CHEETAH_TRACE_1	= IOMUX_PAD(0x0638, 0x0268, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT5__IPU1_CSI0_D_5	= IOMUX_PAD(0x063C, 0x026C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT5__WEIM_WEIM_D_3	= IOMUX_PAD(0x063C, 0x026C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT5__ECSPI1_MOSI		= IOMUX_PAD(0x063C, 0x026C, 2, 0x07FC, 3, 0),
-	MX6Q_PAD_CSI0_DAT5__KPP_ROW_5		= IOMUX_PAD(0x063C, 0x026C, 3, 0x08F4, 1, 0),
-	MX6Q_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD	= IOMUX_PAD(0x063C, 0x026C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT5__GPIO_5_23		= IOMUX_PAD(0x063C, 0x026C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT5__MMDC_MMDC_DEBUG_44	= IOMUX_PAD(0x063C, 0x026C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT5__CHEETAH_TRACE_2	= IOMUX_PAD(0x063C, 0x026C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT6__IPU1_CSI0_D_6	= IOMUX_PAD(0x0640, 0x0270, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT6__WEIM_WEIM_D_4	= IOMUX_PAD(0x0640, 0x0270, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT6__ECSPI1_MISO		= IOMUX_PAD(0x0640, 0x0270, 2, 0x07F8, 3, 0),
-	MX6Q_PAD_CSI0_DAT6__KPP_COL_6		= IOMUX_PAD(0x0640, 0x0270, 3, 0x08EC, 1, 0),
-	MX6Q_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS	= IOMUX_PAD(0x0640, 0x0270, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT6__GPIO_5_24		= IOMUX_PAD(0x0640, 0x0270, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT6__MMDC_MMDC_DEBUG_45	= IOMUX_PAD(0x0640, 0x0270, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT6__CHEETAH_TRACE_3	= IOMUX_PAD(0x0640, 0x0270, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT7__IPU1_CSI0_D_7	= IOMUX_PAD(0x0644, 0x0274, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT7__WEIM_WEIM_D_5	= IOMUX_PAD(0x0644, 0x0274, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT7__ECSPI1_SS0		= IOMUX_PAD(0x0644, 0x0274, 2, 0x0800, 3, 0),
-	MX6Q_PAD_CSI0_DAT7__KPP_ROW_6		= IOMUX_PAD(0x0644, 0x0274, 3, 0x08F8, 2, 0),
-	MX6Q_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD	= IOMUX_PAD(0x0644, 0x0274, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT7__GPIO_5_25		= IOMUX_PAD(0x0644, 0x0274, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT7__MMDC_MMDC_DEBUG_46	= IOMUX_PAD(0x0644, 0x0274, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT7__CHEETAH_TRACE_4	= IOMUX_PAD(0x0644, 0x0274, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT8__IPU1_CSI0_D_8	= IOMUX_PAD(0x0648, 0x0278, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT8__WEIM_WEIM_D_6	= IOMUX_PAD(0x0648, 0x0278, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT8__ECSPI2_SCLK		= IOMUX_PAD(0x0648, 0x0278, 2, 0x0810, 2, 0),
-	MX6Q_PAD_CSI0_DAT8__KPP_COL_7		= IOMUX_PAD(0x0648, 0x0278, 3, 0x08F0, 2, 0),
-	MX6Q_PAD_CSI0_DAT8__I2C1_SDA		= IOMUX_PAD(0x0648, 0x0278, 20, 0x089C, 1, 0),
-	MX6Q_PAD_CSI0_DAT8__GPIO_5_26		= IOMUX_PAD(0x0648, 0x0278, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT8__MMDC_MMDC_DEBUG_47	= IOMUX_PAD(0x0648, 0x0278, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT8__CHEETAH_TRACE_5	= IOMUX_PAD(0x0648, 0x0278, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT9__IPU1_CSI0_D_9	= IOMUX_PAD(0x064C, 0x027C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT9__WEIM_WEIM_D_7	= IOMUX_PAD(0x064C, 0x027C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT9__ECSPI2_MOSI		= IOMUX_PAD(0x064C, 0x027C, 2, 0x0818, 2, 0),
-	MX6Q_PAD_CSI0_DAT9__KPP_ROW_7		= IOMUX_PAD(0x064C, 0x027C, 3, 0x08FC, 2, 0),
-	MX6Q_PAD_CSI0_DAT9__I2C1_SCL		= IOMUX_PAD(0x064C, 0x027C, 20, 0x0898, 1, 0),
-	MX6Q_PAD_CSI0_DAT9__GPIO_5_27		= IOMUX_PAD(0x064C, 0x027C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT9__MMDC_MMDC_DEBUG_48	= IOMUX_PAD(0x064C, 0x027C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT9__CHEETAH_TRACE_6	= IOMUX_PAD(0x064C, 0x027C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT10__IPU1_CSI0_D_10	= IOMUX_PAD(0x0650, 0x0280, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT10__AUDMUX_AUD3_RXC	= IOMUX_PAD(0x0650, 0x0280, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT10__ECSPI2_MISO	= IOMUX_PAD(0x0650, 0x0280, 2, 0x0814, 2, 0),
-	MX6Q_PAD_CSI0_DAT10__UART1_TXD		= IOMUX_PAD(0x0650, 0x0280, 3, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT10__UART1_TXD_RXD	= IOMUX_PAD(0x0650, 0x0280, 3, 0x0920, 0, 0),
-	MX6Q_PAD_CSI0_DAT10__SDMA_DEBUG_PC_4	= IOMUX_PAD(0x0650, 0x0280, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT10__GPIO_5_28		= IOMUX_PAD(0x0650, 0x0280, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT10__MMDC_MMDC_DEBUG_33	= IOMUX_PAD(0x0650, 0x0280, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT10__CHEETAH_TRACE_7	= IOMUX_PAD(0x0650, 0x0280, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT11__IPU1_CSI0_D_11	= IOMUX_PAD(0x0654, 0x0284, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT11__AUDMUX_AUD3_RXFS	= IOMUX_PAD(0x0654, 0x0284, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT11__ECSPI2_SS0		= IOMUX_PAD(0x0654, 0x0284, 2, 0x081C, 2, 0),
-	MX6Q_PAD_CSI0_DAT11__UART1_RXD		= IOMUX_PAD(0x0654, 0x0284, 3, 0x0920, 1, 0),
-	MX6Q_PAD_CSI0_DAT11__SDMA_DEBUG_PC_5	= IOMUX_PAD(0x0654, 0x0284, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT11__GPIO_5_29		= IOMUX_PAD(0x0654, 0x0284, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT11__MMDC_MMDC_DEBUG_34	= IOMUX_PAD(0x0654, 0x0284, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT11__CHEETAH_TRACE_8	= IOMUX_PAD(0x0654, 0x0284, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12	= IOMUX_PAD(0x0658, 0x0288, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT12__WEIM_WEIM_D_8	= IOMUX_PAD(0x0658, 0x0288, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT12__PCIE_CTRL_MUX_16	= IOMUX_PAD(0x0658, 0x0288, 2, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT12__UART4_TXD		= IOMUX_PAD(0x0658, 0x0288, 3, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT12__UART4_TXD_RXD	= IOMUX_PAD(0x0658, 0x0288, 3, 0x0938, 2, 0),
-	MX6Q_PAD_CSI0_DAT12__SDMA_DEBUG_PC_6	= IOMUX_PAD(0x0658, 0x0288, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT12__GPIO_5_30		= IOMUX_PAD(0x0658, 0x0288, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT12__MMDC_MMDC_DEBUG_35	= IOMUX_PAD(0x0658, 0x0288, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT12__CHEETAH_TRACE_9	= IOMUX_PAD(0x0658, 0x0288, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13	= IOMUX_PAD(0x065C, 0x028C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT13__WEIM_WEIM_D_9	= IOMUX_PAD(0x065C, 0x028C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT13__PCIE_CTRL_MUX_17	= IOMUX_PAD(0x065C, 0x028C, 2, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT13__UART4_RXD		= IOMUX_PAD(0x065C, 0x028C, 3, 0x0938, 3, 0),
-	MX6Q_PAD_CSI0_DAT13__SDMA_DEBUG_PC_7	= IOMUX_PAD(0x065C, 0x028C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT13__GPIO_5_31		= IOMUX_PAD(0x065C, 0x028C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT13__MMDC_MMDC_DEBUG_36	= IOMUX_PAD(0x065C, 0x028C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT13__CHEETAH_TRACE_10	= IOMUX_PAD(0x065C, 0x028C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14	= IOMUX_PAD(0x0660, 0x0290, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT14__WEIM_WEIM_D_10	= IOMUX_PAD(0x0660, 0x0290, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT14__PCIE_CTRL_MUX_18	= IOMUX_PAD(0x0660, 0x0290, 2, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT14__UART5_TXD		= IOMUX_PAD(0x0660, 0x0290, 3, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT14__UART5_TXD_RXD	= IOMUX_PAD(0x0660, 0x0290, 3, 0x0940, 2, 0),
-	MX6Q_PAD_CSI0_DAT14__SDMA_DEBUG_PC_8	= IOMUX_PAD(0x0660, 0x0290, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT14__GPIO_6_0		= IOMUX_PAD(0x0660, 0x0290, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT14__MMDC_MMDC_DEBUG_37	= IOMUX_PAD(0x0660, 0x0290, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT14__CHEETAH_TRACE_11	= IOMUX_PAD(0x0660, 0x0290, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15	= IOMUX_PAD(0x0664, 0x0294, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT15__WEIM_WEIM_D_11	= IOMUX_PAD(0x0664, 0x0294, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT15__PCIE_CTRL_MUX_19	= IOMUX_PAD(0x0664, 0x0294, 2, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT15__UART5_RXD		= IOMUX_PAD(0x0664, 0x0294, 3, 0x0940, 3, 0),
-	MX6Q_PAD_CSI0_DAT15__SDMA_DEBUG_PC_9	= IOMUX_PAD(0x0664, 0x0294, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT15__GPIO_6_1		= IOMUX_PAD(0x0664, 0x0294, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT15__MMDC_MMDC_DEBUG_38	= IOMUX_PAD(0x0664, 0x0294, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT15__CHEETAH_TRACE_12	= IOMUX_PAD(0x0664, 0x0294, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16	= IOMUX_PAD(0x0668, 0x0298, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT16__WEIM_WEIM_D_12	= IOMUX_PAD(0x0668, 0x0298, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT16__PCIE_CTRL_MUX_20	= IOMUX_PAD(0x0668, 0x0298, 2, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT16__UART4_CTS		= IOMUX_PAD(0x0668, 0x0298, 3, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT16__UART4_RTS		= IOMUX_PAD(0x0668, 0x0298, 3, 0x0934, 0, 0),
-	MX6Q_PAD_CSI0_DAT16__SDMA_DEBUG_PC_10	= IOMUX_PAD(0x0668, 0x0298, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT16__GPIO_6_2		= IOMUX_PAD(0x0668, 0x0298, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT16__MMDC_MMDC_DEBUG_39	= IOMUX_PAD(0x0668, 0x0298, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT16__CHEETAH_TRACE_13	= IOMUX_PAD(0x0668, 0x0298, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17	= IOMUX_PAD(0x066C, 0x029C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT17__WEIM_WEIM_D_13	= IOMUX_PAD(0x066C, 0x029C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT17__PCIE_CTRL_MUX_21	= IOMUX_PAD(0x066C, 0x029C, 2, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT17__UART4_CTS		= IOMUX_PAD(0x066C, 0x029C, 3, 0x0934, 1, 0),
-	MX6Q_PAD_CSI0_DAT17__SDMA_DEBUG_PC_11	= IOMUX_PAD(0x066C, 0x029C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT17__GPIO_6_3		= IOMUX_PAD(0x066C, 0x029C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT17__MMDC_MMDC_DEBUG_40	= IOMUX_PAD(0x066C, 0x029C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT17__CHEETAH_TRACE_14	= IOMUX_PAD(0x066C, 0x029C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18	= IOMUX_PAD(0x0670, 0x02A0, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT18__WEIM_WEIM_D_14	= IOMUX_PAD(0x0670, 0x02A0, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT18__PCIE_CTRL_MUX_22	= IOMUX_PAD(0x0670, 0x02A0, 2, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT18__UART5_CTS		= IOMUX_PAD(0x0670, 0x02A0, 3, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT18__UART5_RTS		= IOMUX_PAD(0x0670, 0x02A0, 3, 0x093C, 2, 0),
-	MX6Q_PAD_CSI0_DAT18__SDMA_DEBUG_PC_12	= IOMUX_PAD(0x0670, 0x02A0, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT18__GPIO_6_4		= IOMUX_PAD(0x0670, 0x02A0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT18__MMDC_MMDC_DEBUG_41	= IOMUX_PAD(0x0670, 0x02A0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT18__CHEETAH_TRACE_15	= IOMUX_PAD(0x0670, 0x02A0, 7, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19	= IOMUX_PAD(0x0674, 0x02A4, 0, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT19__WEIM_WEIM_D_15	= IOMUX_PAD(0x0674, 0x02A4, 1, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT19__PCIE_CTRL_MUX_23	= IOMUX_PAD(0x0674, 0x02A4, 2, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT19__UART5_CTS		= IOMUX_PAD(0x0674, 0x02A4, 3, 0x093C, 3, 0),
-	MX6Q_PAD_CSI0_DAT19__SDMA_DEBUG_PC_13	= IOMUX_PAD(0x0674, 0x02A4, 4, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT19__GPIO_6_5		= IOMUX_PAD(0x0674, 0x02A4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT19__MMDC_MMDC_DEBUG_42	= IOMUX_PAD(0x0674, 0x02A4, 6, 0x0000, 0, 0),
-	MX6Q_PAD_CSI0_DAT19__ANATOP_TESTO_9	= IOMUX_PAD(0x0674, 0x02A4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_JTAG_TMS__SJC_TMS		= IOMUX_PAD(0x0678, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_JTAG_MOD__SJC_MOD		= IOMUX_PAD(0x067C, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_JTAG_TRSTB__SJC_TRSTB		= IOMUX_PAD(0x0680, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_JTAG_TDI__SJC_TDI		= IOMUX_PAD(0x0684, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_JTAG_TCK__SJC_TCK		= IOMUX_PAD(0x0688, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_JTAG_TDO__SJC_TDO		= IOMUX_PAD(0x068C, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_TAMPER__SNVS_LP_WRAP_SNVS_TD1	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_PMIC_ON_REQ__SNVS_LPWRAP_WKALM = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_PMIC_STBY_REQ__CCM_PMIC_STBYRQ = IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_POR_B__SRC_POR_B		= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_BOOT_MODE1__SRC_BOOT_MODE_1	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_RESET_IN_B__SRC_RESET_B	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_BOOT_MODE0__SRC_BOOT_MODE_0	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_TEST_MODE__TCU_TEST_MODE	= IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT7__USDHC3_DAT7		= IOMUX_PAD(0x0690, 0x02A8, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT7__UART1_TXD		= IOMUX_PAD(0x0690, 0x02A8, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT7__UART1_TXD_RXD	= IOMUX_PAD(0x0690, 0x02A8, 1, 0x0920, 2, 0),
-	MX6Q_PAD_SD3_DAT7__PCIE_CTRL_MUX_24	= IOMUX_PAD(0x0690, 0x02A8, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT7__USBOH3_UH3_DFD_OUT_0	= IOMUX_PAD(0x0690, 0x02A8, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT7__USBOH3_UH2_DFD_OUT_0	= IOMUX_PAD(0x0690, 0x02A8, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT7__GPIO_6_17		= IOMUX_PAD(0x0690, 0x02A8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT7__MIPI_CORE_DPHY_IN_12	= IOMUX_PAD(0x0690, 0x02A8, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT7__USBPHY2_CLK20DIV	= IOMUX_PAD(0x0690, 0x02A8, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT6__USDHC3_DAT6		= IOMUX_PAD(0x0694, 0x02AC, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT6__UART1_RXD		= IOMUX_PAD(0x0694, 0x02AC, 1, 0x0920, 3, 0),
-	MX6Q_PAD_SD3_DAT6__PCIE_CTRL_MUX_25	= IOMUX_PAD(0x0694, 0x02AC, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT6__USBOH3_UH3_DFD_OUT_1 = IOMUX_PAD(0x0694, 0x02AC, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT6__USBOH3_UH2_DFD_OUT_1 = IOMUX_PAD(0x0694, 0x02AC, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT6__GPIO_6_18		= IOMUX_PAD(0x0694, 0x02AC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT6__MIPI_CORE_DPHY_IN_13	= IOMUX_PAD(0x0694, 0x02AC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT6__ANATOP_TESTO_10	= IOMUX_PAD(0x0694, 0x02AC, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT5__USDHC3_DAT5		= IOMUX_PAD(0x0698, 0x02B0, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT5__UART2_TXD		= IOMUX_PAD(0x0698, 0x02B0, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT5__UART2_TXD_RXD	= IOMUX_PAD(0x0698, 0x02B0, 1, 0x0928, 4, 0),
-	MX6Q_PAD_SD3_DAT5__PCIE_CTRL_MUX_26	= IOMUX_PAD(0x0698, 0x02B0, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT5__USBOH3_UH3_DFD_OUT_2	= IOMUX_PAD(0x0698, 0x02B0, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT5__USBOH3_UH2_DFD_OUT_2	= IOMUX_PAD(0x0698, 0x02B0, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT5__GPIO_7_0		= IOMUX_PAD(0x0698, 0x02B0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT5__MIPI_CORE_DPHY_IN_14	= IOMUX_PAD(0x0698, 0x02B0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT5__ANATOP_TESTO_11	= IOMUX_PAD(0x0698, 0x02B0, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT4__USDHC3_DAT4		= IOMUX_PAD(0x069C, 0x02B4, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT4__UART2_RXD		= IOMUX_PAD(0x069C, 0x02B4, 1, 0x0928, 5, 0),
-	MX6Q_PAD_SD3_DAT4__PCIE_CTRL_MUX_27	= IOMUX_PAD(0x069C, 0x02B4, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT4__USBOH3_UH3_DFD_OUT_3	= IOMUX_PAD(0x069C, 0x02B4, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT4__USBOH3_UH2_DFD_OUT_3	= IOMUX_PAD(0x069C, 0x02B4, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT4__GPIO_7_1		= IOMUX_PAD(0x069C, 0x02B4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT4__MIPI_CORE_DPHY_IN_15	= IOMUX_PAD(0x069C, 0x02B4, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT4__ANATOP_TESTO_12	= IOMUX_PAD(0x069C, 0x02B4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_CMD__USDHC3_CMD		= IOMUX_PAD(0x06A0, 0x02B8, 16, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_CMD__UART2_CTS		= IOMUX_PAD(0x06A0, 0x02B8, 1, 0x0924, 2, 0),
-	MX6Q_PAD_SD3_CMD__CAN1_TXCAN		= IOMUX_PAD(0x06A0, 0x02B8, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_CMD__USBOH3_UH3_DFD_OUT_4	= IOMUX_PAD(0x06A0, 0x02B8, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_CMD__USBOH3_UH2_DFD_OUT_4	= IOMUX_PAD(0x06A0, 0x02B8, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_CMD__GPIO_7_2		= IOMUX_PAD(0x06A0, 0x02B8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_CMD__MIPI_CORE_DPHY_IN_16	= IOMUX_PAD(0x06A0, 0x02B8, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_CMD__ANATOP_TESTO_13	= IOMUX_PAD(0x06A0, 0x02B8, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_CLK__USDHC3_CLK		= IOMUX_PAD(0x06A4, 0x02BC, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_CLK__UART2_CTS		= IOMUX_PAD(0x06A4, 0x02BC, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_CLK__UART2_RTS		= IOMUX_PAD(0x06A4, 0x02BC, 1, 0x0924, 3, 0),
-	MX6Q_PAD_SD3_CLK__CAN1_RXCAN		= IOMUX_PAD(0x06A4, 0x02BC, 2, 0x07E4, 2, 0),
-	MX6Q_PAD_SD3_CLK__USBOH3_UH3_DFD_OUT_5	= IOMUX_PAD(0x06A4, 0x02BC, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_CLK__USBOH3_UH2_DFD_OUT_5	= IOMUX_PAD(0x06A4, 0x02BC, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_CLK__GPIO_7_3		= IOMUX_PAD(0x06A4, 0x02BC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_CLK__MIPI_CORE_DPHY_IN_17	= IOMUX_PAD(0x06A4, 0x02BC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_CLK__ANATOP_TESTO_14	= IOMUX_PAD(0x06A4, 0x02BC, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT0__USDHC3_DAT0		= IOMUX_PAD(0x06A8, 0x02C0, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT0__UART1_CTS		= IOMUX_PAD(0x06A8, 0x02C0, 1, 0x091C, 2, 0),
-	MX6Q_PAD_SD3_DAT0__CAN2_TXCAN		= IOMUX_PAD(0x06A8, 0x02C0, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT0__USBOH3_UH3_DFD_OUT_6	= IOMUX_PAD(0x06A8, 0x02C0, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT0__USBOH3_UH2_DFD_OUT_6	= IOMUX_PAD(0x06A8, 0x02C0, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT0__GPIO_7_4		= IOMUX_PAD(0x06A8, 0x02C0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT0__MIPI_CORE_DPHY_IN_18	= IOMUX_PAD(0x06A8, 0x02C0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT0__ANATOP_TESTO_15	= IOMUX_PAD(0x06A8, 0x02C0, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT1__USDHC3_DAT1		= IOMUX_PAD(0x06AC, 0x02C4, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT1__UART1_CTS		= IOMUX_PAD(0x06AC, 0x02C4, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT1__UART1_RTS		= IOMUX_PAD(0x06AC, 0x02C4, 1, 0x091C, 3, 0),
-	MX6Q_PAD_SD3_DAT1__CAN2_RXCAN		= IOMUX_PAD(0x06AC, 0x02C4, 2, 0x07E8, 1, 0),
-	MX6Q_PAD_SD3_DAT1__USBOH3_UH3_DFD_OUT_7	= IOMUX_PAD(0x06AC, 0x02C4, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT1__USBOH3_UH2_DFD_OUT_7	= IOMUX_PAD(0x06AC, 0x02C4, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT1__GPIO_7_5		= IOMUX_PAD(0x06AC, 0x02C4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT1__MIPI_CORE_DPHY_IN_19 = IOMUX_PAD(0x06AC, 0x02C4, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT1__ANATOP_TESTI_0	= IOMUX_PAD(0x06AC, 0x02C4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT2__USDHC3_DAT2		= IOMUX_PAD(0x06B0, 0x02C8, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT2__PCIE_CTRL_MUX_28	= IOMUX_PAD(0x06B0, 0x02C8, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT2__USBOH3_UH3_DFD_OUT_8	= IOMUX_PAD(0x06B0, 0x02C8, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT2__USBOH3_UH2_DFD_OUT_8	= IOMUX_PAD(0x06B0, 0x02C8, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT2__GPIO_7_6		= IOMUX_PAD(0x06B0, 0x02C8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT2__MIPI_CORE_DPHY_IN_20	= IOMUX_PAD(0x06B0, 0x02C8, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT2__ANATOP_TESTI_1	= IOMUX_PAD(0x06B0, 0x02C8, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT3__USDHC3_DAT3		= IOMUX_PAD(0x06B4, 0x02CC, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT3__UART3_CTS		= IOMUX_PAD(0x06B4, 0x02CC, 1, 0x092C, 4, 0),
-	MX6Q_PAD_SD3_DAT3__PCIE_CTRL_MUX_29	= IOMUX_PAD(0x06B4, 0x02CC, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT3__USBOH3_UH3_DFD_OUT_9	= IOMUX_PAD(0x06B4, 0x02CC, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT3__USBOH3_UH2_DFD_OUT_9	= IOMUX_PAD(0x06B4, 0x02CC, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT3__GPIO_7_7		= IOMUX_PAD(0x06B4, 0x02CC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT3__MIPI_CORE_DPHY_IN_21	= IOMUX_PAD(0x06B4, 0x02CC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_DAT3__ANATOP_TESTI_2	= IOMUX_PAD(0x06B4, 0x02CC, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_RST__USDHC3_RST		= IOMUX_PAD(0x06B8, 0x02D0, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_RST__UART3_CTS		= IOMUX_PAD(0x06B8, 0x02D0, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_RST__UART3_RTS		= IOMUX_PAD(0x06B8, 0x02D0, 1, 0x092C, 5, 0),
-	MX6Q_PAD_SD3_RST__PCIE_CTRL_MUX_30	= IOMUX_PAD(0x06B8, 0x02D0, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_RST__USBOH3_UH3_DFD_OUT_10	= IOMUX_PAD(0x06B8, 0x02D0, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_RST__USBOH3_UH2_DFD_OUT_10	= IOMUX_PAD(0x06B8, 0x02D0, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_RST__GPIO_7_8		= IOMUX_PAD(0x06B8, 0x02D0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_RST__MIPI_CORE_DPHY_IN_22	= IOMUX_PAD(0x06B8, 0x02D0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD3_RST__ANATOP_ANATOP_TESTI_3	= IOMUX_PAD(0x06B8, 0x02D0, 7, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CLE__RAWNAND_CLE		= IOMUX_PAD(0x06BC, 0x02D4, 0, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CLE__IPU2_SISG_4		= IOMUX_PAD(0x06BC, 0x02D4, 1, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CLE__PCIE_CTRL_MUX_31	= IOMUX_PAD(0x06BC, 0x02D4, 2, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CLE__USBOH3_UH3_DFD_OT11 = IOMUX_PAD(0x06BC, 0x02D4, 3, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CLE__USBOH3_UH2_DFD_OT11	= IOMUX_PAD(0x06BC, 0x02D4, 4, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CLE__GPIO_6_7		= IOMUX_PAD(0x06BC, 0x02D4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CLE__MIPI_CORE_DPHY_IN23 = IOMUX_PAD(0x06BC, 0x02D4, 6, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CLE__TPSMP_HTRANS_0	= IOMUX_PAD(0x06BC, 0x02D4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_ALE__RAWNAND_ALE		= IOMUX_PAD(0x06C0, 0x02D8, 0, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_ALE__USDHC4_RST		= IOMUX_PAD(0x06C0, 0x02D8, 1, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_ALE__PCIE_CTRL_MUX_0	= IOMUX_PAD(0x06C0, 0x02D8, 2, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_ALE__USBOH3_UH3_DFD_OT12	= IOMUX_PAD(0x06C0, 0x02D8, 3, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_ALE__USBOH3_UH2_DFD_OT12	= IOMUX_PAD(0x06C0, 0x02D8, 4, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_ALE__GPIO_6_8		= IOMUX_PAD(0x06C0, 0x02D8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_ALE__MIPI_CR_DPHY_IN_24	= IOMUX_PAD(0x06C0, 0x02D8, 6, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_ALE__TPSMP_HTRANS_1	= IOMUX_PAD(0x06C0, 0x02D8, 7, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN	= IOMUX_PAD(0x06C4, 0x02DC, 0, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_WP_B__IPU2_SISG_5	= IOMUX_PAD(0x06C4, 0x02DC, 1, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_WP_B__PCIE_CTRL__MUX_1	= IOMUX_PAD(0x06C4, 0x02DC, 2, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_WP_B__USBOH3_UH3_DFDOT13 = IOMUX_PAD(0x06C4, 0x02DC, 3, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_WP_B__USBOH3_UH2_DFDOT13 = IOMUX_PAD(0x06C4, 0x02DC, 4, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_WP_B__GPIO_6_9		= IOMUX_PAD(0x06C4, 0x02DC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_WP_B__MIPI_CR_DPHY_OUT32	= IOMUX_PAD(0x06C4, 0x02DC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_WP_B__PL301_PER1_HSIZE_0 = IOMUX_PAD(0x06C4, 0x02DC, 7, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_RB0__RAWNAND_READY0	= IOMUX_PAD(0x06C8, 0x02E0, 0, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_RB0__IPU2_DI0_PIN1	= IOMUX_PAD(0x06C8, 0x02E0, 1, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_RB0__PCIE_CTRL_MUX_2	= IOMUX_PAD(0x06C8, 0x02E0, 2, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_RB0__USBOH3_UH3_DFD_OT14 = IOMUX_PAD(0x06C8, 0x02E0, 3, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_RB0__USBOH3_UH2_DFD_OT14 = IOMUX_PAD(0x06C8, 0x02E0, 4, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_RB0__GPIO_6_10		= IOMUX_PAD(0x06C8, 0x02E0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_RB0__MIPI_CR_DPHY_OUT_33	= IOMUX_PAD(0x06C8, 0x02E0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_RB0__PL301_PER1_HSIZE_1	= IOMUX_PAD(0x06C8, 0x02E0, 7, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS0__RAWNAND_CE0N	= IOMUX_PAD(0x06CC, 0x02E4, 0, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS0__USBOH3_UH3_DFD_OT15 = IOMUX_PAD(0x06CC, 0x02E4, 3, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS0__USBOH3_UH2_DFD_OT15 = IOMUX_PAD(0x06CC, 0x02E4, 4, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS0__GPIO_6_11		= IOMUX_PAD(0x06CC, 0x02E4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS0__PL301_PER1_HSIZE_2	= IOMUX_PAD(0x06CC, 0x02E4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS1__RAWNAND_CE1N	= IOMUX_PAD(0x06D0, 0x02E8, 0, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS1__USDHC4_VSELECT	= IOMUX_PAD(0x06D0, 0x02E8, 1, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS1__USDHC3_VSELECT	= IOMUX_PAD(0x06D0, 0x02E8, 2, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS1__PCIE_CTRL_MUX_3	= IOMUX_PAD(0x06D0, 0x02E8, 4, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS1__GPIO_6_14		= IOMUX_PAD(0x06D0, 0x02E8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS1__PL301_PER1_HRDYOUT	= IOMUX_PAD(0x06D0, 0x02E8, 7, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS2__RAWNAND_CE2N	= IOMUX_PAD(0x06D4, 0x02EC, 0, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS2__IPU1_SISG_0		= IOMUX_PAD(0x06D4, 0x02EC, 1, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS2__ESAI1_TX0		= IOMUX_PAD(0x06D4, 0x02EC, 2, 0x0874, 1, 0),
-	MX6Q_PAD_NANDF_CS2__WEIM_WEIM_CRE	= IOMUX_PAD(0x06D4, 0x02EC, 3, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS2__CCM_CLKO2		= IOMUX_PAD(0x06D4, 0x02EC, 4, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS2__GPIO_6_15		= IOMUX_PAD(0x06D4, 0x02EC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS2__IPU2_SISG_0		= IOMUX_PAD(0x06D4, 0x02EC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS3__RAWNAND_CE3N	= IOMUX_PAD(0x06D8, 0x02F0, 0, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS3__IPU1_SISG_1		= IOMUX_PAD(0x06D8, 0x02F0, 1, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS3__ESAI1_TX1		= IOMUX_PAD(0x06D8, 0x02F0, 2, 0x0878, 1, 0),
-	MX6Q_PAD_NANDF_CS3__WEIM_WEIM_A_26	= IOMUX_PAD(0x06D8, 0x02F0, 3, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS3__PCIE_CTRL_MUX_4	= IOMUX_PAD(0x06D8, 0x02F0, 4, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS3__GPIO_6_16		= IOMUX_PAD(0x06D8, 0x02F0, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS3__IPU2_SISG_1		= IOMUX_PAD(0x06D8, 0x02F0, 6, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_CS3__TPSMP_CLK		= IOMUX_PAD(0x06D8, 0x02F0, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_CMD__USDHC4_CMD		= IOMUX_PAD(0x06DC, 0x02F4, 16, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_CMD__RAWNAND_RDN		= IOMUX_PAD(0x06DC, 0x02F4, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_CMD__UART3_TXD		= IOMUX_PAD(0x06DC, 0x02F4, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_CMD__UART3_TXD_RXD		= IOMUX_PAD(0x06DC, 0x02F4, 2, 0x0930, 2, 0),
-	MX6Q_PAD_SD4_CMD__PCIE_CTRL_MUX_5	= IOMUX_PAD(0x06DC, 0x02F4, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_CMD__GPIO_7_9		= IOMUX_PAD(0x06DC, 0x02F4, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_CMD__TPSMP_HDATA_DIR	= IOMUX_PAD(0x06DC, 0x02F4, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_CLK__USDHC4_CLK		= IOMUX_PAD(0x06E0, 0x02F8, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_CLK__RAWNAND_WRN		= IOMUX_PAD(0x06E0, 0x02F8, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_CLK__UART3_RXD		= IOMUX_PAD(0x06E0, 0x02F8, 2, 0x0930, 3, 0),
-	MX6Q_PAD_SD4_CLK__PCIE_CTRL_MUX_6	= IOMUX_PAD(0x06E0, 0x02F8, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_CLK__GPIO_7_10		= IOMUX_PAD(0x06E0, 0x02F8, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D0__RAWNAND_D0		= IOMUX_PAD(0x06E4, 0x02FC, 0, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D0__USDHC1_DAT4		= IOMUX_PAD(0x06E4, 0x02FC, 1, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D0__GPU3D_GPU_DBG_OUT_0	= IOMUX_PAD(0x06E4, 0x02FC, 2, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D0__USBOH3_UH2_DFD_OUT16	= IOMUX_PAD(0x06E4, 0x02FC, 3, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D0__USBOH3_UH3_DFD_OUT16	= IOMUX_PAD(0x06E4, 0x02FC, 4, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D0__GPIO_2_0		= IOMUX_PAD(0x06E4, 0x02FC, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D0__IPU1_IPU_DIAG_BUS_0	= IOMUX_PAD(0x06E4, 0x02FC, 6, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D0__IPU2_IPU_DIAG_BUS_0	= IOMUX_PAD(0x06E4, 0x02FC, 7, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D1__RAWNAND_D1		= IOMUX_PAD(0x06E8, 0x0300, 0, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D1__USDHC1_DAT5		= IOMUX_PAD(0x06E8, 0x0300, 1, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D1__GPU3D_GPU_DEBUG_OUT1	= IOMUX_PAD(0x06E8, 0x0300, 2, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D1__USBOH3_UH2_DFD_OUT17	= IOMUX_PAD(0x06E8, 0x0300, 3, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D1__USBOH3_UH3_DFD_OUT17	= IOMUX_PAD(0x06E8, 0x0300, 4, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D1__GPIO_2_1		= IOMUX_PAD(0x06E8, 0x0300, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D1__IPU1_IPU_DIAG_BUS_1	= IOMUX_PAD(0x06E8, 0x0300, 6, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D1__IPU2_IPU_DIAG_BUS_1	= IOMUX_PAD(0x06E8, 0x0300, 7, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D2__RAWNAND_D2		= IOMUX_PAD(0x06EC, 0x0304, 0, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D2__USDHC1_DAT6		= IOMUX_PAD(0x06EC, 0x0304, 1, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D2__GPU3D_GPU_DBG_OUT_2	= IOMUX_PAD(0x06EC, 0x0304, 2, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D2__USBOH3_UH2_DFD_OUT18	= IOMUX_PAD(0x06EC, 0x0304, 3, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D2__USBOH3_UH3_DFD_OUT18	= IOMUX_PAD(0x06EC, 0x0304, 4, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D2__GPIO_2_2		= IOMUX_PAD(0x06EC, 0x0304, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D2__IPU1_IPU_DIAG_BUS_2	= IOMUX_PAD(0x06EC, 0x0304, 6, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D2__IPU2_IPU_DIAG_BUS_2	= IOMUX_PAD(0x06EC, 0x0304, 7, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D3__RAWNAND_D3		= IOMUX_PAD(0x06F0, 0x0308, 0, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D3__USDHC1_DAT7		= IOMUX_PAD(0x06F0, 0x0308, 1, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D3__GPU3D_GPU_DBG_OUT_3	= IOMUX_PAD(0x06F0, 0x0308, 2, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D3__USBOH3_UH2_DFD_OUT19	= IOMUX_PAD(0x06F0, 0x0308, 3, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D3__USBOH3_UH3_DFD_OUT19	= IOMUX_PAD(0x06F0, 0x0308, 4, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D3__GPIO_2_3		= IOMUX_PAD(0x06F0, 0x0308, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D3__IPU1_IPU_DIAG_BUS_3	= IOMUX_PAD(0x06F0, 0x0308, 6, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D3__IPU2_IPU_DIAG_BUS_3	= IOMUX_PAD(0x06F0, 0x0308, 7, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D4__RAWNAND_D4		= IOMUX_PAD(0x06F4, 0x030C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D4__USDHC2_DAT4		= IOMUX_PAD(0x06F4, 0x030C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D4__GPU3D_GPU_DBG_OUT_4	= IOMUX_PAD(0x06F4, 0x030C, 2, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D4__USBOH3_UH2_DFD_OUT20	= IOMUX_PAD(0x06F4, 0x030C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D4__USBOH3_UH3_DFD_OUT20	= IOMUX_PAD(0x06F4, 0x030C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D4__GPIO_2_4		= IOMUX_PAD(0x06F4, 0x030C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D4__IPU1_IPU_DIAG_BUS_4	= IOMUX_PAD(0x06F4, 0x030C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D4__IPU2_IPU_DIAG_BUS_4	= IOMUX_PAD(0x06F4, 0x030C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D5__RAWNAND_D5		= IOMUX_PAD(0x06F8, 0x0310, 0, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D5__USDHC2_DAT5		= IOMUX_PAD(0x06F8, 0x0310, 1, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D5__GPU3D_GPU_DBG_OUT_5	= IOMUX_PAD(0x06F8, 0x0310, 2, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D5__USBOH3_UH2_DFD_OUT21	= IOMUX_PAD(0x06F8, 0x0310, 3, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D5__USBOH3_UH3_DFD_OUT21	= IOMUX_PAD(0x06F8, 0x0310, 4, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D5__GPIO_2_5		= IOMUX_PAD(0x06F8, 0x0310, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D5__IPU1_IPU_DIAG_BUS_5	= IOMUX_PAD(0x06F8, 0x0310, 6, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D5__IPU2_IPU_DIAG_BUS_5	= IOMUX_PAD(0x06F8, 0x0310, 7, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D6__RAWNAND_D6		= IOMUX_PAD(0x06FC, 0x0314, 0, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D6__USDHC2_DAT6		= IOMUX_PAD(0x06FC, 0x0314, 1, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D6__GPU3D_GPU_DBG_OUT_6	= IOMUX_PAD(0x06FC, 0x0314, 2, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D6__USBOH3_UH2_DFD_OUT22	= IOMUX_PAD(0x06FC, 0x0314, 3, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D6__USBOH3_UH3_DFD_OUT22	= IOMUX_PAD(0x06FC, 0x0314, 4, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D6__GPIO_2_6		= IOMUX_PAD(0x06FC, 0x0314, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D6__IPU1_IPU_DIAG_BUS_6	= IOMUX_PAD(0x06FC, 0x0314, 6, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D6__IPU2_IPU_DIAG_BUS_6	= IOMUX_PAD(0x06FC, 0x0314, 7, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D7__RAWNAND_D7		= IOMUX_PAD(0x0700, 0x0318, 0, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D7__USDHC2_DAT7		= IOMUX_PAD(0x0700, 0x0318, 1, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D7__GPU3D_GPU_DBG_OUT_7	= IOMUX_PAD(0x0700, 0x0318, 2, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D7__USBOH3_UH2_DFD_OUT23	= IOMUX_PAD(0x0700, 0x0318, 3, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D7__USBOH3_UH3_DFD_OUT23	= IOMUX_PAD(0x0700, 0x0318, 4, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D7__GPIO_2_7		= IOMUX_PAD(0x0700, 0x0318, 5, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D7__IPU1_IPU_DIAG_BUS_7	= IOMUX_PAD(0x0700, 0x0318, 6, 0x0000, 0, 0),
-	MX6Q_PAD_NANDF_D7__IPU2_IPU_DIAG_BUS_7	= IOMUX_PAD(0x0700, 0x0318, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT0__RAWNAND_D8		= IOMUX_PAD(0x0704, 0x031C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT0__USDHC4_DAT0		= IOMUX_PAD(0x0704, 0x031C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT0__RAWNAND_DQS		= IOMUX_PAD(0x0704, 0x031C, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT0__USBOH3_UH2_DFD_OUT24	= IOMUX_PAD(0x0704, 0x031C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT0__USBOH3_UH3_DFD_OUT24	= IOMUX_PAD(0x0704, 0x031C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT0__GPIO_2_8		= IOMUX_PAD(0x0704, 0x031C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT0__IPU1_IPU_DIAG_BUS_8	= IOMUX_PAD(0x0704, 0x031C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT0__IPU2_IPU_DIAG_BUS_8	= IOMUX_PAD(0x0704, 0x031C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT1__RAWNAND_D9		= IOMUX_PAD(0x0708, 0x0320, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT1__USDHC4_DAT1		= IOMUX_PAD(0x0708, 0x0320, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT1__PWM3_PWMO		= IOMUX_PAD(0x0708, 0x0320, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT1__USBOH3_UH2_DFD_OUT25	= IOMUX_PAD(0x0708, 0x0320, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT1__USBOH3_UH3_DFD_OUT25	= IOMUX_PAD(0x0708, 0x0320, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT1__GPIO_2_9		= IOMUX_PAD(0x0708, 0x0320, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT1__IPU1_IPU_DIAG_BUS_9	= IOMUX_PAD(0x0708, 0x0320, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT1__IPU2_IPU_DIAG_BUS_9	= IOMUX_PAD(0x0708, 0x0320, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT2__RAWNAND_D10		= IOMUX_PAD(0x070C, 0x0324, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT2__USDHC4_DAT2		= IOMUX_PAD(0x070C, 0x0324, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT2__PWM4_PWMO		= IOMUX_PAD(0x070C, 0x0324, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT2__USBOH3_UH2_DFD_OUT26	= IOMUX_PAD(0x070C, 0x0324, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT2__USBOH3_UH3_DFD_OUT26	= IOMUX_PAD(0x070C, 0x0324, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT2__GPIO_2_10		= IOMUX_PAD(0x070C, 0x0324, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT2__IPU1_IPU_DIAG_BUS_10	= IOMUX_PAD(0x070C, 0x0324, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT2__IPU2_IPU_DIAG_BUS_10	= IOMUX_PAD(0x070C, 0x0324, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT3__RAWNAND_D11		= IOMUX_PAD(0x0710, 0x0328, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT3__USDHC4_DAT3		= IOMUX_PAD(0x0710, 0x0328, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT3__USBOH3_UH2_DFD_OUT27	= IOMUX_PAD(0x0710, 0x0328, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT3__USBOH3_UH3_DFD_OUT27	= IOMUX_PAD(0x0710, 0x0328, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT3__GPIO_2_11		= IOMUX_PAD(0x0710, 0x0328, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT3__IPU1_IPU_DIAG_BUS_11	= IOMUX_PAD(0x0710, 0x0328, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT3__IPU2_IPU_DIAG_BUS_11	= IOMUX_PAD(0x0710, 0x0328, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT4__RAWNAND_D12		= IOMUX_PAD(0x0714, 0x032C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT4__USDHC4_DAT4		= IOMUX_PAD(0x0714, 0x032C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT4__UART2_RXD		= IOMUX_PAD(0x0714, 0x032C, 2, 0x0928, 6, 0),
-	MX6Q_PAD_SD4_DAT4__USBOH3_UH2_DFD_OUT28	= IOMUX_PAD(0x0714, 0x032C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT4__USBOH3_UH3_DFD_OUT28	= IOMUX_PAD(0x0714, 0x032C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT4__GPIO_2_12		= IOMUX_PAD(0x0714, 0x032C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT4__IPU1_IPU_DIAG_BUS_12	= IOMUX_PAD(0x0714, 0x032C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT4__IPU2_IPU_DIAG_BUS_12	= IOMUX_PAD(0x0714, 0x032C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT5__RAWNAND_D13		= IOMUX_PAD(0x0718, 0x0330, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT5__USDHC4_DAT5		= IOMUX_PAD(0x0718, 0x0330, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT5__UART2_CTS		= IOMUX_PAD(0x0718, 0x0330, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT5__UART2_RTS		= IOMUX_PAD(0x0718, 0x0330, 2, 0x0924, 4, 0),
-	MX6Q_PAD_SD4_DAT5__USBOH3_UH2_DFD_OUT29	= IOMUX_PAD(0x0718, 0x0330, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT5__USBOH3_UH3_DFD_OUT29	= IOMUX_PAD(0x0718, 0x0330, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT5__GPIO_2_13		= IOMUX_PAD(0x0718, 0x0330, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT5__IPU1_IPU_DIAG_BUS_13	= IOMUX_PAD(0x0718, 0x0330, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT5__IPU2_IPU_DIAG_BUS_13	= IOMUX_PAD(0x0718, 0x0330, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT6__RAWNAND_D14		= IOMUX_PAD(0x071C, 0x0334, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT6__USDHC4_DAT6		= IOMUX_PAD(0x071C, 0x0334, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT6__UART2_CTS		= IOMUX_PAD(0x071C, 0x0334, 2, 0x0924, 5, 0),
-	MX6Q_PAD_SD4_DAT6__USBOH3_UH2_DFD_OUT30	= IOMUX_PAD(0x071C, 0x0334, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT6__USBOH3_UH3_DFD_OUT30	= IOMUX_PAD(0x071C, 0x0334, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT6__GPIO_2_14		= IOMUX_PAD(0x071C, 0x0334, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT6__IPU1_IPU_DIAG_BUS_14	= IOMUX_PAD(0x071C, 0x0334, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT6__IPU2_IPU_DIAG_BUS_14	= IOMUX_PAD(0x071C, 0x0334, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT7__RAWNAND_D15		= IOMUX_PAD(0x0720, 0x0338, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT7__USDHC4_DAT7		= IOMUX_PAD(0x0720, 0x0338, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT7__UART2_TXD		= IOMUX_PAD(0x0720, 0x0338, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT7__UART2_TXD_RXD	= IOMUX_PAD(0x0720, 0x0338, 2, 0x0928, 7, 0),
-	MX6Q_PAD_SD4_DAT7__USBOH3_UH2_DFD_OUT31 = IOMUX_PAD(0x0720, 0x0338, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT7__USBOH3_UH3_DFD_OUT31 = IOMUX_PAD(0x0720, 0x0338, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT7__GPIO_2_15		= IOMUX_PAD(0x0720, 0x0338, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT7__IPU1_IPU_DIAG_BUS_15	= IOMUX_PAD(0x0720, 0x0338, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD4_DAT7__IPU2_IPU_DIAG_BUS_15	= IOMUX_PAD(0x0720, 0x0338, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT1__USDHC1_DAT1		= IOMUX_PAD(0x0724, 0x033C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT1__ECSPI5_SS0		= IOMUX_PAD(0x0724, 0x033C, 1, 0x0834, 1, 0),
-	MX6Q_PAD_SD1_DAT1__PWM3_PWMO		= IOMUX_PAD(0x0724, 0x033C, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT1__GPT_CAPIN2		= IOMUX_PAD(0x0724, 0x033C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT1__PCIE_CTRL_MUX_7	= IOMUX_PAD(0x0724, 0x033C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT1__GPIO_1_17		= IOMUX_PAD(0x0724, 0x033C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT1__HDMI_TX_OPHYDTB_0	= IOMUX_PAD(0x0724, 0x033C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT1__ANATOP_TESTO_8	= IOMUX_PAD(0x0724, 0x033C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT0__USDHC1_DAT0		= IOMUX_PAD(0x0728, 0x0340, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT0__ECSPI5_MISO		= IOMUX_PAD(0x0728, 0x0340, 1, 0x082C, 1, 0),
-	MX6Q_PAD_SD1_DAT0__CAAM_WRAP_RNG_OSCOBS	= IOMUX_PAD(0x0728, 0x0340, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT0__GPT_CAPIN1		= IOMUX_PAD(0x0728, 0x0340, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT0__PCIE_CTRL_MUX_8	= IOMUX_PAD(0x0728, 0x0340, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT0__GPIO_1_16		= IOMUX_PAD(0x0728, 0x0340, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT0__HDMI_TX_OPHYDTB_1	= IOMUX_PAD(0x0728, 0x0340, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT0__ANATOP_TESTO_7	= IOMUX_PAD(0x0728, 0x0340, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT3__USDHC1_DAT3		= IOMUX_PAD(0x072C, 0x0344, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT3__ECSPI5_SS2		= IOMUX_PAD(0x072C, 0x0344, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT3__GPT_CMPOUT3		= IOMUX_PAD(0x072C, 0x0344, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT3__PWM1_PWMO		= IOMUX_PAD(0x072C, 0x0344, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT3__WDOG2_WDOG_B		= IOMUX_PAD(0x072C, 0x0344, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT3__GPIO_1_21		= IOMUX_PAD(0x072C, 0x0344, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT3__WDOG2_WDOG_RST_B_DEB	= IOMUX_PAD(0x072C, 0x0344, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT3__ANATOP_TESTO_6	= IOMUX_PAD(0x072C, 0x0344, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_CMD__USDHC1_CMD		= IOMUX_PAD(0x0730, 0x0348, 16, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_CMD__ECSPI5_MOSI		= IOMUX_PAD(0x0730, 0x0348, 1, 0x0830, 0, 0),
-	MX6Q_PAD_SD1_CMD__PWM4_PWMO		= IOMUX_PAD(0x0730, 0x0348, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_CMD__GPT_CMPOUT1		= IOMUX_PAD(0x0730, 0x0348, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_CMD__GPIO_1_18		= IOMUX_PAD(0x0730, 0x0348, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_CMD__ANATOP_TESTO_5	= IOMUX_PAD(0x0730, 0x0348, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT2__USDHC1_DAT2		= IOMUX_PAD(0x0734, 0x034C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT2__ECSPI5_SS1		= IOMUX_PAD(0x0734, 0x034C, 1, 0x0838, 1, 0),
-	MX6Q_PAD_SD1_DAT2__GPT_CMPOUT2		= IOMUX_PAD(0x0734, 0x034C, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT2__PWM2_PWMO		= IOMUX_PAD(0x0734, 0x034C, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT2__WDOG1_WDOG_B		= IOMUX_PAD(0x0734, 0x034C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT2__GPIO_1_19		= IOMUX_PAD(0x0734, 0x034C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT2__WDOG1_WDOG_RST_B_DEB	= IOMUX_PAD(0x0734, 0x034C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_DAT2__ANATOP_TESTO_4	= IOMUX_PAD(0x0734, 0x034C, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_CLK__USDHC1_CLK		= IOMUX_PAD(0x0738, 0x0350, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_CLK__ECSPI5_SCLK		= IOMUX_PAD(0x0738, 0x0350, 1, 0x0828, 0, 0),
-	MX6Q_PAD_SD1_CLK__OSC32K_32K_OUT	= IOMUX_PAD(0x0738, 0x0350, 2, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_CLK__GPT_CLKIN		= IOMUX_PAD(0x0738, 0x0350, 3, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_CLK__GPIO_1_20		= IOMUX_PAD(0x0738, 0x0350, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_CLK__PHY_DTB_0		= IOMUX_PAD(0x0738, 0x0350, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD1_CLK__SATA_PHY_DTB_0	= IOMUX_PAD(0x0738, 0x0350, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_CLK__USDHC2_CLK		= IOMUX_PAD(0x073C, 0x0354, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_CLK__ECSPI5_SCLK		= IOMUX_PAD(0x073C, 0x0354, 1, 0x0828, 1, 0),
-	MX6Q_PAD_SD2_CLK__KPP_COL_5		= IOMUX_PAD(0x073C, 0x0354, 2, 0x08E8, 3, 0),
-	MX6Q_PAD_SD2_CLK__AUDMUX_AUD4_RXFS	= IOMUX_PAD(0x073C, 0x0354, 3, 0x07C0, 1, 0),
-	MX6Q_PAD_SD2_CLK__PCIE_CTRL_MUX_9	= IOMUX_PAD(0x073C, 0x0354, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_CLK__GPIO_1_10		= IOMUX_PAD(0x073C, 0x0354, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_CLK__PHY_DTB_1		= IOMUX_PAD(0x073C, 0x0354, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_CLK__SATA_PHY_DTB_1	= IOMUX_PAD(0x073C, 0x0354, 7, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_CMD__USDHC2_CMD		= IOMUX_PAD(0x0740, 0x0358, 16, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_CMD__ECSPI5_MOSI		= IOMUX_PAD(0x0740, 0x0358, 1, 0x0830, 1, 0),
-	MX6Q_PAD_SD2_CMD__KPP_ROW_5		= IOMUX_PAD(0x0740, 0x0358, 2, 0x08F4, 2, 0),
-	MX6Q_PAD_SD2_CMD__AUDMUX_AUD4_RXC	= IOMUX_PAD(0x0740, 0x0358, 3, 0x07BC, 1, 0),
-	MX6Q_PAD_SD2_CMD__PCIE_CTRL_MUX_10	= IOMUX_PAD(0x0740, 0x0358, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_CMD__GPIO_1_11		= IOMUX_PAD(0x0740, 0x0358, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT3__USDHC2_DAT3		= IOMUX_PAD(0x0744, 0x035C, 0, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT3__ECSPI5_SS3		= IOMUX_PAD(0x0744, 0x035C, 1, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT3__KPP_COL_6		= IOMUX_PAD(0x0744, 0x035C, 2, 0x08EC, 2, 0),
-	MX6Q_PAD_SD2_DAT3__AUDMUX_AUD4_TXC	= IOMUX_PAD(0x0744, 0x035C, 3, 0x07C4, 1, 0),
-	MX6Q_PAD_SD2_DAT3__PCIE_CTRL_MUX_11	= IOMUX_PAD(0x0744, 0x035C, 4, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT3__GPIO_1_12		= IOMUX_PAD(0x0744, 0x035C, 5, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT3__SJC_DONE		= IOMUX_PAD(0x0744, 0x035C, 6, 0x0000, 0, 0),
-	MX6Q_PAD_SD2_DAT3__ANATOP_TESTO_3	= IOMUX_PAD(0x0744, 0x035C, 7, 0x0000, 0, 0),
-};
-
diff --git a/libethdrivers/src/plat/imx6/uboot/mxc_gpio.c b/libethdrivers/src/plat/imx6/uboot/mxc_gpio.c
index 21780b8..1339050 100644
--- a/libethdrivers/src/plat/imx6/uboot/mxc_gpio.c
+++ b/libethdrivers/src/plat/imx6/uboot/mxc_gpio.c
@@ -1,16 +1,11 @@
 /*
- * @TAG(OTHER_GPL)
- */
-
-/*
- * Copyright (C) 2009
- * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ * Copyright (C) 2009 Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
+ * Copyright (C) 2011 Stefano Babic, DENX Software Engineering, <sbabic@denx.de>
+ * Copyright (C) 2020, HENSOLDT Cyber GmbH
  *
- * Copyright (C) 2011
- * Stefano Babic, DENX Software Engineering, <sbabic@denx.de>
+ * See U-Boot file CREDITS for list of people who contributed to this project.
  *
- * See file CREDITS for list of people who contributed to this
- * project.
+ * SPDX-License-Identifier: GPL-2.0-or-later
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -27,11 +22,11 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
  */
+
 #include "common.h"
 #include "imx-regs.h"
 #include "gpio.h"
 #include "../io.h"
-#include "../unimplemented.h"
 
 enum mxc_gpio_direction {
     MXC_GPIO_DIRECTION_IN,
@@ -44,7 +39,8 @@
 
 /* GPIO port description */
 
-#ifdef CONFIG_PLAT_IMX6
+#if defined(CONFIG_PLAT_IMX6)
+
 static unsigned long gpio_ports[] = {
     [0] = 0,
     [1] = 0,
@@ -64,8 +60,9 @@
     [5] = GPIO6_BASE_ADDR,
     [6] = GPIO7_BASE_ADDR,
 };
-#endif
-#ifdef CONFIG_PLAT_IMX8MQ_EVK
+
+#elif defined(CONFIG_PLAT_IMX8MQ_EVK)
+
 static unsigned long gpio_ports[] = {
     [0] = 0,
     [1] = 0,
@@ -81,8 +78,12 @@
     [3] = 0x30230000,
     [4] = 0x30240000,
 };
+
+#else
+#error "unknown i.MX SOC"
 #endif
 
+
 static int mxc_gpio_direction(unsigned int gpio,
                               enum mxc_gpio_direction direction, ps_io_ops_t *io_ops)
 {
@@ -91,6 +92,7 @@
     uint32_t l;
 
     if (port >= ARRAY_SIZE(gpio_ports)) {
+        ZF_LOGE("invalid GPIO port %u for pin %u", port, gpio);
         return -1;
     }
 
@@ -100,7 +102,8 @@
         uintptr_t gpio_phys = (uintptr_t)gpio_paddr[port];
         gpio_ports[port] = (unsigned long)ps_io_map(&io_ops->io_mapper, gpio_phys, GPIO_SIZE, 0, PS_MEM_NORMAL);
         if (gpio_ports[port] == 0) {
-            LOG_ERROR("Warning: No map for GPIO %d. Assuming that it is already configured\n", port);
+            ZF_LOGE("No mapping for GPIO port %u of pin %u. Assuming it's already configured",
+                    port, gpio);
             return 0;
         }
     }
@@ -127,6 +130,7 @@
     uint32_t l;
 
     if (port >= ARRAY_SIZE(gpio_ports)) {
+        ZF_LOGE("invalid GPIO port %u for pin %u", port, gpio);
         return -1;
     }
 
@@ -152,6 +156,7 @@
     uint32_t val;
 
     if (port >= ARRAY_SIZE(gpio_ports)) {
+        ZF_LOGE("invalid GPIO port %u for pin %u", port, gpio);
         return -1;
     }
 
@@ -168,6 +173,7 @@
 {
     unsigned int port = GPIO_TO_PORT(gpio);
     if (port >= ARRAY_SIZE(gpio_ports)) {
+        ZF_LOGE("invalid GPIO port %u for pin %u", port, gpio);
         return -1;
     }
     return 0;
@@ -188,6 +194,8 @@
     int ret = mxc_gpio_direction(gpio, MXC_GPIO_DIRECTION_OUT, io_ops);
 
     if (ret < 0) {
+        ZF_LOGE("Could not set output direction for pin %u, code %u",
+                gpio, ret);
         return ret;
     }
 
diff --git a/libethdrivers/src/plat/imx6/uboot/phy.c b/libethdrivers/src/plat/imx6/uboot/phy.c
index 2b00bb5..f837d93 100644
--- a/libethdrivers/src/plat/imx6/uboot/phy.c
+++ b/libethdrivers/src/plat/imx6/uboot/phy.c
@@ -1,9 +1,12 @@
 /*
- * @TAG(OTHER_GPL)
- */
-
-/*
  * Generic PHY Management code
+ * Based loosely off of Linux's PHY Lib
+ *
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * author Andy Fleming
+ * Copyright 2020, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -19,24 +22,15 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  * MA 02111-1307 USA
- *
- *
- * Copyright 2011 Freescale Semiconductor, Inc.
- * author Andy Fleming
- *
- * Based loosely off of Linux's PHY Lib
  */
 
-#include <stdlib.h>
-#include "config.h"
 #include "common.h"
 #include "fec_mxc.h"
 #include "miiphy.h"
 #include "phy.h"
+#include <stdlib.h>
+#include <string.h>
 #include <errno.h>
-#include "bitops.h"
-#include "../unimplemented.h"
-#include "string.h"
 
 /* Generic PHY support and helper functions */
 
@@ -51,69 +45,81 @@
  */
 static int genphy_config_advert(struct phy_device *phydev)
 {
-	u32 advertise;
-	int oldadv, adv;
-	int err, changed = 0;
+    u32 advertise;
+    int oldadv, adv;
+    int err, changed = 0;
 
-	/* Only allow advertising what
-	 * this PHY supports */
-	phydev->advertising &= phydev->supported;
-	advertise = phydev->advertising;
+    /* Only allow advertising what
+     * this PHY supports */
+    phydev->advertising &= phydev->supported;
+    advertise = phydev->advertising;
 
-	/* Setup standard advertisement */
-	oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
+    /* Setup standard advertisement */
+    oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
 
-	if (adv < 0)
-		return adv;
+    if (adv < 0) {
+        return adv;
+    }
 
-	adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
-		 ADVERTISE_PAUSE_ASYM);
-	if (advertise & ADVERTISED_10baseT_Half)
-		adv |= ADVERTISE_10HALF;
-	if (advertise & ADVERTISED_10baseT_Full)
-		adv |= ADVERTISE_10FULL;
-	if (advertise & ADVERTISED_100baseT_Half)
-		adv |= ADVERTISE_100HALF;
-	if (advertise & ADVERTISED_100baseT_Full)
-		adv |= ADVERTISE_100FULL;
-	if (advertise & ADVERTISED_Pause)
-		adv |= ADVERTISE_PAUSE_CAP;
-	if (advertise & ADVERTISED_Asym_Pause)
-		adv |= ADVERTISE_PAUSE_ASYM;
+    adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
+             ADVERTISE_PAUSE_ASYM);
+    if (advertise & ADVERTISED_10baseT_Half) {
+        adv |= ADVERTISE_10HALF;
+    }
+    if (advertise & ADVERTISED_10baseT_Full) {
+        adv |= ADVERTISE_10FULL;
+    }
+    if (advertise & ADVERTISED_100baseT_Half) {
+        adv |= ADVERTISE_100HALF;
+    }
+    if (advertise & ADVERTISED_100baseT_Full) {
+        adv |= ADVERTISE_100FULL;
+    }
+    if (advertise & ADVERTISED_Pause) {
+        adv |= ADVERTISE_PAUSE_CAP;
+    }
+    if (advertise & ADVERTISED_Asym_Pause) {
+        adv |= ADVERTISE_PAUSE_ASYM;
+    }
 
-	if (adv != oldadv) {
-		err = phy_write(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE, adv);
+    if (adv != oldadv) {
+        err = phy_write(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE, adv);
 
-		if (err < 0)
-			return err;
-		changed = 1;
-	}
+        if (err < 0) {
+            return err;
+        }
+        changed = 1;
+    }
 
-	/* Configure gigabit if it's supported */
-	if (phydev->supported & (SUPPORTED_1000baseT_Half |
-				SUPPORTED_1000baseT_Full)) {
-		oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
+    /* Configure gigabit if it's supported */
+    if (phydev->supported & (SUPPORTED_1000baseT_Half |
+                             SUPPORTED_1000baseT_Full)) {
+        oldadv = adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
 
-		if (adv < 0)
-			return adv;
+        if (adv < 0) {
+            return adv;
+        }
 
-		adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
-		if (advertise & SUPPORTED_1000baseT_Half)
-			adv |= ADVERTISE_1000HALF;
-		if (advertise & SUPPORTED_1000baseT_Full)
-			adv |= ADVERTISE_1000FULL;
+        adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
+        if (advertise & SUPPORTED_1000baseT_Half) {
+            adv |= ADVERTISE_1000HALF;
+        }
+        if (advertise & SUPPORTED_1000baseT_Full) {
+            adv |= ADVERTISE_1000FULL;
+        }
 
-		if (adv != oldadv) {
-			err = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000,
-					adv);
+        if (adv != oldadv) {
+            err = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000,
+                            adv);
 
-			if (err < 0)
-				return err;
-			changed = 1;
-		}
-	}
+            if (err < 0) {
+                return err;
+            }
+            changed = 1;
+        }
+    }
 
-	return changed;
+    return changed;
 }
 
 /**
@@ -125,22 +131,24 @@
  */
 static int genphy_setup_forced(struct phy_device *phydev)
 {
-	int err;
-	int ctl = 0;
+    int err;
+    int ctl = 0;
 
-	phydev->pause = phydev->asym_pause = 0;
+    phydev->pause = phydev->asym_pause = 0;
 
-	if (SPEED_1000 == phydev->speed)
-		ctl |= BMCR_SPEED1000;
-	else if (SPEED_100 == phydev->speed)
-		ctl |= BMCR_SPEED100;
+    if (SPEED_1000 == phydev->speed) {
+        ctl |= BMCR_SPEED1000;
+    } else if (SPEED_100 == phydev->speed) {
+        ctl |= BMCR_SPEED100;
+    }
 
-	if (DUPLEX_FULL == phydev->duplex)
-		ctl |= BMCR_FULLDPLX;
+    if (DUPLEX_FULL == phydev->duplex) {
+        ctl |= BMCR_FULLDPLX;
+    }
 
-	err = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
+    err = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
 
-	return err;
+    return err;
 }
 
 /**
@@ -149,21 +157,22 @@
  */
 int genphy_restart_aneg(struct phy_device *phydev)
 {
-	int ctl;
+    int ctl;
 
-	ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+    ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
 
-	if (ctl < 0)
-		return ctl;
+    if (ctl < 0) {
+        return ctl;
+    }
 
-	ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
+    ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
 
-	/* Don't isolate the PHY if we're negotiating */
-	ctl &= ~(BMCR_ISOLATE);
+    /* Don't isolate the PHY if we're negotiating */
+    ctl &= ~(BMCR_ISOLATE);
 
-	ctl = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
+    ctl = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
 
-	return ctl;
+    return ctl;
 }
 
 /**
@@ -176,34 +185,39 @@
  */
 int genphy_config_aneg(struct phy_device *phydev)
 {
-	int result;
+    int result;
 
-	if (AUTONEG_ENABLE != phydev->autoneg)
-		return genphy_setup_forced(phydev);
+    if (AUTONEG_ENABLE != phydev->autoneg) {
+        return genphy_setup_forced(phydev);
+    }
 
-	result = genphy_config_advert(phydev);
+    result = genphy_config_advert(phydev);
 
-	if (result < 0) /* error */
-		return result;
+    if (result < 0) { /* error */
+        return result;
+    }
 
-	if (result == 0) {
-		/* Advertisment hasn't changed, but maybe aneg was never on to
-		 * begin with?  Or maybe phy was isolated? */
-		int ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+    if (result == 0) {
+        /* Advertisment hasn't changed, but maybe aneg was never on to
+         * begin with?  Or maybe phy was isolated? */
+        int ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
 
-		if (ctl < 0)
-			return ctl;
+        if (ctl < 0) {
+            return ctl;
+        }
 
-		if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE))
-			result = 1; /* do restart aneg */
-	}
+        if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE)) {
+            result = 1;    /* do restart aneg */
+        }
+    }
 
-	/* Only restart aneg if we are advertising something different
-	 * than we were before.	 */
-	if (result > 0)
-		result = genphy_restart_aneg(phydev);
+    /* Only restart aneg if we are advertising something different
+     * than we were before.  */
+    if (result > 0) {
+        result = genphy_restart_aneg(phydev);
+    }
 
-	return result;
+    return result;
 }
 
 /**
@@ -216,57 +230,63 @@
  */
 int genphy_update_link(struct phy_device *phydev)
 {
-	unsigned int mii_reg;
+    unsigned int mii_reg;
 
-	/*
-	 * Wait if the link is up, and autonegotiation is in progress
-	 * (ie - we're capable and it's not done)
-	 */
-	mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+    /*
+     * Wait if the link is up, and autonegotiation is in progress
+     * (ie - we're capable and it's not done)
+     */
+    mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
 
-	/*
-	 * If we already saw the link up, and it hasn't gone down, then
-	 * we don't need to wait for autoneg again
-	 */
-	if (phydev->link && mii_reg & BMSR_LSTATUS)
-		return 0;
+    /*
+     * If we already saw the link up, and it hasn't gone down, then
+     * we don't need to wait for autoneg again
+     */
+    if (phydev->link && mii_reg & BMSR_LSTATUS) {
+        ZF_LOGI("link already established");
+        return 0;
+    }
 
-	if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {
-		int i = 0;
+    if ((mii_reg & BMSR_ANEGCAPABLE) && !(mii_reg & BMSR_ANEGCOMPLETE)) {
+        int i = 0;
 
-		printf("%s Waiting for PHY auto negotiation to complete", phydev->dev->name);
+        ZF_LOGI(
+            "waiting for auto negotiation to complete on phy %d, '%s'",
+            phydev->addr, phydev->dev->name);
         fflush(stdout);
-		while (!(mii_reg & BMSR_ANEGCOMPLETE)) {
-			/*
-			 * Timeout reached ?
-			 */
-			if (i > PHY_ANEG_TIMEOUT) {
-				printf(" TIMEOUT !\n");
-				phydev->link = 0;
-				return 0;
-			}
+        while (!(mii_reg & BMSR_ANEGCOMPLETE)) {
+            /*
+             * Timeout reached ?
+             */
+            if (i > PHY_ANEG_TIMEOUT) {
+                ZF_LOGE("auto negotiation timeout");
+                phydev->link = 0;
+                return 0;
+            }
 
-			if ((i++ % 500) == 0){
-				printf(".");
+            if ((i++ % 500) == 0) {
+                printf(".");
                 fflush(stdout);
             }
 
-			udelay(1000);	/* 1 ms */
-			mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
-		}
-		printf(" done\n");
-		phydev->link = 1;
-	} else {
-		/* Read the link a second time to clear the latched state */
-		mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+            udelay(1000);   /* 1 ms */
+            mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+        }
+        ZF_LOGI("auto negotiation complete on phy %d, '%s'",
+                phydev->addr, phydev->dev->name);
+        phydev->link = 1;
+    } else {
+        /* Read the link a second time to clear the latched state */
+        mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
 
-		if (mii_reg & BMSR_LSTATUS)
-			phydev->link = 1;
-		else
-			phydev->link = 0;
-	}
+        if (mii_reg & BMSR_LSTATUS) {
+            phydev->link = 1;
+        } else {
+            phydev->link = 0;
+        }
+    }
 
-	return 0;
+    return 0;
 }
 
 /*
@@ -280,139 +300,153 @@
  */
 static int genphy_parse_link(struct phy_device *phydev)
 {
-	int mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+    int mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
 
-	/* We're using autonegotiation */
-	if (mii_reg & BMSR_ANEGCAPABLE) {
-		u32 lpa = 0;
-		u32 gblpa = 0;
+    /* We're using autonegotiation */
+    if (mii_reg & BMSR_ANEGCAPABLE) {
+        u32 lpa = 0;
+        u32 gblpa = 0;
 
-		/* Check for gigabit capability */
-		if (mii_reg & BMSR_ERCAP) {
-			/* We want a list of states supported by
-			 * both PHYs in the link
-			 */
-			gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
-			gblpa &= phy_read(phydev,
-					MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
-		}
+        /* Check for gigabit capability */
+        if (mii_reg & BMSR_ERCAP) {
+            /* We want a list of states supported by
+             * both PHYs in the link
+             */
+            gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
+            gblpa &= phy_read(phydev,
+                              MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
+        }
 
-		/* Set the baseline so we only have to set them
-		 * if they're different
-		 */
-		phydev->speed = SPEED_10;
-		phydev->duplex = DUPLEX_HALF;
+        /* Set the baseline so we only have to set them
+         * if they're different
+         */
+        phydev->speed = SPEED_10;
+        phydev->duplex = DUPLEX_HALF;
 
-		/* Check the gigabit fields */
-		if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
-			phydev->speed = SPEED_1000;
+        /* Check the gigabit fields */
+        if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
+            phydev->speed = SPEED_1000;
 
-			if (gblpa & PHY_1000BTSR_1000FD)
-				phydev->duplex = DUPLEX_FULL;
+            if (gblpa & PHY_1000BTSR_1000FD) {
+                phydev->duplex = DUPLEX_FULL;
+            }
 
-			/* We're done! */
-			return 0;
-		}
+            /* We're done! */
+            return 0;
+        }
 
-		lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
-		lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
+        lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
+        lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
 
-		if (lpa & (LPA_100FULL | LPA_100HALF)) {
-			phydev->speed = SPEED_100;
+        if (lpa & (LPA_100FULL | LPA_100HALF)) {
+            phydev->speed = SPEED_100;
 
-			if (lpa & LPA_100FULL)
-				phydev->duplex = DUPLEX_FULL;
+            if (lpa & LPA_100FULL) {
+                phydev->duplex = DUPLEX_FULL;
+            }
 
-		} else if (lpa & LPA_10FULL)
-			phydev->duplex = DUPLEX_FULL;
-	} else {
-		u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+        } else if (lpa & LPA_10FULL) {
+            phydev->duplex = DUPLEX_FULL;
+        }
+    } else {
+        u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
 
-		phydev->speed = SPEED_10;
-		phydev->duplex = DUPLEX_HALF;
+        phydev->speed = SPEED_10;
+        phydev->duplex = DUPLEX_HALF;
 
-		if (bmcr & BMCR_FULLDPLX)
-			phydev->duplex = DUPLEX_FULL;
+        if (bmcr & BMCR_FULLDPLX) {
+            phydev->duplex = DUPLEX_FULL;
+        }
 
-		if (bmcr & BMCR_SPEED1000)
-			phydev->speed = SPEED_1000;
-		else if (bmcr & BMCR_SPEED100)
-			phydev->speed = SPEED_100;
-	}
+        if (bmcr & BMCR_SPEED1000) {
+            phydev->speed = SPEED_1000;
+        } else if (bmcr & BMCR_SPEED100) {
+            phydev->speed = SPEED_100;
+        }
+    }
 
-	return 0;
+    return 0;
 }
 
 int genphy_config(struct phy_device *phydev)
 {
-	int val;
-	u32 features;
+    int val;
+    u32 features;
 
-	/* For now, I'll claim that the generic driver supports
-	 * all possible port types */
-	features = (SUPPORTED_TP | SUPPORTED_MII
-			| SUPPORTED_AUI | SUPPORTED_FIBRE |
-			SUPPORTED_BNC);
+    /* For now, I'll claim that the generic driver supports
+     * all possible port types */
+    features = (SUPPORTED_TP | SUPPORTED_MII
+                | SUPPORTED_AUI | SUPPORTED_FIBRE |
+                SUPPORTED_BNC);
 
-	/* Do we support autonegotiation? */
-	val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+    /* Do we support autonegotiation? */
+    val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
 
-	if (val < 0)
-		return val;
+    if (val < 0) {
+        return val;
+    }
 
-	if (val & BMSR_ANEGCAPABLE)
-		features |= SUPPORTED_Autoneg;
+    if (val & BMSR_ANEGCAPABLE) {
+        features |= SUPPORTED_Autoneg;
+    }
 
-	if (val & BMSR_100FULL)
-		features |= SUPPORTED_100baseT_Full;
-	if (val & BMSR_100HALF)
-		features |= SUPPORTED_100baseT_Half;
-	if (val & BMSR_10FULL)
-		features |= SUPPORTED_10baseT_Full;
-	if (val & BMSR_10HALF)
-		features |= SUPPORTED_10baseT_Half;
+    if (val & BMSR_100FULL) {
+        features |= SUPPORTED_100baseT_Full;
+    }
+    if (val & BMSR_100HALF) {
+        features |= SUPPORTED_100baseT_Half;
+    }
+    if (val & BMSR_10FULL) {
+        features |= SUPPORTED_10baseT_Full;
+    }
+    if (val & BMSR_10HALF) {
+        features |= SUPPORTED_10baseT_Half;
+    }
 
-	if (val & BMSR_ESTATEN) {
-		val = phy_read(phydev, MDIO_DEVAD_NONE, MII_ESTATUS);
+    if (val & BMSR_ESTATEN) {
+        val = phy_read(phydev, MDIO_DEVAD_NONE, MII_ESTATUS);
 
-		if (val < 0)
-			return val;
+        if (val < 0) {
+            return val;
+        }
 
-		if (val & ESTATUS_1000_TFULL)
-			features |= SUPPORTED_1000baseT_Full;
-		if (val & ESTATUS_1000_THALF)
-			features |= SUPPORTED_1000baseT_Half;
-	}
+        if (val & ESTATUS_1000_TFULL) {
+            features |= SUPPORTED_1000baseT_Full;
+        }
+        if (val & ESTATUS_1000_THALF) {
+            features |= SUPPORTED_1000baseT_Half;
+        }
+    }
 
-	phydev->supported = features;
-	phydev->advertising = features;
+    phydev->supported = features;
+    phydev->advertising = features;
 
-	genphy_config_aneg(phydev);
+    genphy_config_aneg(phydev);
 
-	return 0;
+    return 0;
 }
 
 int genphy_startup(struct phy_device *phydev)
 {
-	genphy_update_link(phydev);
-	genphy_parse_link(phydev);
+    genphy_update_link(phydev);
+    genphy_parse_link(phydev);
 
-	return 0;
+    return 0;
 }
 
 int genphy_shutdown(struct phy_device *phydev)
 {
-	return 0;
+    return 0;
 }
 
 static struct phy_driver genphy_driver = {
-	.uid		= 0xffffffff,
-	.mask		= 0xffffffff,
-	.name		= "Generic PHY",
-	.features	= 0,
-	.config		= genphy_config,
-	.startup	= genphy_startup,
-	.shutdown	= genphy_shutdown,
+    .uid        = 0xffffffff,
+    .mask       = 0xffffffff,
+    .name       = "Generic PHY",
+    .features   = 0,
+    .config     = genphy_config,
+    .startup    = genphy_startup,
+    .shutdown   = genphy_shutdown,
 };
 
 struct list_head phy_drivers = { &phy_drivers, &phy_drivers };
@@ -421,85 +455,87 @@
 {
     drv->list.next = &drv->list;
     drv->list.prev = &drv->list;
-	list_add_tail(&drv->list, &phy_drivers);
+    list_add_tail(&drv->list, &phy_drivers);
 
-	return 0;
+    return 0;
 }
 
 static int phy_probe(struct phy_device *phydev)
 {
-	int err = 0;
+    int err = 0;
 
-	phydev->advertising = phydev->supported = phydev->drv->features;
-	phydev->mmds = phydev->drv->mmds;
+    phydev->advertising = phydev->supported = phydev->drv->features;
+    phydev->mmds = phydev->drv->mmds;
 
-	if (phydev->drv->probe)
-		err = phydev->drv->probe(phydev);
+    if (phydev->drv->probe) {
+        err = phydev->drv->probe(phydev);
+    }
 
-	return err;
+    return err;
 }
 
 static struct phy_driver *generic_for_interface(phy_interface_t interface)
 {
 #ifdef CONFIG_PHYLIB_10G
-	if (is_10g_interface(interface))
-		return &gen10g_driver;
+    if (is_10g_interface(interface)) {
+        return &gen10g_driver;
+    }
 #endif
 
-	return &genphy_driver;
+    return &genphy_driver;
 }
 
 static struct phy_driver *get_phy_driver(struct phy_device *phydev,
-				phy_interface_t interface)
+                                         phy_interface_t interface)
 {
-	struct list_head *entry;
-	int phy_id = phydev->phy_id;
-	struct phy_driver *drv = NULL;
+    struct list_head *entry;
+    int phy_id = phydev->phy_id;
+    struct phy_driver *drv = NULL;
 
-	list_for_each(entry, &phy_drivers) {
-		drv = list_entry(entry, struct phy_driver, list);
-		if ((drv->uid & drv->mask) == (phy_id & drv->mask))
-			return drv;
-	}
+    list_for_each(entry, &phy_drivers) {
+        drv = list_entry(entry, struct phy_driver, list);
+        if ((drv->uid & drv->mask) == (phy_id & drv->mask)) {
+            return drv;
+        }
+    }
 
-	/* If we made it here, there's no driver for this PHY */
-	return generic_for_interface(interface);
+    /* If we made it here, there's no driver for this PHY */
+    return generic_for_interface(interface);
 }
 
 static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
-					    int phy_id,
-					    phy_interface_t interface)
+                                            int phy_id,
+                                            phy_interface_t interface)
 {
-	struct phy_device *dev;
+    struct phy_device *dev;
 
-	/* We allocate the device, and initialize the
-	 * default values */
-	dev = malloc(sizeof(*dev));
-	if (!dev) {
-		printf("Failed to allocate PHY device for %s:%d\n",
-			bus->name, addr);
-		return NULL;
-	}
+    /* We allocate the device, and initialize the
+     * default values */
+    dev = malloc(sizeof(*dev));
+    if (!dev) {
+        ZF_LOGE("Failed to allocate PHY device for '%s':%d", bus->name, addr);
+        return NULL;
+    }
 
-	memset(dev, 0, sizeof(*dev));
+    memset(dev, 0, sizeof(*dev));
 
-	dev->duplex = -1;
-	dev->link = 1;
-	dev->interface = interface;
+    dev->duplex = -1;
+    dev->link = 1;
+    dev->interface = interface;
 
-	dev->autoneg = AUTONEG_ENABLE;
+    dev->autoneg = AUTONEG_ENABLE;
 
-	dev->addr = addr;
-	dev->phy_id = phy_id;
-	dev->bus = bus;
+    dev->addr = addr;
+    dev->phy_id = phy_id;
+    dev->bus = bus;
 
-	dev->drv = get_phy_driver(dev, interface);
+    dev->drv = get_phy_driver(dev, interface);
 
-	phy_probe(dev);
+    phy_probe(dev);
 
-	bus->phymap[addr] = dev;
+    bus->phymap[addr] = dev;
 
-	return dev;
+    return dev;
 }
 
 /**
@@ -513,80 +549,85 @@
  */
 static int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
 {
-	int phy_reg;
+    int phy_reg;
 
-	/* Grab the bits from PHYIR1, and put them
-	 * in the upper half */
-	phy_reg = bus->read(bus, addr, devad, MII_PHYSID1);
+    /* Grab the bits from PHYIR1, and put them
+     * in the upper half */
+    phy_reg = bus->read(bus, addr, devad, MII_PHYSID1);
 
-	if (phy_reg < 0)
-		return -EIO;
+    if (phy_reg < 0) {
+        ZF_LOGE("read MII_PHYSID1 failed, code %d", phy_reg);
+        return -EIO;
+    }
 
-	*phy_id = (phy_reg & 0xffff) << 16;
+    *phy_id = (phy_reg & 0xffff) << 16;
 
-	/* Grab the bits from PHYIR2, and put them in the lower half */
-	phy_reg = bus->read(bus, addr, devad, MII_PHYSID2);
+    /* Grab the bits from PHYIR2, and put them in the lower half */
+    phy_reg = bus->read(bus, addr, devad, MII_PHYSID2);
 
-	if (phy_reg < 0)
-		return -EIO;
+    if (phy_reg < 0) {
+        ZF_LOGE("read MII_PHYSID2 failed, code %d", phy_reg);
+        return -EIO;
+    }
 
-	*phy_id |= (phy_reg & 0xffff);
+    *phy_id |= (phy_reg & 0xffff);
 
-	return 0;
+    return 0;
 }
 
 static struct phy_device *create_phy_by_mask(struct mii_dev *bus,
-		unsigned phy_mask, int devad, phy_interface_t interface)
+                                             unsigned phy_mask, int devad, phy_interface_t interface)
 {
-	u32 phy_id = 0xffffffff;
-	while (phy_mask) {
-		int addr = ffs(phy_mask) - 1;
-		int r = get_phy_id(bus, addr, devad, &phy_id);
-		if (r < 0)
-			return (void*)r;
-		/* If the PHY ID is mostly f's, we didn't find anything */
-		if ((phy_id & 0x1fffffff) != 0x1fffffff)
-			return phy_device_create(bus, addr, phy_id, interface);
-		phy_mask &= ~(BIT(addr));
-	}
-	return NULL;
+    u32 phy_id = 0xffffffff;
+    while (phy_mask) {
+        int addr = ffs(phy_mask) - 1;
+        int r = get_phy_id(bus, addr, devad, &phy_id);
+        if (r < 0) {
+            ZF_LOGE("Failed to get PHY ID, code %d", r);
+            return NULL;
+        }
+        /* If the PHY ID is mostly f's, we didn't find anything */
+        if ((phy_id & 0x1fffffff) != 0x1fffffff) {
+            return phy_device_create(bus, addr, phy_id, interface);
+        }
+        phy_mask &= ~(BIT(addr));
+    }
+    ZF_LOGE("Failed to create PHY by mask");
+    return NULL;
 }
 
 static struct phy_device *search_for_existing_phy(struct mii_dev *bus,
-		unsigned phy_mask, phy_interface_t interface)
+                                                  unsigned phy_mask, phy_interface_t interface)
 {
-	/* If we have one, return the existing device, with new interface */
-	while (phy_mask) {
-		int addr = ffs(phy_mask) - 1;
-		if (bus->phymap[addr]) {
-			bus->phymap[addr]->interface = interface;
-			return bus->phymap[addr];
-		}
-		phy_mask &= ~(BIT(addr));
-	}
-	return NULL;
+    /* If we have one, return the existing device, with new interface */
+    while (phy_mask) {
+        int addr = ffs(phy_mask) - 1;
+        if (bus->phymap[addr]) {
+            bus->phymap[addr]->interface = interface;
+            return bus->phymap[addr];
+        }
+        phy_mask &= ~(BIT(addr));
+    }
+    return NULL;
 }
 
 static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
-		unsigned phy_mask, phy_interface_t interface)
+                                                 unsigned phy_mask, phy_interface_t interface)
 {
-	int i;
-	struct phy_device *phydev;
-
-	phydev = search_for_existing_phy(bus, phy_mask, interface);
-	if (phydev)
-		return phydev;
-	/* Try Standard (ie Clause 22) access */
-	/* Otherwise we have to try Clause 45 */
-	for (i = 0; i < 5; i++) {
-		phydev = create_phy_by_mask(bus, phy_mask, i ? i : MDIO_DEVAD_NONE, interface);
-		if ((unsigned long)phydev >= (unsigned long)-4096)
-			return NULL;
-		if (phydev)
-			return phydev;
-	}
-	printf("Phy not found\n");
-	return phy_device_create(bus, ffs(phy_mask) - 1, 0xffffffff, interface);
+    struct phy_device *phydev = search_for_existing_phy(bus, phy_mask, interface);
+    if (phydev) {
+        return phydev;
+    }
+    /* Try Standard (ie Clause 22) access */
+    /* Otherwise we have to try Clause 45 */
+    for (unsigned int i = 0; i < 5; i++) {
+        phydev = create_phy_by_mask(bus, phy_mask, i ? i : MDIO_DEVAD_NONE, interface);
+        if (phydev) {
+            return phydev;
+        }
+    }
+    ZF_LOGE("PHY not found");
+    return phy_device_create(bus, ffs(phy_mask) - 1, 0xffffffff, interface);
 }
 
 /**
@@ -598,128 +639,132 @@
  *   @bus, then allocates and returns the phy_device to represent it.
  */
 static struct phy_device *get_phy_device(struct mii_dev *bus, int addr,
-					 phy_interface_t interface)
+                                         phy_interface_t interface)
 {
-	return get_phy_device_by_mask(bus, BIT(addr), interface);
+    return get_phy_device_by_mask(bus, BIT(addr), interface);
 }
 
 int phy_reset(struct phy_device *phydev)
 {
-	int reg;
-	int timeout = 500;
-	int devad = MDIO_DEVAD_NONE;
+    int reg;
+    int timeout = 500;
+    int devad = MDIO_DEVAD_NONE;
 
 #ifdef CONFIG_PHYLIB_10G
-	/* If it's 10G, we need to issue reset through one of the MMDs */
-	if (is_10g_interface(phydev->interface)) {
-		if (!phydev->mmds)
-			gen10g_discover_mmds(phydev);
+    /* If it's 10G, we need to issue reset through one of the MMDs */
+    if (is_10g_interface(phydev->interface)) {
+        if (!phydev->mmds) {
+            gen10g_discover_mmds(phydev);
+        }
 
-		devad = ffs(phydev->mmds) - 1;
-	}
+        devad = ffs(phydev->mmds) - 1;
+    }
 #endif
 
-	reg = phy_read(phydev, devad, MII_BMCR);
-	if (reg < 0) {
-		debug("PHY status read failed\n");
-		return -1;
-	}
+    reg = phy_read(phydev, devad, MII_BMCR);
+    if (reg < 0) {
+        ZF_LOGE("PHY status read failed");
+        return -1;
+    }
 
-	reg |= BMCR_RESET;
+    reg |= BMCR_RESET;
 
-	if (phy_write(phydev, devad, MII_BMCR, reg) < 0) {
-		debug("PHY reset failed\n");
-		return -1;
-	}
+    if (phy_write(phydev, devad, MII_BMCR, reg) < 0) {
+        ZF_LOGE("PHY reset failed");
+        return -1;
+    }
 
 #ifdef CONFIG_PHY_RESET_DELAY
-	udelay(CONFIG_PHY_RESET_DELAY);	/* Intel LXT971A needs this */
+    udelay(CONFIG_PHY_RESET_DELAY); /* Intel LXT971A needs this */
 #endif
-	/*
-	 * Poll the control register for the reset bit to go to 0 (it is
-	 * auto-clearing).  This should happen within 0.5 seconds per the
-	 * IEEE spec.
-	 */
-	while ((reg & BMCR_RESET) && timeout--) {
-		reg = phy_read(phydev, devad, MII_BMCR);
+    /*
+     * Poll the control register for the reset bit to go to 0 (it is
+     * auto-clearing).  This should happen within 0.5 seconds per the
+     * IEEE spec.
+     */
+    while ((reg & BMCR_RESET) && timeout--) {
+        reg = phy_read(phydev, devad, MII_BMCR);
 
-		if (reg < 0) {
-			debug("PHY status read failed\n");
-			return -1;
-		}
-		udelay(1000);
-	}
+        if (reg < 0) {
+            ZF_LOGE("PHY status read failed");
+            return -1;
+        }
+        udelay(1000);
+    }
 
-	if (reg & BMCR_RESET) {
-		puts("PHY reset timed out\n");
-		return -1;
-	}
+    if (reg & BMCR_RESET) {
+        ZF_LOGE("PHY reset timed out");
+        return -1;
+    }
 
-	return 0;
+    return 0;
 }
 
 int miiphy_reset(const char *devname, unsigned char addr)
 {
-	struct mii_dev *bus = miiphy_get_dev_by_name(devname);
-	struct phy_device *phydev;
+    struct mii_dev *bus = miiphy_get_dev_by_name(devname);
+    struct phy_device *phydev;
 
-	/*
-	 * miiphy_reset was only used on standard PHYs, so we'll fake it here.
-	 * If later code tries to connect with the right interface, this will
-	 * be corrected by get_phy_device in phy_connect()
-	 */
-	phydev = get_phy_device(bus, addr, PHY_INTERFACE_MODE_MII);
+    /*
+     * miiphy_reset was only used on standard PHYs, so we'll fake it here.
+     * If later code tries to connect with the right interface, this will
+     * be corrected by get_phy_device in phy_connect()
+     */
+    phydev = get_phy_device(bus, addr, PHY_INTERFACE_MODE_MII);
 
-	return phy_reset(phydev);
+    return phy_reset(phydev);
 }
 
 struct phy_device *phy_connect_by_mask(struct mii_dev *bus, unsigned phy_mask,
-		struct eth_device *dev, phy_interface_t interface)
+                                       struct eth_device *dev, phy_interface_t interface)
 {
-	struct phy_device *phydev;
+    struct phy_device *phydev;
 
-	/* Reset the bus */
-	if (bus->reset)
-		bus->reset(bus);
+    /* Reset the bus */
+    if (bus->reset) {
+        bus->reset(bus);
+    }
 
-	/* Wait 15ms to make sure the PHY has come out of hard reset */
-	udelay(15000);
+    /* Wait 15ms to make sure the PHY has come out of hard reset */
+    udelay(15000);
 
-	phydev = get_phy_device_by_mask(bus, phy_mask, interface);
+    phydev = get_phy_device_by_mask(bus, phy_mask, interface);
 
-	if (!phydev) {
-		printf("Could not get PHY for %s: phy mask %x\n",
-				bus->name, phy_mask);
-		return NULL;
-	}
+    if (!phydev) {
+        ZF_LOGE("Could not get PHY for '%s' phy mask 0x%x",
+                bus->name, phy_mask);
+        return NULL;
+    }
 
-	/* Soft Reset the PHY */
-	phy_reset(phydev);
+    /* Soft Reset the PHY */
+    phy_reset(phydev);
 
-	if (phydev->dev)
-		printf("%s:%d is connected to %s.  Reconnecting to %s\n",
-			bus->name, phydev->addr, phydev->dev->name, dev->name);
+    if (phydev->dev) {
+        ZF_LOGI("%s:%d is connected to %s.  Reconnecting to %s",
+                bus->name, phydev->addr, phydev->dev->name, dev->name);
+    }
+    phydev->dev = dev;
 
-	phydev->dev = dev;
+    ZF_LOGI("Connected PHY '%s' at address %d to '%s'",
+            phydev->drv->name, phydev->addr, phydev->dev->name);
 
-	debug("%s connected to %s\n", dev->name, phydev->drv->name);
-
-	return phydev;
+    return phydev;
 }
 
 /*
  * Start the PHY.  Returns 0 on success, or a negative error code.
  */
 struct phy_device *phy_connect(struct mii_dev *bus, int addr,
-		struct eth_device *dev, phy_interface_t interface)
+                               struct eth_device *dev, phy_interface_t interface)
 {
-	return phy_connect_by_mask(bus, BIT(addr), dev, interface);
+    return phy_connect_by_mask(bus, BIT(addr), dev, interface);
 }
 
 int phy_shutdown(struct phy_device *phydev)
 {
-	if (phydev->drv->shutdown)
-		phydev->drv->shutdown(phydev);
+    if (phydev->drv->shutdown) {
+        phydev->drv->shutdown(phydev);
+    }
 
-	return 0;
+    return 0;
 }
diff --git a/libethdrivers/src/plat/imx6/uboot/phy.h b/libethdrivers/src/plat/imx6/uboot/phy.h
index f440070..99c62eb 100644
--- a/libethdrivers/src/plat/imx6/uboot/phy.h
+++ b/libethdrivers/src/plat/imx6/uboot/phy.h
@@ -1,10 +1,10 @@
 /*
- * @TAG(OTHER_GPL)
- */
-
-/*
+ * This file derived from Linux's mii.h/ethtool.h/phy.h
+ *
  * Copyright 2011 Freescale Semiconductor, Inc.
- *	Andy Fleming <afleming@freescale.com>
+ * Andy Fleming <afleming@freescale.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -22,10 +22,6 @@
  * MA 02111-1307 USA
  */
 
-/*
- * This file derived from Linux's mii.h/ethtool.h/phy.h
- */
-
 #pragma once
 
 #include "list.h"
@@ -36,60 +32,61 @@
 
 #define PHY_MAX_ADDR 32
 
-#define PHY_BASIC_FEATURES	(SUPPORTED_10baseT_Half | \
-				 SUPPORTED_10baseT_Full | \
-				 SUPPORTED_100baseT_Half | \
-				 SUPPORTED_100baseT_Full | \
-				 SUPPORTED_Autoneg | \
-				 SUPPORTED_TP | \
-				 SUPPORTED_MII)
+#define PHY_BASIC_FEATURES  (SUPPORTED_10baseT_Half | \
+                 SUPPORTED_10baseT_Full | \
+                 SUPPORTED_100baseT_Half | \
+                 SUPPORTED_100baseT_Full | \
+                 SUPPORTED_Autoneg | \
+                 SUPPORTED_TP | \
+                 SUPPORTED_MII)
 
-#define PHY_GBIT_FEATURES	(PHY_BASIC_FEATURES | \
-				 SUPPORTED_1000baseT_Half | \
-				 SUPPORTED_1000baseT_Full)
+#define PHY_GBIT_FEATURES   (PHY_BASIC_FEATURES | \
+                 SUPPORTED_1000baseT_Half | \
+                 SUPPORTED_1000baseT_Full)
 
-#define PHY_10G_FEATURES	(PHY_GBIT_FEATURES | \
-				SUPPORTED_10000baseT_Full)
+#define PHY_10G_FEATURES    (PHY_GBIT_FEATURES | \
+                SUPPORTED_10000baseT_Full)
 
-#define PHY_ANEG_TIMEOUT	40000
+#define PHY_ANEG_TIMEOUT    40000
 
 typedef enum {
-	PHY_INTERFACE_MODE_MII,
-	PHY_INTERFACE_MODE_GMII,
-	PHY_INTERFACE_MODE_SGMII,
-	PHY_INTERFACE_MODE_TBI,
-	PHY_INTERFACE_MODE_RMII,
-	PHY_INTERFACE_MODE_RGMII,
-	PHY_INTERFACE_MODE_RGMII_ID,
-	PHY_INTERFACE_MODE_RGMII_RXID,
-	PHY_INTERFACE_MODE_RGMII_TXID,
-	PHY_INTERFACE_MODE_RTBI,
-	PHY_INTERFACE_MODE_XGMII,
-	PHY_INTERFACE_MODE_NONE	/* Must be last */
+    PHY_INTERFACE_MODE_MII,
+    PHY_INTERFACE_MODE_GMII,
+    PHY_INTERFACE_MODE_SGMII,
+    PHY_INTERFACE_MODE_TBI,
+    PHY_INTERFACE_MODE_RMII,
+    PHY_INTERFACE_MODE_RGMII,
+    PHY_INTERFACE_MODE_RGMII_ID,
+    PHY_INTERFACE_MODE_RGMII_RXID,
+    PHY_INTERFACE_MODE_RGMII_TXID,
+    PHY_INTERFACE_MODE_RTBI,
+    PHY_INTERFACE_MODE_XGMII,
+    PHY_INTERFACE_MODE_NONE /* Must be last */
 } phy_interface_t;
 
 static const char *phy_interface_strings[] = {
-	[PHY_INTERFACE_MODE_MII]		= "mii",
-	[PHY_INTERFACE_MODE_GMII]		= "gmii",
-	[PHY_INTERFACE_MODE_SGMII]		= "sgmii",
-	[PHY_INTERFACE_MODE_TBI]		= "tbi",
-	[PHY_INTERFACE_MODE_RMII]		= "rmii",
-	[PHY_INTERFACE_MODE_RGMII]		= "rgmii",
-	[PHY_INTERFACE_MODE_RGMII_ID]		= "rgmii-id",
-	[PHY_INTERFACE_MODE_RGMII_RXID]		= "rgmii-rxid",
-	[PHY_INTERFACE_MODE_RGMII_TXID]		= "rgmii-txid",
-	[PHY_INTERFACE_MODE_RTBI]		= "rtbi",
-	[PHY_INTERFACE_MODE_XGMII]		= "xgmii",
-	[PHY_INTERFACE_MODE_NONE]		= "",
+    [PHY_INTERFACE_MODE_MII]        = "mii",
+    [PHY_INTERFACE_MODE_GMII]       = "gmii",
+    [PHY_INTERFACE_MODE_SGMII]      = "sgmii",
+    [PHY_INTERFACE_MODE_TBI]        = "tbi",
+    [PHY_INTERFACE_MODE_RMII]       = "rmii",
+    [PHY_INTERFACE_MODE_RGMII]      = "rgmii",
+    [PHY_INTERFACE_MODE_RGMII_ID]       = "rgmii-id",
+    [PHY_INTERFACE_MODE_RGMII_RXID]     = "rgmii-rxid",
+    [PHY_INTERFACE_MODE_RGMII_TXID]     = "rgmii-txid",
+    [PHY_INTERFACE_MODE_RTBI]       = "rtbi",
+    [PHY_INTERFACE_MODE_XGMII]      = "xgmii",
+    [PHY_INTERFACE_MODE_NONE]       = "",
 };
 
 static inline const char *phy_string_for_interface(phy_interface_t i)
 {
-	/* Default to unknown */
-	if (i > PHY_INTERFACE_MODE_NONE)
-		i = PHY_INTERFACE_MODE_NONE;
+    /* Default to unknown */
+    if (i > PHY_INTERFACE_MODE_NONE) {
+        i = PHY_INTERFACE_MODE_NONE;
+    }
 
-	return phy_interface_strings[i];
+    return phy_interface_strings[i];
 }
 
 struct phy_device;
@@ -97,15 +94,15 @@
 #define MDIO_NAME_LEN 32
 
 struct mii_dev {
-	struct list_head link;
-	char name[MDIO_NAME_LEN];
-	void *priv;
-	int (*read)(struct mii_dev *bus, int addr, int devad, int reg);
-	int (*write)(struct mii_dev *bus, int addr, int devad, int reg,
-			uint16_t val);
-	int (*reset)(struct mii_dev *bus);
-	struct phy_device *phymap[PHY_MAX_ADDR];
-	uint32_t phy_mask;
+    struct list_head link;
+    char name[MDIO_NAME_LEN];
+    void *priv;
+    int (*read)(struct mii_dev *bus, int addr, int devad, int reg);
+    int (*write)(struct mii_dev *bus, int addr, int devad, int reg,
+                 uint16_t val);
+    int (*reset)(struct mii_dev *bus);
+    struct phy_device *phymap[PHY_MAX_ADDR];
+    uint32_t phy_mask;
 };
 
 /* struct phy_driver: a structure which defines PHY behavior
@@ -119,75 +116,75 @@
  *
  */
 struct phy_driver {
-	char *name;
-	unsigned int uid;
-	unsigned int mask;
-	unsigned int mmds;
+    char *name;
+    unsigned int uid;
+    unsigned int mask;
+    unsigned int mmds;
 
-	uint32_t features;
+    uint32_t features;
 
-	/* Called to do any driver startup necessities */
-	/* Will be called during phy_connect */
-	int (*probe)(struct phy_device *phydev);
+    /* Called to do any driver startup necessities */
+    /* Will be called during phy_connect */
+    int (*probe)(struct phy_device *phydev);
 
-	/* Called to configure the PHY, and modify the controller
-	 * based on the results.  Should be called after phy_connect */
-	int (*config)(struct phy_device *phydev);
+    /* Called to configure the PHY, and modify the controller
+     * based on the results.  Should be called after phy_connect */
+    int (*config)(struct phy_device *phydev);
 
-	/* Called when starting up the controller */
-	int (*startup)(struct phy_device *phydev);
+    /* Called when starting up the controller */
+    int (*startup)(struct phy_device *phydev);
 
-	/* Called when bringing down the controller */
-	int (*shutdown)(struct phy_device *phydev);
+    /* Called when bringing down the controller */
+    int (*shutdown)(struct phy_device *phydev);
 
-	struct list_head list;
+    struct list_head list;
 };
 
 struct phy_device {
-	/* Information about the PHY type */
-	/* And management functions */
-	struct mii_dev *bus;
-	struct phy_driver *drv;
-	void *priv;
+    /* Information about the PHY type */
+    /* And management functions */
+    struct mii_dev *bus;
+    struct phy_driver *drv;
+    void *priv;
 
-	struct eth_device *dev;
+    struct eth_device *dev;
 
-	/* forced speed & duplex (no autoneg)
-	 * partner speed & duplex & pause (autoneg)
-	 */
-	int speed;
-	int duplex;
+    /* forced speed & duplex (no autoneg)
+     * partner speed & duplex & pause (autoneg)
+     */
+    int speed;
+    int duplex;
 
-	/* The most recently read link state */
-	int link;
-	int port;
-	phy_interface_t interface;
+    /* The most recently read link state */
+    int link;
+    int port;
+    phy_interface_t interface;
 
-	uint32_t advertising;
-	uint32_t supported;
-	uint32_t mmds;
+    uint32_t advertising;
+    uint32_t supported;
+    uint32_t mmds;
 
-	int autoneg;
-	int addr;
-	int pause;
-	int asym_pause;
-	uint32_t phy_id;
-	uint32_t flags;
+    int autoneg;
+    int addr;
+    int pause;
+    int asym_pause;
+    uint32_t phy_id;
+    uint32_t flags;
 };
 
 static inline int phy_read(struct phy_device *phydev, int devad, int regnum)
 {
-	struct mii_dev *bus = phydev->bus;
+    struct mii_dev *bus = phydev->bus;
 
-	return bus->read(bus, phydev->addr, devad, regnum);
+    return bus->read(bus, phydev->addr, devad, regnum);
 }
 
 static inline int phy_write(struct phy_device *phydev, int devad, int regnum,
-			uint16_t val)
+                            uint16_t val)
 {
-	struct mii_dev *bus = phydev->bus;
+    struct mii_dev *bus = phydev->bus;
 
-	return bus->write(bus, phydev->addr, devad, regnum, val);
+    return bus->write(bus, phydev->addr, devad, regnum, val);
 }
 
 #ifdef CONFIG_PHYLIB_10G
@@ -196,7 +193,7 @@
 /* For now, XGMII is the only 10G interface */
 static inline int is_10g_interface(phy_interface_t interface)
 {
-	return interface == PHY_INTERFACE_MODE_XGMII;
+    return interface == PHY_INTERFACE_MODE_XGMII;
 }
 
 #endif
@@ -204,10 +201,10 @@
 int phy_init(void);
 int phy_reset(struct phy_device *phydev);
 struct phy_device *phy_connect(struct mii_dev *bus, int addr,
-				struct eth_device *dev,
-				phy_interface_t interface);
+                               struct eth_device *dev,
+                               phy_interface_t interface);
 struct phy_device *phy_connect_by_mask(struct mii_dev *bus, unsigned phy_mask,
-		struct eth_device *dev, phy_interface_t interface);
+                                       struct eth_device *dev, phy_interface_t interface);
 int phy_startup(struct phy_device *phydev);
 int phy_config(struct phy_device *phydev);
 int phy_shutdown(struct phy_device *phydev);
@@ -236,5 +233,4 @@
 int phy_vitesse_init(void);
 
 /* PHY UIDs for various PHYs that are referenced in external code */
-#define PHY_UID_TN2020	0x00a19410
-
+#define PHY_UID_TN2020  0x00a19410
diff --git a/libethdrivers/src/plat/imx6/unimplemented.c b/libethdrivers/src/plat/imx6/unimplemented.c
index 2fee8ad..ad258c2 100644
--- a/libethdrivers/src/plat/imx6/unimplemented.c
+++ b/libethdrivers/src/plat/imx6/unimplemented.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #include <stdio.h>
diff --git a/libethdrivers/src/plat/imx6/unimplemented.h b/libethdrivers/src/plat/imx6/unimplemented.h
index c02c1d1..c40cf41 100644
--- a/libethdrivers/src/plat/imx6/unimplemented.h
+++ b/libethdrivers/src/plat/imx6/unimplemented.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #pragma once
diff --git a/libethdrivers/src/plat/odroidc2/ethernet.c b/libethdrivers/src/plat/odroidc2/ethernet.c
new file mode 100644
index 0000000..c1fe779
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/ethernet.c
@@ -0,0 +1,502 @@
+/*
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+#include <errno.h>
+#include <string.h>
+#include <assert.h>
+
+#include <platsupport/driver_module.h>
+#include <platsupport/fdt.h>
+#include <ethdrivers/gen_config.h>
+#include <ethdrivers/odroidc2.h>
+#include <ethdrivers/raw.h>
+#include <ethdrivers/helpers.h>
+#include <utils/util.h>
+
+#include "uboot/common.h"
+#include "uboot/net.h"
+#include "uboot/miiphy.h"
+#include "io.h"
+#include "uboot/netdev.h"
+#include "unimplemented.h"
+#include "uboot/designware.h"
+
+#define BUF_SIZE 2048
+#define MAC_LEN 6
+#define DMA_ALIGN 64
+
+struct descriptor {
+    uint32_t txrx_status;
+    uint32_t dmamac_cntl;
+    uint32_t dmamac_addr;
+    uint32_t dmamac_next;
+};
+
+struct odroidc2_eth_data {
+    struct eth_device *eth_dev;
+    uint8_t mac[MAC_LEN];
+    uintptr_t tx_ring_phys;
+    uintptr_t rx_ring_phys;
+    volatile struct descriptor *tx_ring;
+    volatile struct descriptor *rx_ring;
+    unsigned int rx_size;
+    unsigned int tx_size;
+    void **rx_cookies; /* Array of rx_size elements of type 'void *' */
+    void **tx_cookies; /* Array of tx_size elements of type 'void *' */
+    unsigned int rx_remain;
+    unsigned int tx_remain;
+    unsigned int *tx_lengths;
+    /* Indexes used to keep track of the head and tail of the descriptor queues */
+    unsigned int rdt, rdh, tdt, tdh;
+};
+
+static bool enabled = false;
+
+static void low_level_init(struct eth_driver *driver, uint8_t *mac, int *mtu)
+{
+    struct odroidc2_eth_data *dev = (struct odroidc2_eth_data *)driver->eth_data;
+    memcpy(mac, dev->mac, MAC_LEN);
+    *mtu = MAX_PKT_SIZE;
+}
+
+static void fill_rx_bufs(struct eth_driver *driver)
+{
+    struct odroidc2_eth_data *dev = (struct odroidc2_eth_data *)driver->eth_data;
+    __sync_synchronize();
+    while (dev->rx_remain > 0) {
+        /* request a buffer */
+        void *cookie = NULL;
+        int next_rdt = (dev->rdt + 1) % dev->rx_size;
+
+        // This fn ptr is either lwip_allocate_rx_buf or lwip_pbuf_allocate_rx_buf (in src/lwip.c)
+        uintptr_t phys = driver->i_cb.allocate_rx_buf ? driver->i_cb.allocate_rx_buf(driver->cb_cookie, BUF_SIZE, &cookie) : 0;
+        if (!phys) {
+            // NOTE: This condition could happen if
+            //       CONFIG_LIB_ETHDRIVER_NUM_PREALLOCATED_BUFFERS < CONFIG_LIB_ETHDRIVER_RX_DESC_COUNT
+            break;
+        }
+
+        dev->rx_cookies[dev->rdt] = cookie;
+        dev->rx_ring[dev->rdt].dmamac_addr = phys;
+        dev->rx_ring[dev->rdt].dmamac_cntl = (MAC_MAX_FRAME_SZ & DESC_RXCTRL_SIZE1MASK) | DESC_RXCTRL_RXCHAIN;
+        dev->rx_ring[dev->rdt].txrx_status = DESC_RXSTS_OWNBYDMA;
+
+        __sync_synchronize();
+        dev->rdt = next_rdt;
+        dev->rx_remain--;
+    }
+    __sync_synchronize();
+
+    /* NOTE Maybe check if receiving isn't enabled? */
+    if (enabled) {
+        designware_start_receive(dev->eth_dev);
+    }
+}
+
+static void free_desc_ring(struct odroidc2_eth_data *dev, ps_dma_man_t *dma_man)
+{
+    if (dev->rx_ring) {
+        dma_unpin_free(dma_man, (void *)dev->rx_ring, sizeof(struct descriptor) * dev->rx_size);
+        dev->rx_ring = NULL;
+    }
+    if (dev->tx_ring) {
+        dma_unpin_free(dma_man, (void *)dev->tx_ring, sizeof(struct descriptor) * dev->tx_size);
+        dev->tx_ring = NULL;
+    }
+    if (dev->rx_cookies) {
+        free(dev->rx_cookies);
+        dev->rx_cookies = NULL;
+    }
+    if (dev->tx_cookies) {
+        free(dev->tx_cookies);
+        dev->tx_cookies = NULL;
+    }
+    if (dev->tx_lengths) {
+        free(dev->tx_lengths);
+        dev->tx_lengths = NULL;
+    }
+}
+
+static int initialize_desc_ring(struct odroidc2_eth_data *dev, ps_dma_man_t *dma_man)
+{
+    dma_addr_t rx_ring = dma_alloc_pin(dma_man, sizeof(struct descriptor) * dev->rx_size, 0, DMA_ALIGN);
+    if (!rx_ring.phys) {
+        LOG_ERROR("Failed to allocate rx_ring");
+        return -1;
+    }
+    dev->rx_ring = rx_ring.virt;
+    dev->rx_ring_phys = rx_ring.phys;
+    dma_addr_t tx_ring = dma_alloc_pin(dma_man, sizeof(struct descriptor) * dev->tx_size, 0, DMA_ALIGN);
+    if (!tx_ring.phys) {
+        LOG_ERROR("Failed to allocate tx_ring");
+        free_desc_ring(dev, dma_man);
+        return -1;
+    }
+    ps_dma_cache_clean_invalidate(dma_man, rx_ring.virt, sizeof(struct descriptor) * dev->rx_size);
+    ps_dma_cache_clean_invalidate(dma_man, tx_ring.virt, sizeof(struct descriptor) * dev->tx_size);
+    dev->rx_cookies = malloc(sizeof(void *) * dev->rx_size);
+    dev->tx_cookies = malloc(sizeof(void *) * dev->tx_size);
+    dev->tx_lengths = malloc(sizeof(unsigned int) * dev->tx_size);
+    if (!dev->rx_cookies || !dev->tx_cookies || !dev->tx_lengths) {
+        if (dev->rx_cookies) {
+            free(dev->rx_cookies);
+        }
+        if (dev->tx_cookies) {
+            free(dev->tx_cookies);
+        }
+        if (dev->tx_lengths) {
+            free(dev->tx_lengths);
+        }
+        LOG_ERROR("Failed to malloc");
+        free_desc_ring(dev, dma_man);
+        return -1;
+    }
+    dev->tx_ring = tx_ring.virt;
+    dev->tx_ring_phys = tx_ring.phys;
+    /* Remaining needs to be 2 less than size as we cannot actually enqueue size many descriptors,
+     * since then the head and tail pointers would be equal, indicating empty. */
+    dev->rx_remain = dev->rx_size - 2;
+    dev->tx_remain = dev->tx_size - 2;
+
+    dev->rdt = dev->rdh = dev->tdt = dev->tdh = 0;
+
+    uintptr_t next_phys = dev->tx_ring_phys;
+
+    for (unsigned int i = 0; i < dev->tx_size; i++) {
+        next_phys += sizeof(struct descriptor);
+        dev->tx_ring[i].dmamac_addr = 0;
+        if (i == (dev->tx_size - 1)) {
+            dev->tx_ring[i].dmamac_next = (uint32_t)(dev->tx_ring_phys & 0xFFFFFFFF);
+        } else {
+            dev->tx_ring[i].dmamac_next = (uint32_t)(next_phys & 0xFFFFFFFF);
+        }
+        dev->tx_ring[i].dmamac_cntl = DESC_TXCTRL_TXCHAIN;
+        dev->tx_ring[i].txrx_status = 0;
+    }
+
+    next_phys = dev->rx_ring_phys;
+
+    for (unsigned int i = 0; i < dev->rx_size; i++) {
+        next_phys += sizeof(struct descriptor);
+        dev->rx_ring[i].dmamac_addr = 0;
+        if (i == (dev->rx_size - 1)) {
+            dev->rx_ring[i].dmamac_next = (uint32_t)(dev->rx_ring_phys & 0xFFFFFFFF);
+        } else {
+            dev->rx_ring[i].dmamac_next = (uint32_t)(next_phys & 0xFFFFFFFF);
+        }
+        dev->rx_ring[i].dmamac_cntl = (MAC_MAX_FRAME_SZ & DESC_RXCTRL_SIZE1MASK) | DESC_RXCTRL_RXCHAIN;
+        dev->rx_ring[i].txrx_status = 0;
+    }
+
+    __sync_synchronize();
+
+    return 0;
+}
+
+static void complete_rx(struct eth_driver *eth_driver)
+{
+    struct odroidc2_eth_data *dev = (struct odroidc2_eth_data *)eth_driver->eth_data;
+    unsigned int rdt = dev->rdt;
+    while (dev->rdh != rdt) {
+        unsigned int status = dev->rx_ring[dev->rdh].txrx_status;
+        /* Ensure no memory references get ordered before we checked the descriptor was written back */
+        __sync_synchronize();
+        if (status & DESC_RXSTS_OWNBYDMA) {
+            /* not complete yet */
+            break;
+        }
+        void *cookie = dev->rx_cookies[dev->rdh];
+        unsigned int len = (status & DESC_RXSTS_FRMLENMSK) >> DESC_RXSTS_FRMLENSHFT;
+        /* update rdh */
+        dev->rdh = (dev->rdh + 1) % dev->rx_size;
+        dev->rx_remain++;
+        /* Give the buffers back */
+        eth_driver->i_cb.rx_complete(eth_driver->cb_cookie, 1, &cookie, &len);
+    }
+    /* NOTE Maybe re-enable the Ethernet device for RX if there are still descriptors? */
+}
+
+static void complete_tx(struct eth_driver *driver)
+{
+    struct odroidc2_eth_data *dev = (struct odroidc2_eth_data *)driver->eth_data;
+    while (dev->tdh != dev->tdt) {
+        unsigned int i;
+        for (i = 0; i < dev->tx_lengths[dev->tdh]; i++) {
+            if (dev->tx_ring[dev->tdh + i].txrx_status & DESC_TXSTS_OWNBYDMA) {
+                /* Not yet complete */
+                return;
+            }
+        }
+        /* do not let memory loads happen before our checking of the descriptor write back */
+        __sync_synchronize();
+        /* increase where we believe tdh to be */
+        void *cookie = dev->tx_cookies[dev->tdh];
+        dev->tx_remain += dev->tx_lengths[dev->tdh];
+        dev->tdh = (dev->tdh + dev->tx_lengths[dev->tdh]) % dev->tx_size;
+        /* give the buffer back */
+        driver->i_cb.tx_complete(driver->cb_cookie, cookie);
+    }
+    /* NOTE Maybe re-enable the Ethernet device for TX if there are still descriptors? */
+}
+
+static void print_state(struct eth_driver *eth_driver)
+{
+    ZF_LOGE("Not implemented");
+}
+
+static void handle_irq(struct eth_driver *driver, int irq)
+{
+    struct odroidc2_eth_data *eth_data = (struct odroidc2_eth_data *)driver->eth_data;
+    uint32_t status = 0;
+    designware_interrupt_status(eth_data->eth_dev, &status);
+    designware_ack(eth_data->eth_dev, status);
+    if (status & DMA_INTR_ENA_TIE) {
+        complete_tx(driver);
+    }
+    if (status & DMA_INTR_ENA_RIE) {
+        complete_rx(driver);
+        fill_rx_bufs(driver);
+    }
+    if (status & DMA_INTR_ABNORMAL) {
+        ZF_LOGE("Ethernet device crashed with an abnormal interrupt, reporting...");
+        if (status & DMA_INTR_ENA_FBE) {
+            ZF_LOGE("    Ethernet device fatal bus error");
+        }
+        if (status & DMA_INTR_ENA_UNE) {
+            ZF_LOGE("    Ethernet device TX underflow");
+        }
+        ZF_LOGF("Done.");
+    }
+}
+
+/* This is a platsuport IRQ interface IRQ handler wrapper for handle_irq() */
+static void eth_irq_handle(void *data, ps_irq_acknowledge_fn_t acknowledge_fn, void *ack_data)
+{
+    ZF_LOGF_IF(data == NULL, "Passed in NULL for the data");
+    struct eth_driver *driver = data;
+
+    /* handle_irq doesn't really expect an IRQ number */
+    handle_irq(driver, 0);
+
+    int error = acknowledge_fn(ack_data);
+    if (error) {
+        LOG_ERROR("Failed to acknowledge the Ethernet device's IRQ");
+    }
+}
+
+static void raw_poll(struct eth_driver *driver)
+{
+    complete_rx(driver);
+    complete_tx(driver);
+    fill_rx_bufs(driver);
+}
+
+static int raw_tx(struct eth_driver *driver, unsigned int num, uintptr_t *phys, unsigned int *len, void *cookie)
+{
+    struct odroidc2_eth_data *dev = (struct odroidc2_eth_data *)driver->eth_data;
+    /* Ensure we have room */
+    if (dev->tx_remain < num) {
+        /* try and complete some */
+        complete_tx(driver);
+        if (dev->tx_remain < num) {
+            return ETHIF_TX_FAILED;
+        }
+    }
+    unsigned int i;
+    __sync_synchronize();
+    for (i = 0; i < num; i++) {
+        unsigned int ring = (dev->tdt + i) % dev->tx_size;
+        dev->tx_ring[ring].dmamac_addr = phys[i];
+        dev->tx_ring[ring].dmamac_cntl = DESC_TXCTRL_TXCHAIN;
+        dev->tx_ring[ring].dmamac_cntl |= (len[i] << DESC_TXCTRL_SIZE1SHFT) & DESC_TXCTRL_SIZE1MASK;
+        if (i == 0) {
+            dev->tx_ring[ring].dmamac_cntl |= DESC_TXCTRL_TXFIRST;
+        }
+        if (i == (num - 1)) {
+            dev->tx_ring[ring].dmamac_cntl |= DESC_TXCTRL_TXLAST;
+        }
+        dev->tx_ring[ring].dmamac_cntl |= DESC_TXCTRL_TXINT;
+        dev->tx_ring[ring].txrx_status = DESC_TXSTS_OWNBYDMA;
+    }
+    dev->tx_cookies[dev->tdt] = cookie;
+    dev->tx_lengths[dev->tdt] = num;
+    dev->tdt = (dev->tdt + num) % dev->tx_size;
+    dev->tx_remain -= num;
+    __sync_synchronize();
+
+    /* NOTE Maybe check if it's in the middle of sending? */
+    designware_start_send(dev->eth_dev);
+
+    return ETHIF_TX_ENQUEUED;
+}
+
+static void get_mac(struct eth_driver *driver, uint8_t *mac)
+{
+    struct odroidc2_eth_data *eth_data = (struct odroidc2_eth_data *) driver->eth_data;
+    memcpy(mac, eth_data->mac, MAC_LEN);
+}
+
+static struct raw_iface_funcs iface_fns = {
+    .raw_handleIRQ = handle_irq,
+    .print_state = print_state,
+    .low_level_init = low_level_init,
+    .raw_tx = raw_tx,
+    .raw_poll = raw_poll,
+    .get_mac = get_mac
+};
+
+int ethif_odroidc2_init(struct eth_driver *eth_driver, ps_io_ops_t io_ops, void *config)
+{
+    int err;
+    struct odroidc2_eth_data *eth_data = NULL;
+    struct eth_device *eth_dev;
+
+    if (config == NULL) {
+        ZF_LOGE("Cannot get platform info; passed in config pointer NULL");
+        goto error;
+    }
+
+    struct arm_eth_plat_config *plat_config = (struct arm_eth_plat_config *)config;
+    unsigned long base_addr = (unsigned long)((uintptr_t) plat_config->buffer_addr);
+
+    eth_data = (struct odroidc2_eth_data *)malloc(sizeof(struct odroidc2_eth_data));
+    if (eth_data == NULL) {
+        ZF_LOGE("Failed to allocate eth data struct");
+        goto error;
+    }
+
+    eth_data->tx_size = CONFIG_LIB_ETHDRIVER_TX_DESC_COUNT;
+    eth_data->rx_size = CONFIG_LIB_ETHDRIVER_RX_DESC_COUNT;
+    eth_driver->eth_data = eth_data;
+    eth_driver->dma_alignment = DMA_ALIGN;
+    eth_driver->i_fn = iface_fns;
+
+    err = initialize_desc_ring(eth_data, &io_ops.dma_manager);
+    if (err) {
+        LOG_ERROR("Failed to allocate descriptor rings");
+        goto error;
+    }
+
+    /* Initialise the MII abstraction layer */
+    miiphy_init();
+
+    /* Initialise the actual Realtek PHY */
+    phy_init();
+
+    /* Do some more PHY init, setup structures */
+    eth_dev = malloc(sizeof(*eth_dev));
+    if (NULL == eth_dev) {
+        ZF_LOGE("Failed to allocate eth_dev structure");
+        goto error;
+    }
+
+    int ret = designware_initialize(base_addr, 0, eth_dev);
+    if (ret != 0) {
+        ZF_LOGE("Failed: designware_initialize.");
+        goto error;
+    }
+
+    eth_data->eth_dev = eth_dev;
+
+    /* We must read the MAC address out of the device after the register
+     * addresses have been initialized (designware_initialize), but before
+     * initializing the hardware (uboot_eth_dev.init), because initializing
+     * the hardware involves a soft reset which will wipe the MAC address
+     * which was configured by u-boot */
+
+    ret = designware_read_hwaddr(eth_dev, eth_data->mac);
+    if (ret != 0) {
+        ZF_LOGE("Failed: designware_read_hwaddr.");
+        goto error;
+    }
+
+    /* NOTE: This line determines what our MAC address will be, it is
+     * internally programmed into the device during the next init step*/
+    memcpy(eth_dev->enetaddr, eth_data->mac, 6);
+
+    /* Bring up the interface */
+    ret = designware_startup(eth_dev);
+    if (ret != 0) {
+        ZF_LOGE("Failed: designware_startup");
+        goto error;
+    }
+
+    ret = designware_write_descriptors(eth_dev, eth_data->tx_ring_phys, eth_data->rx_ring_phys);
+    if (ret != 0) {
+        ZF_LOGE("Failed: designware_write_descriptors");
+        goto error;
+    }
+
+    fill_rx_bufs(eth_driver);
+
+    enabled = true;
+
+    /* Last step, enable it */
+    ret = designware_enable(eth_dev);
+    if (ret != 0) {
+        ZF_LOGE("Failed: designware_enable");
+    }
+
+    return 0;
+error:
+    if (eth_data) {
+        free(eth_data);
+    }
+    if (eth_dev) {
+        free(eth_dev);
+    }
+    free_desc_ring(eth_data, &io_ops.dma_manager);
+    return -1;
+}
+
+int ethif_odroidc2_init_module(ps_io_ops_t *io_ops, const char *device_path)
+{
+    struct arm_eth_plat_config plat_config;
+    struct eth_driver *eth_driver;
+
+    int error = ps_calloc(&io_ops->malloc_ops, 1, sizeof(*eth_driver), (void **) &eth_driver);
+    if (error) {
+        ZF_LOGE("Failed to allocate memory for the Ethernet driver");
+        return -ENOMEM;
+    }
+
+    ps_fdt_cookie_t *cookie = NULL;
+    error = ps_fdt_read_path(&io_ops->io_fdt, &io_ops->malloc_ops, device_path, &cookie);
+    if (error) {
+        ZF_LOGE("Failed to read the path of the Ethernet driver");
+        return -ENODEV;
+    }
+
+    void *mapped_addr = ps_fdt_index_map_register(io_ops, cookie, 0, NULL);
+    if (mapped_addr == NULL) {
+        ZF_LOGE("Failed to map the registers");
+        return -ENODEV;
+    }
+
+    irq_id_t eth_irq_id = ps_fdt_index_register_irq(io_ops, cookie, 0, eth_irq_handle, eth_driver);
+    if (eth_irq_id < 0) {
+        ZF_LOGE("Failed to register the Ethernet's IRQ");
+        return -ENODEV;
+    }
+
+    plat_config.buffer_addr = mapped_addr;
+    plat_config.prom_mode = 1;
+
+    error = ethif_odroidc2_init(eth_driver, *io_ops, &plat_config);
+    if (error) {
+        ZF_LOGE("Failed to initialise the Ethernet driver");
+        return -ENODEV;
+    }
+
+    return ps_interface_register(&io_ops->interface_registration_ops, PS_ETHERNET_INTERFACE, eth_driver, NULL);
+}
+
+static const char *compatible_strings[] = {
+    "amlogic,meson-gx-dwmac",
+    "amlogic,meson-gxbb-dwmac",
+    "snps,dwmac",
+    NULL
+};
+PS_DRIVER_MODULE_DEFINE(odroidc2_ethernet, compatible_strings, ethif_odroidc2_init_module);
diff --git a/libethdrivers/src/plat/odroidc2/io.h b/libethdrivers/src/plat/odroidc2/io.h
new file mode 100644
index 0000000..05005f9
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/io.h
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+#pragma once
+
+#define __arch_getl(addr)         *((volatile uint32_t*)(addr))
+#define __arch_getw(addr)         *((volatile uint16_t*)(addr))
+#define __arch_getb(addr)         *((volatile uint8_t*)(addr))
+
+#define __arch_putl(val, addr)    *((volatile uint32_t*)(addr)) = val
+#define __arch_putw(val, addr)    *((volatile uint16_t*)(addr)) = val
+#define __arch_putb(val, addr)    *((volatile uint8_t*)(addr)) = val
+
+
+//#define __raw_writel(...) writel(__VA_ARGS__)
+//#define __raw_readl(...) readl(__VA_ARGS__)
+
+
+
+
+#define __raw_writeb(v,a)   __arch_putb(v,a)
+#define __raw_writew(v,a)   __arch_putw(v,a)
+#define __raw_writel(v,a)   __arch_putl(v,a)
+
+#define __raw_readb(a)      __arch_getb(a)
+#define __raw_readw(a)      __arch_getw(a)
+#define __raw_readl(a)      __arch_getl(a)
+
+/*
+ * TODO: The kernel offers some more advanced versions of barriers, it might
+ * have some advantages to use them instead of the simple one here.
+ */
+#define dmb()     asm volatile("dmb sy" ::: "memory")
+#define dsb()     asm volatile("dsb sy" ::: "memory")
+#define isb()     asm volatile("isb sy" ::: "memory")
+#define __iormb()   dmb()
+#define __iowmb()   dmb()
+
+#define writeb(v,c) ({ uint8_t  __v = v; __iowmb(); __arch_putb(__v,c); __v; })
+#define writew(v,c) ({ uint16_t __v = v; __iowmb(); __arch_putw(__v,c); __v; })
+#define writel(v,c) ({ uint32_t __v = v; __iowmb(); __arch_putl(__v,c); __v; })
+
+#define readb(c)    ({ uint8_t  __v = __arch_getb(c); __iormb(); __v; })
+#define readw(c)    ({ uint16_t __v = __arch_getw(c); __iormb(); __v; })
+#define readl(c)    ({ uint32_t __v = __arch_getl(c); __iormb(); __v; })
+
+
+
+#define __cpu_to_le64(x) ((__force __le64)(__u64)(x))
+#define __le64_to_cpu(x) ((__force __u64)(__le64)(x))
+#define __cpu_to_le32(x) ((__force __le32)(__u32)(x))
+#define __le32_to_cpu(x) ((__force __u32)(__le32)(x))
+#define __cpu_to_le16(x) ((__force __le16)(__u16)(x))
+#define __le16_to_cpu(x) ((__force __u16)(__le16)(x))
+#define __cpu_to_be64(x) ((__force __be64)__swab64((x)))
+#define __be64_to_cpu(x) __swab64((__force __u64)(__be64)(x))
+#define __cpu_to_be32(x) ((__force __be32)__swab32((x)))
+#define __be32_to_cpu(x) __swab32((__force __u32)(__be32)(x))
+#define __cpu_to_be16(x) ((__force __be16)__swab16((x)))
+#define __be16_to_cpu(x) __swab16((__force __u16)(__be16)(x))
+
+#define cpu_to_le64 __cpu_to_le64
+#define le64_to_cpu __le64_to_cpu
+#define cpu_to_le32 __cpu_to_le32
+#define le32_to_cpu __le32_to_cpu
+#define cpu_to_le16 __cpu_to_le16
+#define le16_to_cpu __le16_to_cpu
+#define cpu_to_be64 __cpu_to_be64
+#define be64_to_cpu __be64_to_cpu
+#define cpu_to_be32 __cpu_to_be32
+#define be32_to_cpu __be32_to_cpu
+#define cpu_to_be16 __cpu_to_be16
+#define be16_to_cpu __be16_to_cpu
+#define cpu_to_le64p __cpu_to_le64p
+#define le64_to_cpup __le64_to_cpup
+#define cpu_to_le32p __cpu_to_le32p
+#define le32_to_cpup __le32_to_cpup
+#define cpu_to_le16p __cpu_to_le16p
+#define le16_to_cpup __le16_to_cpup
+#define cpu_to_be64p __cpu_to_be64p
+#define be64_to_cpup __be64_to_cpup
+#define cpu_to_be32p __cpu_to_be32p
+#define be32_to_cpup __be32_to_cpup
+#define cpu_to_be16p __cpu_to_be16p
+#define be16_to_cpup __be16_to_cpup
+#define cpu_to_le64s __cpu_to_le64s
+#define le64_to_cpus __le64_to_cpus
+#define cpu_to_le32s __cpu_to_le32s
+#define le32_to_cpus __le32_to_cpus
+#define cpu_to_le16s __cpu_to_le16s
+#define le16_to_cpus __le16_to_cpus
+#define cpu_to_be64s __cpu_to_be64s
+#define be64_to_cpus __be64_to_cpus
+#define cpu_to_be32s __cpu_to_be32s
+#define be32_to_cpus __be32_to_cpus
+#define cpu_to_be16s __cpu_to_be16s
+#define be16_to_cpus __be16_to_cpus
+
+#define out_arch(type, endian, a, v)    __raw_write##type(cpu_to_##endian(v), a)
+#define in_arch(type, endian, a)    endian##_to_cpu(__raw_read##type(a))
+
+#define out_le32(a, v)  out_arch(l, le32, a, v)
+#define out_le16(a, v)  out_arch(w, le16, a, v)
+
+#define in_le32(a)  in_arch(l, le32, a)
+#define in_le16(a)  in_arch(w, le16, a)
+
+#define out_be32(a, v)  out_arch(l, be32, a, v)
+#define out_be16(a, v)  out_arch(w, be16, a, v)
+
+#define in_be32(a)  in_arch(l, be32, a)
+#define in_be16(a)  in_arch(w, be16, a)
+
+#define out_8(a, v) __raw_writeb(v, a)
+#define in_8(a)     __raw_readb(a)
+
+/*
+ * Clear and set bits in one shot. These macros can be used to clear and
+ * set multiple bits in a register using a single call. These macros can
+ * also be used to set a multiple-bit bit pattern using a mask, by
+ * specifying the mask in the 'clear' parameter and the new bit pattern
+ * in the 'set' parameter.
+ */
+
+#define clrbits(type, addr, clear) \
+    out_##type((addr), in_##type(addr) & ~(clear))
+
+#define setbits(type, addr, set) \
+    out_##type((addr), in_##type(addr) | (set))
+
+#define clrsetbits(type, addr, clear, set) \
+    out_##type((addr), (in_##type(addr) & ~(clear)) | (set))
+
+#define clrbits_be32(addr, clear) clrbits(be32, addr, clear)
+#define setbits_be32(addr, set) setbits(be32, addr, set)
+#define clrsetbits_be32(addr, clear, set) clrsetbits(be32, addr, clear, set)
+
+#define clrbits_le32(addr, clear) clrbits(le32, addr, clear)
+#define setbits_le32(addr, set) setbits(le32, addr, set)
+#define clrsetbits_le32(addr, clear, set) clrsetbits(le32, addr, clear, set)
+
+#define clrbits_be16(addr, clear) clrbits(be16, addr, clear)
+#define setbits_be16(addr, set) setbits(be16, addr, set)
+#define clrsetbits_be16(addr, clear, set) clrsetbits(be16, addr, clear, set)
+
+#define clrbits_le16(addr, clear) clrbits(le16, addr, clear)
+#define setbits_le16(addr, set) setbits(le16, addr, set)
+#define clrsetbits_le16(addr, clear, set) clrsetbits(le16, addr, clear, set)
+
+#define clrbits_8(addr, clear) clrbits(8, addr, clear)
+#define setbits_8(addr, set) setbits(8, addr, set)
+#define clrsetbits_8(addr, clear, set) clrsetbits(8, addr, clear, set)
diff --git a/libethdrivers/src/plat/odroidc2/uboot/bitops.h b/libethdrivers/src/plat/odroidc2/uboot/bitops.h
new file mode 100644
index 0000000..07ce063
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/bitops.h
@@ -0,0 +1,48 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ * Copyright Linux
+ */
+
+#pragma once
+
+#include "../unimplemented.h"
+
+/*
+ * ffs: find first bit set. This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ */
+
+static inline int generic_ffs(int x)
+{
+    int r = 1;
+
+    if (!x) {
+        return 0;
+    }
+    if (!(x & 0xffff)) {
+        x >>= 16;
+        r += 16;
+    }
+    if (!(x & 0xff)) {
+        x >>= 8;
+        r += 8;
+    }
+    if (!(x & 0xf)) {
+        x >>= 4;
+        r += 4;
+    }
+    if (!(x & 3)) {
+        x >>= 2;
+        r += 2;
+    }
+    if (!(x & 1)) {
+        x >>= 1;
+        r += 1;
+    }
+    return r;
+}
+
+#ifndef PLATFORM_FFS
+# define ffs generic_ffs
+#endif
diff --git a/libethdrivers/src/plat/odroidc2/uboot/common.h b/libethdrivers/src/plat/odroidc2/uboot/common.h
new file mode 100644
index 0000000..01b90b1
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/common.h
@@ -0,0 +1,85 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+/*
+ * (C) Copyright 2000-2009
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 (at your option) 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#pragma once
+
+#undef  _LINUX_CONFIG_H
+#define _LINUX_CONFIG_H 1   /* avoid reading Linux autoconf.h file  */
+
+#include "config.h"
+#include "../unimplemented.h"
+
+
+#ifdef CONFIG_POST
+#define CONFIG_HAS_POST
+#ifndef CONFIG_POST_ALT_LIST
+#define CONFIG_POST_STD_LIST
+#endif
+#endif
+
+#ifdef CONFIG_INIT_CRITICAL
+#error CONFIG_INIT_CRITICAL is deprecated!
+#error Read section CONFIG_SKIP_LOWLEVEL_INIT in README.
+#endif
+
+
+#define ROUND(a,b)      (((a) + (b) - 1) & ~((b) - 1))
+#define roundup(x, y)       ((((x) + ((y) - 1)) / (y)) * (y))
+
+#define __ALIGN_MASK(x,mask)    (((x)+(mask))&~(mask))
+
+
+
+#ifdef ETH_DEBUG
+#define _DEBUG  1
+#else
+#define _DEBUG  0
+#endif
+
+/*
+ * Output a debug text when condition "cond" is met. The "cond" should be
+ * computed by a preprocessor in the best case, allowing for the best
+ * optimization.
+ */
+#define debug_cond(cond, fmt, args...)      \
+    do {                    \
+        if (cond)           \
+            printf(fmt, ##args);    \
+    } while (0)
+
+#define debug(fmt, args...)         \
+    debug_cond(_DEBUG, fmt, ##args)
+
+/**
+ * container_of - cast a member of a structure out to the containing structure
+ * @ptr:    the pointer to the member.
+ * @type:   the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({          \
+    const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
+    (type *)( (char *)__mptr - offsetof(type,member) );})
diff --git a/libethdrivers/src/plat/odroidc2/uboot/config.h b/libethdrivers/src/plat/odroidc2/uboot/config.h
new file mode 100644
index 0000000..b596ccf
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/config.h
@@ -0,0 +1,16 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+ */
+
+#pragma once
+
+#define CONFIG_PHY_REALTEK 1
+#define CONFIG_SYS_HZ 1000 /* Current timer header uses milliseconds for get_timer */
+#define CONFIG_ARM 1
+#define CONFIG_ARCH_MESON 1
+#define CONFIG_MESON_GXBB 1
+#define CONFIG_TARGET_ODROID_C2 1
+#define CONFIG_NET_RANDOM_ETHADDR 1
+#define CONFIG_ETH_DESIGNWARE 1
+#define CONFIG_PHYLIB 1
diff --git a/libethdrivers/src/plat/odroidc2/uboot/designware.c b/libethdrivers/src/plat/odroidc2/uboot/designware.c
new file mode 100644
index 0000000..ddc47f2
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/designware.c
@@ -0,0 +1,425 @@
+/*
+ * @TAG(OTHER_GPL)
+ */
+
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * (C) Copyright 2010
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
+ */
+
+/*
+ * Designware ethernet IP driver for U-Boot
+ */
+
+#include "common.h"
+#include "net.h"
+#include <errno.h>
+#include "miiphy.h"
+#include <malloc.h>
+#include "../io.h"
+#include "designware.h"
+
+#define        GMAC_INT_MASK           0x0000003c
+#define        GMAC_INT_DISABLE_RGMII          BIT(0)
+#define        GMAC_INT_DISABLE_PCSLINK        BIT(1)
+#define        GMAC_INT_DISABLE_PCSAN          BIT(2)
+#define        GMAC_INT_DISABLE_PMT            BIT(3)
+#define        GMAC_INT_DISABLE_TIMESTAMP      BIT(9)
+#define        GMAC_INT_DISABLE_PCS    (GMAC_INT_DISABLE_RGMII | \
+                                GMAC_INT_DISABLE_PCSLINK | \
+                                GMAC_INT_DISABLE_PCSAN)
+#define        GMAC_INT_DEFAULT_MASK   (GMAC_INT_DISABLE_TIMESTAMP | \
+                                GMAC_INT_DISABLE_PCS)
+
+
+static int dw_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
+{
+#ifdef CONFIG_DM_ETH
+    struct dw_eth_dev *priv = dev_get_priv((struct udevice *)bus->priv);
+    struct eth_mac_regs *mac_p = priv->mac_regs_p;
+#else
+    struct eth_mac_regs *mac_p = bus->priv;
+#endif
+    ulong start;
+    u16 miiaddr;
+    int timeout = CONFIG_MDIO_TIMEOUT;
+
+    miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) |
+              ((reg << MIIREGSHIFT) & MII_REGMSK);
+
+    writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
+
+    for (int i = 0; i < 10; i++) {
+        if (!(readl(&mac_p->miiaddr) & MII_BUSY)) {
+            return readl(&mac_p->miidata);
+        }
+        uboot_udelay(10);
+    };
+
+    return -ETIMEDOUT;
+}
+
+static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
+                         u16 val)
+{
+#ifdef CONFIG_DM_ETH
+    struct dw_eth_dev *priv = dev_get_priv((struct udevice *)bus->priv);
+    struct eth_mac_regs *mac_p = priv->mac_regs_p;
+#else
+    struct eth_mac_regs *mac_p = bus->priv;
+#endif
+    ulong start;
+    u16 miiaddr;
+    int ret = -ETIMEDOUT, timeout = CONFIG_MDIO_TIMEOUT;
+
+    writel(val, &mac_p->miidata);
+    miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) |
+              ((reg << MIIREGSHIFT) & MII_REGMSK) | MII_WRITE;
+
+    writel(miiaddr | MII_CLKRANGE_150_250M | MII_BUSY, &mac_p->miiaddr);
+
+    for (int i = 0; i < 10; i++) {
+        if (!(readl(&mac_p->miiaddr) & MII_BUSY)) {
+            ret = 0;
+            break;
+        }
+        uboot_udelay(10);
+    };
+
+    return ret;
+}
+
+#if defined(CONFIG_DM_ETH) && defined(CONFIG_DM_GPIO)
+static int dw_mdio_reset(struct mii_dev *bus)
+{
+    struct udevice *dev = bus->priv;
+    struct dw_eth_dev *priv = dev_get_priv(dev);
+    struct dw_eth_pdata *pdata = dev_get_platdata(dev);
+    int ret;
+
+    if (!dm_gpio_is_valid(&priv->reset_gpio)) {
+        return 0;
+    }
+
+    /* reset the phy */
+    ret = dm_gpio_set_value(&priv->reset_gpio, 0);
+    if (ret) {
+        return ret;
+    }
+
+    uboot_udelay(pdata->reset_delays[0]);
+
+    ret = dm_gpio_set_value(&priv->reset_gpio, 1);
+    if (ret) {
+        return ret;
+    }
+
+    uboot_udelay(pdata->reset_delays[1]);
+
+    ret = dm_gpio_set_value(&priv->reset_gpio, 0);
+    if (ret) {
+        return ret;
+    }
+
+    uboot_udelay(pdata->reset_delays[2]);
+
+    return 0;
+}
+#endif
+
+static int dw_mdio_init(const char *name, void *priv)
+{
+    struct mii_dev *bus = mdio_alloc();
+
+    if (!bus) {
+        printf("Failed to allocate MDIO bus\n");
+        return -ENOMEM;
+    }
+
+    bus->read = dw_mdio_read;
+    bus->write = dw_mdio_write;
+    snprintf(bus->name, sizeof(bus->name), "%s", name);
+#if defined(CONFIG_DM_ETH) && defined(CONFIG_DM_GPIO)
+    bus->reset = dw_mdio_reset;
+#endif
+
+    bus->priv = priv;
+
+    return mdio_register(bus);
+}
+
+static int _dw_write_hwaddr(struct dw_eth_dev *priv, u8 *mac_id)
+{
+    struct eth_mac_regs *mac_p = priv->mac_regs_p;
+    u32 macid_lo, macid_hi;
+
+    macid_lo = mac_id[0] + (mac_id[1] << 8) + (mac_id[2] << 16) +
+               (mac_id[3] << 24);
+    macid_hi = mac_id[4] + (mac_id[5] << 8);
+
+    writel(macid_hi, &mac_p->macaddr0hi);
+    writel(macid_lo, &mac_p->macaddr0lo);
+
+    return 0;
+}
+
+static int _dw_read_hwaddr(struct dw_eth_dev *priv, u8 *mac_out)
+{
+    assert(mac_out);
+    struct eth_mac_regs *mac_p = priv->mac_regs_p;
+
+    u32 macid_hi = readl(&mac_p->macaddr0hi);
+    u32 macid_lo = readl(&mac_p->macaddr0lo);
+
+    memcpy(mac_out,   &macid_lo, 4);
+    memcpy(mac_out + 4, &macid_hi, 2);
+
+    return 0;
+}
+
+static int dw_adjust_link(struct dw_eth_dev *priv, struct eth_mac_regs *mac_p,
+                          struct phy_device *phydev)
+{
+    u32 conf = readl(&mac_p->conf) | FRAMEBURSTENABLE | DISABLERXOWN;
+
+    if (!phydev->link) {
+        printf("%s: No link.\n", phydev->dev->name);
+        return 0;
+    }
+
+    if (phydev->speed != 1000) {
+        conf |= MII_PORTSELECT;
+    } else {
+        conf &= ~MII_PORTSELECT;
+    }
+
+    if (phydev->speed == 100) {
+        conf |= FES_100;
+    }
+
+    if (phydev->duplex) {
+        conf |= FULLDPLXMODE;
+    }
+
+    writel(conf, &mac_p->conf);
+
+    printf("Speed: %d, %s duplex%s\n", phydev->speed,
+           (phydev->duplex) ? "full" : "half",
+           (phydev->port == PORT_FIBRE) ? ", fiber mode" : "");
+
+    return 0;
+}
+
+static void _dw_eth_halt(struct dw_eth_dev *priv)
+{
+    struct eth_mac_regs *mac_p = priv->mac_regs_p;
+    struct eth_dma_regs *dma_p = priv->dma_regs_p;
+
+    writel(readl(&mac_p->conf) & ~(RXENABLE | TXENABLE), &mac_p->conf);
+    writel(readl(&dma_p->opmode) & ~(RXSTART | TXSTART), &dma_p->opmode);
+
+    phy_shutdown(priv->phydev);
+}
+
+int designware_eth_init(struct dw_eth_dev *priv, u8 *enetaddr)
+{
+    struct eth_mac_regs *mac_p = priv->mac_regs_p;
+    struct eth_dma_regs *dma_p = priv->dma_regs_p;
+    ulong start;
+    int ret;
+
+    writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode);
+
+    int curr = 0;
+    while (readl(&dma_p->busmode) & DMAMAC_SRST) {
+        if (curr > 10) {
+            printf("DMA reset timeout\n");
+            return -ETIMEDOUT;
+        }
+        curr++;
+
+        uboot_udelay(100000);
+    };
+
+    /*
+     * Soft reset above clears HW address registers.
+     * So we have to set it here once again.
+     */
+    _dw_write_hwaddr(priv, enetaddr);
+
+    writel(FIXEDBURST | PRIORXTX_41 | DMA_PBL, &dma_p->busmode);
+
+#ifndef CONFIG_DW_MAC_FORCE_THRESHOLD_MODE
+    writel(readl(&dma_p->opmode) | FLUSHTXFIFO | STOREFORWARD,
+           &dma_p->opmode);
+#else
+    writel(readl(&dma_p->opmode) | FLUSHTXFIFO,
+           &dma_p->opmode);
+#endif
+
+#ifdef CONFIG_DW_AXI_BURST_LEN
+    writel((CONFIG_DW_AXI_BURST_LEN & 0x1FF >> 1), &dma_p->axibus);
+#endif
+
+
+    /* enable transmit and recv interrupts */
+    writel(readl(&dma_p->intenable) | DMA_INTR_DEFAULT_MASK, &dma_p->intenable);
+
+    /* mask unneeded GMAC interrupts */
+    writel(GMAC_INT_DEFAULT_MASK, &mac_p->intmask);
+
+    /* Start up the PHY */
+    ret = phy_startup(priv->phydev);
+    if (ret) {
+        printf("Could not initialize PHY %s\n",
+               priv->phydev->dev->name);
+        return ret;
+    }
+
+    ret = dw_adjust_link(priv, mac_p, priv->phydev);
+    if (ret) {
+        return ret;
+    }
+
+    return 0;
+}
+
+
+#define ETH_ZLEN    60
+
+static int dw_phy_init(struct dw_eth_dev *priv, void *dev)
+{
+    struct phy_device *phydev;
+    int mask = 0xffffffff, ret;
+
+#ifdef CONFIG_PHY_ADDR
+    mask = 1 << CONFIG_PHY_ADDR;
+#endif
+
+    phydev = phy_find_by_mask(priv->bus, mask, priv->interface);
+    if (!phydev) {
+        return -ENODEV;
+    }
+
+    phy_connect_dev(phydev, dev);
+
+    phydev->supported &= PHY_GBIT_FEATURES;
+    if (priv->max_speed) {
+        ret = phy_set_supported(phydev, priv->max_speed);
+        if (ret) {
+            return ret;
+        }
+    }
+    phydev->advertising = phydev->supported;
+
+    priv->phydev = phydev;
+    phy_config(phydev);
+
+    return 0;
+}
+
+int designware_ack(struct eth_device *dev, u32 status)
+{
+    struct dw_eth_dev *priv = dev->priv;
+    writel(status, &priv->dma_regs_p->status);
+}
+
+int designware_read_hwaddr(struct eth_device *dev, u8 *mac_out)
+{
+    return _dw_read_hwaddr(dev->priv, mac_out);
+}
+
+int designware_initialize(ulong base_addr, u32 interface, struct eth_device *dev)
+{
+    struct dw_eth_dev *priv;
+
+    /* This needs to exist for driver lifetime. Doesn't need to be DMA
+     * any more as we allocate our DMA descriptors below */
+    priv = (struct dw_eth_dev *) malloc(sizeof(struct dw_eth_dev));
+
+    if (!priv) {
+        free(dev);
+        return -ENOMEM;
+    }
+
+    memset(dev, 0, sizeof(struct eth_device));
+    memset(priv, 0, sizeof(struct dw_eth_dev));
+
+    sprintf(dev->name, "dwmac.%lx", base_addr);
+    dev->iobase = (int)base_addr;
+    dev->priv = priv;
+
+    priv->dev = dev;
+    priv->mac_regs_p = (struct eth_mac_regs *)base_addr;
+    priv->dma_regs_p = (struct eth_dma_regs *)(base_addr +
+                                               DW_DMA_BASE_OFFSET);
+
+    priv->interface = interface;
+
+    dw_mdio_init(dev->name, priv->mac_regs_p);
+    priv->bus = miiphy_get_dev_by_name(dev->name);
+
+    return dw_phy_init(priv, dev);
+}
+
+int designware_startup(struct eth_device *dev)
+{
+    int ret;
+
+    ret = designware_eth_init(dev->priv, dev->enetaddr);
+
+    return ret;
+}
+
+int designware_enable(struct eth_device *dev)
+{
+    struct dw_eth_dev *priv = (struct dw_eth_dev *) dev->priv;
+
+    struct eth_mac_regs *mac_p = priv->mac_regs_p;
+    struct eth_dma_regs *dma_p = priv->dma_regs_p;
+
+    if (!priv->phydev->link) {
+        return -EIO;
+    }
+
+    writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf);
+    writel(readl(&dma_p->opmode) | TXSTART | RXSTART, &dma_p->opmode);
+
+    return 0;
+}
+
+int designware_write_descriptors(struct eth_device *dev, uintptr_t tx_ring_base, uintptr_t rx_ring_base)
+{
+    struct dw_eth_dev *priv = (struct dw_eth_dev *) dev->priv;
+    struct eth_dma_regs *dma_p = priv->dma_regs_p;
+    writel((ulong)tx_ring_base, &dma_p->txdesclistaddr);
+    writel((ulong)rx_ring_base, &dma_p->rxdesclistaddr);
+
+    return 0;
+}
+
+int designware_interrupt_status(struct eth_device *dev, uint32_t *ret_status)
+{
+    struct dw_eth_dev *priv = (struct dw_eth_dev *) dev->priv;
+    *ret_status = readl(&priv->dma_regs_p->status);
+    return 0;
+}
+
+int designware_start_send(struct eth_device *dev)
+{
+    /* Start the transmission */
+    struct dw_eth_dev *priv = (struct dw_eth_dev *) dev->priv;
+    struct eth_dma_regs *dma_p = priv->dma_regs_p;
+    writel(POLL_DATA, &dma_p->txpolldemand);
+    return 0;
+}
+
+int designware_start_receive(struct eth_device *dev)
+{
+    /* Start the transmission */
+    struct dw_eth_dev *priv = (struct dw_eth_dev *) dev->priv;
+    struct eth_dma_regs *dma_p = priv->dma_regs_p;
+    writel(POLL_DATA, &dma_p->rxpolldemand);
+    return 0;
+}
diff --git a/libethdrivers/src/plat/odroidc2/uboot/designware.h b/libethdrivers/src/plat/odroidc2/uboot/designware.h
new file mode 100644
index 0000000..c25822b
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/designware.h
@@ -0,0 +1,255 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * (C) Copyright 2010
+ * Vipin Kumar, ST Micoelectronics, vipin.kumar@st.com.
+ */
+
+#pragma once
+
+#ifdef CONFIG_DM_GPIO
+#include <asm-generic/gpio.h>
+#endif
+
+#define CONFIG_TX_DESCR_NUM 16
+#define CONFIG_RX_DESCR_NUM 16
+#define CONFIG_ETH_BUFSIZE  2048
+#define TX_TOTAL_BUFSIZE    (CONFIG_ETH_BUFSIZE * CONFIG_TX_DESCR_NUM)
+#define RX_TOTAL_BUFSIZE    (CONFIG_ETH_BUFSIZE * CONFIG_RX_DESCR_NUM)
+
+#define CONFIG_MACRESET_TIMEOUT (3 * CONFIG_SYS_HZ)
+#define CONFIG_MDIO_TIMEOUT (3 * CONFIG_SYS_HZ)
+
+struct eth_mac_regs {
+    u32 conf;       /* 0x00 */
+    u32 framefilt;      /* 0x04 */
+    u32 hashtablehigh;  /* 0x08 */
+    u32 hashtablelow;   /* 0x0c */
+    u32 miiaddr;        /* 0x10 */
+    u32 miidata;        /* 0x14 */
+    u32 flowcontrol;    /* 0x18 */
+    u32 vlantag;        /* 0x1c */
+    u32 version;        /* 0x20 */
+    u8 reserved_1[20];
+    u32 intreg;     /* 0x38 */
+    u32 intmask;        /* 0x3c */
+    u32 macaddr0hi;     /* 0x40 */
+    u32 macaddr0lo;     /* 0x44 */
+};
+
+/* MAC configuration register definitions */
+#define FRAMEBURSTENABLE    (1 << 21)
+#define MII_PORTSELECT      (1 << 15)
+#define FES_100         (1 << 14)
+#define DISABLERXOWN        (1 << 13)
+#define FULLDPLXMODE        (1 << 11)
+#define RXENABLE        (1 << 2)
+#define TXENABLE        (1 << 3)
+
+/* MII address register definitions */
+#define MII_BUSY        (1 << 0)
+#define MII_WRITE       (1 << 1)
+#define MII_CLKRANGE_60_100M    (0)
+#define MII_CLKRANGE_100_150M   (0x4)
+#define MII_CLKRANGE_20_35M (0x8)
+#define MII_CLKRANGE_35_60M (0xC)
+#define MII_CLKRANGE_150_250M   (0x10)
+#define MII_CLKRANGE_250_300M   (0x14)
+
+#define MIIADDRSHIFT        (11)
+#define MIIREGSHIFT     (6)
+#define MII_REGMSK      (0x1F << 6)
+#define MII_ADDRMSK     (0x1F << 11)
+
+
+struct eth_dma_regs {
+    u32 busmode;        /* 0x00 */
+    u32 txpolldemand;   /* 0x04 */
+    u32 rxpolldemand;   /* 0x08 */
+    u32 rxdesclistaddr; /* 0x0c */
+    u32 txdesclistaddr; /* 0x10 */
+    u32 status;     /* 0x14 */
+    u32 opmode;     /* 0x18 */
+    u32 intenable;      /* 0x1c */
+    u32 reserved1[2];
+    u32 axibus;     /* 0x28 */
+    u32 reserved2[7];
+    u32 currhosttxdesc; /* 0x48 */
+    u32 currhostrxdesc; /* 0x4c */
+    u32 currhosttxbuffaddr; /* 0x50 */
+    u32 currhostrxbuffaddr; /* 0x54 */
+};
+
+#define DW_DMA_BASE_OFFSET  (0x1000)
+
+/* Default DMA Burst length */
+#ifndef CONFIG_DW_GMAC_DEFAULT_DMA_PBL
+#define CONFIG_DW_GMAC_DEFAULT_DMA_PBL 8
+#endif
+
+/* Bus mode register definitions */
+#define FIXEDBURST      (1 << 16)
+#define PRIORXTX_41     (3 << 14)
+#define PRIORXTX_31     (2 << 14)
+#define PRIORXTX_21     (1 << 14)
+#define PRIORXTX_11     (0 << 14)
+#define DMA_PBL         (CONFIG_DW_GMAC_DEFAULT_DMA_PBL<<8)
+#define RXHIGHPRIO      (1 << 1)
+#define DMAMAC_SRST     (1 << 0)
+
+/* Poll demand definitions */
+#define POLL_DATA       (0xFFFFFFFF)
+
+/* Operation mode definitions */
+#define STOREFORWARD        (1 << 21)
+#define FLUSHTXFIFO     (1 << 20)
+#define TXSTART         (1 << 13)
+#define TXSECONDFRAME       (1 << 2)
+#define RXSTART         (1 << 1)
+
+/* Descriptior related definitions */
+#define MAC_MAX_FRAME_SZ    (1600)
+
+#define DMA_INTR_ENA_TIE 0x00000001 /* Transmit interrupt */
+#define DMA_INTR_ENA_NIE 0x00010000 /* Normal summary */
+#define DMA_INTR_ENA_RIE 0x00000040 /* Receive Interrupt */
+
+#define DMA_INTR_NORMAL (DMA_INTR_ENA_NIE | DMA_INTR_ENA_RIE | \
+                    DMA_INTR_ENA_TIE)
+
+#define DMA_INTR_ENA_AIE 0x00008000 /* Abnormal Summary */
+#define DMA_INTR_ENA_FBE 0x00002000 /* Fatal Bus Error */
+#define DMA_INTR_ENA_UNE 0x00000020 /* Tx Underflow */
+
+#define DMA_INTR_ABNORMAL   (DMA_INTR_ENA_AIE | DMA_INTR_ENA_FBE | \
+                        DMA_INTR_ENA_UNE)
+#define DMA_INTR_DEFAULT_MASK   (DMA_INTR_NORMAL | DMA_INTR_ABNORMAL)
+
+struct dmamacdescr {
+    u32 txrx_status;
+    u32 dmamac_cntl;
+    u32 dmamac_addr;
+    u32 dmamac_next;
+} __aligned(ARCH_DMA_MINALIGN);
+
+/*
+ * txrx_status definitions
+ */
+
+/* tx status bits definitions */
+#if defined(CONFIG_DW_ALTDESCRIPTOR)
+
+#define DESC_TXSTS_OWNBYDMA     (1 << 31)
+#define DESC_TXSTS_TXINT        (1 << 30)
+#define DESC_TXSTS_TXLAST       (1 << 29)
+#define DESC_TXSTS_TXFIRST      (1 << 28)
+#define DESC_TXSTS_TXCRCDIS     (1 << 27)
+
+#define DESC_TXSTS_TXPADDIS     (1 << 26)
+#define DESC_TXSTS_TXCHECKINSCTRL   (3 << 22)
+#define DESC_TXSTS_TXRINGEND        (1 << 21)
+#define DESC_TXSTS_TXCHAIN      (1 << 20)
+#define DESC_TXSTS_MSK          (0x1FFFF << 0)
+
+#else
+
+#define DESC_TXSTS_OWNBYDMA     (1 << 31)
+#define DESC_TXSTS_MSK          (0x1FFFF << 0)
+
+#endif
+
+/* rx status bits definitions */
+#define DESC_RXSTS_OWNBYDMA     (1 << 31)
+#define DESC_RXSTS_DAFILTERFAIL     (1 << 30)
+#define DESC_RXSTS_FRMLENMSK        (0x3FFF << 16)
+#define DESC_RXSTS_FRMLENSHFT       (16)
+
+#define DESC_RXSTS_ERROR        (1 << 15)
+#define DESC_RXSTS_RXTRUNCATED      (1 << 14)
+#define DESC_RXSTS_SAFILTERFAIL     (1 << 13)
+#define DESC_RXSTS_RXIPC_GIANTFRAME (1 << 12)
+#define DESC_RXSTS_RXDAMAGED        (1 << 11)
+#define DESC_RXSTS_RXVLANTAG        (1 << 10)
+#define DESC_RXSTS_RXFIRST      (1 << 9)
+#define DESC_RXSTS_RXLAST       (1 << 8)
+#define DESC_RXSTS_RXIPC_GIANT      (1 << 7)
+#define DESC_RXSTS_RXCOLLISION      (1 << 6)
+#define DESC_RXSTS_RXFRAMEETHER     (1 << 5)
+#define DESC_RXSTS_RXWATCHDOG       (1 << 4)
+#define DESC_RXSTS_RXMIIERROR       (1 << 3)
+#define DESC_RXSTS_RXDRIBBLING      (1 << 2)
+#define DESC_RXSTS_RXCRC        (1 << 1)
+
+/*
+ * dmamac_cntl definitions
+ */
+
+/* tx control bits definitions */
+#if defined(CONFIG_DW_ALTDESCRIPTOR)
+
+#define DESC_TXCTRL_SIZE1MASK       (0x1FFF << 0)
+#define DESC_TXCTRL_SIZE1SHFT       (0)
+#define DESC_TXCTRL_SIZE2MASK       (0x1FFF << 16)
+#define DESC_TXCTRL_SIZE2SHFT       (16)
+
+#else
+
+#define DESC_TXCTRL_TXINT       (1 << 31)
+#define DESC_TXCTRL_TXLAST      (1 << 30)
+#define DESC_TXCTRL_TXFIRST     (1 << 29)
+#define DESC_TXCTRL_TXCHECKINSCTRL  (3 << 27)
+#define DESC_TXCTRL_TXCRCDIS        (1 << 26)
+#define DESC_TXCTRL_TXRINGEND       (1 << 25)
+#define DESC_TXCTRL_TXCHAIN     (1 << 24)
+
+#define DESC_TXCTRL_SIZE1MASK       (0x7FF << 0)
+#define DESC_TXCTRL_SIZE1SHFT       (0)
+#define DESC_TXCTRL_SIZE2MASK       (0x7FF << 11)
+#define DESC_TXCTRL_SIZE2SHFT       (11)
+
+#endif
+
+/* rx control bits definitions */
+#if defined(CONFIG_DW_ALTDESCRIPTOR)
+
+#define DESC_RXCTRL_RXINTDIS        (1 << 31)
+#define DESC_RXCTRL_RXRINGEND       (1 << 15)
+#define DESC_RXCTRL_RXCHAIN     (1 << 14)
+
+#define DESC_RXCTRL_SIZE1MASK       (0x1FFF << 0)
+#define DESC_RXCTRL_SIZE1SHFT       (0)
+#define DESC_RXCTRL_SIZE2MASK       (0x1FFF << 16)
+#define DESC_RXCTRL_SIZE2SHFT       (16)
+
+#else
+
+#define DESC_RXCTRL_RXINTDIS        (1 << 31)
+#define DESC_RXCTRL_RXRINGEND       (1 << 25)
+#define DESC_RXCTRL_RXCHAIN     (1 << 24)
+
+#define DESC_RXCTRL_SIZE1MASK       (0x7FF << 0)
+#define DESC_RXCTRL_SIZE1SHFT       (0)
+#define DESC_RXCTRL_SIZE2MASK       (0x7FF << 11)
+#define DESC_RXCTRL_SIZE2SHFT       (11)
+
+#endif
+
+struct dw_eth_dev {
+    u32 interface;
+    u32 max_speed;
+
+    struct eth_mac_regs *mac_regs_p;
+    struct eth_dma_regs *dma_regs_p;
+#ifndef CONFIG_DM_ETH
+    struct eth_device *dev;
+#endif
+#ifdef CONFIG_DM_GPIO
+    struct gpio_desc reset_gpio;
+#endif
+#ifdef CONFIG_CLK
+    struct clk *clocks; /* clock list */
+    int clock_count;    /* number of clock in clock list */
+#endif
+
+    struct phy_device *phydev;
+    struct mii_dev *bus;
+};
diff --git a/libethdrivers/src/plat/odroidc2/uboot/err.h b/libethdrivers/src/plat/odroidc2/uboot/err.h
new file mode 100644
index 0000000..f1e815a
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/err.h
@@ -0,0 +1,52 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ * Copyright Linux
+ */
+#pragma once
+
+#include <errno.h>
+
+
+/*
+ * Kernel pointers have redundant information, so we can use a
+ * scheme where we can return either an error code or a dentry
+ * pointer with the same return value.
+ *
+ * This should be a per-architecture thing, to allow different
+ * error and pointer decisions.
+ */
+#define MAX_ERRNO   4095
+
+#ifndef __ASSEMBLY__
+
+#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO)
+
+static inline void *ERR_PTR(long error)
+{
+    return (void *) error;
+}
+
+static inline long PTR_ERR(const void *ptr)
+{
+    return (long) ptr;
+}
+
+static inline long IS_ERR(const void *ptr)
+{
+    return IS_ERR_VALUE((unsigned long)ptr);
+}
+
+/**
+ * ERR_CAST - Explicitly cast an error-valued pointer to another pointer type
+ * @ptr: The pointer to cast.
+ *
+ * Explicitly cast an error-valued pointer to another pointer type in such a
+ * way as to make it clear that's what's going on.
+ */
+static inline void *__must_check ERR_CAST(__force const void *ptr)
+{
+    /* cast away the const */
+    return (void *) ptr;
+}
+
+#endif
diff --git a/libethdrivers/src/plat/odroidc2/uboot/ethtool.h b/libethdrivers/src/plat/odroidc2/uboot/ethtool.h
new file mode 100644
index 0000000..1fdd90b
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/ethtool.h
@@ -0,0 +1,726 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+/*
+ * ethtool.h: Defines for Linux ethtool.
+ *
+ * Copyright (C) 1998 David S. Miller (davem@redhat.com)
+ * Copyright 2001 Jeff Garzik <jgarzik@pobox.com>
+ * Portions Copyright 2001 Sun Microsystems (thockin@sun.com)
+ * Portions Copyright 2002 Intel (eli.kupermann@intel.com,
+ *                                christopher.leech@intel.com,
+ *                                scott.feldman@intel.com)
+ * Portions Copyright (C) Sun Microsystems 2008
+ */
+
+#pragma once
+
+#include <stdint.h>
+
+/* This should work for both 32 and 64 bit userland. */
+struct ethtool_cmd {
+    uint32_t    cmd;
+    uint32_t    supported;  /* Features this interface supports */
+    uint32_t    advertising;    /* Features this interface advertises */
+    uint16_t    speed;      /* The forced speed, 10Mb, 100Mb, gigabit */
+    uint8_t duplex;     /* Duplex, half or full */
+    uint8_t port;       /* Which connector port */
+    uint8_t phy_address;
+    uint8_t transceiver;    /* Which transceiver to use */
+    uint8_t autoneg;    /* Enable or disable autonegotiation */
+    uint8_t mdio_support;
+    uint32_t    maxtxpkt;   /* Tx pkts before generating tx int */
+    uint32_t    maxrxpkt;   /* Rx pkts before generating rx int */
+    uint16_t    speed_hi;
+    uint8_t eth_tp_mdix;
+    uint8_t reserved2;
+    uint32_t    lp_advertising; /* Features the link partner advertises */
+    uint32_t    reserved[2];
+};
+
+static inline void ethtool_cmd_speed_set(struct ethtool_cmd *ep,
+                                         uint32_t speed)
+{
+
+    ep->speed = (uint16_t)speed;
+    ep->speed_hi = (uint16_t)(speed >> 16);
+}
+
+static inline uint32_t ethtool_cmd_speed(struct ethtool_cmd *ep)
+{
+    return (ep->speed_hi << 16) | ep->speed;
+}
+
+#define ETHTOOL_FWVERS_LEN  32
+#define ETHTOOL_BUSINFO_LEN 32
+/* these strings are set to whatever the driver author decides... */
+struct ethtool_drvinfo {
+    uint32_t    cmd;
+    char    driver[32]; /* driver short name, "tulip", "eepro100" */
+    char    version[32];    /* driver version string */
+    char    fw_version[ETHTOOL_FWVERS_LEN]; /* firmware version string */
+    char    bus_info[ETHTOOL_BUSINFO_LEN];  /* Bus info for this IF. */
+    /* For PCI devices, use pci_name(pci_dev). */
+    char    reserved1[32];
+    char    reserved2[12];
+    /*
+     * Some struct members below are filled in
+     * using ops->get_sset_count().  Obtaining
+     * this info from ethtool_drvinfo is now
+     * deprecated; Use ETHTOOL_GSSET_INFO
+     * instead.
+     */
+    uint32_t    n_priv_flags;   /* number of flags valid in ETHTOOL_GPFLAGS */
+    uint32_t    n_stats;    /* number of u64's from ETHTOOL_GSTATS */
+    uint32_t    testinfo_len;
+    uint32_t    eedump_len; /* Size of data from ETHTOOL_GEEPROM (bytes) */
+    uint32_t    regdump_len;    /* Size of data from ETHTOOL_GREGS (bytes) */
+};
+
+#define SOPASS_MAX  6
+/* wake-on-lan settings */
+struct ethtool_wolinfo {
+    uint32_t    cmd;
+    uint32_t    supported;
+    uint32_t    wolopts;
+    uint8_t sopass[SOPASS_MAX]; /* SecureOn(tm) password */
+};
+
+/* for passing single values */
+struct ethtool_value {
+    uint32_t    cmd;
+    uint32_t    data;
+};
+
+/* for passing big chunks of data */
+struct ethtool_regs {
+    uint32_t    cmd;
+    uint32_t    version; /* driver-specific, indicates different chips/revs */
+    uint32_t    len; /* bytes */
+    uint8_t data[0];
+};
+
+/* for passing EEPROM chunks */
+struct ethtool_eeprom {
+    uint32_t    cmd;
+    uint32_t    magic;
+    uint32_t    offset; /* in bytes */
+    uint32_t    len; /* in bytes */
+    uint8_t data[0];
+};
+
+/* for configuring coalescing parameters of chip */
+struct ethtool_coalesce {
+    uint32_t    cmd;    /* ETHTOOL_{G,S}COALESCE */
+
+    /* How many usecs to delay an RX interrupt after
+     * a packet arrives.  If 0, only rx_max_coalesced_frames
+     * is used.
+     */
+    uint32_t    rx_coalesce_usecs;
+
+    /* How many packets to delay an RX interrupt after
+     * a packet arrives.  If 0, only rx_coalesce_usecs is
+     * used.  It is illegal to set both usecs and max frames
+     * to zero as this would cause RX interrupts to never be
+     * generated.
+     */
+    uint32_t    rx_max_coalesced_frames;
+
+    /* Same as above two parameters, except that these values
+     * apply while an IRQ is being serviced by the host.  Not
+     * all cards support this feature and the values are ignored
+     * in that case.
+     */
+    uint32_t    rx_coalesce_usecs_irq;
+    uint32_t    rx_max_coalesced_frames_irq;
+
+    /* How many usecs to delay a TX interrupt after
+     * a packet is sent.  If 0, only tx_max_coalesced_frames
+     * is used.
+     */
+    uint32_t    tx_coalesce_usecs;
+
+    /* How many packets to delay a TX interrupt after
+     * a packet is sent.  If 0, only tx_coalesce_usecs is
+     * used.  It is illegal to set both usecs and max frames
+     * to zero as this would cause TX interrupts to never be
+     * generated.
+     */
+    uint32_t    tx_max_coalesced_frames;
+
+    /* Same as above two parameters, except that these values
+     * apply while an IRQ is being serviced by the host.  Not
+     * all cards support this feature and the values are ignored
+     * in that case.
+     */
+    uint32_t    tx_coalesce_usecs_irq;
+    uint32_t    tx_max_coalesced_frames_irq;
+
+    /* How many usecs to delay in-memory statistics
+     * block updates.  Some drivers do not have an in-memory
+     * statistic block, and in such cases this value is ignored.
+     * This value must not be zero.
+     */
+    uint32_t    stats_block_coalesce_usecs;
+
+    /* Adaptive RX/TX coalescing is an algorithm implemented by
+     * some drivers to improve latency under low packet rates and
+     * improve throughput under high packet rates.  Some drivers
+     * only implement one of RX or TX adaptive coalescing.  Anything
+     * not implemented by the driver causes these values to be
+     * silently ignored.
+     */
+    uint32_t    use_adaptive_rx_coalesce;
+    uint32_t    use_adaptive_tx_coalesce;
+
+    /* When the packet rate (measured in packets per second)
+     * is below pkt_rate_low, the {rx,tx}_*_low parameters are
+     * used.
+     */
+    uint32_t    pkt_rate_low;
+    uint32_t    rx_coalesce_usecs_low;
+    uint32_t    rx_max_coalesced_frames_low;
+    uint32_t    tx_coalesce_usecs_low;
+    uint32_t    tx_max_coalesced_frames_low;
+
+    /* When the packet rate is below pkt_rate_high but above
+     * pkt_rate_low (both measured in packets per second) the
+     * normal {rx,tx}_* coalescing parameters are used.
+     */
+
+    /* When the packet rate is (measured in packets per second)
+     * is above pkt_rate_high, the {rx,tx}_*_high parameters are
+     * used.
+     */
+    uint32_t    pkt_rate_high;
+    uint32_t    rx_coalesce_usecs_high;
+    uint32_t    rx_max_coalesced_frames_high;
+    uint32_t    tx_coalesce_usecs_high;
+    uint32_t    tx_max_coalesced_frames_high;
+
+    /* How often to do adaptive coalescing packet rate sampling,
+     * measured in seconds.  Must not be zero.
+     */
+    uint32_t    rate_sample_interval;
+};
+
+/* for configuring RX/TX ring parameters */
+struct ethtool_ringparam {
+    uint32_t    cmd;    /* ETHTOOL_{G,S}RINGPARAM */
+
+    /* Read only attributes.  These indicate the maximum number
+     * of pending RX/TX ring entries the driver will allow the
+     * user to set.
+     */
+    uint32_t    rx_max_pending;
+    uint32_t    rx_mini_max_pending;
+    uint32_t    rx_jumbo_max_pending;
+    uint32_t    tx_max_pending;
+
+    /* Values changeable by the user.  The valid values are
+     * in the range 1 to the "*_max_pending" counterpart above.
+     */
+    uint32_t    rx_pending;
+    uint32_t    rx_mini_pending;
+    uint32_t    rx_jumbo_pending;
+    uint32_t    tx_pending;
+};
+
+/* for configuring link flow control parameters */
+struct ethtool_pauseparam {
+    uint32_t    cmd;    /* ETHTOOL_{G,S}PAUSEPARAM */
+
+    /* If the link is being auto-negotiated (via ethtool_cmd.autoneg
+     * being true) the user may set 'autonet' here non-zero to have the
+     * pause parameters be auto-negotiated too.  In such a case, the
+     * {rx,tx}_pause values below determine what capabilities are
+     * advertised.
+     *
+     * If 'autoneg' is zero or the link is not being auto-negotiated,
+     * then {rx,tx}_pause force the driver to use/not-use pause
+     * flow control.
+     */
+    uint32_t    autoneg;
+    uint32_t    rx_pause;
+    uint32_t    tx_pause;
+};
+
+#define ETH_GSTRING_LEN     32
+enum ethtool_stringset {
+    ETH_SS_TEST     = 0,
+    ETH_SS_STATS,
+    ETH_SS_PRIV_FLAGS,
+    ETH_SS_NTUPLE_FILTERS,
+    ETH_SS_FEATURES,
+};
+
+/* for passing string sets for data tagging */
+struct ethtool_gstrings {
+    uint32_t    cmd;        /* ETHTOOL_GSTRINGS */
+    uint32_t    string_set; /* string set id e.c. ETH_SS_TEST, etc*/
+    uint32_t    len;        /* number of strings in the string set */
+    uint8_t data[0];
+};
+
+struct ethtool_sset_info {
+    uint32_t    cmd;        /* ETHTOOL_GSSET_INFO */
+    uint32_t    reserved;
+    uint64_t    sset_mask;  /* input: each bit selects an sset to query */
+    /* output: each bit a returned sset */
+    uint32_t    data[0];    /* ETH_SS_xxx count, in order, based on bits
+                   in sset_mask.  One bit implies one
+                   uint32_t, two bits implies two
+                   uint32_t's, etc. */
+};
+
+enum ethtool_test_flags {
+    ETH_TEST_FL_OFFLINE = (1 << 0), /* online / offline */
+    ETH_TEST_FL_FAILED  = (1 << 1), /* test passed / failed */
+};
+
+/* for requesting NIC test and getting results*/
+struct ethtool_test {
+    uint32_t    cmd;        /* ETHTOOL_TEST */
+    uint32_t    flags;      /* ETH_TEST_FL_xxx */
+    uint32_t    reserved;
+    uint32_t    len;        /* result length, in number of u64 elements */
+    uint64_t    data[0];
+};
+
+/* for dumping NIC-specific statistics */
+struct ethtool_stats {
+    uint32_t    cmd;        /* ETHTOOL_GSTATS */
+    uint32_t    n_stats;    /* number of u64's being returned */
+    uint64_t    data[0];
+};
+
+struct ethtool_perm_addr {
+    uint32_t    cmd;        /* ETHTOOL_GPERMADDR */
+    uint32_t    size;
+    uint8_t data[0];
+};
+
+/* boolean flags controlling per-interface behavior characteristics.
+ * When reading, the flag indicates whether or not a certain behavior
+ * is enabled/present.  When writing, the flag indicates whether
+ * or not the driver should turn on (set) or off (clear) a behavior.
+ *
+ * Some behaviors may read-only (unconditionally absent or present).
+ * If such is the case, return EINVAL in the set-flags operation if the
+ * flag differs from the read-only value.
+ */
+enum ethtool_flags {
+    ETH_FLAG_TXVLAN     = (1 << 7), /* TX VLAN offload enabled */
+    ETH_FLAG_RXVLAN     = (1 << 8), /* RX VLAN offload enabled */
+    ETH_FLAG_LRO        = (1 << 15),    /* LRO is enabled */
+    ETH_FLAG_NTUPLE     = (1 << 27),    /* N-tuple filters enabled */
+    ETH_FLAG_RXHASH     = (1 << 28),
+};
+
+/* The following structures are for supporting RX network flow
+ * classification and RX n-tuple configuration. Note, all multibyte
+ * fields, e.g., ip4src, ip4dst, psrc, pdst, spi, etc. are expected to
+ * be in network byte order.
+ */
+
+/**
+ * struct ethtool_tcpip4_spec - flow specification for TCP/IPv4 etc.
+ * @ip4src: Source host
+ * @ip4dst: Destination host
+ * @psrc: Source port
+ * @pdst: Destination port
+ * @tos: Type-of-service
+ *
+ * This can be used to specify a TCP/IPv4, UDP/IPv4 or SCTP/IPv4 flow.
+ */
+struct ethtool_tcpip4_spec {
+    uint32_t    ip4src;
+    uint32_t    ip4dst;
+    uint16_t    psrc;
+    uint16_t    pdst;
+    uint8_t    tos;
+};
+
+/**
+ * struct ethtool_ah_espip4_spec - flow specification for IPsec/IPv4
+ * @ip4src: Source host
+ * @ip4dst: Destination host
+ * @spi: Security parameters index
+ * @tos: Type-of-service
+ *
+ * This can be used to specify an IPsec transport or tunnel over IPv4.
+ */
+struct ethtool_ah_espip4_spec {
+    uint32_t    ip4src;
+    uint32_t    ip4dst;
+    uint32_t    spi;
+    uint8_t    tos;
+};
+
+#define ETH_RX_NFC_IP4  1
+
+/**
+ * struct ethtool_usrip4_spec - general flow specification for IPv4
+ * @ip4src: Source host
+ * @ip4dst: Destination host
+ * @l4_4_bytes: First 4 bytes of transport (layer 4) header
+ * @tos: Type-of-service
+ * @ip_ver: Value must be %ETH_RX_NFC_IP4; mask must be 0
+ * @proto: Transport protocol number; mask must be 0
+ */
+struct ethtool_usrip4_spec {
+    uint32_t    ip4src;
+    uint32_t    ip4dst;
+    uint32_t    l4_4_bytes;
+    uint8_t    tos;
+    uint8_t    ip_ver;
+    uint8_t    proto;
+};
+
+
+/**
+ * struct ethtool_rxfh_indir - command to get or set RX flow hash indirection
+ * @cmd: Specific command number - %ETHTOOL_GRXFHINDIR or %ETHTOOL_SRXFHINDIR
+ * @size: On entry, the array size of the user buffer.  On return from
+ *  %ETHTOOL_GRXFHINDIR, the array size of the hardware indirection table.
+ * @ring_index: RX ring/queue index for each hash value
+ */
+struct ethtool_rxfh_indir {
+    uint32_t    cmd;
+    uint32_t    size;
+    uint32_t    ring_index[0];
+};
+
+#define ETHTOOL_FLASH_MAX_FILENAME  128
+enum ethtool_flash_op_type {
+    ETHTOOL_FLASH_ALL_REGIONS   = 0,
+};
+
+/* for passing firmware flashing related parameters */
+struct ethtool_flash {
+    uint32_t    cmd;
+    uint32_t    region;
+    char    data[ETHTOOL_FLASH_MAX_FILENAME];
+};
+
+/* for returning and changing feature sets */
+
+/**
+ * struct ethtool_get_features_block - block with state of 32 features
+ * @available: mask of changeable features
+ * @requested: mask of features requested to be enabled if possible
+ * @active: mask of currently enabled features
+ * @never_changed: mask of features not changeable for any device
+ */
+struct ethtool_get_features_block {
+    uint32_t    available;
+    uint32_t    requested;
+    uint32_t    active;
+    uint32_t    never_changed;
+};
+
+/**
+ * struct ethtool_gfeatures - command to get state of device's features
+ * @cmd: command number = %ETHTOOL_GFEATURES
+ * @size: in: number of elements in the features[] array;
+ *       out: number of elements in features[] needed to hold all features
+ * @features: state of features
+ */
+struct ethtool_gfeatures {
+    uint32_t    cmd;
+    uint32_t    size;
+    struct ethtool_get_features_block features[0];
+};
+
+/**
+ * struct ethtool_set_features_block - block with request for 32 features
+ * @valid: mask of features to be changed
+ * @requested: values of features to be changed
+ */
+struct ethtool_set_features_block {
+    uint32_t    valid;
+    uint32_t    requested;
+};
+
+/**
+ * struct ethtool_sfeatures - command to request change in device's features
+ * @cmd: command number = %ETHTOOL_SFEATURES
+ * @size: array size of the features[] array
+ * @features: feature change masks
+ */
+struct ethtool_sfeatures {
+    uint32_t    cmd;
+    uint32_t    size;
+    struct ethtool_set_features_block features[0];
+};
+
+/*
+ * %ETHTOOL_SFEATURES changes features present in features[].valid to the
+ * values of corresponding bits in features[].requested. Bits in .requested
+ * not set in .valid or not changeable are ignored.
+ *
+ * Returns %EINVAL when .valid contains undefined or never-changable bits
+ * or size is not equal to required number of features words (32-bit blocks).
+ * Returns >= 0 if request was completed; bits set in the value mean:
+ *   %ETHTOOL_F_UNSUPPORTED - there were bits set in .valid that are not
+ *  changeable (not present in %ETHTOOL_GFEATURES' features[].available)
+ *  those bits were ignored.
+ *   %ETHTOOL_F_WISH - some or all changes requested were recorded but the
+ *      resulting state of bits masked by .valid is not equal to .requested.
+ *      Probably there are other device-specific constraints on some features
+ *      in the set. When %ETHTOOL_F_UNSUPPORTED is set, .valid is considered
+ *      here as though ignored bits were cleared.
+ *   %ETHTOOL_F_COMPAT - some or all changes requested were made by calling
+ *      compatibility functions. Requested offload state cannot be properly
+ *      managed by kernel.
+ *
+ * Meaning of bits in the masks are obtained by %ETHTOOL_GSSET_INFO (number of
+ * bits in the arrays - always multiple of 32) and %ETHTOOL_GSTRINGS commands
+ * for ETH_SS_FEATURES string set. First entry in the table corresponds to least
+ * significant bit in features[0] fields. Empty strings mark undefined features.
+ */
+enum ethtool_sfeatures_retval_bits {
+    ETHTOOL_F_UNSUPPORTED__BIT,
+    ETHTOOL_F_WISH__BIT,
+    ETHTOOL_F_COMPAT__BIT,
+};
+
+#define ETHTOOL_F_UNSUPPORTED   (1 << ETHTOOL_F_UNSUPPORTED__BIT)
+#define ETHTOOL_F_WISH          (1 << ETHTOOL_F_WISH__BIT)
+#define ETHTOOL_F_COMPAT        (1 << ETHTOOL_F_COMPAT__BIT)
+
+/* CMDs currently supported */
+#define ETHTOOL_GSET        0x00000001 /* Get settings. */
+#define ETHTOOL_SSET        0x00000002 /* Set settings. */
+#define ETHTOOL_GDRVINFO    0x00000003 /* Get driver info. */
+#define ETHTOOL_GREGS       0x00000004 /* Get NIC registers. */
+#define ETHTOOL_GWOL        0x00000005 /* Get wake-on-lan options. */
+#define ETHTOOL_SWOL        0x00000006 /* Set wake-on-lan options. */
+#define ETHTOOL_GMSGLVL     0x00000007 /* Get driver message level */
+#define ETHTOOL_SMSGLVL     0x00000008 /* Set driver msg level. */
+#define ETHTOOL_NWAY_RST    0x00000009 /* Restart autonegotiation. */
+/* Get link status for host, i.e. whether the interface *and* the
+ * physical port (if there is one) are up (ethtool_value). */
+#define ETHTOOL_GLINK       0x0000000a
+#define ETHTOOL_GEEPROM     0x0000000b /* Get EEPROM data */
+#define ETHTOOL_SEEPROM     0x0000000c /* Set EEPROM data. */
+#define ETHTOOL_GCOALESCE   0x0000000e /* Get coalesce config */
+#define ETHTOOL_SCOALESCE   0x0000000f /* Set coalesce config. */
+#define ETHTOOL_GRINGPARAM  0x00000010 /* Get ring parameters */
+#define ETHTOOL_SRINGPARAM  0x00000011 /* Set ring parameters. */
+#define ETHTOOL_GPAUSEPARAM 0x00000012 /* Get pause parameters */
+#define ETHTOOL_SPAUSEPARAM 0x00000013 /* Set pause parameters. */
+#define ETHTOOL_GRXCSUM     0x00000014 /* Get RX hw csum enable (ethtool_value) */
+#define ETHTOOL_SRXCSUM     0x00000015 /* Set RX hw csum enable (ethtool_value) */
+#define ETHTOOL_GTXCSUM     0x00000016 /* Get TX hw csum enable (ethtool_value) */
+#define ETHTOOL_STXCSUM     0x00000017 /* Set TX hw csum enable (ethtool_value) */
+#define ETHTOOL_GSG     0x00000018 /* Get scatter-gather enable
+                        * (ethtool_value) */
+#define ETHTOOL_SSG     0x00000019 /* Set scatter-gather enable
+                        * (ethtool_value). */
+#define ETHTOOL_TEST        0x0000001a /* execute NIC self-test. */
+#define ETHTOOL_GSTRINGS    0x0000001b /* get specified string set */
+#define ETHTOOL_PHYS_ID     0x0000001c /* identify the NIC */
+#define ETHTOOL_GSTATS      0x0000001d /* get NIC-specific statistics */
+#define ETHTOOL_GTSO        0x0000001e /* Get TSO enable (ethtool_value) */
+#define ETHTOOL_STSO        0x0000001f /* Set TSO enable (ethtool_value) */
+#define ETHTOOL_GPERMADDR   0x00000020 /* Get permanent hardware address */
+#define ETHTOOL_GUFO        0x00000021 /* Get UFO enable (ethtool_value) */
+#define ETHTOOL_SUFO        0x00000022 /* Set UFO enable (ethtool_value) */
+#define ETHTOOL_GGSO        0x00000023 /* Get GSO enable (ethtool_value) */
+#define ETHTOOL_SGSO        0x00000024 /* Set GSO enable (ethtool_value) */
+#define ETHTOOL_GFLAGS      0x00000025 /* Get flags bitmap(ethtool_value) */
+#define ETHTOOL_SFLAGS      0x00000026 /* Set flags bitmap(ethtool_value) */
+#define ETHTOOL_GPFLAGS     0x00000027 /* Get driver-private flags bitmap */
+#define ETHTOOL_SPFLAGS     0x00000028 /* Set driver-private flags bitmap */
+
+#define ETHTOOL_GRXFH       0x00000029 /* Get RX flow hash configuration */
+#define ETHTOOL_SRXFH       0x0000002a /* Set RX flow hash configuration */
+#define ETHTOOL_GGRO        0x0000002b /* Get GRO enable (ethtool_value) */
+#define ETHTOOL_SGRO        0x0000002c /* Set GRO enable (ethtool_value) */
+#define ETHTOOL_GRXRINGS    0x0000002d /* Get RX rings available for LB */
+#define ETHTOOL_GRXCLSRLCNT 0x0000002e /* Get RX class rule count */
+#define ETHTOOL_GRXCLSRULE  0x0000002f /* Get RX classification rule */
+#define ETHTOOL_GRXCLSRLALL 0x00000030 /* Get all RX classification rule */
+#define ETHTOOL_SRXCLSRLDEL 0x00000031 /* Delete RX classification rule */
+#define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */
+#define ETHTOOL_FLASHDEV    0x00000033 /* Flash firmware to device */
+#define ETHTOOL_RESET       0x00000034 /* Reset hardware */
+#define ETHTOOL_SRXNTUPLE   0x00000035 /* Add an n-tuple filter to device */
+#define ETHTOOL_GRXNTUPLE   0x00000036 /* Get n-tuple filters from device */
+#define ETHTOOL_GSSET_INFO  0x00000037 /* Get string set info */
+#define ETHTOOL_GRXFHINDIR  0x00000038 /* Get RX flow hash indir'n table */
+#define ETHTOOL_SRXFHINDIR  0x00000039 /* Set RX flow hash indir'n table */
+
+#define ETHTOOL_GFEATURES   0x0000003a /* Get device offload settings */
+#define ETHTOOL_SFEATURES   0x0000003b /* Change device offload settings */
+
+/* compatibility with older code */
+#define SPARC_ETH_GSET      ETHTOOL_GSET
+#define SPARC_ETH_SSET      ETHTOOL_SSET
+
+/* Indicates what features are supported by the interface. */
+#define SUPPORTED_10baseT_Half      (1 << 0)
+#define SUPPORTED_10baseT_Full      (1 << 1)
+#define SUPPORTED_100baseT_Half     (1 << 2)
+#define SUPPORTED_100baseT_Full     (1 << 3)
+#define SUPPORTED_1000baseT_Half    (1 << 4)
+#define SUPPORTED_1000baseT_Full    (1 << 5)
+#define SUPPORTED_Autoneg       (1 << 6)
+#define SUPPORTED_TP            (1 << 7)
+#define SUPPORTED_AUI           (1 << 8)
+#define SUPPORTED_MII           (1 << 9)
+#define SUPPORTED_FIBRE         (1 << 10)
+#define SUPPORTED_BNC           (1 << 11)
+#define SUPPORTED_10000baseT_Full   (1 << 12)
+#define SUPPORTED_Pause         (1 << 13)
+#define SUPPORTED_Asym_Pause        (1 << 14)
+#define SUPPORTED_2500baseX_Full    (1 << 15)
+#define SUPPORTED_Backplane     (1 << 16)
+#define SUPPORTED_1000baseKX_Full   (1 << 17)
+#define SUPPORTED_10000baseKX4_Full (1 << 18)
+#define SUPPORTED_10000baseKR_Full  (1 << 19)
+#define SUPPORTED_10000baseR_FEC    (1 << 20)
+#define SUPPORTED_1000baseX_Half    (1 << 21)
+#define SUPPORTED_1000baseX_Full    (1 << 22)
+
+/* Indicates what features are advertised by the interface. */
+#define ADVERTISED_10baseT_Half     (1 << 0)
+#define ADVERTISED_10baseT_Full     (1 << 1)
+#define ADVERTISED_100baseT_Half    (1 << 2)
+#define ADVERTISED_100baseT_Full    (1 << 3)
+#define ADVERTISED_1000baseT_Half   (1 << 4)
+#define ADVERTISED_1000baseT_Full   (1 << 5)
+#define ADVERTISED_Autoneg      (1 << 6)
+#define ADVERTISED_TP           (1 << 7)
+#define ADVERTISED_AUI          (1 << 8)
+#define ADVERTISED_MII          (1 << 9)
+#define ADVERTISED_FIBRE        (1 << 10)
+#define ADVERTISED_BNC          (1 << 11)
+#define ADVERTISED_10000baseT_Full  (1 << 12)
+#define ADVERTISED_Pause        (1 << 13)
+#define ADVERTISED_Asym_Pause       (1 << 14)
+#define ADVERTISED_2500baseX_Full   (1 << 15)
+#define ADVERTISED_Backplane        (1 << 16)
+#define ADVERTISED_1000baseKX_Full  (1 << 17)
+#define ADVERTISED_10000baseKX4_Full    (1 << 18)
+#define ADVERTISED_10000baseKR_Full (1 << 19)
+#define ADVERTISED_10000baseR_FEC   (1 << 20)
+#define ADVERTISED_1000baseX_Half   (1 << 21)
+#define ADVERTISED_1000baseX_Full   (1 << 22)
+
+/* The following are all involved in forcing a particular link
+ * mode for the device for setting things.  When getting the
+ * devices settings, these indicate the current mode and whether
+ * it was foced up into this mode or autonegotiated.
+ */
+
+/* The forced speed, 10Mb, 100Mb, gigabit, 2.5Gb, 10GbE. */
+#define SPEED_10        10
+#define SPEED_100       100
+#define SPEED_1000      1000
+#define SPEED_2500      2500
+#define SPEED_10000     10000
+
+/* Duplex, half or full. */
+#define DUPLEX_HALF     0x00
+#define DUPLEX_FULL     0x01
+
+/* Which connector port. */
+#define PORT_TP         0x00
+#define PORT_AUI        0x01
+#define PORT_MII        0x02
+#define PORT_FIBRE      0x03
+#define PORT_BNC        0x04
+#define PORT_DA         0x05
+#define PORT_NONE       0xef
+#define PORT_OTHER      0xff
+
+/* Which transceiver to use. */
+#define XCVR_INTERNAL       0x00
+#define XCVR_EXTERNAL       0x01
+#define XCVR_DUMMY1     0x02
+#define XCVR_DUMMY2     0x03
+#define XCVR_DUMMY3     0x04
+
+/* Enable or disable autonegotiation.  If this is set to enable,
+ * the forced link modes above are completely ignored.
+ */
+#define AUTONEG_DISABLE     0x00
+#define AUTONEG_ENABLE      0x01
+
+/* Mode MDI or MDI-X */
+#define ETH_TP_MDI_INVALID  0x00
+#define ETH_TP_MDI      0x01
+#define ETH_TP_MDI_X        0x02
+
+/* Wake-On-Lan options. */
+#define WAKE_PHY        (1 << 0)
+#define WAKE_UCAST      (1 << 1)
+#define WAKE_MCAST      (1 << 2)
+#define WAKE_BCAST      (1 << 3)
+#define WAKE_ARP        (1 << 4)
+#define WAKE_MAGIC      (1 << 5)
+#define WAKE_MAGICSECURE    (1 << 6) /* only meaningful if WAKE_MAGIC */
+
+/* L2-L4 network traffic flow types */
+#define TCP_V4_FLOW 0x01    /* hash or spec (tcp_ip4_spec) */
+#define UDP_V4_FLOW 0x02    /* hash or spec (udp_ip4_spec) */
+#define SCTP_V4_FLOW    0x03    /* hash or spec (sctp_ip4_spec) */
+#define AH_ESP_V4_FLOW  0x04    /* hash only */
+#define TCP_V6_FLOW 0x05    /* hash only */
+#define UDP_V6_FLOW 0x06    /* hash only */
+#define SCTP_V6_FLOW    0x07    /* hash only */
+#define AH_ESP_V6_FLOW  0x08    /* hash only */
+#define AH_V4_FLOW  0x09    /* hash or spec (ah_ip4_spec) */
+#define ESP_V4_FLOW 0x0a    /* hash or spec (esp_ip4_spec) */
+#define AH_V6_FLOW  0x0b    /* hash only */
+#define ESP_V6_FLOW 0x0c    /* hash only */
+#define IP_USER_FLOW    0x0d    /* spec only (usr_ip4_spec) */
+#define IPV4_FLOW   0x10    /* hash only */
+#define IPV6_FLOW   0x11    /* hash only */
+#define ETHER_FLOW  0x12    /* spec only (ether_spec) */
+
+/* L3-L4 network traffic flow hash options */
+#define RXH_L2DA    (1 << 1)
+#define RXH_VLAN    (1 << 2)
+#define RXH_L3_PROTO    (1 << 3)
+#define RXH_IP_SRC  (1 << 4)
+#define RXH_IP_DST  (1 << 5)
+#define RXH_L4_B_0_1    (1 << 6) /* src port in case of TCP/UDP/SCTP */
+#define RXH_L4_B_2_3    (1 << 7) /* dst port in case of TCP/UDP/SCTP */
+#define RXH_DISCARD (1U << 31)
+
+#define RX_CLS_FLOW_DISC    0xffffffffffffffffULL
+
+/* Reset flags */
+/* The reset() operation must clear the flags for the components which
+ * were actually reset.  On successful return, the flags indicate the
+ * components which were not reset, either because they do not exist
+ * in the hardware or because they cannot be reset independently.  The
+ * driver must never reset any components that were not requested.
+ */
+enum ethtool_reset_flags {
+    /* These flags represent components dedicated to the interface
+     * the command is addressed to.  Shift any flag left by
+     * ETH_RESET_SHARED_SHIFT to reset a shared component of the
+     * same type.
+     */
+    ETH_RESET_MGMT      = 1 << 0,   /* Management processor */
+    ETH_RESET_IRQ       = 1 << 1,   /* Interrupt requester */
+    ETH_RESET_DMA       = 1 << 2,   /* DMA engine */
+    ETH_RESET_FILTER    = 1 << 3,   /* Filtering/flow direction */
+    ETH_RESET_OFFLOAD   = 1 << 4,   /* Protocol offload */
+    ETH_RESET_MAC       = 1 << 5,   /* Media access controller */
+    ETH_RESET_PHY       = 1 << 6,   /* Transceiver/PHY */
+    ETH_RESET_RAM       = 1 << 7,   /* RAM shared between
+                         * multiple components */
+
+    ETH_RESET_DEDICATED = 0x0000ffff,   /* All components dedicated to
+                         * this interface */
+    ETH_RESET_ALL       = 0xffffffff,   /* All components used by this
+                         * interface, even if shared */
+};
+#define ETH_RESET_SHARED_SHIFT  16
diff --git a/libethdrivers/src/plat/odroidc2/uboot/list.h b/libethdrivers/src/plat/odroidc2/uboot/list.h
new file mode 100644
index 0000000..542b069
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/list.h
@@ -0,0 +1,682 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ * Copyright Linux
+ */
+#pragma once
+
+#include <stddef.h>
+
+#define LIST_POISON1  ((void *) 0x0)
+#define LIST_POISON2  ((void *) 0x0)
+
+static inline void prefetch(const void *x) {;}
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+    struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+    struct list_head name = LIST_HEAD_INIT(name)
+
+static inline void INIT_LIST_HEAD(struct list_head *list)
+{
+    list->next = list;
+    list->prev = list;
+}
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_add(struct list_head *new,
+                              struct list_head *prev,
+                              struct list_head *next)
+{
+    next->prev = new;
+    new->next = next;
+    new->prev = prev;
+    prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static inline void list_add(struct list_head *new, struct list_head *head)
+{
+    __list_add(new, head, head->next);
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static inline void list_add_tail(struct list_head *new, struct list_head *head)
+{
+    __list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static inline void __list_del(struct list_head *prev, struct list_head *next)
+{
+    next->prev = prev;
+    prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty() on entry does not return true after this, the entry is
+ * in an undefined state.
+ */
+static inline void list_del(struct list_head *entry)
+{
+    __list_del(entry->prev, entry->next);
+    entry->next = LIST_POISON1;
+    entry->prev = LIST_POISON2;
+}
+
+/**
+ * list_replace - replace old entry by new one
+ * @old : the element to be replaced
+ * @new : the new element to insert
+ *
+ * If @old was empty, it will be overwritten.
+ */
+static inline void list_replace(struct list_head *old,
+                                struct list_head *new)
+{
+    new->next = old->next;
+    new->next->prev = new;
+    new->prev = old->prev;
+    new->prev->next = new;
+}
+
+static inline void list_replace_init(struct list_head *old,
+                                     struct list_head *new)
+{
+    list_replace(old, new);
+    INIT_LIST_HEAD(old);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static inline void list_del_init(struct list_head *entry)
+{
+    __list_del(entry->prev, entry->next);
+    INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_move - delete from one list and add as another's head
+ * @list: the entry to move
+ * @head: the head that will precede our entry
+ */
+static inline void list_move(struct list_head *list, struct list_head *head)
+{
+    __list_del(list->prev, list->next);
+    list_add(list, head);
+}
+
+/**
+ * list_move_tail - delete from one list and add as another's tail
+ * @list: the entry to move
+ * @head: the head that will follow our entry
+ */
+static inline void list_move_tail(struct list_head *list,
+                                  struct list_head *head)
+{
+    __list_del(list->prev, list->next);
+    list_add_tail(list, head);
+}
+
+/**
+ * list_is_last - tests whether @list is the last entry in list @head
+ * @list: the entry to test
+ * @head: the head of the list
+ */
+static inline int list_is_last(const struct list_head *list,
+                               const struct list_head *head)
+{
+    return list->next == head;
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static inline int list_empty(const struct list_head *head)
+{
+    return head->next == head;
+}
+
+/**
+ * list_empty_careful - tests whether a list is empty and not being modified
+ * @head: the list to test
+ *
+ * Description:
+ * tests whether a list is empty _and_ checks that no other CPU might be
+ * in the process of modifying either member (next or prev)
+ *
+ * NOTE: using list_empty_careful() without synchronization
+ * can only be safe if the only activity that can happen
+ * to the list entry is list_del_init(). Eg. it cannot be used
+ * if another CPU could re-list_add() it.
+ */
+static inline int list_empty_careful(const struct list_head *head)
+{
+    struct list_head *next = head->next;
+    return (next == head) && (next == head->prev);
+}
+
+/**
+ * list_is_singular - tests whether a list has just one entry.
+ * @head: the list to test.
+ */
+static inline int list_is_singular(const struct list_head *head)
+{
+    return !list_empty(head) && (head->next == head->prev);
+}
+
+static inline void __list_cut_position(struct list_head *list,
+                                       struct list_head *head, struct list_head *entry)
+{
+    struct list_head *new_first = entry->next;
+    list->next = head->next;
+    list->next->prev = list;
+    list->prev = entry;
+    entry->next = list;
+    head->next = new_first;
+    new_first->prev = head;
+}
+
+/**
+ * list_cut_position - cut a list into two
+ * @list: a new list to add all removed entries
+ * @head: a list with entries
+ * @entry: an entry within head, could be the head itself
+ *  and if so we won't cut the list
+ *
+ * This helper moves the initial part of @head, up to and
+ * including @entry, from @head to @list. You should
+ * pass on @entry an element you know is on @head. @list
+ * should be an empty list or a list you do not care about
+ * losing its data.
+ *
+ */
+static inline void list_cut_position(struct list_head *list,
+                                     struct list_head *head, struct list_head *entry)
+{
+    if (list_empty(head)) {
+        return;
+    }
+    if (list_is_singular(head) &&
+        (head->next != entry && head != entry)) {
+        return;
+    }
+    if (entry == head) {
+        INIT_LIST_HEAD(list);
+    } else {
+        __list_cut_position(list, head, entry);
+    }
+}
+
+static inline void __list_splice(const struct list_head *list,
+                                 struct list_head *prev,
+                                 struct list_head *next)
+{
+    struct list_head *first = list->next;
+    struct list_head *last = list->prev;
+
+    first->prev = prev;
+    prev->next = first;
+
+    last->next = next;
+    next->prev = last;
+}
+
+/**
+ * list_splice - join two lists, this is designed for stacks
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice(const struct list_head *list,
+                               struct list_head *head)
+{
+    if (!list_empty(list)) {
+        __list_splice(list, head, head->next);
+    }
+}
+
+/**
+ * list_splice_tail - join two lists, each list being a queue
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static inline void list_splice_tail(struct list_head *list,
+                                    struct list_head *head)
+{
+    if (!list_empty(list)) {
+        __list_splice(list, head->prev, head);
+    }
+}
+
+/**
+ * list_splice_init - join two lists and reinitialise the emptied list.
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_init(struct list_head *list,
+                                    struct list_head *head)
+{
+    if (!list_empty(list)) {
+        __list_splice(list, head, head->next);
+        INIT_LIST_HEAD(list);
+    }
+}
+
+/**
+ * list_splice_tail_init - join two lists and reinitialise the emptied list
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ *
+ * Each of the lists is a queue.
+ * The list at @list is reinitialised
+ */
+static inline void list_splice_tail_init(struct list_head *list,
+                                         struct list_head *head)
+{
+    if (!list_empty(list)) {
+        __list_splice(list, head->prev, head);
+        INIT_LIST_HEAD(list);
+    }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr:    the &struct list_head pointer.
+ * @type:   the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+    container_of(ptr, type, member)
+
+/**
+ * list_first_entry - get the first element from a list
+ * @ptr:    the list head to take the element from.
+ * @type:   the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Note, that list is expected to be not empty.
+ */
+#define list_first_entry(ptr, type, member) \
+    list_entry((ptr)->next, type, member)
+
+/**
+ * list_for_each    -   iterate over a list
+ * @pos:    the &struct list_head to use as a loop cursor.
+ * @head:   the head for your list.
+ */
+#define list_for_each(pos, head) \
+    for (pos = (head)->next; prefetch(pos->next), pos != (head); \
+        pos = pos->next)
+
+/**
+ * __list_for_each  -   iterate over a list
+ * @pos:    the &struct list_head to use as a loop cursor.
+ * @head:   the head for your list.
+ *
+ * This variant differs from list_for_each() in that it's the
+ * simplest possible list iteration code, no prefetching is done.
+ * Use this for code that knows the list to be very short (empty
+ * or 1 entry) most of the time.
+ */
+#define __list_for_each(pos, head) \
+    for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_prev   -   iterate over a list backwards
+ * @pos:    the &struct list_head to use as a loop cursor.
+ * @head:   the head for your list.
+ */
+#define list_for_each_prev(pos, head) \
+    for (pos = (head)->prev; prefetch(pos->prev), pos != (head); \
+        pos = pos->prev)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of list entry
+ * @pos:    the &struct list_head to use as a loop cursor.
+ * @n:      another &struct list_head to use as temporary storage
+ * @head:   the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+    for (pos = (head)->next, n = pos->next; pos != (head); \
+        pos = n, n = pos->next)
+
+/**
+ * list_for_each_prev_safe - iterate over a list backwards safe against removal of list entry
+ * @pos:    the &struct list_head to use as a loop cursor.
+ * @n:      another &struct list_head to use as temporary storage
+ * @head:   the head for your list.
+ */
+#define list_for_each_prev_safe(pos, n, head) \
+    for (pos = (head)->prev, n = pos->prev; \
+         prefetch(pos->prev), pos != (head); \
+         pos = n, n = pos->prev)
+
+/**
+ * list_for_each_entry  -   iterate over list of given type
+ * @pos:    the type * to use as a loop cursor.
+ * @head:   the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member)              \
+    for (pos = list_entry((head)->next, typeof(*pos), member);  \
+         prefetch(pos->member.next), &pos->member != (head);    \
+         pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_reverse - iterate backwards over list of given type.
+ * @pos:    the type * to use as a loop cursor.
+ * @head:   the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_reverse(pos, head, member)          \
+    for (pos = list_entry((head)->prev, typeof(*pos), member);  \
+         prefetch(pos->member.prev), &pos->member != (head);    \
+         pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_prepare_entry - prepare a pos entry for use in list_for_each_entry_continue()
+ * @pos:    the type * to use as a start point
+ * @head:   the head of the list
+ * @member: the name of the list_struct within the struct.
+ *
+ * Prepares a pos entry for use as a start point in list_for_each_entry_continue().
+ */
+#define list_prepare_entry(pos, head, member) \
+    ((pos) ? : list_entry(head, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue - continue iteration over list of given type
+ * @pos:    the type * to use as a loop cursor.
+ * @head:   the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Continue to iterate over list of given type, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue(pos, head, member)         \
+    for (pos = list_entry(pos->member.next, typeof(*pos), member);  \
+         prefetch(pos->member.next), &pos->member != (head);    \
+         pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_continue_reverse - iterate backwards from the given point
+ * @pos:    the type * to use as a loop cursor.
+ * @head:   the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Start to iterate over list of given type backwards, continuing after
+ * the current position.
+ */
+#define list_for_each_entry_continue_reverse(pos, head, member)     \
+    for (pos = list_entry(pos->member.prev, typeof(*pos), member);  \
+         prefetch(pos->member.prev), &pos->member != (head);    \
+         pos = list_entry(pos->member.prev, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_from - iterate over list of given type from the current point
+ * @pos:    the type * to use as a loop cursor.
+ * @head:   the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing from current position.
+ */
+#define list_for_each_entry_from(pos, head, member)         \
+    for (; prefetch(pos->member.next), &pos->member != (head);  \
+         pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @pos:    the type * to use as a loop cursor.
+ * @n:      another type * to use as temporary storage
+ * @head:   the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member)          \
+    for (pos = list_entry((head)->next, typeof(*pos), member),  \
+        n = list_entry(pos->member.next, typeof(*pos), member); \
+         &pos->member != (head);                    \
+         pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_continue
+ * @pos:    the type * to use as a loop cursor.
+ * @n:      another type * to use as temporary storage
+ * @head:   the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type, continuing after current point,
+ * safe against removal of list entry.
+ */
+#define list_for_each_entry_safe_continue(pos, n, head, member)         \
+    for (pos = list_entry(pos->member.next, typeof(*pos), member),      \
+        n = list_entry(pos->member.next, typeof(*pos), member);     \
+         &pos->member != (head);                        \
+         pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_from
+ * @pos:    the type * to use as a loop cursor.
+ * @n:      another type * to use as temporary storage
+ * @head:   the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate over list of given type from current point, safe against
+ * removal of list entry.
+ */
+#define list_for_each_entry_safe_from(pos, n, head, member)         \
+    for (n = list_entry(pos->member.next, typeof(*pos), member);        \
+         &pos->member != (head);                        \
+         pos = n, n = list_entry(n->member.next, typeof(*n), member))
+
+/**
+ * list_for_each_entry_safe_reverse
+ * @pos:    the type * to use as a loop cursor.
+ * @n:      another type * to use as temporary storage
+ * @head:   the head for your list.
+ * @member: the name of the list_struct within the struct.
+ *
+ * Iterate backwards over list of given type, safe against removal
+ * of list entry.
+ */
+#define list_for_each_entry_safe_reverse(pos, n, head, member)      \
+    for (pos = list_entry((head)->prev, typeof(*pos), member),  \
+        n = list_entry(pos->member.prev, typeof(*pos), member); \
+         &pos->member != (head);                    \
+         pos = n, n = list_entry(n->member.prev, typeof(*n), member))
+
+/*
+ * Double linked lists with a single pointer list head.
+ * Mostly useful for hash tables where the two pointer list head is
+ * too wasteful.
+ * You lose the ability to access the tail in O(1).
+ */
+
+struct hlist_head {
+    struct hlist_node *first;
+};
+
+struct hlist_node {
+    struct hlist_node *next, * *pprev;
+};
+
+#define HLIST_HEAD_INIT { .first = NULL }
+#define HLIST_HEAD(name) struct hlist_head name = {  .first = NULL }
+#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
+static inline void INIT_HLIST_NODE(struct hlist_node *h)
+{
+    h->next = NULL;
+    h->pprev = NULL;
+}
+
+static inline int hlist_unhashed(const struct hlist_node *h)
+{
+    return !h->pprev;
+}
+
+static inline int hlist_empty(const struct hlist_head *h)
+{
+    return !h->first;
+}
+
+static inline void __hlist_del(struct hlist_node *n)
+{
+    struct hlist_node *next = n->next;
+    struct hlist_node **pprev = n->pprev;
+    *pprev = next;
+    if (next) {
+        next->pprev = pprev;
+    }
+}
+
+static inline void hlist_del(struct hlist_node *n)
+{
+    __hlist_del(n);
+    n->next = LIST_POISON1;
+    n->pprev = LIST_POISON2;
+}
+
+static inline void hlist_del_init(struct hlist_node *n)
+{
+    if (!hlist_unhashed(n)) {
+        __hlist_del(n);
+        INIT_HLIST_NODE(n);
+    }
+}
+
+static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
+{
+    struct hlist_node *first = h->first;
+    n->next = first;
+    if (first) {
+        first->pprev = &n->next;
+    }
+    h->first = n;
+    n->pprev = &h->first;
+}
+
+/* next must be != NULL */
+static inline void hlist_add_before(struct hlist_node *n,
+                                    struct hlist_node *next)
+{
+    n->pprev = next->pprev;
+    n->next = next;
+    next->pprev = &n->next;
+    *(n->pprev) = n;
+}
+
+static inline void hlist_add_after(struct hlist_node *n,
+                                   struct hlist_node *next)
+{
+    next->next = n->next;
+    n->next = next;
+    next->pprev = &n->next;
+
+    if (next->next) {
+        next->next->pprev  = &next->next;
+    }
+}
+
+#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
+
+#define hlist_for_each(pos, head) \
+    for (pos = (head)->first; pos && ({ prefetch(pos->next); 1; }); \
+         pos = pos->next)
+
+#define hlist_for_each_safe(pos, n, head) \
+    for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
+         pos = n)
+
+/**
+ * hlist_for_each_entry - iterate over list of given type
+ * @tpos:   the type * to use as a loop cursor.
+ * @pos:    the &struct hlist_node to use as a loop cursor.
+ * @head:   the head for your list.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry(tpos, pos, head, member)            \
+    for (pos = (head)->first;                    \
+         pos && ({ prefetch(pos->next); 1;}) &&          \
+        ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+         pos = pos->next)
+
+/**
+ * hlist_for_each_entry_continue - iterate over a hlist continuing after current point
+ * @tpos:   the type * to use as a loop cursor.
+ * @pos:    the &struct hlist_node to use as a loop cursor.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_continue(tpos, pos, member)         \
+    for (pos = (pos)->next;                      \
+         pos && ({ prefetch(pos->next); 1;}) &&          \
+        ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+         pos = pos->next)
+
+/**
+ * hlist_for_each_entry_from - iterate over a hlist continuing from current point
+ * @tpos:   the type * to use as a loop cursor.
+ * @pos:    the &struct hlist_node to use as a loop cursor.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_from(tpos, pos, member)             \
+    for (; pos && ({ prefetch(pos->next); 1;}) &&            \
+        ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+         pos = pos->next)
+
+/**
+ * hlist_for_each_entry_safe - iterate over list of given type safe against removal of list entry
+ * @tpos:   the type * to use as a loop cursor.
+ * @pos:    the &struct hlist_node to use as a loop cursor.
+ * @n:      another &struct hlist_node to use as temporary storage
+ * @head:   the head for your list.
+ * @member: the name of the hlist_node within the struct.
+ */
+#define hlist_for_each_entry_safe(tpos, pos, n, head, member)        \
+    for (pos = (head)->first;                    \
+         pos && ({ n = pos->next; 1; }) &&               \
+        ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
+         pos = n)
diff --git a/libethdrivers/src/plat/odroidc2/uboot/mdio.h b/libethdrivers/src/plat/odroidc2/uboot/mdio.h
new file mode 100644
index 0000000..182d443
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/mdio.h
@@ -0,0 +1,285 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+/*
+ * linux/mdio.h: definitions for MDIO (clause 45) transceivers
+ * Copyright 2006-2009 Solarflare Communications Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published
+ * by the Free Software Foundation, incorporated herein by reference.
+ */
+
+#pragma once
+
+#include "mii.h"
+
+/* MDIO Manageable Devices (MMDs). */
+#define MDIO_MMD_PMAPMD     1   /* Physical Medium Attachment/
+                     * Physical Medium Dependent */
+#define MDIO_MMD_WIS        2   /* WAN Interface Sublayer */
+#define MDIO_MMD_PCS        3   /* Physical Coding Sublayer */
+#define MDIO_MMD_PHYXS      4   /* PHY Extender Sublayer */
+#define MDIO_MMD_DTEXS      5   /* DTE Extender Sublayer */
+#define MDIO_MMD_TC     6   /* Transmission Convergence */
+#define MDIO_MMD_AN     7   /* Auto-Negotiation */
+#define MDIO_MMD_C22EXT     29  /* Clause 22 extension */
+#define MDIO_MMD_VEND1      30  /* Vendor specific 1 */
+#define MDIO_MMD_VEND2      31  /* Vendor specific 2 */
+
+/* Generic MDIO registers. */
+#define MDIO_CTRL1      MII_BMCR
+#define MDIO_STAT1      MII_BMSR
+#define MDIO_DEVID1     MII_PHYSID1
+#define MDIO_DEVID2     MII_PHYSID2
+#define MDIO_SPEED      4   /* Speed ability */
+#define MDIO_DEVS1      5   /* Devices in package */
+#define MDIO_DEVS2      6
+#define MDIO_CTRL2      7   /* 10G control 2 */
+#define MDIO_STAT2      8   /* 10G status 2 */
+#define MDIO_PMA_TXDIS      9   /* 10G PMA/PMD transmit disable */
+#define MDIO_PMA_RXDET      10  /* 10G PMA/PMD receive signal detect */
+#define MDIO_PMA_EXTABLE    11  /* 10G PMA/PMD extended ability */
+#define MDIO_PKGID1     14  /* Package identifier */
+#define MDIO_PKGID2     15
+#define MDIO_AN_ADVERTISE   16  /* AN advertising (base page) */
+#define MDIO_AN_LPA     19  /* AN LP abilities (base page) */
+#define MDIO_PHYXS_LNSTAT   24  /* PHY XGXS lane state */
+
+/* Media-dependent registers. */
+#define MDIO_PMA_10GBT_SWAPPOL  130 /* 10GBASE-T pair swap & polarity */
+#define MDIO_PMA_10GBT_TXPWR    131 /* 10GBASE-T TX power control */
+#define MDIO_PMA_10GBT_SNR  133 /* 10GBASE-T SNR margin, lane A.
+                     * Lanes B-D are numbered 134-136. */
+#define MDIO_PMA_10GBR_FECABLE  170 /* 10GBASE-R FEC ability */
+#define MDIO_PCS_10GBX_STAT1    24  /* 10GBASE-X PCS status 1 */
+#define MDIO_PCS_10GBRT_STAT1   32  /* 10GBASE-R/-T PCS status 1 */
+#define MDIO_PCS_10GBRT_STAT2   33  /* 10GBASE-R/-T PCS status 2 */
+#define MDIO_AN_10GBT_CTRL  32  /* 10GBASE-T auto-negotiation control */
+#define MDIO_AN_10GBT_STAT  33  /* 10GBASE-T auto-negotiation status */
+#define MDIO_AN_EEE_ADV     60  /* EEE advertisement */
+
+/* LASI (Link Alarm Status Interrupt) registers, defined by XENPAK MSA. */
+#define MDIO_PMA_LASI_RXCTRL    0x9000  /* RX_ALARM control */
+#define MDIO_PMA_LASI_TXCTRL    0x9001  /* TX_ALARM control */
+#define MDIO_PMA_LASI_CTRL  0x9002  /* LASI control */
+#define MDIO_PMA_LASI_RXSTAT    0x9003  /* RX_ALARM status */
+#define MDIO_PMA_LASI_TXSTAT    0x9004  /* TX_ALARM status */
+#define MDIO_PMA_LASI_STAT  0x9005  /* LASI status */
+
+/* Control register 1. */
+/* Enable extended speed selection */
+#define MDIO_CTRL1_SPEEDSELEXT      (BMCR_SPEED1000 | BMCR_SPEED100)
+/* All speed selection bits */
+#define MDIO_CTRL1_SPEEDSEL     (MDIO_CTRL1_SPEEDSELEXT | 0x003c)
+#define MDIO_CTRL1_FULLDPLX     BMCR_FULLDPLX
+#define MDIO_CTRL1_LPOWER       BMCR_PDOWN
+#define MDIO_CTRL1_RESET        BMCR_RESET
+#define MDIO_PMA_CTRL1_LOOPBACK     0x0001
+#define MDIO_PMA_CTRL1_SPEED1000    BMCR_SPEED1000
+#define MDIO_PMA_CTRL1_SPEED100     BMCR_SPEED100
+#define MDIO_PCS_CTRL1_LOOPBACK     BMCR_LOOPBACK
+#define MDIO_PHYXS_CTRL1_LOOPBACK   BMCR_LOOPBACK
+#define MDIO_AN_CTRL1_RESTART       BMCR_ANRESTART
+#define MDIO_AN_CTRL1_ENABLE        BMCR_ANENABLE
+#define MDIO_AN_CTRL1_XNP       0x2000  /* Enable extended next page */
+
+/* 10 Gb/s */
+#define MDIO_CTRL1_SPEED10G     (MDIO_CTRL1_SPEEDSELEXT | 0x00)
+/* 10PASS-TS/2BASE-TL */
+#define MDIO_CTRL1_SPEED10P2B       (MDIO_CTRL1_SPEEDSELEXT | 0x04)
+
+/* Status register 1. */
+#define MDIO_STAT1_LPOWERABLE       0x0002  /* Low-power ability */
+#define MDIO_STAT1_LSTATUS      BMSR_LSTATUS
+#define MDIO_STAT1_FAULT        0x0080  /* Fault */
+#define MDIO_AN_STAT1_LPABLE        0x0001  /* Link partner AN ability */
+#define MDIO_AN_STAT1_ABLE      BMSR_ANEGCAPABLE
+#define MDIO_AN_STAT1_RFAULT        BMSR_RFAULT
+#define MDIO_AN_STAT1_COMPLETE      BMSR_ANEGCOMPLETE
+#define MDIO_AN_STAT1_PAGE      0x0040  /* Page received */
+#define MDIO_AN_STAT1_XNP       0x0080  /* Extended next page status */
+
+/* Speed register. */
+#define MDIO_SPEED_10G          0x0001  /* 10G capable */
+#define MDIO_PMA_SPEED_2B       0x0002  /* 2BASE-TL capable */
+#define MDIO_PMA_SPEED_10P      0x0004  /* 10PASS-TS capable */
+#define MDIO_PMA_SPEED_1000     0x0010  /* 1000M capable */
+#define MDIO_PMA_SPEED_100      0x0020  /* 100M capable */
+#define MDIO_PMA_SPEED_10       0x0040  /* 10M capable */
+#define MDIO_PCS_SPEED_10P2B        0x0002  /* 10PASS-TS/2BASE-TL capable */
+
+/* Device present registers. */
+#define MDIO_DEVS_PRESENT(devad)    (1 << (devad))
+#define MDIO_DEVS_PMAPMD        MDIO_DEVS_PRESENT(MDIO_MMD_PMAPMD)
+#define MDIO_DEVS_WIS           MDIO_DEVS_PRESENT(MDIO_MMD_WIS)
+#define MDIO_DEVS_PCS           MDIO_DEVS_PRESENT(MDIO_MMD_PCS)
+#define MDIO_DEVS_PHYXS         MDIO_DEVS_PRESENT(MDIO_MMD_PHYXS)
+#define MDIO_DEVS_DTEXS         MDIO_DEVS_PRESENT(MDIO_MMD_DTEXS)
+#define MDIO_DEVS_TC            MDIO_DEVS_PRESENT(MDIO_MMD_TC)
+#define MDIO_DEVS_AN            MDIO_DEVS_PRESENT(MDIO_MMD_AN)
+#define MDIO_DEVS_C22EXT        MDIO_DEVS_PRESENT(MDIO_MMD_C22EXT)
+#define MDIO_DEVS_VEND1         MDIO_DEVS_PRESENT(MDIO_MMD_VEND1)
+#define MDIO_DEVS_VEND2         MDIO_DEVS_PRESENT(MDIO_MMD_VEND2)
+
+#define MDIO_DEVS_LINK          (MDIO_DEVS_PMAPMD | \
+                    MDIO_DEVS_WIS | \
+                    MDIO_DEVS_PCS | \
+                    MDIO_DEVS_PHYXS | \
+                    MDIO_DEVS_DTEXS | \
+                    MDIO_DEVS_AN)
+
+/* Control register 2. */
+#define MDIO_PMA_CTRL2_TYPE     0x000f  /* PMA/PMD type selection */
+#define MDIO_PMA_CTRL2_10GBCX4      0x0000  /* 10GBASE-CX4 type */
+#define MDIO_PMA_CTRL2_10GBEW       0x0001  /* 10GBASE-EW type */
+#define MDIO_PMA_CTRL2_10GBLW       0x0002  /* 10GBASE-LW type */
+#define MDIO_PMA_CTRL2_10GBSW       0x0003  /* 10GBASE-SW type */
+#define MDIO_PMA_CTRL2_10GBLX4      0x0004  /* 10GBASE-LX4 type */
+#define MDIO_PMA_CTRL2_10GBER       0x0005  /* 10GBASE-ER type */
+#define MDIO_PMA_CTRL2_10GBLR       0x0006  /* 10GBASE-LR type */
+#define MDIO_PMA_CTRL2_10GBSR       0x0007  /* 10GBASE-SR type */
+#define MDIO_PMA_CTRL2_10GBLRM      0x0008  /* 10GBASE-LRM type */
+#define MDIO_PMA_CTRL2_10GBT        0x0009  /* 10GBASE-T type */
+#define MDIO_PMA_CTRL2_10GBKX4      0x000a  /* 10GBASE-KX4 type */
+#define MDIO_PMA_CTRL2_10GBKR       0x000b  /* 10GBASE-KR type */
+#define MDIO_PMA_CTRL2_1000BT       0x000c  /* 1000BASE-T type */
+#define MDIO_PMA_CTRL2_1000BKX      0x000d  /* 1000BASE-KX type */
+#define MDIO_PMA_CTRL2_100BTX       0x000e  /* 100BASE-TX type */
+#define MDIO_PMA_CTRL2_10BT     0x000f  /* 10BASE-T type */
+#define MDIO_PCS_CTRL2_TYPE     0x0003  /* PCS type selection */
+#define MDIO_PCS_CTRL2_10GBR        0x0000  /* 10GBASE-R type */
+#define MDIO_PCS_CTRL2_10GBX        0x0001  /* 10GBASE-X type */
+#define MDIO_PCS_CTRL2_10GBW        0x0002  /* 10GBASE-W type */
+#define MDIO_PCS_CTRL2_10GBT        0x0003  /* 10GBASE-T type */
+
+/* Status register 2. */
+#define MDIO_STAT2_RXFAULT      0x0400  /* Receive fault */
+#define MDIO_STAT2_TXFAULT      0x0800  /* Transmit fault */
+#define MDIO_STAT2_DEVPRST      0xc000  /* Device present */
+#define MDIO_STAT2_DEVPRST_VAL      0x8000  /* Device present value */
+#define MDIO_PMA_STAT2_LBABLE       0x0001  /* PMA loopback ability */
+#define MDIO_PMA_STAT2_10GBEW       0x0002  /* 10GBASE-EW ability */
+#define MDIO_PMA_STAT2_10GBLW       0x0004  /* 10GBASE-LW ability */
+#define MDIO_PMA_STAT2_10GBSW       0x0008  /* 10GBASE-SW ability */
+#define MDIO_PMA_STAT2_10GBLX4      0x0010  /* 10GBASE-LX4 ability */
+#define MDIO_PMA_STAT2_10GBER       0x0020  /* 10GBASE-ER ability */
+#define MDIO_PMA_STAT2_10GBLR       0x0040  /* 10GBASE-LR ability */
+#define MDIO_PMA_STAT2_10GBSR       0x0080  /* 10GBASE-SR ability */
+#define MDIO_PMD_STAT2_TXDISAB      0x0100  /* PMD TX disable ability */
+#define MDIO_PMA_STAT2_EXTABLE      0x0200  /* Extended abilities */
+#define MDIO_PMA_STAT2_RXFLTABLE    0x1000  /* Receive fault ability */
+#define MDIO_PMA_STAT2_TXFLTABLE    0x2000  /* Transmit fault ability */
+#define MDIO_PCS_STAT2_10GBR        0x0001  /* 10GBASE-R capable */
+#define MDIO_PCS_STAT2_10GBX        0x0002  /* 10GBASE-X capable */
+#define MDIO_PCS_STAT2_10GBW        0x0004  /* 10GBASE-W capable */
+#define MDIO_PCS_STAT2_RXFLTABLE    0x1000  /* Receive fault ability */
+#define MDIO_PCS_STAT2_TXFLTABLE    0x2000  /* Transmit fault ability */
+
+/* Transmit disable register. */
+#define MDIO_PMD_TXDIS_GLOBAL       0x0001  /* Global PMD TX disable */
+#define MDIO_PMD_TXDIS_0        0x0002  /* PMD TX disable 0 */
+#define MDIO_PMD_TXDIS_1        0x0004  /* PMD TX disable 1 */
+#define MDIO_PMD_TXDIS_2        0x0008  /* PMD TX disable 2 */
+#define MDIO_PMD_TXDIS_3        0x0010  /* PMD TX disable 3 */
+
+/* Receive signal detect register. */
+#define MDIO_PMD_RXDET_GLOBAL       0x0001  /* Global PMD RX signal detect */
+#define MDIO_PMD_RXDET_0        0x0002  /* PMD RX signal detect 0 */
+#define MDIO_PMD_RXDET_1        0x0004  /* PMD RX signal detect 1 */
+#define MDIO_PMD_RXDET_2        0x0008  /* PMD RX signal detect 2 */
+#define MDIO_PMD_RXDET_3        0x0010  /* PMD RX signal detect 3 */
+
+/* Extended abilities register. */
+#define MDIO_PMA_EXTABLE_10GCX4     0x0001  /* 10GBASE-CX4 ability */
+#define MDIO_PMA_EXTABLE_10GBLRM    0x0002  /* 10GBASE-LRM ability */
+#define MDIO_PMA_EXTABLE_10GBT      0x0004  /* 10GBASE-T ability */
+#define MDIO_PMA_EXTABLE_10GBKX4    0x0008  /* 10GBASE-KX4 ability */
+#define MDIO_PMA_EXTABLE_10GBKR     0x0010  /* 10GBASE-KR ability */
+#define MDIO_PMA_EXTABLE_1000BT     0x0020  /* 1000BASE-T ability */
+#define MDIO_PMA_EXTABLE_1000BKX    0x0040  /* 1000BASE-KX ability */
+#define MDIO_PMA_EXTABLE_100BTX     0x0080  /* 100BASE-TX ability */
+#define MDIO_PMA_EXTABLE_10BT       0x0100  /* 10BASE-T ability */
+
+/* PHY XGXS lane state register. */
+#define MDIO_PHYXS_LNSTAT_SYNC0     0x0001
+#define MDIO_PHYXS_LNSTAT_SYNC1     0x0002
+#define MDIO_PHYXS_LNSTAT_SYNC2     0x0004
+#define MDIO_PHYXS_LNSTAT_SYNC3     0x0008
+#define MDIO_PHYXS_LNSTAT_ALIGN     0x1000
+
+/* PMA 10GBASE-T pair swap & polarity */
+#define MDIO_PMA_10GBT_SWAPPOL_ABNX 0x0001  /* Pair A/B uncrossed */
+#define MDIO_PMA_10GBT_SWAPPOL_CDNX 0x0002  /* Pair C/D uncrossed */
+#define MDIO_PMA_10GBT_SWAPPOL_AREV 0x0100  /* Pair A polarity reversed */
+#define MDIO_PMA_10GBT_SWAPPOL_BREV 0x0200  /* Pair B polarity reversed */
+#define MDIO_PMA_10GBT_SWAPPOL_CREV 0x0400  /* Pair C polarity reversed */
+#define MDIO_PMA_10GBT_SWAPPOL_DREV 0x0800  /* Pair D polarity reversed */
+
+/* PMA 10GBASE-T TX power register. */
+#define MDIO_PMA_10GBT_TXPWR_SHORT  0x0001  /* Short-reach mode */
+
+/* PMA 10GBASE-T SNR registers. */
+/* Value is SNR margin in dB, clamped to range [-127, 127], plus 0x8000. */
+#define MDIO_PMA_10GBT_SNR_BIAS     0x8000
+#define MDIO_PMA_10GBT_SNR_MAX      127
+
+/* PMA 10GBASE-R FEC ability register. */
+#define MDIO_PMA_10GBR_FECABLE_ABLE 0x0001  /* FEC ability */
+#define MDIO_PMA_10GBR_FECABLE_ERRABLE  0x0002  /* FEC error indic. ability */
+
+/* PCS 10GBASE-R/-T status register 1. */
+#define MDIO_PCS_10GBRT_STAT1_BLKLK 0x0001  /* Block lock attained */
+
+/* PCS 10GBASE-R/-T status register 2. */
+#define MDIO_PCS_10GBRT_STAT2_ERR   0x00ff
+#define MDIO_PCS_10GBRT_STAT2_BER   0x3f00
+
+/* AN 10GBASE-T control register. */
+#define MDIO_AN_10GBT_CTRL_ADV10G   0x1000  /* Advertise 10GBASE-T */
+
+/* AN 10GBASE-T status register. */
+#define MDIO_AN_10GBT_STAT_LPTRR    0x0200  /* LP training reset req. */
+#define MDIO_AN_10GBT_STAT_LPLTABLE 0x0400  /* LP loop timing ability */
+#define MDIO_AN_10GBT_STAT_LP10G    0x0800  /* LP is 10GBT capable */
+#define MDIO_AN_10GBT_STAT_REMOK    0x1000  /* Remote OK */
+#define MDIO_AN_10GBT_STAT_LOCOK    0x2000  /* Local OK */
+#define MDIO_AN_10GBT_STAT_MS       0x4000  /* Master/slave config */
+#define MDIO_AN_10GBT_STAT_MSFLT    0x8000  /* Master/slave config fault */
+
+/* AN EEE Advertisement register. */
+#define MDIO_AN_EEE_ADV_100TX       0x0002  /* Advertise 100TX EEE cap */
+#define MDIO_AN_EEE_ADV_1000T       0x0004  /* Advertise 1000T EEE cap */
+
+/* LASI RX_ALARM control/status registers. */
+#define MDIO_PMA_LASI_RX_PHYXSLFLT  0x0001  /* PHY XS RX local fault */
+#define MDIO_PMA_LASI_RX_PCSLFLT    0x0008  /* PCS RX local fault */
+#define MDIO_PMA_LASI_RX_PMALFLT    0x0010  /* PMA/PMD RX local fault */
+#define MDIO_PMA_LASI_RX_OPTICPOWERFLT  0x0020  /* RX optical power fault */
+#define MDIO_PMA_LASI_RX_WISLFLT    0x0200  /* WIS local fault */
+
+/* LASI TX_ALARM control/status registers. */
+#define MDIO_PMA_LASI_TX_PHYXSLFLT  0x0001  /* PHY XS TX local fault */
+#define MDIO_PMA_LASI_TX_PCSLFLT    0x0008  /* PCS TX local fault */
+#define MDIO_PMA_LASI_TX_PMALFLT    0x0010  /* PMA/PMD TX local fault */
+#define MDIO_PMA_LASI_TX_LASERPOWERFLT  0x0080  /* Laser output power fault */
+#define MDIO_PMA_LASI_TX_LASERTEMPFLT   0x0100  /* Laser temperature fault */
+#define MDIO_PMA_LASI_TX_LASERBICURRFLT 0x0200  /* Laser bias current fault */
+
+/* LASI control/status registers. */
+#define MDIO_PMA_LASI_LSALARM       0x0001  /* LS_ALARM enable/status */
+#define MDIO_PMA_LASI_TXALARM       0x0002  /* TX_ALARM enable/status */
+#define MDIO_PMA_LASI_RXALARM       0x0004  /* RX_ALARM enable/status */
+
+/* Mapping between MDIO PRTAD/DEVAD and mii_ioctl_data::phy_id */
+
+#define MDIO_PHY_ID_C45         0x8000
+#define MDIO_PHY_ID_PRTAD       0x03e0
+#define MDIO_PHY_ID_DEVAD       0x001f
+#define MDIO_PHY_ID_C45_MASK                        \
+    (MDIO_PHY_ID_C45 | MDIO_PHY_ID_PRTAD | MDIO_PHY_ID_DEVAD)
+
+#define MDIO_PRTAD_NONE         (-1)
+#define MDIO_DEVAD_NONE         (-1)
+#define MDIO_EMULATE_C22        4
diff --git a/libethdrivers/src/plat/odroidc2/uboot/mii.h b/libethdrivers/src/plat/odroidc2/uboot/mii.h
new file mode 100644
index 0000000..10e4e12
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/mii.h
@@ -0,0 +1,197 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+/*
+ * linux/mii.h: definitions for MII-compatible transceivers
+ * Originally drivers/net/sunhme.h.
+ *
+ * Copyright (C) 1996, 1999, 2001 David S. Miller (davem@redhat.com)
+ */
+
+#pragma once
+
+/* Generic MII registers. */
+
+#define MII_BMCR        0x00    /* Basic mode control register */
+#define MII_BMSR        0x01    /* Basic mode status register  */
+#define MII_PHYSID1     0x02    /* PHYS ID 1               */
+#define MII_PHYSID2     0x03    /* PHYS ID 2               */
+#define MII_ADVERTISE       0x04    /* Advertisement control reg   */
+#define MII_LPA         0x05    /* Link partner ability reg    */
+#define MII_EXPANSION       0x06    /* Expansion register          */
+#define MII_CTRL1000        0x09    /* 1000BASE-T control          */
+#define MII_STAT1000        0x0a    /* 1000BASE-T status           */
+#define MII_ESTATUS     0x0f    /* Extended Status */
+#define MII_DCOUNTER        0x12    /* Disconnect counter          */
+#define MII_FCSCOUNTER      0x13    /* False carrier counter       */
+#define MII_NWAYTEST        0x14    /* N-way auto-neg test reg     */
+#define MII_RERRCOUNTER     0x15    /* Receive error counter       */
+#define MII_SREVISION       0x16    /* Silicon revision        */
+#define MII_RESV1       0x17    /* Reserved...             */
+#define MII_LBRERROR        0x18    /* Lpback, rx, bypass error    */
+#define MII_PHYADDR     0x19    /* PHY address             */
+#define MII_RESV2       0x1a    /* Reserved...             */
+#define MII_TPISTATUS       0x1b    /* TPI status for 10mbps       */
+#define MII_NCONFIG     0x1c    /* Network interface config    */
+
+/* Basic mode control register. */
+#define BMCR_RESV       0x003f  /* Unused...               */
+#define BMCR_SPEED1000      0x0040  /* MSB of Speed (1000)         */
+#define BMCR_CTST       0x0080  /* Collision test          */
+#define BMCR_FULLDPLX       0x0100  /* Full duplex             */
+#define BMCR_ANRESTART      0x0200  /* Auto negotiation restart    */
+#define BMCR_ISOLATE        0x0400  /* Disconnect DP83840 from MII */
+#define BMCR_PDOWN      0x0800  /* Powerdown the DP83840       */
+#define BMCR_ANENABLE       0x1000  /* Enable auto negotiation     */
+#define BMCR_SPEED100       0x2000  /* Select 100Mbps          */
+#define BMCR_LOOPBACK       0x4000  /* TXD loopback bits           */
+#define BMCR_RESET      0x8000  /* Reset the DP83840           */
+
+/* Basic mode status register. */
+#define BMSR_ERCAP      0x0001  /* Ext-reg capability          */
+#define BMSR_JCD        0x0002  /* Jabber detected         */
+#define BMSR_LSTATUS        0x0004  /* Link status             */
+#define BMSR_ANEGCAPABLE    0x0008  /* Able to do auto-negotiation */
+#define BMSR_RFAULT     0x0010  /* Remote fault detected       */
+#define BMSR_ANEGCOMPLETE   0x0020  /* Auto-negotiation complete   */
+#define BMSR_RESV       0x00c0  /* Unused...               */
+#define BMSR_ESTATEN        0x0100  /* Extended Status in R15 */
+#define BMSR_100HALF2       0x0200  /* Can do 100BASE-T2 HDX */
+#define BMSR_100FULL2       0x0400  /* Can do 100BASE-T2 FDX */
+#define BMSR_10HALF     0x0800  /* Can do 10mbps, half-duplex  */
+#define BMSR_10FULL     0x1000  /* Can do 10mbps, full-duplex  */
+#define BMSR_100HALF        0x2000  /* Can do 100mbps, half-duplex */
+#define BMSR_100FULL        0x4000  /* Can do 100mbps, full-duplex */
+#define BMSR_100BASE4       0x8000  /* Can do 100mbps, 4k packets  */
+
+/* Advertisement control register. */
+#define ADVERTISE_SLCT      0x001f  /* Selector bits           */
+#define ADVERTISE_CSMA      0x0001  /* Only selector supported     */
+#define ADVERTISE_10HALF    0x0020  /* Try for 10mbps half-duplex  */
+#define ADVERTISE_1000XFULL 0x0020  /* Try for 1000BASE-X full-duplex */
+#define ADVERTISE_10FULL    0x0040  /* Try for 10mbps full-duplex  */
+#define ADVERTISE_1000XHALF 0x0040  /* Try for 1000BASE-X half-duplex */
+#define ADVERTISE_100HALF   0x0080  /* Try for 100mbps half-duplex */
+#define ADVERTISE_1000XPAUSE    0x0080  /* Try for 1000BASE-X pause    */
+#define ADVERTISE_100FULL   0x0100  /* Try for 100mbps full-duplex */
+#define ADVERTISE_1000XPSE_ASYM 0x0100  /* Try for 1000BASE-X asym pause */
+#define ADVERTISE_100BASE4  0x0200  /* Try for 100mbps 4k packets  */
+#define ADVERTISE_PAUSE_CAP 0x0400  /* Try for pause           */
+#define ADVERTISE_PAUSE_ASYM    0x0800  /* Try for asymetric pause     */
+#define ADVERTISE_RESV      0x1000  /* Unused...               */
+#define ADVERTISE_RFAULT    0x2000  /* Say we can detect faults    */
+#define ADVERTISE_LPACK     0x4000  /* Ack link partners response  */
+#define ADVERTISE_NPAGE     0x8000  /* Next page bit           */
+
+#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \
+            ADVERTISE_CSMA)
+#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \
+               ADVERTISE_100HALF | ADVERTISE_100FULL)
+
+/* Link partner ability register. */
+#define LPA_SLCT        0x001f  /* Same as advertise selector  */
+#define LPA_10HALF      0x0020  /* Can do 10mbps half-duplex   */
+#define LPA_1000XFULL       0x0020  /* Can do 1000BASE-X full-duplex */
+#define LPA_10FULL      0x0040  /* Can do 10mbps full-duplex   */
+#define LPA_1000XHALF       0x0040  /* Can do 1000BASE-X half-duplex */
+#define LPA_100HALF     0x0080  /* Can do 100mbps half-duplex  */
+#define LPA_1000XPAUSE      0x0080  /* Can do 1000BASE-X pause     */
+#define LPA_100FULL     0x0100  /* Can do 100mbps full-duplex  */
+#define LPA_1000XPAUSE_ASYM 0x0100  /* Can do 1000BASE-X pause asym*/
+#define LPA_100BASE4        0x0200  /* Can do 100mbps 4k packets   */
+#define LPA_PAUSE_CAP       0x0400  /* Can pause               */
+#define LPA_PAUSE_ASYM      0x0800  /* Can pause asymetrically     */
+#define LPA_RESV        0x1000  /* Unused...               */
+#define LPA_RFAULT      0x2000  /* Link partner faulted        */
+#define LPA_LPACK       0x4000  /* Link partner acked us       */
+#define LPA_NPAGE       0x8000  /* Next page bit           */
+
+#define LPA_DUPLEX      (LPA_10FULL | LPA_100FULL)
+#define LPA_100         (LPA_100FULL | LPA_100HALF | LPA_100BASE4)
+
+/* Expansion register for auto-negotiation. */
+#define EXPANSION_NWAY      0x0001  /* Can do N-way auto-nego      */
+#define EXPANSION_LCWP      0x0002  /* Got new RX page code word   */
+#define EXPANSION_ENABLENPAGE   0x0004  /* This enables npage words    */
+#define EXPANSION_NPCAPABLE 0x0008  /* Link partner supports npage */
+#define EXPANSION_MFAULTS   0x0010  /* Multiple faults detected    */
+#define EXPANSION_RESV      0xffe0  /* Unused...               */
+
+#define ESTATUS_1000_XFULL  0x8000  /* Can do 1000BX Full */
+#define ESTATUS_1000_XHALF  0x4000  /* Can do 1000BX Half */
+#define ESTATUS_1000_TFULL  0x2000  /* Can do 1000BT Full */
+#define ESTATUS_1000_THALF  0x1000  /* Can do 1000BT Half */
+
+/* N-way test register. */
+#define NWAYTEST_RESV1      0x00ff  /* Unused...               */
+#define NWAYTEST_LOOPBACK   0x0100  /* Enable loopback for N-way   */
+#define NWAYTEST_RESV2      0xfe00  /* Unused...               */
+
+/* 1000BASE-T Control register */
+#define ADVERTISE_1000FULL  0x0200  /* Advertise 1000BASE-T full duplex */
+#define ADVERTISE_1000HALF  0x0100  /* Advertise 1000BASE-T half duplex */
+
+/* 1000BASE-T Status register */
+#define LPA_1000LOCALRXOK   0x2000  /* Link partner local receiver status */
+#define LPA_1000REMRXOK     0x1000  /* Link partner remote receiver status */
+#define LPA_1000FULL        0x0800  /* Link partner 1000BASE-T full duplex */
+#define LPA_1000HALF        0x0400  /* Link partner 1000BASE-T half duplex */
+
+/* Flow control flags */
+#define FLOW_CTRL_TX        0x01
+#define FLOW_CTRL_RX        0x02
+
+/**
+ * mii_nway_result
+ * @negotiated: value of MII ANAR and'd with ANLPAR
+ *
+ * Given a set of MII abilities, check each bit and returns the
+ * currently supported media, in the priority order defined by
+ * IEEE 802.3u.  We use LPA_xxx constants but note this is not the
+ * value of LPA solely, as described above.
+ *
+ * The one exception to IEEE 802.3u is that 100baseT4 is placed
+ * between 100T-full and 100T-half.  If your phy does not support
+ * 100T4 this is fine. If your phy places 100T4 elsewhere in the
+ * priority order, you will need to roll your own function.
+ */
+static inline unsigned int mii_nway_result(unsigned int negotiated)
+{
+    unsigned int ret;
+
+    if (negotiated & LPA_100FULL) {
+        ret = LPA_100FULL;
+    } else if (negotiated & LPA_100BASE4) {
+        ret = LPA_100BASE4;
+    } else if (negotiated & LPA_100HALF) {
+        ret = LPA_100HALF;
+    } else if (negotiated & LPA_10FULL) {
+        ret = LPA_10FULL;
+    } else {
+        ret = LPA_10HALF;
+    }
+
+    return ret;
+}
+
+/**
+ * mii_duplex
+ * @duplex_lock: Non-zero if duplex is locked at full
+ * @negotiated: value of MII ANAR and'd with ANLPAR
+ *
+ * A small helper function for a common case.  Returns one
+ * if the media is operating or locked at full duplex, and
+ * returns zero otherwise.
+ */
+static inline unsigned int mii_duplex(unsigned int duplex_lock,
+                                      unsigned int negotiated)
+{
+    if (duplex_lock) {
+        return 1;
+    }
+    if (mii_nway_result(negotiated) & LPA_DUPLEX) {
+        return 1;
+    }
+    return 0;
+}
diff --git a/libethdrivers/src/plat/odroidc2/uboot/miiphy.h b/libethdrivers/src/plat/odroidc2/uboot/miiphy.h
new file mode 100644
index 0000000..18b51a1
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/miiphy.h
@@ -0,0 +1,142 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+/*----------------------------------------------------------------------------+
+|   This source code is dual-licensed.  You may use it under the terms of the
+|   GNU General Public License version 2, or under the license below.
+|
+|   This source code has been made available to you by IBM on an AS-IS
+|   basis.  Anyone receiving this source is licensed under IBM
+|   copyrights to use it in any way he or she deems fit, including
+|   copying it, modifying it, compiling it, and redistributing it either
+|   with or without modifications.  No license under IBM patents or
+|   patent applications is to be implied by the copyright license.
+|
+|   Any user of this software should understand that IBM cannot provide
+|   technical support for this software and will not be responsible for
+|   any consequences resulting from the use of this software.
+|
+|   Any person who transfers this source code or any derivative work
+|   must include the IBM copyright notice, this paragraph, and the
+|   preceding two paragraphs in the transferred software.
+|
+|   COPYRIGHT   I B M   CORPORATION 1999
+|   LICENSED MATERIAL  -  PROGRAM PROPERTY OF I B M
+|
+|   Additions (C) Copyright 2009 Industrie Dial Face S.p.A.
++----------------------------------------------------------------------------*/
+/*----------------------------------------------------------------------------+
+|
+|  File Name:   miiphy.h
+|
+|  Function:    Include file defining PHY registers.
+|
+|  Author:  Mark Wisner
+|
++----------------------------------------------------------------------------*/
+#pragma once
+
+#include "common.h"
+#include "list.h"
+#include "phy.h"
+
+struct legacy_mii_dev {
+    int (*read)(const char *devname, unsigned char addr,
+                unsigned char reg, unsigned short *value);
+    int (*write)(const char *devname, unsigned char addr,
+                 unsigned char reg, unsigned short value);
+};
+
+int miiphy_read(const char *devname, unsigned char addr, unsigned char reg,
+                unsigned short *value);
+int miiphy_write(const char *devname, unsigned char addr, unsigned char reg,
+                 unsigned short value);
+int miiphy_info(const char *devname, unsigned char addr, unsigned int *oui,
+                unsigned char *model, unsigned char *rev);
+int miiphy_reset(const char *devname, unsigned char addr);
+int miiphy_speed(const char *devname, unsigned char addr);
+int miiphy_duplex(const char *devname, unsigned char addr);
+int miiphy_is_1000base_x(const char *devname, unsigned char addr);
+#ifdef CONFIG_SYS_FAULT_ECHO_LINK_DOWN
+int miiphy_link(const char *devname, unsigned char addr);
+#endif
+
+void miiphy_init(void);
+
+void miiphy_register(const char *devname,
+                     int (*read)(const char *devname, unsigned char addr,
+                                 unsigned char reg, unsigned short *value),
+                     int (*write)(const char *devname, unsigned char addr,
+                                  unsigned char reg, unsigned short value));
+
+int miiphy_set_current_dev(const char *devname);
+const char *miiphy_get_current_dev(void);
+struct mii_dev *mdio_get_current_dev(void);
+struct mii_dev *miiphy_get_dev_by_name(const char *devname);
+struct phy_device *mdio_phydev_for_ethname(const char *devname);
+
+void miiphy_listdev(void);
+
+struct mii_dev *mdio_alloc(void);
+int mdio_register(struct mii_dev *bus);
+void mdio_list_devices(void);
+
+#ifdef CONFIG_BITBANGMII
+
+#define BB_MII_DEVNAME  "bb_miiphy"
+
+struct bb_miiphy_bus {
+    char name[16];
+    int (*init)(struct bb_miiphy_bus *bus);
+    int (*mdio_active)(struct bb_miiphy_bus *bus);
+    int (*mdio_tristate)(struct bb_miiphy_bus *bus);
+    int (*set_mdio)(struct bb_miiphy_bus *bus, int v);
+    int (*get_mdio)(struct bb_miiphy_bus *bus, int *v);
+    int (*set_mdc)(struct bb_miiphy_bus *bus, int v);
+    int (*delay)(struct bb_miiphy_bus *bus);
+#ifdef CONFIG_BITBANGMII_MULTI
+    void *priv;
+#endif
+};
+
+extern struct bb_miiphy_bus bb_miiphy_buses[];
+extern int bb_miiphy_buses_num;
+
+void bb_miiphy_init(void);
+int bb_miiphy_read(const char *devname, unsigned char addr,
+                   unsigned char reg, unsigned short *value);
+int bb_miiphy_write(const char *devname, unsigned char addr,
+                    unsigned char reg, unsigned short value);
+#endif
+
+/* phy seed setup */
+#define AUTO            99
+#define _1000BASET      1000
+#define _100BASET       100
+#define _10BASET        10
+#define HALF            22
+#define FULL            44
+
+/* phy register offsets */
+#define MII_MIPSCR      0x11
+
+/* MII_LPA */
+#define PHY_ANLPAR_PSB_802_3    0x0001
+#define PHY_ANLPAR_PSB_802_9    0x0002
+
+/* MII_CTRL1000 masks */
+#define PHY_1000BTCR_1000FD 0x0200
+#define PHY_1000BTCR_1000HD 0x0100
+
+/* MII_STAT1000 masks */
+#define PHY_1000BTSR_MSCF   0x8000
+#define PHY_1000BTSR_MSCR   0x4000
+#define PHY_1000BTSR_LRS    0x2000
+#define PHY_1000BTSR_RRS    0x1000
+#define PHY_1000BTSR_1000FD 0x0800
+#define PHY_1000BTSR_1000HD 0x0400
+
+/* phy EXSR */
+#define ESTATUS_1000XF      0x8000
+#define ESTATUS_1000XH      0x4000
diff --git a/libethdrivers/src/plat/odroidc2/uboot/miiphyutil.c b/libethdrivers/src/plat/odroidc2/uboot/miiphyutil.c
new file mode 100644
index 0000000..490c6c6
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/miiphyutil.c
@@ -0,0 +1,625 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+
+/*
+ * (C) Copyright 2001
+ * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * 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 (at your option) 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+/*
+ * This provides a bit-banged interface to the ethernet MII management
+ * channel.
+ */
+
+#include "common.h"
+#include "miiphy.h"
+#include "phy.h"
+
+#include "list.h"
+#include "net.h"
+#include <stdlib.h>
+#include <string.h>
+#include "../unimplemented.h"
+
+#define BUG_ON(x) do {} while(0)
+
+/* local debug macro */
+#undef MII_DEBUG
+
+#undef debug
+#ifdef MII_DEBUG
+#define debug(fmt, args...) printf(fmt, ##args)
+#else
+#define debug(fmt, args...)
+#endif /* MII_DEBUG */
+
+static struct list_head mii_devs;
+static struct mii_dev *current_mii;
+
+/*
+ * Lookup the mii_dev struct by the registered device name.
+ */
+struct mii_dev *miiphy_get_dev_by_name(const char *devname)
+{
+    struct list_head *entry;
+    struct mii_dev *dev;
+
+    if (!devname) {
+        printf("NULL device name!\n");
+        return NULL;
+    }
+
+    list_for_each(entry, &mii_devs) {
+        dev = list_entry(entry, struct mii_dev, link);
+        if (strcmp(dev->name, devname) == 0) {
+            return dev;
+        }
+    }
+
+    return NULL;
+}
+
+/*****************************************************************************
+ *
+ * Initialize global data. Need to be called before any other miiphy routine.
+ */
+void miiphy_init(void)
+{
+    mii_devs.next = &mii_devs;
+    mii_devs.prev = &mii_devs;
+    current_mii = NULL;
+}
+
+static int legacy_miiphy_read(struct mii_dev *bus, int addr, int devad, int reg)
+{
+    unsigned short val;
+    int ret;
+    struct legacy_mii_dev *ldev = bus->priv;
+
+    ret = ldev->read(bus->name, addr, reg, &val);
+
+    return ret ? -1 : (int)val;
+}
+
+static int legacy_miiphy_write(struct mii_dev *bus, int addr, int devad,
+                               int reg, u16 val)
+{
+    struct legacy_mii_dev *ldev = bus->priv;
+
+    return ldev->write(bus->name, addr, reg, val);
+}
+
+/*****************************************************************************
+ *
+ * Register read and write MII access routines for the device <name>.
+ * This API is now deprecated. Please use mdio_alloc and mdio_register, instead.
+ */
+void miiphy_register(const char *name,
+                     int (*read)(const char *devname, unsigned char addr,
+                                 unsigned char reg, unsigned short *value),
+                     int (*write)(const char *devname, unsigned char addr,
+                                  unsigned char reg, unsigned short value))
+{
+    struct mii_dev *new_dev;
+    struct legacy_mii_dev *ldev;
+
+    BUG_ON(strlen(name) >= MDIO_NAME_LEN);
+
+    /* check if we have unique name */
+    new_dev = miiphy_get_dev_by_name(name);
+    if (new_dev) {
+        printf("miiphy_register: non unique device name '%s'\n", name);
+        return;
+    }
+
+    /* allocate memory */
+    new_dev = mdio_alloc();
+    ldev = malloc(sizeof(*ldev));
+
+    if (new_dev == NULL || ldev == NULL) {
+        printf("miiphy_register: cannot allocate memory for '%s'\n",
+               name);
+        return;
+    }
+
+    /* initalize mii_dev struct fields */
+    new_dev->read = legacy_miiphy_read;
+    new_dev->write = legacy_miiphy_write;
+    strncpy(new_dev->name, name, MDIO_NAME_LEN);
+    new_dev->name[MDIO_NAME_LEN - 1] = 0;
+    ldev->read = read;
+    ldev->write = write;
+    new_dev->priv = ldev;
+
+    debug("miiphy_register: added '%s', read=0x%08lx, write=0x%08lx\n",
+          new_dev->name, ldev->read, ldev->write);
+
+    /* add it to the list */
+    list_add_tail(&new_dev->link, &mii_devs);
+
+    if (!current_mii) {
+        current_mii = new_dev;
+    }
+}
+
+struct mii_dev *mdio_alloc(void)
+{
+    struct mii_dev *bus;
+
+    bus = malloc(sizeof(*bus));
+    if (!bus) {
+        return bus;
+    }
+
+    memset(bus, 0, sizeof(*bus));
+
+    /* initalize mii_dev struct fields */
+    INIT_LIST_HEAD(&bus->link);
+
+    return bus;
+}
+
+int mdio_register(struct mii_dev *bus)
+{
+    if (!bus || !bus->name || !bus->read || !bus->write) {
+        return -1;
+    }
+
+    /* check if we have unique name */
+    if (miiphy_get_dev_by_name(bus->name)) {
+        printf("mdio_register: non unique device name '%s'\n",
+               bus->name);
+        return -1;
+    }
+
+    /* add it to the list */
+    list_add_tail(&bus->link, &mii_devs);
+
+    if (!current_mii) {
+        current_mii = bus;
+    }
+
+    return 0;
+}
+
+void mdio_list_devices(void)
+{
+    struct list_head *entry;
+
+    list_for_each(entry, &mii_devs) {
+        int i;
+        struct mii_dev *bus = list_entry(entry, struct mii_dev, link);
+
+        printf("%s:\n", bus->name);
+
+        for (i = 0; i < PHY_MAX_ADDR; i++) {
+            struct phy_device *phydev = bus->phymap[i];
+
+            if (phydev) {
+                printf("%d - %s", i, phydev->drv->name);
+
+                if (phydev->dev) {
+                    printf(" <--> %s\n", phydev->dev->name);
+                } else {
+                    printf("\n");
+                }
+            }
+        }
+    }
+}
+
+int miiphy_set_current_dev(const char *devname)
+{
+    struct mii_dev *dev;
+
+    dev = miiphy_get_dev_by_name(devname);
+    if (dev) {
+        current_mii = dev;
+        return 0;
+    }
+
+    printf("No such device: %s\n", devname);
+
+    return 1;
+}
+
+struct mii_dev *mdio_get_current_dev(void)
+{
+    return current_mii;
+}
+
+struct phy_device *mdio_phydev_for_ethname(const char *ethname)
+{
+    struct list_head *entry;
+    struct mii_dev *bus;
+
+    list_for_each(entry, &mii_devs) {
+        int i;
+        bus = list_entry(entry, struct mii_dev, link);
+
+        for (i = 0; i < PHY_MAX_ADDR; i++) {
+            if (!bus->phymap[i] || !bus->phymap[i]->dev) {
+                continue;
+            }
+
+            if (strcmp(bus->phymap[i]->dev->name, ethname) == 0) {
+                return bus->phymap[i];
+            }
+        }
+    }
+
+    printf("%s is not a known ethernet\n", ethname);
+    return NULL;
+}
+
+const char *miiphy_get_current_dev(void)
+{
+    if (current_mii) {
+        return current_mii->name;
+    }
+
+    return NULL;
+}
+
+static struct mii_dev *miiphy_get_active_dev(const char *devname)
+{
+    /* If the current mii is the one we want, return it */
+    if (current_mii)
+        if (strcmp(current_mii->name, devname) == 0) {
+            return current_mii;
+        }
+
+    /* Otherwise, set the active one to the one we want */
+    if (miiphy_set_current_dev(devname)) {
+        return NULL;
+    } else {
+        return current_mii;
+    }
+}
+
+/*****************************************************************************
+ *
+ * Read to variable <value> from the PHY attached to device <devname>,
+ * use PHY address <addr> and register <reg>.
+ *
+ * This API is deprecated. Use phy_read on a phy_device found via phy_connect
+ *
+ * Returns:
+ *   0 on success
+ */
+int miiphy_read(const char *devname, unsigned char addr, unsigned char reg,
+                unsigned short *value)
+{
+    struct mii_dev *bus;
+    int ret;
+
+    bus = miiphy_get_active_dev(devname);
+    if (!bus) {
+        return 1;
+    }
+
+    ret = bus->read(bus, addr, MDIO_DEVAD_NONE, reg);
+    if (ret < 0) {
+        return 1;
+    }
+
+    *value = (unsigned short)ret;
+    return 0;
+}
+
+/*****************************************************************************
+ *
+ * Write <value> to the PHY attached to device <devname>,
+ * use PHY address <addr> and register <reg>.
+ *
+ * This API is deprecated. Use phy_write on a phy_device found by phy_connect
+ *
+ * Returns:
+ *   0 on success
+ */
+int miiphy_write(const char *devname, unsigned char addr, unsigned char reg,
+                 unsigned short value)
+{
+    struct mii_dev *bus;
+
+    bus = miiphy_get_active_dev(devname);
+    if (bus) {
+        return bus->write(bus, addr, MDIO_DEVAD_NONE, reg, value);
+    }
+
+    return 1;
+}
+
+/*****************************************************************************
+ *
+ * Print out list of registered MII capable devices.
+ */
+void miiphy_listdev(void)
+{
+    struct list_head *entry;
+    struct mii_dev *dev;
+
+    puts("MII devices: ");
+    list_for_each(entry, &mii_devs) {
+        dev = list_entry(entry, struct mii_dev, link);
+        printf("'%s' ", dev->name);
+    }
+    puts("\n");
+
+    if (current_mii) {
+        printf("Current device: '%s'\n", current_mii->name);
+    }
+}
+
+/*****************************************************************************
+ *
+ * Read the OUI, manufacture's model number, and revision number.
+ *
+ * OUI:     22 bits (unsigned int)
+ * Model:    6 bits (unsigned char)
+ * Revision: 4 bits (unsigned char)
+ *
+ * This API is deprecated.
+ *
+ * Returns:
+ *   0 on success
+ */
+int miiphy_info(const char *devname, unsigned char addr, unsigned int *oui,
+                unsigned char *model, unsigned char *rev)
+{
+    unsigned int reg = 0;
+    unsigned short tmp;
+
+    if (miiphy_read(devname, addr, MII_PHYSID2, &tmp) != 0) {
+        debug("PHY ID register 2 read failed\n");
+        return -1;
+    }
+    reg = tmp;
+
+    debug("MII_PHYSID2 @ 0x%x = 0x%04x\n", addr, reg);
+
+    if (reg == 0xFFFF) {
+        /* No physical device present at this address */
+        return -1;
+    }
+
+    if (miiphy_read(devname, addr, MII_PHYSID1, &tmp) != 0) {
+        debug("PHY ID register 1 read failed\n");
+        return -1;
+    }
+    reg |= tmp << 16;
+    debug("PHY_PHYIDR[1,2] @ 0x%x = 0x%08x\n", addr, reg);
+
+    *oui = (reg >> 10);
+    *model = (unsigned char)((reg >> 4) & 0x0000003F);
+    *rev = (unsigned char)(reg & 0x0000000F);
+    return 0;
+}
+
+#ifndef CONFIG_PHYLIB
+/*****************************************************************************
+ *
+ * Reset the PHY.
+ *
+ * This API is deprecated. Use PHYLIB.
+ *
+ * Returns:
+ *   0 on success
+ */
+int miiphy_reset(const char *devname, unsigned char addr)
+{
+    unsigned short reg;
+    int timeout = 500;
+
+    if (miiphy_read(devname, addr, MII_BMCR, &reg) != 0) {
+        debug("PHY status read failed\n");
+        return -1;
+    }
+    if (miiphy_write(devname, addr, MII_BMCR, reg | BMCR_RESET) != 0) {
+        debug("PHY reset failed\n");
+        return -1;
+    }
+#ifdef CONFIG_PHY_RESET_DELAY
+    udelay(CONFIG_PHY_RESET_DELAY); /* Intel LXT971A needs this */
+#endif
+    /*
+     * Poll the control register for the reset bit to go to 0 (it is
+     * auto-clearing).  This should happen within 0.5 seconds per the
+     * IEEE spec.
+     */
+    reg = 0x8000;
+    while (((reg & 0x8000) != 0) && timeout--) {
+        if (miiphy_read(devname, addr, MII_BMCR, &reg) != 0) {
+            debug("PHY status read failed\n");
+            return -1;
+        }
+        udelay(1000);
+    }
+    if ((reg & 0x8000) == 0) {
+        return 0;
+    } else {
+        puts("PHY reset timed out\n");
+        return -1;
+    }
+    return 0;
+}
+#endif /* !PHYLIB */
+
+/*****************************************************************************
+ *
+ * Determine the ethernet speed (10/100/1000).  Return 10 on error.
+ */
+int miiphy_speed(const char *devname, unsigned char addr)
+{
+    u16 bmcr, anlpar;
+
+#if defined(CONFIG_PHY_GIGE)
+    u16 btsr;
+
+    /*
+     * Check for 1000BASE-X.  If it is supported, then assume that the speed
+     * is 1000.
+     */
+    if (miiphy_is_1000base_x(devname, addr)) {
+        return _1000BASET;
+    }
+
+    /*
+     * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
+     */
+    /* Check for 1000BASE-T. */
+    if (miiphy_read(devname, addr, MII_STAT1000, &btsr)) {
+        printf("PHY 1000BT status");
+        goto miiphy_read_failed;
+    }
+    if (btsr != 0xFFFF &&
+        (btsr & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD))) {
+        return _1000BASET;
+    }
+#endif /* CONFIG_PHY_GIGE */
+
+    /* Check Basic Management Control Register first. */
+    if (miiphy_read(devname, addr, MII_BMCR, &bmcr)) {
+        printf("PHY speed");
+        goto miiphy_read_failed;
+    }
+    /* Check if auto-negotiation is on. */
+    if (bmcr & BMCR_ANENABLE) {
+        /* Get auto-negotiation results. */
+        if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
+            printf("PHY AN speed");
+            goto miiphy_read_failed;
+        }
+        return (anlpar & LPA_100) ? _100BASET : _10BASET;
+    }
+    /* Get speed from basic control settings. */
+    return (bmcr & BMCR_SPEED100) ? _100BASET : _10BASET;
+
+miiphy_read_failed:
+    printf(" read failed, assuming 10BASE-T\n");
+    return _10BASET;
+}
+
+/*****************************************************************************
+ *
+ * Determine full/half duplex.  Return half on error.
+ */
+int miiphy_duplex(const char *devname, unsigned char addr)
+{
+    u16 bmcr, anlpar;
+
+#if defined(CONFIG_PHY_GIGE)
+    u16 btsr;
+
+    /* Check for 1000BASE-X. */
+    if (miiphy_is_1000base_x(devname, addr)) {
+        /* 1000BASE-X */
+        if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
+            printf("1000BASE-X PHY AN duplex");
+            goto miiphy_read_failed;
+        }
+    }
+    /*
+     * No 1000BASE-X, so assume 1000BASE-T/100BASE-TX/10BASE-T register set.
+     */
+    /* Check for 1000BASE-T. */
+    if (miiphy_read(devname, addr, MII_STAT1000, &btsr)) {
+        printf("PHY 1000BT status");
+        goto miiphy_read_failed;
+    }
+    if (btsr != 0xFFFF) {
+        if (btsr & PHY_1000BTSR_1000FD) {
+            return FULL;
+        } else if (btsr & PHY_1000BTSR_1000HD) {
+            return HALF;
+        }
+    }
+#endif /* CONFIG_PHY_GIGE */
+
+    /* Check Basic Management Control Register first. */
+    if (miiphy_read(devname, addr, MII_BMCR, &bmcr)) {
+        puts("PHY duplex");
+        goto miiphy_read_failed;
+    }
+    /* Check if auto-negotiation is on. */
+    if (bmcr & BMCR_ANENABLE) {
+        /* Get auto-negotiation results. */
+        if (miiphy_read(devname, addr, MII_LPA, &anlpar)) {
+            puts("PHY AN duplex");
+            goto miiphy_read_failed;
+        }
+        return (anlpar & (LPA_10FULL | LPA_100FULL)) ?
+               FULL : HALF;
+    }
+    /* Get speed from basic control settings. */
+    return (bmcr & BMCR_FULLDPLX) ? FULL : HALF;
+
+miiphy_read_failed:
+    printf(" read failed, assuming half duplex\n");
+    return HALF;
+}
+
+/*****************************************************************************
+ *
+ * Return 1 if PHY supports 1000BASE-X, 0 if PHY supports 10BASE-T/100BASE-TX/
+ * 1000BASE-T, or on error.
+ */
+int miiphy_is_1000base_x(const char *devname, unsigned char addr)
+{
+#if defined(CONFIG_PHY_GIGE)
+    u16 exsr;
+
+    if (miiphy_read(devname, addr, MII_ESTATUS, &exsr)) {
+        printf("PHY extended status read failed, assuming no "
+               "1000BASE-X\n");
+        return 0;
+    }
+    return 0 != (exsr & (ESTATUS_1000XF | ESTATUS_1000XH));
+#else
+    return 0;
+#endif
+}
+
+#ifdef CONFIG_SYS_FAULT_ECHO_LINK_DOWN
+/*****************************************************************************
+ *
+ * Determine link status
+ */
+int miiphy_link(const char *devname, unsigned char addr)
+{
+    unsigned short reg;
+
+    /* dummy read; needed to latch some phys */
+    (void)miiphy_read(devname, addr, MII_BMSR, &reg);
+    if (miiphy_read(devname, addr, MII_BMSR, &reg)) {
+        puts("MII_BMSR read failed, assuming no link\n");
+        return 0;
+    }
+
+    /* Determine if a link is active */
+    if ((reg & BMSR_LSTATUS) != 0) {
+        return 1;
+    } else {
+        return 0;
+    }
+}
+#endif
diff --git a/libethdrivers/src/plat/odroidc2/uboot/net.h b/libethdrivers/src/plat/odroidc2/uboot/net.h
new file mode 100644
index 0000000..9a808e9
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/net.h
@@ -0,0 +1,846 @@
+/*
+ *  LiMon Monitor (LiMon) - Network.
+ *
+ *  Copyright 1994 - 2000 Neil Russell.
+ *  (See License)
+ *  SPDX-License-Identifier:    GPL-2.0-only
+ *
+ * History
+ *  9/16/00   bor  adapted to TQM823L/STK8xxL board, RARP/TFTP boot added
+ */
+
+#pragma once
+
+#include <string.h>
+#include <stdlib.h>
+#include "config.h"
+#include "../unimplemented.h"   /* for nton* / ntoh* stuff */
+#include "phy.h"
+
+#define DEBUG_LL_STATE 0    /* Link local state machine changes */
+#define DEBUG_DEV_PKT 0     /* Packets or info directed to the device */
+#define DEBUG_NET_PKT 0     /* Packets on info on the network at large */
+#define DEBUG_INT_STATE 0   /* Internal network state changes */
+
+/*
+ *  The number of receive packet buffers, and the required packet buffer
+ *  alignment in memory.
+ *
+ */
+
+#ifdef CONFIG_SYS_RX_ETH_BUFFER
+# define PKTBUFSRX  CONFIG_SYS_RX_ETH_BUFFER
+#else
+# define PKTBUFSRX  4
+#endif
+
+#define PKTALIGN    ARCH_DMA_MINALIGN
+
+/* IPv4 addresses are always 32 bits in size */
+struct in_addr {
+    __be32 s_addr;
+};
+
+/**
+ * An incoming packet handler.
+ * @param pkt    pointer to the application packet
+ * @param dport  destination UDP port
+ * @param sip    source IP address
+ * @param sport  source UDP port
+ * @param len    packet length
+ */
+typedef void rxhand_f(uchar *pkt, unsigned dport,
+                      struct in_addr sip, unsigned sport,
+                      unsigned len);
+
+/**
+ * An incoming ICMP packet handler.
+ * @param type  ICMP type
+ * @param code  ICMP code
+ * @param dport destination UDP port
+ * @param sip   source IP address
+ * @param sport source UDP port
+ * @param pkt   pointer to the ICMP packet data
+ * @param len   packet length
+ */
+typedef void rxhand_icmp_f(unsigned type, unsigned code, unsigned dport,
+                           struct in_addr sip, unsigned sport, uchar *pkt, unsigned len);
+
+/*
+ *  A timeout handler.  Called after time interval has expired.
+ */
+typedef void    thand_f(void);
+
+enum eth_state_t {
+    ETH_STATE_INIT,
+    ETH_STATE_PASSIVE,
+    ETH_STATE_ACTIVE
+};
+
+#ifdef CONFIG_DM_ETH
+/**
+ * struct eth_pdata - Platform data for Ethernet MAC controllers
+ *
+ * @iobase: The base address of the hardware registers
+ * @enetaddr: The Ethernet MAC address that is loaded from EEPROM or env
+ * @phy_interface: PHY interface to use - see PHY_INTERFACE_MODE_...
+ * @max_speed: Maximum speed of Ethernet connection supported by MAC
+ */
+struct eth_pdata {
+    phys_addr_t iobase;
+    unsigned char enetaddr[6];
+    int phy_interface;
+    int max_speed;
+};
+
+enum eth_recv_flags {
+    /*
+     * Check hardware device for new packets (otherwise only return those
+     * which are already in the memory buffer ready to process)
+     */
+    ETH_RECV_CHECK_DEVICE       = 1 << 0,
+};
+
+/**
+ * struct eth_ops - functions of Ethernet MAC controllers
+ *
+ * start: Prepare the hardware to send and receive packets
+ * send: Send the bytes passed in "packet" as a packet on the wire
+ * recv: Check if the hardware received a packet. If so, set the pointer to the
+ *   packet buffer in the packetp parameter. If not, return an error or 0 to
+ *   indicate that the hardware receive FIFO is empty. If 0 is returned, the
+ *   network stack will not process the empty packet, but free_pkt() will be
+ *   called if supplied
+ * free_pkt: Give the driver an opportunity to manage its packet buffer memory
+ *       when the network stack is finished processing it. This will only be
+ *       called when no error was returned from recv - optional
+ * stop: Stop the hardware from looking for packets - may be called even if
+ *   state == PASSIVE
+ * mcast: Join or leave a multicast group (for TFTP) - optional
+ * write_hwaddr: Write a MAC address to the hardware (used to pass it to Linux
+ *       on some platforms like ARM). This function expects the
+ *       eth_pdata::enetaddr field to be populated. The method can
+ *       return -ENOSYS to indicate that this is not implemented for
+         this hardware - optional.
+ * read_rom_hwaddr: Some devices have a backup of the MAC address stored in a
+ *          ROM on the board. This is how the driver should expose it
+ *          to the network stack. This function should fill in the
+ *          eth_pdata::enetaddr field - optional
+ */
+struct eth_ops {
+    int (*start)(struct udevice *dev);
+    int (*send)(struct udevice *dev, void *packet, int length);
+    int (*recv)(struct udevice *dev, int flags, uchar **packetp);
+    int (*free_pkt)(struct udevice *dev, uchar *packet, int length);
+    void (*stop)(struct udevice *dev);
+#ifdef CONFIG_MCAST_TFTP
+    int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join);
+#endif
+    int (*write_hwaddr)(struct udevice *dev);
+    int (*read_rom_hwaddr)(struct udevice *dev);
+};
+
+#define eth_get_ops(dev) ((struct eth_ops *)(dev)->driver->ops)
+
+struct udevice *eth_get_dev(void); /* get the current device */
+/*
+ * The devname can be either an exact name given by the driver or device tree
+ * or it can be an alias of the form "eth%d"
+ */
+struct udevice *eth_get_dev_by_name(const char *devname);
+unsigned char *eth_get_ethaddr(void); /* get the current device MAC */
+
+/* Used only when NetConsole is enabled */
+int eth_is_active(struct udevice *dev); /* Test device for active state */
+int eth_init_state_only(void); /* Set active state */
+void eth_halt_state_only(void); /* Set passive state */
+#endif
+
+#ifndef CONFIG_DM_ETH
+struct eth_device {
+    char name[16];
+    unsigned char enetaddr[6];
+    phys_addr_t iobase;
+    int state;
+
+    int (*init)(struct eth_device *);
+    int (*send)(struct eth_device *, void *packet, int length);
+    int (*recv)(struct eth_device *);
+    void (*halt)(struct eth_device *);
+#ifdef CONFIG_MCAST_TFTP
+    int (*mcast)(struct eth_device *, const u8 *enetaddr, u8 set);
+#endif
+    int (*write_hwaddr)(struct eth_device *);
+    struct eth_device *next;
+    int index;
+    void *priv;
+};
+
+int eth_register(struct eth_device *dev);/* Register network device */
+int eth_unregister(struct eth_device *dev);/* Remove network device */
+
+extern struct eth_device *eth_current;
+
+static __always_inline struct eth_device *eth_get_dev(void)
+{
+    return eth_current;
+}
+struct eth_device *eth_get_dev_by_name(const char *devname);
+struct eth_device *eth_get_dev_by_index(int index); /* get dev @ index */
+
+/* get the current device MAC */
+static inline unsigned char *eth_get_ethaddr(void)
+{
+    if (eth_current) {
+        return eth_current->enetaddr;
+    }
+    return NULL;
+}
+
+/* Used only when NetConsole is enabled */
+int eth_is_active(struct eth_device *dev); /* Test device for active state */
+/* Set active state */
+static __always_inline int eth_init_state_only(void)
+{
+    eth_get_dev()->state = ETH_STATE_ACTIVE;
+
+    return 0;
+}
+/* Set passive state */
+static __always_inline void eth_halt_state_only(void)
+{
+    eth_get_dev()->state = ETH_STATE_PASSIVE;
+}
+
+/*
+ * Set the hardware address for an ethernet interface based on 'eth%daddr'
+ * environment variable (or just 'ethaddr' if eth_number is 0).
+ * Args:
+ *  base_name - base name for device (normally "eth")
+ *  eth_number - value of %d (0 for first device of this type)
+ * Returns:
+ *  0 is success, non-zero is error status from driver.
+ */
+int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
+                     int eth_number);
+
+int usb_eth_initialize(bd_t *bi);
+#endif
+
+int eth_initialize(void);       /* Initialize network subsystem */
+void eth_try_another(int first_restart);    /* Change the device */
+void eth_set_current(void);     /* set nterface to ethcur var */
+
+int eth_get_dev_index(void);        /* get the device index */
+void eth_parse_enetaddr(const char *addr, uchar *enetaddr);
+int eth_getenv_enetaddr(const char *name, uchar *enetaddr);
+int eth_setenv_enetaddr(const char *name, const uchar *enetaddr);
+
+/**
+ * eth_setenv_enetaddr_by_index() - set the MAC address envrionment variable
+ *
+ * This sets up an environment variable with the given MAC address (@enetaddr).
+ * The environment variable to be set is defined by <@base_name><@index>addr.
+ * If @index is 0 it is omitted. For common Ethernet this means ethaddr,
+ * eth1addr, etc.
+ *
+ * @base_name:  Base name for variable, typically "eth"
+ * @index:      Index of interface being updated (>=0)
+ * @enetaddr:   Pointer to MAC address to put into the variable
+ * @return 0 if OK, other value on error
+ */
+int eth_setenv_enetaddr_by_index(const char *base_name, int index,
+                                 uchar *enetaddr);
+
+
+/*
+ * Get the hardware address for an ethernet interface .
+ * Args:
+ *  base_name - base name for device (normally "eth")
+ *  index - device index number (0 for first)
+ *  enetaddr - returns 6 byte hardware address
+ * Returns:
+ *  Return true if the address is valid.
+ */
+int eth_getenv_enetaddr_by_index(const char *base_name, int index,
+                                 uchar *enetaddr);
+
+int eth_init(void);         /* Initialize the device */
+int eth_send(void *packet, int length);    /* Send a packet */
+
+#if defined(CONFIG_API) || defined(CONFIG_EFI_LOADER)
+int eth_receive(void *packet, int length); /* Receive a packet*/
+extern void (*push_packet)(void *packet, int length);
+#endif
+int eth_rx(void);           /* Check for received packets */
+void eth_halt(void);            /* stop SCC */
+const char *eth_get_name(void);     /* get name of current device */
+
+#ifdef CONFIG_MCAST_TFTP
+int eth_mcast_join(struct in_addr mcast_addr, int join);
+u32 ether_crc(size_t len, unsigned char const *p);
+#endif
+
+
+/**********************************************************************/
+/*
+ *  Protocol headers.
+ */
+
+/*
+ *  Ethernet header
+ */
+
+struct ethernet_hdr {
+    u8      et_dest[6]; /* Destination node     */
+    u8      et_src[6];  /* Source node          */
+    u16     et_protlen; /* Protocol or length       */
+};
+
+/* Ethernet header size */
+#define ETHER_HDR_SIZE  (sizeof(struct ethernet_hdr))
+
+#define ETH_FCS_LEN 4       /* Octets in the FCS        */
+
+struct e802_hdr {
+    u8      et_dest[6]; /* Destination node     */
+    u8      et_src[6];  /* Source node          */
+    u16     et_protlen; /* Protocol or length       */
+    u8      et_dsap;    /* 802 DSAP         */
+    u8      et_ssap;    /* 802 SSAP         */
+    u8      et_ctl;     /* 802 control          */
+    u8      et_snap1;   /* SNAP             */
+    u8      et_snap2;
+    u8      et_snap3;
+    u16     et_prot;    /* 802 protocol         */
+};
+
+/* 802 + SNAP + ethernet header size */
+#define E802_HDR_SIZE   (sizeof(struct e802_hdr))
+
+/*
+ *  Virtual LAN Ethernet header
+ */
+struct vlan_ethernet_hdr {
+    u8      vet_dest[6];    /* Destination node     */
+    u8      vet_src[6]; /* Source node          */
+    u16     vet_vlan_type;  /* PROT_VLAN            */
+    u16     vet_tag;    /* TAG of VLAN          */
+    u16     vet_type;   /* protocol type        */
+};
+
+/* VLAN Ethernet header size */
+#define VLAN_ETHER_HDR_SIZE (sizeof(struct vlan_ethernet_hdr))
+
+#define PROT_IP     0x0800      /* IP protocol          */
+#define PROT_ARP    0x0806      /* IP ARP protocol      */
+#define PROT_RARP   0x8035      /* IP ARP protocol      */
+#define PROT_VLAN   0x8100      /* IEEE 802.1q protocol     */
+#define PROT_IPV6   0x86dd      /* IPv6 over bluebook       */
+#define PROT_PPP_SES    0x8864      /* PPPoE session messages   */
+
+#define IPPROTO_ICMP     1  /* Internet Control Message Protocol    */
+#define IPPROTO_UDP 17  /* User Datagram Protocol       */
+
+/*
+ *  Internet Protocol (IP) header.
+ */
+struct ip_hdr {
+    u8      ip_hl_v;    /* header length and version    */
+    u8      ip_tos;     /* type of service      */
+    u16     ip_len;     /* total length         */
+    u16     ip_id;      /* identification       */
+    u16     ip_off;     /* fragment offset field    */
+    u8      ip_ttl;     /* time to live         */
+    u8      ip_p;       /* protocol         */
+    u16     ip_sum;     /* checksum         */
+    struct in_addr  ip_src;     /* Source IP address        */
+    struct in_addr  ip_dst;     /* Destination IP address   */
+};
+
+#define IP_OFFS     0x1fff /* ip offset *= 8 */
+#define IP_FLAGS    0xe000 /* first 3 bits */
+#define IP_FLAGS_RES    0x8000 /* reserved */
+#define IP_FLAGS_DFRAG  0x4000 /* don't fragments */
+#define IP_FLAGS_MFRAG  0x2000 /* more fragments */
+
+#define IP_HDR_SIZE     (sizeof(struct ip_hdr))
+
+/*
+ *  Internet Protocol (IP) + UDP header.
+ */
+struct ip_udp_hdr {
+    u8      ip_hl_v;    /* header length and version    */
+    u8      ip_tos;     /* type of service      */
+    u16     ip_len;     /* total length         */
+    u16     ip_id;      /* identification       */
+    u16     ip_off;     /* fragment offset field    */
+    u8      ip_ttl;     /* time to live         */
+    u8      ip_p;       /* protocol         */
+    u16     ip_sum;     /* checksum         */
+    struct in_addr  ip_src;     /* Source IP address        */
+    struct in_addr  ip_dst;     /* Destination IP address   */
+    u16     udp_src;    /* UDP source port      */
+    u16     udp_dst;    /* UDP destination port     */
+    u16     udp_len;    /* Length of UDP packet     */
+    u16     udp_xsum;   /* Checksum         */
+};
+
+#define IP_UDP_HDR_SIZE     (sizeof(struct ip_udp_hdr))
+#define UDP_HDR_SIZE        (IP_UDP_HDR_SIZE - IP_HDR_SIZE)
+
+/*
+ *  Address Resolution Protocol (ARP) header.
+ */
+struct arp_hdr {
+    u16     ar_hrd;     /* Format of hardware address   */
+#   define ARP_ETHER        1       /* Ethernet  hardware address   */
+    u16     ar_pro;     /* Format of protocol address   */
+    u8      ar_hln;     /* Length of hardware address   */
+#   define ARP_HLEN 6
+    u8      ar_pln;     /* Length of protocol address   */
+#   define ARP_PLEN 4
+    u16     ar_op;      /* Operation            */
+#   define ARPOP_REQUEST    1       /* Request  to resolve  address */
+#   define ARPOP_REPLY      2       /* Response to previous request */
+
+#   define RARPOP_REQUEST   3       /* Request  to resolve  address */
+#   define RARPOP_REPLY     4       /* Response to previous request */
+
+    /*
+     * The remaining fields are variable in size, according to
+     * the sizes above, and are defined as appropriate for
+     * specific hardware/protocol combinations.
+     */
+    u8      ar_data[0];
+#define ar_sha      ar_data[0]
+#define ar_spa      ar_data[ARP_HLEN]
+#define ar_tha      ar_data[ARP_HLEN + ARP_PLEN]
+#define ar_tpa      ar_data[ARP_HLEN + ARP_PLEN + ARP_HLEN]
+#if 0
+    u8      ar_sha[];   /* Sender hardware address  */
+    u8      ar_spa[];   /* Sender protocol address  */
+    u8      ar_tha[];   /* Target hardware address  */
+    u8      ar_tpa[];   /* Target protocol address  */
+#endif /* 0 */
+};
+
+#define ARP_HDR_SIZE    (8+20)      /* Size assuming ethernet   */
+
+/*
+ * ICMP stuff (just enough to handle (host) redirect messages)
+ */
+#define ICMP_ECHO_REPLY     0   /* Echo reply           */
+#define ICMP_NOT_REACH      3   /* Detination unreachable   */
+#define ICMP_REDIRECT       5   /* Redirect (change route)  */
+#define ICMP_ECHO_REQUEST   8   /* Echo request         */
+
+/* Codes for REDIRECT. */
+#define ICMP_REDIR_NET      0   /* Redirect Net         */
+#define ICMP_REDIR_HOST     1   /* Redirect Host        */
+
+/* Codes for NOT_REACH */
+#define ICMP_NOT_REACH_PORT 3   /* Port unreachable     */
+
+struct icmp_hdr {
+    u8      type;
+    u8      code;
+    u16     checksum;
+    union {
+        struct {
+            u16 id;
+            u16 sequence;
+        } echo;
+        u32 gateway;
+        struct {
+            u16 unused;
+            u16 mtu;
+        } frag;
+        u8 data[0];
+    } un;
+};
+
+#define ICMP_HDR_SIZE       (sizeof(struct icmp_hdr))
+#define IP_ICMP_HDR_SIZE    (IP_HDR_SIZE + ICMP_HDR_SIZE)
+
+/*
+ * Maximum packet size; used to allocate packet storage. Use
+ * the maxium Ethernet frame size as specified by the Ethernet
+ * standard including the 802.1Q tag (VLAN tagging).
+ * maximum packet size =  1522
+ * maximum packet size and multiple of 32 bytes =  1536
+ */
+#define PKTSIZE         1522
+#define PKTSIZE_ALIGN       1536
+
+/*
+ * Maximum receive ring size; that is, the number of packets
+ * we can buffer before overflow happens. Basically, this just
+ * needs to be enough to prevent a packet being discarded while
+ * we are processing the previous one.
+ */
+#define RINGSZ      4
+#define RINGSZ_LOG2 2
+
+/**********************************************************************/
+/*
+ *  Globals.
+ *
+ * Note:
+ *
+ * All variables of type struct in_addr are stored in NETWORK byte order
+ * (big endian).
+ */
+
+/* net.c */
+/** BOOTP EXTENTIONS **/
+extern struct in_addr net_gateway;  /* Our gateway IP address */
+extern struct in_addr net_netmask;  /* Our subnet mask (0 = unknown) */
+/* Our Domain Name Server (0 = unknown) */
+extern struct in_addr net_dns_server;
+#if defined(CONFIG_BOOTP_DNS2)
+/* Our 2nd Domain Name Server (0 = unknown) */
+extern struct in_addr net_dns_server2;
+#endif
+extern char net_nis_domain[32]; /* Our IS domain */
+extern char net_hostname[32];   /* Our hostname */
+extern char net_root_path[64];  /* Our root path */
+/** END OF BOOTP EXTENTIONS **/
+extern u8       net_ethaddr[6];     /* Our ethernet address */
+extern u8       net_server_ethaddr[6];  /* Boot server enet address */
+extern struct in_addr   net_ip;     /* Our    IP addr (0 = unknown) */
+extern struct in_addr   net_server_ip;  /* Server IP addr (0 = unknown) */
+extern uchar        *net_tx_packet;     /* THE transmit packet */
+extern uchar        *net_rx_packets[PKTBUFSRX]; /* Receive packets */
+extern uchar        *net_rx_packet;     /* Current receive packet */
+extern int      net_rx_packet_len;  /* Current rx packet length */
+extern const u8     net_bcast_ethaddr[6];   /* Ethernet broadcast address */
+extern const u8     net_null_ethaddr[6];
+
+#define VLAN_NONE   4095            /* untagged */
+#define VLAN_IDMASK 0x0fff          /* mask of valid vlan id */
+extern ushort       net_our_vlan;       /* Our VLAN */
+extern ushort       net_native_vlan;    /* Our Native VLAN */
+
+extern int      net_restart_wrap;   /* Tried all network devices */
+
+enum proto_t {
+    BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
+    TFTPSRV, TFTPPUT, LINKLOCAL
+};
+
+extern char net_boot_file_name[1024];/* Boot File name */
+/* The actual transferred size of the bootfile (in bytes) */
+extern u32  net_boot_file_size;
+/* Boot file size in blocks as reported by the DHCP server */
+extern u32  net_boot_file_expected_size_in_blocks;
+
+#if defined(CONFIG_CMD_DNS)
+extern char *net_dns_resolve;       /* The host to resolve  */
+extern char *net_dns_env_var;       /* the env var to put the ip into */
+#endif
+
+#if defined(CONFIG_CMD_PING)
+extern struct in_addr net_ping_ip;  /* the ip address to ping */
+#endif
+
+#if defined(CONFIG_CMD_CDP)
+/* when CDP completes these hold the return values */
+extern ushort cdp_native_vlan;      /* CDP returned native VLAN */
+extern ushort cdp_appliance_vlan;   /* CDP returned appliance VLAN */
+
+/*
+ * Check for a CDP packet by examining the received MAC address field
+ */
+static inline int is_cdp_packet(const uchar *ethaddr)
+{
+    extern const u8 net_cdp_ethaddr[6];
+
+    return memcmp(ethaddr, net_cdp_ethaddr, 6) == 0;
+}
+#endif
+
+#if defined(CONFIG_CMD_SNTP)
+extern struct in_addr   net_ntp_server;     /* the ip address to NTP */
+extern int net_ntp_time_offset;         /* offset time from UTC */
+#endif
+
+#if defined(CONFIG_MCAST_TFTP)
+extern struct in_addr net_mcast_addr;
+#endif
+
+/* Initialize the network adapter */
+void net_init(void);
+int net_loop(enum proto_t);
+
+/* Load failed.  Start again. */
+int net_start_again(void);
+
+/* Get size of the ethernet header when we send */
+int net_eth_hdr_size(void);
+
+/* Set ethernet header; returns the size of the header */
+int net_set_ether(uchar *xet, const uchar *dest_ethaddr, uint prot);
+int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot);
+
+/* Set IP header */
+void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source);
+void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport,
+                        int sport, int len);
+
+/**
+ * compute_ip_checksum() - Compute IP checksum
+ *
+ * @addr:   Address to check (must be 16-bit aligned)
+ * @nbytes: Number of bytes to check (normally a multiple of 2)
+ * @return 16-bit IP checksum
+ */
+unsigned compute_ip_checksum(const void *addr, unsigned nbytes);
+
+/**
+ * add_ip_checksums() - add two IP checksums
+ *
+ * @offset: Offset of first sum (if odd we do a byte-swap)
+ * @sum:    First checksum
+ * @new_sum:    New checksum to add
+ * @return updated 16-bit IP checksum
+ */
+unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new_sum);
+
+/**
+ * ip_checksum_ok() - check if a checksum is correct
+ *
+ * This works by making sure the checksum sums to 0
+ *
+ * @addr:   Address to check (must be 16-bit aligned)
+ * @nbytes: Number of bytes to check (normally a multiple of 2)
+ * @return true if the checksum matches, false if not
+ */
+int ip_checksum_ok(const void *addr, unsigned nbytes);
+
+/* Callbacks */
+rxhand_f *net_get_udp_handler(void);    /* Get UDP RX packet handler */
+void net_set_udp_handler(rxhand_f *);   /* Set UDP RX packet handler */
+rxhand_f *net_get_arp_handler(void);    /* Get ARP RX packet handler */
+void net_set_arp_handler(rxhand_f *);   /* Set ARP RX packet handler */
+void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */
+void net_set_timeout_handler(ulong, thand_f *);/* Set timeout handler */
+
+/* Network loop state */
+enum net_loop_state {
+    NETLOOP_CONTINUE,
+    NETLOOP_RESTART,
+    NETLOOP_SUCCESS,
+    NETLOOP_FAIL
+};
+extern enum net_loop_state net_state;
+
+static inline void net_set_state(enum net_loop_state state)
+{
+    net_state = state;
+}
+
+/* Transmit a packet */
+static inline void net_send_packet(uchar *pkt, int len)
+{
+    /* Currently no way to return errors from eth_send() */
+    (void) eth_send(pkt, len);
+}
+
+/*
+ * Transmit "net_tx_packet" as UDP packet, performing ARP request if needed
+ *  (ether will be populated)
+ *
+ * @param ether Raw packet buffer
+ * @param dest IP address to send the datagram to
+ * @param dport Destination UDP port
+ * @param sport Source UDP port
+ * @param payload_len Length of data after the UDP header
+ */
+int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport,
+                        int sport, int payload_len);
+
+/* Processes a received packet */
+void ethif_process_received_packet(uchar *in_packet, int len);
+
+#ifdef CONFIG_NETCONSOLE
+void nc_start(void);
+int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned dest_port,
+                    unsigned src_port, unsigned len);
+#endif
+
+static __always_inline int eth_is_on_demand_init(void)
+{
+#ifdef CONFIG_NETCONSOLE
+    extern enum proto_t net_loop_last_protocol;
+
+    return net_loop_last_protocol != NETCONS;
+#else
+    return 1;
+#endif
+}
+
+static inline void eth_set_last_protocol(int protocol)
+{
+#ifdef CONFIG_NETCONSOLE
+    extern enum proto_t net_loop_last_protocol;
+
+    net_loop_last_protocol = protocol;
+#endif
+}
+
+/*
+ * Check if autoload is enabled. If so, use either NFS or TFTP to download
+ * the boot file.
+ */
+void net_auto_load(void);
+
+/*
+ * The following functions are a bit ugly, but necessary to deal with
+ * alignment restrictions on ARM.
+ *
+ * We're using inline functions, which had the smallest memory
+ * footprint in our tests.
+ */
+/* return IP *in network byteorder* */
+static inline struct in_addr net_read_ip(void *from)
+{
+    struct in_addr ip;
+
+    memcpy((void *)&ip, (void *)from, sizeof(ip));
+    return ip;
+}
+
+/* return ulong *in network byteorder* */
+static inline u32 net_read_u32(u32 *from)
+{
+    u32 l;
+
+    memcpy((void *)&l, (void *)from, sizeof(l));
+    return l;
+}
+
+/* write IP *in network byteorder* */
+static inline void net_write_ip(void *to, struct in_addr ip)
+{
+    memcpy(to, (void *)&ip, sizeof(ip));
+}
+
+/* copy IP */
+static inline void net_copy_ip(void *to, void *from)
+{
+    memcpy((void *)to, from, sizeof(struct in_addr));
+}
+
+/* copy ulong */
+static inline void net_copy_u32(u32 *to, u32 *from)
+{
+    memcpy((void *)to, (void *)from, sizeof(u32));
+}
+
+/**
+ * is_zero_ethaddr - Determine if give Ethernet address is all zeros.
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Return true if the address is all zeroes.
+ */
+static inline int is_zero_ethaddr(const u8 *addr)
+{
+    return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
+}
+
+/**
+ * is_multicast_ethaddr - Determine if the Ethernet address is a multicast.
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Return true if the address is a multicast address.
+ * By definition the broadcast address is also a multicast address.
+ */
+static inline int is_multicast_ethaddr(const u8 *addr)
+{
+    return 0x01 & addr[0];
+}
+
+/*
+ * is_broadcast_ethaddr - Determine if the Ethernet address is broadcast
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Return true if the address is the broadcast address.
+ */
+static inline int is_broadcast_ethaddr(const u8 *addr)
+{
+    return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) ==
+           0xff;
+}
+
+/*
+ * is_valid_ethaddr - Determine if the given Ethernet address is valid
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not
+ * a multicast address, and is not FF:FF:FF:FF:FF:FF.
+ *
+ * Return true if the address is valid.
+ */
+static inline int is_valid_ethaddr(const u8 *addr)
+{
+    /* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to
+     * explicitly check for it here. */
+    return !is_multicast_ethaddr(addr) && !is_zero_ethaddr(addr);
+}
+
+/**
+ * net_random_ethaddr - Generate software assigned random Ethernet address
+ * @addr: Pointer to a six-byte array containing the Ethernet address
+ *
+ * Generate a random Ethernet address (MAC) that is not multicast
+ * and has the local assigned bit set.
+ */
+static inline void net_random_ethaddr(uchar *addr)
+{
+    int i;
+    unsigned int seed = random();
+
+    for (i = 0; i < 6; i++) {
+        addr[i] = rand_r(&seed);
+    }
+
+    addr[0] &= 0xfe;    /* clear multicast bit */
+    addr[0] |= 0x02;    /* set local assignment bit (IEEE802) */
+}
+
+/* Convert an IP address to a string */
+void ip_to_string(struct in_addr x, char *s);
+
+/* Convert a string to ip address */
+struct in_addr string_to_ip(const char *s);
+
+/* Convert a VLAN id to a string */
+void vlan_to_string(ushort x, char *s);
+
+/* Convert a string to a vlan id */
+ushort string_to_vlan(const char *s);
+
+/* read a VLAN id from an environment variable */
+ushort getenv_vlan(char *);
+
+/* copy a filename (allow for "..." notation, limit length) */
+void copy_filename(char *dst, const char *src, int size);
+
+/* get a random source port */
+unsigned int random_port(void);
+
+/**
+ * update_tftp - Update firmware over TFTP (via DFU)
+ *
+ * This function updates board's firmware via TFTP
+ *
+ * @param addr - memory address where data is stored
+ * @param interface - the DFU medium name - e.g. "mmc"
+ * @param devstring - the DFU medium number - e.g. "1"
+ *
+ * @return - 0 on success, other value on failure
+ */
+int update_tftp(ulong addr, char *interface, char *devstring);
+
+/**********************************************************************/
diff --git a/libethdrivers/src/plat/odroidc2/uboot/netdev.h b/libethdrivers/src/plat/odroidc2/uboot/netdev.h
new file mode 100644
index 0000000..24583cb
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/netdev.h
@@ -0,0 +1,225 @@
+/*
+ * (C) Copyright 2008
+ * Benjamin Warren, biggerbadderben@gmail.com
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/*
+ * netdev.h - definitions an prototypes for network devices
+ */
+
+#pragma once
+
+#include "net.h"
+
+/*
+ * Board and CPU-specific initialization functions
+ * board_eth_init() has highest priority.  cpu_eth_init() only
+ * gets called if board_eth_init() isn't instantiated or fails.
+ * Return values:
+ *      0: success
+ *     -1: failure
+ */
+
+int board_eth_init(void);
+int cpu_eth_init(void);
+
+/* Driver initialization prototypes */
+int at91emac_register(bd_t *bis, unsigned long iobase);
+int au1x00_enet_initialize(bd_t *);
+int ax88180_initialize(bd_t *bis);
+int bcm_sf2_eth_register(bd_t *bis, u8 dev_num);
+int bfin_EMAC_initialize(bd_t *bis);
+int calxedaxgmac_initialize(u32 id, ulong base_addr);
+int cs8900_initialize(u8 dev_num, int base_addr);
+int davinci_emac_initialize(void);
+int dc21x4x_initialize(bd_t *bis);
+int designware_read_hwaddr(struct eth_device *dev, u8 *mac_out);
+int designware_initialize(ulong base_addr, u32 interface, struct eth_device *dev);
+int designware_startup(struct eth_device *dev);
+int designware_enable(struct eth_device *dev);
+int designware_write_descriptors(struct eth_device *dev, uintptr_t tx_ring_base, uintptr_t rx_ring_base);
+int designware_ack(struct eth_device *dev, u32 status);
+int designware_interrupt_status(struct eth_device *dev, uint32_t *ret_status);
+int designware_start_send(struct eth_device *dev);
+int designware_start_receive(struct eth_device *dev);
+int dm9000_initialize(bd_t *bis);
+int dnet_eth_initialize(int id, void *regs, unsigned int phy_addr);
+int e1000_initialize(bd_t *bis);
+int eepro100_initialize(bd_t *bis);
+int enc28j60_initialize(unsigned int bus, unsigned int cs,
+                        unsigned int max_hz, unsigned int mode);
+int ep93xx_eth_initialize(u8 dev_num, int base_addr);
+int eth_3com_initialize(bd_t *bis);
+int ethoc_initialize(u8 dev_num, int base_addr);
+int fec_initialize(bd_t *bis);
+int fecmxc_initialize(bd_t *bis);
+int fecmxc_initialize_multi(bd_t *bis, int dev_id, int phy_id, uint32_t addr);
+int ftgmac100_initialize(bd_t *bits);
+int ftmac100_initialize(bd_t *bits);
+int ftmac110_initialize(bd_t *bits);
+int greth_initialize(bd_t *bis);
+void gt6426x_eth_initialize(bd_t *bis);
+int ks8851_mll_initialize(u8 dev_num, int base_addr);
+int lan91c96_initialize(u8 dev_num, int base_addr);
+int lpc32xx_eth_initialize(bd_t *bis);
+int macb_eth_initialize(int id, void *regs, unsigned int phy_addr);
+int mcdmafec_initialize(bd_t *bis);
+int mcffec_initialize(bd_t *bis);
+int mpc512x_fec_initialize(bd_t *bis);
+int mpc5xxx_fec_initialize(bd_t *bis);
+int mpc82xx_scc_enet_initialize(bd_t *bis);
+int mvgbe_initialize(bd_t *bis);
+int mvneta_initialize(bd_t *bis, int base_addr, int devnum, int phy_addr);
+int natsemi_initialize(bd_t *bis);
+int ne2k_register(void);
+int npe_initialize(bd_t *bis);
+int ns8382x_initialize(bd_t *bis);
+int pcnet_initialize(bd_t *bis);
+int ppc_4xx_eth_initialize(bd_t *bis);
+int rtl8139_initialize(bd_t *bis);
+int rtl8169_initialize(bd_t *bis);
+int scc_initialize(bd_t *bis);
+int sh_eth_initialize(bd_t *bis);
+int skge_initialize(bd_t *bis);
+int smc91111_initialize(u8 dev_num, int base_addr);
+int smc911x_initialize(u8 dev_num, int base_addr);
+int tsi108_eth_initialize(bd_t *bis);
+int uec_standard_init(bd_t *bis);
+int uli526x_initialize(bd_t *bis);
+int armada100_fec_register(unsigned long base_addr);
+int xilinx_axiemac_initialize(bd_t *bis, unsigned long base_addr,
+                              unsigned long dma_addr);
+int xilinx_emaclite_of_init(const void *blob);
+int xilinx_emaclite_initialize(bd_t *bis, unsigned long base_addr,
+                               int txpp, int rxpp);
+int xilinx_ll_temac_eth_init(bd_t *bis, unsigned long base_addr, int flags,
+                             unsigned long ctrl_addr);
+int zynq_gem_of_init(const void *blob);
+int zynq_gem_initialize(phys_addr_t base_addr,
+                        int phy_addr, u32 emio);
+void zynq_gem_handle_irq(int irq);
+void zynq_set_gem_iobase(unsigned int base_addr);
+
+/*
+ * As long as the Xilinx xps_ll_temac ethernet driver has not its own interface
+ * exported by a public hader file, we need a global definition at this point.
+ */
+#if defined(CONFIG_XILINX_LL_TEMAC)
+#define XILINX_LL_TEMAC_M_FIFO      0   /* use FIFO Ctrl */
+#define XILINX_LL_TEMAC_M_SDMA_PLB  (1 << 0)/* use SDMA Ctrl via PLB */
+#define XILINX_LL_TEMAC_M_SDMA_DCR  (1 << 1)/* use SDMA Ctrl via DCR */
+#endif
+
+/* Boards with PCI network controllers can call this from their board_eth_init()
+ * function to initialize whatever's on board.
+ * Return value is total # of devices found */
+
+static inline int pci_eth_init(bd_t *bis)
+{
+    int num = 0;
+
+#ifdef CONFIG_PCI
+
+#ifdef CONFIG_EEPRO100
+    num += eepro100_initialize(bis);
+#endif
+#ifdef CONFIG_TULIP
+    num += dc21x4x_initialize(bis);
+#endif
+#ifdef CONFIG_E1000
+    num += e1000_initialize(bis);
+#endif
+#ifdef CONFIG_PCNET
+    num += pcnet_initialize(bis);
+#endif
+#ifdef CONFIG_NATSEMI
+    num += natsemi_initialize(bis);
+#endif
+#ifdef CONFIG_NS8382X
+    num += ns8382x_initialize(bis);
+#endif
+#if defined(CONFIG_RTL8139)
+    num += rtl8139_initialize(bis);
+#endif
+#if defined(CONFIG_RTL8169)
+    num += rtl8169_initialize(bis);
+#endif
+#if defined(CONFIG_ULI526X)
+    num += uli526x_initialize(bis);
+#endif
+
+#endif  /* CONFIG_PCI */
+    return num;
+}
+
+/*
+ * Boards with mv88e61xx switch can use this by defining
+ * CONFIG_MV88E61XX_SWITCH in respective board configheader file
+ * the stuct and enums here are used to specify switch configuration params
+ */
+#if defined(CONFIG_MV88E61XX_SWITCH)
+
+/* constants for any 88E61xx switch */
+#define MV88E61XX_MAX_PORTS_NUM 6
+
+enum mv88e61xx_cfg_mdip {
+    MV88E61XX_MDIP_NOCHANGE,
+    MV88E61XX_MDIP_REVERSE
+};
+
+enum mv88e61xx_cfg_ledinit {
+    MV88E61XX_LED_INIT_DIS,
+    MV88E61XX_LED_INIT_EN
+};
+
+enum mv88e61xx_cfg_rgmiid {
+    MV88E61XX_RGMII_DELAY_DIS,
+    MV88E61XX_RGMII_DELAY_EN
+};
+
+enum mv88e61xx_cfg_prtstt {
+    MV88E61XX_PORTSTT_DISABLED,
+    MV88E61XX_PORTSTT_BLOCKING,
+    MV88E61XX_PORTSTT_LEARNING,
+    MV88E61XX_PORTSTT_FORWARDING
+};
+
+struct mv88e61xx_config {
+    char *name;
+    u8 vlancfg[MV88E61XX_MAX_PORTS_NUM];
+    enum mv88e61xx_cfg_rgmiid rgmii_delay;
+    enum mv88e61xx_cfg_prtstt portstate;
+    enum mv88e61xx_cfg_ledinit led_init;
+    enum mv88e61xx_cfg_mdip mdip;
+    u32 ports_enabled;
+    u8 cpuport;
+};
+
+/*
+ * Common mappings for Internal VLANs
+ * These mappings consider that all ports are useable; the driver
+ * will mask inexistent/unused ports.
+ */
+
+/* Switch mode : routes any port to any port */
+#define MV88E61XX_VLANCFG_SWITCH { 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F }
+
+/* Router mode: routes only CPU port 5 to/from non-CPU ports 0-4 */
+#define MV88E61XX_VLANCFG_ROUTER { 0x20, 0x20, 0x20, 0x20, 0x20, 0x1F }
+
+int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig);
+#endif /* CONFIG_MV88E61XX_SWITCH */
+
+struct mii_dev *fec_get_miibus(uint32_t base_addr, int dev_id);
+#ifdef CONFIG_PHYLIB
+struct phy_device;
+int fec_probe(bd_t *bd, int dev_id, uint32_t base_addr,
+              struct mii_dev *bus, struct phy_device *phydev);
+#else
+/*
+ * Allow FEC to fine-tune MII configuration on boards which require this.
+ */
+int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int));
+#endif
diff --git a/libethdrivers/src/plat/odroidc2/uboot/phy.c b/libethdrivers/src/plat/odroidc2/uboot/phy.c
new file mode 100644
index 0000000..ded48e6
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/phy.c
@@ -0,0 +1,966 @@
+/*
+ * Generic PHY Management code
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ * author Andy Fleming
+ *
+ * Based loosely off of Linux's PHY Lib
+ */
+
+#include <stdlib.h>
+#include "config.h"
+#include "common.h"
+#include "net.h"
+// #include "dm.h"
+#include "miiphy.h"
+#include "phy.h"
+#include "err.h"
+#include <errno.h>
+#include "bitops.h"
+#include "../unimplemented.h"
+#include "string.h"
+
+/* Generic PHY support and helper functions */
+
+/**
+ * genphy_config_advert - sanitize and advertise auto-negotation parameters
+ * @phydev: target phy_device struct
+ *
+ * Description: Writes MII_ADVERTISE with the appropriate values,
+ *   after sanitizing the values to make sure we only advertise
+ *   what is supported.  Returns < 0 on error, 0 if the PHY's advertisement
+ *   hasn't changed, and > 0 if it has changed.
+ */
+static int genphy_config_advert(struct phy_device *phydev)
+{
+    u32 advertise;
+    int oldadv, adv, bmsr;
+    int err, changed = 0;
+
+    /* Only allow advertising what this PHY supports */
+    phydev->advertising &= phydev->supported;
+    advertise = phydev->advertising;
+
+    /* Setup standard advertisement */
+    adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
+    oldadv = adv;
+
+    if (adv < 0) {
+        return adv;
+    }
+
+    adv &= ~(ADVERTISE_ALL | ADVERTISE_100BASE4 | ADVERTISE_PAUSE_CAP |
+             ADVERTISE_PAUSE_ASYM);
+    if (advertise & ADVERTISED_10baseT_Half) {
+        adv |= ADVERTISE_10HALF;
+    }
+    if (advertise & ADVERTISED_10baseT_Full) {
+        adv |= ADVERTISE_10FULL;
+    }
+    if (advertise & ADVERTISED_100baseT_Half) {
+        adv |= ADVERTISE_100HALF;
+    }
+    if (advertise & ADVERTISED_100baseT_Full) {
+        adv |= ADVERTISE_100FULL;
+    }
+    if (advertise & ADVERTISED_Pause) {
+        adv |= ADVERTISE_PAUSE_CAP;
+    }
+    if (advertise & ADVERTISED_Asym_Pause) {
+        adv |= ADVERTISE_PAUSE_ASYM;
+    }
+    if (advertise & ADVERTISED_1000baseX_Half) {
+        adv |= ADVERTISE_1000XHALF;
+    }
+    if (advertise & ADVERTISED_1000baseX_Full) {
+        adv |= ADVERTISE_1000XFULL;
+    }
+
+    if (adv != oldadv) {
+        err = phy_write(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE, adv);
+
+        if (err < 0) {
+            return err;
+        }
+        changed = 1;
+    }
+
+    bmsr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+    if (bmsr < 0) {
+        return bmsr;
+    }
+
+    /* Per 802.3-2008, Section 22.2.4.2.16 Extended status all
+     * 1000Mbits/sec capable PHYs shall have the BMSR_ESTATEN bit set to a
+     * logical 1.
+     */
+    if (!(bmsr & BMSR_ESTATEN)) {
+        return changed;
+    }
+
+    /* Configure gigabit if it's supported */
+    adv = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
+    oldadv = adv;
+
+    if (adv < 0) {
+        return adv;
+    }
+
+    adv &= ~(ADVERTISE_1000FULL | ADVERTISE_1000HALF);
+
+    if (phydev->supported & (SUPPORTED_1000baseT_Half |
+                             SUPPORTED_1000baseT_Full)) {
+        if (advertise & SUPPORTED_1000baseT_Half) {
+            adv |= ADVERTISE_1000HALF;
+        }
+        if (advertise & SUPPORTED_1000baseT_Full) {
+            adv |= ADVERTISE_1000FULL;
+        }
+    }
+
+    if (adv != oldadv) {
+        changed = 1;
+    }
+
+    err = phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, adv);
+    if (err < 0) {
+        return err;
+    }
+
+    return changed;
+}
+
+
+/**
+ * genphy_setup_forced - configures/forces speed/duplex from @phydev
+ * @phydev: target phy_device struct
+ *
+ * Description: Configures MII_BMCR to force speed/duplex
+ *   to the values in phydev. Assumes that the values are valid.
+ */
+static int genphy_setup_forced(struct phy_device *phydev)
+{
+    int err;
+    int ctl = BMCR_ANRESTART;
+
+    phydev->pause = phydev->asym_pause = 0;
+
+    if (SPEED_1000 == phydev->speed) {
+        ctl |= BMCR_SPEED1000;
+    } else if (SPEED_100 == phydev->speed) {
+        ctl |= BMCR_SPEED100;
+    }
+
+    if (DUPLEX_FULL == phydev->duplex) {
+        ctl |= BMCR_FULLDPLX;
+    }
+
+    err = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
+
+    return err;
+}
+
+
+/**
+ * genphy_restart_aneg - Enable and Restart Autonegotiation
+ * @phydev: target phy_device struct
+ */
+int genphy_restart_aneg(struct phy_device *phydev)
+{
+    int ctl;
+
+    ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+
+    if (ctl < 0) {
+        return ctl;
+    }
+
+    ctl |= (BMCR_ANENABLE | BMCR_ANRESTART);
+
+    /* Don't isolate the PHY if we're negotiating */
+    ctl &= ~(BMCR_ISOLATE);
+
+    ctl = phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, ctl);
+
+    return ctl;
+}
+
+
+/**
+ * genphy_config_aneg - restart auto-negotiation or write BMCR
+ * @phydev: target phy_device struct
+ *
+ * Description: If auto-negotiation is enabled, we configure the
+ *   advertising, and then restart auto-negotiation.  If it is not
+ *   enabled, then we write the BMCR.
+ */
+int genphy_config_aneg(struct phy_device *phydev)
+{
+    int result;
+
+    if (AUTONEG_ENABLE != phydev->autoneg) {
+        return genphy_setup_forced(phydev);
+    }
+
+    result = genphy_config_advert(phydev);
+
+    if (result < 0) { /* error */
+        return result;
+    }
+
+    if (result == 0) {
+        /* Advertisment hasn't changed, but maybe aneg was never on to
+         * begin with?  Or maybe phy was isolated? */
+        int ctl = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+
+        if (ctl < 0) {
+            return ctl;
+        }
+
+        if (!(ctl & BMCR_ANENABLE) || (ctl & BMCR_ISOLATE)) {
+            result = 1;    /* do restart aneg */
+        }
+    }
+
+    /* Only restart aneg if we are advertising something different
+     * than we were before.  */
+    if (result > 0) {
+        result = genphy_restart_aneg(phydev);
+    }
+
+    return result;
+}
+
+/**
+ * genphy_update_link - update link status in @phydev
+ * @phydev: target phy_device struct
+ *
+ * Description: Update the value in phydev->link to reflect the
+ *   current link value.  In order to do this, we need to read
+ *   the status register twice, keeping the second value.
+ */
+int genphy_update_link(struct phy_device *phydev)
+{
+    unsigned int mii_reg;
+
+    /*
+     * Wait if the link is up, and autonegotiation is in progress
+     * (ie - we're capable and it's not done)
+     */
+    mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+
+    /*
+     * If we already saw the link up, and it hasn't gone down, then
+     * we don't need to wait for autoneg again
+     */
+    if (phydev->link && mii_reg & BMSR_LSTATUS) {
+        return 0;
+    }
+
+    if ((phydev->autoneg == AUTONEG_ENABLE) &&
+        !(mii_reg & BMSR_ANEGCOMPLETE)) {
+        int i = 0;
+
+        printf("%s Waiting for PHY auto negotiation to complete", phydev->dev->name);
+        fflush(stdout);
+        while (!(mii_reg & BMSR_ANEGCOMPLETE)) {
+            /*
+             * Timeout reached ?
+             */
+            if (i > PHY_ANEG_TIMEOUT) {
+                printf(" TIMEOUT !\n");
+                phydev->link = 0;
+                return -ETIMEDOUT;
+            }
+
+            if ((i++ % 500) == 0) {
+                printf(".");
+            }
+
+            uboot_udelay(1000); /* 1 ms */
+            mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+        }
+        printf(" done\n");
+        phydev->link = 1;
+    } else {
+        /* Read the link a second time to clear the latched state */
+        mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+
+        if (mii_reg & BMSR_LSTATUS) {
+            phydev->link = 1;
+        } else {
+            phydev->link = 0;
+        }
+    }
+
+    return 0;
+}
+
+/*
+ * Generic function which updates the speed and duplex.  If
+ * autonegotiation is enabled, it uses the AND of the link
+ * partner's advertised capabilities and our advertised
+ * capabilities.  If autonegotiation is disabled, we use the
+ * appropriate bits in the control register.
+ *
+ * Stolen from Linux's mii.c and phy_device.c
+ */
+int genphy_parse_link(struct phy_device *phydev)
+{
+    int mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+
+    /* We're using autonegotiation */
+    if (phydev->autoneg == AUTONEG_ENABLE) {
+        u32 lpa = 0;
+        int gblpa = 0;
+        u32 estatus = 0;
+
+        /* Check for gigabit capability */
+        if (phydev->supported & (SUPPORTED_1000baseT_Full |
+                                 SUPPORTED_1000baseT_Half)) {
+            /* We want a list of states supported by
+             * both PHYs in the link
+             */
+            gblpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_STAT1000);
+            if (gblpa < 0) {
+                debug("Could not read MII_STAT1000. Ignoring gigabit capability\n");
+                gblpa = 0;
+            }
+            gblpa &= phy_read(phydev,
+                              MDIO_DEVAD_NONE, MII_CTRL1000) << 2;
+        }
+
+        /* Set the baseline so we only have to set them
+         * if they're different
+         */
+        phydev->speed = SPEED_10;
+        phydev->duplex = DUPLEX_HALF;
+
+        /* Check the gigabit fields */
+        if (gblpa & (PHY_1000BTSR_1000FD | PHY_1000BTSR_1000HD)) {
+            phydev->speed = SPEED_1000;
+
+            if (gblpa & PHY_1000BTSR_1000FD) {
+                phydev->duplex = DUPLEX_FULL;
+            }
+
+            /* We're done! */
+            return 0;
+        }
+
+        lpa = phy_read(phydev, MDIO_DEVAD_NONE, MII_ADVERTISE);
+        lpa &= phy_read(phydev, MDIO_DEVAD_NONE, MII_LPA);
+
+        if (lpa & (LPA_100FULL | LPA_100HALF)) {
+            phydev->speed = SPEED_100;
+
+            if (lpa & LPA_100FULL) {
+                phydev->duplex = DUPLEX_FULL;
+            }
+
+        } else if (lpa & LPA_10FULL) {
+            phydev->duplex = DUPLEX_FULL;
+        }
+
+        /*
+         * Extended status may indicate that the PHY supports
+         * 1000BASE-T/X even though the 1000BASE-T registers
+         * are missing. In this case we can't tell whether the
+         * peer also supports it, so we only check extended
+         * status if the 1000BASE-T registers are actually
+         * missing.
+         */
+        if ((mii_reg & BMSR_ESTATEN) && !(mii_reg & BMSR_ERCAP))
+            estatus = phy_read(phydev, MDIO_DEVAD_NONE,
+                               MII_ESTATUS);
+
+        if (estatus & (ESTATUS_1000_XFULL | ESTATUS_1000_XHALF |
+                       ESTATUS_1000_TFULL | ESTATUS_1000_THALF)) {
+            phydev->speed = SPEED_1000;
+            if (estatus & (ESTATUS_1000_XFULL | ESTATUS_1000_TFULL)) {
+                phydev->duplex = DUPLEX_FULL;
+            }
+        }
+
+    } else {
+        u32 bmcr = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMCR);
+
+        phydev->speed = SPEED_10;
+        phydev->duplex = DUPLEX_HALF;
+
+        if (bmcr & BMCR_FULLDPLX) {
+            phydev->duplex = DUPLEX_FULL;
+        }
+
+        if (bmcr & BMCR_SPEED1000) {
+            phydev->speed = SPEED_1000;
+        } else if (bmcr & BMCR_SPEED100) {
+            phydev->speed = SPEED_100;
+        }
+    }
+
+    return 0;
+}
+
+int genphy_config(struct phy_device *phydev)
+{
+    int val;
+    u32 features;
+
+    features = (SUPPORTED_TP | SUPPORTED_MII
+                | SUPPORTED_AUI | SUPPORTED_FIBRE |
+                SUPPORTED_BNC);
+
+    /* Do we support autonegotiation? */
+    val = phy_read(phydev, MDIO_DEVAD_NONE, MII_BMSR);
+
+    if (val < 0) {
+        return val;
+    }
+
+    if (val & BMSR_ANEGCAPABLE) {
+        features |= SUPPORTED_Autoneg;
+    }
+
+    if (val & BMSR_100FULL) {
+        features |= SUPPORTED_100baseT_Full;
+    }
+    if (val & BMSR_100HALF) {
+        features |= SUPPORTED_100baseT_Half;
+    }
+    if (val & BMSR_10FULL) {
+        features |= SUPPORTED_10baseT_Full;
+    }
+    if (val & BMSR_10HALF) {
+        features |= SUPPORTED_10baseT_Half;
+    }
+
+    if (val & BMSR_ESTATEN) {
+        val = phy_read(phydev, MDIO_DEVAD_NONE, MII_ESTATUS);
+
+        if (val < 0) {
+            return val;
+        }
+
+        if (val & ESTATUS_1000_TFULL) {
+            features |= SUPPORTED_1000baseT_Full;
+        }
+        if (val & ESTATUS_1000_THALF) {
+            features |= SUPPORTED_1000baseT_Half;
+        }
+        if (val & ESTATUS_1000_XFULL) {
+            features |= SUPPORTED_1000baseX_Full;
+        }
+        if (val & ESTATUS_1000_XHALF) {
+            features |= SUPPORTED_1000baseX_Half;
+        }
+    }
+
+    phydev->supported &= features;
+    phydev->advertising &= features;
+
+    genphy_config_aneg(phydev);
+
+    return 0;
+}
+
+int genphy_startup(struct phy_device *phydev)
+{
+    int ret;
+
+    ret = genphy_update_link(phydev);
+    if (ret) {
+        return ret;
+    }
+
+    return genphy_parse_link(phydev);
+}
+
+int genphy_shutdown(struct phy_device *phydev)
+{
+    return 0;
+}
+
+static struct phy_driver genphy_driver = {
+    .uid        = 0xffffffff,
+    .mask       = 0xffffffff,
+    .name       = "Generic PHY",
+    .features   = PHY_GBIT_FEATURES | SUPPORTED_MII |
+    SUPPORTED_AUI | SUPPORTED_FIBRE |
+    SUPPORTED_BNC,
+    .config     = genphy_config,
+    .startup    = genphy_startup,
+    .shutdown   = genphy_shutdown,
+};
+
+static LIST_HEAD(phy_drivers);
+
+int phy_init(void)
+{
+#ifdef CONFIG_MV88E61XX_SWITCH
+    phy_mv88e61xx_init();
+#endif
+#ifdef CONFIG_PHY_AQUANTIA
+    phy_aquantia_init();
+#endif
+#ifdef CONFIG_PHY_ATHEROS
+    phy_atheros_init();
+#endif
+#ifdef CONFIG_PHY_BROADCOM
+    phy_broadcom_init();
+#endif
+#ifdef CONFIG_PHY_CORTINA
+    phy_cortina_init();
+#endif
+#ifdef CONFIG_PHY_DAVICOM
+    phy_davicom_init();
+#endif
+#ifdef CONFIG_PHY_ET1011C
+    phy_et1011c_init();
+#endif
+#ifdef CONFIG_PHY_LXT
+    phy_lxt_init();
+#endif
+#ifdef CONFIG_PHY_MARVELL
+    phy_marvell_init();
+#endif
+#ifdef CONFIG_PHY_MICREL
+    phy_micrel_init();
+#endif
+#ifdef CONFIG_PHY_NATSEMI
+    phy_natsemi_init();
+#endif
+#ifdef CONFIG_PHY_REALTEK
+    phy_realtek_init();
+#endif
+#ifdef CONFIG_PHY_SMSC
+    phy_smsc_init();
+#endif
+#ifdef CONFIG_PHY_TERANETICS
+    phy_teranetics_init();
+#endif
+#ifdef CONFIG_PHY_TI
+    phy_ti_init();
+#endif
+#ifdef CONFIG_PHY_VITESSE
+    phy_vitesse_init();
+#endif
+#ifdef CONFIG_PHY_XILINX
+    phy_xilinx_init();
+#endif
+
+    return 0;
+}
+
+int phy_register(struct phy_driver *drv)
+{
+    INIT_LIST_HEAD(&drv->list);
+    list_add_tail(&drv->list, &phy_drivers);
+
+#ifdef CONFIG_NEEDS_MANUAL_RELOC
+    if (drv->probe) {
+        drv->probe += gd->reloc_off;
+    }
+    if (drv->config) {
+        drv->config += gd->reloc_off;
+    }
+    if (drv->startup) {
+        drv->startup += gd->reloc_off;
+    }
+    if (drv->shutdown) {
+        drv->shutdown += gd->reloc_off;
+    }
+    if (drv->readext) {
+        drv->readext += gd->reloc_off;
+    }
+    if (drv->writeext) {
+        drv->writeext += gd->reloc_off;
+    }
+#endif
+    return 0;
+}
+
+int phy_set_supported(struct phy_device *phydev, u32 max_speed)
+{
+    /* The default values for phydev->supported are provided by the PHY
+     * driver "features" member, we want to reset to sane defaults first
+     * before supporting higher speeds.
+     */
+    phydev->supported &= PHY_DEFAULT_FEATURES;
+
+    switch (max_speed) {
+    default:
+        return -ENOTSUPP;
+    case SPEED_1000:
+        phydev->supported |= PHY_1000BT_FEATURES;
+    /* fall through */
+    case SPEED_100:
+        phydev->supported |= PHY_100BT_FEATURES;
+    /* fall through */
+    case SPEED_10:
+        phydev->supported |= PHY_10BT_FEATURES;
+    }
+
+    return 0;
+}
+
+static int phy_probe(struct phy_device *phydev)
+{
+    int err = 0;
+
+    phydev->advertising = phydev->supported = phydev->drv->features;
+    phydev->mmds = phydev->drv->mmds;
+
+    if (phydev->drv->probe) {
+        err = phydev->drv->probe(phydev);
+    }
+
+    return err;
+}
+
+static struct phy_driver *generic_for_interface(phy_interface_t interface)
+{
+#ifdef CONFIG_PHYLIB_10G
+    if (is_10g_interface(interface)) {
+        return &gen10g_driver;
+    }
+#endif
+
+    return &genphy_driver;
+}
+
+static struct phy_driver *get_phy_driver(struct phy_device *phydev,
+                                         phy_interface_t interface)
+{
+    struct list_head *entry;
+    int phy_id = phydev->phy_id;
+    struct phy_driver *drv = NULL;
+
+    list_for_each(entry, &phy_drivers) {
+        drv = list_entry(entry, struct phy_driver, list);
+        if ((drv->uid & drv->mask) == (phy_id & drv->mask)) {
+            return drv;
+        }
+    }
+
+    /* If we made it here, there's no driver for this PHY */
+    return generic_for_interface(interface);
+}
+
+static struct phy_device *phy_device_create(struct mii_dev *bus, int addr,
+                                            u32 phy_id,
+                                            phy_interface_t interface)
+{
+    struct phy_device *dev;
+
+    /* We allocate the device, and initialize the
+     * default values */
+    dev = malloc(sizeof(*dev));
+    if (!dev) {
+        printf("Failed to allocate PHY device for %s:%d\n",
+               bus->name, addr);
+        return NULL;
+    }
+
+    memset(dev, 0, sizeof(*dev));
+
+    dev->duplex = -1;
+    dev->link = 0;
+    dev->interface = interface;
+
+    dev->autoneg = AUTONEG_ENABLE;
+
+    dev->addr = addr;
+    dev->phy_id = phy_id;
+    dev->bus = bus;
+
+    dev->drv = get_phy_driver(dev, interface);
+
+    phy_probe(dev);
+
+    bus->phymap[addr] = dev;
+
+    return dev;
+}
+
+/**
+ * get_phy_id - reads the specified addr for its ID.
+ * @bus: the target MII bus
+ * @addr: PHY address on the MII bus
+ * @phy_id: where to store the ID retrieved.
+ *
+ * Description: Reads the ID registers of the PHY at @addr on the
+ *   @bus, stores it in @phy_id and returns zero on success.
+ */
+int __weak get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id)
+{
+    int phy_reg;
+
+    /* Grab the bits from PHYIR1, and put them
+     * in the upper half */
+    phy_reg = bus->read(bus, addr, devad, MII_PHYSID1);
+
+    if (phy_reg < 0) {
+        return -EIO;
+    }
+
+    *phy_id = (phy_reg & 0xffff) << 16;
+
+    /* Grab the bits from PHYIR2, and put them in the lower half */
+    phy_reg = bus->read(bus, addr, devad, MII_PHYSID2);
+
+    if (phy_reg < 0) {
+        return -EIO;
+    }
+
+    *phy_id |= (phy_reg & 0xffff);
+
+    return 0;
+}
+
+static struct phy_device *create_phy_by_mask(struct mii_dev *bus,
+                                             unsigned phy_mask, int devad, phy_interface_t interface)
+{
+    u32 phy_id = 0xffffffff;
+    while (phy_mask) {
+        int addr = ffs(phy_mask) - 1;
+        int r = get_phy_id(bus, addr, devad, &phy_id);
+        /* If the PHY ID is mostly f's, we didn't find anything */
+        if (r == 0 && (phy_id & 0x1fffffff) != 0x1fffffff) {
+            return phy_device_create(bus, addr, phy_id, interface);
+        }
+        phy_mask &= ~(1 << addr);
+    }
+    return NULL;
+}
+
+static struct phy_device *search_for_existing_phy(struct mii_dev *bus,
+                                                  unsigned phy_mask, phy_interface_t interface)
+{
+    /* If we have one, return the existing device, with new interface */
+    while (phy_mask) {
+        int addr = ffs(phy_mask) - 1;
+        if (bus->phymap[addr]) {
+            bus->phymap[addr]->interface = interface;
+            return bus->phymap[addr];
+        }
+        phy_mask &= ~(1 << addr);
+    }
+    return NULL;
+}
+
+static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
+                                                 unsigned phy_mask, phy_interface_t interface)
+{
+    int i;
+    struct phy_device *phydev;
+
+    phydev = search_for_existing_phy(bus, phy_mask, interface);
+    if (phydev) {
+        return phydev;
+    }
+    /* Try Standard (ie Clause 22) access */
+    /* Otherwise we have to try Clause 45 */
+    for (i = 0; i < 5; i++) {
+        phydev = create_phy_by_mask(bus, phy_mask,
+                                    i ? i : MDIO_DEVAD_NONE, interface);
+        if (IS_ERR(phydev)) {
+            return NULL;
+        }
+        if (phydev) {
+            return phydev;
+        }
+    }
+
+    debug("\n%s PHY: ", bus->name);
+    while (phy_mask) {
+        int addr = ffs(phy_mask) - 1;
+        debug("%d ", addr);
+        phy_mask &= ~(1 << addr);
+    }
+    debug("not found\n");
+
+    return NULL;
+}
+
+/**
+ * get_phy_device - reads the specified PHY device and returns its @phy_device struct
+ * @bus: the target MII bus
+ * @addr: PHY address on the MII bus
+ *
+ * Description: Reads the ID registers of the PHY at @addr on the
+ *   @bus, then allocates and returns the phy_device to represent it.
+ */
+static struct phy_device *get_phy_device(struct mii_dev *bus, int addr,
+                                         phy_interface_t interface)
+{
+    return get_phy_device_by_mask(bus, 1 << addr, interface);
+}
+
+int phy_reset(struct phy_device *phydev)
+{
+    int reg;
+    int timeout = 500;
+    int devad = MDIO_DEVAD_NONE;
+
+    if (phydev->flags & PHY_FLAG_BROKEN_RESET) {
+        return 0;
+    }
+
+#ifdef CONFIG_PHYLIB_10G
+    /* If it's 10G, we need to issue reset through one of the MMDs */
+    if (is_10g_interface(phydev->interface)) {
+        if (!phydev->mmds) {
+            gen10g_discover_mmds(phydev);
+        }
+
+        devad = ffs(phydev->mmds) - 1;
+    }
+#endif
+
+    if (phy_write(phydev, devad, MII_BMCR, BMCR_RESET) < 0) {
+        debug("PHY reset failed\n");
+        return -1;
+    }
+
+#ifdef CONFIG_PHY_RESET_DELAY
+    uboot_udelay(CONFIG_PHY_RESET_DELAY);   /* Intel LXT971A needs this */
+#endif
+    /*
+     * Poll the control register for the reset bit to go to 0 (it is
+     * auto-clearing).  This should happen within 0.5 seconds per the
+     * IEEE spec.
+     */
+    reg = phy_read(phydev, devad, MII_BMCR);
+    while ((reg & BMCR_RESET) && timeout--) {
+        reg = phy_read(phydev, devad, MII_BMCR);
+
+        if (reg < 0) {
+            debug("PHY status read failed\n");
+            return -1;
+        }
+        uboot_udelay(1000);
+    }
+
+    if (reg & BMCR_RESET) {
+        puts("PHY reset timed out\n");
+        return -1;
+    }
+
+    return 0;
+}
+
+int miiphy_reset(const char *devname, unsigned char addr)
+{
+    struct mii_dev *bus = miiphy_get_dev_by_name(devname);
+    struct phy_device *phydev;
+
+    /*
+     * miiphy_reset was only used on standard PHYs, so we'll fake it here.
+     * If later code tries to connect with the right interface, this will
+     * be corrected by get_phy_device in phy_connect()
+     */
+    phydev = get_phy_device(bus, addr, PHY_INTERFACE_MODE_MII);
+
+    return phy_reset(phydev);
+}
+
+struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
+                                    phy_interface_t interface)
+{
+    /* Reset the bus */
+    if (bus->reset) {
+        bus->reset(bus);
+
+        /* Wait 15ms to make sure the PHY has come out of hard reset */
+        uboot_udelay(15000);
+    }
+
+    return get_phy_device_by_mask(bus, phy_mask, interface);
+}
+
+#ifdef CONFIG_DM_ETH
+void phy_connect_dev(struct phy_device *phydev, struct udevice *dev)
+#else
+void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev)
+#endif
+{
+    /* Soft Reset the PHY */
+    phy_reset(phydev);
+    if (phydev->dev && phydev->dev != dev) {
+        printf("%s:%d is connected to %s.  Reconnecting to %s\n",
+               phydev->bus->name, phydev->addr,
+               phydev->dev->name, dev->name);
+    }
+    phydev->dev = dev;
+    debug("%s connected to %s\n", dev->name, phydev->drv->name);
+}
+
+#ifdef CONFIG_DM_ETH
+struct phy_device *phy_connect(struct mii_dev *bus, int addr,
+                               struct udevice *dev, phy_interface_t interface)
+#else
+struct phy_device *phy_connect(struct mii_dev *bus, int addr,
+                               struct eth_device *dev, phy_interface_t interface)
+#endif
+{
+    struct phy_device *phydev;
+
+    phydev = phy_find_by_mask(bus, 1 << addr, interface);
+    if (phydev) {
+        phy_connect_dev(phydev, dev);
+    } else {
+        printf("Could not get PHY for %s: addr %d\n", bus->name, addr);
+    }
+    return phydev;
+}
+
+/*
+ * Start the PHY.  Returns 0 on success, or a negative error code.
+ */
+int phy_startup(struct phy_device *phydev)
+{
+    if (phydev->drv->startup) {
+        return phydev->drv->startup(phydev);
+    }
+
+    return 0;
+}
+
+__weak int board_phy_config(struct phy_device *phydev)
+{
+    if (phydev->drv->config) {
+        return phydev->drv->config(phydev);
+    }
+    return 0;
+}
+
+int phy_config(struct phy_device *phydev)
+{
+    /* Invoke an optional board-specific helper */
+    return board_phy_config(phydev);
+}
+
+int phy_shutdown(struct phy_device *phydev)
+{
+    if (phydev->drv->shutdown) {
+        phydev->drv->shutdown(phydev);
+    }
+
+    return 0;
+}
+
+int phy_get_interface_by_name(const char *str)
+{
+    int i;
+
+    for (i = 0; i < PHY_INTERFACE_MODE_COUNT; i++) {
+        if (!strcmp(str, phy_interface_strings[i])) {
+            return i;
+        }
+    }
+
+    return -1;
+}
diff --git a/libethdrivers/src/plat/odroidc2/uboot/phy.h b/libethdrivers/src/plat/odroidc2/uboot/phy.h
new file mode 100644
index 0000000..b11e921
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/phy.h
@@ -0,0 +1,306 @@
+/*
+ * Copyright 2011 Freescale Semiconductor, Inc.
+ *  Andy Fleming <afleming@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ *
+ * This file pretty much stolen from Linux's mii.h/ethtool.h/phy.h
+ */
+
+#pragma once
+
+#include "list.h"
+#include <stdio.h>
+#include "mii.h"
+#include "ethtool.h"
+#include "mdio.h"
+
+#define PHY_MAX_ADDR 32
+
+#define PHY_FLAG_BROKEN_RESET   (1 << 0) /* soft reset not supported */
+
+#define PHY_DEFAULT_FEATURES    (SUPPORTED_Autoneg | \
+                 SUPPORTED_TP | \
+                 SUPPORTED_MII)
+
+#define PHY_10BT_FEATURES   (SUPPORTED_10baseT_Half | \
+                 SUPPORTED_10baseT_Full)
+
+#define PHY_100BT_FEATURES  (SUPPORTED_100baseT_Half | \
+                 SUPPORTED_100baseT_Full)
+
+#define PHY_1000BT_FEATURES (SUPPORTED_1000baseT_Half | \
+                 SUPPORTED_1000baseT_Full)
+
+#define PHY_BASIC_FEATURES  (PHY_10BT_FEATURES | \
+                 PHY_100BT_FEATURES | \
+                 PHY_DEFAULT_FEATURES)
+
+#define PHY_GBIT_FEATURES   (PHY_BASIC_FEATURES | \
+                 PHY_1000BT_FEATURES)
+
+#define PHY_10G_FEATURES    (PHY_GBIT_FEATURES | \
+                SUPPORTED_10000baseT_Full)
+
+#ifndef PHY_ANEG_TIMEOUT
+#define PHY_ANEG_TIMEOUT    10000
+#endif
+
+
+typedef enum {
+    PHY_INTERFACE_MODE_MII,
+    PHY_INTERFACE_MODE_GMII,
+    PHY_INTERFACE_MODE_SGMII,
+    PHY_INTERFACE_MODE_SGMII_2500,
+    PHY_INTERFACE_MODE_QSGMII,
+    PHY_INTERFACE_MODE_TBI,
+    PHY_INTERFACE_MODE_RMII,
+    PHY_INTERFACE_MODE_RGMII,
+    PHY_INTERFACE_MODE_RGMII_ID,
+    PHY_INTERFACE_MODE_RGMII_RXID,
+    PHY_INTERFACE_MODE_RGMII_TXID,
+    PHY_INTERFACE_MODE_RTBI,
+    PHY_INTERFACE_MODE_XGMII,
+    PHY_INTERFACE_MODE_NONE,    /* Must be last */
+
+    PHY_INTERFACE_MODE_COUNT,
+} phy_interface_t;
+
+static const char *phy_interface_strings[] = {
+    [PHY_INTERFACE_MODE_MII]        = "mii",
+    [PHY_INTERFACE_MODE_GMII]       = "gmii",
+    [PHY_INTERFACE_MODE_SGMII]      = "sgmii",
+    [PHY_INTERFACE_MODE_SGMII_2500]     = "sgmii-2500",
+    [PHY_INTERFACE_MODE_QSGMII]     = "qsgmii",
+    [PHY_INTERFACE_MODE_TBI]        = "tbi",
+    [PHY_INTERFACE_MODE_RMII]       = "rmii",
+    [PHY_INTERFACE_MODE_RGMII]      = "rgmii",
+    [PHY_INTERFACE_MODE_RGMII_ID]       = "rgmii-id",
+    [PHY_INTERFACE_MODE_RGMII_RXID]     = "rgmii-rxid",
+    [PHY_INTERFACE_MODE_RGMII_TXID]     = "rgmii-txid",
+    [PHY_INTERFACE_MODE_RTBI]       = "rtbi",
+    [PHY_INTERFACE_MODE_XGMII]      = "xgmii",
+    [PHY_INTERFACE_MODE_NONE]       = "",
+};
+
+static inline const char *phy_string_for_interface(phy_interface_t i)
+{
+    /* Default to unknown */
+    if (i > PHY_INTERFACE_MODE_NONE) {
+        i = PHY_INTERFACE_MODE_NONE;
+    }
+
+    return phy_interface_strings[i];
+}
+
+
+struct phy_device;
+
+#define MDIO_NAME_LEN 32
+
+struct mii_dev {
+    struct list_head link;
+    char name[MDIO_NAME_LEN];
+    void *priv;
+    int (*read)(struct mii_dev *bus, int addr, int devad, int reg);
+    int (*write)(struct mii_dev *bus, int addr, int devad, int reg,
+                 uint16_t val);
+    int (*reset)(struct mii_dev *bus);
+    struct phy_device *phymap[PHY_MAX_ADDR];
+    u32 phy_mask;
+};
+
+/* struct phy_driver: a structure which defines PHY behavior
+ *
+ * uid will contain a number which represents the PHY.  During
+ * startup, the driver will poll the PHY to find out what its
+ * UID--as defined by registers 2 and 3--is.  The 32-bit result
+ * gotten from the PHY will be masked to
+ * discard any bits which may change based on revision numbers
+ * unimportant to functionality
+ *
+ */
+struct phy_driver {
+    char *name;
+    unsigned int uid;
+    unsigned int mask;
+    unsigned int mmds;
+
+    uint32_t features;
+
+    /* Called to do any driver startup necessities */
+    /* Will be called during phy_connect */
+    int (*probe)(struct phy_device *phydev);
+
+    /* Called to configure the PHY, and modify the controller
+     * based on the results.  Should be called after phy_connect */
+    int (*config)(struct phy_device *phydev);
+
+    /* Called when starting up the controller */
+    int (*startup)(struct phy_device *phydev);
+
+    /* Called when bringing down the controller */
+    int (*shutdown)(struct phy_device *phydev);
+
+    int (*readext)(struct phy_device *phydev, int addr, int devad, int reg);
+    int (*writeext)(struct phy_device *phydev, int addr, int devad, int reg,
+                    u16 val);
+    struct list_head list;
+};
+
+struct phy_device {
+    /* Information about the PHY type */
+    /* And management functions */
+    struct mii_dev *bus;
+    struct phy_driver *drv;
+    void *priv;
+
+#ifdef CONFIG_DM_ETH
+    struct udevice *dev;
+#else
+    struct eth_device *dev;
+#endif
+
+    /* forced speed & duplex (no autoneg)
+     * partner speed & duplex & pause (autoneg)
+     */
+    int speed;
+    int duplex;
+
+    /* The most recently read link state */
+    int link;
+    int port;
+    phy_interface_t interface;
+
+    uint32_t advertising;
+    uint32_t supported;
+    uint32_t mmds;
+
+    int autoneg;
+    int addr;
+    int pause;
+    int asym_pause;
+    uint32_t phy_id;
+    uint32_t flags;
+};
+
+struct fixed_link {
+    int phy_id;
+    int duplex;
+    int link_speed;
+    int pause;
+    int asym_pause;
+};
+
+static inline int phy_read(struct phy_device *phydev, int devad, int regnum)
+{
+    struct mii_dev *bus = phydev->bus;
+
+    return bus->read(bus, phydev->addr, devad, regnum);
+}
+
+static inline int phy_write(struct phy_device *phydev, int devad, int regnum,
+                            uint16_t val)
+{
+    struct mii_dev *bus = phydev->bus;
+
+    return bus->write(bus, phydev->addr, devad, regnum, val);
+}
+
+#ifdef CONFIG_PHYLIB_10G
+extern struct phy_driver gen10g_driver;
+
+/* For now, XGMII is the only 10G interface */
+static inline int is_10g_interface(phy_interface_t interface)
+{
+    return interface == PHY_INTERFACE_MODE_XGMII;
+}
+
+#endif
+
+int phy_init(void);
+int phy_reset(struct phy_device *phydev);
+struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
+                                    phy_interface_t interface);
+#ifdef CONFIG_DM_ETH
+void phy_connect_dev(struct phy_device *phydev, struct udevice *dev);
+struct phy_device *phy_connect(struct mii_dev *bus, int addr,
+                               struct udevice *dev,
+                               phy_interface_t interface);
+#else
+void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev);
+struct phy_device *phy_connect(struct mii_dev *bus, int addr,
+                               struct eth_device *dev,
+                               phy_interface_t interface);
+#endif
+int phy_startup(struct phy_device *phydev);
+int phy_config(struct phy_device *phydev);
+int phy_shutdown(struct phy_device *phydev);
+int phy_register(struct phy_driver *drv);
+int phy_set_supported(struct phy_device *phydev, u32 max_speed);
+int genphy_config_aneg(struct phy_device *phydev);
+int genphy_restart_aneg(struct phy_device *phydev);
+int genphy_update_link(struct phy_device *phydev);
+int genphy_parse_link(struct phy_device *phydev);
+int genphy_config(struct phy_device *phydev);
+int genphy_startup(struct phy_device *phydev);
+int genphy_shutdown(struct phy_device *phydev);
+int gen10g_config(struct phy_device *phydev);
+int gen10g_startup(struct phy_device *phydev);
+int gen10g_shutdown(struct phy_device *phydev);
+int gen10g_discover_mmds(struct phy_device *phydev);
+
+int phy_mv88e61xx_init(void);
+int phy_aquantia_init(void);
+int phy_atheros_init(void);
+int phy_broadcom_init(void);
+int phy_cortina_init(void);
+int phy_davicom_init(void);
+int phy_et1011c_init(void);
+int phy_lxt_init(void);
+int phy_marvell_init(void);
+int phy_micrel_init(void);
+int phy_natsemi_init(void);
+int phy_realtek_init(void);
+int phy_smsc_init(void);
+int phy_teranetics_init(void);
+int phy_ti_init(void);
+int phy_vitesse_init(void);
+int phy_xilinx_init(void);
+
+int board_phy_config(struct phy_device *phydev);
+int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id);
+
+/**
+ * phy_get_interface_by_name() - Look up a PHY interface name
+ *
+ * @str:    PHY interface name, e.g. "mii"
+ * @return PHY_INTERFACE_MODE_... value, or -1 if not found
+ */
+int phy_get_interface_by_name(const char *str);
+
+/**
+ * phy_interface_is_rgmii - Convenience function for testing if a PHY interface
+ * is RGMII (all variants)
+ * @phydev: the phy_device struct
+ */
+static inline u8 phy_interface_is_rgmii(struct phy_device *phydev)
+{
+    return phydev->interface >= PHY_INTERFACE_MODE_RGMII &&
+               phydev->interface <= PHY_INTERFACE_MODE_RGMII_TXID;
+}
+
+/**
+ * phy_interface_is_sgmii - Convenience function for testing if a PHY interface
+ * is SGMII (all variants)
+ * @phydev: the phy_device struct
+ */
+static inline u8 phy_interface_is_sgmii(struct phy_device *phydev)
+{
+    return phydev->interface >= PHY_INTERFACE_MODE_SGMII &&
+               phydev->interface <= PHY_INTERFACE_MODE_QSGMII;
+}
+
+/* PHY UIDs for various PHYs that are referenced in external code */
+#define PHY_UID_CS4340  0x13e51002
+#define PHY_UID_TN2020  0x00a19410
diff --git a/libethdrivers/src/plat/odroidc2/uboot/realtek.c b/libethdrivers/src/plat/odroidc2/uboot/realtek.c
new file mode 100644
index 0000000..be23cce
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/realtek.c
@@ -0,0 +1,358 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * RealTek PHY drivers
+ *
+ * Copyright 2010-2011, 2015 Freescale Semiconductor, Inc.
+ * author Andy Fleming
+ * Copyright 2016 Karsten Merker <merker@debian.org>
+ */
+#include "common.h"
+#include "bitops.h"
+#include "phy.h"
+
+#define PHY_RTL8211x_FORCE_MASTER BIT(1)
+#define PHY_RTL8211E_PINE64_GIGABIT_FIX BIT(2)
+
+#define PHY_AUTONEGOTIATE_TIMEOUT 5000
+
+/* RTL8211x 1000BASE-T Control Register */
+#define MIIM_RTL8211x_CTRL1000T_MSCE BIT(12);
+#define MIIM_RTL8211x_CTRL1000T_MASTER BIT(11);
+
+/* RTL8211x PHY Status Register */
+#define MIIM_RTL8211x_PHY_STATUS       0x11
+#define MIIM_RTL8211x_PHYSTAT_SPEED    0xc000
+#define MIIM_RTL8211x_PHYSTAT_GBIT     0x8000
+#define MIIM_RTL8211x_PHYSTAT_100      0x4000
+#define MIIM_RTL8211x_PHYSTAT_DUPLEX   0x2000
+#define MIIM_RTL8211x_PHYSTAT_SPDDONE  0x0800
+#define MIIM_RTL8211x_PHYSTAT_LINK     0x0400
+
+/* RTL8211x PHY Interrupt Enable Register */
+#define MIIM_RTL8211x_PHY_INER         0x12
+#define MIIM_RTL8211x_PHY_INTR_ENA     0x9f01
+#define MIIM_RTL8211x_PHY_INTR_DIS     0x0000
+
+/* RTL8211x PHY Interrupt Status Register */
+#define MIIM_RTL8211x_PHY_INSR         0x13
+
+/* RTL8211F PHY Status Register */
+#define MIIM_RTL8211F_PHY_STATUS       0x1a
+#define MIIM_RTL8211F_AUTONEG_ENABLE   0x1000
+#define MIIM_RTL8211F_PHYSTAT_SPEED    0x0030
+#define MIIM_RTL8211F_PHYSTAT_GBIT     0x0020
+#define MIIM_RTL8211F_PHYSTAT_100      0x0010
+#define MIIM_RTL8211F_PHYSTAT_DUPLEX   0x0008
+#define MIIM_RTL8211F_PHYSTAT_SPDDONE  0x0800
+#define MIIM_RTL8211F_PHYSTAT_LINK     0x0004
+
+#define MIIM_RTL8211E_CONFREG           0x1c
+#define MIIM_RTL8211E_CONFREG_TXD       0x0002
+#define MIIM_RTL8211E_CONFREG_RXD       0x0004
+#define MIIM_RTL8211E_CONFREG_MAGIC     0xb400  /* Undocumented */
+
+#define MIIM_RTL8211E_EXT_PAGE_SELECT  0x1e
+
+#define MIIM_RTL8211F_PAGE_SELECT      0x1f
+#define MIIM_RTL8211F_TX_DELAY      0x100
+#define MIIM_RTL8211F_LCR       0x10
+
+static int rtl8211b_probe(struct phy_device *phydev)
+{
+#ifdef CONFIG_RTL8211X_PHY_FORCE_MASTER
+    phydev->flags |= PHY_RTL8211x_FORCE_MASTER;
+#endif
+
+    return 0;
+}
+
+static int rtl8211e_probe(struct phy_device *phydev)
+{
+#ifdef CONFIG_RTL8211E_PINE64_GIGABIT_FIX
+    phydev->flags |= PHY_RTL8211E_PINE64_GIGABIT_FIX;
+#endif
+
+    return 0;
+}
+
+/* RealTek RTL8211x */
+static int rtl8211x_config(struct phy_device *phydev)
+{
+    phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
+
+    /* mask interrupt at init; if the interrupt is
+     * needed indeed, it should be explicitly enabled
+     */
+    phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER,
+              MIIM_RTL8211x_PHY_INTR_DIS);
+
+    if (phydev->flags & PHY_RTL8211x_FORCE_MASTER) {
+        unsigned int reg;
+
+        reg = phy_read(phydev, MDIO_DEVAD_NONE, MII_CTRL1000);
+        /* force manual master/slave configuration */
+        reg |= MIIM_RTL8211x_CTRL1000T_MSCE;
+        /* force master mode */
+        reg |= MIIM_RTL8211x_CTRL1000T_MASTER;
+        phy_write(phydev, MDIO_DEVAD_NONE, MII_CTRL1000, reg);
+    }
+    if (phydev->flags & PHY_RTL8211E_PINE64_GIGABIT_FIX) {
+        unsigned int reg;
+
+        phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT,
+                  7);
+        phy_write(phydev, MDIO_DEVAD_NONE,
+                  MIIM_RTL8211E_EXT_PAGE_SELECT, 0xa4);
+        reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG);
+        /* Ensure both internal delays are turned off */
+        reg &= ~(MIIM_RTL8211E_CONFREG_TXD | MIIM_RTL8211E_CONFREG_RXD);
+        /* Flip the magic undocumented bits */
+        reg |= MIIM_RTL8211E_CONFREG_MAGIC;
+        phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211E_CONFREG, reg);
+        phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT,
+                  0);
+    }
+    /* read interrupt status just to clear it */
+    phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_INER);
+
+    genphy_config_aneg(phydev);
+
+    return 0;
+}
+
+static int rtl8211f_config(struct phy_device *phydev)
+{
+    u16 reg;
+
+    phy_write(phydev, MDIO_DEVAD_NONE, MII_BMCR, BMCR_RESET);
+
+    phy_write(phydev, MDIO_DEVAD_NONE,
+              MIIM_RTL8211F_PAGE_SELECT, 0xd08);
+    reg = phy_read(phydev, MDIO_DEVAD_NONE, 0x11);
+
+    /* enable TX-delay for rgmii-id and rgmii-txid, otherwise disable it */
+    if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID ||
+        phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
+        reg |= MIIM_RTL8211F_TX_DELAY;
+    } else {
+        reg &= ~MIIM_RTL8211F_TX_DELAY;
+    }
+
+    phy_write(phydev, MDIO_DEVAD_NONE, 0x11, reg);
+    /* restore to default page 0 */
+    phy_write(phydev, MDIO_DEVAD_NONE,
+              MIIM_RTL8211F_PAGE_SELECT, 0x0);
+
+    /* Set green LED for Link, yellow LED for Active */
+    phy_write(phydev, MDIO_DEVAD_NONE,
+              MIIM_RTL8211F_PAGE_SELECT, 0xd04);
+    phy_write(phydev, MDIO_DEVAD_NONE, 0x10, 0x617f);
+    phy_write(phydev, MDIO_DEVAD_NONE,
+              MIIM_RTL8211F_PAGE_SELECT, 0x0);
+
+    genphy_config_aneg(phydev);
+
+    return 0;
+}
+
+static int rtl8211x_parse_status(struct phy_device *phydev)
+{
+    unsigned int speed;
+    unsigned int mii_reg;
+
+    mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211x_PHY_STATUS);
+
+    if (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) {
+        int i = 0;
+
+        /* in case of timeout ->link is cleared */
+        phydev->link = 1;
+        puts("Waiting for PHY realtime link");
+        while (!(mii_reg & MIIM_RTL8211x_PHYSTAT_SPDDONE)) {
+            /* Timeout reached ? */
+            if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
+                puts(" TIMEOUT !\n");
+                phydev->link = 0;
+                break;
+            }
+
+            if ((i++ % 1000) == 0) {
+                putchar('.');
+            }
+            uboot_udelay(1000); /* 1 ms */
+            mii_reg = phy_read(phydev, MDIO_DEVAD_NONE,
+                               MIIM_RTL8211x_PHY_STATUS);
+        }
+        puts(" done\n");
+        uboot_udelay(500000);   /* another 500 ms (results in faster booting) */
+    } else {
+        if (mii_reg & MIIM_RTL8211x_PHYSTAT_LINK) {
+            phydev->link = 1;
+        } else {
+            phydev->link = 0;
+        }
+    }
+
+    if (mii_reg & MIIM_RTL8211x_PHYSTAT_DUPLEX) {
+        phydev->duplex = DUPLEX_FULL;
+    } else {
+        phydev->duplex = DUPLEX_HALF;
+    }
+
+    speed = (mii_reg & MIIM_RTL8211x_PHYSTAT_SPEED);
+
+    switch (speed) {
+    case MIIM_RTL8211x_PHYSTAT_GBIT:
+        phydev->speed = SPEED_1000;
+        break;
+    case MIIM_RTL8211x_PHYSTAT_100:
+        phydev->speed = SPEED_100;
+        break;
+    default:
+        phydev->speed = SPEED_10;
+    }
+
+    return 0;
+}
+
+static int rtl8211f_parse_status(struct phy_device *phydev)
+{
+    unsigned int speed;
+    unsigned int mii_reg;
+    int i = 0;
+
+    phy_write(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PAGE_SELECT, 0xa43);
+    mii_reg = phy_read(phydev, MDIO_DEVAD_NONE, MIIM_RTL8211F_PHY_STATUS);
+
+    phydev->link = 1;
+    while (!(mii_reg & MIIM_RTL8211F_PHYSTAT_LINK)) {
+        if (i > PHY_AUTONEGOTIATE_TIMEOUT) {
+            puts(" TIMEOUT !\n");
+            phydev->link = 0;
+            break;
+        }
+
+        if ((i++ % 1000) == 0) {
+            putchar('.');
+        }
+        uboot_udelay(1000);
+        mii_reg = phy_read(phydev, MDIO_DEVAD_NONE,
+                           MIIM_RTL8211F_PHY_STATUS);
+    }
+
+    if (mii_reg & MIIM_RTL8211F_PHYSTAT_DUPLEX) {
+        phydev->duplex = DUPLEX_FULL;
+    } else {
+        phydev->duplex = DUPLEX_HALF;
+    }
+
+    speed = (mii_reg & MIIM_RTL8211F_PHYSTAT_SPEED);
+
+    switch (speed) {
+    case MIIM_RTL8211F_PHYSTAT_GBIT:
+        phydev->speed = SPEED_1000;
+        break;
+    case MIIM_RTL8211F_PHYSTAT_100:
+        phydev->speed = SPEED_100;
+        break;
+    default:
+        phydev->speed = SPEED_10;
+    }
+
+    return 0;
+}
+
+static int rtl8211x_startup(struct phy_device *phydev)
+{
+    int ret;
+
+    /* Read the Status (2x to make sure link is right) */
+    ret = genphy_update_link(phydev);
+    if (ret) {
+        return ret;
+    }
+
+    return rtl8211x_parse_status(phydev);
+}
+
+static int rtl8211e_startup(struct phy_device *phydev)
+{
+    int ret;
+
+    ret = genphy_update_link(phydev);
+    if (ret) {
+        return ret;
+    }
+
+    return genphy_parse_link(phydev);
+}
+
+static int rtl8211f_startup(struct phy_device *phydev)
+{
+    int ret;
+
+    /* Read the Status (2x to make sure link is right) */
+    ret = genphy_update_link(phydev);
+    if (ret) {
+        return ret;
+    }
+    /* Read the Status (2x to make sure link is right) */
+
+    return rtl8211f_parse_status(phydev);
+}
+
+/* Support for RTL8211B PHY */
+static struct phy_driver RTL8211B_driver = {
+    .name = "RealTek RTL8211B",
+    .uid = 0x1cc912,
+    .mask = 0xffffff,
+    .features = PHY_GBIT_FEATURES,
+    .probe = &rtl8211b_probe,
+    .config = &rtl8211x_config,
+    .startup = &rtl8211x_startup,
+    .shutdown = &genphy_shutdown,
+};
+
+/* Support for RTL8211E-VB-CG, RTL8211E-VL-CG and RTL8211EG-VB-CG PHYs */
+static struct phy_driver RTL8211E_driver = {
+    .name = "RealTek RTL8211E",
+    .uid = 0x1cc915,
+    .mask = 0xffffff,
+    .features = PHY_GBIT_FEATURES,
+    .probe = &rtl8211e_probe,
+    .config = &rtl8211x_config,
+    .startup = &rtl8211e_startup,
+    .shutdown = &genphy_shutdown,
+};
+
+/* Support for RTL8211DN PHY */
+static struct phy_driver RTL8211DN_driver = {
+    .name = "RealTek RTL8211DN",
+    .uid = 0x1cc914,
+    .mask = 0xffffff,
+    .features = PHY_GBIT_FEATURES,
+    .config = &rtl8211x_config,
+    .startup = &rtl8211x_startup,
+    .shutdown = &genphy_shutdown,
+};
+
+/* Support for RTL8211F PHY */
+static struct phy_driver RTL8211F_driver = {
+    .name = "RealTek RTL8211F",
+    .uid = 0x1cc916,
+    .mask = 0xffffff,
+    .features = PHY_GBIT_FEATURES,
+    .config = &rtl8211f_config,
+    .startup = &rtl8211f_startup,
+    .shutdown = &genphy_shutdown,
+};
+
+int phy_realtek_init(void)
+{
+    phy_register(&RTL8211B_driver);
+    phy_register(&RTL8211E_driver);
+    phy_register(&RTL8211F_driver);
+    phy_register(&RTL8211DN_driver);
+
+    return 0;
+}
diff --git a/libethdrivers/src/plat/odroidc2/uboot/system.h b/libethdrivers/src/plat/odroidc2/uboot/system.h
new file mode 100644
index 0000000..390752b
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/uboot/system.h
@@ -0,0 +1,309 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ * Copyright Linux
+ */
+#pragma once
+
+#include <autoconf.h>
+
+#ifdef CONFIG_ARM64
+
+/*
+ * SCTLR_EL1/SCTLR_EL2/SCTLR_EL3 bits definitions
+ */
+#define CR_M        (1 << 0)    /* MMU enable           */
+#define CR_A        (1 << 1)    /* Alignment abort enable   */
+#define CR_C        (1 << 2)    /* Dcache enable        */
+#define CR_SA       (1 << 3)    /* Stack Alignment Check Enable */
+#define CR_I        (1 << 12)   /* Icache enable        */
+#define CR_WXN      (1 << 19)   /* Write Permision Imply XN */
+#define CR_EE       (1 << 25)   /* Exception (Big) Endian   */
+
+#define PGTABLE_SIZE    (0x10000)
+/* 2MB granularity */
+#define MMU_SECTION_SHIFT   21
+#define MMU_SECTION_SIZE    (1 << MMU_SECTION_SHIFT)
+
+#ifndef __ASSEMBLY__
+
+enum dcache_option {
+    DCACHE_OFF = 0x3,
+};
+
+#define isb()               \
+    ({asm volatile(         \
+    "isb" : : : "memory");      \
+    })
+
+#define wfi()               \
+    ({asm volatile(         \
+    "wfi" : : : "memory");      \
+    })
+
+static inline unsigned int current_el(void)
+{
+    unsigned int el;
+    asm volatile("mrs %0, CurrentEL" : "=r"(el) : : "cc");
+    return el >> 2;
+}
+
+static inline unsigned int get_sctlr(void)
+{
+    unsigned int el, val;
+
+    el = current_el();
+    if (el == 1) {
+        asm volatile("mrs %0, sctlr_el1" : "=r"(val) : : "cc");
+    } else if (el == 2) {
+        asm volatile("mrs %0, sctlr_el2" : "=r"(val) : : "cc");
+    } else {
+        asm volatile("mrs %0, sctlr_el3" : "=r"(val) : : "cc");
+    }
+
+    return val;
+}
+
+static inline void set_sctlr(unsigned int val)
+{
+    unsigned int el;
+
+    el = current_el();
+    if (el == 1) {
+        asm volatile("msr sctlr_el1, %0" : : "r"(val) : "cc");
+    } else if (el == 2) {
+        asm volatile("msr sctlr_el2, %0" : : "r"(val) : "cc");
+    } else {
+        asm volatile("msr sctlr_el3, %0" : : "r"(val) : "cc");
+    }
+
+    asm volatile("isb");
+}
+
+void __asm_flush_dcache_all(void);
+void __asm_invalidate_dcache_all(void);
+void __asm_flush_dcache_range(u64 start, u64 end);
+void __asm_invalidate_tlb_all(void);
+void __asm_invalidate_icache_all(void);
+int __asm_flush_l3_cache(void);
+
+void armv8_switch_to_el2(void);
+void armv8_switch_to_el1(void);
+void gic_init(void);
+void gic_send_sgi(unsigned long sgino);
+void wait_for_wakeup(void);
+void protect_secure_region(void);
+void smp_kick_all_cpus(void);
+
+void flush_l3_cache(void);
+
+#endif  /* __ASSEMBLY__ */
+
+#else /* CONFIG_ARM64 */
+
+#define CPU_ARCH_UNKNOWN    0
+#define CPU_ARCH_ARMv3      1
+#define CPU_ARCH_ARMv4      2
+#define CPU_ARCH_ARMv4T     3
+#define CPU_ARCH_ARMv5      4
+#define CPU_ARCH_ARMv5T     5
+#define CPU_ARCH_ARMv5TE    6
+#define CPU_ARCH_ARMv5TEJ   7
+#define CPU_ARCH_ARMv6      8
+#define CPU_ARCH_ARMv7      9
+
+/*
+ * CR1 bits (CP#15 CR1)
+ */
+#define CR_M    (1 << 0)    /* MMU enable               */
+#define CR_A    (1 << 1)    /* Alignment abort enable       */
+#define CR_C    (1 << 2)    /* Dcache enable            */
+#define CR_W    (1 << 3)    /* Write buffer enable          */
+#define CR_P    (1 << 4)    /* 32-bit exception handler     */
+#define CR_D    (1 << 5)    /* 32-bit data address range        */
+#define CR_L    (1 << 6)    /* Implementation defined       */
+#define CR_B    (1 << 7)    /* Big endian               */
+#define CR_S    (1 << 8)    /* System MMU protection        */
+#define CR_R    (1 << 9)    /* ROM MMU protection           */
+#define CR_F    (1 << 10)   /* Implementation defined       */
+#define CR_Z    (1 << 11)   /* Implementation defined       */
+#define CR_I    (1 << 12)   /* Icache enable            */
+#define CR_V    (1 << 13)   /* Vectors relocated to 0xffff0000  */
+#define CR_RR   (1 << 14)   /* Round Robin cache replacement    */
+#define CR_L4   (1 << 15)   /* LDR pc can set T bit         */
+#define CR_DT   (1 << 16)
+#define CR_IT   (1 << 18)
+#define CR_ST   (1 << 19)
+#define CR_FI   (1 << 21)   /* Fast interrupt (lower latency mode)  */
+#define CR_U    (1 << 22)   /* Unaligned access operation       */
+#define CR_XP   (1 << 23)   /* Extended page tables         */
+#define CR_VE   (1 << 24)   /* Vectored interrupts          */
+#define CR_EE   (1 << 25)   /* Exception (Big) Endian       */
+#define CR_TRE  (1 << 28)   /* TEX remap enable         */
+#define CR_AFE  (1 << 29)   /* Access flag enable           */
+#define CR_TE   (1 << 30)   /* Thumb exception enable       */
+
+#define PGTABLE_SIZE        (4096 * 4)
+
+/*
+ * This is used to ensure the compiler did actually allocate the register we
+ * asked it for some inline assembly sequences.  Apparently we can't trust
+ * the compiler from one version to another so a bit of paranoia won't hurt.
+ * This string is meant to be concatenated with the inline asm string and
+ * will cause compilation to stop on mismatch.
+ * (for details, see gcc PR 15089)
+ */
+#define __asmeq(x, y)  ".ifnc " x "," y " ; .err ; .endif\n\t"
+
+#ifndef __ASSEMBLY__
+
+/**
+ * save_boot_params() - Save boot parameters before starting reset sequence
+ *
+ * If you provide this function it will be called immediately U-Boot starts,
+ * both for SPL and U-Boot proper.
+ *
+ * All registers are unchanged from U-Boot entry. No registers need be
+ * preserved.
+ *
+ * This is not a normal C function. There is no stack. Return by branching to
+ * save_boot_params_ret.
+ *
+ * void save_boot_params(u32 r0, u32 r1, u32 r2, u32 r3);
+ */
+
+/**
+ * save_boot_params_ret() - Return from save_boot_params()
+ *
+ * If you provide save_boot_params(), then you should jump back to this
+ * function when done. Try to preserve all registers.
+ *
+ * If your implementation of save_boot_params() is in C then it is acceptable
+ * to simply call save_boot_params_ret() at the end of your function. Since
+ * there is no link register set up, you cannot just exit the function. U-Boot
+ * will return to the (initialised) value of lr, and likely crash/hang.
+ *
+ * If your implementation of save_boot_params() is in assembler then you
+ * should use 'b' or 'bx' to return to save_boot_params_ret.
+ */
+void save_boot_params_ret(void);
+
+#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
+
+#ifdef CONFIG_ARCH_ARM_V7A
+#define wfi() __asm__ __volatile__ ("wfi" : : : "memory")
+#else
+#define wfi()
+#endif
+
+static inline unsigned int get_cr(void)
+{
+    unsigned int val;
+    asm volatile("mrc p15, 0, %0, c1, c0, 0	@ get CR" : "=r"(val) : : "cc");
+    return val;
+}
+
+static inline void set_cr(unsigned int val)
+{
+    asm volatile("mcr p15, 0, %0, c1, c0, 0	@ set CR"
+                 : : "r"(val) : "cc");
+    isb();
+}
+
+static inline unsigned int get_dacr(void)
+{
+    unsigned int val;
+    asm("mrc p15, 0, %0, c3, c0, 0	@ get DACR" : "=r"(val) : : "cc");
+    return val;
+}
+
+static inline void set_dacr(unsigned int val)
+{
+    asm volatile("mcr p15, 0, %0, c3, c0, 0	@ set DACR"
+                 : : "r"(val) : "cc");
+    isb();
+}
+
+#ifdef CONFIG_ARCH_ARM_V7A
+/* Short-Descriptor Translation Table Level 1 Bits */
+#define TTB_SECT_NS_MASK    (1 << 19)
+#define TTB_SECT_NG_MASK    (1 << 17)
+#define TTB_SECT_S_MASK     (1 << 16)
+/* Note: TTB AP bits are set elsewhere */
+#define TTB_SECT_TEX(x)     ((x & 0x7) << 12)
+#define TTB_SECT_DOMAIN(x)  ((x & 0xf) << 5)
+#define TTB_SECT_XN_MASK    (1 << 4)
+#define TTB_SECT_C_MASK     (1 << 3)
+#define TTB_SECT_B_MASK     (1 << 2)
+#define TTB_SECT            (2 << 0)
+
+/* options available for data cache on each page */
+enum dcache_option {
+    DCACHE_OFF = TTB_SECT_S_MASK | TTB_SECT_DOMAIN(0) |
+                 TTB_SECT_XN_MASK | TTB_SECT,
+    DCACHE_WRITETHROUGH = DCACHE_OFF | TTB_SECT_C_MASK,
+    DCACHE_WRITEBACK = DCACHE_WRITETHROUGH | TTB_SECT_B_MASK,
+    DCACHE_WRITEALLOC = DCACHE_WRITEBACK | TTB_SECT_TEX(1),
+};
+
+#else  /* CONFIG_ARCH_ARM_V7A */
+/* options available for data cache on each page */
+enum dcache_option {
+    DCACHE_OFF = 0x12,
+    DCACHE_WRITETHROUGH = 0x1a,
+    DCACHE_WRITEBACK = 0x1e,
+    DCACHE_WRITEALLOC = 0x16,
+};
+#endif
+
+/* Size of an MMU section */
+enum {
+    MMU_SECTION_SHIFT   = 20,
+    MMU_SECTION_SIZE    = 1 << MMU_SECTION_SHIFT,
+};
+
+#ifdef CONFIG_ARCH_ARM_V7A
+/* TTBR0 bits */
+#define TTBR0_BASE_ADDR_MASK    0xFFFFC000
+#define TTBR0_RGN_NC            (0 << 3)
+#define TTBR0_RGN_WBWA          (1 << 3)
+#define TTBR0_RGN_WT            (2 << 3)
+#define TTBR0_RGN_WB            (3 << 3)
+/* TTBR0[6] is IRGN[0] and TTBR[0] is IRGN[1] */
+#define TTBR0_IRGN_NC           (0 << 0 | 0 << 6)
+#define TTBR0_IRGN_WBWA         (0 << 0 | 1 << 6)
+#define TTBR0_IRGN_WT           (1 << 0 | 0 << 6)
+#define TTBR0_IRGN_WB           (1 << 0 | 1 << 6)
+#endif
+
+/**
+ * Register an update to the page tables, and flush the TLB
+ *
+ * \param start     start address of update in page table
+ * \param stop      stop address of update in page table
+ */
+void mmu_page_table_flush(unsigned long start, unsigned long stop);
+
+#endif /* __ASSEMBLY__ */
+
+#define arch_align_stack(x) (x)
+
+
+#endif /* CONFIG_ARM64 */
+
+#ifndef __ASSEMBLY__
+/**
+ * Change the cache settings for a region.
+ *
+ * \param start     start address of memory region to change
+ * \param size      size of memory region to change
+ * \param option    dcache option to select
+ */
+void mmu_set_region_dcache_behaviour(phys_addr_t start, size_t size,
+                                     enum dcache_option option);
+
+#ifdef CONFIG_SYS_NONCACHED_MEMORY
+void noncached_init(void);
+phys_addr_t noncached_alloc(size_t size, size_t align);
+#endif /* CONFIG_SYS_NONCACHED_MEMORY */
+
+#endif /* __ASSEMBLY__ */
diff --git a/libethdrivers/src/plat/odroidc2/unimplemented.c b/libethdrivers/src/plat/odroidc2/unimplemented.c
new file mode 100644
index 0000000..0d070ab
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/unimplemented.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+#include <stdio.h>
+#include <stdint.h>
+#include <ctype.h>
+
+#include "unimplemented.h"
+
+void udelay(uint32_t us)
+{
+    volatile int i;
+    for (; us > 0; us--) {
+        for (i = 0; i < 100; i++) {
+        }
+    }
+}
+
+unsigned long simple_strtoul(const char *cp, char **endp,
+                             unsigned int base)
+{
+    unsigned long result = 0;
+    unsigned long value;
+
+    if (*cp == '0') {
+        cp++;
+        if ((*cp == 'x') && isxdigit(cp[1])) {
+            base = 16;
+            cp++;
+        }
+
+        if (!base) {
+            base = 8;
+        }
+    }
+
+    if (!base) {
+        base = 10;
+    }
+
+    while (isxdigit(*cp) && (value = isdigit(*cp) ? *cp - '0' : (islower(*cp)
+                                                                 ? toupper(*cp) : *cp) - 'A' + 10) < base) {
+        result = result * base + value;
+        cp++;
+    }
+
+    if (endp) {
+        *endp = (char *)cp;
+    }
+
+    return result;
+}
+
diff --git a/libethdrivers/src/plat/odroidc2/unimplemented.h b/libethdrivers/src/plat/odroidc2/unimplemented.h
new file mode 100644
index 0000000..e187a44
--- /dev/null
+++ b/libethdrivers/src/plat/odroidc2/unimplemented.h
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: GPL-2.0-only
+ */
+#pragma once
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <utils/util.h>
+
+/*****************************************
+ * Adaptors for u-boot functions         *
+ *****************************************/
+
+void udelay(uint32_t);
+
+static inline void uboot_udelay(uint32_t us)
+{
+    udelay(us);
+}
+
+/***********************************************************************************
+ * The rest of this file is a dumping ground of missing symbols required by u-boot *
+ ***********************************************************************************/
+
+#define CONFIG_SYS_CACHELINE_SIZE 64 /* for cortex a53 MPCore */
+#define ARCH_DMA_MINALIGN   CONFIG_SYS_CACHELINE_SIZE
+
+#define max(a,b) \
+   ({ __typeof__ (a) _a = (a); \
+       __typeof__ (b) _b = (b); \
+     _a > _b ? _a : _b; })
+
+#ifndef RESOURCE
+#define RESOURCE(mapper, id) ps_io_map(mapper,  (uintptr_t) id##_PADDR, id##_SIZE, 0, PS_MEM_NORMAL)
+#define UNRESOURCE(mapper, id, addr) ps_io_unmap(mapper, addr, id##_SIZE)
+#endif
+
+#define __aligned(x) __attribute__((aligned(x)))
+#define unlikely(x) __builtin_expect(!!(x), 0)
+
+#define __always_inline inline __attribute__((always_inline))
+#define  noinline   __attribute__((noinline))
+
+#define __deprecated    __attribute__((deprecated))
+#define __packed    __attribute__((packed))
+#define __weak      __attribute__((weak))
+#define __alias(symbol) __attribute__((alias(#symbol)))
+#define __must_check        __attribute__((warn_unused_result))
+
+#define MAX_PKT_SIZE    1536
+
+#define BITS_PER_LONG 32
+
+#define ENOTSUPP    524 /* Operation is not supported */
+
+unsigned long simple_strtoul(const char *cp, char **endp, unsigned int base);
+
+#ifdef CONFIG_PHYS_64BIT
+typedef unsigned long long phys_addr_t;
+typedef unsigned long long phys_size_t;
+#else
+/* DMA addresses are 32-bits wide */
+typedef unsigned long phys_addr_t;
+typedef unsigned long phys_size_t;
+#endif
+
+typedef uint64_t u64;
+typedef uint32_t u32;
+typedef uint16_t u16;
+typedef uint8_t  u8;
+
+typedef int64_t s64;
+typedef int32_t s32;
+typedef int16_t s16;
+typedef int8_t  s8;
+
+typedef unsigned long ulong;
+typedef unsigned short ushort;
+typedef unsigned int  uint;
+typedef unsigned char uchar;
+
+typedef u64 __u64;
+typedef u32 __u32;
+typedef u16 __u16;
+typedef u8  __u8;
+
+#define __bitwise /*__attribute__((bitwise))*/
+#define __force /* __attribute__((force)) */
+
+typedef s64 __bitwise __le64;
+typedef s32 __bitwise __le32;
+typedef s16 __bitwise __le16;
+typedef s8  __bitwise __le8;
+
+typedef s64 __bitwise __be64;
+typedef s32 __bitwise __be32;
+typedef s16 __bitwise __be16;
+typedef s8  __bitwise __be8;
+
+typedef unsigned __bitwise  gfp_t;
+
+#define gpio_init()
+#define WATCHDOG_RESET()
+
+typedef struct bd_info {
+    unsigned long   bi_memstart;    /* start of DRAM memory */
+    phys_size_t bi_memsize; /* size  of DRAM memory in bytes */
+    unsigned long   bi_flashstart;  /* start of FLASH memory */
+    unsigned long   bi_flashsize;   /* size  of FLASH memory */
+    unsigned long   bi_flashoffset; /* reserved area for startup monitor */
+    unsigned long   bi_sramstart;   /* start of SRAM memory */
+    unsigned long   bi_sramsize;    /* size  of SRAM memory */
+#ifdef CONFIG_AVR32
+    unsigned char   bi_phy_id[4];   /* PHY address for ATAG_ETHERNET */
+    unsigned long   bi_board_number;/* ATAG_BOARDINFO */
+#endif
+#ifdef CONFIG_ARM
+    unsigned long   bi_arm_freq; /* arm frequency */
+    unsigned long   bi_dsp_freq; /* dsp core frequency */
+    unsigned long   bi_ddr_freq; /* ddr frequency */
+#endif
+#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_MPC8260) \
+    || defined(CONFIG_E500) || defined(CONFIG_MPC86xx)
+    unsigned long   bi_immr_base;   /* base of IMMR register */
+#endif
+#if defined(CONFIG_MPC5xxx) || defined(CONFIG_M68K)
+    unsigned long   bi_mbar_base;   /* base of internal registers */
+#endif
+#if defined(CONFIG_MPC83xx)
+    unsigned long   bi_immrbar;
+#endif
+    unsigned long   bi_bootflags;   /* boot / reboot flag (Unused) */
+    unsigned long   bi_ip_addr; /* IP Address */
+    unsigned char   bi_enetaddr[6]; /* OLD: see README.enetaddr */
+    unsigned short  bi_ethspeed;    /* Ethernet speed in Mbps */
+    unsigned long   bi_intfreq; /* Internal Freq, in MHz */
+    unsigned long   bi_busfreq; /* Bus Freq, in MHz */
+#if defined(CONFIG_CPM2)
+    unsigned long   bi_cpmfreq; /* CPM_CLK Freq, in MHz */
+    unsigned long   bi_brgfreq; /* BRG_CLK Freq, in MHz */
+    unsigned long   bi_sccfreq; /* SCC_CLK Freq, in MHz */
+    unsigned long   bi_vco;     /* VCO Out from PLL, in MHz */
+#endif
+#if defined(CONFIG_MPC512X)
+    unsigned long   bi_ipsfreq; /* IPS Bus Freq, in MHz */
+#endif /* CONFIG_MPC512X */
+#if defined(CONFIG_MPC5xxx) || defined(CONFIG_M68K)
+    unsigned long   bi_ipbfreq; /* IPB Bus Freq, in MHz */
+    unsigned long   bi_pcifreq; /* PCI Bus Freq, in MHz */
+#endif
+#if defined(CONFIG_EXTRA_CLOCK)
+    unsigned long bi_inpfreq;   /* input Freq in MHz */
+    unsigned long bi_vcofreq;   /* vco Freq in MHz */
+    unsigned long bi_flbfreq;   /* Flexbus Freq in MHz */
+#endif
+#if defined(CONFIG_405)   || \
+        defined(CONFIG_405GP) || \
+        defined(CONFIG_405EP) || \
+        defined(CONFIG_405EZ) || \
+        defined(CONFIG_405EX) || \
+        defined(CONFIG_440)
+    unsigned char   bi_s_version[4];    /* Version of this structure */
+    unsigned char   bi_r_version[32];   /* Version of the ROM (AMCC) */
+    unsigned int    bi_procfreq;    /* CPU (Internal) Freq, in Hz */
+    unsigned int    bi_plb_busfreq; /* PLB Bus speed, in Hz */
+    unsigned int    bi_pci_busfreq; /* PCI Bus speed, in Hz */
+    unsigned char   bi_pci_enetaddr[6]; /* PCI Ethernet MAC address */
+#endif
+
+#ifdef CONFIG_HAS_ETH1
+    unsigned char   bi_enet1addr[6];    /* OLD: see README.enetaddr */
+#endif
+#ifdef CONFIG_HAS_ETH2
+    unsigned char   bi_enet2addr[6];    /* OLD: see README.enetaddr */
+#endif
+#ifdef CONFIG_HAS_ETH3
+    unsigned char   bi_enet3addr[6];    /* OLD: see README.enetaddr */
+#endif
+#ifdef CONFIG_HAS_ETH4
+    unsigned char   bi_enet4addr[6];    /* OLD: see README.enetaddr */
+#endif
+#ifdef CONFIG_HAS_ETH5
+    unsigned char   bi_enet5addr[6];    /* OLD: see README.enetaddr */
+#endif
+
+#if defined(CONFIG_405GP) || defined(CONFIG_405EP) || \
+        defined(CONFIG_405EZ) || defined(CONFIG_440GX) || \
+        defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+        defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+        defined(CONFIG_460EX) || defined(CONFIG_460GT)
+    unsigned int    bi_opbfreq;     /* OPB clock in Hz */
+    int     bi_iic_fast[2];     /* Use fast i2c mode */
+#endif
+#if defined(CONFIG_4xx)
+#if defined(CONFIG_440GX) || \
+        defined(CONFIG_460EX) || defined(CONFIG_460GT)
+    int     bi_phynum[4];           /* Determines phy mapping */
+    int     bi_phymode[4];          /* Determines phy mode */
+#elif defined(CONFIG_405EP) || defined(CONFIG_405EX) || defined(CONFIG_440)
+    int     bi_phynum[2];           /* Determines phy mapping */
+    int     bi_phymode[2];          /* Determines phy mode */
+#else
+    int     bi_phynum[1];           /* Determines phy mapping */
+    int     bi_phymode[1];          /* Determines phy mode */
+#endif
+#endif /* defined(CONFIG_4xx) */
+    ulong           bi_arch_number; /* unique id for this board */
+    ulong           bi_boot_params; /* where this board expects params */
+#ifdef CONFIG_NR_DRAM_BANKS
+    struct {            /* RAM configuration */
+        phys_addr_t start;
+        phys_size_t size;
+    } bi_dram[CONFIG_NR_DRAM_BANKS];
+#endif /* CONFIG_NR_DRAM_BANKS */
+} bd_t;
diff --git a/libethdrivers/src/plat/pc99/intel.c b/libethdrivers/src/plat/pc99/intel.c
index 2baf420..c5f008b 100644
--- a/libethdrivers/src/plat/pc99/intel.c
+++ b/libethdrivers/src/plat/pc99/intel.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #include <ethdrivers/gen_config.h>
diff --git a/libethdrivers/src/plat/tx2/io.h b/libethdrivers/src/plat/tx2/io.h
index bd83d9a..6f0c43f 100644
--- a/libethdrivers/src/plat/tx2/io.h
+++ b/libethdrivers/src/plat/tx2/io.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2020, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #pragma once
diff --git a/libethdrivers/src/plat/tx2/tx2.c b/libethdrivers/src/plat/tx2/tx2.c
index 4fd42b6..b6f42c8 100644
--- a/libethdrivers/src/plat/tx2/tx2.c
+++ b/libethdrivers/src/plat/tx2/tx2.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2020, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #include <platsupport/fdt.h>
diff --git a/libethdrivers/src/plat/tx2/tx2.h b/libethdrivers/src/plat/tx2/tx2.h
index bd7a5ce..a2490ad 100644
--- a/libethdrivers/src/plat/tx2/tx2.h
+++ b/libethdrivers/src/plat/tx2/tx2.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2020, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 #include <platsupport/io.h>
 #include <utils/util.h>
diff --git a/libethdrivers/src/plat/tx2/uboot/common.h b/libethdrivers/src/plat/tx2/uboot/common.h
index dd64c14..d794101 100644
--- a/libethdrivers/src/plat/tx2/uboot/common.h
+++ b/libethdrivers/src/plat/tx2/uboot/common.h
@@ -1,5 +1,5 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 /*
diff --git a/libethdrivers/src/plat/tx2/uboot/dwc_eth_qos.c b/libethdrivers/src/plat/tx2/uboot/dwc_eth_qos.c
index 9af3c8f..777edec 100644
--- a/libethdrivers/src/plat/tx2/uboot/dwc_eth_qos.c
+++ b/libethdrivers/src/plat/tx2/uboot/dwc_eth_qos.c
@@ -1,7 +1,7 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
-// SPDX-License-Identifier: GPL-2.0
+
 /*
  * Copyright (c) 2016, NVIDIA CORPORATION.
  *
diff --git a/libethdrivers/src/plat/tx2/uboot/dwc_eth_qos.h b/libethdrivers/src/plat/tx2/uboot/dwc_eth_qos.h
index 20e0098..225c609 100644
--- a/libethdrivers/src/plat/tx2/uboot/dwc_eth_qos.h
+++ b/libethdrivers/src/plat/tx2/uboot/dwc_eth_qos.h
@@ -1,7 +1,7 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
-// SPDX-License-Identifier: GPL-2.0
+
 /*
  * Copyright (c) 2016, NVIDIA CORPORATION.
  *
diff --git a/libethdrivers/src/plat/tx2/uboot/err.h b/libethdrivers/src/plat/tx2/uboot/err.h
index 13e05a9..f1e815a 100644
--- a/libethdrivers/src/plat/tx2/uboot/err.h
+++ b/libethdrivers/src/plat/tx2/uboot/err.h
@@ -1,5 +1,6 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
+ * Copyright Linux
  */
 #pragma once
 
diff --git a/libethdrivers/src/plat/tx2/uboot/ethtool.h b/libethdrivers/src/plat/tx2/uboot/ethtool.h
index 66cc485..1fdd90b 100644
--- a/libethdrivers/src/plat/tx2/uboot/ethtool.h
+++ b/libethdrivers/src/plat/tx2/uboot/ethtool.h
@@ -1,5 +1,5 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 /*
diff --git a/libethdrivers/src/plat/tx2/uboot/list.h b/libethdrivers/src/plat/tx2/uboot/list.h
index 7cfb4e9..1303bc1 100644
--- a/libethdrivers/src/plat/tx2/uboot/list.h
+++ b/libethdrivers/src/plat/tx2/uboot/list.h
@@ -1,5 +1,6 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
+ * Copyright Linux
  */
 #pragma once
 
diff --git a/libethdrivers/src/plat/tx2/uboot/mdio.h b/libethdrivers/src/plat/tx2/uboot/mdio.h
index 3f196fe..182d443 100644
--- a/libethdrivers/src/plat/tx2/uboot/mdio.h
+++ b/libethdrivers/src/plat/tx2/uboot/mdio.h
@@ -1,5 +1,5 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 /*
diff --git a/libethdrivers/src/plat/tx2/uboot/mii.h b/libethdrivers/src/plat/tx2/uboot/mii.h
index 0060a86..10e4e12 100644
--- a/libethdrivers/src/plat/tx2/uboot/mii.h
+++ b/libethdrivers/src/plat/tx2/uboot/mii.h
@@ -1,5 +1,5 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 /*
diff --git a/libethdrivers/src/plat/tx2/uboot/miiphy.h b/libethdrivers/src/plat/tx2/uboot/miiphy.h
index 5d692fb..950919f 100644
--- a/libethdrivers/src/plat/tx2/uboot/miiphy.h
+++ b/libethdrivers/src/plat/tx2/uboot/miiphy.h
@@ -1,7 +1,4 @@
-/*
- * @TAG(OTHER_GPL)
- */
-/* SPDX-License-Identifier: GPL-2.0 OR IBM-pibs */
+/* SPDX-License-Identifier: GPL-2.0-only OR IBM-pibs */
 /*
  * Additions (C) Copyright 2009 Industrie Dial Face S.p.A.
  */
diff --git a/libethdrivers/src/plat/tx2/uboot/miiphyutil.c b/libethdrivers/src/plat/tx2/uboot/miiphyutil.c
index a99bee0..bd6862b 100644
--- a/libethdrivers/src/plat/tx2/uboot/miiphyutil.c
+++ b/libethdrivers/src/plat/tx2/uboot/miiphyutil.c
@@ -1,7 +1,7 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
-// SPDX-License-Identifier: GPL-2.0+
+
 /*
  * (C) Copyright 2001
  * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com.
diff --git a/libethdrivers/src/plat/tx2/uboot/net.h b/libethdrivers/src/plat/tx2/uboot/net.h
index 1fe2e1c..1863f44 100644
--- a/libethdrivers/src/plat/tx2/uboot/net.h
+++ b/libethdrivers/src/plat/tx2/uboot/net.h
@@ -1,7 +1,4 @@
-/*
- * @TAG(OTHER_GPL)
- */
-/* SPDX-License-Identifier: GPL-2.0 */
+/* SPDX-License-Identifier: GPL-2.0-only */
 /*
  *  LiMon Monitor (LiMon) - Network.
  *
diff --git a/libethdrivers/src/plat/tx2/uboot/phy.c b/libethdrivers/src/plat/tx2/uboot/phy.c
index 5f6b95a..8665359 100644
--- a/libethdrivers/src/plat/tx2/uboot/phy.c
+++ b/libethdrivers/src/plat/tx2/uboot/phy.c
@@ -1,10 +1,7 @@
 /*
- * @TAG(OTHER_GPL)
- */
-/*
  * Generic PHY Management code
  *
- * SPDX-License-Identifier: GPL-2.0+
+ * SPDX-License-Identifier: GPL-2.0-or-later
  *
  * Copyright 2011 Freescale Semiconductor, Inc.
  * author Andy Fleming
diff --git a/libethdrivers/src/plat/tx2/uboot/phy.h b/libethdrivers/src/plat/tx2/uboot/phy.h
index 918b27e..3c83260 100644
--- a/libethdrivers/src/plat/tx2/uboot/phy.h
+++ b/libethdrivers/src/plat/tx2/uboot/phy.h
@@ -1,11 +1,8 @@
 /*
- * @TAG(OTHER_GPL)
- */
-/*
  * Copyright 2011 Freescale Semiconductor, Inc.
  *  Andy Fleming <afleming@gmail.com>
  *
- * SPDX-License-Identifier: GPL-2.0+
+ * SPDX-License-Identifier: GPL-2.0-or-later
  *
  * This file pretty much stolen from Linux's mii.h/ethtool.h/phy.h
  */
diff --git a/libethdrivers/src/plat/tx2/uboot/tx2_configs.h b/libethdrivers/src/plat/tx2/uboot/tx2_configs.h
index 5efd2cb..d94573c 100644
--- a/libethdrivers/src/plat/tx2/uboot/tx2_configs.h
+++ b/libethdrivers/src/plat/tx2/uboot/tx2_configs.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2020, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #pragma once
diff --git a/libethdrivers/src/plat/tx2/uboot/wait_bit.h b/libethdrivers/src/plat/tx2/uboot/wait_bit.h
index 6395c5c..968f156 100644
--- a/libethdrivers/src/plat/tx2/uboot/wait_bit.h
+++ b/libethdrivers/src/plat/tx2/uboot/wait_bit.h
@@ -1,7 +1,4 @@
-/*
- * @TAG(OTHER_GPL)
- */
-/* SPDX-License-Identifier: GPL-2.0+ */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
 /*
  * Wait for bit with timeout and ctrlc
  *
diff --git a/libethdrivers/src/plat/tx2/unimplemented.c b/libethdrivers/src/plat/tx2/unimplemented.c
index 7078d16..4d1a483 100644
--- a/libethdrivers/src/plat/tx2/unimplemented.c
+++ b/libethdrivers/src/plat/tx2/unimplemented.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2020, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #include <stdio.h>
diff --git a/libethdrivers/src/plat/tx2/unimplemented.h b/libethdrivers/src/plat/tx2/unimplemented.h
index f484c69..d95112a 100644
--- a/libethdrivers/src/plat/tx2/unimplemented.h
+++ b/libethdrivers/src/plat/tx2/unimplemented.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2020, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #pragma once
diff --git a/libethdrivers/src/plat/zynq7000/io.h b/libethdrivers/src/plat/zynq7000/io.h
index 549b8ea..7439561 100644
--- a/libethdrivers/src/plat/zynq7000/io.h
+++ b/libethdrivers/src/plat/zynq7000/io.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #ifndef _ETHDRIVER_ZYNQ7000_IO_H_
diff --git a/libethdrivers/src/plat/zynq7000/uboot/bitops.h b/libethdrivers/src/plat/zynq7000/uboot/bitops.h
index d620c06..13217e4 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/bitops.h
+++ b/libethdrivers/src/plat/zynq7000/uboot/bitops.h
@@ -1,5 +1,6 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
+ * Copyright Linux
  */
 
 #ifndef _LINUX_BITOPS_H
diff --git a/libethdrivers/src/plat/zynq7000/uboot/common.h b/libethdrivers/src/plat/zynq7000/uboot/common.h
index 6e01467..cd29243 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/common.h
+++ b/libethdrivers/src/plat/zynq7000/uboot/common.h
@@ -1,5 +1,5 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 /*
diff --git a/libethdrivers/src/plat/zynq7000/uboot/config.h b/libethdrivers/src/plat/zynq7000/uboot/config.h
index e2bf9f6..d111a28 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/config.h
+++ b/libethdrivers/src/plat/zynq7000/uboot/config.h
@@ -1,5 +1,6 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
+ * Copyright Dornerworks
  */
 
 #include "zynq_zc70x.h"
diff --git a/libethdrivers/src/plat/zynq7000/uboot/err.h b/libethdrivers/src/plat/zynq7000/uboot/err.h
index e73470a..49d35b0 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/err.h
+++ b/libethdrivers/src/plat/zynq7000/uboot/err.h
@@ -1,3 +1,8 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ * Copyright Linux
+ */
+
 #ifndef _LINUX_ERR_H
 #define _LINUX_ERR_H
 
diff --git a/libethdrivers/src/plat/zynq7000/uboot/ethtool.h b/libethdrivers/src/plat/zynq7000/uboot/ethtool.h
index 6c4c449..faf68b9 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/ethtool.h
+++ b/libethdrivers/src/plat/zynq7000/uboot/ethtool.h
@@ -1,5 +1,5 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 /*
diff --git a/libethdrivers/src/plat/zynq7000/uboot/list.h b/libethdrivers/src/plat/zynq7000/uboot/list.h
index 8e3cc17..f007739 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/list.h
+++ b/libethdrivers/src/plat/zynq7000/uboot/list.h
@@ -1,3 +1,8 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-only
+ * Copyright Linux
+ */
+
 #ifndef _LINUX_LIST_H
 #define _LINUX_LIST_H
 
diff --git a/libethdrivers/src/plat/zynq7000/uboot/marvell.c b/libethdrivers/src/plat/zynq7000/uboot/marvell.c
index 20a7a9a..dff3062 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/marvell.c
+++ b/libethdrivers/src/plat/zynq7000/uboot/marvell.c
@@ -1,11 +1,12 @@
 /*
  * Marvell PHY drivers
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier: GPL-2.0-or-later
  *
  * Copyright 2010-2011 Freescale Semiconductor, Inc.
  * author Andy Fleming
  */
+
 #include "config.h"
 #include "common.h"
 #include "phy.h"
diff --git a/libethdrivers/src/plat/zynq7000/uboot/mdio.h b/libethdrivers/src/plat/zynq7000/uboot/mdio.h
index f543908..97fe2ca 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/mdio.h
+++ b/libethdrivers/src/plat/zynq7000/uboot/mdio.h
@@ -1,5 +1,5 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 /*
diff --git a/libethdrivers/src/plat/zynq7000/uboot/mii.h b/libethdrivers/src/plat/zynq7000/uboot/mii.h
index 5a4ff64..5e8adf2 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/mii.h
+++ b/libethdrivers/src/plat/zynq7000/uboot/mii.h
@@ -1,5 +1,5 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 /*
diff --git a/libethdrivers/src/plat/zynq7000/uboot/miiphy.h b/libethdrivers/src/plat/zynq7000/uboot/miiphy.h
index 48511e5..4f3e5d4 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/miiphy.h
+++ b/libethdrivers/src/plat/zynq7000/uboot/miiphy.h
@@ -1,5 +1,5 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 /*----------------------------------------------------------------------------+
diff --git a/libethdrivers/src/plat/zynq7000/uboot/miiphyutil.c b/libethdrivers/src/plat/zynq7000/uboot/miiphyutil.c
index dbb7305..cfb25ac 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/miiphyutil.c
+++ b/libethdrivers/src/plat/zynq7000/uboot/miiphyutil.c
@@ -1,5 +1,5 @@
 /*
- * @TAG(OTHER_GPL)
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 /*
diff --git a/libethdrivers/src/plat/zynq7000/uboot/net.h b/libethdrivers/src/plat/zynq7000/uboot/net.h
index 3602dba..a8c3cf2 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/net.h
+++ b/libethdrivers/src/plat/zynq7000/uboot/net.h
@@ -3,7 +3,7 @@
  *
  *	Copyright 1994 - 2000 Neil Russell.
  *	(See License)
- *	SPDX-License-Identifier:	GPL-2.0
+ *	SPDX-License-Identifier: GPL-2.0-only
  *
  * History
  *	9/16/00	  bor  adapted to TQM823L/STK8xxL board, RARP/TFTP boot added
diff --git a/libethdrivers/src/plat/zynq7000/uboot/netdev.h b/libethdrivers/src/plat/zynq7000/uboot/netdev.h
index 650b617..fcf04ce 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/netdev.h
+++ b/libethdrivers/src/plat/zynq7000/uboot/netdev.h
@@ -2,7 +2,7 @@
  * (C) Copyright 2008
  * Benjamin Warren, biggerbadderben@gmail.com
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 /*
diff --git a/libethdrivers/src/plat/zynq7000/uboot/phy.c b/libethdrivers/src/plat/zynq7000/uboot/phy.c
index 82db665..cefb257 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/phy.c
+++ b/libethdrivers/src/plat/zynq7000/uboot/phy.c
@@ -1,7 +1,7 @@
 /*
  * Generic PHY Management code
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier: GPL-2.0-or-later
  *
  * Copyright 2011 Freescale Semiconductor, Inc.
  * author Andy Fleming
diff --git a/libethdrivers/src/plat/zynq7000/uboot/phy.h b/libethdrivers/src/plat/zynq7000/uboot/phy.h
index e8dc854..35aa711 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/phy.h
+++ b/libethdrivers/src/plat/zynq7000/uboot/phy.h
@@ -2,7 +2,7 @@
  * Copyright 2011 Freescale Semiconductor, Inc.
  *	Andy Fleming <afleming@gmail.com>
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier: GPL-2.0-or-later
  *
  * This file pretty much stolen from Linux's mii.h/ethtool.h/phy.h
  */
diff --git a/libethdrivers/src/plat/zynq7000/uboot/system.h b/libethdrivers/src/plat/zynq7000/uboot/system.h
index e4d6ee4..06050a6 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/system.h
+++ b/libethdrivers/src/plat/zynq7000/uboot/system.h
@@ -1,3 +1,8 @@
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ */
+
 #ifndef __ASM_ARM_SYSTEM_H
 #define __ASM_ARM_SYSTEM_H
 
diff --git a/libethdrivers/src/plat/zynq7000/uboot/zynq-common.h b/libethdrivers/src/plat/zynq7000/uboot/zynq-common.h
index f532534..9bfb813 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/zynq-common.h
+++ b/libethdrivers/src/plat/zynq7000/uboot/zynq-common.h
@@ -4,7 +4,7 @@
  *
  * Common configuration options for all Zynq boards.
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 #ifndef __CONFIG_ZYNQ_COMMON_H
diff --git a/libethdrivers/src/plat/zynq7000/uboot/zynq_gem.c b/libethdrivers/src/plat/zynq7000/uboot/zynq_gem.c
index 58c2c3f..0c96a1f 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/zynq_gem.c
+++ b/libethdrivers/src/plat/zynq7000/uboot/zynq_gem.c
@@ -9,7 +9,7 @@
  * Based on Xilinx gmac driver:
  * (C) Copyright 2011 Xilinx
  *
- * SPDX-License-Identifier: GPL-2.0+
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 #include "common.h"
@@ -333,7 +333,7 @@
     return 0;
 }
 
-int zynq_gem_start_send(struct eth_device *dev, uint32_t txbase)
+int zynq_gem_start_send(struct eth_device *dev)
 {
     struct zynq_gem_regs *regs = (struct zynq_gem_regs *)dev->iobase;
 
@@ -343,8 +343,6 @@
         status = readl(&regs->txsr);
     }
 
-    writel(txbase, &regs->txqbase);
-
     /* Start transmit */
     setbits_le32(&regs->nwctrl, ZYNQ_GEM_NWCTRL_STARTTX_MASK);
 
diff --git a/libethdrivers/src/plat/zynq7000/uboot/zynq_zc70x.h b/libethdrivers/src/plat/zynq7000/uboot/zynq_zc70x.h
index 8180903..56fd2ca 100644
--- a/libethdrivers/src/plat/zynq7000/uboot/zynq_zc70x.h
+++ b/libethdrivers/src/plat/zynq7000/uboot/zynq_zc70x.h
@@ -4,7 +4,7 @@
  * Configuration settings for the Xilinx Zynq ZC702 and ZC706 boards
  * See zynq-common.h for Zynq common configs
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
 
 #ifndef __CONFIG_ZYNQ_ZC70X_H
diff --git a/libethdrivers/src/plat/zynq7000/unimplemented.c b/libethdrivers/src/plat/zynq7000/unimplemented.c
index 8ef7b5d..be3a84a 100644
--- a/libethdrivers/src/plat/zynq7000/unimplemented.c
+++ b/libethdrivers/src/plat/zynq7000/unimplemented.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #include <stdio.h>
diff --git a/libethdrivers/src/plat/zynq7000/unimplemented.h b/libethdrivers/src/plat/zynq7000/unimplemented.h
index 4ad0bc3..8a9238f 100644
--- a/libethdrivers/src/plat/zynq7000/unimplemented.h
+++ b/libethdrivers/src/plat/zynq7000/unimplemented.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #ifndef __UNIMPLEMENTED_H__
diff --git a/libethdrivers/src/plat/zynq7000/zynq7000.c b/libethdrivers/src/plat/zynq7000/zynq7000.c
index 869a737..0986423 100644
--- a/libethdrivers/src/plat/zynq7000/zynq7000.c
+++ b/libethdrivers/src/plat/zynq7000/zynq7000.c
@@ -1,14 +1,8 @@
 /*
  * Copyright 2017, DornerWorks, Ltd.
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #include "unimplemented.h"
@@ -129,20 +123,24 @@
 
     dev->rdt = dev->rdh = dev->tdt = dev->tdh = 0;
 
-    /* zero both rings */
+    /* initialise both rings */
     for (unsigned int i = 0; i < dev->tx_size; i++) {
         dev->tx_ring[i] = (struct emac_bd) {
             .addr = 0,
+            .status = ZYNQ_GEM_TXBUF_USED_MASK
+        };
+    }
+
+    dev->tx_ring[dev->tx_size - 1].status |= ZYNQ_GEM_TXBUF_WRAP_MASK;
+
+    for (unsigned int i = 0; i < dev->rx_size; i++) {
+        dev->rx_ring[i] = (struct emac_bd) {
+            .addr = ZYNQ_GEM_RXBUF_NEW_MASK,
             .status = 0
         };
     }
 
-    for (unsigned int i = 0; i < dev->rx_size; i++) {
-        dev->rx_ring[i] = (struct emac_bd) {
-            .addr = 0,
-            .status = 0
-        };
-    }
+    dev->rx_ring[dev->rx_size - 1].addr |= ZYNQ_GEM_RXBUF_WRAP_MASK;
 
     __sync_synchronize();
 
@@ -161,20 +159,20 @@
         void *cookie = NULL;
         int next_rdt = (dev->rdt + 1) % dev->rx_size;
 
-        uintptr_t phys = driver->i_cb.allocate_rx_buf ? driver->i_cb.allocate_rx_buf(driver->cb_cookie, BUF_SIZE, &cookie): 0;
+        uintptr_t phys = driver->i_cb.allocate_rx_buf ? driver->i_cb.allocate_rx_buf(driver->cb_cookie, BUF_SIZE, &cookie) : 0;
         if (!phys) {
             break;
         }
 
         dev->rx_cookies[dev->rdt] = cookie;
 
-        /* If this is the last descriptor in the ring, set the wrap bit of the address (bit 1)
-         *   so the controller knows to loop back around
-         */
         dev->rx_ring[dev->rdt].status = 0;
 
-        uint32_t mask = (next_rdt == 0 ? ZYNQ_GEM_RXBUF_WRAP_MASK : 0);
-        dev->rx_ring[dev->rdt].addr = (phys & ZYNQ_GEM_RXBUF_ADD_MASK) | mask;
+        /* Remove the used bit so the controller knows this descriptor is
+         * available to be written to */
+        dev->rx_ring[dev->rdt].addr &= ~(ZYNQ_GEM_RXBUF_NEW_MASK | ZYNQ_GEM_RXBUF_ADD_MASK);
+
+        dev->rx_ring[dev->rdt].addr |= (phys & ZYNQ_GEM_RXBUF_ADD_MASK);
 
         __sync_synchronize();
 
@@ -234,10 +232,13 @@
         for (i = 0; i < dev->tx_lengths[dev->tdh]; i++) {
             int ring_pos = (i + dev->tdh) % dev->tx_size;
 
-            if (!(dev->tx_ring[ring_pos].status & ZYNQ_GEM_TXBUF_USED_MASK)) {
+            if (i == 0 && !(dev->tx_ring[ring_pos].status & ZYNQ_GEM_TXBUF_USED_MASK)) {
                 /* not all parts complete */
                 return;
             }
+
+            dev->tx_ring[ring_pos].status &= (ZYNQ_GEM_TXBUF_USED_MASK | ZYNQ_GEM_TXBUF_WRAP_MASK);
+            dev->tx_ring[ring_pos].status |= ZYNQ_GEM_TXBUF_USED_MASK;
         }
 
         /* do not let memory loads happen before our checking of the descriptor write back */
@@ -253,8 +254,7 @@
     }
 
     if (dev->tdh != dev->tdt) {
-        uintptr_t txbase = dev->tx_ring_phys + (uintptr_t)(dev->tdh * sizeof(struct emac_bd));
-        zynq_gem_start_send(dev->eth_dev, txbase);
+        zynq_gem_start_send(dev->eth_dev);
     }
 }
 
@@ -264,20 +264,20 @@
     struct zynq_gem_regs *regs = (struct zynq_gem_regs *)eth_data->eth_dev->iobase;
 
     // Clear Interrupts
-    u32 val = readl(&regs->isr);
-    writel(val, &regs->isr);
+    u32 isr = readl(&regs->isr);
+    writel(isr, &regs->isr);
 
-    if (val & ZYNQ_GEM_IXR_TXCOMPLETE) {
+    if (isr & ZYNQ_GEM_IXR_TXCOMPLETE) {
         /* Clear TX Status register */
-        val = readl(&regs->txsr);
+        u32 val = readl(&regs->txsr);
         writel(val, &regs->txsr);
 
         complete_tx(driver);
     }
 
-    if (val & ZYNQ_GEM_IXR_FRAMERX) {
+    if (isr & ZYNQ_GEM_IXR_FRAMERX) {
         /* Clear RX Status register */
-        val = readl(&regs->rxsr);
+        u32 val = readl(&regs->rxsr);
         writel(val, &regs->rxsr);
 
         complete_rx(driver);
@@ -328,29 +328,16 @@
     unsigned int i;
     __sync_synchronize();
 
-    uintptr_t txbase = dev->tx_ring_phys + (uintptr_t)(dev->tdt * sizeof(struct emac_bd));
-
     for (i = 0; i < num; i++) {
-
         unsigned int ring = (dev->tdt + i) % dev->tx_size;
         dev->tx_ring[ring].addr = phys[i];
-        dev->tx_ring[ring].status = (len[i] & ZYNQ_GEM_TXBUF_FRMLEN_MASK) |
-                                    ZYNQ_GEM_TXBUF_LAST_MASK;
-
-        __sync_synchronize();
+        dev->tx_ring[ring].status &= ~(ZYNQ_GEM_TXBUF_USED_MASK | ZYNQ_GEM_TXBUF_FRMLEN_MASK | ZYNQ_GEM_TXBUF_LAST_MASK);
+        dev->tx_ring[ring].status |= (len[i] & ZYNQ_GEM_TXBUF_FRMLEN_MASK);
+        if (i == (num - 1)) {
+            dev->tx_ring[ring].status |= ZYNQ_GEM_TXBUF_LAST_MASK;
+        }
     }
 
-    unsigned int ring = (dev->tdt + i) % dev->tx_size;
-
-    /* Dummy descriptor to mark it as the last in descriptor chain */
-    dev->tx_ring[ring].addr = 0x0;
-    dev->tx_ring[ring].status = ZYNQ_GEM_TXBUF_WRAP_MASK |
-                                ZYNQ_GEM_TXBUF_LAST_MASK |
-                                ZYNQ_GEM_TXBUF_USED_MASK;
-
-    /* Increment num by 1 to account for the added last byte */
-    num += 1;
-
     dev->tx_cookies[dev->tdt] = cookie;
     dev->tx_lengths[dev->tdt] = num;
     dev->tdt = (dev->tdt + num) % dev->tx_size;
@@ -358,7 +345,7 @@
 
     __sync_synchronize();
 
-    zynq_gem_start_send(dev->eth_dev, txbase);
+    zynq_gem_start_send(dev->eth_dev);
 
     return ETHIF_TX_ENQUEUED;
 }
@@ -407,8 +394,8 @@
     }
     uint32_t base_addr = (uint32_t)plat_config->buffer_addr;
 
-    eth_data->tx_size = CONFIG_LIB_ETHDRIVER_RX_DESC_COUNT;
-    eth_data->rx_size = CONFIG_LIB_ETHDRIVER_TX_DESC_COUNT;
+    eth_data->tx_size = CONFIG_LIB_ETHDRIVER_TX_DESC_COUNT;
+    eth_data->rx_size = CONFIG_LIB_ETHDRIVER_RX_DESC_COUNT;
     eth_driver->eth_data = eth_data;
     eth_driver->dma_alignment = ARCH_DMA_MINALIGN;
     eth_driver->i_fn = iface_fns;
diff --git a/libethdrivers/src/plat/zynq7000/zynq_gem.h b/libethdrivers/src/plat/zynq7000/zynq_gem.h
index a458687..18672ef 100644
--- a/libethdrivers/src/plat/zynq7000/zynq_gem.h
+++ b/libethdrivers/src/plat/zynq7000/zynq_gem.h
@@ -9,72 +9,71 @@
  * Based on Xilinx gmac driver:
  * (C) Copyright 2011 Xilinx
  *
- * SPDX-License-Identifier:	GPL-2.0+
+ * SPDX-License-Identifier: GPL-2.0-or-later
  */
-#ifndef _ZYNQ_GEM_H
-#define _ZYNQ_GEM_H
+#pragma once
 
 #include <platsupport/io.h>
 
 /* Bit/mask specification */
-#define ZYNQ_GEM_PHYMNTNC_OP_MASK	0x40020000 /* operation mask bits */
-#define ZYNQ_GEM_PHYMNTNC_OP_R_MASK	0x20000000 /* read operation */
-#define ZYNQ_GEM_PHYMNTNC_OP_W_MASK	0x10000000 /* write operation */
-#define ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK	23 /* Shift bits for PHYAD */
-#define ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK	18 /* Shift bits for PHREG */
+#define ZYNQ_GEM_PHYMNTNC_OP_MASK   0x40020000 /* operation mask bits */
+#define ZYNQ_GEM_PHYMNTNC_OP_R_MASK 0x20000000 /* read operation */
+#define ZYNQ_GEM_PHYMNTNC_OP_W_MASK 0x10000000 /* write operation */
+#define ZYNQ_GEM_PHYMNTNC_PHYAD_SHIFT_MASK  23 /* Shift bits for PHYAD */
+#define ZYNQ_GEM_PHYMNTNC_PHREG_SHIFT_MASK  18 /* Shift bits for PHREG */
 
-#define ZYNQ_GEM_RXBUF_EOF_MASK		0x00008000 /* End of frame. */
-#define ZYNQ_GEM_RXBUF_SOF_MASK		0x00004000 /* Start of frame. */
-#define ZYNQ_GEM_RXBUF_LEN_MASK		0x00003FFF /* Mask for length field */
+#define ZYNQ_GEM_RXBUF_EOF_MASK     0x00008000 /* End of frame. */
+#define ZYNQ_GEM_RXBUF_SOF_MASK     0x00004000 /* Start of frame. */
+#define ZYNQ_GEM_RXBUF_LEN_MASK     0x00003FFF /* Mask for length field */
 
-#define ZYNQ_GEM_RXBUF_WRAP_MASK	0x00000002 /* Wrap bit, last BD */
-#define ZYNQ_GEM_RXBUF_NEW_MASK		0x00000001 /* Used bit.. */
-#define ZYNQ_GEM_RXBUF_ADD_MASK		0xFFFFFFFC /* Mask for address */
+#define ZYNQ_GEM_RXBUF_WRAP_MASK    0x00000002 /* Wrap bit, last BD */
+#define ZYNQ_GEM_RXBUF_NEW_MASK     0x00000001 /* Used bit.. */
+#define ZYNQ_GEM_RXBUF_ADD_MASK     0xFFFFFFFC /* Mask for address */
 
 /* Wrap bit, last descriptor */
-#define ZYNQ_GEM_TXBUF_WRAP_MASK	0x40000000
-#define ZYNQ_GEM_TXBUF_LAST_MASK	0x00008000 /* Last buffer */
-#define ZYNQ_GEM_TXBUF_USED_MASK	0x80000000 /* Used by Hw */
+#define ZYNQ_GEM_TXBUF_WRAP_MASK    0x40000000
+#define ZYNQ_GEM_TXBUF_LAST_MASK    0x00008000 /* Last buffer */
+#define ZYNQ_GEM_TXBUF_USED_MASK    0x80000000 /* Used by Hw */
 
-#define ZYNQ_GEM_NWCTRL_TXEN_MASK	0x00000008 /* Enable transmit */
-#define ZYNQ_GEM_NWCTRL_RXEN_MASK	0x00000004 /* Enable receive */
-#define ZYNQ_GEM_NWCTRL_MDEN_MASK	0x00000010 /* Enable MDIO port */
-#define ZYNQ_GEM_NWCTRL_STARTTX_MASK	0x00000200 /* Start tx (tx_go) */
+#define ZYNQ_GEM_NWCTRL_TXEN_MASK   0x00000008 /* Enable transmit */
+#define ZYNQ_GEM_NWCTRL_RXEN_MASK   0x00000004 /* Enable receive */
+#define ZYNQ_GEM_NWCTRL_MDEN_MASK   0x00000010 /* Enable MDIO port */
+#define ZYNQ_GEM_NWCTRL_STARTTX_MASK    0x00000200 /* Start tx (tx_go) */
 
-#define ZYNQ_GEM_NWCFG_SPEED100		0x000000001 /* 100 Mbps operation */
-#define ZYNQ_GEM_NWCFG_SPEED1000	0x000000400 /* 1Gbps operation */
-#define ZYNQ_GEM_NWCFG_FDEN		0x000000002 /* Full Duplex mode */
-#define ZYNQ_GEM_NWCFG_FSREM		0x000020000 /* FCS removal */
-#define ZYNQ_GEM_NWCFG_MDCCLKDIV	0x0000c0000 /* Div pclk by 48, max 120MHz */
-#define ZYNQ_GEM_NWCFG_COPY_ALL 	0x000000010 /* Promiscuous Mode */
+#define ZYNQ_GEM_NWCFG_SPEED100     0x000000001 /* 100 Mbps operation */
+#define ZYNQ_GEM_NWCFG_SPEED1000    0x000000400 /* 1Gbps operation */
+#define ZYNQ_GEM_NWCFG_FDEN     0x000000002 /* Full Duplex mode */
+#define ZYNQ_GEM_NWCFG_FSREM        0x000020000 /* FCS removal */
+#define ZYNQ_GEM_NWCFG_MDCCLKDIV    0x0000c0000 /* Div pclk by 48, max 120MHz */
+#define ZYNQ_GEM_NWCFG_COPY_ALL     0x000000010 /* Promiscuous Mode */
 
 #ifdef CONFIG_ARM64
-# define ZYNQ_GEM_DBUS_WIDTH	(1 << 21) /* 64 bit bus */
+# define ZYNQ_GEM_DBUS_WIDTH    (1 << 21) /* 64 bit bus */
 #else
-# define ZYNQ_GEM_DBUS_WIDTH	(0 << 21) /* 32 bit bus */
+# define ZYNQ_GEM_DBUS_WIDTH    (0 << 21) /* 32 bit bus */
 #endif
 
-#define ZYNQ_GEM_NWCFG_INIT		(ZYNQ_GEM_DBUS_WIDTH | \
-					ZYNQ_GEM_NWCFG_FDEN | \
-					ZYNQ_GEM_NWCFG_FSREM | \
-					ZYNQ_GEM_NWCFG_MDCCLKDIV)
+#define ZYNQ_GEM_NWCFG_INIT     (ZYNQ_GEM_DBUS_WIDTH | \
+                    ZYNQ_GEM_NWCFG_FDEN | \
+                    ZYNQ_GEM_NWCFG_FSREM | \
+                    ZYNQ_GEM_NWCFG_MDCCLKDIV)
 
-#define ZYNQ_GEM_NWSR_MDIOIDLE_MASK	0x00000004 /* PHY management idle */
+#define ZYNQ_GEM_NWSR_MDIOIDLE_MASK 0x00000004 /* PHY management idle */
 
-#define ZYNQ_GEM_DMACR_BLENGTH		0x00000004 /* INCR4 AHB bursts */
+#define ZYNQ_GEM_DMACR_BLENGTH      0x00000004 /* INCR4 AHB bursts */
 /* Use full configured addressable space (8 Kb) */
-#define ZYNQ_GEM_DMACR_RXSIZE		0x00000300
+#define ZYNQ_GEM_DMACR_RXSIZE       0x00000300
 /* Use full configured addressable space (4 Kb) */
-#define ZYNQ_GEM_DMACR_TXSIZE		0x00000400
+#define ZYNQ_GEM_DMACR_TXSIZE       0x00000400
 /* Set with binary 00011000 to use 1536 byte(1*max length frame/buffer) */
-#define ZYNQ_GEM_DMACR_RXBUF		0x00180000
+#define ZYNQ_GEM_DMACR_RXBUF        0x00180000
 
-#define ZYNQ_GEM_DMACR_INIT		(ZYNQ_GEM_DMACR_BLENGTH | \
-					ZYNQ_GEM_DMACR_RXSIZE | \
-					ZYNQ_GEM_DMACR_TXSIZE | \
-					ZYNQ_GEM_DMACR_RXBUF)
+#define ZYNQ_GEM_DMACR_INIT     (ZYNQ_GEM_DMACR_BLENGTH | \
+                    ZYNQ_GEM_DMACR_RXSIZE | \
+                    ZYNQ_GEM_DMACR_TXSIZE | \
+                    ZYNQ_GEM_DMACR_RXBUF)
 
-#define ZYNQ_GEM_TSR_DONE		0x00000020 /* Tx done mask */
+#define ZYNQ_GEM_TSR_DONE       0x00000020 /* Tx done mask */
 
 /* Use MII register 1 (MII status register) to detect PHY */
 #define PHY_DETECT_REG  1
@@ -88,14 +87,14 @@
 #define PHY_DETECT_MASK 0x1808
 
 /* TX BD status masks */
-#define ZYNQ_GEM_TXBUF_FRMLEN_MASK	0x000007ff
-#define ZYNQ_GEM_TXBUF_EXHAUSTED	0x08000000
-#define ZYNQ_GEM_TXBUF_UNDERRUN		0x10000000
+#define ZYNQ_GEM_TXBUF_FRMLEN_MASK  0x000007ff
+#define ZYNQ_GEM_TXBUF_EXHAUSTED    0x08000000
+#define ZYNQ_GEM_TXBUF_UNDERRUN     0x10000000
 
 /* Clock frequencies for different speeds */
-#define ZYNQ_GEM_FREQUENCY_10	2500000UL
-#define ZYNQ_GEM_FREQUENCY_100	25000000UL
-#define ZYNQ_GEM_FREQUENCY_1000	125000000UL
+#define ZYNQ_GEM_FREQUENCY_10   2500000UL
+#define ZYNQ_GEM_FREQUENCY_100  25000000UL
+#define ZYNQ_GEM_FREQUENCY_1000 125000000UL
 
 #define ZYNQ_GEM_IXR_FRAMERX (1 << 1)
 #define ZYNQ_GEM_IXR_TXCOMPLETE (1 << 7)
@@ -104,63 +103,61 @@
 
 /* Device registers */
 struct zynq_gem_regs {
-	u32 nwctrl; /* 0x0 - Network Control reg */
-	u32 nwcfg; /* 0x4 - Network Config reg */
-	u32 nwsr; /* 0x8 - Network Status reg */
-	u32 reserved1;
-	u32 dmacr; /* 0x10 - DMA Control reg */
-	u32 txsr; /* 0x14 - TX Status reg */
-	u32 rxqbase; /* 0x18 - RX Q Base address reg */
-	u32 txqbase; /* 0x1c - TX Q Base address reg */
-	u32 rxsr; /* 0x20 - RX Status reg */
-	u32 isr;
-	u32 ier;
-	u32 idr; /* 0x2c - Interrupt Disable reg */
-	u32 reserved3;
-	u32 phymntnc; /* 0x34 - Phy Maintaince reg */
-	u32 reserved4[18];
-	u32 hashl; /* 0x80 - Hash Low address reg */
-	u32 hashh; /* 0x84 - Hash High address reg */
-#define LADDR_LOW	0
-#define LADDR_HIGH	1
-	u32 laddr[4][LADDR_HIGH + 1]; /* 0x8c - Specific1 addr low/high reg */
-	u32 match[4]; /* 0xa8 - Type ID1 Match reg */
-	u32 reserved6[18];
-#define STAT_SIZE	44
-	u32 stat[STAT_SIZE]; /* 0x100 - Octects transmitted Low reg */
-	u32 reserved7[164];
-	u32 transmit_q1_ptr; /* 0x440 - Transmit priority queue 1 */
-	u32 reserved8[15];
-	u32 receive_q1_ptr; /* 0x480 - Receive priority queue 1 */
+    u32 nwctrl; /* 0x0 - Network Control reg */
+    u32 nwcfg; /* 0x4 - Network Config reg */
+    u32 nwsr; /* 0x8 - Network Status reg */
+    u32 reserved1;
+    u32 dmacr; /* 0x10 - DMA Control reg */
+    u32 txsr; /* 0x14 - TX Status reg */
+    u32 rxqbase; /* 0x18 - RX Q Base address reg */
+    u32 txqbase; /* 0x1c - TX Q Base address reg */
+    u32 rxsr; /* 0x20 - RX Status reg */
+    u32 isr;
+    u32 ier;
+    u32 idr; /* 0x2c - Interrupt Disable reg */
+    u32 reserved3;
+    u32 phymntnc; /* 0x34 - Phy Maintaince reg */
+    u32 reserved4[18];
+    u32 hashl; /* 0x80 - Hash Low address reg */
+    u32 hashh; /* 0x84 - Hash High address reg */
+#define LADDR_LOW   0
+#define LADDR_HIGH  1
+    u32 laddr[4][LADDR_HIGH + 1]; /* 0x8c - Specific1 addr low/high reg */
+    u32 match[4]; /* 0xa8 - Type ID1 Match reg */
+    u32 reserved6[18];
+#define STAT_SIZE   44
+    u32 stat[STAT_SIZE]; /* 0x100 - Octects transmitted Low reg */
+    u32 reserved7[164];
+    u32 transmit_q1_ptr; /* 0x440 - Transmit priority queue 1 */
+    u32 reserved8[15];
+    u32 receive_q1_ptr; /* 0x480 - Receive priority queue 1 */
 };
 
 /* BD descriptors */
 struct emac_bd {
-	u32 addr; /* Next descriptor pointer */
-	u32 status;
+    u32 addr; /* Next descriptor pointer */
+    u32 status;
 };
 
 #define RX_BUF 32
 /* Page table entries are set to 1MB, or multiples of 1MB
  * (not < 1MB). driver uses less bd's so use 1MB bdspace.
  */
-#define BD_SPACE	0x100000
+#define BD_SPACE    0x100000
 /* BD separation space */
-#define BD_SEPRN_SPACE	(RX_BUF * sizeof(struct emac_bd))
+#define BD_SEPRN_SPACE  (RX_BUF * sizeof(struct emac_bd))
 
 /* Setup the first free TX descriptor */
-#define TX_FREE_DESC	2
+#define TX_FREE_DESC    2
 
 struct eth_device *zynq_gem_initialize(phys_addr_t base_addr,
-			int phy_addr, u32 emio);
+                                       int phy_addr, u32 emio);
 int zynq_gem_init(struct eth_device *dev);
 int zynq_gem_setup_mac(struct eth_device *dev);
-int zynq_gem_start_send(struct eth_device *dev, uint32_t txbase);
+int zynq_gem_start_send(struct eth_device *dev);
 int zynq_gem_recv_enabled(struct eth_device *dev);
 void zynq_gem_recv_enable(struct eth_device *dev);
 void zynq_gem_halt(struct eth_device *dev);
 void zynq_set_gem_ioops(ps_io_ops_t *io_ops);
 void zynq_gem_prom_enable(struct eth_device *dev);
 void zynq_gem_prom_disable(struct eth_device *dev);
-
-#endif
diff --git a/libethdrivers/src/plat/pc99/virtio_pci.c b/libethdrivers/src/virtio_pci.c
similarity index 79%
rename from libethdrivers/src/plat/pc99/virtio_pci.c
rename to libethdrivers/src/virtio_pci.c
index 9423976..dabf0bb 100644
--- a/libethdrivers/src/plat/pc99/virtio_pci.c
+++ b/libethdrivers/src/virtio_pci.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the GNU General Public License version 2. Note that NO WARRANTY is provided.
- * See "LICENSE_GPLv2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 
 #include <ethdrivers/virtio_pci.h>
@@ -61,63 +55,75 @@
     uintptr_t virtio_net_hdr_phys;
 } virtio_dev_t;
 
-static uint8_t read_reg8(virtio_dev_t *dev, uint16_t port) {
+static uint8_t read_reg8(virtio_dev_t *dev, uint16_t port)
+{
     uint32_t val;
     ps_io_port_in(&dev->ioops, dev->io_base + port, 1, &val);
     return (uint8_t)val;
 }
 
-static uint16_t read_reg16(virtio_dev_t *dev, uint16_t port) {
+static uint16_t read_reg16(virtio_dev_t *dev, uint16_t port)
+{
     uint32_t val;
     ps_io_port_in(&dev->ioops, dev->io_base + port, 2, &val);
     return (uint16_t)val;
 }
 
-static uint32_t read_reg32(virtio_dev_t *dev, uint16_t port) {
+static uint32_t read_reg32(virtio_dev_t *dev, uint16_t port)
+{
     uint32_t val;
     ps_io_port_in(&dev->ioops, dev->io_base + port, 4, &val);
     return val;
 }
 
-static void write_reg8(virtio_dev_t *dev, uint16_t port, uint8_t val) {
+static void write_reg8(virtio_dev_t *dev, uint16_t port, uint8_t val)
+{
     ps_io_port_out(&dev->ioops, dev->io_base + port, 1, val);
 }
 
-static void write_reg16(virtio_dev_t *dev, uint16_t port, uint16_t val) {
+static void write_reg16(virtio_dev_t *dev, uint16_t port, uint16_t val)
+{
     ps_io_port_out(&dev->ioops, dev->io_base + port, 2, val);
 }
 
-static void write_reg32(virtio_dev_t *dev, uint16_t port, uint32_t val) {
+static void write_reg32(virtio_dev_t *dev, uint16_t port, uint32_t val)
+{
     ps_io_port_out(&dev->ioops, dev->io_base + port, 4, val);
 }
 
-static void set_status(virtio_dev_t *dev, uint8_t status) {
+static void set_status(virtio_dev_t *dev, uint8_t status)
+{
     write_reg8(dev, VIRTIO_PCI_STATUS, status);
 }
 
-static uint8_t get_status(virtio_dev_t *dev) {
+static uint8_t get_status(virtio_dev_t *dev)
+{
     return read_reg8(dev, VIRTIO_PCI_STATUS);
 }
 
-static void add_status(virtio_dev_t *dev, uint8_t status) {
+static void add_status(virtio_dev_t *dev, uint8_t status)
+{
     write_reg8(dev, VIRTIO_PCI_STATUS, get_status(dev) | status);
 }
 
-static uint32_t get_features(virtio_dev_t *dev) {
+static uint32_t get_features(virtio_dev_t *dev)
+{
     return read_reg32(dev, VIRTIO_PCI_HOST_FEATURES);
 }
 
-static void set_features(virtio_dev_t *dev, uint32_t features) {
+static void set_features(virtio_dev_t *dev, uint32_t features)
+{
     write_reg32(dev, VIRTIO_PCI_GUEST_FEATURES, features);
 }
 
-static void free_desc_ring(virtio_dev_t *dev, ps_dma_man_t *dma_man) {
+static void free_desc_ring(virtio_dev_t *dev, ps_dma_man_t *dma_man)
+{
     if (dev->rx_ring.desc) {
-        dma_unpin_free(dma_man, (void*)dev->rx_ring.desc, vring_size(dev->rx_size, VIRTIO_PCI_VRING_ALIGN));
+        dma_unpin_free(dma_man, (void *)dev->rx_ring.desc, vring_size(dev->rx_size, VIRTIO_PCI_VRING_ALIGN));
         dev->rx_ring.desc = NULL;
     }
     if (dev->tx_ring.desc) {
-        dma_unpin_free(dma_man, (void*)dev->tx_ring.desc, vring_size(dev->tx_size, VIRTIO_PCI_VRING_ALIGN));
+        dma_unpin_free(dma_man, (void *)dev->tx_ring.desc, vring_size(dev->tx_size, VIRTIO_PCI_VRING_ALIGN));
         dev->tx_ring.desc = NULL;
     }
     if (dev->rx_cookies) {
@@ -134,29 +140,32 @@
     }
 }
 
-static int initialize_desc_ring(virtio_dev_t *dev, ps_dma_man_t *dma_man) {
-    dma_addr_t rx_ring = dma_alloc_pin(dma_man, vring_size(dev->rx_size, VIRTIO_PCI_VRING_ALIGN), 1, VIRTIO_PCI_VRING_ALIGN);
+static int initialize_desc_ring(virtio_dev_t *dev, ps_dma_man_t *dma_man)
+{
+    dma_addr_t rx_ring = dma_alloc_pin(dma_man, vring_size(dev->rx_size, VIRTIO_PCI_VRING_ALIGN), 1,
+                                       VIRTIO_PCI_VRING_ALIGN);
     if (!rx_ring.phys) {
-        LOG_ERROR("Failed to allocate rx_ring");
+        ZF_LOGE("Failed to allocate rx_ring");
         return -1;
     }
     memset(rx_ring.virt, 0, vring_size(dev->rx_size, VIRTIO_PCI_VRING_ALIGN));
     vring_init(&dev->rx_ring, dev->rx_size, rx_ring.virt, VIRTIO_PCI_VRING_ALIGN);
     dev->rx_ring_phys = rx_ring.phys;
-    dma_addr_t tx_ring = dma_alloc_pin(dma_man, vring_size(dev->tx_size, VIRTIO_PCI_VRING_ALIGN), 1, VIRTIO_PCI_VRING_ALIGN);
+    dma_addr_t tx_ring = dma_alloc_pin(dma_man, vring_size(dev->tx_size, VIRTIO_PCI_VRING_ALIGN), 1,
+                                       VIRTIO_PCI_VRING_ALIGN);
     if (!tx_ring.phys) {
-        LOG_ERROR("Failed to allocate tx_ring");
+        ZF_LOGE("Failed to allocate tx_ring");
         free_desc_ring(dev, dma_man);
         return -1;
     }
     memset(tx_ring.virt, 0, vring_size(dev->tx_size, VIRTIO_PCI_VRING_ALIGN));
     vring_init(&dev->tx_ring, dev->tx_size, tx_ring.virt, VIRTIO_PCI_VRING_ALIGN);
     dev->tx_ring_phys = tx_ring.phys;
-    dev->rx_cookies = malloc(sizeof(void*) * dev->rx_size);
-    dev->tx_cookies = malloc(sizeof(void*) * dev->tx_size);
+    dev->rx_cookies = malloc(sizeof(void *) * dev->rx_size);
+    dev->tx_cookies = malloc(sizeof(void *) * dev->tx_size);
     dev->tx_lengths = malloc(sizeof(unsigned int) * dev->tx_size);
     if (!dev->rx_cookies || !dev->tx_cookies || !dev->tx_lengths) {
-        LOG_ERROR("Failed to malloc");
+        ZF_LOGE("Failed to malloc");
         free_desc_ring(dev, dma_man);
         return -1;
     }
@@ -172,7 +181,8 @@
     return 0;
 }
 
-static int initialize(virtio_dev_t *dev, ps_dma_man_t *dma_man) {
+static int initialize(virtio_dev_t *dev, ps_dma_man_t *dma_man)
+{
     int err;
     /* perform a reset */
     set_status(dev, 0);
@@ -181,8 +191,8 @@
     /* read device features */
     uint32_t features;
     features = get_features(dev);
-    if ( (features & FEATURES_REQUIRED) != FEATURES_REQUIRED) {
-        LOG_ERROR("Required features 0x%x, have 0x%x", (unsigned int)FEATURES_REQUIRED, features);
+    if ((features & FEATURES_REQUIRED) != FEATURES_REQUIRED) {
+        ZF_LOGE("Required features 0x%x, have 0x%x", (unsigned int)FEATURES_REQUIRED, features);
         return -1;
     }
     features &= FEATURES_REQUIRED;
@@ -208,24 +218,28 @@
     return 0;
 }
 
-static void get_mac(virtio_dev_t *dev, uint8_t *mac) {
+static void get_mac(virtio_dev_t *dev, uint8_t *mac)
+{
     int i;
     for (i = 0; i < 6; i++) {
         mac[i] = read_reg8(dev, 0x14 + i);
     }
 }
 
-static void low_level_init(struct eth_driver *driver, uint8_t *mac, int *mtu) {
-    virtio_dev_t *dev = (virtio_dev_t*)driver->eth_data;
+static void low_level_init(struct eth_driver *driver, uint8_t *mac, int *mtu)
+{
+    virtio_dev_t *dev = (virtio_dev_t *)driver->eth_data;
     get_mac(dev, mac);
     *mtu = 1500;
 }
 
-static void print_state(struct eth_driver *eth_driver) {
+static void print_state(struct eth_driver *eth_driver)
+{
 }
 
-static void complete_tx(struct eth_driver *driver) {
-    virtio_dev_t *dev = (virtio_dev_t*)driver->eth_data;
+static void complete_tx(struct eth_driver *driver)
+{
+    virtio_dev_t *dev = (virtio_dev_t *)driver->eth_data;
     while (dev->tuh != dev->tx_ring.used->idx) {
         uint16_t ring = dev->tuh % dev->tx_size;
         unsigned int UNUSED desc = dev->tx_ring.used->ring[ring].id;
@@ -242,8 +256,9 @@
     }
 }
 
-static void fill_rx_bufs(struct eth_driver *driver) {
-    virtio_dev_t *dev = (virtio_dev_t*)driver->eth_data;
+static void fill_rx_bufs(struct eth_driver *driver)
+{
+    virtio_dev_t *dev = (virtio_dev_t *)driver->eth_data;
     /* we need 2 free as we enqueue in pairs. One descriptor to hold the
      * virtio header, another one for the actual buffer */
     while (dev->rx_remain >= 2) {
@@ -268,17 +283,18 @@
             .next = 0
         };
         dev->rx_ring.avail->ring[dev->rx_ring.avail->idx % dev->rx_size] = dev->rdt;
-        asm volatile("sfence" ::: "memory");
+        __atomic_thread_fence(__ATOMIC_RELEASE);
         dev->rx_ring.avail->idx++;
-        asm volatile("sfence" ::: "memory");
+        __atomic_thread_fence(__ATOMIC_RELEASE);
         write_reg16(dev, VIRTIO_PCI_QUEUE_NOTIFY, RX_QUEUE);
         dev->rdt = (dev->rdt + 2) % dev->rx_size;
-        dev->rx_remain-=2;
+        dev->rx_remain -= 2;
     }
 }
 
-static void complete_rx(struct eth_driver *driver) {
-    virtio_dev_t *dev = (virtio_dev_t*)driver->eth_data;
+static void complete_rx(struct eth_driver *driver)
+{
+    virtio_dev_t *dev = (virtio_dev_t *)driver->eth_data;
     while (dev->ruh != dev->rx_ring.used->idx) {
         uint16_t ring = dev->ruh % dev->rx_size;
         unsigned int UNUSED desc = dev->rx_ring.used->ring[ring].id;
@@ -296,8 +312,9 @@
     }
 }
 
-static int raw_tx(struct eth_driver *driver, unsigned int num, uintptr_t *phys, unsigned int *len, void *cookie) {
-    virtio_dev_t *dev = (virtio_dev_t*)driver->eth_data;
+static int raw_tx(struct eth_driver *driver, unsigned int num, uintptr_t *phys, unsigned int *len, void *cookie)
+{
+    virtio_dev_t *dev = (virtio_dev_t *)driver->eth_data;
     /* we need to num + 1 free descriptors. The + 1 is for the virtio header */
     if (dev->tx_remain < num + 1) {
         complete_tx(driver);
@@ -324,28 +341,30 @@
             .next = next_desc
         };
     }
-    dev->tx_ring.avail->ring[dev->tx_ring.avail->idx% dev->tx_size] = dev->tdt;
+    dev->tx_ring.avail->ring[dev->tx_ring.avail->idx % dev->tx_size] = dev->tdt;
     dev->tx_cookies[dev->tdt] = cookie;
     dev->tx_lengths[dev->tdt] = num;
     /* ensure update to descriptors visible before updating the index */
-    asm volatile("mfence" ::: "memory");
+    __atomic_thread_fence(__ATOMIC_SEQ_CST);
     dev->tdt = (dev->tdt + num + 1) % dev->tx_size;
     dev->tx_remain -= (num + 1);
     dev->tx_ring.avail->idx++;
     /* ensure index update visible before notifying */
-    asm volatile("mfence" ::: "memory");
+    __atomic_thread_fence(__ATOMIC_SEQ_CST);
     write_reg16(dev, VIRTIO_PCI_QUEUE_NOTIFY, TX_QUEUE);
     return ETHIF_TX_ENQUEUED;
 }
 
-static void raw_poll(struct eth_driver *driver) {
+static void raw_poll(struct eth_driver *driver)
+{
     complete_tx(driver);
     complete_rx(driver);
     fill_rx_bufs(driver);
 }
 
-static void handle_irq(struct eth_driver *driver, int irq) {
-    virtio_dev_t *dev = (virtio_dev_t*)driver->eth_data;
+static void handle_irq(struct eth_driver *driver, int irq)
+{
+    virtio_dev_t *dev = (virtio_dev_t *)driver->eth_data;
     /* read and throw away the ISR state. This will perform the ack */
     read_reg8(dev, VIRTIO_PCI_ISR);
     raw_poll(driver);
@@ -358,10 +377,11 @@
     .raw_poll = raw_poll
 };
 
-int ethif_virtio_pci_init(struct eth_driver *eth_driver, ps_io_ops_t io_ops, void *config) {
+int ethif_virtio_pci_init(struct eth_driver *eth_driver, ps_io_ops_t io_ops, void *config)
+{
     int err;
-    ethif_virtio_pci_config_t *virtio_config = (ethif_virtio_pci_config_t*)config;
-    virtio_dev_t *dev = (virtio_dev_t*)malloc(sizeof(*dev));
+    ethif_virtio_pci_config_t *virtio_config = (ethif_virtio_pci_config_t *)config;
+    virtio_dev_t *dev = (virtio_dev_t *)malloc(sizeof(*dev));
     if (!dev) {
         return -1;
     }
diff --git a/libfdt/CMakeLists.txt b/libfdt/CMakeLists.txt
index bd57158..89332c8 100644
--- a/libfdt/CMakeLists.txt
+++ b/libfdt/CMakeLists.txt
@@ -1,12 +1,7 @@
-# Copyright 2019, Data61
-# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-# ABN 41 687 119 230.
 #
-# This software may be distributed and modified according to the terms of
-# the BSD 2-Clause license. Note that NO WARRANTY is provided.
-# See "LICENSE_BSD2.txt" for details.
+# Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
 #
-# @TAG(DATA61_BSD)
+# SPDX-License-Identifier: BSD-2-Clause
 #
 
 cmake_minimum_required(VERSION 3.7.2)
diff --git a/libfdt/fdt.c b/libfdt/fdt.c
index ae03b11..c75b06f 100644
--- a/libfdt/fdt.c
+++ b/libfdt/fdt.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
diff --git a/libfdt/fdt.h b/libfdt/fdt.h
index 74961f9..aed4859 100644
--- a/libfdt/fdt.h
+++ b/libfdt/fdt.h
@@ -1,5 +1,8 @@
 #ifndef FDT_H
 #define FDT_H
+
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
diff --git a/libfdt/fdt_addresses.c b/libfdt/fdt_addresses.c
index 49537b5..1eb39b8 100644
--- a/libfdt/fdt_addresses.c
+++ b/libfdt/fdt_addresses.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2014 David Gibson <david@gibson.dropbear.id.au>
diff --git a/libfdt/fdt_empty_tree.c b/libfdt/fdt_empty_tree.c
index f2ae9b7..2963689 100644
--- a/libfdt/fdt_empty_tree.c
+++ b/libfdt/fdt_empty_tree.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2012 David Gibson, IBM Corporation.
diff --git a/libfdt/fdt_overlay.c b/libfdt/fdt_overlay.c
index 5fdab6c..766bf76 100644
--- a/libfdt/fdt_overlay.c
+++ b/libfdt/fdt_overlay.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2016 Free Electrons
diff --git a/libfdt/fdt_ro.c b/libfdt/fdt_ro.c
index eafc142..5f69cfd 100644
--- a/libfdt/fdt_ro.c
+++ b/libfdt/fdt_ro.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
diff --git a/libfdt/fdt_rw.c b/libfdt/fdt_rw.c
index 2e49855..2c3483e 100644
--- a/libfdt/fdt_rw.c
+++ b/libfdt/fdt_rw.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
diff --git a/libfdt/fdt_strerror.c b/libfdt/fdt_strerror.c
index 9677a18..1a73a4f 100644
--- a/libfdt/fdt_strerror.c
+++ b/libfdt/fdt_strerror.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
diff --git a/libfdt/fdt_sw.c b/libfdt/fdt_sw.c
index 9fa4a94..b37a25b 100644
--- a/libfdt/fdt_sw.c
+++ b/libfdt/fdt_sw.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
diff --git a/libfdt/fdt_wip.c b/libfdt/fdt_wip.c
index 534c1cb..1a313d0 100644
--- a/libfdt/fdt_wip.c
+++ b/libfdt/fdt_wip.c
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
diff --git a/libfdt/fdtget.c b/libfdt/fdtget.c
index ab40b82..ef0069a 100644
--- a/libfdt/fdtget.c
+++ b/libfdt/fdtget.c
@@ -1,26 +1,28 @@
-/*opyright (c) 2011 The Chromium OS Authors. All rights reserved.
+/*
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
  *
- *  * Portions from U-Boot cmd_fdt.c (C) Copyright 2007
- *   * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com
- *    * Based on code written by:
- *     *   Pantelis Antoniou <pantelis.antoniou@gmail.com> and
- *      *   Matthew McClintock <msm@freescale.com>
- *       *
- *        * 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 (at your option) 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, write to the Free Software
- *                    * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
- *                     * MA 02111-1307 USA
- *                      */
+ * Portions from U-Boot cmd_fdt.c (C) Copyright 2007
+ * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com
+ * Based on code written by:
+ *    Pantelis Antoniou <pantelis.antoniou@gmail.com> and
+ *    Matthew McClintock <msm@freescale.com>
+ *
+ * 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 (at your option) 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
 
 #include <assert.h>
 #include <ctype.h>
diff --git a/libfdt/libfdt.h b/libfdt/libfdt.h
index 97d2ef2..dfbf689 100644
--- a/libfdt/libfdt.h
+++ b/libfdt/libfdt.h
@@ -1,5 +1,8 @@
 #ifndef LIBFDT_H
 #define LIBFDT_H
+
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
diff --git a/libfdt/libfdt_env.h b/libfdt/libfdt_env.h
index eb20538..3a38239 100644
--- a/libfdt/libfdt_env.h
+++ b/libfdt/libfdt_env.h
@@ -1,5 +1,8 @@
 #ifndef LIBFDT_ENV_H
 #define LIBFDT_ENV_H
+
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
diff --git a/libfdt/libfdt_internal.h b/libfdt/libfdt_internal.h
index 4109f89..9eb9fd1 100644
--- a/libfdt/libfdt_internal.h
+++ b/libfdt/libfdt_internal.h
@@ -1,5 +1,8 @@
 #ifndef LIBFDT_INTERNAL_H
 #define LIBFDT_INTERNAL_H
+
+/* SPDX-License-Identifier: GPL-2.0-or-later or BSD-2-Clause */
+
 /*
  * libfdt - Flat Device Tree manipulation
  * Copyright (C) 2006 David Gibson, IBM Corporation.
diff --git a/liblwip/CMakeLists.txt b/liblwip/CMakeLists.txt
index 21fdf36..5ea6b05 100644
--- a/liblwip/CMakeLists.txt
+++ b/liblwip/CMakeLists.txt
@@ -1,13 +1,7 @@
 #
-# Copyright 2020, Data61
-# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-# ABN 41 687 119 230.
+# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
 #
-# This software may be distributed and modified according to the terms of
-# the BSD 2-Clause license. Note that NO WARRANTY is provided.
-# See "LICENSE_BSD2.txt" for details.
-#
-# @TAG(DATA61_BSD)
+# SPDX-License-Identifier: BSD-2-Clause
 #
 
 cmake_minimum_required(VERSION 3.8.2)
diff --git a/liblwip/default_opts/lwipopts.h b/liblwip/default_opts/lwipopts.h
index bd6cb9e..68ade14 100644
--- a/liblwip/default_opts/lwipopts.h
+++ b/liblwip/default_opts/lwipopts.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+
 /*
  * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
  * All rights reserved. 
diff --git a/liblwip/include/arch/perf.h b/liblwip/include/arch/perf.h
index 100d120..2f0aa99 100644
--- a/liblwip/include/arch/perf.h
+++ b/liblwip/include/arch/perf.h
@@ -1,3 +1,5 @@
+/* SPDX-License-Identifier: BSD-3-Clause */
+
 /*
  * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
  * All rights reserved. 
diff --git a/liblwip/include/lwip/arch/cc.h b/liblwip/include/lwip/arch/cc.h
index 4edbfa0..abd99fa 100644
--- a/liblwip/include/lwip/arch/cc.h
+++ b/liblwip/include/lwip/arch/cc.h
@@ -1,3 +1,8 @@
+/*
+ * SPDX-License-Identifier: BSD-3-Clause
+ * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
+ */
+
 #include <stdint.h>
 
 typedef  uint8_t  u8_t;
diff --git a/liblwip/lwip_helpers.cmake b/liblwip/lwip_helpers.cmake
index 5be4298..77cafd5 100644
--- a/liblwip/lwip_helpers.cmake
+++ b/liblwip/lwip_helpers.cmake
@@ -1,13 +1,7 @@
 #
-# Copyright 2018, Data61
-# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-# ABN 41 687 119 230.
+# Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
 #
-# This software may be distributed and modified according to the terms of
-# the BSD 2-Clause license. Note that NO WARRANTY is provided.
-# See "LICENSE_BSD2.txt" for details.
-#
-# @TAG(DATA61_BSD)
+# SPDX-License-Identifier: BSD-2-Clause
 #
 
 cmake_minimum_required(VERSION 3.8.2)
diff --git a/libpci/CMakeLists.txt b/libpci/CMakeLists.txt
index 45ffaf4..13c2601 100644
--- a/libpci/CMakeLists.txt
+++ b/libpci/CMakeLists.txt
@@ -1,19 +1,25 @@
 #
-# Copyright 2018, Data61
-# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-# ABN 41 687 119 230.
+# Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
 #
-# This software may be distributed and modified according to the terms of
-# the BSD 2-Clause license. Note that NO WARRANTY is provided.
-# See "LICENSE_BSD2.txt" for details.
-#
-# @TAG(DATA61_BSD)
+# SPDX-License-Identifier: BSD-2-Clause
 #
 
 cmake_minimum_required(VERSION 3.7.2)
 
 project(libpci C)
 
+set(configure_string "")
+
+config_option(
+    LibPCIDisplayFoundDevices
+    PCI_DISPLAY_FOUND_DEVICES
+    "Display found devices during a libpci_scan"
+    DEFAULT
+    OFF
+)
+
+add_config_library(pci "${configure_string}")
+
 add_library(
     pci
     STATIC
@@ -24,5 +30,6 @@
     src/virtual_device.c
     src/virtual_pci.c
 )
+
 target_include_directories(pci PUBLIC include)
 target_link_libraries(pci muslc platsupport)
diff --git a/libpci/LICENSE_BSD2.txt b/libpci/LICENSE_BSD2.txt
deleted file mode 100644
index 9823020..0000000
--- a/libpci/LICENSE_BSD2.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Files described as being under the "BSD 2-Clause" license fall under the
-following license.
-
------------------------------------------------------------------------
-
-Copyright (c) 2014 National ICT Australia and other contributors.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-
-2. 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.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
diff --git a/libpci/include/pci/helper.h b/libpci/include/pci/helper.h
index 77e2cab..b52a754 100644
--- a/libpci/include/pci/helper.h
+++ b/libpci/include/pci/helper.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libpci/include/pci/helper_gen.py b/libpci/include/pci/helper_gen.py
index db9a208..eb7ec03 100755
--- a/libpci/include/pci/helper_gen.py
+++ b/libpci/include/pci/helper_gen.py
@@ -2,11 +2,7 @@
 #
 # Copyright 2014, NICTA
 #
-# This software may be distributed and modified according to the terms of
-# the BSD 2-Clause license. Note that NO WARRANTY is provided.
-# See "LICENSE_BSD2.txt" for details.
-#
-# @TAG(DATA61_BSD)
+# SPDX-License-Identifier: BSD-2-Clause
 #
 
 import re, os;
diff --git a/libpci/include/pci/ioreg.h b/libpci/include/pci/ioreg.h
index 0479034..6645eff 100644
--- a/libpci/include/pci/ioreg.h
+++ b/libpci/include/pci/ioreg.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libpci/include/pci/pci.h b/libpci/include/pci/pci.h
index 590bf93..26542d5 100644
--- a/libpci/include/pci/pci.h
+++ b/libpci/include/pci/pci.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libpci/include/pci/pci_config.h b/libpci/include/pci/pci_config.h
index f895e0d..43858e1 100644
--- a/libpci/include/pci/pci_config.h
+++ b/libpci/include/pci/pci_config.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libpci/include/pci/virtual_device.h b/libpci/include/pci/virtual_device.h
index 21b0375..f2be9af 100644
--- a/libpci/include/pci/virtual_device.h
+++ b/libpci/include/pci/virtual_device.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 /* Virtual PCI devices - allows rebasing base addresses.
 
diff --git a/libpci/include/pci/virtual_pci.h b/libpci/include/pci/virtual_pci.h
index 97207fa..68e4b0a 100644
--- a/libpci/include/pci/virtual_pci.h
+++ b/libpci/include/pci/virtual_pci.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libpci/src/helper.c b/libpci/src/helper.c
index 2eb24b1..5344b58 100644
--- a/libpci/src/helper.c
+++ b/libpci/src/helper.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 // WARNING: This file is generated. DO NOT EDIT.
diff --git a/libpci/src/ioreg.c b/libpci/src/ioreg.c
index 958683e..0010c91 100644
--- a/libpci/src/ioreg.c
+++ b/libpci/src/ioreg.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <stdio.h>
 #include <assert.h>
diff --git a/libpci/src/pci.c b/libpci/src/pci.c
index c8ced63..53bd563 100644
--- a/libpci/src/pci.c
+++ b/libpci/src/pci.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <autoconf.h>
 #include <stdio.h>
@@ -19,21 +13,22 @@
 #include <utils/attribute.h>
 #include <utils/zf_log.h>
 
-#define PCI_DISPLAY_FOUND_DEVICES
-
 libpci_device_t libpci_device_list[PCI_MAX_DEVICES];
 uint32_t libpci_num_devices = 0;
 static ps_io_port_ops_t global_port_ops;
 
-uint32_t libpci_ioread(uint32_t port_no, uint32_t* val, uint32_t size) {
+uint32_t libpci_ioread(uint32_t port_no, uint32_t *val, uint32_t size)
+{
     return (uint32_t)ps_io_port_in(&global_port_ops, port_no, (int)size, val);
 }
 
-uint32_t libpci_iowrite(uint32_t port_no, uint32_t val, uint32_t size) {
+uint32_t libpci_iowrite(uint32_t port_no, uint32_t val, uint32_t size)
+{
     return (uint32_t)ps_io_port_out(&global_port_ops, port_no, (int)size, val);
 }
 
-libpci_device_t* libpci_find_device(uint16_t vendor_id, uint16_t device_id) {
+libpci_device_t *libpci_find_device(uint16_t vendor_id, uint16_t device_id)
+{
     for (uint32_t i = 0; i < libpci_num_devices; i++) {
         if (libpci_device_list[i].vendor_id == vendor_id &&
             libpci_device_list[i].device_id == device_id) {
@@ -43,7 +38,8 @@
     return NULL;
 }
 
-int libpci_find_device_all(uint16_t vendor_id, uint16_t device_id, libpci_device_t** out) {
+int libpci_find_device_all(uint16_t vendor_id, uint16_t device_id, libpci_device_t **out)
+{
     assert(out);
     int n = 0;
     for (uint32_t i = 0; i < libpci_num_devices; i++) {
@@ -55,7 +51,8 @@
     return n;
 }
 
-libpci_device_t* libpci_find_device_matching(libpci_device_t *device) {
+libpci_device_t *libpci_find_device_matching(libpci_device_t *device)
+{
     for (uint32_t i = 0; i < libpci_num_devices; i++) {
         if (libpci_device_list[i].bus == device->bus &&
             libpci_device_list[i].dev == device->dev &&
@@ -68,7 +65,8 @@
     return NULL;
 }
 
-libpci_device_t* libpci_find_device_bdf(uint8_t bus, uint8_t dev, uint8_t fun) {
+libpci_device_t *libpci_find_device_bdf(uint8_t bus, uint8_t dev, uint8_t fun)
+{
     for (uint32_t i = 0; i < libpci_num_devices; i++) {
         if (libpci_device_list[i].bus == bus &&
             libpci_device_list[i].dev == dev &&
@@ -79,7 +77,8 @@
     return NULL;
 }
 
-static int libpci_add_fun(uint8_t bus, uint8_t dev, uint8_t fun) {
+static int libpci_add_fun(uint8_t bus, uint8_t dev, uint8_t fun)
+{
     uint16_t vendor_id = libpci_read_reg16(bus, dev, fun, PCI_VENDOR_ID);
 
     if (vendor_id == PCI_VENDOR_ID_INVALID) {
@@ -93,7 +92,10 @@
     uint16_t device_id = libpci_read_reg16(bus, dev, fun, PCI_DEVICE_ID);
     ZF_LOGD("    deviceID = %s [0x%x]\n", libpci_deviceID_str(vendor_id, device_id), device_id);
 
-    assert(libpci_num_devices + 1<= PCI_MAX_DEVICES);
+    if (libpci_num_devices + 1 > PCI_MAX_DEVICES) {
+        return 0;
+    }
+
     libpci_device_list[libpci_num_devices].bus = bus;
     libpci_device_list[libpci_num_devices].dev = dev;
     libpci_device_list[libpci_num_devices].fun = fun;
@@ -110,15 +112,15 @@
     libpci_device_iocfg_debug_print(&libpci_device_list[libpci_num_devices].cfg, false);
 #endif
 
-    #ifdef PCI_DISPLAY_FOUND_DEVICES
+#ifdef CONFIG_PCI_DISPLAY_FOUND_DEVICES
     printf("PCI :: %.2x.%.2x.%.2x : %s %s (vid 0x%x did 0x%x) line%d pin%d\n", bus, dev, fun,
-        libpci_vendorID_str(vendor_id), libpci_deviceID_str(vendor_id, device_id),
-        vendor_id, device_id,
-        libpci_read_reg8(bus, dev, fun, PCI_INTERRUPT_LINE),
-        libpci_read_reg8(bus, dev, fun, PCI_INTERRUPT_PIN)
-    );
+           libpci_vendorID_str(vendor_id), libpci_deviceID_str(vendor_id, device_id),
+           vendor_id, device_id,
+           libpci_read_reg8(bus, dev, fun, PCI_INTERRUPT_LINE),
+           libpci_read_reg8(bus, dev, fun, PCI_INTERRUPT_PIN)
+          );
     libpci_device_iocfg_debug_print(&libpci_device_list[libpci_num_devices].cfg, true);
-    #endif
+#endif
 
     libpci_num_devices++;
 
@@ -127,24 +129,26 @@
 
 static void lib_pci_scan_bus(int bus);
 
-static void lib_pci_scan_fun(int bus, int dev, int fun) {
+static void lib_pci_scan_fun(int bus, int dev, int fun)
+{
     libpci_add_fun(bus, dev, fun);
-    if ( libpci_read_reg16(bus, dev, fun, PCI_CLASS_DEVICE) == 0x0604) {
+    if (libpci_read_reg16(bus, dev, fun, PCI_CLASS_DEVICE) == 0x0604) {
         int new_bus = libpci_read_reg8(bus, dev, fun, PCI_SECONDARY_BUS);
-        printf("%s found additional bus %d from %d %d %d\n", __FUNCTION__, new_bus, bus, dev, fun);
+        ZF_LOGD("%s found additional bus %d from %d %d %d\n", __FUNCTION__, new_bus, bus, dev, fun);
         lib_pci_scan_bus(new_bus);
     }
 }
 
-static void lib_pci_scan_dev(int bus, int dev) {
+static void lib_pci_scan_dev(int bus, int dev)
+{
     uint16_t vendor_id = libpci_read_reg16(bus, dev, 0, PCI_VENDOR_ID);
     if (vendor_id == PCI_VENDOR_ID_INVALID) {
         return;
     }
-    printf("%s found pci device %d %d\n", __FUNCTION__, bus, dev);
+    ZF_LOGD("%s found pci device %d %d\n", __FUNCTION__, bus, dev);
     lib_pci_scan_fun(bus, dev, 0);
-    if ( (libpci_read_reg8(bus, dev, 0, PCI_HEADER_TYPE) & 0x80) != 0) {
-        printf("%s found multi function device %d %d\n", __FUNCTION__, bus, dev);
+    if ((libpci_read_reg8(bus, dev, 0, PCI_HEADER_TYPE) & 0x80) != 0) {
+        ZF_LOGD("%s found multi function device %d %d\n", __FUNCTION__, bus, dev);
         for (int function = 1; function < 8; function++) {
             if (libpci_read_reg16(bus, dev, function, PCI_VENDOR_ID) != PCI_VENDOR_ID_INVALID) {
                 lib_pci_scan_fun(bus, dev, function);
@@ -153,29 +157,32 @@
     }
 }
 
-static void lib_pci_scan_bus(int bus) {
+static void lib_pci_scan_bus(int bus)
+{
     for (int dev = 0; dev < 32; dev++) {
         lib_pci_scan_dev(bus, dev);
     }
 }
 
-void libpci_scan(ps_io_port_ops_t port_ops) {
+void libpci_scan(ps_io_port_ops_t port_ops)
+{
     global_port_ops = port_ops;
     ZF_LOGD("PCI :: Scanning...\n");
-    if ( (libpci_read_reg8(0, 0, 0, PCI_HEADER_TYPE) & 0x80) == 0) {
-        printf("Single bus detected\n");
+    if ((libpci_read_reg8(0, 0, 0, PCI_HEADER_TYPE) & 0x80) == 0) {
+        ZF_LOGD("Single bus detected\n");
         lib_pci_scan_bus(0);
     } else {
         for (int function = 0; function < 8; function++) {
             if (libpci_read_reg16(0, 0, function, PCI_VENDOR_ID) != PCI_VENDOR_ID_INVALID) {
-                printf("%s detected bus %d\n", __FUNCTION__, function);
+                ZF_LOGD("%s detected bus %d\n", __FUNCTION__, function);
                 lib_pci_scan_bus(function);
             }
         }
     }
 }
 
-void libpci_read_ioconfig(libpci_device_iocfg_t *cfg, uint8_t bus, uint8_t dev, uint8_t fun) {
+void libpci_read_ioconfig(libpci_device_iocfg_t *cfg, uint8_t bus, uint8_t dev, uint8_t fun)
+{
     assert(cfg);
     memset(cfg, 0, sizeof(libpci_device_iocfg_t));
 
@@ -198,7 +205,9 @@
 
         if (cfg_base_addr == 0)
             /* no device here. */
+        {
             continue;
+        }
 
         cfg->base_addr_space[i] = cfg_base_addr & PCI_BASE_ADDRESS_SPACE;
         if (cfg->base_addr_space[i] == PCI_BASE_ADDRESS_SPACE_MEMORY) {
@@ -215,7 +224,7 @@
             } else {
                 cfg->base_addr[i] = bios_base_addr & PCI_BASE_ADDRESS_MEM_MASK;
             }
-        } else  /* PCI_BASE_ADDRESS_SPACE_IO */ {
+        } else { /* PCI_BASE_ADDRESS_SPACE_IO */
             cfg->base_addr[i] = bios_base_addr & PCI_BASE_ADDRESS_IO_MASK;
             cfg->base_addr_size_mask[i] = cfg_base_addr & PCI_BASE_ADDRESS_IO_MASK;
             cfg->base_addr_type[i] = PCI_BASE_ADDRESS_MEM_TYPE_32;
diff --git a/libpci/src/virtual_device.c b/libpci/src/virtual_device.c
index 0396814..061993f 100644
--- a/libpci/src/virtual_device.c
+++ b/libpci/src/virtual_device.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <assert.h>
 #include <stdio.h>
diff --git a/libpci/src/virtual_pci.c b/libpci/src/virtual_pci.c
index 7369510..0078410 100644
--- a/libpci/src/virtual_pci.c
+++ b/libpci/src/virtual_pci.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <assert.h>
diff --git a/libpicotcp/CMakeLists.txt b/libpicotcp/CMakeLists.txt
index f396fe5..1671b1a 100644
--- a/libpicotcp/CMakeLists.txt
+++ b/libpicotcp/CMakeLists.txt
@@ -1,13 +1,7 @@
 #
-# Copyright 2018, Data61
-# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-# ABN 41 687 119 230.
+# Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
 #
-# This software may be distributed and modified according to the terms of
-# the BSD 2-Clause license. Note that NO WARRANTY is provided.
-# See "LICENSE_BSD2.txt" for details.
-#
-# @TAG(DATA61_BSD)
+# SPDX-License-Identifier: BSD-2-Clause
 #
 
 cmake_minimum_required(VERSION 3.7.2)
diff --git a/libpicotcp/picoopts.h b/libpicotcp/picoopts.h
index 43f19bc..ec6cdde 100644
--- a/libpicotcp/picoopts.h
+++ b/libpicotcp/picoopts.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* PicoTCP - Definition file to add support for modules */
diff --git a/libplatsupport/CMakeLists.txt b/libplatsupport/CMakeLists.txt
index 646b0fb..9ca567e 100644
--- a/libplatsupport/CMakeLists.txt
+++ b/libplatsupport/CMakeLists.txt
@@ -1,13 +1,7 @@
 #
-# Copyright 2017, Data61
-# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-# ABN 41 687 119 230.
+# Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 #
-# This software may be distributed and modified according to the terms of
-# the BSD 2-Clause license. Note that NO WARRANTY is provided.
-# See "LICENSE_BSD2.txt" for details.
-#
-# @TAG(DATA61_BSD)
+# SPDX-License-Identifier: BSD-2-Clause
 #
 
 cmake_minimum_required(VERSION 3.7.2)
@@ -40,15 +34,27 @@
     "ega;LibPlatSupportX86ConsoleDeviceEGA;LIB_PLAT_SUPPORT_SERIAL_TEXT_EGA;KernelPlatPC99"
 )
 
+set(LibPlatSupportMach "")
+if(KernelPlatformRpi3 OR KernelPlatformRpi4)
+    set(LibPlatSupportMach "bcm283x")
+elseif(NOT ${KernelArmMach} STREQUAL "")
+    # falling back to kernel settings is done to keep legacy compatibility
+    set(LibPlatSupportMach "${KernelArmMach}")
+endif()
+
 file(
     GLOB
         deps
-        src/mach/${KernelArmMach}/*.c
         src/plat/${KernelPlatform}/*.c
         src/*.c
         src/plat/${KernelPlatform}/acpi/*.c
 )
 
+if(NOT ${LibPlatSupportMach} STREQUAL "")
+    file(GLOB lib_deps "src/mach/${LibPlatSupportMach}/*.c")
+    list(APPEND deps ${lib_deps})
+endif()
+
 if(${KernelArch} STREQUAL "arm")
     list(APPEND deps src/arch/arm/clock.c)
     list(APPEND deps src/arch/arm/delay.c)
@@ -59,7 +65,6 @@
     list(APPEND deps src/arch/arm/irqchip/gic.c)
     list(APPEND deps src/arch/arm/irqchip/tegra.c)
     list(APPEND deps src/arch/arm/irqchip/gicv3.c)
-    list(APPEND deps src/arch/arm/irqchip/avic.c)
     list(APPEND deps src/arch/arm/irqchip/omap3.c)
     # Link the IRQ chip parser modules
     list(
@@ -83,55 +88,76 @@
 endif()
 
 if(KernelPlatformExynos5422)
-    list(APPEND deps src/mach/${KernelArmMach}/clock/exynos_5422_clock.c)
+    list(APPEND deps src/mach/${LibPlatSupportMach}/clock/exynos_5422_clock.c)
 elseif(KernelPlatformExynos4 OR KernelPlatformExynos5410 OR KernelPlatformExynos5250)
-    list(APPEND deps src/mach/${KernelArmMach}/clock/exynos_common_clock.c)
+    list(APPEND deps src/mach/${LibPlatSupportMach}/clock/exynos_common_clock.c)
+endif()
+
+if(KernelPlatImx6 OR KernelPlatformImx7Sabre)
+    list(APPEND deps src/mach/${LibPlatSupportMach}/epit/epit.c)
 endif()
 
 if(
     KernelPlatImx6
     OR KernelPlatformImx7Sabre
-    OR KernelPlatformKZM
     OR KernelPlatformImx8mq-evk
     OR KernelPlatformImx8mm-evk
 )
-    if(NOT (KernelPlatformImx8mq-evk OR KernelPlatformImx8mm-evk))
-        list(APPEND deps src/mach/${KernelArmMach}/epit/epit.c)
-    endif()
-    if(NOT KernelPlatformKZM)
-        list(APPEND deps src/mach/${KernelArmMach}/serial/serial.c)
-    endif()
+    list(APPEND deps src/mach/${LibPlatSupportMach}/serial/serial.c)
 endif()
+
 if(KernelPlatformImx8mq-evk OR KernelPlatformImx8mm-evk)
     list(APPEND deps src/plat/imx8m/chardev.c)
-    # There's no clock driver at the moment, but this is to allow the libethdrivers to build for imx8mq
+    # There's no clock driver at the moment, but this is to allow the
+    # libethdrivers to build for imx8mq
     list(APPEND deps src/plat/imx8m/clock.c)
 endif()
 
+if(KernelPlatPC99)
+    set_source_files_properties(
+        src/plat/pc99/keyboard_vkey.c
+        PROPERTIES
+        COMPILE_FLAGS
+        -Wno-initializer-overrides
+    )
+endif()
+
 list(SORT deps)
 
 add_config_library(platsupport "${configure_string}")
 
 add_library(platsupport EXCLUDE_FROM_ALL ${deps})
-target_include_directories(platsupport PRIVATE src/plat_include/${KernelPlatform})
 
 if(KernelPlatformImx8mq-evk OR KernelPlatformImx8mm-evk)
     target_include_directories(platsupport PUBLIC plat_include/imx8m)
 endif()
+
+if(KernelPlatformZynqmpZcu102 OR KernelPlatformZynqmpUltra96)
+    # This still needs to be cleaned up, so there is a mach folder "zynymq" and
+    # the board specific folders "zcu102" and "ultra96". Then we don't need to
+    # include this folder here explicitly
+    target_include_directories(platsupport PUBLIC plat_include/zynqmp)
+endif()
+
+if(NOT "${LibPlatSupportMach}" STREQUAL "")
+    target_include_directories(platsupport PUBLIC mach_include/${LibPlatSupportMach})
+endif()
+
+# special handling for "arm_hyp", it's an add-on-hack over "aarch32"
+set(_inc_folder_KernelSel4Arch "${KernelSel4Arch}")
+if("${KernelSel4Arch}" STREQUAL "arm_hyp")
+    set(_inc_folder_KernelSel4Arch "aarch32")
+endif()
+
 target_include_directories(
     platsupport
-    PUBLIC include plat_include/${KernelPlatform} arch_include/${KernelArch}
+    PUBLIC
+        include
+        plat_include/${KernelPlatform}
+        sel4_arch_include/${_inc_folder_KernelSel4Arch}
+        arch_include/${KernelArch}
 )
-if(NOT "${KernelArmMach}" STREQUAL "")
-    target_include_directories(platsupport PUBLIC mach_include/${KernelArmMach})
-endif()
-if("${KernelArch}" STREQUAL "arm")
-    set(sel4_arch "${KernelSel4Arch}")
-    if("${KernelSel4Arch}" STREQUAL "arm_hyp")
-        set(sel4_arch "aarch32")
-    endif()
-    target_include_directories(platsupport PUBLIC sel4_arch_include/${sel4_arch})
-endif()
+
 target_link_libraries(
     platsupport
     muslc
diff --git a/libplatsupport/LICENSE_BSD2.txt b/libplatsupport/LICENSE_BSD2.txt
deleted file mode 100644
index 9823020..0000000
--- a/libplatsupport/LICENSE_BSD2.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Files described as being under the "BSD 2-Clause" license fall under the
-following license.
-
------------------------------------------------------------------------
-
-Copyright (c) 2014 National ICT Australia and other contributors.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-
-2. 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.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
diff --git a/libplatsupport/README.md b/libplatsupport/README.md
index 01baceb..220a2ef 100644
--- a/libplatsupport/README.md
+++ b/libplatsupport/README.md
@@ -1,14 +1,9 @@
 <!--
-     Copyright 2017, Data61
-     Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-     ABN 41 687 119 230.
+     Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 
-     This software may be distributed and modified according to the terms of
-     the BSD 2-Clause license. Note that NO WARRANTY is provided.
-     See "LICENSE_BSD2.txt" for details.
-
-     @TAG(DATA61_BSD)
+     SPDX-License-Identifier: CC-BY-SA-4.0
 -->
+
 seL4 libplatsupport
 --------------------
 
diff --git a/libplatsupport/arch_include/arm/platsupport/arch/generic_timer.h b/libplatsupport/arch_include/arm/platsupport/arch/generic_timer.h
index 37ab1ad..816fe6a 100644
--- a/libplatsupport/arch_include/arm/platsupport/arch/generic_timer.h
+++ b/libplatsupport/arch_include/arm/platsupport/arch/generic_timer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/arch_include/arm/platsupport/clock.h b/libplatsupport/arch_include/arm/platsupport/clock.h
index a482e5b..2e6b333 100644
--- a/libplatsupport/arch_include/arm/platsupport/clock.h
+++ b/libplatsupport/arch_include/arm/platsupport/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/arch_include/arm/platsupport/dma330.h b/libplatsupport/arch_include/arm/platsupport/dma330.h
index a8051bb..41d47ee 100644
--- a/libplatsupport/arch_include/arm/platsupport/dma330.h
+++ b/libplatsupport/arch_include/arm/platsupport/dma330.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/arch_include/arm/platsupport/gpio.h b/libplatsupport/arch_include/arm/platsupport/gpio.h
index 8ef1cdd..c4db66f 100644
--- a/libplatsupport/arch_include/arm/platsupport/gpio.h
+++ b/libplatsupport/arch_include/arm/platsupport/gpio.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/arch_include/arm/platsupport/gpio_utils.h b/libplatsupport/arch_include/arm/platsupport/gpio_utils.h
index 121b4c1..e717012 100644
--- a/libplatsupport/arch_include/arm/platsupport/gpio_utils.h
+++ b/libplatsupport/arch_include/arm/platsupport/gpio_utils.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/arch_include/arm/platsupport/i2c.h b/libplatsupport/arch_include/arm/platsupport/i2c.h
index f395e96..4d0be24 100644
--- a/libplatsupport/arch_include/arm/platsupport/i2c.h
+++ b/libplatsupport/arch_include/arm/platsupport/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/arch_include/arm/platsupport/irq_combiner.h b/libplatsupport/arch_include/arm/platsupport/irq_combiner.h
index 14dfb00..97c121e 100644
--- a/libplatsupport/arch_include/arm/platsupport/irq_combiner.h
+++ b/libplatsupport/arch_include/arm/platsupport/irq_combiner.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/arch_include/arm/platsupport/mux.h b/libplatsupport/arch_include/arm/platsupport/mux.h
index e25993e..bf904b5 100644
--- a/libplatsupport/arch_include/arm/platsupport/mux.h
+++ b/libplatsupport/arch_include/arm/platsupport/mux.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/arch_include/arm/platsupport/reset.h b/libplatsupport/arch_include/arm/platsupport/reset.h
index 2948ef2..f6960c1 100644
--- a/libplatsupport/arch_include/arm/platsupport/reset.h
+++ b/libplatsupport/arch_include/arm/platsupport/reset.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2020, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/arch_include/arm/platsupport/spi.h b/libplatsupport/arch_include/arm/platsupport/spi.h
index 258d690..6ab0e1d 100644
--- a/libplatsupport/arch_include/arm/platsupport/spi.h
+++ b/libplatsupport/arch_include/arm/platsupport/spi.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/arch_include/arm/platsupport/src.h b/libplatsupport/arch_include/arm/platsupport/src.h
index 41155ac..301a091 100644
--- a/libplatsupport/arch_include/arm/platsupport/src.h
+++ b/libplatsupport/arch_include/arm/platsupport/src.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/arch_include/x86/platsupport/arch/tsc.h b/libplatsupport/arch_include/x86/platsupport/arch/tsc.h
index 6234281..3141649 100644
--- a/libplatsupport/arch_include/x86/platsupport/arch/tsc.h
+++ b/libplatsupport/arch_include/x86/platsupport/arch/tsc.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/docs/driver_environment/index.md b/libplatsupport/docs/driver_environment/index.md
new file mode 100644
index 0000000..909bef4
--- /dev/null
+++ b/libplatsupport/docs/driver_environment/index.md
@@ -0,0 +1,230 @@
+<!--
+     Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+
+     SPDX-License-Identifier: CC-BY-SA-4.0
+-->
+
+# Driver environment
+
+The driver environment provides a series of interfaces for writing hardware
+device drivers. These interfaces consist of hardware access interfaces and
+driver interfaces.
+
+## Usage
+
+The goal of this environment is to make it possible to implement hardware
+device drivers that can be used in various projects that may have different
+system environments.  By providing a valid implementation of this driver
+environment, different projects should be able to reuse compatible device
+drivers in other projects without requiring a large porting effort.
+Additionally, by relying on well-defined driver interfaces, new drivers can be
+implemented that depend on other without compatibility issues. 
+
+Most of the interfaces described below can be accessed via a handle to the
+`ps_io_ops_t` interface.  When a system environment is initialised, functions
+required for implementation of drivers will be initialised and registered to
+the `ps_io_ops_t` interface via sub-interfaces.  There is a core set of
+interfaces that provide functionality needed for implementing basic drivers,
+and a possibility for additional interfaces to be registered in order to extend
+the driver environment for building more complicated drivers. This allows
+drivers that depend on other drivers to be created, as they can find interfaces
+to other driver systems inside `ps_io_ops_t`.
+
+The following core interfaces provide access to hardware resources and are
+expected to be available for any driver to use:
+
+- [`ps_dma_man_t`][1]: Direct Memory Access (DMA) management interface for
+  allocating and managing memory that is used in DMA transactions with
+  hardware.
+- [`ps_io_mapper_t`][2]: Memory Mapped I/O (MMIO) interface for creating
+  virtual memory mappings to device registers.
+- [`ps_io_port_ops_t`][3]: Architecture-specific I/O operations interface to
+  facilitate any hardware I/O that is not possible through MMIO.
+- [`ps_irq_ops_t`][4] Hardware interrupt handling interface for registering
+  interrupt handlers against hardware interrupts.
+- [`ps_malloc_ops_t`][5]: Memory allocation interface for performing anonymous
+  memory allocation.
+- [`ps_io_fdt_t`][6]: Device tree interface for providing access to a flattened
+  device tree (FDT) used to query platform information.
+- [`ps_interface_registration_ops_t`][7]: Interface for allowing the
+  registration and locating of specific driver interfaces.
+
+These interfaces should be sufficient for creating a typical device driver
+where other devices aren't required to enable the device to be used.
+
+[1]:ps_dma_man_t.md
+[2]:ps_io_mapper_t.md
+[3]:ps_io_port_ops_t.md
+[4]:ps_irq_ops_t.md
+[5]:ps_malloc_ops_t.md
+[6]:ps_io_fdt_t.md
+[7]:ps_interface_registration_ops_t.md
+
+Many drivers require another device to perform some sort of operation to allow
+their device to function correctly. One example is an UART driver that needs to
+communicate with a clock driver to configure its input frequency. Access to
+other drivers are going to depend on the system configuration as many systems
+will try to isolate drivers from each other for better fault-tolerance and
+access control policies. Therefore many driver interfaces would not exist in
+certain software components.  The `ps_interface_registration_ops_t` interface
+is used for co-ordinating variable interface availability for a particular
+driver environment. If a driver has a dependency on another driver, then it can
+try to find the interface instance within the list of registered driver
+interfaces. If the environment is configured correctly, the driver interface
+should be available. It is also expected that once a driver has initialised it
+registers its own interface in the `ps_interface_registration_ops_t` for future
+users to find it.
+
+The initialisation process refers to how a driver is initialised. The driver's entry point
+or constructor is how the driver environment passes the initial `ps_io_ops_t` reference
+and any initial configuration for the driver to know how to initialise itself.  This entry point
+function can be registered under a compatibility string in a known location so that the
+driver environment can call it if it wishes to instantiate a driver for a particular device.
+
+```c
+int imx6_uart_init(ps_io_ops_t *io_ops, const char* device_path)
+```
+
+In the above function, a i.MX6 UART driver can be created by calling
+`imx6_uart_init` with a `ps_io_ops_t` and a string to a UART device in the FDT.
+These initial variables are enough for the driver to locate the device node in
+the FDT, create MMIO mappings, register an interrupt handler, configure the
+input clock frequency, take the device out of reset before initialising the
+device registers, and finally registering a serial driver interface with
+`ps_io_ops_t`.
+
+Driver configuration is usually provided via properties in its device node in
+the FDT. This allows a driver to define its own configuration values that it
+will understand.  The only initial configuration required would be to specify
+which device in the device tree that the driver should be configuring. When the
+driver finishes initialising and registers an initialised driver interface, it
+can provide configuration information to any future users via setting key-value
+pair attributes. This is intended to be a way to provide any configuration
+information that is 'outside' of the interface that is being registered.  This
+is how multiple interfaces of the same type can be registered while still
+allowing the eventual user to make an informed choice about which interface
+instance to use.
+
+In order to ensure re-usability of drivers in many different operating system
+environments that may have different software execution models, we require that
+all driver environments serialise any calls to driver functions essentially
+treating anything that `ps_io_ops_t` has been given to as a critical section.
+This means that drivers should also be written with this assumption in mind and
+not perform operations that expect to block for indefinite amounts of time.
+Most devices tend to be designed in a way to allow drivers to be designed as
+event handlers that maintain a state machine and perform fairly short running
+operations in response to new events that may be generated by either a hardware
+event, or a call from a user. This is also why there are no interfaces for
+creating additional threads of control.  Mechanisms to support concurrency may
+be added in the future but are currently out of scope of this driver
+environment.
+
+Drivers can assume the existence of some sort of standard C library existing
+that they can link against.  However, they should be careful to only use
+functions that don't violate the assumptions of this driver environment.
+Additional libraries are also able to be linked for implementations of data
+structures a driver needs to operate correctly. In the future the available
+standard library functions may be more restricted.
+
+Access control relates to how certain operations may be restricted or allowed
+depending on some sort of contextual information. Access control policies can
+be implemented and enforced by any interface implementation. A driver should
+generally trust any interface that it is calling but not necessarily trust
+things calling it. Generally it is assumed that all software executing in the
+same protection domain trusts itself. This assumption means that drivers being
+called across a local interface will usually trust the caller. (This doesn't
+mean that it should expect all calls to be correct). A driver should expect
+that any resources that it doesn't have access to will have strong access
+control mechanisms that prevent it from being able to access them, usually
+implemented with hardware mechanisms, and that any access control policies that
+a driver wants to implement will be able to be reinforced by hardware
+mechanisms also.
+
+Fault tolerance refers to how a system will respond due to errors that occur
+while it is in operation.  Strong component isolation is expected to provide
+most of the fault tolerance in a system and as such some drivers may not be
+required to be implemented to a high degree of reliability if they aren't
+expected to be used in any critical pathways. This is in contrast to systems
+without strong component isolation where a crashing driver could result in the
+entire system crashing. This doesn't mean that a driver should abort if it gets
+unexpected inputs. It is encouraged that all drivers at least return an error
+response and consider logging an error in situations where they encounter
+unrecoverable situations.
+
+Remote drivers are a name given to drivers that operate in a different software
+component from their users.  This means that driver requests cannot be
+performed via a simple function call and some sort of remote communication
+mechanism is required. Remote drivers are able to more effectively implement
+access control policies and distrust their users as they have an isolation
+boundary protecting them from any attempted malicious actions by their users. A
+remote driver may have a different interface type than if the driver was in the
+same software component as it is not always possible to transparently move
+software into a different execution domain. A driver that depends on other
+device drivers that may be remote may need to be able to handle interracting
+with the other driver using different interfaces.  Implementing remote drivers
+is out of scope of this current section as providing operating system
+independent interfaces for implementing communication with remote components is
+out of scope of this environment at the moment.  Remote drivers can still be
+accessed via interfaces that are registered with
+`ps_interface_registration_ops_t`, only the interface implementations are out
+of scope.
+
+As the goal of this driver environment is to make reusing device drivers across
+projects easier, mechanisms will likely be needed for handling compatibility
+issues as the common interfaces are evolved. Given that this framework is
+currently considered under development, there isn't expected to be many
+mechanisms for ensuring compatibility. We currently expect version control
+software to be used to synchronise sources, and that binary distribution
+of artifacts is unsupported. Informal compatibility mechanisms such as
+interface and CHANGES documentation and more formal mechanisms such as typed
+interfaces should be used to provide some form of compatibility assurance.
+
+## Implementation details
+
+This driver environment is designed with the intention to support both dynamic
+and static implementations.  A static environment refers to an environment
+where the topology of software and hardware components is unchanging after
+intitialisation and resource consumption behavior is known ahead of time. In
+static environments, many of the interface implementations already expect to
+give specific resources to certain components and also don't expect to have to
+destroy instances in response to changing environment.  Dynamic environments
+should also be supported and the interfaces listed above should support dynamic
+implementations such as on-demand memory mapping or destruction of entire
+components. Supporting static environments is currently a higher priority than
+dynamic environments, so there may be areas where mechanisms for dynamic
+implementations are hindered based on static assumptions. This is an area where
+interfaces should evolve to be more accomodating to dynamic implementations.
+
+This driver environment is also designed with the assumption that drivers don't
+all exist in the same software protection domain. This prevents drivers from
+being able to informally access other resources that aren't explicitly
+available as they may be located in different protection domains. Additionally,
+certain interfaces may be designed with certain trade-offs made in favour of
+remote implementations.  These special cases explained just now may indicate
+that a different interface is needed that is more specialised to a particular
+use case.
+
+## Potential future changes
+
+Driver initialisation starts with a driver function call that starts the
+initialisation. There are not currently a wide range of protocols in place for a
+driver to make itself discoverable to an environment.  The current mechanisms
+either require the driver to provide a unique symbol name that the environment
+somehow knows to call, or by placing the function in a unique global variable
+with some metadata that is then added to a special linker section that the
+driver environment can perform searches on. As the amount of drivers that are
+available grows, a wider range of driver discovery mechanisms may be provided.
+This would then require additional support to be added to each driver if it
+wanted to take advantage of the additional mechanisms. 
+
+As mentioned in the usage section, concurrency is not supported and there are
+no mechanisms for creating additional execution contexts. This functionality
+may be added in the future once more use-cases are available to enable a
+satisfactory design and these mechanisms become more prioritised.
+
+The core set of library functions available could become more well defined in
+the future. This may be by either making it possible for drivers to define
+their own standard library, or by developing a smaller, libcore that is usable
+in all driver environments.  Each environment likely wants to control its own
+standard library and so it may be difficult to take a strong policy choice
+here.
diff --git a/libplatsupport/docs/driver_environment/ps_dma_man_t.md b/libplatsupport/docs/driver_environment/ps_dma_man_t.md
new file mode 100644
index 0000000..a8e0cae
--- /dev/null
+++ b/libplatsupport/docs/driver_environment/ps_dma_man_t.md
@@ -0,0 +1,158 @@
+<!--
+     Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+
+     SPDX-License-Identifier: CC-BY-SA-4.0
+-->
+
+# Direct Memory Access (DMA) management interface
+
+`ps_dma_man_t` is an interface for software to allocate and provide direct
+memory access (DMA) memory for devices to use.
+
+<https://github.com/seL4/util_libs/blob/master/libplatsupport/include/platsupport/io.h>
+
+## Usage
+
+DMA communication allows devices to directly access memory. This enables
+communication between hardware devices and software to happen asynchronously.
+This DMA management interface is how software can manage the memory used in DMA
+transactions.
+
+A DMA transaction works as follows:
+
+1. Software allocates some memory to be shared with the hardware.
+2. The memory is initialised by the software. If the transaction involves
+   sending data to the hardware then this data can be written into the memory.
+3. The memory gets 'pinned' which means that the software's system environment
+   is not supposed to swap the backing memory out in dynamic environments. Once
+   the memory has been pinned, the software is free to tell the hardware about
+   the memory so that it can be used.
+4. The software hands the memory region over to the hardware by communicating
+   with it over some interface.  Once the memory is handed over to the
+   hardware, the software is not expected to modify it.
+5. The hardware is free to access the memory which it can do by reading or
+   writing to it directly.
+6. Once the hardware is ready to release the memory back to the software it
+   indicates that it has finished with the memory via some interface.
+7. The software can now access the modified data by reading the memory that may
+   have been updated by the hardware.
+8. The software can 'unpin' the memory to indicate to the system environment
+   that the memory is not going to be used by the hardware anymore and it may
+   choose to swap it out.
+9. When the software is finished with the memory it can free the memory and it
+   gets given back to the DMA manager to potentially reallocate elsewhere.
+
+This transaction protocol relies on the software and hardware synchronising
+access to the shared memory correctly.  In all cases the memory access is
+controlled by the software. Sending data from the hardware to software requires
+the software to initially provide DMA memory for the hardware to then write
+into.
+
+To have memory safety, the hardware should only access memory within the
+regions provided to it by the software.  This requires the software to
+communicate addresses to the hardware correctly, and also for the hardware to
+only access memory that it has been given by the software. Without special
+hardware architecture mechanisms such as a hardware memory management unit, the
+software and hardware components need to be trusted to behave correctly.
+
+These hardware protection mechanisms are known as IOMMU on x86 and SMMU on Arm
+and provide a mechanism for system software to control memory access by
+hardware devices to both protect against devices and drivers that are
+untrustworthy, or have errors.  On systems with these mechanisms, the 'pin' and
+'unpin' operations can allow the system environment software to create device
+mappings of the memory and provide an address for the software to then provide
+to the hardware.  In this scenario, in cases where the hardware tries to access
+memory that is outside of the allocated DMA regions it will generate a
+protection fault instead of accessing the memory.
+
+Support for hardware memory protection mechanisms is intended to be handled by
+the interface implementation and the users of this interface do not need to be
+aware of this.
+
+Scatter-gather is a common mechanism used to specify how a single data stream
+can be constructed from a sequence of buffers. In a scenario where a device
+supports scatter-gather, multiple DMA allocations can be used for all of the
+buffers.  Essentially, scatter-gather becomes a mechanism implemented on top of
+this interface.
+
+```c
+void * ps_dma_alloc(const ps_dma_man_t *dma_man, size_t size, int align, int cache, ps_mem_flags_t flags)
+void ps_dma_free(const ps_dma_man_t *dma_man, void *addr, size_t size)
+```
+
+The two functions, `ps_dma_alloc` and `ps_dma_free`, allocate and free memory
+that can be used in DMA transactions.  The `size` and `alignment` arguments are
+used to specify the size and position of the allocated region that will be
+compatible with hardware requirements. These methods also handle mapping and
+unmapping the DMA regions into the software address space. The return value
+specifies the address of the allocated memory in the caller's address space.
+If an allocation is not possible then `NULL` will be returned.  Memory mapping
+attributes for the caller's mappings are specified by the `cache` and `flags`
+arguments.  It is architecture dependent whether hardware memory accesses are
+cache coherent. In situations where DMA is not cache coherent, the DMA memory
+allocation can either be mapped uncached, or cached but then cache operations
+are used to ensure that the uncached hardware access sees a consistent view of
+memory contents.  On architectures where DMA is cache coherent then cached
+mappings do not require cache maintenance operations.
+
+```c
+uintptr_t ps_dma_pin(ps_dma_man_t *dma_man, void *addr, size_t size)
+void ps_dma_unpin(ps_dma_man_t *dma_man, void *addr, size_t size)
+```
+
+The two functions `ps_dma_pin` and `ps_dma_unpin` indicate to the system
+environment that the memory can be accessed by the hardware. The pinning
+operation is required because DMA access faults cannot be trapped and restarted
+by a system environment the same way that regular memory faults can be trapped
+and restarted for on-demand paging. `ps_dma_pin` gets provided with `addr` and
+`size` which describe a region of memory that has previously been allocated.
+The return value is an address that the software can provide to the hardware
+for accessing the memory.  `ps_dma_unpin` will inform the system environment
+that the hardware is finished accessing the memory. `addr` and `size` specify
+the memory range to unpin.
+
+```c
+void ps_dma_cache_op(const ps_dma_man_t *dma_man, void *addr, size_t size, dma_cache_op_t op)
+void ps_dma_cache_clean(const ps_dma_man_t *dma_man, void *addr, size_t size)
+void ps_dma_cache_invalidate(const ps_dma_man_t *dma_man, void *addr, size_t size)
+void ps_dma_cache_clean_invalidate(const ps_dma_man_t *dma_man, void *addr, size_t size)
+```
+
+The above functions perform cache operations that may be required to make the
+contents of memory visible to hardware or software. A clean operation will
+cause data in the cache to be written back to memory, invalidate will cause
+data in the cache to be marked invalid so that future reads will load the data
+in from memory, and clean/invalidate will clean the cache and then invalidate
+the cache. In a scenario where the software access is cached and the hardware
+access is uncached, a clean operation would be required before releasing DMA
+regions to the device and an invalidate operation would be required before
+accessing the DMA memory after getting the descriptor back from the device.
+
+## Implementation details
+
+It is up to the implementation when it chooses to create and destroy mappings
+for the caller and for the device hardware.  The interface guarantees that the
+memory is accessible for the caller between matching calls to `ps_dma_alloc`
+and `ps_dma_free` and accessible to the hardware between calls to `ps_dma_pin`
+and `ps_dma_unpin`.  Static implementations of this interface may leave all
+mappings in place for the lifetime of the system and simply return addresses to
+the caller when it uses the interface.
+
+It is up to the implementation whether it implements hardware protection
+mechanisms (IOMMU/SMMU). The interface does not provide a mechanism for error
+handling faults caused by invalid hardware access and so this feature is
+essentially hidden from the caller.
+
+## Potential future changes
+
+Some devices cannot handle 64-bit addresses for DMA but there is no way to
+specify this as a constraint in the original allocation call. This could likely
+be implemented as an additional flag in the allocation interface and the
+implementation would need to be able to provide 32-bit memory allocations.
+Implementations that are able to use a hardware MMU to create device mappings
+likely will not be affected by this issue as they can create mappings less than
+`2^32` that can access physical memory located higher than `2^32`.
+
+Interface support for dealing with scatter-gather lists may be added in the
+future in response to performance optimisations.  Callers can currently
+assemble scatter-gather lists from a collection of allocated DMA regions.
diff --git a/libplatsupport/docs/driver_environment/ps_interface_registration_ops_t.md b/libplatsupport/docs/driver_environment/ps_interface_registration_ops_t.md
new file mode 100644
index 0000000..7540d5d
--- /dev/null
+++ b/libplatsupport/docs/driver_environment/ps_interface_registration_ops_t.md
@@ -0,0 +1,68 @@
+<!--
+     Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+
+     SPDX-License-Identifier: CC-BY-SA-4.0
+-->
+
+# Interface registration interface
+
+`ps_interface_registration_ops_t` is an interface for registering additional
+interfaces within a `ps_io_ops_t` instance. These interfaces may then be used
+by future users of the `ps_io_ops_t` instance for handling more complex
+operations than those provided in the statically defined interfaces.
+
+<https://github.com/seL4/util_libs/blob/master/libplatsupport/include/platsupport/interface_registration.h>
+
+## Usage
+
+This interface provides a way for registering interface instances, and for
+locating such registered interface instances.
+
+```c
+int ps_interface_register(ps_interface_registration_ops_t *interface_registration_ops, ps_interface_type_t interface_type, void *interface_instance, char **properties)
+int ps_interface_unregister(ps_interface_registration_ops_t *interface_registration_ops, ps_interface_type_t interface_type, void *interface_instance)
+```
+
+Registering an interface involves providing an initialised interface,
+`interface_instance`, of type `interface_type`. A `ps_interface_type_t` is an
+enumeration of interfaces type IDs.  Each value of this enumeration refers to a
+specific interface and indicates how the type of `interface_instance` is
+interpreted. A user of the interface would need to know about the interface
+type referred to in order to correctly interpret the interface.  The
+`properties` argument given to `ps_interface_register` contains a list of
+`key=value` strings that can be used to identify an interface instance when it
+is being selected by a user.
+
+An interface can be unregistered by calling `ps_interface_unregister` with the
+same arguments.  An interface may be unregistered if it only supports a single
+user and the user of the interface unregisters it while it is being used. There
+is no way for an interface that is unregistered to be taken away from any
+existing users of it.  This would need to be handled by the interface instance
+itself.
+
+```c
+int ps_interface_find(ps_interface_registration_ops_t *interface_registration_ops, ps_interface_type_t interface_type, ps_interface_search_handler_t handler, void *handler_data)
+int (*ps_interface_search_handler_t)(void *handler_data, void *interface_instance, char **properties)
+```
+
+When searching for an interface, `ps_interface_find` is given an
+`interface_type` and a handler to be called for each interface instance it has
+of a given type.  The handler will be called with the `interface_instance` and
+`properties` parameters that were provided when the interface was registered.
+This allows the caller of `ps_interface_find` to select a valid interface
+instance.
+
+## Implementation details
+
+The contents of `properties` that are given to `ps_interface_register` need to
+be copied by the implementation so that it has its own record. This allows the
+caller to free the `properties` once the interface has been registered.  When
+`ps_interface_unregister` is called, the implementation is allowed to free its
+copy of properties. If an interface instance is destroyed, it is up to that
+interface instance to handle cleaning up its resources, including the memory
+that `void *interface_instance` refers to.
+
+`ps_interface_type_t` represents a global namespace for different interface
+types. Interface types will need to coordinate to ensure that multiple
+interface types do not end up with the same enum value.
+
diff --git a/libplatsupport/docs/driver_environment/ps_io_fdt_t.md b/libplatsupport/docs/driver_environment/ps_io_fdt_t.md
new file mode 100644
index 0000000..8e340c9
--- /dev/null
+++ b/libplatsupport/docs/driver_environment/ps_io_fdt_t.md
@@ -0,0 +1,144 @@
+<!--
+     Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+
+     SPDX-License-Identifier: CC-BY-SA-4.0
+-->
+
+# FDT interface
+
+`libplatsupport` provides interfaces and utility functions to interact with the
+flattened device tree (FDT) of a platform.
+
+<https://github.com/seL4/util_libs/blob/master/libplatsupport/include/platsupport/io.h>
+
+## Usage
+
+The interface provides one function:
+
+```c
+char *ps_io_fdt_get(const ps_io_fdt_t *io_fdt);
+```
+
+`io_fdt` is a handle to the instance of the interface being called. This is
+typically constructed as part of a system environment and then provided to the
+caller to use.
+
+The function is expected to operate synchronously, which means that their
+effects are visible once the function has returned.
+
+`ps_io_fdt_get` will retrieve the copy of the FDT that the interface has saved
+and return it to the user. The copy follows the shallow copy semantics in that
+it is only a reference to the FDT that the interface holds.
+
+The FDT can be walked manually or it can be passed to a number of utility
+functions for parsing and mapping resources.
+
+### Device tree parsing utility functions
+
+<https://github.com/seL4/util_libs/blob/master/libplatsupport/include/platsupport/fdt.h>
+
+These utility functions cover the common FDT use cases, for example, reading
+the `regs` and `interrupts/interrupts-extended` properties to map registers and
+allocate hardware interrupts.
+
+The functions are designed in such a way that they parse the properties and
+invoke a callback on each instance in the properties field. Each callback is
+given information about the current instance, the total number of instances and
+a user-supplied token. It is up to the driver providing the callback function as
+to what is done with the property information passed to it, for example, it
+could use the information to allocate appropriate hardware resources.
+
+The key functions in this interface are described below.
+
+```c
+int ps_fdt_read_path(ps_io_fdt_t *io_fdt, ps_malloc_ops_t *malloc_ops, const char *path, ps_fdt_cookie_t **ret_cookie);
+```
+
+Given a device tree path, this function will return a cookie that can be used in
+other functions in this library.
+
+```c
+int ps_fdt_walk_registers(ps_io_fdt_t *io_fdt, ps_fdt_cookie_t *cookie, reg_walk_cb_fn_t callback, void *token);
+```
+
+This function walks the `regs` property of the device node (if any)
+corresponding to the input cookie and invokes a callback function at each
+register instance of the field.
+
+```c
+int ps_fdt_walk_irqs(ps_io_fdt_t *io_fdt, ps_fdt_cookie_t *cookie, irq_walk_cb_fn_t callback, void *token);
+```
+
+This function walks the `interrupts/interrupts-extended` field of the device
+node (if any) corresponding to the cookie passed in and invokes a callback
+function at each interrupt instance of the field.
+
+To illustrate this interface, consider a snippet of the device tree from the NVIDIA Jetson TX2.
+
+```
+ahci-sata@3507000 {
+    compatible = "nvidia,tegra186-ahci-sata";
+    reg = < 0x00 0x3507000 0x00 0x2000 0x00 0x3501000 0x00 0x6000 0x00 0x3500000 0x00 0x1000 0x00 0x3a90 000 0x00 0x10000 >;
+    reg-names = "sata-ahci","sata-config","sata-ipfs","sata-aux";
+    interrupts = < 0x00 0xc5 0x04 >;
+    ...
+};
+```
+
+The `regs` property consists of a sequence of *address* and *size* cells. The
+parent node of this device (not shown) specifies that the number of address and
+size cells per register instance is 2.  So when we call the register walking
+function it would read the first instance in the register property (which is
+`<0x00 0x3507000 0x00 0x2000>` in this example) and invoke the callback with
+this information.  It would then invoke the callback again with the next
+instance (`<0x00 0x3501000 0x00 0x6000>`), and continue until the whole of the
+`regs` property has been processed.
+
+For convenience's sake, there are two functions which can be used to map
+resources without supplying an explicit callback. These can be useful when the
+structure of the targeted node in the FDT is known beforehand.
+
+```c
+void *ps_fdt_index_map_register(ps_io_ops_t *io_ops, ps_fdt_cookie_t *cookie, unsigned offset, pmem_region_t *ret_pmem);
+
+void ps_fdt_index_register_irq(ps_io_ops_t *io_ops, ps_fdt_cookie_t *cookie, unsigned offset, irq_callback_fn_t irq_callback, void *irq_callback_data);
+```
+
+### Interrupt parsing
+
+Note that parsing the `interrupts` property is a little special. Depending on
+the platform and device, the `interrupts` property of a device may have a
+special encoding format.
+
+For example, the Arm GICv2 specifies that each `interrupts` instance takes 3
+cells, the first cell describes the type of interrupt (e.g. SPI or PPI), the
+second cell describes the interrupt number, and the third cell describes the
+flags of the interrupt. On the GICv3, however, each instance can take 3 or 4
+cells as multiple formats are specified, and so processing the property
+requires a different process.
+
+Our approach to determining the interrupt property encoding is similar to
+Linux's approach. We follow the parent node's interrupt controller `phandle` to
+the interrupt controller node that is responsible for the target device. The
+`compatible` string of the interrupt controller is checked to determine what
+type of interrupt controller it is. The parsing is then delegated to a parser
+module that understands the interrupt controller and its expected `interrupts`
+property format.
+
+More information about the interrupt encodings is available in Linux's interrupt
+bindings documentation:
+<https://github.com/torvalds/linux/tree/master/Documentation/devicetree/bindings/interrupt-controller>.
+
+## Implementation details
+
+The implementation must keep a valid copy of the FDT that reflects all the
+devices or a part of the devices on the running platform. The implementation is
+not strictly required to support x86/pc99 or any platforms where the device
+setup on the platform can be dynamic and/or hotswappable.
+
+## Potential future changes
+
+For now, the interface only contains a function to retrieve the FDT of the
+platform. This may seem to be a unnecessary abstraction since we only provide
+one function, but this design allows us to easily extend the functionality, if
+need be, in the future.
diff --git a/libplatsupport/docs/driver_environment/ps_io_mapper_t.md b/libplatsupport/docs/driver_environment/ps_io_mapper_t.md
new file mode 100644
index 0000000..09c808c
--- /dev/null
+++ b/libplatsupport/docs/driver_environment/ps_io_mapper_t.md
@@ -0,0 +1,117 @@
+<!--
+     Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+
+     SPDX-License-Identifier: CC-BY-SA-4.0
+-->
+
+# Memory Mapped I/O interface
+
+`ps_io_mapper_t` is an interface for providing access to device memory (for
+memory mapped I/O) by creating memory mappings in an address space.
+
+<https://github.com/seL4/util_libs/blob/master/libplatsupport/include/platsupport/io.h>
+
+## Usage
+
+The interface provides two functions:
+
+```c
+void * ps_io_map(const ps_io_mapper_t *io_mapper, uintptr_t paddr, size_t size, int cached, ps_mem_flags_t flags)
+void ps_io_unmap(const ps_io_mapper_t *io_mapper, void *vaddr, size_t size)
+```
+
+`io_mapper` is a handle to the instance of the interface being called. This is
+typically constructed as part of a system environment and then provided to the
+caller to use.
+
+Both functions are expected to operate synchronously, which means that their
+effects are visible once the function has returned.
+
+`ps_io_map` will try to create a mapping region of size `size` and starting
+physical address of `paddr`. The architecture specific mapping attributes will
+be set based on the values of `cached` and `flags`. The return value indicates
+the virtual address of `paddr` in the new mapping or `NULL` will be returned if
+a mapping was not created. The values that the `flags` parameter can take are
+currently:
+
+```c
+typedef enum ps_mem_flags {
+    PS_MEM_NORMAL, /* No hints, consider 'normal' memory */
+    PS_MEM_HR,     /* Host typically reads */
+    PS_MEM_HW      /* Host typically writes */
+} ps_mem_flags_t;
+```
+
+`ps_io_unmap` will likely remove a mapping created by `ps_io_map`. The mapping
+to remove is identified by its virtual address and size, `vaddr` and `size`.
+There is no return value. Implementations are not required to remove the
+mapping when this is called, but a caller is not allowed to access the mapping
+after `ps_io_unmap` is called.
+
+Callers of this interface are expected to know the address of physical memory
+that they intend to access. Anonymous style mappings, where the physical
+address is unspecified, should be provided by a different interface.
+
+`paddr` and `size` will typically describe a region that can be constructed
+from valid hardware frame sizes.  If this is not the case then the created
+mapping should cover the entire region requested but the return value will
+specify the virtual address corresponding to the `paddr` requested.
+
+It is up to the implementation of this interface how to handle access control.
+If the caller tries to create a mapping with different mapping attributes than
+what it has access rights for it is up to the implementation to return a `NULL`
+mapping, or to return an address for a mapping that may result in a memory
+access fault when accessed.
+
+It is expected that device memory mappings are created during device
+initialisation and will not be created in a fastpath scenario where performance
+is more critical.
+
+## Implementation details
+
+A goal for this interface is to allow implementations for both static and
+dynamic environments. An example of a static environment implementation is
+where all of the mappings are created during program initialisation and mapping
+calls to this interface simply return the existing mappings, while unmapping
+calls have no observable effect. An example of a dynamic environment
+implementation is where a mapping is created or destroyed in direct response to
+calls to this interface.
+
+In some platforms, it is possible that register physical addresses can exist in
+chunks that are smaller than the smallest hardware page, therefore, it is not
+feasible to expect any implementation to validate that all physical addresses
+being mapped are valid. Additionally, certain device registers may have
+additional protections that are not managed by a virtual memory system and
+likely outside of any implementation's responsibilities.
+
+Virtual addresses returned by an implementation likely exist in an address
+space with other address allocations from other interfaces and therefore the
+implementation would need to be aware of these and not return address ranges
+that would overlap with other addresses. An implementation should use a common
+address space allocator for obtaining valid virtual address regions to then map
+physical memory into.
+
+Access control policies for access to underlying memory can be implemented. The
+interface can currently only return `NULL` to indicate that a mapping was not
+created.  If a physical region requested is invalid the implementation is
+allowed to return `NULL` to indicate no mapping was created, or to return a
+virtual address that has less access rights than requested or even a virtual
+address that is not mapped to the physical memory requested. It is expected
+that this interface is used on architectures with memory management systems
+that generate memory faults when a program accesses memory invalid permissions.
+
+Implementations are not required to perform any accounting internally. Calls to
+`ps_io_unmap` that do not correspond to earlier calls to `ps_io_map` can be
+ignored.
+
+## Potential future changes
+
+The interface currently does not provide a mechanism for callers to provide
+exact hardware mapping attributes and must specify them via the `cached` and
+`flags` arguments. It may be preferable to explicitly provide these attributes
+to avoid ambiguity.
+
+There is currently no way for the caller to be synchronously informed about
+what caused a `NULL` value to be returned.  This does not enable a caller to
+respond differently to different error conditions. Such error conditions could
+be generic or implementation defined.
diff --git a/libplatsupport/docs/driver_environment/ps_io_port_ops_t.md b/libplatsupport/docs/driver_environment/ps_io_port_ops_t.md
new file mode 100644
index 0000000..9bddde9
--- /dev/null
+++ b/libplatsupport/docs/driver_environment/ps_io_port_ops_t.md
@@ -0,0 +1,81 @@
+<!--
+     Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+
+     SPDX-License-Identifier: CC-BY-SA-4.0
+-->
+
+# Architectural I/O operations
+
+`ps_io_port_ops_t` is an interface for performing architectural I/O operations,
+i.e. device I/O that cannot be performed via memory-mapped IO. One example of
+this is I/O Ports on x86.
+
+<https://github.com/seL4/util_libs/blob/master/libplatsupport/include/platsupport/io.h>
+
+## Usage
+
+The interface provides two functions:
+
+```c
+int ps_io_port_in(const ps_io_port_ops_t *port_ops, uint32_t port, int io_size, uint32_t *result)
+int ps_io_port_out(const ps_io_port_ops_t *port_ops, uint32_t port, int io_size, uint32_t val)
+```
+
+`port_ops` is a handle to the instance of the interface being called. This is
+typically constructed as part of a system environment and then provided to the
+caller to use.
+
+Both functions are expected to operate synchronously, which means that their
+effects are visible once the function has returned.
+
+`ps_io_port_in` will perform a blocking read operation on a port. `result` will
+be set to the result of the read.  `io_size` specifies the size, in bytes, of
+the read and cannot be larger than 4. The `port` contains the architectural
+address of the port that the operation applies to. The return value is used to
+indicate if the operation succeeded.
+
+`ps_io_port_out` will perform a blocking write operation on a port. `val`
+contains the value to be written and `io_size` the size, in bytes, of the data
+to be written and also cannot be larger than 4. For values of `io_size` less
+than 4, the input value, `val`, will be cast to a variable of the smaller size
+and data that is removed in the cast will be ignored.  The return value is used
+to indicate if the operation succeeded.
+
+Acceptable values of `port` depend on the implementation and an instance of
+this interface is expected to return an error for port values that are
+unrecognised.  Valid ports may change over the lifetime of the interface if the
+implementation can dynamically add or remove ports.
+
+## Implementation details
+
+While it would be possible to use this interface for devices that use
+memory-mapped I/O (MMIO) it is not a design goal and it would be better to use
+the `ps_io_mapper_t` interface instead.
+
+It is expected that these in and out operations complete within a reasonable
+amount of time and that the interface functions are effectively non-blocking.
+
+An implementation may provide its own mechanisms for dynamically changing and
+querying available ports. This would require a custom interface that the
+implementation provides.  Such an interface could be used by the caller or by
+the system environment but this would be defined by the implementation.
+
+## Potential future changes
+
+This interface is currently intended for handling x86 I/O Port operations via
+the `in8, in16, in32, out8, out16, out32` instructions as these are protected
+operations and must be performed in a privileged processor mode.  Arm could
+have a use for this interface to allow performing secure monitor calls which is
+how communication with software running in the "Secure" security state is
+performed.  Supporting this would require extending the interface to allow for
+providing more arguments than a single 32-bit value.
+
+It may be necessary to provide a consistent way of querying which ports an
+interface instance supports.  Currently it is assumed that the caller knows
+this implicitly. This may be due to providing a list of ports during the
+construction of the interface, or some shared configuration.
+
+Performance optimisations such as batching operations may be needed in the
+future. Currently we assume that these ports are used for low bandwidth
+configuration, and any operations that require higher data transfer bandwidth
+use an MMIO interface.
diff --git a/libplatsupport/docs/driver_environment/ps_irq_ops_t.md b/libplatsupport/docs/driver_environment/ps_irq_ops_t.md
new file mode 100644
index 0000000..467bbea
--- /dev/null
+++ b/libplatsupport/docs/driver_environment/ps_irq_ops_t.md
@@ -0,0 +1,98 @@
+<!--
+     Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+
+     SPDX-License-Identifier: CC-BY-SA-4.0
+-->
+
+# Interrupt handling interface
+
+`ps_irq_ops_t` is an interface for registering interrupt handlers to be called
+when hardware interrupts are received.
+
+<https://github.com/seL4/util_libs/blob/master/libplatsupport/include/platsupport/irq.h>
+
+## Usage
+
+This interface allows interrupt handlers to be registered for different IRQs.
+If an interrupt is received matching an IRQ that has a registered handler, the
+handler can be called. The handler is given a function for acknowledging the
+interrupt which it needs to call once the interrupt has been handled. Once the
+interrupt has been acknowledged then the interrupt can be received again.
+
+```c
+irq_id_t ps_irq_register(ps_irq_ops_t *irq_ops, ps_irq_t irq, irq_callback_fn_t callback, void *callback_data)
+int ps_irq_unregister(ps_irq_ops_t *irq_ops, irq_id_t irq_id)
+```
+
+Registering and unregistering interrupt handler actions are performed by
+calling `ps_irq_register` and `ps_irq_unregister`. `irq` identifies an
+interrupt to register the handler for. A `ps_irq_t` is a union that allows
+different interrupt types to be passed into the interface.  An implementation
+cannot be expected to be able to match any `irq` value to a hardware interrupt
+due to different ways interrupts can be described across different
+architectures. The `irq` value is also used to specify which attributes the
+interrupt has. An example is the `irq.trigger` type which allows a handler to
+be registered with a trigger that is edge based or level based for a particular
+interrupt number.
+
+Registering more than one interrupt handler for a single interrupt is not
+allowed. This is because there is no generic way to handle acknowledgement of
+the interrupt. If multiple handlers need to be called for a particular
+interrupt, then an additional handler can be created that calls the multiple
+other handlers and picks a policy for when to acknowledge the interrupt.
+
+`ps_irq_unregister` causes the interrupt handler to be unregistered for a
+particular interrupt. Multiple calls to `ps_irq_register` for the same `irq`
+need to have matching calls to `ps_irq_unregister` before each new
+`ps_irq_register`.  This is so that the implementation is able to detect errors
+for mistakenly trying to register different handlers for the same hardware
+interrupt.
+
+```c
+void (*irq_callback_fn_t)(void *data, ps_irq_acknowledge_fn_t acknowledge_fn, void *ack_data)
+int (*ps_irq_acknowledge_fn_t)(void *ack_data)
+```
+
+The callback function provided to `ps_irq_register` will be called with the
+`data` parameter that was provided when the handler was registered.
+Additionally `acknowledge_fn` and `ack_data` will be provided for acknowledging
+the interrupt. The interrupt handler will not be called again until the ack
+function is called. It is not required to call the ack function before the
+callback function returns. This enables situations where sufficiently handling
+the interrupt requires an event to happen asynchronously.
+
+## Implementation details
+
+Any interrupts that are received before an IRQ handler is registered do not
+need to be tracked. It is expected that the caller registering an interrupt
+handler is able to poll for any events that need to be processed after
+registering the handler. The implementation is required to configure the
+interrupt handling such that if the hardware generates an interrupt after the
+handler is registered it will be possible to call the interrupt handler.
+
+Given that it is possible for the `acknowledge_fn` given to the interrupt
+handler to be called after the interrupt handler has returned, the
+implementation will need to ensure it is able to keep track of any resources
+allocated for the handler until the `acknowledge_fn` is called. If
+`ps_irq_unregister` is called, any existing `acknowledge_fn`s for that `irq`
+can be cleaned up.
+
+Multiple values of `irq` could map to the same hardware interrupt. In these
+cases it is not valid for a different interrupt handler to be registered for
+different values. The implementation needs to reject any additional
+`ps_irq_register` calls for these `irq`s.
+
+Reconfiguring an interrupt is possible by first calling `ps_irq_unregister`,
+followed by `ps_irq_register` on the same interrupt but with a different value
+of `irq` that has different attributes.
+
+An implementation that would like to case match over the different
+`ps_irq_ops_t` types should be aware that this union is expected to get
+additional types added that certain implementations are not aware of. An
+implementation should be able to handle the case where it sees a `ps_irq_ops_t`
+type that it is unable to handle, and fail accordingly.
+
+## Potential future changes
+
+`ps_irq_ops_t` will be extended when new types of hardware interrupt
+configurations are supported.
diff --git a/libplatsupport/docs/driver_environment/ps_malloc_ops_t.md b/libplatsupport/docs/driver_environment/ps_malloc_ops_t.md
new file mode 100644
index 0000000..e5efd8e
--- /dev/null
+++ b/libplatsupport/docs/driver_environment/ps_malloc_ops_t.md
@@ -0,0 +1,53 @@
+<!--
+     Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+
+     SPDX-License-Identifier: CC-BY-SA-4.0
+-->
+
+# Memory allocation interface
+
+`ps_malloc_ops_t` is an interface to provide implementations for allocating
+anonymous memory using malloc-like functions.
+
+<https://github.com/seL4/util_libs/blob/master/libplatsupport/include/platsupport/io.h>
+
+## Usage
+
+The functions in this interface are very similar to POSIX functions `malloc`,
+`calloc` and `free`. This interface is provided to enable allocation of memory
+from an underlying memory allocator that supports allocating memory sizes
+smaller than a hardware page.
+
+```c
+int ps_malloc(const ps_malloc_ops_t *ops, size_t size, void **ptr)
+int ps_calloc(const ps_malloc_ops_t *ops, size_t nmemb, size_t size, void **ptr)
+```
+
+The additional argument `ptr` is used to return the allocated address. The
+return value is then used for reporting whether the allocation failed and
+provides an error code.  `ps_calloc` will clear the allocated memory and takes
+an `nmemb` argument for multiple elements as `calloc` does.
+
+```c
+int ps_free(const ps_malloc_ops_t *ops, size_t size, void *ptr)
+```
+
+`ps_free` is used to free only memory allocations created by `ps_malloc` and
+`ps_calloc`.  Compared to POSIX `free` this function takes an additional `size`
+argument that can be used by the implementation for stricter checking of
+freeing of memory regions. Additionally, a return value is provided to allow
+reporting of errors.
+
+## Implementation details
+
+A valid implementation of this interface would be to call the underlying POSIX
+functions `malloc`, `calloc`, and `free`.
+
+Multiple instances of this interface could be used to track memory allocations
+of different driver instances within the same software component to allow
+destruction of a driver instance and reclamation of resources without having to
+destroy the software component.
+
+## Future changes
+
+Adding a `realloc` like function may occur in the future.
diff --git a/libplatsupport/docs/index.md b/libplatsupport/docs/index.md
new file mode 100644
index 0000000..4f39b00
--- /dev/null
+++ b/libplatsupport/docs/index.md
@@ -0,0 +1,21 @@
+<!--
+     Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+
+     SPDX-License-Identifier: CC-BY-SA-4.0
+-->
+
+# libplatsupport
+
+This documents the interfaces and drivers provided in libplatsupport.
+
+## Background
+
+This library provides interface definitions for writing user level device
+drivers. It also provides drivers for a variety of devices on a variety of
+platforms.
+
+## Contents
+
+- [Driver environment](driver_environment): The driver environment provides a
+  series of interfaces for writing hardware device drivers, including hardware
+  access interfaces and driver interfaces.
diff --git a/libplatsupport/include/platsupport/chardev.h b/libplatsupport/include/platsupport/chardev.h
index a46e1a6..28085f8 100644
--- a/libplatsupport/include/platsupport/chardev.h
+++ b/libplatsupport/include/platsupport/chardev.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/delay.h b/libplatsupport/include/platsupport/delay.h
index ac6659a..d35d218 100644
--- a/libplatsupport/include/platsupport/delay.h
+++ b/libplatsupport/include/platsupport/delay.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/driver_module.h b/libplatsupport/include/platsupport/driver_module.h
index 6817440..1e9ae0a 100644
--- a/libplatsupport/include/platsupport/driver_module.h
+++ b/libplatsupport/include/platsupport/driver_module.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2020, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/fdt.h b/libplatsupport/include/platsupport/fdt.h
index 06814dd..6060b6e 100644
--- a/libplatsupport/include/platsupport/fdt.h
+++ b/libplatsupport/include/platsupport/fdt.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/interface_registration.h b/libplatsupport/include/platsupport/interface_registration.h
index 6a4a03b..ec938be 100644
--- a/libplatsupport/include/platsupport/interface_registration.h
+++ b/libplatsupport/include/platsupport/interface_registration.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2020, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/interface_types.h b/libplatsupport/include/platsupport/interface_types.h
index 1c1c838..6199d47 100644
--- a/libplatsupport/include/platsupport/interface_types.h
+++ b/libplatsupport/include/platsupport/interface_types.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2020, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/io.h b/libplatsupport/include/platsupport/io.h
index 252d8ac..0addcd9 100644
--- a/libplatsupport/include/platsupport/io.h
+++ b/libplatsupport/include/platsupport/io.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/irq.h b/libplatsupport/include/platsupport/irq.h
index e0c1d00..8119b9d 100644
--- a/libplatsupport/include/platsupport/irq.h
+++ b/libplatsupport/include/platsupport/irq.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/local_time_manager.h b/libplatsupport/include/platsupport/local_time_manager.h
index 0bf2a03..0ab534f 100644
--- a/libplatsupport/include/platsupport/local_time_manager.h
+++ b/libplatsupport/include/platsupport/local_time_manager.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/ltimer.h b/libplatsupport/include/platsupport/ltimer.h
index 537b011..6525412 100644
--- a/libplatsupport/include/platsupport/ltimer.h
+++ b/libplatsupport/include/platsupport/ltimer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/pmem.h b/libplatsupport/include/platsupport/pmem.h
index 0b1a603..f1f3913 100644
--- a/libplatsupport/include/platsupport/pmem.h
+++ b/libplatsupport/include/platsupport/pmem.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/serial.h b/libplatsupport/include/platsupport/serial.h
index 774b5f1..aaee340 100644
--- a/libplatsupport/include/platsupport/serial.h
+++ b/libplatsupport/include/platsupport/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/sync/atomic.h b/libplatsupport/include/platsupport/sync/atomic.h
index c1575b8..f5949d7 100644
--- a/libplatsupport/include/platsupport/sync/atomic.h
+++ b/libplatsupport/include/platsupport/sync/atomic.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/sync/spinlock.h b/libplatsupport/include/platsupport/sync/spinlock.h
index 2da1572..71b6be2 100644
--- a/libplatsupport/include/platsupport/sync/spinlock.h
+++ b/libplatsupport/include/platsupport/sync/spinlock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/sync/sync.h b/libplatsupport/include/platsupport/sync/sync.h
index 9099a8d..5e33481 100644
--- a/libplatsupport/include/platsupport/sync/sync.h
+++ b/libplatsupport/include/platsupport/sync/sync.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/time_manager.h b/libplatsupport/include/platsupport/time_manager.h
index a76b848..888f51f 100644
--- a/libplatsupport/include/platsupport/time_manager.h
+++ b/libplatsupport/include/platsupport/time_manager.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/timer.h b/libplatsupport/include/platsupport/timer.h
index 6632bc6..e06254c 100644
--- a/libplatsupport/include/platsupport/timer.h
+++ b/libplatsupport/include/platsupport/timer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/tmu.h b/libplatsupport/include/platsupport/tmu.h
index 6ccb2b2..ff4a3e9 100644
--- a/libplatsupport/include/platsupport/tmu.h
+++ b/libplatsupport/include/platsupport/tmu.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/include/platsupport/tqueue.h b/libplatsupport/include/platsupport/tqueue.h
index e54839a..738bea6 100644
--- a/libplatsupport/include/platsupport/tqueue.h
+++ b/libplatsupport/include/platsupport/tqueue.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/mach_include/bcm283x/platsupport/mach/mailbox.h b/libplatsupport/mach_include/bcm283x/platsupport/mach/mailbox.h
new file mode 100644
index 0000000..0f18899
--- /dev/null
+++ b/libplatsupport/mach_include/bcm283x/platsupport/mach/mailbox.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2021, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <utils/util.h>
+#include <platsupport/io.h>
+
+// Mailbox status codes
+enum {
+    MAILBOX_OK                  = 0,
+    MAILBOX_ERR_INTERNAL        = -1,
+    MAILBOX_ERR_INVALID         = -2,
+    MAILBOX_ERR_BUSY            = -3,
+    MAILBOX_ERR_DMA             = -4,
+    MAILBOX_ERR_READ            = -5,
+    MAILBOX_ERR_WRITE           = -6,
+    MAILBOX_ERR_BUFFER          = -7,
+    MAILBOX_ERR_TAG             = -8
+};
+
+typedef struct mailbox {
+    /**
+     * Mailbox request/response message.
+     * @param   mbox                Initialized mailbox driver instance.
+     * @param   tag_id              Tag ID encoding a mailbox command.
+     * @param   request_tag         Pointer to request tag struct object.
+     * @param   request_tag_size    Size of request tag struct object.
+     * @param   response_tag        Pointer to response tag struct object.
+     * @param   response_tag_size   Size of response tag struct object.
+     * @return 0 on success. Non-zero on error.
+     */
+    int (*message)(struct mailbox   *mbox,
+                   uint32_t         tag_id,
+                   void             *request_tag,
+                   uint32_t         request_tag_size,
+                   void             *response_tag,
+                   uint32_t         response_tag_size);
+    /* Device data */
+    void *priv;
+    /* DMA allocator */
+    ps_dma_man_t *dma_man;
+    /* Buffer for mailbox requests/responses */
+    void *buffer;
+    /* Physical Address of the DMA region */
+    uintptr_t phys_addr;
+} mailbox_t;
+
+// See: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
+#define CODE_BUFFER_REQUEST_PROCESS     0x00000000
+#define CODE_BUFFER_RESPONSE_SUCCESS    0x80000000
+#define CODE_BUFFER_RESPONSE_FAILURE    0x80000001
+typedef struct MailboxInterface_PropertyBuffer {
+    uint32_t    buffer_size;
+    uint32_t    code;
+    uint8_t     tags[0];
+}
+MailboxInterface_PropertyBuffer_t;
+
+// See: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
+// bit 0-30: value length in bytes
+// bit 31:   request (clear) / response (set)
+#define VALUE_LENGTH_RESPONSE           (1u << 31)
+typedef struct MailboxInterface_PropertyTag {
+    uint32_t    tag_id;
+    uint32_t    value_buffer_size;
+    uint32_t    value_length;
+}
+MailboxInterface_PropertyTag_t;
+
+/**
+ * Initialise the mailbox subsystem and provide a handle for access
+ * @param[in]  io_ops   io operations for device initialisation
+ * @param[out] mailbox  A mailbox handle structure to initialise
+ * @return              0 on success, errno value otherwise
+ */
+int mailbox_init(ps_io_ops_t *io_ops, mailbox_t *mailbox);
+
+/**
+ * Destroy the mailbox by freeing the allocated DMA region.
+ * @param[in] mailbox   A mailbox handle structure to destroy
+ * @return              0 on success, errno value otherwise
+ */
+int mailbox_destroy(mailbox_t *mailbox);
diff --git a/libplatsupport/mach_include/bcm283x/platsupport/mach/mailbox_util.h b/libplatsupport/mach_include/bcm283x/platsupport/mach/mailbox_util.h
new file mode 100644
index 0000000..aaf107a
--- /dev/null
+++ b/libplatsupport/mach_include/bcm283x/platsupport/mach/mailbox_util.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2021, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <stdbool.h>
+#include <platsupport/plat/mailbox.h>
+
+// Clock IDs: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface#clocks
+enum {
+    CLOCK_ID_EMMC = 1,
+    CLOCK_ID_UART,
+    CLOCK_ID_ARM,
+    CLOCK_ID_CORE,
+    CLOCK_ID_V3D,
+    CLOCK_ID_H264,
+    CLOCK_ID_ISP,
+    CLOCK_ID_SDRAM,
+    CLOCK_ID_PIXEL,
+    CLOCK_ID_PWM,
+    CLOCK_ID_HEVC,
+    CLOCK_ID_EMMC2,
+    CLOCK_ID_M2MC,
+    CLOCK_ID_PIXEL_BVB
+};
+
+// Device IDs: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface#power
+enum {
+    DEVICE_ID_SD_CARD = 0,
+    DEVICE_ID_UART0,
+    DEVICE_ID_UART1,
+    DEVICE_ID_USB_HCD,
+    DEVICE_ID_I2C0,
+    DEVICE_ID_I2C1,
+    DEVICE_ID_I2C2,
+    DEVICE_ID_SPI,
+    DEVICE_ID_CCP2TX
+};
+
+////////////////////////////////////////////////////////////////////////////////
+//--------------------------------Property Tags-------------------------------//
+////////////////////////////////////////////////////////////////////////////////
+
+// See: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
+#define TAG_SET_POWER_STATE     0x00028001
+#define TAG_GET_CLOCK_RATE      0x00030002
+#define TAG_GET_MAC_ADDRESS     0x00010003
+
+// TODO: Add more property tags if needed
+
+////////////////////////////////////////////////////////////////////////////////
+//-----------------------------Request/Reponse Tags---------------------------//
+////////////////////////////////////////////////////////////////////////////////
+
+// See: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface#set-power-state
+#define SET_POWER_STATE_OFF             (0u << 0)
+#define SET_POWER_STATE_ON              (1u << 0)
+#define SET_POWER_STATE_WAIT            (1u << 1)
+typedef struct {
+    MailboxInterface_PropertyTag_t tag;
+    uint32_t device_id;
+    uint32_t state;
+}
+PropertyTag_SetPowerState_Request_t;
+
+#define SET_POWER_STATE_NO_DEVICE       (1u << 1)
+typedef struct {
+    MailboxInterface_PropertyTag_t tag;
+    uint32_t device_id;
+    uint32_t state;
+}
+PropertyTag_SetPowerState_Response_t;
+
+// See: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface#get-clock-rate
+typedef struct {
+    MailboxInterface_PropertyTag_t tag;
+    uint32_t clock_id;
+}
+PropertyTag_GetClockRate_Request_t;
+
+typedef struct {
+    MailboxInterface_PropertyTag_t tag;
+    uint32_t clock_id;
+    uint32_t rate;
+}
+PropertyTag_GetClockRate_Response_t;
+
+// See: https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface#get-board-mac-address
+#define MAC_ADDRESS_SIZE 6
+typedef struct {
+    MailboxInterface_PropertyTag_t tag;
+}
+PropertyTag_GetMACAddress_Request_t;
+
+typedef struct {
+    MailboxInterface_PropertyTag_t tag;
+    uint8_t mac_address[MAC_ADDRESS_SIZE];
+}
+PropertyTag_GetMACAddress_Response_t;
+
+// TODO: Add more request/reponse tags if needed
+
+////////////////////////////////////////////////////////////////////////////////
+//-----------------------------Mailbox Functions------------------------------//
+////////////////////////////////////////////////////////////////////////////////
+
+bool mailbox_set_power_state_on(mailbox_t *mbox, uint32_t device_id);
+
+int mailbox_get_clock_rate(mailbox_t *mbox, uint32_t clock_id);
+
+bool mailbox_get_mac_address(mailbox_t *mbox, uint8_t buffer[MAC_ADDRESS_SIZE]);
+
+// TODO: Add more mailbox functions if needed
diff --git a/libplatsupport/mach_include/exynos/platsupport/mach/pmic.h b/libplatsupport/mach_include/exynos/platsupport/mach/pmic.h
index 74794ee..de86454 100644
--- a/libplatsupport/mach_include/exynos/platsupport/mach/pmic.h
+++ b/libplatsupport/mach_include/exynos/platsupport/mach/pmic.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/mach_include/exynos/platsupport/mach/pmic_rtc.h b/libplatsupport/mach_include/exynos/platsupport/mach/pmic_rtc.h
index 91cbaa0..13bbc49 100644
--- a/libplatsupport/mach_include/exynos/platsupport/mach/pmic_rtc.h
+++ b/libplatsupport/mach_include/exynos/platsupport/mach/pmic_rtc.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/mach_include/exynos/platsupport/mach/pwm.h b/libplatsupport/mach_include/exynos/platsupport/mach/pwm.h
index 8f862a4..557773a 100644
--- a/libplatsupport/mach_include/exynos/platsupport/mach/pwm.h
+++ b/libplatsupport/mach_include/exynos/platsupport/mach/pwm.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/mach_include/exynos/platsupport/mach/serial.h b/libplatsupport/mach_include/exynos/platsupport/mach/serial.h
index 5aaea80..13f3a51 100644
--- a/libplatsupport/mach_include/exynos/platsupport/mach/serial.h
+++ b/libplatsupport/mach_include/exynos/platsupport/mach/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/mach_include/exynos/platsupport/mach/tmu.h b/libplatsupport/mach_include/exynos/platsupport/mach/tmu.h
index 9f31b4b..cf7855e 100644
--- a/libplatsupport/mach_include/exynos/platsupport/mach/tmu.h
+++ b/libplatsupport/mach_include/exynos/platsupport/mach/tmu.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/mach_include/imx/platsupport/mach/epit.h b/libplatsupport/mach_include/imx/platsupport/mach/epit.h
index 97fe14b..44bbcd1 100644
--- a/libplatsupport/mach_include/imx/platsupport/mach/epit.h
+++ b/libplatsupport/mach_include/imx/platsupport/mach/epit.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/mach_include/imx/platsupport/mach/gpt.h b/libplatsupport/mach_include/imx/platsupport/mach/gpt.h
index f9a18e0..600ebc5 100644
--- a/libplatsupport/mach_include/imx/platsupport/mach/gpt.h
+++ b/libplatsupport/mach_include/imx/platsupport/mach/gpt.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/mach_include/imx/platsupport/mach/serial.h b/libplatsupport/mach_include/imx/platsupport/mach/serial.h
index b8b250f..eaf423c 100644
--- a/libplatsupport/mach_include/imx/platsupport/mach/serial.h
+++ b/libplatsupport/mach_include/imx/platsupport/mach/serial.h
@@ -1,13 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
@@ -26,12 +21,18 @@
     PS_SERIAL2 = IMX_UART3,
     PS_SERIAL3 = IMX_UART4,
     PS_SERIAL4 = IMX_UART5,
+
 #if defined(CONFIG_PLAT_SABRE) || defined(CONFIG_PLAT_IMX8MM_EVK)
+
     PS_SERIAL_DEFAULT = IMX_UART2
-#elif defined(CONFIG_PLAT_WANDQ) || defined(CONFIG_PLAT_IMX7) || defined(CONFIG_PLAT_IMX8MQ_EVK)
+
+#elif defined(CONFIG_PLAT_WANDQ) || defined(CONFIG_PLAT_NITROGEN6SX) \
+      || defined(CONFIG_PLAT_IMX7_SABRE) || defined(CONFIG_PLAT_IMX8MQ_EVK)
+
     PS_SERIAL_DEFAULT = IMX_UART1
+
 #else
 #error "unknown imx platform selected!"
 #endif
-};
 
+};
diff --git a/libplatsupport/mach_include/nvidia/platsupport/mach/serial.h b/libplatsupport/mach_include/nvidia/platsupport/mach/serial.h
index a243e4c..bdd991e 100644
--- a/libplatsupport/mach_include/nvidia/platsupport/mach/serial.h
+++ b/libplatsupport/mach_include/nvidia/platsupport/mach/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 #include <autoconf.h>
diff --git a/libplatsupport/mach_include/nvidia/platsupport/mach/serial_tk1_tx1_defs.h b/libplatsupport/mach_include/nvidia/platsupport/mach/serial_tk1_tx1_defs.h
index 031e211..d1bc947 100644
--- a/libplatsupport/mach_include/nvidia/platsupport/mach/serial_tk1_tx1_defs.h
+++ b/libplatsupport/mach_include/nvidia/platsupport/mach/serial_tk1_tx1_defs.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/mach_include/nvidia/platsupport/mach/timer.h b/libplatsupport/mach_include/nvidia/platsupport/mach/timer.h
index b30feae..28bb499 100644
--- a/libplatsupport/mach_include/nvidia/platsupport/mach/timer.h
+++ b/libplatsupport/mach_include/nvidia/platsupport/mach/timer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/mach_include/nvidia/platsupport/mach/timer_tk1_tx1_defs.h b/libplatsupport/mach_include/nvidia/platsupport/mach/timer_tk1_tx1_defs.h
index 4b456ad..7d7d6ce 100644
--- a/libplatsupport/mach_include/nvidia/platsupport/mach/timer_tk1_tx1_defs.h
+++ b/libplatsupport/mach_include/nvidia/platsupport/mach/timer_tk1_tx1_defs.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/mach_include/omap/platsupport/mach/gpt.h b/libplatsupport/mach_include/omap/platsupport/mach/gpt.h
index 583d36a..95a42c1 100644
--- a/libplatsupport/mach_include/omap/platsupport/mach/gpt.h
+++ b/libplatsupport/mach_include/omap/platsupport/mach/gpt.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/mach_include/zynq/platsupport/mach/axi_uartlite.h b/libplatsupport/mach_include/zynq/platsupport/mach/axi_uartlite.h
index 4cd37fe..c59fab0 100644
--- a/libplatsupport/mach_include/zynq/platsupport/mach/axi_uartlite.h
+++ b/libplatsupport/mach_include/zynq/platsupport/mach/axi_uartlite.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 int axi_uartlite_init(void* vaddr, ps_chardevice_t *dev);
diff --git a/libplatsupport/mach_include/zynq/platsupport/mach/gpio.h b/libplatsupport/mach_include/zynq/platsupport/mach/gpio.h
index 942a059..c8f3972 100644
--- a/libplatsupport/mach_include/zynq/platsupport/mach/gpio.h
+++ b/libplatsupport/mach_include/zynq/platsupport/mach/gpio.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/mach_include/zynq/platsupport/mach/i2c.h b/libplatsupport/mach_include/zynq/platsupport/mach/i2c.h
index 781b762..4aeade1 100644
--- a/libplatsupport/mach_include/zynq/platsupport/mach/i2c.h
+++ b/libplatsupport/mach_include/zynq/platsupport/mach/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/mach_include/zynq/platsupport/mach/mux.h b/libplatsupport/mach_include/zynq/platsupport/mach/mux.h
index b687b7e..daacdbf 100644
--- a/libplatsupport/mach_include/zynq/platsupport/mach/mux.h
+++ b/libplatsupport/mach_include/zynq/platsupport/mach/mux.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/mach_include/zynq/platsupport/mach/timer.h b/libplatsupport/mach_include/zynq/platsupport/mach/timer.h
index 18f376c..04ee027 100644
--- a/libplatsupport/mach_include/zynq/platsupport/mach/timer.h
+++ b/libplatsupport/mach_include/zynq/platsupport/mach/timer.h
@@ -1,15 +1,10 @@
 /*
  * Copyright 2017, DornerWorks
- * Copyright 2020, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_DORNERWORKS_BSD)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
+
 /*
  * This data was produced by DornerWorks, Ltd. of Grand Rapids, MI, USA under
  * a DARPA SBIR, Contract Number D16PC00107.
diff --git a/libplatsupport/plat_include/am335x/platsupport/plat/clock.h b/libplatsupport/plat_include/am335x/platsupport/plat/clock.h
index 4a212a1..072a13d 100644
--- a/libplatsupport/plat_include/am335x/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/am335x/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/am335x/platsupport/plat/i2c.h b/libplatsupport/plat_include/am335x/platsupport/plat/i2c.h
index 9223614..5711a3b 100644
--- a/libplatsupport/plat_include/am335x/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/am335x/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/am335x/platsupport/plat/serial.h b/libplatsupport/plat_include/am335x/platsupport/plat/serial.h
index dc9e334..0ddb632 100644
--- a/libplatsupport/plat_include/am335x/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/am335x/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/am335x/platsupport/plat/timer.h b/libplatsupport/plat_include/am335x/platsupport/plat/timer.h
index f55aa53..79fa130 100644
--- a/libplatsupport/plat_include/am335x/platsupport/plat/timer.h
+++ b/libplatsupport/plat_include/am335x/platsupport/plat/timer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/apq8064/platsupport/plat/clock.h b/libplatsupport/plat_include/apq8064/platsupport/plat/clock.h
index c318e6c..3b608a6 100644
--- a/libplatsupport/plat_include/apq8064/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/apq8064/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/apq8064/platsupport/plat/i2c.h b/libplatsupport/plat_include/apq8064/platsupport/plat/i2c.h
index 14b63ec..40efe17 100644
--- a/libplatsupport/plat_include/apq8064/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/apq8064/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/apq8064/platsupport/plat/serial.h b/libplatsupport/plat_include/apq8064/platsupport/plat/serial.h
index d2342d2..345ec03 100644
--- a/libplatsupport/plat_include/apq8064/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/apq8064/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/apq8064/platsupport/plat/timer.h b/libplatsupport/plat_include/apq8064/platsupport/plat/timer.h
index 3865bee..b9c282c 100644
--- a/libplatsupport/plat_include/apq8064/platsupport/plat/timer.h
+++ b/libplatsupport/plat_include/apq8064/platsupport/plat/timer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 /* @AUTHOR(akroh@ertos.nicta.com.au) */
 
diff --git a/libplatsupport/plat_include/ariane/platsupport/plat/apb_timer.h b/libplatsupport/plat_include/ariane/platsupport/plat/apb_timer.h
new file mode 100644
index 0000000..26382ae
--- /dev/null
+++ b/libplatsupport/plat_include/ariane/platsupport/plat/apb_timer.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <platsupport/timer.h>
+
+#include <utils/util.h>
+#include <stdint.h>
+#include <stdbool.h>
+
+/* The input frequence is the CPU frequency which is 50MHz by default */
+#define APB_TIMER_INPUT_FREQ (50*1000*1000)
+#define APB_TIMER_PADDR   0x18000000
+
+/* Multiple timers */
+#define APB_TIMER_DIST      0x10
+#define APB_TIMER_NUM       2
+#define APB_TIMER_BASE(n)   APB_TIMER_DIST * n
+
+#define CMP_WIDTH               32
+#define APB_TIMER_CTRL_ENABLE   BIT(0);
+#define CMP_MASK                MASK(CMP_WIDTH)
+
+/* Timer IRQs */
+#define APB_TIMER_PLIC_BASE     4
+#define APB_TIMER_IRQ_OVF(n)    APB_TIMER_PLIC_BASE + 2*n + 0x0
+#define APB_TIMER_IRQ_CMP(n)    APB_TIMER_PLIC_BASE + 2*n + 0x1
+
+typedef struct {
+    /* vaddr apb_timer is mapped to */
+    void *vaddr;
+} apb_timer_config_t;
+
+typedef struct apb_timer {
+    volatile struct apb_timer_map *apb_timer_map;
+    uint64_t time_h;
+} apb_timer_t;
+
+struct apb_timer_map {
+    uint32_t time;
+    uint32_t ctrl;
+    uint32_t cmp;
+};
+
+int apb_timer_start(apb_timer_t *apb_timer);
+int apb_timer_stop(apb_timer_t *apb_timer);
+uint64_t apb_timer_get_time(apb_timer_t *apb_timer);
+int apb_timer_set_timeout(apb_timer_t *apb_timer, uint64_t ns);
+int apb_timer_init(apb_timer_t *apb_timer, apb_timer_config_t config);
diff --git a/libplatsupport/plat_include/ariane/platsupport/plat/serial.h b/libplatsupport/plat_include/ariane/platsupport/plat/serial.h
index 60d0503..6656a5f 100644
--- a/libplatsupport/plat_include/ariane/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/ariane/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/bcm2711/platsupport/plat/clock.h b/libplatsupport/plat_include/bcm2711/platsupport/plat/clock.h
new file mode 100644
index 0000000..3b06231
--- /dev/null
+++ b/libplatsupport/plat_include/bcm2711/platsupport/plat/clock.h
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright (C) 2021, Hensoldt Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#pragma once
+
+enum clk_id {
+    CLK_MASTER,
+    CLK_SP804,
+    /* ----- */
+    NCLOCKS,
+};
+
+enum clock_gate {
+    NCLKGATES
+};
diff --git a/libplatsupport/plat_include/bcm2711/platsupport/plat/gpio.h b/libplatsupport/plat_include/bcm2711/platsupport/plat/gpio.h
new file mode 100644
index 0000000..dd44b65
--- /dev/null
+++ b/libplatsupport/plat_include/bcm2711/platsupport/plat/gpio.h
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2021, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <utils/util.h>
+#include <platsupport/gpio.h>
+
+enum gpio_port {
+    GPIO_BANK1,
+    GPIO_NBANKS
+};
+
+// GPIO IDs: https://elinux.org/RPi_BCM2711_GPIOs
+#define GPIOID_GPIO_00      GPIOID(GPIO_BANK1,  0)
+#define GPIOID_GPIO_01      GPIOID(GPIO_BANK1,  1)
+#define GPIOID_GPIO_02      GPIOID(GPIO_BANK1,  2)
+#define GPIOID_GPIO_03      GPIOID(GPIO_BANK1,  3)
+#define GPIOID_GPIO_04      GPIOID(GPIO_BANK1,  4)
+#define GPIOID_GPIO_05      GPIOID(GPIO_BANK1,  5)
+#define GPIOID_GPIO_06      GPIOID(GPIO_BANK1,  6)
+#define GPIOID_GPIO_07      GPIOID(GPIO_BANK1,  7)
+#define GPIOID_GPIO_08      GPIOID(GPIO_BANK1,  8)
+#define GPIOID_GPIO_09      GPIOID(GPIO_BANK1,  9)
+#define GPIOID_GPIO_10      GPIOID(GPIO_BANK1,  10)
+#define GPIOID_GPIO_11      GPIOID(GPIO_BANK1,  11)
+#define GPIOID_GPIO_12      GPIOID(GPIO_BANK1,  12)
+#define GPIOID_GPIO_13      GPIOID(GPIO_BANK1,  13)
+#define GPIOID_GPIO_14      GPIOID(GPIO_BANK1,  14)
+#define GPIOID_GPIO_15      GPIOID(GPIO_BANK1,  15)
+#define GPIOID_GPIO_16      GPIOID(GPIO_BANK1,  16)
+#define GPIOID_GPIO_17      GPIOID(GPIO_BANK1,  17)
+#define GPIOID_GPIO_18      GPIOID(GPIO_BANK1,  18)
+#define GPIOID_GPIO_19      GPIOID(GPIO_BANK1,  19)
+#define GPIOID_GPIO_20      GPIOID(GPIO_BANK1,  20)
+#define GPIOID_GPIO_21      GPIOID(GPIO_BANK1,  21)
+#define GPIOID_GPIO_22      GPIOID(GPIO_BANK1,  22)
+#define GPIOID_GPIO_23      GPIOID(GPIO_BANK1,  23)
+#define GPIOID_GPIO_24      GPIOID(GPIO_BANK1,  24)
+#define GPIOID_GPIO_25      GPIOID(GPIO_BANK1,  25)
+#define GPIOID_GPIO_26      GPIOID(GPIO_BANK1,  26)
+#define GPIOID_GPIO_27      GPIOID(GPIO_BANK1,  27)
+#define GPIOID_GPIO_28      GPIOID(GPIO_BANK1,  28)
+#define GPIOID_GPIO_29      GPIOID(GPIO_BANK1,  29)
+#define GPIOID_GPIO_30      GPIOID(GPIO_BANK1,  30)
+#define GPIOID_GPIO_31      GPIOID(GPIO_BANK1,  31)
+#define GPIOID_GPIO_32      GPIOID(GPIO_BANK1,  32)
+#define GPIOID_GPIO_33      GPIOID(GPIO_BANK1,  33)
+#define GPIOID_GPIO_34      GPIOID(GPIO_BANK1,  34)
+#define GPIOID_GPIO_35      GPIOID(GPIO_BANK1,  35)
+#define GPIOID_GPIO_36      GPIOID(GPIO_BANK1,  36)
+#define GPIOID_GPIO_37      GPIOID(GPIO_BANK1,  37)
+#define GPIOID_GPIO_38      GPIOID(GPIO_BANK1,  38)
+#define GPIOID_GPIO_39      GPIOID(GPIO_BANK1,  39)
+#define GPIOID_GPIO_40      GPIOID(GPIO_BANK1,  40)
+#define GPIOID_GPIO_41      GPIOID(GPIO_BANK1,  41)
+#define GPIOID_GPIO_42      GPIOID(GPIO_BANK1,  42)
+#define GPIOID_GPIO_43      GPIOID(GPIO_BANK1,  43)
+#define GPIOID_GPIO_44      GPIOID(GPIO_BANK1,  44)
+#define GPIOID_GPIO_45      GPIOID(GPIO_BANK1,  45)
+#define GPIOID_GPIO_46      GPIOID(GPIO_BANK1,  46)
+#define GPIOID_GPIO_47      GPIOID(GPIO_BANK1,  47)
+#define GPIOID_GPIO_48      GPIOID(GPIO_BANK1,  48)
+#define GPIOID_GPIO_49      GPIOID(GPIO_BANK1,  49)
+#define GPIOID_GPIO_50      GPIOID(GPIO_BANK1,  50)
+#define GPIOID_GPIO_51      GPIOID(GPIO_BANK1,  51)
+#define GPIOID_GPIO_52      GPIOID(GPIO_BANK1,  52)
+#define GPIOID_GPIO_53      GPIOID(GPIO_BANK1,  53)
+#define GPIOID_GPIO_54      GPIOID(GPIO_BANK1,  54)
+#define GPIOID_GPIO_55      GPIOID(GPIO_BANK1,  55)
+#define GPIOID_GPIO_56      GPIOID(GPIO_BANK1,  56)
+#define GPIOID_GPIO_57      GPIOID(GPIO_BANK1,  57)
+
+#define MAX_GPIO_ID         GPIOID_GPIO_57
+
+/*
+ * According to BCM2711 TRM, section 5.2 Register View
+ *
+ * 000 = GPIO Pin is an input
+ * 001 = GPIO Pin is an output
+ * 100 = GPIO Pin takes alternate function 0
+ * 101 = GPIO Pin takes alternate function 1
+ * 110 = GPIO Pin takes alternate function 2
+ * 111 = GPIO Pin takes alternate function 3
+ * 011 = GPIO Pin takes alternate function 4
+ * 010 = GPIO Pin takes alternate function 5
+ */
+enum {
+    BCM2711_GPIO_FSEL_INPT = 0,
+    BCM2711_GPIO_FSEL_OUTP = 1,
+    BCM2711_GPIO_FSEL_ALT0 = 4,
+    BCM2711_GPIO_FSEL_ALT1 = 5,
+    BCM2711_GPIO_FSEL_ALT2 = 6,
+    BCM2711_GPIO_FSEL_ALT3 = 7,
+    BCM2711_GPIO_FSEL_ALT4 = 3,
+    BCM2711_GPIO_FSEL_ALT5 = 2,
+    BCM2711_GPIO_FSEL_MASK = 7
+};
+
+/**
+ * Initialise the bcm2711 GPIO system
+ * @param[in] bankX      A virtual mapping for gpio bank X.
+ * @param[out] gpio_sys  A handle to a gpio subsystem to populate.
+ * @return               0 on success
+ */
+int bcm2711_gpio_sys_init(void *bank1, gpio_sys_t *gpio_sys);
+
+/**
+ * Sets the Function Select register for the given pin, which configures the pin
+ * as Input, Output or one of the 6 alternate functions.
+ * @param[in] pin   GPIO pin number
+ * @param[in] mode  Mode to set the pin to, one of BCM2711_GPIO_FSEL_*
+ * @return          0 on success
+ */
+int bcm2711_gpio_fsel(gpio_t *gpio, uint8_t mode);
diff --git a/libplatsupport/plat_include/bcm2711/platsupport/plat/i2c.h b/libplatsupport/plat_include/bcm2711/platsupport/plat/i2c.h
new file mode 100644
index 0000000..91bc9c9
--- /dev/null
+++ b/libplatsupport/plat_include/bcm2711/platsupport/plat/i2c.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright (C) 2021, Hensoldt Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#pragma once
+
+enum i2c_id {
+    NI2C
+};
diff --git a/libplatsupport/plat_include/bcm2711/platsupport/plat/mailbox.h b/libplatsupport/plat_include/bcm2711/platsupport/plat/mailbox.h
new file mode 100644
index 0000000..555fb7d
--- /dev/null
+++ b/libplatsupport/plat_include/bcm2711/platsupport/plat/mailbox.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2021, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <platsupport/mach/mailbox.h>
+
+// The actual mailbox base address is 0xFE00B880 but mappings have to be page
+// aligned (actually DMA_PAGE_SIZE aligned).
+#define MAILBOX_PADDR       0xfe00b000
+#define MAILBOX_SIZE        0x1000
diff --git a/libplatsupport/plat_include/bcm2711/platsupport/plat/serial.h b/libplatsupport/plat_include/bcm2711/platsupport/plat/serial.h
new file mode 100644
index 0000000..3add49f
--- /dev/null
+++ b/libplatsupport/plat_include/bcm2711/platsupport/plat/serial.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright (C) 2021, Hensoldt Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#pragma once
+
+#define BUS_ADDR_OFFSET     0x7E000000
+#define PADDDR_OFFSET       0xFE000000
+
+/*
+ * The mini UART (UART1) is one of the 3 auxiliary
+ * peripherals on the bcm2711 (section 2.1.)
+ *      find in seL4/tools/dts/rpi4.dts under
+ *          /soc/aux@7e215000
+ *          /soc/serial@7e215040
+ */
+#define UART_BUSADDR        0x7E215000
+
+#define UART_PADDR_1        (UART_BUSADDR - BUS_ADDR_OFFSET + PADDDR_OFFSET)
+/*
+ * BCM2711 TRM
+ * The mini UART (UART1) is part of AUX
+ * section 6.2.4. VideoCore interrupts:             29
+ * section 6.3.   GIC-400 - VC peripheral IRQs:     96
+ * => mini UART IRQ: 96 + 29 = 125
+ */
+#define UART_IRQ_1          (125)
+
+enum chardev_id {
+    BCM2711_UART0,
+    BCM2711_UART1,
+    BCM2711_UART2,
+    BCM2711_UART3,
+    BCM2711_UART4,
+    BCM2711_UART5,
+
+    NUM_CHARDEV,
+    /* Aliases */
+    PS_SERIAL0 = BCM2711_UART0,
+    PS_SERIAL1 = BCM2711_UART1,
+    PS_SERIAL2 = BCM2711_UART2,
+    PS_SERIAL3 = BCM2711_UART3,
+    PS_SERIAL4 = BCM2711_UART4,
+    PS_SERIAL5 = BCM2711_UART5,
+    /* defaults */
+    PS_SERIAL_DEFAULT = BCM2711_UART1
+};
+
+#define DEFAULT_SERIAL_PADDR UART_PADDR_1
+#define DEFAULT_SERIAL_INTERRUPT UART_IRQ_1
diff --git a/libplatsupport/plat_include/bcm2711/platsupport/plat/spt.h b/libplatsupport/plat_include/bcm2711/platsupport/plat/spt.h
new file mode 100644
index 0000000..925895f
--- /dev/null
+++ b/libplatsupport/plat_include/bcm2711/platsupport/plat/spt.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright (C) 2021, Hensoldt Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#pragma once
+
+#include <platsupport/timer.h>
+
+/*
+ * BCM2711 TRM
+ * section 6.2.3. ARMC interrupts:                   0
+ * section 6.3.   GIC-400 - ARMC peripheral IRQs:   64
+ * => ARM Timer IRQ: 64 + 0 = 64
+ */
+#define SP804_TIMER_IRQ        64
+
+#define BUS_ADDR_OFFSET        0x7E000000
+#define PADDDR_OFFSET          0xFE000000
+
+/*
+ * According to BCM2711 TRM section 12.2. Timer Registers:
+ *      0x7e00b000
+ */
+#define SP804_TIMER_BUSADDR    0x7E00B000
+#define SP804_TIMER_PADDR      (SP804_TIMER_BUSADDR-BUS_ADDR_OFFSET+PADDDR_OFFSET)
+
+typedef struct arm_timer {
+    uint32_t load;              /* Sets value for timer to count down */
+    uint32_t value;             /* Holds the current timer value */
+    uint32_t ctrl;              /* Control register for timer */
+    uint32_t irq_clear;         /* Clears interrupt pending bit; write only */
+    uint32_t raw_irq;           /* Shows status of interrupt pending bit; read only */
+    uint32_t masked_irq;        /* Logical and of interrupt pending and interrupt enable */
+    uint32_t reload;            /* Also timer reload value, only it doesn't force a reload */
+    uint32_t pre_divider;       /* Prescaler, reset value is 0x7D  */
+    uint32_t free_run_count;    /* Read only incrementing counter */
+} arm_timer_t;
+
+typedef struct {
+    freq_t freq;
+    volatile arm_timer_t *regs;
+    uint32_t prescaler;
+    uint64_t counter_start;
+} spt_t;
+
+typedef struct {
+    /* vaddr timer is mapped to */
+    void *vaddr;
+} spt_config_t;
+
+UNUSED static timer_properties_t spt_properties = {
+    .upcounter = false,
+    .timeouts = true,
+    .relative_timeouts = true,
+    .irqs = 1,
+    .bit_width = 32
+};
+
+int spt_init(spt_t *spt, spt_config_t config);
+uint64_t spt_get_time(spt_t *spt);
+int spt_handle_irq(spt_t *spt);
+int spt_set_timeout(spt_t *spt, uint64_t ns);
+int spt_stop(spt_t *spt);
+int spt_start(spt_t *spt);
diff --git a/libplatsupport/plat_include/bcm2711/platsupport/plat/system_timer.h b/libplatsupport/plat_include/bcm2711/platsupport/plat/system_timer.h
new file mode 100644
index 0000000..25d7d7f
--- /dev/null
+++ b/libplatsupport/plat_include/bcm2711/platsupport/plat/system_timer.h
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright (C) 2021, Hensoldt Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#include <platsupport/timer.h>
+
+#pragma once
+
+#define BUS_ADDR_OFFSET          0x7E000000
+#define PADDDR_OFFSET            0xFE000000
+
+/*
+ * According to BCM2711 TRM section 10.1.:
+ *      0x7e003000
+ */
+#define SYSTEM_TIMER_BUSADDR     0x7E003000
+#define SYSTEM_TIMER_PADDR       (SYSTEM_TIMER_BUSADDR-BUS_ADDR_OFFSET+PADDDR_OFFSET)
+
+/*
+ * The system timer frequency is fixed at 1 MHz:
+ *      in seL4/tools/dts/rpi4.dts under /soc/timer@7e003000
+ */
+#define SYSTEM_TIMER_FREQ        (1 * MHZ)
+#define SYSTEM_TIMER_NS_PER_TICK (GHZ / SYSTEM_TIMER_FREQ)
+
+/*
+ * IRQs generated when timer matches occur.
+ *
+ * The system timer generates a different IRQ for each of the 4 match
+ * registers whenever the low 32-bits of the counter match the
+ * corresponding compare register.
+ *
+ * To clear an interrupt for a partiuclar match, simply write a 1 to the
+ * the bit with an index corresponding to the match register.
+ *
+ * DO NOT USE compare 0 or 2, they overlap with GPU IRQs. (we use 1).
+ */
+#define SYSTEM_TIMER_MATCH_COUNT       0x04
+#define SYSTEM_TIMER_MATCH             0x01
+
+/*
+ * BCM2711 TRM
+ * section 6.2.4. VideoCore interrupts:             0,1,2,3
+ * section 6.3.   GIC-400 - VC peripheral IRQs:     96
+ * => System Timer IRQs (4 different channels):
+ *      96 + {0,1,2,3} = {96,97,98,99}
+ */
+#define SYSTEM_TIMER_MATCH_IRQ_START   0x60
+#define SYSTEM_TIMER_MATCH_IRQ(n)      (SYSTEM_TIMER_MATCH_IRQ_START + n)
+
+typedef struct {
+    /* Status control register. */
+    uint32_t ctrl;
+    /* Low 32 bits of the 64-bit free-running counter. */
+    uint32_t counter_low;
+    /* High 32 bits of the 64-bit free-running counter. */
+    uint32_t counter_high;
+    /* Four compare registers to trigger IRQs. */
+    uint32_t compare[SYSTEM_TIMER_MATCH_COUNT];
+} system_timer_regs_t;
+
+typedef struct {
+    system_timer_regs_t *regs;
+} system_timer_t;
+
+typedef struct {
+    void *vaddr;
+} system_timer_config_t;
+
+int system_timer_init(system_timer_t *timer, system_timer_config_t config);
+
+uint64_t system_timer_get_time(system_timer_t *timer);
+
+int system_timer_set_timeout(system_timer_t *timer, uint64_t ns);
+
+int system_timer_handle_irq(system_timer_t *timer);
+
+int system_timer_reset(system_timer_t *timer);
diff --git a/libplatsupport/plat_include/bcm2837/platsupport/plat/clock.h b/libplatsupport/plat_include/bcm2837/platsupport/plat/clock.h
index ed88f68..6388d80 100644
--- a/libplatsupport/plat_include/bcm2837/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/bcm2837/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/bcm2837/platsupport/plat/gpio.h b/libplatsupport/plat_include/bcm2837/platsupport/plat/gpio.h
new file mode 100644
index 0000000..5f40d56
--- /dev/null
+++ b/libplatsupport/plat_include/bcm2837/platsupport/plat/gpio.h
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2021, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <utils/util.h>
+#include <platsupport/gpio.h>
+
+enum gpio_port {
+    GPIO_BANK1,
+    GPIO_NBANKS
+};
+
+// GPIO IDs: https://elinux.org/RPi_BCM2835_GPIOs
+#define GPIOID_GPIO_00      GPIOID(GPIO_BANK1,  0)
+#define GPIOID_GPIO_01      GPIOID(GPIO_BANK1,  1)
+#define GPIOID_GPIO_02      GPIOID(GPIO_BANK1,  2)
+#define GPIOID_GPIO_03      GPIOID(GPIO_BANK1,  3)
+#define GPIOID_GPIO_04      GPIOID(GPIO_BANK1,  4)
+#define GPIOID_GPIO_05      GPIOID(GPIO_BANK1,  5)
+#define GPIOID_GPIO_06      GPIOID(GPIO_BANK1,  6)
+#define GPIOID_GPIO_07      GPIOID(GPIO_BANK1,  7)
+#define GPIOID_GPIO_08      GPIOID(GPIO_BANK1,  8)
+#define GPIOID_GPIO_09      GPIOID(GPIO_BANK1,  9)
+#define GPIOID_GPIO_10      GPIOID(GPIO_BANK1,  10)
+#define GPIOID_GPIO_11      GPIOID(GPIO_BANK1,  11)
+#define GPIOID_GPIO_12      GPIOID(GPIO_BANK1,  12)
+#define GPIOID_GPIO_13      GPIOID(GPIO_BANK1,  13)
+#define GPIOID_GPIO_14      GPIOID(GPIO_BANK1,  14)
+#define GPIOID_GPIO_15      GPIOID(GPIO_BANK1,  15)
+#define GPIOID_GPIO_16      GPIOID(GPIO_BANK1,  16)
+#define GPIOID_GPIO_17      GPIOID(GPIO_BANK1,  17)
+#define GPIOID_GPIO_18      GPIOID(GPIO_BANK1,  18)
+#define GPIOID_GPIO_19      GPIOID(GPIO_BANK1,  19)
+#define GPIOID_GPIO_20      GPIOID(GPIO_BANK1,  20)
+#define GPIOID_GPIO_21      GPIOID(GPIO_BANK1,  21)
+#define GPIOID_GPIO_22      GPIOID(GPIO_BANK1,  22)
+#define GPIOID_GPIO_23      GPIOID(GPIO_BANK1,  23)
+#define GPIOID_GPIO_24      GPIOID(GPIO_BANK1,  24)
+#define GPIOID_GPIO_25      GPIOID(GPIO_BANK1,  25)
+#define GPIOID_GPIO_26      GPIOID(GPIO_BANK1,  26)
+#define GPIOID_GPIO_27      GPIOID(GPIO_BANK1,  27)
+#define GPIOID_GPIO_28      GPIOID(GPIO_BANK1,  28)
+#define GPIOID_GPIO_29      GPIOID(GPIO_BANK1,  29)
+#define GPIOID_GPIO_30      GPIOID(GPIO_BANK1,  30)
+#define GPIOID_GPIO_31      GPIOID(GPIO_BANK1,  31)
+#define GPIOID_GPIO_32      GPIOID(GPIO_BANK1,  32)
+#define GPIOID_GPIO_33      GPIOID(GPIO_BANK1,  33)
+#define GPIOID_GPIO_34      GPIOID(GPIO_BANK1,  34)
+#define GPIOID_GPIO_35      GPIOID(GPIO_BANK1,  35)
+#define GPIOID_GPIO_36      GPIOID(GPIO_BANK1,  36)
+#define GPIOID_GPIO_37      GPIOID(GPIO_BANK1,  37)
+#define GPIOID_GPIO_38      GPIOID(GPIO_BANK1,  38)
+#define GPIOID_GPIO_39      GPIOID(GPIO_BANK1,  39)
+#define GPIOID_GPIO_40      GPIOID(GPIO_BANK1,  40)
+#define GPIOID_GPIO_41      GPIOID(GPIO_BANK1,  41)
+#define GPIOID_GPIO_42      GPIOID(GPIO_BANK1,  42)
+#define GPIOID_GPIO_43      GPIOID(GPIO_BANK1,  43)
+#define GPIOID_GPIO_44      GPIOID(GPIO_BANK1,  44)
+#define GPIOID_GPIO_45      GPIOID(GPIO_BANK1,  45)
+#define GPIOID_GPIO_46      GPIOID(GPIO_BANK1,  46)
+#define GPIOID_GPIO_47      GPIOID(GPIO_BANK1,  47)
+#define GPIOID_GPIO_48      GPIOID(GPIO_BANK1,  48)
+#define GPIOID_GPIO_49      GPIOID(GPIO_BANK1,  49)
+#define GPIOID_GPIO_50      GPIOID(GPIO_BANK1,  50)
+#define GPIOID_GPIO_51      GPIOID(GPIO_BANK1,  51)
+#define GPIOID_GPIO_52      GPIOID(GPIO_BANK1,  52)
+#define GPIOID_GPIO_53      GPIOID(GPIO_BANK1,  53)
+
+#define MAX_GPIO_ID         GPIOID_GPIO_53
+
+/*
+ * According to BCM2835 TRM, section 6.1 Register View
+ * GPIO function select (bit 27-29):
+ *
+ * 000 = GPIO Pin is an input
+ * 001 = GPIO Pin is an output
+ * 100 = GPIO Pin takes alternate function 0
+ * 101 = GPIO Pin takes alternate function 1
+ * 110 = GPIO Pin takes alternate function 2
+ * 111 = GPIO Pin takes alternate function 3
+ * 011 = GPIO Pin takes alternate function 4
+ * 010 = GPIO Pin takes alternate function 5
+ */
+enum {
+    BCM2837_GPIO_FSEL_INPT = 0,
+    BCM2837_GPIO_FSEL_OUTP = 1,
+    BCM2837_GPIO_FSEL_ALT0 = 4,
+    BCM2837_GPIO_FSEL_ALT1 = 5,
+    BCM2837_GPIO_FSEL_ALT2 = 6,
+    BCM2837_GPIO_FSEL_ALT3 = 7,
+    BCM2837_GPIO_FSEL_ALT4 = 3,
+    BCM2837_GPIO_FSEL_ALT5 = 2,
+    BCM2837_GPIO_FSEL_MASK = 7
+};
+
+/**
+ * Initialise the bcm2837 GPIO system
+ * @param[in] bankX      A virtual mapping for gpio bank X.
+ * @param[out] gpio_sys  A handle to a gpio subsystem to populate.
+ * @return               0 on success
+ */
+int bcm2837_gpio_sys_init(void *bank1, gpio_sys_t *gpio_sys);
+
+/**
+ * Sets the Function Select register for the given pin, which configures the pin
+ * as Input, Output or one of the 6 alternate functions.
+ * @param[in] pin   GPIO pin number
+ * @param[in] mode  Mode to set the pin to, one of BCM2837_GPIO_FSEL_*
+ * @return          0 on success
+ */
+int bcm2837_gpio_fsel(gpio_t *gpio, uint8_t mode);
diff --git a/libplatsupport/plat_include/bcm2837/platsupport/plat/i2c.h b/libplatsupport/plat_include/bcm2837/platsupport/plat/i2c.h
index c7871b4..b340349 100644
--- a/libplatsupport/plat_include/bcm2837/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/bcm2837/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
  #pragma once
diff --git a/libplatsupport/plat_include/bcm2837/platsupport/plat/mailbox.h b/libplatsupport/plat_include/bcm2837/platsupport/plat/mailbox.h
new file mode 100644
index 0000000..89ae38e
--- /dev/null
+++ b/libplatsupport/plat_include/bcm2837/platsupport/plat/mailbox.h
@@ -0,0 +1,14 @@
+/*
+ * Copyright (C) 2021, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <platsupport/mach/mailbox.h>
+
+// The actual mailbox base address is 0x3F00B880 but mappings have to be page
+// aligned (actually DMA_PAGE_SIZE aligned).
+#define MAILBOX_PADDR       0x3f00b000
+#define MAILBOX_SIZE        0x1000
diff --git a/libplatsupport/plat_include/bcm2837/platsupport/plat/serial.h b/libplatsupport/plat_include/bcm2837/platsupport/plat/serial.h
index c62a7b8..003cbc5 100644
--- a/libplatsupport/plat_include/bcm2837/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/bcm2837/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
  #pragma once
diff --git a/libplatsupport/plat_include/bcm2837/platsupport/plat/spt.h b/libplatsupport/plat_include/bcm2837/platsupport/plat/spt.h
index 38a6eb2..30f82c5 100644
--- a/libplatsupport/plat_include/bcm2837/platsupport/plat/spt.h
+++ b/libplatsupport/plat_include/bcm2837/platsupport/plat/spt.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
  #pragma once
 
diff --git a/libplatsupport/plat_include/bcm2837/platsupport/plat/system_timer.h b/libplatsupport/plat_include/bcm2837/platsupport/plat/system_timer.h
index bf60415..54ae5a6 100644
--- a/libplatsupport/plat_include/bcm2837/platsupport/plat/system_timer.h
+++ b/libplatsupport/plat_include/bcm2837/platsupport/plat/system_timer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <platsupport/timer.h>
 
diff --git a/libplatsupport/plat_include/exynos4/platsupport/plat/clock.h b/libplatsupport/plat_include/exynos4/platsupport/plat/clock.h
index 68cc661..3a755b6 100644
--- a/libplatsupport/plat_include/exynos4/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/exynos4/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos4/platsupport/plat/dma330.h b/libplatsupport/plat_include/exynos4/platsupport/plat/dma330.h
index 9fc87ec..bfe040d 100644
--- a/libplatsupport/plat_include/exynos4/platsupport/plat/dma330.h
+++ b/libplatsupport/plat_include/exynos4/platsupport/plat/dma330.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos4/platsupport/plat/gpio.h b/libplatsupport/plat_include/exynos4/platsupport/plat/gpio.h
index 5925c1f..f7f2d3a 100644
--- a/libplatsupport/plat_include/exynos4/platsupport/plat/gpio.h
+++ b/libplatsupport/plat_include/exynos4/platsupport/plat/gpio.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos4/platsupport/plat/i2c.h b/libplatsupport/plat_include/exynos4/platsupport/plat/i2c.h
index 728e1e3..25b6b4b 100644
--- a/libplatsupport/plat_include/exynos4/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/exynos4/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos4/platsupport/plat/irq_combiner.h b/libplatsupport/plat_include/exynos4/platsupport/plat/irq_combiner.h
index c4892a1..a7e6ba8 100644
--- a/libplatsupport/plat_include/exynos4/platsupport/plat/irq_combiner.h
+++ b/libplatsupport/plat_include/exynos4/platsupport/plat/irq_combiner.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos4/platsupport/plat/mux.h b/libplatsupport/plat_include/exynos4/platsupport/plat/mux.h
index 91f6e94..85b0f7e 100644
--- a/libplatsupport/plat_include/exynos4/platsupport/plat/mux.h
+++ b/libplatsupport/plat_include/exynos4/platsupport/plat/mux.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos4/platsupport/plat/pmic.h b/libplatsupport/plat_include/exynos4/platsupport/plat/pmic.h
index 8f00c62..d52cb0b 100644
--- a/libplatsupport/plat_include/exynos4/platsupport/plat/pmic.h
+++ b/libplatsupport/plat_include/exynos4/platsupport/plat/pmic.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos4/platsupport/plat/pwm.h b/libplatsupport/plat_include/exynos4/platsupport/plat/pwm.h
index 5eed194..87d2a9e 100644
--- a/libplatsupport/plat_include/exynos4/platsupport/plat/pwm.h
+++ b/libplatsupport/plat_include/exynos4/platsupport/plat/pwm.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/exynos4/platsupport/plat/serial.h b/libplatsupport/plat_include/exynos4/platsupport/plat/serial.h
index 41ab25b..bc57ffe 100644
--- a/libplatsupport/plat_include/exynos4/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/exynos4/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos4/platsupport/plat/spi.h b/libplatsupport/plat_include/exynos4/platsupport/plat/spi.h
index 9623640..01a7053 100644
--- a/libplatsupport/plat_include/exynos4/platsupport/plat/spi.h
+++ b/libplatsupport/plat_include/exynos4/platsupport/plat/spi.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos4/platsupport/plat/src.h b/libplatsupport/plat_include/exynos4/platsupport/plat/src.h
index ce9a128..aff8138 100644
--- a/libplatsupport/plat_include/exynos4/platsupport/plat/src.h
+++ b/libplatsupport/plat_include/exynos4/platsupport/plat/src.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos4/platsupport/plat/tmu.h b/libplatsupport/plat_include/exynos4/platsupport/plat/tmu.h
index 19bcd7e..5ae5c77 100644
--- a/libplatsupport/plat_include/exynos4/platsupport/plat/tmu.h
+++ b/libplatsupport/plat_include/exynos4/platsupport/plat/tmu.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos5/platsupport/plat/clock.h b/libplatsupport/plat_include/exynos5/platsupport/plat/clock.h
index fda44b6..5555724 100644
--- a/libplatsupport/plat_include/exynos5/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/exynos5/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos5/platsupport/plat/dma330.h b/libplatsupport/plat_include/exynos5/platsupport/plat/dma330.h
index a643bdb..e8e0f46 100644
--- a/libplatsupport/plat_include/exynos5/platsupport/plat/dma330.h
+++ b/libplatsupport/plat_include/exynos5/platsupport/plat/dma330.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos5/platsupport/plat/gpio.h b/libplatsupport/plat_include/exynos5/platsupport/plat/gpio.h
index 3c50eb5..9aa14ee 100644
--- a/libplatsupport/plat_include/exynos5/platsupport/plat/gpio.h
+++ b/libplatsupport/plat_include/exynos5/platsupport/plat/gpio.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos5/platsupport/plat/i2c.h b/libplatsupport/plat_include/exynos5/platsupport/plat/i2c.h
index 2104830..9ecfa3a 100644
--- a/libplatsupport/plat_include/exynos5/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/exynos5/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos5/platsupport/plat/irq_combiner.h b/libplatsupport/plat_include/exynos5/platsupport/plat/irq_combiner.h
index 9e6c16b..0203a65 100644
--- a/libplatsupport/plat_include/exynos5/platsupport/plat/irq_combiner.h
+++ b/libplatsupport/plat_include/exynos5/platsupport/plat/irq_combiner.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos5/platsupport/plat/mux.h b/libplatsupport/plat_include/exynos5/platsupport/plat/mux.h
index 7f600a2..016217f 100644
--- a/libplatsupport/plat_include/exynos5/platsupport/plat/mux.h
+++ b/libplatsupport/plat_include/exynos5/platsupport/plat/mux.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/exynos5/platsupport/plat/pmic.h b/libplatsupport/plat_include/exynos5/platsupport/plat/pmic.h
index dce9734..bf4b750 100644
--- a/libplatsupport/plat_include/exynos5/platsupport/plat/pmic.h
+++ b/libplatsupport/plat_include/exynos5/platsupport/plat/pmic.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos5/platsupport/plat/pwm.h b/libplatsupport/plat_include/exynos5/platsupport/plat/pwm.h
index b0fd3ae..0281d52 100644
--- a/libplatsupport/plat_include/exynos5/platsupport/plat/pwm.h
+++ b/libplatsupport/plat_include/exynos5/platsupport/plat/pwm.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/exynos5/platsupport/plat/rtc.h b/libplatsupport/plat_include/exynos5/platsupport/plat/rtc.h
index fc65123..4e7437b 100644
--- a/libplatsupport/plat_include/exynos5/platsupport/plat/rtc.h
+++ b/libplatsupport/plat_include/exynos5/platsupport/plat/rtc.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos5/platsupport/plat/serial.h b/libplatsupport/plat_include/exynos5/platsupport/plat/serial.h
index c35495b..274d671 100644
--- a/libplatsupport/plat_include/exynos5/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/exynos5/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos5/platsupport/plat/spi.h b/libplatsupport/plat_include/exynos5/platsupport/plat/spi.h
index a725a29..800cc0b 100644
--- a/libplatsupport/plat_include/exynos5/platsupport/plat/spi.h
+++ b/libplatsupport/plat_include/exynos5/platsupport/plat/spi.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos5/platsupport/plat/sysreg.h b/libplatsupport/plat_include/exynos5/platsupport/plat/sysreg.h
index 9c6a037..436acd5 100644
--- a/libplatsupport/plat_include/exynos5/platsupport/plat/sysreg.h
+++ b/libplatsupport/plat_include/exynos5/platsupport/plat/sysreg.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/exynos5/platsupport/plat/timer.h b/libplatsupport/plat_include/exynos5/platsupport/plat/timer.h
index 7213c40..987ca21 100644
--- a/libplatsupport/plat_include/exynos5/platsupport/plat/timer.h
+++ b/libplatsupport/plat_include/exynos5/platsupport/plat/timer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/exynos5/platsupport/plat/tmu.h b/libplatsupport/plat_include/exynos5/platsupport/plat/tmu.h
index 39e8cdb..99dd13f 100644
--- a/libplatsupport/plat_include/exynos5/platsupport/plat/tmu.h
+++ b/libplatsupport/plat_include/exynos5/platsupport/plat/tmu.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/fvp/platsupport/plat/clock.h b/libplatsupport/plat_include/fvp/platsupport/plat/clock.h
index fd1db89..568ba6f 100644
--- a/libplatsupport/plat_include/fvp/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/fvp/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/fvp/platsupport/plat/i2c.h b/libplatsupport/plat_include/fvp/platsupport/plat/i2c.h
index a9d5020..bb3269b 100644
--- a/libplatsupport/plat_include/fvp/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/fvp/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/fvp/platsupport/plat/serial.h b/libplatsupport/plat_include/fvp/platsupport/plat/serial.h
index d3067ae..5b3bdbc 100644
--- a/libplatsupport/plat_include/fvp/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/fvp/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/fvp/platsupport/plat/sp804.h b/libplatsupport/plat_include/fvp/platsupport/plat/sp804.h
index 056aff4..89b3d62 100644
--- a/libplatsupport/plat_include/fvp/platsupport/plat/sp804.h
+++ b/libplatsupport/plat_include/fvp/platsupport/plat/sp804.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/hifive/platsupport/plat/pwm.h b/libplatsupport/plat_include/hifive/platsupport/plat/pwm.h
index 6ee8f3a..de3c16c 100644
--- a/libplatsupport/plat_include/hifive/platsupport/plat/pwm.h
+++ b/libplatsupport/plat_include/hifive/platsupport/plat/pwm.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/hifive/platsupport/plat/serial.h b/libplatsupport/plat_include/hifive/platsupport/plat/serial.h
index f6b3e5d..68acbc6 100644
--- a/libplatsupport/plat_include/hifive/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/hifive/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/hikey/platsupport/plat/clock.h b/libplatsupport/plat_include/hikey/platsupport/plat/clock.h
index 4a212a1..072a13d 100644
--- a/libplatsupport/plat_include/hikey/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/hikey/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/hikey/platsupport/plat/dmt.h b/libplatsupport/plat_include/hikey/platsupport/plat/dmt.h
index f59c1ee..d39c7b2 100644
--- a/libplatsupport/plat_include/hikey/platsupport/plat/dmt.h
+++ b/libplatsupport/plat_include/hikey/platsupport/plat/dmt.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/hikey/platsupport/plat/i2c.h b/libplatsupport/plat_include/hikey/platsupport/plat/i2c.h
index 14b63ec..40efe17 100644
--- a/libplatsupport/plat_include/hikey/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/hikey/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/hikey/platsupport/plat/rtc.h b/libplatsupport/plat_include/hikey/platsupport/plat/rtc.h
index b8f04fe..e1f59e1 100644
--- a/libplatsupport/plat_include/hikey/platsupport/plat/rtc.h
+++ b/libplatsupport/plat_include/hikey/platsupport/plat/rtc.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/hikey/platsupport/plat/serial.h b/libplatsupport/plat_include/hikey/platsupport/plat/serial.h
index 4c7c387..b222493 100644
--- a/libplatsupport/plat_include/hikey/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/hikey/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/imx31/platsupport/plat/clock.h b/libplatsupport/plat_include/imx31/platsupport/plat/clock.h
deleted file mode 100644
index 057de60..0000000
--- a/libplatsupport/plat_include/imx31/platsupport/plat/clock.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
- *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
- */
-
-#pragma once
-
-enum clk_id {
-    CLK_MASTER,
-    NCLOCKS,
-};
-
-enum clock_gate {
-    NCLKGATES,
-};
-
diff --git a/libplatsupport/plat_include/imx31/platsupport/plat/epit_constants.h b/libplatsupport/plat_include/imx31/platsupport/plat/epit_constants.h
deleted file mode 100644
index 52fe2ee..0000000
--- a/libplatsupport/plat_include/imx31/platsupport/plat/epit_constants.h
+++ /dev/null
@@ -1,17 +0,0 @@
-/*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
- *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
- */
-
-#pragma once
-
-#define EPIT1_PATH "/soc/aips@53f00000/timer@53f94000"
-#define EPIT2_PATH "/soc/aips@53f00000/timer@53f98000"
-#define GPT_PATH "/soc/aips@53f00000/timer@53f90000"
diff --git a/libplatsupport/plat_include/imx31/platsupport/plat/gpt_constants.h b/libplatsupport/plat_include/imx31/platsupport/plat/gpt_constants.h
deleted file mode 100644
index 52c0f09..0000000
--- a/libplatsupport/plat_include/imx31/platsupport/plat/gpt_constants.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
- *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
- */
-
-#pragma once
-
-#define GPT_PATH "/soc/aips@53f00000/timer@53f90000"
-
-#define GPT_PRESCALER 1
-
diff --git a/libplatsupport/plat_include/imx31/platsupport/plat/i2c.h b/libplatsupport/plat_include/imx31/platsupport/plat/i2c.h
deleted file mode 100644
index 14b63ec..0000000
--- a/libplatsupport/plat_include/imx31/platsupport/plat/i2c.h
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
- *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
- */
-
-#pragma once
-
-enum i2c_id {
-    NI2C
-};
-
diff --git a/libplatsupport/plat_include/imx31/platsupport/plat/serial.h b/libplatsupport/plat_include/imx31/platsupport/plat/serial.h
deleted file mode 100644
index 3826a4f..0000000
--- a/libplatsupport/plat_include/imx31/platsupport/plat/serial.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
- *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
- */
-
-#pragma once
-
-#define UART1_PADDR  0x43F90000
-#define UART2_PADDR  0x43F94000
-#define UART3_PADDR  0x5000C000
-#define UART4_PADDR  0x43FB0000
-#define UART5_PADDR  0x43FB4000
-
-#define UART1_IRQ    45
-#define UART2_IRQ    32
-#define UART3_IRQ    18
-#define UART4_IRQ    46
-#define UART5_IRQ    47
-
-/* official device names */
-enum chardev_id {
-    IMX31_UART1,
-    IMX31_UART2,
-    IMX31_UART3,
-    IMX31_UART4,
-    IMX31_UART5,
-    /* Aliases */
-    PS_SERIAL0 = IMX31_UART1,
-    PS_SERIAL1 = IMX31_UART2,
-    PS_SERIAL2 = IMX31_UART3,
-    PS_SERIAL3 = IMX31_UART4,
-    /* defaults */
-    PS_SERIAL_DEFAULT = IMX31_UART1
-};
-
-#define DEFAULT_SERIAL_PADDR UART1_PADDR
-#define DEFAULT_SERIAL_INTERRUPT UART1_IRQ
diff --git a/libplatsupport/plat_include/imx31/platsupport/plat/timer.h b/libplatsupport/plat_include/imx31/platsupport/plat/timer.h
deleted file mode 100644
index 676f706..0000000
--- a/libplatsupport/plat_include/imx31/platsupport/plat/timer.h
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
- *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
- */
-#pragma once
-
-#include <autoconf.h>
-#include <platsupport/gen_config.h>
-#include <platsupport/mach/gpt.h>
-#include <platsupport/mach/epit.h>
-
-#define IPG_FREQ (500/8) /* 62.5MHz */
-#define GPT_FREQ IPG_FREQ
-
-#ifdef CONFIG_KERNEL_MCS
-/* for RT, we use the EPIT as timestamp timer as the kernel is using the GPT */
-
-typedef struct {
-    epit_t timestamp;
-    epit_t timeout;
-} imx_timers_t;
-
-static inline uint64_t imx_get_time(imx_timers_t *timers)
-{
-    return epit_get_time(&timers->timestamp);
-}
-
-static inline void imx_start_timestamp(imx_timers_t *timers)
-{
-    epit_set_timeout_ticks(&timers->timestamp, UINT32_MAX, true);
-}
-
-static inline void imx_stop_timestamp(imx_timers_t *timers)
-{
-    epit_stop(&timers->timestamp);
-}
-
-static inline int imx_init_timestamp(imx_timers_t *timers, ps_io_ops_t io_ops, ltimer_callback_fn_t user_callback,
-                                     void *user_callback_token)
-{
-    epit_config_t config = {
-        .io_ops = io_ops,
-        .user_callback = user_callback,
-        .user_callback_token = user_callback_token,
-        .device_path = EPIT1_PATH,
-        .is_timestamp = true,
-        .prescaler = 0,
-    };
-    return epit_init(&timers->timestamp, config);
-}
-
-static inline int imx_destroy_timestamp(imx_timers_t *timers)
-{
-    return epit_destroy(&timers->timestamp);
-}
-#else
-/* for baseline, the timestamp timer is the GPT as the kernel is using EPIT1 */
-
-typedef struct {
-    gpt_t timestamp;
-    epit_t timeout;
-} imx_timers_t;
-
-static inline uint64_t imx_get_time(imx_timers_t *timers)
-{
-    return gpt_get_time(&timers->timestamp);
-}
-
-static inline void imx_start_timestamp(imx_timers_t *timers)
-{
-    gpt_start(&timers->timestamp);
-}
-
-static inline void imx_stop_timestamp(imx_timers_t *timers)
-{
-    gpt_stop(&timers->timestamp);
-}
-
-static inline int imx_init_timestamp(imx_timers_t *timers, ps_io_ops_t io_ops, ltimer_callback_fn_t user_callback,
-                                     void *user_callback_token)
-{
-    gpt_config_t config = {
-        .io_ops = io_ops,
-        .user_callback = user_callback,
-        .user_callback_token = user_callback_token,
-        .device_path = GPT_PATH,
-        .prescaler = GPT_PRESCALER
-    };
-    return gpt_init(&timers->timestamp, config);
-}
-
-static inline int imx_destroy_timestamp(imx_timers_t *timers)
-{
-    return gpt_destroy(&timers->timestamp);
-}
-#endif
-
-/* for both kernel versions, we use EPIT2 as the timeout timer */
-
-static inline int imx_set_timeout(imx_timers_t *timers, uint64_t ns, bool periodic)
-{
-    return epit_set_timeout(&timers->timeout, ns, periodic);
-}
-
-static inline void imx_stop_timeout(imx_timers_t *timers)
-{
-    epit_stop(&timers->timeout);
-}
-
-static inline int imx_init_timeout(imx_timers_t *timers, ps_io_ops_t io_ops, ltimer_callback_fn_t user_callback,
-                                   void *user_callback_token)
-{
-    epit_config_t config = {
-        .io_ops = io_ops,
-        .user_callback = user_callback,
-        .user_callback_token = user_callback_token,
-        .device_path = EPIT2_PATH,
-        .is_timestamp = false,
-        .prescaler = 0
-    };
-    return epit_init(&timers->timeout, config);
-}
-
-static inline int imx_destroy_timeout(imx_timers_t *timers)
-{
-    return epit_destroy(&timers->timeout);
-}
diff --git a/libplatsupport/plat_include/imx6/platsupport/plat/clock.h b/libplatsupport/plat_include/imx6/platsupport/plat/clock.h
index d578c7d..43b2a20 100644
--- a/libplatsupport/plat_include/imx6/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/imx6/platsupport/plat/clock.h
@@ -1,13 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
@@ -44,18 +39,27 @@
 enum clock_gate {
     /* -- CCGR0 -- */
     /* -- CCGR1 -- */
+#if defined(CONFIG_PLAT_IMX6DQ)
+    enet_clock   = CLK_GATE(1, 5),
+#endif
     /* -- CCGR2 -- */
     ocotp_ctrl   = CLK_GATE(2, 6),
     i2c3_serial  = CLK_GATE(2, 5),
     i2c2_serial  = CLK_GATE(2, 4),
     i2c1_serial  = CLK_GATE(2, 3),
     /* -- CCGR3 -- */
+#if defined(CONFIG_PLAT_IMX6DQ)
     ipu1_ipu     = CLK_GATE(3, 0),
     ipu1_ipu_di0 = CLK_GATE(3, 1),
     ipu1_ipu_di1 = CLK_GATE(3, 2),
     ipu2_ipu     = CLK_GATE(3, 3),
     ipu2_ipu_di0 = CLK_GATE(3, 4),
     ipu2_ipu_di1 = CLK_GATE(3, 5),
+#elif defined(CONFIG_PLAT_IMX6SX)
+    enet_clock   = CLK_GATE(3, 2),
+#else
+#error "unknown i.MX6 SOC"
+#endif
     /* -- CCGR4 -- */
     /* -- CCGR5 -- */
 
@@ -66,8 +70,10 @@
     usdhc3       = CLK_GATE(6, 3),
     usdhc4       = CLK_GATE(6, 4),
     eim_slow     = CLK_GATE(6, 5),
+#ifdef CONFIG_PLAT_IMX6Q
     vdoaxiclk    = CLK_GATE(6, 6),
     vpu          = CLK_GATE(6, 7),
+#endif
     NCLKGATES
 };
 
diff --git a/libplatsupport/plat_include/imx6/platsupport/plat/epit_constants.h b/libplatsupport/plat_include/imx6/platsupport/plat/epit_constants.h
index 174b57a..69fe123 100644
--- a/libplatsupport/plat_include/imx6/platsupport/plat/epit_constants.h
+++ b/libplatsupport/plat_include/imx6/platsupport/plat/epit_constants.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/imx6/platsupport/plat/gpio.h b/libplatsupport/plat_include/imx6/platsupport/plat/gpio.h
index 72738be..fa55d03 100644
--- a/libplatsupport/plat_include/imx6/platsupport/plat/gpio.h
+++ b/libplatsupport/plat_include/imx6/platsupport/plat/gpio.h
@@ -1,13 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
@@ -27,6 +22,9 @@
 #define GPIOID_GPIO7     GPIOID(GPIO_BANK1,  7)
 #define GPIOID_GPIO8     GPIOID(GPIO_BANK1,  8)
 #define GPIOID_GPIO9     GPIOID(GPIO_BANK1,  9)
+
+#if defined(CONFIG_PLAT_IMX6DQ)
+
 #define GPIOID_GPIO16    GPIOID(GPIO_BANK7, 11)
 #define GPIOID_GPIO17    GPIOID(GPIO_BANK7, 12)
 #define GPIOID_GPIO18    GPIOID(GPIO_BANK7, 13)
@@ -50,6 +48,28 @@
 #define KEY_MENU    GPIOID_NAND_D01
 #define KEY_VOL_DN  GPIOID_GPIO19
 
+#elif defined(CONFIG_PLAT_IMX6SX)
+
+#define GPIOID_GPIO10    GPIOID(GPIO_BANK1, 10)
+#define GPIOID_GPIO11    GPIOID(GPIO_BANK1, 11)
+#define GPIOID_GPIO12    GPIOID(GPIO_BANK1, 12)
+#define GPIOID_GPIO13    GPIOID(GPIO_BANK1, 13)
+#define GPIOID_NAND_D00  GPIOID(GPIO_BANK4,  4)
+#define GPIOID_NAND_D01  GPIOID(GPIO_BANK4,  5)
+#define GPIOID_NAND_D02  GPIOID(GPIO_BANK4,  6)
+#define GPIOID_NAND_D03  GPIOID(GPIO_BANK4,  7)
+#define GPIOID_NAND_D04  GPIOID(GPIO_BANK4,  8)
+#define GPIOID_NAND_D05  GPIOID(GPIO_BANK4,  9)
+#define GPIOID_NAND_D06  GPIOID(GPIO_BANK4,  10)
+#define GPIOID_NAND_D07  GPIOID(GPIO_BANK4,  11)
+
+#define MAX_GPIO_ID GPIOID_NAND_D07
+
+#else
+#error "unknown i.MX6 SOC"
+#endif
+
+
 enum gpio_port {
     GPIO_BANK1,
     GPIO_BANK2,
diff --git a/libplatsupport/plat_include/imx6/platsupport/plat/gpt_constants.h b/libplatsupport/plat_include/imx6/platsupport/plat/gpt_constants.h
index aa12b07..6d28367 100644
--- a/libplatsupport/plat_include/imx6/platsupport/plat/gpt_constants.h
+++ b/libplatsupport/plat_include/imx6/platsupport/plat/gpt_constants.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/imx6/platsupport/plat/i2c.h b/libplatsupport/plat_include/imx6/platsupport/plat/i2c.h
index 84afe1c..b9a1794 100644
--- a/libplatsupport/plat_include/imx6/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/imx6/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/imx6/platsupport/plat/mux.h b/libplatsupport/plat_include/imx6/platsupport/plat/mux.h
index 13d526b..563c7ee 100644
--- a/libplatsupport/plat_include/imx6/platsupport/plat/mux.h
+++ b/libplatsupport/plat_include/imx6/platsupport/plat/mux.h
@@ -1,13 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
@@ -16,7 +11,13 @@
     MUX_I2C1,
     MUX_I2C2,
     MUX_I2C3,
+#if defined(CONFIG_PLAT_IMX6DQ)
     MUX_GPIO0_CLKO1,
+#elif defined(CONFIG_PLAT_IMX6SX)
+    MUX_GPIO11_CLKO1,
+#else
+#error "unknown i.MX6 SOC"
+#endif
     MUX_UART1,
     NMUX_FEATURES
 };
@@ -28,5 +29,16 @@
  *                    subsystem data.
  * @return            0 on success
  */
-int imx6_mux_init(void* iomuxc, mux_sys_t* mux);
+int imx6_mux_init(void *iomuxc, mux_sys_t *mux);
 
+#ifdef CONFIG_PLAT_IMX6SX
+/**
+ * Initialise the mux subsystem with pre-mapped regions, but consider split regions of IOMUXC and IOMUXC_GPR.
+ * @param[in]  iomuxc A virtual mapping for IOMUXC of the MUX subsystem.
+ * @param[in]  iomuxc_gpr A virtual mapping for IOMUXC_GPR of the MUX subsystem.
+ * @param[out] mux    On success, this will be filled with the appropriate
+ *                    subsystem data.
+ * @return            0 on success
+ */
+int imx6sx_mux_init_split(void *iomuxc, void *iomuxc_gpr, mux_sys_t *mux);
+#endif
diff --git a/libplatsupport/plat_include/imx6/platsupport/plat/serial.h b/libplatsupport/plat_include/imx6/platsupport/plat/serial.h
index c6ef85e..da53d8a 100644
--- a/libplatsupport/plat_include/imx6/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/imx6/platsupport/plat/serial.h
@@ -1,13 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
@@ -28,12 +23,29 @@
 #define UART4_IRQ    61
 #define UART5_IRQ    62
 
+#ifdef CONFIG_PLAT_NITROGEN6SX
+// seL4 starts on the Nitrogen6_SoloX platform with the UART input
+// clock frequency set to 24MHz. This constant is used in baud rate
+// calculations where the input frequency has already been divided by 2.
+#define UART_REF_CLK 12000000
+#else
+// This constant assumes that the UART input clock frequency is 80179200Hz
+// and gets divided by 2 before performing baud calculations where this
+// constant is used.
 #define UART_REF_CLK 40089600
+#endif
+
 
 #if defined(CONFIG_PLAT_SABRE)
-    #define DEFAULT_SERIAL_PADDR UART2_PADDR
-    #define DEFAULT_SERIAL_INTERRUPT UART2_IRQ
-#elif defined(CONFIG_PLAT_WANDQ)
-    #define DEFAULT_SERIAL_PADDR UART1_PADDR
-    #define DEFAULT_SERIAL_INTERRUPT UART1_IRQ
+
+#define DEFAULT_SERIAL_PADDR        UART2_PADDR
+#define DEFAULT_SERIAL_INTERRUPT    UART2_IRQ
+
+#elif defined(CONFIG_PLAT_WANDQ) || defined(CONFIG_PLAT_NITROGEN6SX)
+
+#define DEFAULT_SERIAL_PADDR        UART1_PADDR
+#define DEFAULT_SERIAL_INTERRUPT    UART1_IRQ
+
+#else
+#error "unknown i.MX6 board"
 #endif
diff --git a/libplatsupport/plat_include/imx6/platsupport/plat/src.h b/libplatsupport/plat_include/imx6/platsupport/plat/src.h
index d7e7f0f..7c939a9 100644
--- a/libplatsupport/plat_include/imx6/platsupport/plat/src.h
+++ b/libplatsupport/plat_include/imx6/platsupport/plat/src.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/imx6/platsupport/plat/timer.h b/libplatsupport/plat_include/imx6/platsupport/plat/timer.h
index 8a7ec4b..8e6653c 100644
--- a/libplatsupport/plat_include/imx6/platsupport/plat/timer.h
+++ b/libplatsupport/plat_include/imx6/platsupport/plat/timer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/imx7/platsupport/plat/clock.h b/libplatsupport/plat_include/imx7/platsupport/plat/clock.h
index 1d42815..6a41df4 100644
--- a/libplatsupport/plat_include/imx7/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/imx7/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/imx7/platsupport/plat/epit_constants.h b/libplatsupport/plat_include/imx7/platsupport/plat/epit_constants.h
index 3d4c349..50481cd 100644
--- a/libplatsupport/plat_include/imx7/platsupport/plat/epit_constants.h
+++ b/libplatsupport/plat_include/imx7/platsupport/plat/epit_constants.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/imx7/platsupport/plat/gpt_constants.h b/libplatsupport/plat_include/imx7/platsupport/plat/gpt_constants.h
index 61d0ee6..5b4c569 100644
--- a/libplatsupport/plat_include/imx7/platsupport/plat/gpt_constants.h
+++ b/libplatsupport/plat_include/imx7/platsupport/plat/gpt_constants.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/imx7/platsupport/plat/i2c.h b/libplatsupport/plat_include/imx7/platsupport/plat/i2c.h
index 84afe1c..b9a1794 100644
--- a/libplatsupport/plat_include/imx7/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/imx7/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/imx7/platsupport/plat/serial.h b/libplatsupport/plat_include/imx7/platsupport/plat/serial.h
index 29f952a..bea59e4 100644
--- a/libplatsupport/plat_include/imx7/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/imx7/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/imx7/platsupport/plat/timer.h b/libplatsupport/plat_include/imx7/platsupport/plat/timer.h
index df3aea0..9ecffaa 100644
--- a/libplatsupport/plat_include/imx7/platsupport/plat/timer.h
+++ b/libplatsupport/plat_include/imx7/platsupport/plat/timer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/imx8m/platsupport/plat/clock.h b/libplatsupport/plat_include/imx8m/platsupport/plat/clock.h
index f859607..faf3f06 100644
--- a/libplatsupport/plat_include/imx8m/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/imx8m/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/imx8m/platsupport/plat/gpt_constants.h b/libplatsupport/plat_include/imx8m/platsupport/plat/gpt_constants.h
index 36f2759..78b696e 100644
--- a/libplatsupport/plat_include/imx8m/platsupport/plat/gpt_constants.h
+++ b/libplatsupport/plat_include/imx8m/platsupport/plat/gpt_constants.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/imx8m/platsupport/plat/i2c.h b/libplatsupport/plat_include/imx8m/platsupport/plat/i2c.h
index bd4aabe..672cb9e 100644
--- a/libplatsupport/plat_include/imx8m/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/imx8m/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/imx8m/platsupport/plat/serial.h b/libplatsupport/plat_include/imx8m/platsupport/plat/serial.h
index eef2b91..1337192 100644
--- a/libplatsupport/plat_include/imx8m/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/imx8m/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/imx8m/platsupport/plat/timer.h b/libplatsupport/plat_include/imx8m/platsupport/plat/timer.h
index 56dbe4d..a4e5c56 100644
--- a/libplatsupport/plat_include/imx8m/platsupport/plat/timer.h
+++ b/libplatsupport/plat_include/imx8m/platsupport/plat/timer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/odroidc2/platsupport/plat/clock.h b/libplatsupport/plat_include/odroidc2/platsupport/plat/clock.h
index 9162729..d72bddf 100644
--- a/libplatsupport/plat_include/odroidc2/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/odroidc2/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/odroidc2/platsupport/plat/i2c.h b/libplatsupport/plat_include/odroidc2/platsupport/plat/i2c.h
index a9d5020..bb3269b 100644
--- a/libplatsupport/plat_include/odroidc2/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/odroidc2/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/odroidc2/platsupport/plat/meson_timer.h b/libplatsupport/plat_include/odroidc2/platsupport/plat/meson_timer.h
index 55b71cf..0215317 100644
--- a/libplatsupport/plat_include/odroidc2/platsupport/plat/meson_timer.h
+++ b/libplatsupport/plat_include/odroidc2/platsupport/plat/meson_timer.h
@@ -1,23 +1,13 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
 
 #include <platsupport/timer.h>
-
-#define TIMER_BASE      0xc1100000
-#define TIMER_MAP_BASE  0xc1109000
-
-#define TIMER_REG_START   0x2650    // TIMER_MUX
+#include <platsupport/plat/odroid_timer.h>
 
 #define TIMER_E_INPUT_CLK 8
 #define TIMER_D_INPUT_CLK 6
diff --git a/libplatsupport/plat_include/odroidc2/platsupport/plat/odroid_serial.h b/libplatsupport/plat_include/odroidc2/platsupport/plat/odroid_serial.h
new file mode 100644
index 0000000..d762753
--- /dev/null
+++ b/libplatsupport/plat_include/odroidc2/platsupport/plat/odroid_serial.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#define UART0_PADDR     0xc1108000
+#define UART1_PADDR     0xc1108000
+#define UART2_PADDR     0xc1108000
+#define UART0_AO_PADDR  0xc8100000
+#define UART2_AO_PADDR  0xc8104000
+
+#define UART0_OFFSET    0x4c0
+#define UART1_OFFSET    0x4dc
+#define UART2_OFFSET    0x700
+#define UART0_AO_OFFSET 0x4c0
+#define UART2_AO_OFFSET 0x4e0
+
+#define UART0_IRQ       54
+#define UART1_IRQ       105
+#define UART2_IRQ       123
+#define UART0_AO_IRQ    225
+#define UART2_AO_IRQ    229
+
diff --git a/libplatsupport/plat_include/odroidc2/platsupport/plat/odroid_timer.h b/libplatsupport/plat_include/odroidc2/platsupport/plat/odroid_timer.h
new file mode 100644
index 0000000..3910a38
--- /dev/null
+++ b/libplatsupport/plat_include/odroidc2/platsupport/plat/odroid_timer.h
@@ -0,0 +1,10 @@
+/*
+ * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#define TIMER_BASE      0xc1100000
+#define TIMER_MAP_BASE  0xc1109000
+
+#define TIMER_REG_START   0x2650    // TIMER_MUX
diff --git a/libplatsupport/plat_include/odroidc2/platsupport/plat/serial.h b/libplatsupport/plat_include/odroidc2/platsupport/plat/serial.h
index 873e151..874627f 100644
--- a/libplatsupport/plat_include/odroidc2/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/odroidc2/platsupport/plat/serial.h
@@ -1,34 +1,12 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
 
-#define UART0_PADDR     0xc1108000
-#define UART1_PADDR     0xc1108000
-#define UART2_PADDR     0xc1108000
-#define UART0_AO_PADDR  0xc8100000
-#define UART2_AO_PADDR  0xc8104000
-
-#define UART0_OFFSET    0x4c0
-#define UART1_OFFSET    0x4dc
-#define UART2_OFFSET    0x700
-#define UART0_AO_OFFSET 0x4c0
-#define UART2_AO_OFFSET 0x4e0
-
-#define UART0_IRQ       54
-#define UART1_IRQ       105
-#define UART2_IRQ       123
-#define UART0_AO_IRQ    225
-#define UART2_AO_IRQ    229
+#include <platsupport/plat/odroid_serial.h>
 
 enum chardev_id {
     UART0,
diff --git a/libplatsupport/plat_include/odroidc4/platsupport/plat/clock.h b/libplatsupport/plat_include/odroidc4/platsupport/plat/clock.h
new file mode 120000
index 0000000..2dffcc5
--- /dev/null
+++ b/libplatsupport/plat_include/odroidc4/platsupport/plat/clock.h
@@ -0,0 +1 @@
+../../../odroidc2/platsupport/plat/clock.h
\ No newline at end of file
diff --git a/libplatsupport/plat_include/odroidc4/platsupport/plat/i2c.h b/libplatsupport/plat_include/odroidc4/platsupport/plat/i2c.h
new file mode 120000
index 0000000..3a76f1f
--- /dev/null
+++ b/libplatsupport/plat_include/odroidc4/platsupport/plat/i2c.h
@@ -0,0 +1 @@
+../../../odroidc2/platsupport/plat/i2c.h
\ No newline at end of file
diff --git a/libplatsupport/plat_include/odroidc4/platsupport/plat/meson_timer.h b/libplatsupport/plat_include/odroidc4/platsupport/plat/meson_timer.h
new file mode 120000
index 0000000..4c800da
--- /dev/null
+++ b/libplatsupport/plat_include/odroidc4/platsupport/plat/meson_timer.h
@@ -0,0 +1 @@
+../../../odroidc2/platsupport/plat/meson_timer.h
\ No newline at end of file
diff --git a/libplatsupport/plat_include/odroidc4/platsupport/plat/odroid_serial.h b/libplatsupport/plat_include/odroidc4/platsupport/plat/odroid_serial.h
new file mode 100644
index 0000000..27c0412
--- /dev/null
+++ b/libplatsupport/plat_include/odroidc4/platsupport/plat/odroid_serial.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#define UART0_PADDR     0xffd22000
+#define UART1_PADDR     0xffd24000
+#define UART2_PADDR     0xffd23000
+#define UART0_AO_PADDR  0xff803000
+#define UART2_AO_PADDR  0xff804000
+
+#define UART0_OFFSET    0x0
+#define UART1_OFFSET    0x0
+#define UART2_OFFSET    0x0
+#define UART0_AO_OFFSET 0x0
+#define UART2_AO_OFFSET 0x0
+
+#define UART0_IRQ       58
+#define UART1_IRQ       107
+#define UART2_IRQ       125
+#define UART0_AO_IRQ    225
+#define UART2_AO_IRQ    229
diff --git a/libplatsupport/plat_include/odroidc4/platsupport/plat/odroid_timer.h b/libplatsupport/plat_include/odroidc4/platsupport/plat/odroid_timer.h
new file mode 100644
index 0000000..7519844
--- /dev/null
+++ b/libplatsupport/plat_include/odroidc4/platsupport/plat/odroid_timer.h
@@ -0,0 +1,10 @@
+/*
+ * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#define TIMER_BASE      0xffd00000
+#define TIMER_MAP_BASE  0xffd0f000
+
+#define TIMER_REG_START   0x3c50    // TIMER_MUX
diff --git a/libplatsupport/plat_include/odroidc4/platsupport/plat/serial.h b/libplatsupport/plat_include/odroidc4/platsupport/plat/serial.h
new file mode 120000
index 0000000..aa2c64b
--- /dev/null
+++ b/libplatsupport/plat_include/odroidc4/platsupport/plat/serial.h
@@ -0,0 +1 @@
+../../../odroidc2/platsupport/plat/serial.h
\ No newline at end of file
diff --git a/libplatsupport/plat_include/omap3/platsupport/plat/clock.h b/libplatsupport/plat_include/omap3/platsupport/plat/clock.h
index af70c53..530ad0c 100644
--- a/libplatsupport/plat_include/omap3/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/omap3/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/omap3/platsupport/plat/gpt_constants.h b/libplatsupport/plat_include/omap3/platsupport/plat/gpt_constants.h
index 620ad8f..5e3b001 100644
--- a/libplatsupport/plat_include/omap3/platsupport/plat/gpt_constants.h
+++ b/libplatsupport/plat_include/omap3/platsupport/plat/gpt_constants.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/omap3/platsupport/plat/i2c.h b/libplatsupport/plat_include/omap3/platsupport/plat/i2c.h
index 14b63ec..40efe17 100644
--- a/libplatsupport/plat_include/omap3/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/omap3/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/omap3/platsupport/plat/serial.h b/libplatsupport/plat_include/omap3/platsupport/plat/serial.h
index 019e39f..43f11ff 100644
--- a/libplatsupport/plat_include/omap3/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/omap3/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/README b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/README
index 84ad128..81f2a62 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/README
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/README
@@ -1,13 +1,7 @@
 <!--
-  Copyright 2017, Data61
-  Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-  ABN 41 687 119 230.
+  Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 
-  This software may be distributed and modified according to the terms of
-  the BSD 2-Clause license. Note that NO WARRANTY is provided.
-  See "LICENSE_BSD2.txt" for details.
-
-  @TAG(DATA61_BSD)
+  SPDX-License-Identifier: CC-BY-SA-4.0
 -->
 
 This is a generic, OS independent acpi library.
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/acpi.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/acpi.h
index 041067c..6c8c626 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/acpi.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/acpi.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/regions.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/regions.h
index e4b6911..87ef01a 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/regions.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/regions.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/asf.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/asf.h
index 29500f8..8a8f308 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/asf.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/asf.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/bert.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/bert.h
index e25caaa..561ab21 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/bert.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/bert.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/boot.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/boot.h
index f9f03dc..5f6fe6f 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/boot.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/boot.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/dmar.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/dmar.h
index fac78ba..a5c0ea1 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/dmar.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/dmar.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/dsdt.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/dsdt.h
index 074d420..579f16e 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/dsdt.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/dsdt.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/einj.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/einj.h
index 56816d8..21a6989 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/einj.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/einj.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/erst.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/erst.h
index c3ea121..2df9bbd 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/erst.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/erst.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/facs.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/facs.h
index 0888b75..20ca90f 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/facs.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/facs.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/fadt.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/fadt.h
index a3bf206..de38ce6 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/fadt.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/fadt.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/hest.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/hest.h
index b59dd50..d2a996d 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/hest.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/hest.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/hpet.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/hpet.h
index 01373fd..6766e1c 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/hpet.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/hpet.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/madt.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/madt.h
index 099b908..eeb07f1 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/madt.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/madt.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/mcfg.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/mcfg.h
index abb2beb..17d9ccc 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/mcfg.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/mcfg.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/rsdt.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/rsdt.h
index 9181791..73f690b 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/rsdt.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/rsdt.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/spcr.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/spcr.h
index c943076..f31ae02 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/spcr.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/spcr.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/spmi.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/spmi.h
index f503ba9..e0f9bec 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/spmi.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/spmi.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/ssdt.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/ssdt.h
index d4b551a..62dcc55 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/ssdt.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/ssdt.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/xsdt.h b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/xsdt.h
index 873d8eb..ce3c668 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/xsdt.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/acpi/tables/xsdt.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma pack(push,1)
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/clock.h b/libplatsupport/plat_include/pc99/platsupport/plat/clock.h
index 2a4bdce..fb18285 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/hpet.h b/libplatsupport/plat_include/pc99/platsupport/plat/hpet.h
index d3ee639..68d1099 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/hpet.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/hpet.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
@@ -44,15 +38,6 @@
     uint64_t period_ns;
 } hpet_t;
 
-static UNUSED timer_properties_t hpet_properties =
-{
-        .upcounter = true,
-        .timeouts = true,
-        .absolute_timeouts = true,
-        .bit_width = 64,
-        .irqs = 1
-};
-
 int hpet_init(hpet_t *hpet, hpet_config_t config);
 int hpet_start(const hpet_t *hpet);
 int hpet_stop(const hpet_t *hpet);
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/pit.h b/libplatsupport/plat_include/pc99/platsupport/plat/pit.h
index d654ee6..aad8e15 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/pit.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/pit.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/rtc.h b/libplatsupport/plat_include/pc99/platsupport/plat/rtc.h
index 330a96a..3104758 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/rtc.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/rtc.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/serial.h b/libplatsupport/plat_include/pc99/platsupport/plat/serial.h
index 863aca0..13b0f14 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/pc99/platsupport/plat/timer.h b/libplatsupport/plat_include/pc99/platsupport/plat/timer.h
index feefb2e..a873a26 100644
--- a/libplatsupport/plat_include/pc99/platsupport/plat/timer.h
+++ b/libplatsupport/plat_include/pc99/platsupport/plat/timer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/polarfire/platsupport/plat/icicle_mss.h b/libplatsupport/plat_include/polarfire/platsupport/plat/icicle_mss.h
index 7ef92f1..87f1f92 100644
--- a/libplatsupport/plat_include/polarfire/platsupport/plat/icicle_mss.h
+++ b/libplatsupport/plat_include/polarfire/platsupport/plat/icicle_mss.h
@@ -1,11 +1,7 @@
 /*
  * Copyright 2020, DornerWorks
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DORNERWORKS_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* These values are grabbed from the ICICLE_MSS_0.xml file that is generated from
diff --git a/libplatsupport/plat_include/polarfire/platsupport/plat/serial.h b/libplatsupport/plat_include/polarfire/platsupport/plat/serial.h
index 24232e5..c3c50aa 100644
--- a/libplatsupport/plat_include/polarfire/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/polarfire/platsupport/plat/serial.h
@@ -1,11 +1,7 @@
 /*
  * Copyright 2020, DornerWorks
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DORNERWORKS_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
@@ -83,8 +79,8 @@
 #define DEFAULT_SERIAL_PADDR UART3_PADDR
 #define DEFAULT_SERIAL_INTERRUPT UART3_IRQ
 
-/* Relevant Register Masks *
-/
+/* Relevant Register Masks */
+
 /* Line Control Register */
 #define LCR_WORD_LEN_5                  0b00
 #define LCR_WORD_LEN_6                  0b01
diff --git a/libplatsupport/plat_include/qemu-arm-virt/platsupport/plat/clock.h b/libplatsupport/plat_include/qemu-arm-virt/platsupport/plat/clock.h
index 4a212a1..072a13d 100644
--- a/libplatsupport/plat_include/qemu-arm-virt/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/qemu-arm-virt/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/qemu-arm-virt/platsupport/plat/i2c.h b/libplatsupport/plat_include/qemu-arm-virt/platsupport/plat/i2c.h
index 14b63ec..40efe17 100644
--- a/libplatsupport/plat_include/qemu-arm-virt/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/qemu-arm-virt/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/qemu-arm-virt/platsupport/plat/serial.h b/libplatsupport/plat_include/qemu-arm-virt/platsupport/plat/serial.h
index 4ee11fe..15d4d29 100644
--- a/libplatsupport/plat_include/qemu-arm-virt/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/qemu-arm-virt/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/rocketchip/platsupport/plat/serial.h b/libplatsupport/plat_include/rocketchip/platsupport/plat/serial.h
index 60d0503..6656a5f 100644
--- a/libplatsupport/plat_include/rocketchip/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/rocketchip/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/rockpro64/platsupport/plat/clock.h b/libplatsupport/plat_include/rockpro64/platsupport/plat/clock.h
index 7d047c2..c8a5f1d 100644
--- a/libplatsupport/plat_include/rockpro64/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/rockpro64/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/rockpro64/platsupport/plat/i2c.h b/libplatsupport/plat_include/rockpro64/platsupport/plat/i2c.h
index cb9e676..5f7fa91 100644
--- a/libplatsupport/plat_include/rockpro64/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/rockpro64/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/rockpro64/platsupport/plat/serial.h b/libplatsupport/plat_include/rockpro64/platsupport/plat/serial.h
index a2f7acf..e5fc898 100644
--- a/libplatsupport/plat_include/rockpro64/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/rockpro64/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/rockpro64/platsupport/plat/timer.h b/libplatsupport/plat_include/rockpro64/platsupport/plat/timer.h
index 7e96d7f..42ef340 100644
--- a/libplatsupport/plat_include/rockpro64/platsupport/plat/timer.h
+++ b/libplatsupport/plat_include/rockpro64/platsupport/plat/timer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/spike/platsupport/plat/clock.h b/libplatsupport/plat_include/spike/platsupport/plat/clock.h
index 089b31f..9b476e2 100644
--- a/libplatsupport/plat_include/spike/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/spike/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/spike/platsupport/plat/serial.h b/libplatsupport/plat_include/spike/platsupport/plat/serial.h
index ac6a134..2fe79b8 100644
--- a/libplatsupport/plat_include/spike/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/spike/platsupport/plat/serial.h
@@ -1,23 +1,17 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
 
-enum chardev_id {                      
-    PS_SERIAL0,                        
-    PS_SERIAL1,                        
-    /* defaults */                     
-    PS_SERIAL_DEFAULT = PS_SERIAL1     
-};                                     
+enum chardev_id {
+    PS_SERIAL0,
+    PS_SERIAL1,
+    /* defaults */
+    PS_SERIAL_DEFAULT = PS_SERIAL1
+};
 
 #define PS_SERIAL_DEFAULT 0
 
diff --git a/libplatsupport/plat_include/spike/platsupport/plat/timer.h b/libplatsupport/plat_include/spike/platsupport/plat/timer.h
index bbb9bc3..ccc8fe9 100644
--- a/libplatsupport/plat_include/spike/platsupport/plat/timer.h
+++ b/libplatsupport/plat_include/spike/platsupport/plat/timer.h
@@ -1,12 +1,6 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
diff --git a/libplatsupport/plat_include/tk1/platsupport/plat/clock.h b/libplatsupport/plat_include/tk1/platsupport/plat/clock.h
index 6fee874..b1abe7d 100644
--- a/libplatsupport/plat_include/tk1/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/tk1/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/tk1/platsupport/plat/clock_indexes.h b/libplatsupport/plat_include/tk1/platsupport/plat/clock_indexes.h
index 6bfb974..1ff2176 100644
--- a/libplatsupport/plat_include/tk1/platsupport/plat/clock_indexes.h
+++ b/libplatsupport/plat_include/tk1/platsupport/plat/clock_indexes.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/tk1/platsupport/plat/gpio.h b/libplatsupport/plat_include/tk1/platsupport/plat/gpio.h
index c3c21e0..716298b 100644
--- a/libplatsupport/plat_include/tk1/platsupport/plat/gpio.h
+++ b/libplatsupport/plat_include/tk1/platsupport/plat/gpio.h
@@ -1,14 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
-*/
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
 
 #pragma once
 
diff --git a/libplatsupport/plat_include/tk1/platsupport/plat/i2c.h b/libplatsupport/plat_include/tk1/platsupport/plat/i2c.h
index feb6603..6744855 100644
--- a/libplatsupport/plat_include/tk1/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/tk1/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/tk1/platsupport/plat/mux.h b/libplatsupport/plat_include/tk1/platsupport/plat/mux.h
index 52cbe75..fc8bda1 100644
--- a/libplatsupport/plat_include/tk1/platsupport/plat/mux.h
+++ b/libplatsupport/plat_include/tk1/platsupport/plat/mux.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/tk1/platsupport/plat/serial.h b/libplatsupport/plat_include/tk1/platsupport/plat/serial.h
index 643e992..5369d64 100644
--- a/libplatsupport/plat_include/tk1/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/tk1/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/tk1/platsupport/plat/spi.h b/libplatsupport/plat_include/tk1/platsupport/plat/spi.h
index 64a256c..9327842 100644
--- a/libplatsupport/plat_include/tk1/platsupport/plat/spi.h
+++ b/libplatsupport/plat_include/tk1/platsupport/plat/spi.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/tk1/platsupport/plat/timer.h b/libplatsupport/plat_include/tk1/platsupport/plat/timer.h
index 8bba9c1..731ea73 100644
--- a/libplatsupport/plat_include/tk1/platsupport/plat/timer.h
+++ b/libplatsupport/plat_include/tk1/platsupport/plat/timer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/mach/timer_tk1_tx1_defs.h>
diff --git a/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/clock.h b/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/clock.h
new file mode 100644
index 0000000..3dbc3e5
--- /dev/null
+++ b/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/clock.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2021, Breakaway Consulting Pty. Ltd.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#pragma once
+
+enum clk_id {
+    NCLOCKS,
+};
+
+enum clock_gate {
+    NCLKGATES
+};
diff --git a/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/gpt.h b/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/gpt.h
new file mode 100644
index 0000000..ee2db74
--- /dev/null
+++ b/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/gpt.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2021, Breakaway Consulting Pty. Ltd.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#include <platsupport/io.h>
+#include <platsupport/ltimer.h>
+
+struct gpt_regs;
+
+enum gpt_timeout_type {
+    GPT_TIMEOUT_ONESHOT,
+    GPT_TIMEOUT_PERIODIC,
+    GPT_TIMEOUT_NONE,
+};
+
+typedef struct gpt {
+    /* I/O ops */
+    ps_io_ops_t io_ops;
+
+    /* allocated resources */
+    irq_id_t irq_id;
+    pmem_region_t pmem;
+
+    /* ltimer callback information */
+    ltimer_callback_fn_t user_callback;
+    void *user_callback_token;
+
+    /* registers */
+    volatile struct gpt_regs *regs;
+
+    /* internal state tracking data */
+    uint64_t counted_ticks;
+    uint64_t current_timeout;
+    enum gpt_timeout_type timeout_type;
+} gpt_t;
+
+int gpt_init(gpt_t *gpt, char *fdt_path, ps_io_ops_t ops, ltimer_callback_fn_t user_callback,
+             void *user_callback_token);
+int gpt_get_time(gpt_t *gpt, uint64_t *time);
+int gpt_set_timeout(gpt_t *gpt, uint64_t ns, timeout_type_t type);
+int gpt_reset(gpt_t *gpt);
+void gpt_destroy(gpt_t *gpt);
diff --git a/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/gpt_constants.h b/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/gpt_constants.h
new file mode 100644
index 0000000..dd06bb5
--- /dev/null
+++ b/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/gpt_constants.h
@@ -0,0 +1,7 @@
+/*
+ * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2021, Breakaway Consulting Pty. Ltd.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#pragma once
diff --git a/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/i2c.h b/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/i2c.h
new file mode 100644
index 0000000..f261c0e
--- /dev/null
+++ b/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/i2c.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2021, Breakaway Consulting Pty. Ltd.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#pragma once
+
+enum i2c_id {
+    NI2C
+};
diff --git a/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/serial.h b/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/serial.h
new file mode 100644
index 0000000..9f37c9d
--- /dev/null
+++ b/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/serial.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2021, Breakaway Consulting Pty. Ltd.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#pragma once
+
+/* Note: The TQMa8XQP board only has LPUART_1 available by default.
+ * This is due to that UART being enabled by u-boot. Additional,
+ * UARTs require an implementation of the SCFW client API to
+ * turn on additional UARTs.
+ *
+ * This is beyond the scope of the simple platform support library.
+ * As such only a single UART is supported.
+ */
+enum chardev_id {
+    PS_SERIAL_DEFAULT,
+};
\ No newline at end of file
diff --git a/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/timer.h b/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/timer.h
new file mode 100644
index 0000000..ba6bc8c
--- /dev/null
+++ b/libplatsupport/plat_include/tqma8xqp1gb/platsupport/plat/timer.h
@@ -0,0 +1,11 @@
+/*
+ * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2021, Breakaway Consulting Pty. Ltd.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+/*
+ * This is sufficient for ensure libplatsupport can compile and allow
+ * for sel4test to run.
+ */
+#pragma once
diff --git a/libplatsupport/plat_include/tx1/platsupport/plat/clock.h b/libplatsupport/plat_include/tx1/platsupport/plat/clock.h
index 4a212a1..072a13d 100644
--- a/libplatsupport/plat_include/tx1/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/tx1/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/tx1/platsupport/plat/i2c.h b/libplatsupport/plat_include/tx1/platsupport/plat/i2c.h
index 14b63ec..40efe17 100644
--- a/libplatsupport/plat_include/tx1/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/tx1/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/tx1/platsupport/plat/serial.h b/libplatsupport/plat_include/tx1/platsupport/plat/serial.h
index abe0223..e2a60ac 100644
--- a/libplatsupport/plat_include/tx1/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/tx1/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/tx1/platsupport/plat/timer.h b/libplatsupport/plat_include/tx1/platsupport/plat/timer.h
index 8bba9c1..731ea73 100644
--- a/libplatsupport/plat_include/tx1/platsupport/plat/timer.h
+++ b/libplatsupport/plat_include/tx1/platsupport/plat/timer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/mach/timer_tk1_tx1_defs.h>
diff --git a/libplatsupport/plat_include/tx2/platsupport/plat/clock.h b/libplatsupport/plat_include/tx2/platsupport/plat/clock.h
index a639c61..42ae2aa 100644
--- a/libplatsupport/plat_include/tx2/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/tx2/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/tx2/platsupport/plat/i2c.h b/libplatsupport/plat_include/tx2/platsupport/plat/i2c.h
index 741c1a9..85cec1e 100644
--- a/libplatsupport/plat_include/tx2/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/tx2/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/tx2/platsupport/plat/reset.h b/libplatsupport/plat_include/tx2/platsupport/plat/reset.h
index 026ed6a..adeccaa 100644
--- a/libplatsupport/plat_include/tx2/platsupport/plat/reset.h
+++ b/libplatsupport/plat_include/tx2/platsupport/plat/reset.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2020, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/tx2/platsupport/plat/serial.h b/libplatsupport/plat_include/tx2/platsupport/plat/serial.h
index 68dc498..13f9218 100644
--- a/libplatsupport/plat_include/tx2/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/tx2/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/tx2/platsupport/plat/timer.h b/libplatsupport/plat_include/tx2/platsupport/plat/timer.h
index c143084..41be1a2 100644
--- a/libplatsupport/plat_include/tx2/platsupport/plat/timer.h
+++ b/libplatsupport/plat_include/tx2/platsupport/plat/timer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/zynq7000/platsupport/plat/clock.h b/libplatsupport/plat_include/zynq7000/platsupport/plat/clock.h
index feddf0b..c01675b 100644
--- a/libplatsupport/plat_include/zynq7000/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/zynq7000/platsupport/plat/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/zynq7000/platsupport/plat/i2c.h b/libplatsupport/plat_include/zynq7000/platsupport/plat/i2c.h
index acb7976..9f5dc6b 100644
--- a/libplatsupport/plat_include/zynq7000/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/zynq7000/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/zynq7000/platsupport/plat/serial.h b/libplatsupport/plat_include/zynq7000/platsupport/plat/serial.h
index 3276843..74955d3 100644
--- a/libplatsupport/plat_include/zynq7000/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/zynq7000/platsupport/plat/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/zynq7000/platsupport/plat/src.h b/libplatsupport/plat_include/zynq7000/platsupport/plat/src.h
index 2b2589b..2f21313 100644
--- a/libplatsupport/plat_include/zynq7000/platsupport/plat/src.h
+++ b/libplatsupport/plat_include/zynq7000/platsupport/plat/src.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/plat_include/zynq7000/platsupport/plat/timer.h b/libplatsupport/plat_include/zynq7000/platsupport/plat/timer.h
index db51ead..cf69e8e 100644
--- a/libplatsupport/plat_include/zynq7000/platsupport/plat/timer.h
+++ b/libplatsupport/plat_include/zynq7000/platsupport/plat/timer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 #include <platsupport/mach/timer.h>
diff --git a/libplatsupport/plat_include/zynq7000/platsupport/plat/tmu.h b/libplatsupport/plat_include/zynq7000/platsupport/plat/tmu.h
index de71881..430f6aa 100644
--- a/libplatsupport/plat_include/zynq7000/platsupport/plat/tmu.h
+++ b/libplatsupport/plat_include/zynq7000/platsupport/plat/tmu.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/zynqmp/platsupport/plat/clock.h b/libplatsupport/plat_include/zynqmp/platsupport/plat/clock.h
index 4ba33db..41ae323 100644
--- a/libplatsupport/plat_include/zynqmp/platsupport/plat/clock.h
+++ b/libplatsupport/plat_include/zynqmp/platsupport/plat/clock.h
@@ -1,12 +1,9 @@
 /*
  * Copyright 2017, DornerWorks
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DORNERWORKS_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
+
 /*
  * This data was produced by DornerWorks, Ltd. of Grand Rapids, MI, USA under
  * a DARPA SBIR, Contract Number D16PC00107.
diff --git a/libplatsupport/plat_include/zynqmp/platsupport/plat/i2c.h b/libplatsupport/plat_include/zynqmp/platsupport/plat/i2c.h
index acb7976..9f5dc6b 100644
--- a/libplatsupport/plat_include/zynqmp/platsupport/plat/i2c.h
+++ b/libplatsupport/plat_include/zynqmp/platsupport/plat/i2c.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/plat_include/zynqmp/platsupport/plat/serial.h b/libplatsupport/plat_include/zynqmp/platsupport/plat/serial.h
index c00357e..f1b8eef 100644
--- a/libplatsupport/plat_include/zynqmp/platsupport/plat/serial.h
+++ b/libplatsupport/plat_include/zynqmp/platsupport/plat/serial.h
@@ -1,15 +1,10 @@
 /*
  * Copyright 2017, DornerWorks
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_DORNERWORKS_BSD)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
+
 /*
  * This data was produced by DornerWorks, Ltd. of Grand Rapids, MI, USA under
  * a DARPA SBIR, Contract Number D16PC00107.
diff --git a/libplatsupport/plat_include/zynqmp/platsupport/plat/src.h b/libplatsupport/plat_include/zynqmp/platsupport/plat/src.h
index 18b763d..bc50247 100644
--- a/libplatsupport/plat_include/zynqmp/platsupport/plat/src.h
+++ b/libplatsupport/plat_include/zynqmp/platsupport/plat/src.h
@@ -1,14 +1,8 @@
 /*
  * Copyright 2017, DornerWorks
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_DORNERWORKS_BSD)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 /*
  * This data was produced by DornerWorks, Ltd. of Grand Rapids, MI, USA under
diff --git a/libplatsupport/plat_include/zynqmp/platsupport/plat/timer.h b/libplatsupport/plat_include/zynqmp/platsupport/plat/timer.h
index dcd266c..44a0b81 100644
--- a/libplatsupport/plat_include/zynqmp/platsupport/plat/timer.h
+++ b/libplatsupport/plat_include/zynqmp/platsupport/plat/timer.h
@@ -1,14 +1,8 @@
 /*
  * Copyright 2017, DornerWorks
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_DORNERWORKS_BSD)
+ * SPDX-License-Identifier: GPL-2.0-only
  */
 /*
  * This data was produced by DornerWorks, Ltd. of Grand Rapids, MI, USA under
diff --git a/libplatsupport/sel4_arch_include/aarch32/platsupport/sel4_arch/util.h b/libplatsupport/sel4_arch_include/aarch32/platsupport/sel4_arch/util.h
index f4baeba..a32f563 100644
--- a/libplatsupport/sel4_arch_include/aarch32/platsupport/sel4_arch/util.h
+++ b/libplatsupport/sel4_arch_include/aarch32/platsupport/sel4_arch/util.h
@@ -1,14 +1,8 @@
 /*
-* Copyright 2019, Data61
-* Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-* ABN 41 687 119 230.
-*
-* This software may be distributed and modified according to the terms of
-* the BSD 2-Clause license. Note that NO WARRANTY is provided.
-* See "LICENSE_BSD2.txt" for details.
-*
-* @TAG(DATA61_BSD)
-*/
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
 
 #pragma once
 
diff --git a/libplatsupport/sel4_arch_include/aarch64/platsupport/sel4_arch/util.h b/libplatsupport/sel4_arch_include/aarch64/platsupport/sel4_arch/util.h
index 9ec950a..c683019 100644
--- a/libplatsupport/sel4_arch_include/aarch64/platsupport/sel4_arch/util.h
+++ b/libplatsupport/sel4_arch_include/aarch64/platsupport/sel4_arch/util.h
@@ -1,14 +1,8 @@
 /*
-* Copyright 2019, Data61
-* Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-* ABN 41 687 119 230.
-*
-* This software may be distributed and modified according to the terms of
-* the BSD 2-Clause license. Note that NO WARRANTY is provided.
-* See "LICENSE_BSD2.txt" for details.
-*
-* @TAG(DATA61_BSD)
-*/
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
 
 #pragma once
 
diff --git a/libplatsupport/src/arch/arm/clock.c b/libplatsupport/src/arch/arm/clock.c
index b652bf0..7313875 100644
--- a/libplatsupport/src/arch/arm/clock.c
+++ b/libplatsupport/src/arch/arm/clock.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include "clock.h"
@@ -140,11 +134,11 @@
             strcpy(new_prefix + depth, " ");
         }
         if (freqh == 0) {
-            printf("%s\\%s (%03d %s)\n", new_prefix, clk->name, freql, u[0]);
+            ZF_LOGI("%s\\%s (%03d %s)", new_prefix, clk->name, freql, u[0]);
         } else if (freql == 0) {
-            printf("%s\\%s (%d %s)\n", new_prefix, clk->name, freqh, u[1]);
+            ZF_LOGI("%s\\%s (%d %s)", new_prefix, clk->name, freqh, u[1]);
         } else {
-            printf("%s\\%s (%d.%03d %s)\n", new_prefix, clk->name, freqh, freql, u[1]);
+            ZF_LOGI("%s\\%s (%d.%03d %s)", new_prefix, clk->name, freqh, freql, u[1]);
         }
         clk_print_tree(clk->child, new_prefix);
         clk = clk->sibling;
@@ -169,9 +163,8 @@
         child->sibling = parent->child;
         parent->child = child;
     } else if (child->parent != parent) {
-        printf("%s->%s\n | %s already has parent %s",
-               child->name, parent->name, child->name,
-               child->parent->name);
+        ZF_LOGI("%s->%s (%s already had parent %s)",
+                child->name, parent->name, child->name, child->parent->name);
         assert(!"Changing parents not supported yet");
     }
 }
diff --git a/libplatsupport/src/arch/arm/clock.h b/libplatsupport/src/arch/arm/clock.h
index 710312f..75d65fb 100644
--- a/libplatsupport/src/arch/arm/clock.h
+++ b/libplatsupport/src/arch/arm/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/src/arch/arm/delay.c b/libplatsupport/src/arch/arm/delay.c
index 397f082..f4e18f4 100644
--- a/libplatsupport/src/arch/arm/delay.c
+++ b/libplatsupport/src/arch/arm/delay.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <autoconf.h>
diff --git a/libplatsupport/src/arch/arm/dma330.c b/libplatsupport/src/arch/arm/dma330.c
index 61002fe..3566877 100644
--- a/libplatsupport/src/arch/arm/dma330.c
+++ b/libplatsupport/src/arch/arm/dma330.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <autoconf.h>
diff --git a/libplatsupport/src/arch/arm/generic_ltimer.c b/libplatsupport/src/arch/arm/generic_ltimer.c
index ed1b41b..14d449c 100644
--- a/libplatsupport/src/arch/arm/generic_ltimer.c
+++ b/libplatsupport/src/arch/arm/generic_ltimer.c
@@ -1,14 +1,9 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 128 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
+
 #include <autoconf.h>
 #include <stdio.h>
 #include <assert.h>
diff --git a/libplatsupport/src/arch/arm/generic_timer.c b/libplatsupport/src/arch/arm/generic_timer.c
index be1c8b0..4d20988 100644
--- a/libplatsupport/src/arch/arm/generic_timer.c
+++ b/libplatsupport/src/arch/arm/generic_timer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <autoconf.h>
 #include <platsupport/gen_config.h>
diff --git a/libplatsupport/src/arch/arm/gpio_utils.c b/libplatsupport/src/arch/arm/gpio_utils.c
index e496a61..188a77b 100644
--- a/libplatsupport/src/arch/arm/gpio_utils.c
+++ b/libplatsupport/src/arch/arm/gpio_utils.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdbool.h>
diff --git a/libplatsupport/src/arch/arm/i2c.c b/libplatsupport/src/arch/arm/i2c.c
index b5a0b97..1e4a919 100644
--- a/libplatsupport/src/arch/arm/i2c.c
+++ b/libplatsupport/src/arch/arm/i2c.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/i2c.h>
diff --git a/libplatsupport/src/arch/arm/i2c_bitbang.c b/libplatsupport/src/arch/arm/i2c_bitbang.c
index 7ee9f3e..9d2e7d1 100644
--- a/libplatsupport/src/arch/arm/i2c_bitbang.c
+++ b/libplatsupport/src/arch/arm/i2c_bitbang.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <autoconf.h>
diff --git a/libplatsupport/src/arch/arm/irqchip/avic.c b/libplatsupport/src/arch/arm/irqchip/avic.c
deleted file mode 100644
index 4926f91..0000000
--- a/libplatsupport/src/arch/arm/irqchip/avic.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-* Copyright 2019, Data61
-* Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-* ABN 41 687 119 230.
-*
-* This software may be distributed and modified according to the terms of
-* the BSD 2-Clause license. Note that NO WARRANTY is provided.
-* See "LICENSE_BSD2.txt" for details.
-*
-* @TAG(DATA61_BSD)
-*/
-
-#include <assert.h>
-#include <stdbool.h>
-
-#include <utils/util.h>
-
-#include "../../../irqchip.h"
-
-#define FSL_AVIC_INT_CELL_COUNT 1
-
-static int parse_fsl_avic_interrupts(char *dtb_blob, int node_offset, int intr_controller_phandle,
-                                     irq_walk_cb_fn_t callback, void *token)
-{
-    bool is_extended = false;
-    int prop_len = 0;
-    const void *interrupts_prop = get_interrupts_prop(dtb_blob, node_offset, &is_extended, &prop_len);
-    assert(interrupts_prop != NULL);
-    int UNUSED total_cells = prop_len / sizeof(uint32_t);
-    /* There's only one interrupt cell for this IRQ chip */
-    assert(total_cells == FSL_AVIC_INT_CELL_COUNT);
-    ps_irq_t irq = { .type = PS_INTERRUPT, .irq = { .number = READ_CELL(1, interrupts_prop, 0) }};
-    int error = callback(irq, 0, FSL_AVIC_INT_CELL_COUNT, token);
-    if (error) {
-        return error;
-    }
-    return 0;
-}
-
-char *fsl_avic_compatible_list[] = {
-    "fsl,imx31-avic",
-    NULL
-};
-DEFINE_IRQCHIP_PARSER(fsl_avic, fsl_avic_compatible_list, parse_fsl_avic_interrupts);
diff --git a/libplatsupport/src/arch/arm/irqchip/gic.c b/libplatsupport/src/arch/arm/irqchip/gic.c
index 315cb58..8c01b49 100644
--- a/libplatsupport/src/arch/arm/irqchip/gic.c
+++ b/libplatsupport/src/arch/arm/irqchip/gic.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <assert.h>
diff --git a/libplatsupport/src/arch/arm/irqchip/gicv3.c b/libplatsupport/src/arch/arm/irqchip/gicv3.c
index e36d440..c155184 100644
--- a/libplatsupport/src/arch/arm/irqchip/gicv3.c
+++ b/libplatsupport/src/arch/arm/irqchip/gicv3.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <assert.h>
diff --git a/libplatsupport/src/arch/arm/irqchip/omap3.c b/libplatsupport/src/arch/arm/irqchip/omap3.c
index a39b9dd..41c369b 100644
--- a/libplatsupport/src/arch/arm/irqchip/omap3.c
+++ b/libplatsupport/src/arch/arm/irqchip/omap3.c
@@ -1,14 +1,8 @@
 /*
-* Copyright 2020, Data61
-* Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-* ABN 41 687 119 230.
-*
-* This software may be distributed and modified according to the terms of
-* the BSD 2-Clause license. Note that NO WARRANTY is provided.
-* See "LICENSE_BSD2.txt" for details.
-*
-* @TAG(DATA61_BSD)
-*/
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
 
 #include <assert.h>
 #include <stdbool.h>
diff --git a/libplatsupport/src/arch/arm/irqchip/tegra.c b/libplatsupport/src/arch/arm/irqchip/tegra.c
index b68eb63..35e8a3e 100644
--- a/libplatsupport/src/arch/arm/irqchip/tegra.c
+++ b/libplatsupport/src/arch/arm/irqchip/tegra.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <assert.h>
diff --git a/libplatsupport/src/arch/riscv/irqchip/plic.c b/libplatsupport/src/arch/riscv/irqchip/plic.c
index bb2cd17..53dce42 100644
--- a/libplatsupport/src/arch/riscv/irqchip/plic.c
+++ b/libplatsupport/src/arch/riscv/irqchip/plic.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2020, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <assert.h>
diff --git a/libplatsupport/src/arch/x86/delay.c b/libplatsupport/src/arch/x86/delay.c
index 184b0cf..9af8507 100644
--- a/libplatsupport/src/arch/x86/delay.c
+++ b/libplatsupport/src/arch/x86/delay.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <autoconf.h>
diff --git a/libplatsupport/src/arch/x86/tsc.c b/libplatsupport/src/arch/x86/tsc.c
index 593da70..9b9e9c3 100644
--- a/libplatsupport/src/arch/x86/tsc.c
+++ b/libplatsupport/src/arch/x86/tsc.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/arch/tsc.h>
diff --git a/libplatsupport/src/chardev.h b/libplatsupport/src/chardev.h
index 48b479f..88ba2ab 100644
--- a/libplatsupport/src/chardev.h
+++ b/libplatsupport/src/chardev.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/src/common.h b/libplatsupport/src/common.h
index c09570f..3983acd 100644
--- a/libplatsupport/src/common.h
+++ b/libplatsupport/src/common.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/src/fdt.c b/libplatsupport/src/fdt.c
index dbe4243..f5078d4 100644
--- a/libplatsupport/src/fdt.c
+++ b/libplatsupport/src/fdt.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <assert.h>
diff --git a/libplatsupport/src/io.c b/libplatsupport/src/io.c
index a4b13cc..92e2437 100644
--- a/libplatsupport/src/io.c
+++ b/libplatsupport/src/io.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/io.h>
diff --git a/libplatsupport/src/irqchip.h b/libplatsupport/src/irqchip.h
index f146817..f0cc950 100644
--- a/libplatsupport/src/irqchip.h
+++ b/libplatsupport/src/irqchip.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/src/local_time_manager.c b/libplatsupport/src/local_time_manager.c
index 17baed0..251e301 100644
--- a/libplatsupport/src/local_time_manager.c
+++ b/libplatsupport/src/local_time_manager.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libplatsupport/src/ltimer.h b/libplatsupport/src/ltimer.h
index ee1f425..6cb458d 100644
--- a/libplatsupport/src/ltimer.h
+++ b/libplatsupport/src/ltimer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/ltimer.h>
diff --git a/libplatsupport/src/mach/bcm283x/mailbox.c b/libplatsupport/src/mach/bcm283x/mailbox.c
new file mode 100644
index 0000000..b519e9e
--- /dev/null
+++ b/libplatsupport/src/mach/bcm283x/mailbox.c
@@ -0,0 +1,273 @@
+/*
+ * Copyright (C) 2021, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+/*
+ * More information about the mailboxes:
+ * - https://github.com/raspberrypi/firmware/wiki/Mailboxes
+ * - https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
+ * - https://github.com/raspberrypi/documentation/blob/JamesH65-mailbox_docs/configuration/mailboxes/propertiesARM-VC.md
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#include <utils/util.h>
+#include <platsupport/plat/mailbox.h>
+#include "../../services.h"
+
+#define DMA_PAGE_SIZE       4096
+#define DMA_ALIGNEMENT      4096
+
+// See: https://github.com/raspberrypi/firmware/wiki/Accessing-mailboxes#addresses-as-data
+#define VC_BASE_CACHED      0x40000000
+#define VC_BASE_UNCACHED    0xC0000000
+#define VC_BASE             VC_BASE_UNCACHED
+
+// See: https://github.com/raspberrypi/firmware/wiki/Accessing-mailboxes#sample-code
+#define MAILBOX_EMPTY       0x40000000
+#define MAILBOX_FULL        0x80000000
+
+// See: https://github.com/raspberrypi/firmware/wiki/Mailboxes#channels
+#define MAILBOX_CHANNEL     8
+
+typedef volatile struct {
+    uint32_t read;    // 0x00
+    uint32_t reg_04;  // 0x04
+    uint32_t reg_08;  // 0x08
+    uint32_t reg_0c;  // 0x0c
+    uint32_t reg_10;  // 0x10
+    uint32_t reg_14;  // 0x14
+    uint32_t status0; // 0x18
+    uint32_t reg_1c;  // 0x1c
+    uint32_t write;   // 0x20
+    uint32_t reg_24;  // 0x24
+    uint32_t reg_28;  // 0x28
+    uint32_t reg_2c;  // 0x2c
+    uint32_t reg_30;  // 0x30
+    uint32_t reg_34;  // 0x34
+    uint32_t status1; // 0x38
+} mailbox_regs_t;
+
+static inline mailbox_regs_t *get_mailbox_regs(mailbox_t *mbox)
+{
+    return (mbox != NULL && mbox->priv != NULL) ? (mailbox_regs_t *)((uintptr_t)mbox->priv + 0x880)
+           : NULL;
+}
+
+static inline uint32_t get_bus_address(uint32_t addr)
+{
+    return (((addr) & ~VC_BASE) | VC_BASE);
+}
+
+/*
+ * Mailbox read operation
+ *
+ * 1. Read the status register until the empty flag is not set
+ * 2. Read data from the read register
+ * 3. If the lower four bits do not match the channel number desired then repeat
+ *    from 1
+ * 4. The upper 28 bits are the returned data
+ *
+ * See: https://github.com/raspberrypi/documentation/blob/JamesH65-mailbox_docs/configuration/mailboxes/accessing.md#general-procedure
+ */
+static int mailbox_read(
+    mailbox_regs_t *mailbox,
+    uint32_t        channel,
+    uint32_t       *rsp
+)
+{
+    uint32_t value;
+    do {
+        while (mailbox->status0 & MAILBOX_EMPTY) {
+            // busy loop
+        }
+        value = mailbox->read;
+    } while ((value & 0xF) != channel);
+
+    *rsp =  value & ~0xF;
+
+    return 0;
+}
+
+/*
+ * Mailbox write operation
+ *
+ * 1. Read the status register until the full flag is not set
+ * 2. Write the data (shifted into the upper 28 bits) combined with the channel
+ *    (in the lower four bits) to the write register
+ *
+ * See: https://github.com/raspberrypi/documentation/blob/JamesH65-mailbox_docs/configuration/mailboxes/accessing.md#general-procedure
+ */
+static int mailbox_write(
+    mailbox_regs_t *mailbox,
+    uint32_t        channel,
+    uint32_t        data
+)
+{
+    while (mailbox->status1 & MAILBOX_FULL) {
+        // busy loop
+    }
+    mailbox->write = (data & ~0xF) | (channel & 0xF);
+
+    return 0;
+}
+
+/*
+ * Mailbox Command
+ *
+ * A command should only be issued in case the mailbox is empty. If the mailbox
+ * is not empty, it is said to be busy. In this case, it is the reponsibility of
+ * the caller to handle this situation.
+ *
+ * Every mailbox command consists of a request and a response. For this purpose
+ * PropertyTags must be created and configured for request. Afterwards, the
+ * mailbox interface is notified that there is a message waiting in the buffer.
+ * This signalling is done with the mailbox_write operation, that writes the
+ * buffer_address and the channel number into the write register. The
+ * mailbox_read operation makes sure that the response waiting in the mailbox
+ * interface belongs to the issued request by checking the current
+ * buffer_address and channel number in the read register.
+ */
+static int mailbox_command(
+    mailbox_t  *mbox,
+    uint32_t    channel,
+    uint32_t    data,
+    uint32_t   *rsp
+)
+{
+    mailbox_regs_t *mailbox = get_mailbox_regs(mbox);
+    if (mailbox == NULL) {
+        ZF_LOGE("Mailbox is invalid!");
+        return MAILBOX_ERR_INVALID;
+    }
+
+    // mailbox command should start operation with an empty mailbox
+    if (!(mailbox->status0 & MAILBOX_EMPTY)) {
+        ZF_LOGE("Mailbox is busy!");
+        return MAILBOX_ERR_BUSY;
+    }
+
+    if (mailbox_write(mailbox, channel, data) != 0) {
+        ZF_LOGE("Error when writing to mailbox!");
+        return MAILBOX_ERR_WRITE;
+    }
+    if (mailbox_read(mailbox, channel, rsp) != 0) {
+        ZF_LOGE("Error when reading from mailbox!");
+        return MAILBOX_ERR_READ;
+    }
+    return 0;
+}
+
+static int mailbox_message(
+    mailbox_t  *mbox,
+    uint32_t    tag_id,
+    void       *request_tag,
+    uint32_t    request_tag_size,
+    void       *response_tag,
+    uint32_t    response_tag_size
+)
+{
+    // ToDo: Implement the mailbox interface to handle multiple concatenated
+    //       tags per message. Currently, we assume only one tag per message.
+    // See:  https://github.com/raspberrypi/documentation/blob/JamesH65-mailbox_docs/configuration/mailboxes/propertiesARM-VC.md#message-content
+
+    // Prepare Mailbox
+    uint32_t tag_size = MAX(request_tag_size, response_tag_size);
+    MailboxInterface_PropertyBuffer_t  *buffer  = (MailboxInterface_PropertyBuffer_t *)mbox->buffer;
+    buffer->buffer_size = sizeof(MailboxInterface_PropertyBuffer_t)
+                          + tag_size
+                          + sizeof(uint32_t);
+    buffer->code        = CODE_BUFFER_REQUEST_PROCESS;
+
+    MailboxInterface_PropertyTag_t     *tags    = (MailboxInterface_PropertyTag_t *)buffer->tags;
+    memcpy(tags, request_tag, request_tag_size);
+    tags->tag_id              = tag_id;
+    tags->value_buffer_size   = tag_size - sizeof(MailboxInterface_PropertyTag_t);
+    tags->value_length        = tags->value_buffer_size & ~VALUE_LENGTH_RESPONSE;
+
+    uint32_t *end_tag = (uint32_t *)(tags + tag_size);
+    *end_tag = 0;
+    assert((uintptr_t)(const void *)end_tag % 4 == 0);
+
+    // Mailbox command
+    uint32_t rsp = 0;
+    uint32_t buffer_address = get_bus_address((uint32_t) mbox->phys_addr);
+    int status = mailbox_command(mbox,
+                                 MAILBOX_CHANNEL,
+                                 buffer_address,
+                                 &rsp);
+
+    // Response Evaluation
+    // Buffer format: https://github.com/raspberrypi/documentation/blob/JamesH65-mailbox_docs/configuration/mailboxes/propertiesARM-VC.md#buffer-contents
+    // Tag format: https://github.com/raspberrypi/documentation/blob/JamesH65-mailbox_docs/configuration/mailboxes/propertiesARM-VC.md#tag-format
+    if (status != 0) {
+        ZF_LOGE("Mailbox command error - code: %d!", status);
+        return status;
+    }
+
+    if (rsp != buffer_address) {
+        ZF_LOGE("Mailbox response should be buffer address!");
+        return MAILBOX_ERR_INTERNAL;
+    }
+
+    if (buffer->code != CODE_BUFFER_RESPONSE_SUCCESS) {
+        ZF_LOGE("Mailbox response is not successful!");
+        return MAILBOX_ERR_BUFFER;
+    }
+
+    if (tags->tag_id != tag_id) {
+        ZF_LOGE("Wrong tag id returned!");
+        return MAILBOX_ERR_TAG;
+    }
+
+    if (!(tags->value_length & VALUE_LENGTH_RESPONSE)) {
+        ZF_LOGE("Received tag is not a response!");
+        return MAILBOX_ERR_TAG;
+    }
+
+    if ((tags->value_length &= ~VALUE_LENGTH_RESPONSE) == 0) {
+        ZF_LOGE("Value buffer has length 0 bytes!");
+        return MAILBOX_ERR_TAG;
+    }
+
+    memcpy(response_tag, tags, response_tag_size);
+
+    return MAILBOX_OK;
+}
+
+int mailbox_init(ps_io_ops_t *io_ops, mailbox_t *mailbox)
+{
+    void *reg = NULL;
+    MAP_IF_NULL(io_ops, MAILBOX, reg);
+    mailbox->priv = reg;
+    mailbox->dma_man = &io_ops->dma_manager;
+    mailbox->message = &mailbox_message;
+    mailbox->buffer  = mailbox->dma_man->dma_alloc_fn(
+                           mailbox->dma_man->cookie,
+                           DMA_PAGE_SIZE,
+                           DMA_ALIGNEMENT,
+                           0,
+                           PS_MEM_NORMAL);
+    if (mailbox->buffer == NULL) {
+        ZF_LOGE("DMA allocation failed.");
+        return MAILBOX_ERR_DMA;
+    }
+    mailbox->phys_addr = mailbox->dma_man->dma_pin_fn(mailbox->dma_man->cookie,
+                                                      mailbox->buffer,
+                                                      DMA_PAGE_SIZE);
+    return 0;
+}
+
+int mailbox_destroy(mailbox_t *mailbox)
+{
+    mailbox->dma_man->dma_free_fn(mailbox->dma_man->cookie,
+                                  mailbox->buffer,
+                                  DMA_PAGE_SIZE);
+    mailbox->dma_man->dma_unpin_fn(mailbox->dma_man->cookie,
+                                   mailbox->buffer,
+                                   DMA_PAGE_SIZE);
+    return 0;
+}
diff --git a/libplatsupport/src/mach/bcm283x/mailbox_util.c b/libplatsupport/src/mach/bcm283x/mailbox_util.c
new file mode 100644
index 0000000..dcf0cd5
--- /dev/null
+++ b/libplatsupport/src/mach/bcm283x/mailbox_util.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2021, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+/*
+ * More information about the mailboxes:
+ * - https://github.com/raspberrypi/firmware/wiki/Mailboxes
+ * - https://github.com/raspberrypi/firmware/wiki/Mailbox-property-interface
+ * - https://github.com/raspberrypi/documentation/blob/JamesH65-mailbox_docs/configuration/mailboxes/propertiesARM-VC.md
+ */
+
+#include <platsupport/mach/mailbox_util.h>
+#include <string.h>
+
+static int mbox_req_resp(mailbox_t   *mbox,
+                         uint32_t    tag_id,
+                         void        *req,
+                         uint32_t    req_size,
+                         void        *resp,
+                         uint32_t    resp_size)
+{
+    // ToDo: could add a max loop counter to timeout here to exit the polling
+    //       loop if there is no reponse
+    for (;;) {
+        int status = mbox->message(mbox,
+                                   tag_id,
+                                   req,
+                                   req_size,
+                                   resp,
+                                   resp_size);
+        if (MAILBOX_ERR_BUSY != status) {
+            return status;
+        }
+    }
+}
+
+/**
+ * Set power state on of device.
+ *
+ * @param mbox      Initialized mailbox driver instance
+ * @param device_id Device ID of device that should be activated.
+ * @return          true on success, false on failure
+ */
+bool mailbox_set_power_state_on(mailbox_t *mbox, uint32_t device_id)
+{
+    PropertyTag_SetPowerState_Request_t TagRequest = {
+        .device_id = device_id,
+        .state  = SET_POWER_STATE_ON | SET_POWER_STATE_WAIT
+    };
+
+    PropertyTag_SetPowerState_Response_t TagResponse;
+
+    int status = mbox_req_resp(mbox,
+                               TAG_SET_POWER_STATE,
+                               &TagRequest,
+                               sizeof(TagRequest),
+                               &TagResponse,
+                               sizeof(TagResponse));
+
+    if (MAILBOX_OK != status
+        || (TagResponse.state & SET_POWER_STATE_NO_DEVICE)
+        || !(TagResponse.state & SET_POWER_STATE_ON)) {
+        ZF_LOGE("Failed to set power state on - error code: %d!", status);
+        return false;
+    }
+
+    return true;
+}
+
+/**
+ * Get clock rate of certain device clock.
+ *
+ * @param mbox      Initialized mailbox driver instance
+ * @param clock_id  ID of clock
+ * @return          requested clock rate on success, 0 on failure (e.g. clock id
+ *                  is not valid -> clock does not exist)
+ */
+int mailbox_get_clock_rate(mailbox_t *mbox, uint32_t clock_id)
+{
+    PropertyTag_GetClockRate_Request_t TagRequest = {
+        .clock_id = clock_id
+    };
+
+    PropertyTag_GetClockRate_Response_t TagResponse;
+
+    int status = mbox_req_resp(mbox,
+                               TAG_GET_CLOCK_RATE,
+                               &TagRequest,
+                               sizeof(TagRequest),
+                               &TagResponse,
+                               sizeof(TagResponse));
+
+    if (MAILBOX_OK != status) {
+        ZF_LOGE("Failed to get clock rate of clock %d - error code: %d!", clock_id, status);
+        TagResponse.rate = 0;
+    }
+
+    return TagResponse.rate;
+}
+
+/**
+ * Get board MAC address.
+ *
+ * @param mbox      Initialized mailbox driver instance
+ * @param buffer    Buffer address to which each digit of the MAC address should
+ *                  be copied to.
+ * @return          true on success, false on failure
+ */
+bool mailbox_get_mac_address(mailbox_t *mbox, uint8_t buffer[MAC_ADDRESS_SIZE])
+{
+    PropertyTag_GetMACAddress_Request_t TagRequest;
+    PropertyTag_GetMACAddress_Response_t TagResponse;
+
+    int status = mbox_req_resp(mbox,
+                               TAG_GET_MAC_ADDRESS,
+                               &TagRequest,
+                               sizeof(TagRequest),
+                               &TagResponse,
+                               sizeof(TagResponse));
+
+    if (MAILBOX_OK != status) {
+        ZF_LOGE("Failed to get mac address of board - error code: %d!", status);
+        memset(buffer, 0, MAC_ADDRESS_SIZE);
+        return false;
+    }
+
+    memcpy(buffer, TagResponse.mac_address, MAC_ADDRESS_SIZE);
+
+    return true;
+}
diff --git a/libplatsupport/src/mach/exynos/clock.c b/libplatsupport/src/mach/exynos/clock.c
index 964f184..ad718cd 100644
--- a/libplatsupport/src/mach/exynos/clock.c
+++ b/libplatsupport/src/mach/exynos/clock.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include "clock.h"
diff --git a/libplatsupport/src/mach/exynos/clock.h b/libplatsupport/src/mach/exynos/clock.h
index f44faca..ca1a961 100644
--- a/libplatsupport/src/mach/exynos/clock.h
+++ b/libplatsupport/src/mach/exynos/clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/src/mach/exynos/clock/exynos_5422_clock.c b/libplatsupport/src/mach/exynos/clock/exynos_5422_clock.c
index 7cf95e1..1934ef2 100644
--- a/libplatsupport/src/mach/exynos/clock/exynos_5422_clock.c
+++ b/libplatsupport/src/mach/exynos/clock/exynos_5422_clock.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include "../clock.h"
 
diff --git a/libplatsupport/src/mach/exynos/clock/exynos_5422_clock.h b/libplatsupport/src/mach/exynos/clock/exynos_5422_clock.h
index fea4934..760ef00 100644
--- a/libplatsupport/src/mach/exynos/clock/exynos_5422_clock.h
+++ b/libplatsupport/src/mach/exynos/clock/exynos_5422_clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/src/mach/exynos/clock/exynos_common_clock.c b/libplatsupport/src/mach/exynos/clock/exynos_common_clock.c
index 9da385a..49fde83 100644
--- a/libplatsupport/src/mach/exynos/clock/exynos_common_clock.c
+++ b/libplatsupport/src/mach/exynos/clock/exynos_common_clock.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include "../clock.h"
 
diff --git a/libplatsupport/src/mach/exynos/clock/exynos_common_clock.h b/libplatsupport/src/mach/exynos/clock/exynos_common_clock.h
index 9004601..6a116bd 100644
--- a/libplatsupport/src/mach/exynos/clock/exynos_common_clock.h
+++ b/libplatsupport/src/mach/exynos/clock/exynos_common_clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/src/mach/exynos/i2c.c b/libplatsupport/src/mach/exynos/i2c.c
index 63bdb7e..825221b 100644
--- a/libplatsupport/src/mach/exynos/i2c.c
+++ b/libplatsupport/src/mach/exynos/i2c.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <autoconf.h>
diff --git a/libplatsupport/src/mach/exynos/irq_combiner.c b/libplatsupport/src/mach/exynos/irq_combiner.c
index b13fbe8..6c1294c 100644
--- a/libplatsupport/src/mach/exynos/irq_combiner.c
+++ b/libplatsupport/src/mach/exynos/irq_combiner.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <utils/util.h>
diff --git a/libplatsupport/src/mach/exynos/ltimer.c b/libplatsupport/src/mach/exynos/ltimer.c
index 2428747..4c711c7 100644
--- a/libplatsupport/src/mach/exynos/ltimer.c
+++ b/libplatsupport/src/mach/exynos/ltimer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 /* Implementation of a logical timer for omap platforms
  *
diff --git a/libplatsupport/src/mach/exynos/mux.c b/libplatsupport/src/mach/exynos/mux.c
index 0bbaf35..1c39dbc 100644
--- a/libplatsupport/src/mach/exynos/mux.c
+++ b/libplatsupport/src/mach/exynos/mux.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <autoconf.h>
diff --git a/libplatsupport/src/mach/exynos/mux.h b/libplatsupport/src/mach/exynos/mux.h
index 23dc3ef..df9ed00 100644
--- a/libplatsupport/src/mach/exynos/mux.h
+++ b/libplatsupport/src/mach/exynos/mux.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/src/mach/exynos/pmic.c b/libplatsupport/src/mach/exynos/pmic.c
index 0e085a3..3b24064 100644
--- a/libplatsupport/src/mach/exynos/pmic.c
+++ b/libplatsupport/src/mach/exynos/pmic.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <utils/util.h>
diff --git a/libplatsupport/src/mach/exynos/pmic_rtc.c b/libplatsupport/src/mach/exynos/pmic_rtc.c
index 4a178f7..6942a11 100644
--- a/libplatsupport/src/mach/exynos/pmic_rtc.c
+++ b/libplatsupport/src/mach/exynos/pmic_rtc.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/mach/pmic_rtc.h>
diff --git a/libplatsupport/src/mach/exynos/pwm.c b/libplatsupport/src/mach/exynos/pwm.c
index b64161b..87a39b3 100644
--- a/libplatsupport/src/mach/exynos/pwm.c
+++ b/libplatsupport/src/mach/exynos/pwm.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdio.h>
diff --git a/libplatsupport/src/mach/exynos/serial.c b/libplatsupport/src/mach/exynos/serial.c
index c67d122..0b9e7b7 100644
--- a/libplatsupport/src/mach/exynos/serial.c
+++ b/libplatsupport/src/mach/exynos/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* disabled until someone makes it compile */
diff --git a/libplatsupport/src/mach/exynos/serial.h b/libplatsupport/src/mach/exynos/serial.h
index 4cc65f6..2022e13 100644
--- a/libplatsupport/src/mach/exynos/serial.h
+++ b/libplatsupport/src/mach/exynos/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include "../../chardev.h"
diff --git a/libplatsupport/src/mach/exynos/spi.c b/libplatsupport/src/mach/exynos/spi.c
index 3033d1e..7dda12b 100644
--- a/libplatsupport/src/mach/exynos/spi.c
+++ b/libplatsupport/src/mach/exynos/spi.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* SPI driver */
diff --git a/libplatsupport/src/mach/exynos/tmu.c b/libplatsupport/src/mach/exynos/tmu.c
index 7350c9a..96bce23 100644
--- a/libplatsupport/src/mach/exynos/tmu.c
+++ b/libplatsupport/src/mach/exynos/tmu.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/mach/tmu.h>
diff --git a/libplatsupport/src/mach/imx/epit/epit.c b/libplatsupport/src/mach/imx/epit/epit.c
index 875016a..21c64e9 100644
--- a/libplatsupport/src/mach/imx/epit/epit.c
+++ b/libplatsupport/src/mach/imx/epit/epit.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdio.h>
@@ -149,6 +143,9 @@
     /* Set counter modulus - this effectively sets the timeouts to us but doesn't
      * overflow as fast. */
     uint64_t counterValue = (uint64_t)(IPG_FREQ / (epit->prescaler + 1)) * (ns / 1000ULL);
+    if (counterValue == 0) {
+        return ETIME;
+    }
 
     return epit_set_timeout_ticks(epit, counterValue, periodic);
 }
diff --git a/libplatsupport/src/mach/imx/gpt.c b/libplatsupport/src/mach/imx/gpt.c
index 3e74ba5..e64f04b 100644
--- a/libplatsupport/src/mach/imx/gpt.c
+++ b/libplatsupport/src/mach/imx/gpt.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdio.h>
@@ -223,9 +217,30 @@
 
 uint64_t gpt_get_time(gpt_t *gpt)
 {
+    // Rollover of 32-bit counter can happen while we are reading it,
+    // We need to read in the following order (volatile modifier on gpt_map should ensure this):
+    // - GPT_SR[ROV]
+    // - GPT_CNT
+    // - GPT_SR[ROV]
+    // If GPT_SR[ROV] bit is unchanged, then the GPT_CNT read is valid and can be used.
+    // If GPT_SR[ROV] bit has changed, then the rollover happened sometime between the first
+    // read and the third read.  In this case GPT_CNT would have had a value of 0 at some point
+    // during our reads and so use 0.
+    uint32_t rollover_st = gpt->gpt_map->gptsr & BIT(ROV);
     uint32_t low_bits = gpt->gpt_map->gptcnt;
+    uint32_t rollover_st2 = gpt->gpt_map->gptsr & BIT(ROV);
+    if (rollover_st != rollover_st2) {
+        low_bits = 0;
+    }
+
+    // gpt->high_bits is the number of times the timer has overflowed and is managed by this driver.
+    // If GPT_SR[ROV] is set then gpt_handle_irq hasn't had a chance to run yet and gpt->high_bits
+    // is still recording the old number of overflows. We increment our own local copy and leave
+    // the driver copy to be updated by gpt_handle_irq.
+    // This driver requires that the IRQ handler function won't be called while other driver functions
+    // are executing.
     uint32_t high_bits = gpt->high_bits;
-    if (gpt->gpt_map->gptsr) {
+    if (rollover_st2) {
         /* irq has come in */
         high_bits++;
     }
diff --git a/libplatsupport/src/mach/imx/ltimer.c b/libplatsupport/src/mach/imx/ltimer.c
index 11af342..588be1b 100644
--- a/libplatsupport/src/mach/imx/ltimer.c
+++ b/libplatsupport/src/mach/imx/ltimer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* Implementation of a logical timer for imx platforms
@@ -52,6 +46,9 @@
 
     if (type == TIMEOUT_ABSOLUTE) {
         uint64_t current_time = imx_get_time(&imx_ltimer->timers);
+        if (ns < current_time) {
+            return ETIME;
+        }
         ns -= current_time;
     }
 
@@ -87,7 +84,7 @@
         ZF_LOGF_IF(imx_destroy_timeout(&imx_ltimer->timers), "Failed to destroy the timeout timer");
     }
 
-    ps_free(&imx_ltimer->ops.malloc_ops, sizeof(imx_ltimer), imx_ltimer);
+    ps_free(&imx_ltimer->ops.malloc_ops, sizeof(*imx_ltimer), imx_ltimer);
 }
 
 static int create_ltimer(ltimer_t *ltimer, ps_io_ops_t ops)
diff --git a/libplatsupport/src/mach/imx/serial/serial.c b/libplatsupport/src/mach/imx/serial/serial.c
index f8f3778..2801965 100644
--- a/libplatsupport/src/mach/imx/serial/serial.c
+++ b/libplatsupport/src/mach/imx/serial/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <autoconf.h>
diff --git a/libplatsupport/src/mach/nvidia/chardev.c b/libplatsupport/src/mach/nvidia/chardev.c
index 4a007d2..d751e37 100644
--- a/libplatsupport/src/mach/nvidia/chardev.c
+++ b/libplatsupport/src/mach/nvidia/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libplatsupport/src/mach/nvidia/ltimer.c b/libplatsupport/src/mach/nvidia/ltimer.c
index d98da46..fcc9c55 100644
--- a/libplatsupport/src/mach/nvidia/ltimer.c
+++ b/libplatsupport/src/mach/nvidia/ltimer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /*
diff --git a/libplatsupport/src/mach/nvidia/serial.c b/libplatsupport/src/mach/nvidia/serial.c
index 9ea139e..825a276 100644
--- a/libplatsupport/src/mach/nvidia/serial.c
+++ b/libplatsupport/src/mach/nvidia/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <stdlib.h>
 #include <platsupport/serial.h>
diff --git a/libplatsupport/src/mach/nvidia/timer.c b/libplatsupport/src/mach/nvidia/timer.c
index 8aa7d0c..7ab432d 100644
--- a/libplatsupport/src/mach/nvidia/timer.c
+++ b/libplatsupport/src/mach/nvidia/timer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdio.h>
diff --git a/libplatsupport/src/mach/omap/gpt.c b/libplatsupport/src/mach/omap/gpt.c
index ba0f315..e6a10d7 100644
--- a/libplatsupport/src/mach/omap/gpt.c
+++ b/libplatsupport/src/mach/omap/gpt.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdbool.h>
diff --git a/libplatsupport/src/mach/omap/ltimer.c b/libplatsupport/src/mach/omap/ltimer.c
index 8122b48..d88ac8d 100644
--- a/libplatsupport/src/mach/omap/ltimer.c
+++ b/libplatsupport/src/mach/omap/ltimer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 /* Implementation of a logical timer for omap platforms
  *
diff --git a/libplatsupport/src/mach/zynq/axi_uartlite.c b/libplatsupport/src/mach/zynq/axi_uartlite.c
index 8c96a2c..99bf0e0 100644
--- a/libplatsupport/src/mach/zynq/axi_uartlite.c
+++ b/libplatsupport/src/mach/zynq/axi_uartlite.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdlib.h>
diff --git a/libplatsupport/src/mach/zynq/chardev.c b/libplatsupport/src/mach/zynq/chardev.c
index d358cdc..6a2d954 100644
--- a/libplatsupport/src/mach/zynq/chardev.c
+++ b/libplatsupport/src/mach/zynq/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libplatsupport/src/mach/zynq/ltimer.c b/libplatsupport/src/mach/zynq/ltimer.c
index 1431737..77bfff8 100644
--- a/libplatsupport/src/mach/zynq/ltimer.c
+++ b/libplatsupport/src/mach/zynq/ltimer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2020, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* Minimal implementation of a logical timer for zynq
diff --git a/libplatsupport/src/mach/zynq/mux.c b/libplatsupport/src/mach/zynq/mux.c
index 2cc4a12..80028b1 100644
--- a/libplatsupport/src/mach/zynq/mux.c
+++ b/libplatsupport/src/mach/zynq/mux.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdint.h>
@@ -32,8 +26,8 @@
 }
 
 static int zynq_mux_feature_enable(
-    const mux_sys_t *mux,
-    mux_feature_t mux_feature,
+    UNUSED const mux_sys_t *mux,
+    UNUSED mux_feature_t mux_feature,
     UNUSED enum mux_gpio_dir mgd)
 {
     return 0;
@@ -54,7 +48,7 @@
 }
 
 int mux_sys_init(
-    ps_io_ops_t *io_ops,
+    UNUSED ps_io_ops_t *io_ops,
     UNUSED void *dependencies,
     mux_sys_t *mux)
 {
diff --git a/libplatsupport/src/mach/zynq/serial.c b/libplatsupport/src/mach/zynq/serial.c
index 5d1f2f8..d38adbd 100644
--- a/libplatsupport/src/mach/zynq/serial.c
+++ b/libplatsupport/src/mach/zynq/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdlib.h>
@@ -192,6 +186,13 @@
     uint32_t imr = regs->imr;
     regs->idr = imr;
 
+    /* uart_handle_irq() clears the RTRIG interrupt, but it does not catch all
+     * corner cases. So we clear it here again, assuming the caller loops
+     * reading chars to drain the FIFO anyway. Register implements the "write
+     * a 1 to clear" semantic.
+     */
+    regs->isr = UART_ISR_RTRIG;
+
     if (!(regs->sr & UART_SR_REMPTY)) {
         c = regs->fifo;
 
diff --git a/libplatsupport/src/mach/zynq/timer.c b/libplatsupport/src/mach/zynq/timer.c
index f0bb71b..b6d2167 100644
--- a/libplatsupport/src/mach/zynq/timer.c
+++ b/libplatsupport/src/mach/zynq/timer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2020, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdio.h>
diff --git a/libplatsupport/src/plat/am335x/chardev.c b/libplatsupport/src/plat/am335x/chardev.c
index 777032a..68f93cb 100644
--- a/libplatsupport/src/plat/am335x/chardev.c
+++ b/libplatsupport/src/plat/am335x/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libplatsupport/src/plat/am335x/i2c.c b/libplatsupport/src/plat/am335x/i2c.c
index 43d5535..89dc4d1 100644
--- a/libplatsupport/src/plat/am335x/i2c.c
+++ b/libplatsupport/src/plat/am335x/i2c.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* warning: use of callbacks is NOT tested with this driver */
diff --git a/libplatsupport/src/plat/am335x/ltimer.c b/libplatsupport/src/plat/am335x/ltimer.c
index c068e10..1f7660e 100644
--- a/libplatsupport/src/plat/am335x/ltimer.c
+++ b/libplatsupport/src/plat/am335x/ltimer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* Implementation of a logical timer for beagle bone
diff --git a/libplatsupport/src/plat/am335x/serial.c b/libplatsupport/src/plat/am335x/serial.c
index fd5d389..2c21524 100644
--- a/libplatsupport/src/plat/am335x/serial.c
+++ b/libplatsupport/src/plat/am335x/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <string.h>
diff --git a/libplatsupport/src/plat/am335x/timer.c b/libplatsupport/src/plat/am335x/timer.c
index 143e5d3..b83f9d5 100644
--- a/libplatsupport/src/plat/am335x/timer.c
+++ b/libplatsupport/src/plat/am335x/timer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdio.h>
diff --git a/libplatsupport/src/plat/apq8064/chardev.c b/libplatsupport/src/plat/apq8064/chardev.c
index 6fdaf0b..9698eb2 100644
--- a/libplatsupport/src/plat/apq8064/chardev.c
+++ b/libplatsupport/src/plat/apq8064/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libplatsupport/src/plat/apq8064/clock.c b/libplatsupport/src/plat/apq8064/clock.c
index 53059f1..a6854c7 100644
--- a/libplatsupport/src/plat/apq8064/clock.c
+++ b/libplatsupport/src/plat/apq8064/clock.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include "../../arch/arm/clock.h"
diff --git a/libplatsupport/src/plat/apq8064/intc.c b/libplatsupport/src/plat/apq8064/intc.c
index a98f8b0..86a30b8 100644
--- a/libplatsupport/src/plat/apq8064/intc.c
+++ b/libplatsupport/src/plat/apq8064/intc.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <stdint.h>
 #include <stdio.h>
diff --git a/libplatsupport/src/plat/apq8064/mux.c b/libplatsupport/src/plat/apq8064/mux.c
index 6b7bd83..32c3ebc 100644
--- a/libplatsupport/src/plat/apq8064/mux.c
+++ b/libplatsupport/src/plat/apq8064/mux.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <stdint.h>
 #include <platsupport/mux.h>
diff --git a/libplatsupport/src/plat/apq8064/serial.c b/libplatsupport/src/plat/apq8064/serial.c
index 533d261..5188404 100644
--- a/libplatsupport/src/plat/apq8064/serial.c
+++ b/libplatsupport/src/plat/apq8064/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdlib.h>
diff --git a/libplatsupport/src/plat/apq8064/timer.c b/libplatsupport/src/plat/apq8064/timer.c
index 01fcedd..b684ccb 100644
--- a/libplatsupport/src/plat/apq8064/timer.c
+++ b/libplatsupport/src/plat/apq8064/timer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 /* @AUTHOR(akroh@ertos.nicta.com.au) */
 
diff --git a/libplatsupport/src/plat/ariane/apb_timer.c b/libplatsupport/src/plat/ariane/apb_timer.c
new file mode 100644
index 0000000..5e16642
--- /dev/null
+++ b/libplatsupport/src/plat/ariane/apb_timer.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+
+#include <utils/util.h>
+
+#include <platsupport/timer.h>
+#include <platsupport/plat/apb_timer.h>
+
+/* Largest timeout that can be programmed */
+#define MAX_TIMEOUT_NS (BIT(31) * (NS_IN_S / APB_TIMER_INPUT_FREQ))
+
+int apb_timer_start(apb_timer_t *apb_timer)
+{
+    apb_timer->apb_timer_map->ctrl |= APB_TIMER_CTRL_ENABLE;
+    return 0;
+}
+
+int apb_timer_stop(apb_timer_t *apb_timer)
+{
+    /* Disable timer. */
+    apb_timer->apb_timer_map->cmp = CMP_MASK;
+    apb_timer->apb_timer_map->ctrl &= ~APB_TIMER_CTRL_ENABLE;
+    apb_timer->apb_timer_map->time = 0;
+
+    return 0;
+}
+
+int apb_timer_set_timeout(apb_timer_t *apb_timer, uint64_t ns)
+{
+    if (ns > MAX_TIMEOUT_NS) {
+        ZF_LOGE("Cannot program a timeout larget than %ld ns", MAX_TIMEOUT_NS);
+        return -1;
+    }
+
+    apb_timer->apb_timer_map->cmp = ns / (NS_IN_S / APB_TIMER_INPUT_FREQ);
+    apb_timer_start(apb_timer);
+
+    return 0;
+}
+
+uint64_t apb_timer_get_time(apb_timer_t *apb_timer)
+{
+    uint64_t ticks = apb_timer->apb_timer_map->time + apb_timer->time_h;
+    return ticks * (NS_IN_S / APB_TIMER_INPUT_FREQ);
+}
+
+int apb_timer_init(apb_timer_t *apb_timer, apb_timer_config_t config)
+{
+    apb_timer->apb_timer_map = (volatile struct apb_timer_map *) config.vaddr;
+    apb_timer->time_h = 0;
+    return 0;
+}
diff --git a/libplatsupport/src/plat/ariane/chardev.c b/libplatsupport/src/plat/ariane/chardev.c
index 3b54e7a..0ad021d 100644
--- a/libplatsupport/src/plat/ariane/chardev.c
+++ b/libplatsupport/src/plat/ariane/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include "../../chardev.h"
diff --git a/libplatsupport/src/plat/ariane/ltimer.c b/libplatsupport/src/plat/ariane/ltimer.c
new file mode 100644
index 0000000..dc174fe
--- /dev/null
+++ b/libplatsupport/src/plat/ariane/ltimer.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+/* Implementation of a logical timer for Ariane SoC platform.
+ *
+ */
+#include <platsupport/timer.h>
+#include <platsupport/ltimer.h>
+#include <platsupport/pmem.h>
+#include <utils/util.h>
+#include <platsupport/plat/apb_timer.h>
+
+#include "../../ltimer.h"
+
+typedef struct {
+    apb_timer_t apb_timer;
+    void *vaddr;
+} apb_timer_ltimer_t;
+
+typedef struct {
+    apb_timer_ltimer_t apb_timer_ltimer;
+    //ps_irq_t irq;
+    ps_io_ops_t ops;
+    irq_id_t irq_id;
+    ltimer_callback_fn_t user_callback;
+    timer_callback_data_t callback_data;
+    void *user_callback_token;
+    uint64_t period;
+} ariane_ltimer_t;
+
+static pmem_region_t pmems[] = {
+    {
+        .type = PMEM_TYPE_DEVICE,
+        .base_addr = APB_TIMER_PADDR,
+        .length = PAGE_SIZE_4K
+    }
+};
+
+static ps_irq_t irqs[] = {
+    {
+        .type = PS_INTERRUPT,
+        .irq.number = APB_TIMER_IRQ_CMP(0)
+
+    }
+};
+
+size_t get_num_irqs(void *data)
+{
+    return 1;
+}
+
+static int get_nth_irq(void *data, size_t n, ps_irq_t *irq)
+{
+    assert(data != NULL);
+    assert(irq != NULL);
+    assert(n == 0);
+
+    irq->irq.number = APB_TIMER_IRQ_CMP(0);
+    irq->type = PS_INTERRUPT;
+    return 0;
+}
+
+static size_t get_num_pmems(void *data)
+{
+    return sizeof(pmems) / sizeof(pmems[0]);
+}
+
+static int get_nth_pmem(void *data, size_t n, pmem_region_t *paddr)
+{
+    assert(n < get_num_pmems(data));
+    *paddr = pmems[n];
+    return 0;
+}
+
+static int get_time(void *data, uint64_t *time)
+{
+    assert(data != NULL);
+    assert(time != NULL);
+    ariane_ltimer_t *timer = data;
+
+    *time = apb_timer_get_time(&timer->apb_timer_ltimer.apb_timer);
+    return 0;
+}
+
+static int get_resolution(void *data, uint64_t *resolution)
+{
+    return ENOSYS;
+}
+
+static int set_timeout(void *data, uint64_t ns, timeout_type_t type)
+{
+    assert(data != NULL);
+    ariane_ltimer_t *timer = data;
+    timer->period = 0;
+
+    switch (type) {
+    case TIMEOUT_ABSOLUTE: {
+        uint64_t time = apb_timer_get_time(&timer->apb_timer_ltimer.apb_timer);
+        if (time >= ns) {
+            return ETIME;
+        }
+        apb_timer_set_timeout(&timer->apb_timer_ltimer.apb_timer, ns - time);
+        return 0;
+    }
+    case TIMEOUT_PERIODIC: {
+        timer->period = ns;
+        /* fall through */
+    }
+    case TIMEOUT_RELATIVE: {
+        apb_timer_set_timeout(&timer->apb_timer_ltimer.apb_timer, ns);
+        return 0;
+    }
+    }
+
+    return EINVAL;
+}
+
+static int reset(void *data)
+{
+    assert(data != NULL);
+    ariane_ltimer_t *timer = data;
+    apb_timer_stop(&timer->apb_timer_ltimer.apb_timer);
+    apb_timer_start(&timer->apb_timer_ltimer.apb_timer);
+    return 0;
+}
+
+static void destroy(void *data)
+{
+    assert(data);
+    ariane_ltimer_t *timer = data;
+    if (timer->apb_timer_ltimer.vaddr) {
+        apb_timer_stop(&timer->apb_timer_ltimer.apb_timer);
+        ps_pmem_unmap(&timer->ops, pmems[0], timer->apb_timer_ltimer.vaddr);
+    }
+    if (timer->irq_id > PS_INVALID_IRQ_ID) {
+        int error = ps_irq_unregister(&timer->ops.irq_ops, timer->irq_id);
+        ZF_LOGF_IF(error, "Failed to unregister IRQ");
+    }
+    ps_free(&timer->ops.malloc_ops, sizeof(timer), timer);
+}
+
+static int create_ltimer(ltimer_t *ltimer, ps_io_ops_t ops)
+{
+    assert(ltimer != NULL);
+    ltimer->get_time = get_time;
+    ltimer->get_resolution = get_resolution;
+    ltimer->set_timeout = set_timeout;
+    ltimer->reset = reset;
+    ltimer->destroy = destroy;
+
+    int error = ps_calloc(&ops.malloc_ops, 1, sizeof(ariane_ltimer_t), &ltimer->data);
+    if (error) {
+        return error;
+    }
+    assert(ltimer->data != NULL);
+
+    return 0;
+}
+
+static int init_ltimer(ltimer_t *ltimer)
+{
+    assert(ltimer != NULL);
+    ariane_ltimer_t *timer = ltimer->data;
+
+    /* setup apb_timer */
+    apb_timer_config_t config_counter = {
+        .vaddr = timer->apb_timer_ltimer.vaddr
+    };
+
+    apb_timer_init(&timer->apb_timer_ltimer.apb_timer, config_counter);
+    apb_timer_start(&timer->apb_timer_ltimer.apb_timer);
+    return 0;
+}
+
+static int handle_irq(void *data, ps_irq_t *irq)
+{
+    assert(data != NULL);
+    ariane_ltimer_t *timer = data;
+
+    timer->apb_timer_ltimer.apb_timer.time_h += timer->apb_timer_ltimer.apb_timer.apb_timer_map->cmp;
+    apb_timer_stop(&timer->apb_timer_ltimer.apb_timer);
+
+    if (timer->period > 0) {
+        apb_timer_set_timeout(&timer->apb_timer_ltimer.apb_timer, timer->period);
+    }
+
+    ltimer_event_t event = LTIMER_TIMEOUT_EVENT;
+    if (timer->user_callback) {
+        timer->user_callback(timer->user_callback_token, event);
+    }
+    apb_timer_start(&timer->apb_timer_ltimer.apb_timer);
+}
+
+int ltimer_default_init(ltimer_t *ltimer, ps_io_ops_t ops, ltimer_callback_fn_t callback, void *callback_token)
+{
+
+    int error = ltimer_default_describe(ltimer, ops);
+    if (error) {
+        return error;
+    }
+
+    error = create_ltimer(ltimer, ops);
+    if (error) {
+        return error;
+    }
+
+    ariane_ltimer_t *timer = ltimer->data;
+    timer->ops = ops;
+    timer->user_callback = callback;
+    timer->user_callback_token = callback_token;
+    timer->irq_id = 0;//PS_INVALID_IRQ_ID;
+
+    /* map the registers we need */
+    timer->apb_timer_ltimer.vaddr = ps_pmem_map(&ops, pmems[0], false, PS_MEM_NORMAL);
+    if (timer->apb_timer_ltimer.vaddr == NULL) {
+        destroy(ltimer->data);
+        return ENOMEM;
+    }
+
+    /* register the IRQs we need */
+    error = ps_calloc(&ops.malloc_ops, 1, sizeof(ps_irq_t), (void **) &timer->callback_data.irq);
+    if (error) {
+        destroy(ltimer->data);
+        return error;
+    }
+    timer->callback_data.ltimer = ltimer;
+    timer->callback_data.irq_handler = handle_irq;
+    error = get_nth_irq(ltimer->data, 0, timer->callback_data.irq);
+    if (error) {
+        destroy(ltimer->data);
+        return error;
+    }
+    timer->irq_id = ps_irq_register(&ops.irq_ops, *timer->callback_data.irq, handle_irq_wrapper,
+                                    &timer->callback_data);
+    if (timer->irq_id < 0) {
+        destroy(ltimer->data);
+        return EIO;
+    }
+
+    error = init_ltimer(ltimer);
+    if (error) {
+        destroy(ltimer->data);
+        return error;
+    }
+    /* success! */
+    return 0;
+}
+
+int ltimer_default_describe(ltimer_t *ltimer, ps_io_ops_t ops)
+{
+    if (ltimer == NULL) {
+        ZF_LOGE("Timer is NULL!");
+        return EINVAL;
+    }
+
+    ltimer->get_num_irqs = get_num_irqs;
+    ltimer->get_nth_irq = get_nth_irq;
+    ltimer->get_num_pmems = get_num_pmems;
+    ltimer->get_nth_pmem = get_nth_pmem;
+    return 0;
+}
diff --git a/libplatsupport/src/plat/ariane/serial.c b/libplatsupport/src/plat/ariane/serial.c
index 47b24c2..921b151 100644
--- a/libplatsupport/src/plat/ariane/serial.c
+++ b/libplatsupport/src/plat/ariane/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdlib.h>
diff --git a/libplatsupport/src/plat/bcm2711/chardev.c b/libplatsupport/src/plat/bcm2711/chardev.c
new file mode 100644
index 0000000..fd222d2
--- /dev/null
+++ b/libplatsupport/src/plat/bcm2711/chardev.c
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright (C) 2021, Hensoldt Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+/**
+ * Contains the definition for all character devices on this platform.
+ * Currently this is just a simple patch.
+ */
+
+#include "../../chardev.h"
+#include "../../common.h"
+#include <utils/util.h>
+
+#include "serial.h"
+
+static const int uart0_irqs[] = {UART0_IRQ, -1};
+static const int uart1_irqs[] = {UART1_IRQ, -1};
+static const int uart2_irqs[] = {UART2_IRQ, -1};
+static const int uart3_irqs[] = {UART3_IRQ, -1};
+static const int uart4_irqs[] = {UART4_IRQ, -1};
+static const int uart5_irqs[] = {UART5_IRQ, -1};
+
+#define PL011_UART_DEFN(devid) {    \
+    .id      = BCM2711_UART##devid, \
+    .paddr   = PL011_UART_BASE,     \
+    .size    = BIT(12),             \
+    .irqs    = uart##devid##_irqs,  \
+    .init_fn = &uart_init           \
+}
+
+#define MINI_UART_DEFN(devid) {     \
+    .id      = BCM2711_UART##devid, \
+    .paddr   = MINI_UART_BASE,      \
+    .size    = BIT(12),             \
+    .irqs    = uart##devid##_irqs,  \
+    .init_fn = &uart_init           \
+}
+
+static const struct dev_defn dev_defn[] = {
+    PL011_UART_DEFN(0),
+    MINI_UART_DEFN(1),
+    PL011_UART_DEFN(2),
+    PL011_UART_DEFN(3),
+    PL011_UART_DEFN(4),
+    PL011_UART_DEFN(5)
+};
+
+struct ps_chardevice *
+ps_cdev_init(enum chardev_id id, const ps_io_ops_t *o, struct ps_chardevice *d)
+{
+    unsigned int i;
+    for (i = 0; i < ARRAY_SIZE(dev_defn); i++) {
+        if (dev_defn[i].id == id) {
+            return (dev_defn[i].init_fn(dev_defn + i, o, d)) ? NULL : d;
+        }
+    }
+    return NULL;
+}
diff --git a/libplatsupport/src/plat/bcm2711/clock.c b/libplatsupport/src/plat/bcm2711/clock.c
new file mode 100644
index 0000000..324e07f
--- /dev/null
+++ b/libplatsupport/src/plat/bcm2711/clock.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright (C) 2021, Hensoldt Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#include <platsupport/i2c.h>
+
+#include "../../arch/arm/clock.h"
+#include "../../services.h"
+#include <assert.h>
+#include <string.h>
+#include <utils/util.h>
+
+static struct clock master_clk = { CLK_OPS_DEFAULT(MASTER) };
+static struct clock sp804_clk = { CLK_OPS_DEFAULT(SP804) };
+
+int clock_sys_init(ps_io_ops_t *o, clock_sys_t *clock_sys)
+{
+    clock_sys->priv = (void *)0xdeadbeef;
+    clock_sys->get_clock = &ps_get_clock;
+    clock_sys->gate_enable = NULL;
+    return 0;
+}
+
+void clk_print_clock_tree(clock_sys_t *sys)
+{
+    clk_t *clk = clk_get_clock(sys, CLK_MASTER);
+    clk_print_tree(clk, "");
+}
+
+clk_t *ps_clocks[] = {
+    [CLK_MASTER]   = &master_clk,
+    [CLK_SP804]    = &sp804_clk,
+};
+
+/* These frequencies are NOT the recommended frequencies. They are to be used
+ * when we need to make assumptions about what u-boot has left us with.
+ * These values originate from the bcm2837 platform port. According to the
+ * BCM2837 TRM in section 14.2. the SP804 clock depends on the apb_clock. The
+ * memory bus is controlled by the frequency of the GPU processor core
+ * (core_freq). According to
+ * https://www.raspberrypi.org/documentation/configuration/config-txt/overclocking.md
+ * the bcm2837 has a default core_freq of 400MHz and the bcm2711 has a default
+ * core_freq of 500MHz. But according to
+ * https://www.raspberrypi.org/forums/viewtopic.php?t=227221#p1393826 the
+ * frequency needs to be locked at 250MHz for the bcm2837. In the BCM2711 TRM in
+ * section 2.1.1., it is also mentioned that the system clock is 250MHz. Thus,
+ * we leave the SP804 Clock at 250MHz for now.
+ */
+freq_t ps_freq_default[] = {
+    [CLK_MASTER]   =  0 * MHZ,
+    [CLK_SP804]    = 250 * MHZ,
+};
diff --git a/libplatsupport/src/plat/bcm2711/gpio.c b/libplatsupport/src/plat/bcm2711/gpio.c
new file mode 100644
index 0000000..5e68d49
--- /dev/null
+++ b/libplatsupport/src/plat/bcm2711/gpio.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2021, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <stdint.h>
+#include <utils/util.h>
+#include <platsupport/gpio.h>
+#include <platsupport/plat/gpio.h>
+#include "../../services.h"
+
+#define BCM2711_GPIO_PADDR  0xfe200000
+#define BCM2711_GPIO_SIZE   0x1000
+
+// Registers according to section 5.2 of BCM2711 TRM
+typedef volatile struct bcm2711_gpio_regs {
+    uint32_t gpfsel0;        /* +0x00 */
+    uint32_t gpfsel1;        /* +0x04 */
+    uint32_t gpfsel2;        /* +0x08 */
+    uint32_t gpfsel3;        /* +0x0c */
+    uint32_t gpfsel4;        /* +0x10 */
+    uint32_t gpfsel5;        /* +0x14 */
+    uint32_t unused0;
+    uint32_t gpset0;         /* +0x1c */
+    uint32_t gpset1;         /* +0x20 */
+    uint32_t unused1;
+    uint32_t gpclr0;         /* +0x28 */
+    uint32_t gpclr1;         /* +0x2c */
+    uint32_t unused2;
+    uint32_t gplev0;         /* +0x34 */
+    uint32_t gplev1;         /* +0x38 */
+    uint32_t unused3;
+    uint32_t gpeds0;         /* +0x40 */
+    uint32_t gpeds1;         /* +0x44 */
+    uint32_t unused4;
+    uint32_t gpren0;         /* +0x4c */
+    uint32_t gpren1;         /* +0x50 */
+    uint32_t unused5;
+    uint32_t gpfen0;         /* +0x58 */
+    uint32_t gpfen1;         /* +0x5c */
+    uint32_t unused6;
+    uint32_t gphen0;         /* +0x64 */
+    uint32_t gphen1;         /* +0x68 */
+    uint32_t unused7;
+    uint32_t gplen0;         /* +0x70 */
+    uint32_t gplen1;         /* +0x74 */
+    uint32_t unused8;
+    uint32_t gparen0;        /* +0x7c */
+    uint32_t gparen1;        /* +0x80 */
+    uint32_t unused9;
+    uint32_t gpafen0;        /* +0x88 */
+    uint32_t gpafen1;        /* +0x8c */
+    uint32_t unused10;
+    uint32_t gppud;          /* +0x94 */
+    uint32_t gppudclk0;      /* +0x98 */
+    uint32_t gppudclk1;      /* +0x9c */
+} bcm2711_gpio_regs_t;
+
+static struct bcm2711_gpio {
+    bcm2711_gpio_regs_t *bank[GPIO_NBANKS];
+} gpio_ctx;
+
+static bcm2711_gpio_regs_t *bcm2711_gpio_get_bank(gpio_t *gpio)
+{
+    assert(gpio);
+    assert(gpio->gpio_sys);
+    assert(gpio->gpio_sys->priv);
+    struct bcm2711_gpio *gpio_priv = (struct bcm2711_gpio *)gpio->gpio_sys->priv;
+    int port = 0;
+    return gpio_priv->bank[port];
+}
+
+static int bcm2711_gpio_init(gpio_sys_t *gpio_sys, int id, enum gpio_dir dir, gpio_t *gpio)
+{
+    assert(gpio);
+    assert(gpio_sys);
+    struct bcm2711_gpio *gpio_priv = (struct bcm2711_gpio *)gpio_sys->priv;
+    assert(gpio_priv);
+    if (id < 0 || id > MAX_GPIO_ID) {
+        ZF_LOGE("GPIO Pin ID is not in valid range!");
+        return -1;
+    }
+
+    gpio->id = id;
+    gpio->gpio_sys = gpio_sys;
+
+    return 0;
+}
+
+/*
+ * GPIO set level function
+ *
+ * See BCM2711 TRM, section 5 General Purpose I/O (GPIO):
+ * The bcm2711 SoC features 58 GPIO pins. The level of each of these pins can
+ * be set with the registers gpset0 (0x1c), gpset1 (0x20) and can be cleared
+ * with the registers gpclr0 (0x28), gpclr1 (0x2c). Each bit in one of these
+ * GPIO registers is responsible for setting/clearing the level of a GPIO pin.
+ * Separating the set and clear functions removes the need for read-modify-write
+ * operations.
+ *
+ * A prerequisite for using this function is to configure the respective GPIO
+ * pin to OUT (with the bcm2711_gpio_fsel function).
+ */
+static int bcm2711_gpio_set_level(gpio_t *gpio, enum gpio_level level)
+{
+    bcm2711_gpio_regs_t *bank = bcm2711_gpio_get_bank(gpio);
+    assert(bank);
+    int pin = gpio->id;
+    if (pin < 0 || pin > MAX_GPIO_ID) {
+        ZF_LOGE("GPIO Pin ID is not in valid range!");
+        return -1;
+    }
+
+    volatile uint32_t *paddr = (level == GPIO_LEVEL_HIGH) ? &(bank->gpset0) + (pin / 32)
+                               : &(bank->gpclr0) + (pin / 32);
+    uint8_t shift = (pin % 32);
+    *paddr = (1u << shift);
+
+    return 0;
+}
+
+/*
+ * GPIO read level function
+ *
+ * See BCM2711 TRM, section 5 General Purpose I/O (GPIO):
+ * The bcm2711 SoC features 58 GPIO pins. The level of each of these pins can
+ * be read with the registers gplev0 (0x34) and gplev1 (0x38). Each bit in one
+ * of these GPIO registers is responsible for reading the level of a GPIO pin.
+ * Separating the set and clear functions removes the need for read-modify-write
+ * operations.
+ *
+ * A prerequisite for using this function is to configure the respective GPIO
+ * pin to OUT (with the bcm2711_gpio_fsel function).
+ */
+static int bcm2711_gpio_read_level(gpio_t *gpio)
+{
+    bcm2711_gpio_regs_t *bank = bcm2711_gpio_get_bank(gpio);
+    assert(bank);
+    int pin = gpio->id;
+    if (pin < 0 || pin > MAX_GPIO_ID) {
+        ZF_LOGE("GPIO Pin ID is not in valid range!");
+        return -1;
+    }
+
+    volatile uint32_t *paddr = &(bank->gplev0) + (pin / 32);
+    uint8_t shift = pin % 32;
+    uint32_t value = *paddr;
+
+    return (value & (1u << shift)) ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW;
+}
+
+/*
+ * GPIO function select
+ *
+ * See BCM2711 TRM, section 5.2 Register View:
+ * The bcm2711 has 6 GPIO function select registers. Each of these control
+ * registers controls 10 GPIO pins of a total of 58 GPIO pins. As a result each
+ * of these control registers has 10 sets of 3 bits per GPIO pin. Depending on
+ * the mode given, these 3 bits are set accordingly for a specific pin i:
+ *
+ * 000 = GPIO Pin i is an input
+ * 001 = GPIO Pin i is an output
+ * 100 = GPIO Pin i takes alternate function 0
+ * 101 = GPIO Pin i takes alternate function 1
+ * 110 = GPIO Pin i takes alternate function 2
+ * 111 = GPIO Pin i takes alternate function 3
+ * 011 = GPIO Pin i takes alternate function 4
+ * 010 = GPIO Pin i takes alternate function 5
+ *
+ * To calculate the 3 bits for Pin i use the following formula:
+ *      i / 10 + ((i % 10) * 3)
+ */
+int bcm2711_gpio_fsel(gpio_t *gpio, uint8_t mode)
+{
+    bcm2711_gpio_regs_t *bank = bcm2711_gpio_get_bank(gpio);
+    assert(bank);
+    int pin = gpio->id;
+    if (pin < 0 || pin > MAX_GPIO_ID) {
+        ZF_LOGE("GPIO Pin ID is not in valid range!");
+        return -1;
+    }
+
+    volatile uint32_t *paddr = &(bank->gpfsel0) + (pin / 10);
+    uint8_t  shift = (pin % 10) * 3;
+    uint32_t mask  = BCM2711_GPIO_FSEL_MASK << shift;
+    uint32_t value = mode << shift;
+
+    uint32_t v = *paddr;
+    v = (v & ~mask) | (value & mask);
+    *paddr = v;
+
+    return 0;
+}
+
+int bcm2711_gpio_init_common(gpio_sys_t *gpio_sys)
+{
+    gpio_sys->priv = (void *)&gpio_ctx;
+    gpio_sys->set_level = &bcm2711_gpio_set_level;
+    gpio_sys->read_level = &bcm2711_gpio_read_level;
+    gpio_sys->init = &bcm2711_gpio_init;
+    return 0;
+}
+
+int bcm2711_gpio_sys_init(void *bank1, gpio_sys_t *gpio_sys)
+{
+    if (bank1 != NULL) {
+        gpio_ctx.bank[GPIO_BANK1] = bank1;
+    }
+    return bcm2711_gpio_init_common(gpio_sys);
+}
+
+int gpio_sys_init(ps_io_ops_t *io_ops, gpio_sys_t *gpio_sys)
+{
+    MAP_IF_NULL(io_ops, BCM2711_GPIO, gpio_ctx.bank[0]);
+    return bcm2711_gpio_init_common(gpio_sys);
+}
diff --git a/libplatsupport/src/plat/bcm2711/ltimer.c b/libplatsupport/src/plat/bcm2711/ltimer.c
new file mode 100644
index 0000000..b0c4f04
--- /dev/null
+++ b/libplatsupport/src/plat/bcm2711/ltimer.c
@@ -0,0 +1,271 @@
+/*
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright (C) 2021, Hensoldt Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+/* Implementation of a logical timer for omap platforms
+ *
+ * We use two GPTS: one for the time and relative timeouts, the other
+ * for absolute timeouts.
+ */
+#include <platsupport/timer.h>
+#include <platsupport/ltimer.h>
+#include <platsupport/plat/spt.h>
+#include <platsupport/plat/system_timer.h>
+#include <platsupport/pmem.h>
+#include <utils/util.h>
+
+#include "../../ltimer.h"
+
+#define NV_TMR_ID TMR0
+
+enum {
+    SP804_TIMER = 0,
+    SYSTEM_TIMER = 1,
+    NUM_TIMERS = 2,
+};
+
+typedef struct {
+    spt_t spt;
+    system_timer_t system;
+    void *timer_vaddrs[NUM_TIMERS];
+    irq_id_t timer_irq_ids[NUM_TIMERS];
+    timer_callback_data_t callback_datas[NUM_TIMERS];
+    ltimer_callback_fn_t user_callback;
+    void *user_callback_token;
+    ps_io_ops_t ops;
+    uint64_t period;
+} spt_ltimer_t;
+
+static pmem_region_t pmems[] = {
+    {
+        .type = PMEM_TYPE_DEVICE,
+        .base_addr = SP804_TIMER_PADDR,
+        .length = PAGE_SIZE_4K
+    },
+    {
+        .type = PMEM_TYPE_DEVICE,
+        .base_addr = SYSTEM_TIMER_PADDR,
+        .length = PAGE_SIZE_4K
+    }
+};
+
+size_t get_num_irqs(void *data)
+{
+    return NUM_TIMERS;
+}
+
+static int get_nth_irq(void *data, size_t n, ps_irq_t *irq)
+{
+    assert(n < get_num_irqs(data));
+    switch (n) {
+    case SP804_TIMER:
+        irq->irq.number = SP804_TIMER_IRQ;
+        irq->type = PS_INTERRUPT;
+        break;
+    case SYSTEM_TIMER:
+        irq->irq.number = SYSTEM_TIMER_MATCH_IRQ(SYSTEM_TIMER_MATCH);
+        irq->type = PS_INTERRUPT;
+        break;
+    }
+    return 0;
+}
+
+static size_t get_num_pmems(void *data)
+{
+    return sizeof(pmems) / sizeof(pmems[0]);
+}
+
+static int get_nth_pmem(void *data, size_t n, pmem_region_t *paddr)
+{
+    assert(n < get_num_pmems(data));
+    *paddr = pmems[n];
+    return 0;
+}
+
+static int handle_irq(void *data, ps_irq_t *irq)
+{
+    assert(data != NULL);
+    spt_ltimer_t *spt_ltimer = data;
+
+    // ZF_LOGE("IRQ number: %ld",irq->irq.number);
+
+    switch (irq->irq.number) {
+    case SP804_TIMER_IRQ:
+        // ZF_LOGE("SP804 timer IRQ number: %ld",irq->irq.number);
+        spt_handle_irq(&spt_ltimer->spt);
+        if (spt_ltimer->period > 0) {
+            spt_set_timeout(&spt_ltimer->spt, spt_ltimer->period);
+        }
+        break;
+    case SYSTEM_TIMER_MATCH_IRQ(SYSTEM_TIMER_MATCH):
+        // ZF_LOGE("System timer IRQ number: %ld",irq->irq.number);
+        system_timer_handle_irq(&spt_ltimer->system);
+        break;
+    default:
+        return EINVAL;
+    }
+
+    /* Both IRQs correspond to timeouts, the timestamp is not expected to roll over
+     * in any reasonable timeframe */
+    ltimer_event_t event = LTIMER_TIMEOUT_EVENT;
+    if (spt_ltimer->user_callback) {
+        spt_ltimer->user_callback(spt_ltimer->user_callback_token, event);
+    }
+
+    return 0;
+}
+
+static int get_time(void *data, uint64_t *time)
+{
+    assert(data != NULL);
+    assert(time != NULL);
+
+    spt_ltimer_t *spt_ltimer = data;
+    *time = system_timer_get_time(&spt_ltimer->system);
+    return 0;
+}
+
+static int get_resolution(void *data, uint64_t *resolution)
+{
+    return ENOSYS;
+}
+
+static int set_timeout(void *data, uint64_t ns, timeout_type_t type)
+{
+    assert(data != NULL);
+    spt_ltimer_t *spt_ltimer = data;
+    spt_ltimer->period = 0;
+
+    switch (type) {
+    case TIMEOUT_ABSOLUTE:
+        return system_timer_set_timeout(&spt_ltimer->system, ns);
+    case TIMEOUT_PERIODIC:
+        spt_ltimer->period = ns;
+    /* fall through */
+    case TIMEOUT_RELATIVE:
+        return spt_set_timeout(&spt_ltimer->spt, ns);
+    }
+
+    return EINVAL;
+}
+
+static int reset(void *data)
+{
+    assert(data != NULL);
+    spt_ltimer_t *spt_ltimer = data;
+    spt_stop(&spt_ltimer->spt);
+    spt_start(&spt_ltimer->spt);
+    system_timer_reset(&spt_ltimer->system);
+    return 0;
+}
+
+static void destroy(void *data)
+{
+    assert(data);
+    spt_ltimer_t *spt_ltimer = data;
+    for (int i = 0; i < NUM_TIMERS; i++) {
+        if (i == SP804_TIMER) {
+            spt_stop(&spt_ltimer->spt);
+        }
+        ps_pmem_unmap(&spt_ltimer->ops, pmems[i], spt_ltimer->timer_vaddrs[i]);
+
+        if (spt_ltimer->callback_datas[i].irq) {
+            ps_free(&spt_ltimer->ops.malloc_ops, sizeof(ps_irq_t), spt_ltimer->callback_datas[i].irq);
+        }
+
+        if (spt_ltimer->timer_irq_ids[i] > PS_INVALID_IRQ_ID) {
+            ps_irq_unregister(&spt_ltimer->ops.irq_ops, spt_ltimer->timer_irq_ids[i]);
+        }
+    }
+    ps_free(&spt_ltimer->ops.malloc_ops, sizeof(spt_ltimer), spt_ltimer);
+}
+
+int ltimer_default_init(ltimer_t *ltimer, ps_io_ops_t ops, ltimer_callback_fn_t callback, void *callback_token)
+{
+
+    int error = ltimer_default_describe(ltimer, ops);
+    if (error) {
+        return error;
+    }
+
+    ltimer->get_time = get_time;
+    ltimer->get_resolution = get_resolution;
+    ltimer->set_timeout = set_timeout;
+    ltimer->reset = reset;
+    ltimer->destroy = destroy;
+
+    error = ps_calloc(&ops.malloc_ops, 1, sizeof(spt_ltimer_t), &ltimer->data);
+    if (error) {
+        return error;
+    }
+    assert(ltimer->data != NULL);
+    spt_ltimer_t *spt_ltimer = ltimer->data;
+    spt_ltimer->ops = ops;
+    spt_ltimer->user_callback = callback;
+    spt_ltimer->user_callback_token = callback_token;
+    for (int i = 0; i < NUM_TIMERS; i++) {
+        spt_ltimer->timer_irq_ids[i] = PS_INVALID_IRQ_ID;
+    }
+
+    for (int i = 0; i < NUM_TIMERS; i++) {
+        /* map the registers we need */
+        spt_ltimer->timer_vaddrs[i] = ps_pmem_map(&ops, pmems[i], false, PS_MEM_NORMAL);
+        if (spt_ltimer->timer_vaddrs[i] == NULL) {
+            destroy(ltimer->data);
+            return ENOMEM;
+        }
+
+        /* register the IRQs we need */
+        error = ps_calloc(&ops.malloc_ops, 1, sizeof(ps_irq_t), (void **) &spt_ltimer->callback_datas[i].irq);
+        if (error) {
+            destroy(ltimer->data);
+            return error;
+        }
+        spt_ltimer->callback_datas[i].ltimer = ltimer;
+        spt_ltimer->callback_datas[i].irq_handler = handle_irq;
+        error = get_nth_irq(ltimer->data, i, spt_ltimer->callback_datas[i].irq);
+        if (error) {
+            destroy(ltimer->data);
+            return error;
+        }
+        spt_ltimer->timer_irq_ids[i] = ps_irq_register(&ops.irq_ops, *spt_ltimer->callback_datas[i].irq,
+                                                       handle_irq_wrapper, &spt_ltimer->callback_datas[i]);
+        if (spt_ltimer->timer_irq_ids[i] < 0) {
+            destroy(ltimer->data);
+            return EIO;
+        }
+    }
+
+    /* setup spt */
+    spt_config_t spt_config = {
+        .vaddr = spt_ltimer->timer_vaddrs[SP804_TIMER],
+    };
+
+    spt_init(&spt_ltimer->spt, spt_config);
+    spt_start(&spt_ltimer->spt);
+
+    /* Setup system timer */
+    system_timer_config_t system_config = {
+        .vaddr = spt_ltimer->timer_vaddrs[SYSTEM_TIMER],
+    };
+
+    system_timer_init(&spt_ltimer->system, system_config);
+
+    return 0;
+}
+
+int ltimer_default_describe(ltimer_t *ltimer, ps_io_ops_t ops)
+{
+    if (ltimer == NULL) {
+        ZF_LOGE("Timer is NULL!");
+        return EINVAL;
+    }
+
+    ltimer->get_num_irqs = get_num_irqs;
+    ltimer->get_nth_irq = get_nth_irq;
+    ltimer->get_num_pmems = get_num_pmems;
+    ltimer->get_nth_pmem = get_nth_pmem;
+    return 0;
+}
diff --git a/libplatsupport/src/plat/bcm2711/mini_serial.c b/libplatsupport/src/plat/bcm2711/mini_serial.c
new file mode 100644
index 0000000..1ddc40a
--- /dev/null
+++ b/libplatsupport/src/plat/bcm2711/mini_serial.c
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2021, Hensoldt Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <platsupport/serial.h>
+#include <platsupport/plat/serial.h>
+#include "serial.h"
+#include "mini_serial.h"
+
+typedef volatile struct mini_uart_regs_s {
+    uint32_t mu_io;         // 0x40: mini UART I/O Data
+    uint32_t mu_ier;        // 0x44: mini UART interrupt enable
+    uint32_t mu_iir;        // 0x48: mini UART interrupt identify
+    uint32_t mu_lcr;        // 0x4c: mini UART line control
+    uint32_t mu_mcr;        // 0x50: mini UART modem control
+    uint32_t mu_lsr;        // 0x54: mini UART line status
+    uint32_t mu_msr;        // 0x58: mini UART modem status
+    uint32_t mu_scratch;    // 0x5c: mini UART scratch
+    uint32_t mu_cntl;       // 0x60: mini UART extra control
+    uint32_t mu_stat;       // 0x64: mini UART extra status
+    uint32_t mu_baud;       // 0x68: mini UART baudrate
+}
+mini_uart_regs_t;
+
+/* This bit is set if the transmit FIFO can accept at least one byte.*/
+#define MU_LSR_TXEMPTY   BIT(5)
+/* This bit is set if the transmit FIFO is empty and the
+ * transmitter is idle. (Finished shifting out the last bit). */
+#define MU_LSR_TXIDLE    BIT(6)
+#define MU_LSR_RXOVERRUN BIT(1)
+#define MU_LSR_DATAREADY BIT(0)
+
+#define MU_LCR_DLAB      BIT(7)
+#define MU_LCR_BREAK     BIT(6)
+#define MU_LCR_DATASIZE  BIT(0)
+
+static void mini_uart_handle_irq(ps_chardevice_t *dev)
+{
+}
+
+int mini_uart_init(const struct dev_defn *defn,
+                   const ps_io_ops_t *ops,
+                   ps_chardevice_t *dev)
+{
+    /* Attempt to map the virtual address, assure this works */
+    void *vaddr = chardev_map(defn, ops);
+    memset(dev, 0, sizeof(*dev));
+    if (vaddr == NULL) {
+        return -1;
+    }
+
+    // When mapping the virtual address space, the base addresses need to be
+    // 4k byte aligned. Since the real base addresses of the UART peripherals
+    // are not 4k byte aligned, we have to add the required offset.
+    uint32_t addr_offset = 0;
+    switch (defn->id) {
+    case 1:
+        addr_offset = UART1_OFFSET;
+        break;
+    default:
+        ZF_LOGE("Mini UART with ID %d does not exist!", defn->id);
+        return -1;
+        break;
+    }
+
+    /* Set up all the  device properties. */
+    dev->id         = defn->id;
+    dev->vaddr      = (void *)vaddr + addr_offset; // use real base address
+    dev->read       = &uart_read;
+    dev->write      = &uart_write;
+    dev->handle_irq = &mini_uart_handle_irq;
+    dev->irqs       = defn->irqs;
+    dev->ioops      = *ops;
+    dev->flags      = SERIAL_AUTO_CR;
+
+    return 0;
+}
+
+int mini_uart_getchar(ps_chardevice_t *d)
+{
+    while (!((mini_uart_regs_t *)d->vaddr)->mu_lsr & MU_LSR_DATAREADY);
+    return ((mini_uart_regs_t *)d->vaddr)->mu_io;
+}
+
+int mini_uart_putchar(ps_chardevice_t *d, int c)
+{
+    while (!((mini_uart_regs_t *)d->vaddr)->mu_lsr & MU_LSR_TXIDLE);
+    ((mini_uart_regs_t *)d->vaddr)->mu_io = (c & 0xff);
+
+    return 0;
+}
diff --git a/libplatsupport/src/plat/bcm2711/mini_serial.h b/libplatsupport/src/plat/bcm2711/mini_serial.h
new file mode 100644
index 0000000..ede4ff0
--- /dev/null
+++ b/libplatsupport/src/plat/bcm2711/mini_serial.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2021, Hensoldt Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include "../../chardev.h"
+#include <autoconf.h>
+#include <platsupport/gen_config.h>
+
+int mini_uart_init(const struct dev_defn *defn,
+                   const ps_io_ops_t *ops,
+                   ps_chardevice_t *dev);
+
+int mini_uart_getchar(ps_chardevice_t *d);
+
+int mini_uart_putchar(ps_chardevice_t *d, int c);
\ No newline at end of file
diff --git a/libplatsupport/src/plat/bcm2711/pl011_serial.c b/libplatsupport/src/plat/bcm2711/pl011_serial.c
new file mode 100644
index 0000000..2149a40
--- /dev/null
+++ b/libplatsupport/src/plat/bcm2711/pl011_serial.c
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2021, Hensoldt Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <platsupport/serial.h>
+#include <platsupport/plat/serial.h>
+#include "serial.h"
+#include "pl011_serial.h"
+
+#define DEV_OFFSET(devid) UART##devid##_OFFSET
+
+typedef volatile struct uart_regs_s {
+    uint32_t dr;            // 0x00: data register
+    uint32_t rsrecr;        // 0x04: receive status/error clear register
+    uint64_t unused0[2];    // 0x08
+    uint32_t fr;            // 0x18: flag register
+    uint32_t unused1;       // 0x1c
+    uint32_t ilpr;          // 0x20: not in use
+    uint32_t ibrd;          // 0x24: integer baud rate divisor
+    uint32_t fbrd;          // 0x28: fractional baud rate divisor
+    uint32_t lcrh;          // 0x2c: line control register
+    uint32_t cr;            // 0x30: control register
+    uint32_t ifls;          // 0x34: interrupt FIFO level select register
+    uint32_t imsc;          // 0x38: interrupt mask set clear register
+    uint32_t ris;           // 0x3c: raw interrupt status register
+    uint32_t mis;           // 0x40: masked interrupt status register
+    uint32_t icr;           // 0x44: interrupt clear register
+    uint32_t dmacr;         // 0x48: DMA control register
+}
+uart_regs_t;
+
+/* LCRH register */
+#define LCRH_SPS        (1 << 7) // stick parity select
+#define LCRH_WLEN_8BIT  (3 << 5) // word length
+#define LCRH_WLEN_7BIT  (2 << 5) // word length
+#define LCRH_WLEN_6BIT  (1 << 5) // word length
+#define LCRH_WLEN_5BIT  (0 << 5) // word length
+#define LCRH_FEN        (1 << 4) // enable fifos
+#define LCRH_STP2       (1 << 3) // two stop bits select
+#define LCRH_EPS        (1 << 2) // Even parity select
+#define LCRH_PEN        (1 << 1) // Parity enable
+#define LCRH_BRK        (1 << 0) // send break
+
+/* CR register */
+#define CR_RXE          (1 << 9) // receive enable
+#define CR_TXE          (1 << 8) // transmit enable
+#define CR_UARTEN       (1 << 0) // UART enable
+
+/* FR register */
+#define FR_TXFE         (1 << 7) // Transmit FIFO empty
+#define FR_RXFF         (1 << 6) // Receive FIFO full
+#define FR_TXFF         (1 << 5) // Transmit FIFO full
+#define FR_RXFE         (1 << 4) // Receive FIFO empty
+#define FR_BUSY         (1 << 3) // UART busy
+
+static void pl011_uart_handle_irq(ps_chardevice_t *dev)
+{
+    // clear interrupts
+    ((uart_regs_t *)dev->vaddr)->icr = 0x7f0;
+}
+
+static int pl011_uart_cr_configure(ps_chardevice_t *dev)
+{
+    uint32_t val = ((uart_regs_t *)dev->vaddr)->cr;
+
+    val |= CR_TXE; // transmit enable
+    val |= CR_RXE; // receive enable
+
+    ((uart_regs_t *)dev->vaddr)->cr = val;
+
+    return 0;
+}
+
+static int pl011_uart_lcrh_configure(ps_chardevice_t *dev)
+{
+    uint32_t val = ((uart_regs_t *)dev->vaddr)->lcrh;
+
+    val |= LCRH_WLEN_8BIT; // character size is 8bit
+    val &= ~LCRH_STP2;     // only one stop bit
+    val &= ~LCRH_PEN;      // no parity
+
+    ((uart_regs_t *)dev->vaddr)->lcrh = val;
+
+    return 0;
+}
+
+/*
+ * Set UART baud rate divisor value
+ *
+ * More information: https://developer.arm.com/documentation/ddi0183/g/programmers-model/register-descriptions/fractional-baud-rate-register--uartfbrd
+ */
+static int pl011_uart_baudrate_div_configure(ps_chardevice_t *dev)
+{
+    // Base UART clock according to https://github.com/raspberrypi/firmware/issues/951
+    const uint32_t freq_uart_clk = 48000000;
+    const uint32_t baud_rate = 115200;
+
+    double baud_div = (double) freq_uart_clk / (double)(16.0 * baud_rate);
+    double frac_div = baud_div - (uint32_t) baud_div;
+
+    // Set IBRD register
+    uint32_t val = ((uart_regs_t *)dev->vaddr)->ibrd;
+    val |= (uint32_t) baud_div;
+    ((uart_regs_t *)dev->vaddr)->ibrd = val;
+
+    // Set FBRD register
+    val = ((uart_regs_t *)dev->vaddr)->fbrd;
+    val |= (uint32_t)(frac_div * 64.0 + 0.5);
+    ((uart_regs_t *)dev->vaddr)->fbrd = val;
+
+    return 0;
+}
+
+/*
+ * Configure UART registers
+ *
+ * This configuration process is based on the description in the BCM2711 TRM
+ * section 11.5 Register View, more precisely on the information given for the
+ * CR register. Furthermore, the LCRH and the baudrate divider registers (IBRD,
+ * FBRD) are configured. For all of these registers the UART must be disabled.
+ */
+static int pl011_uart_configure(ps_chardevice_t *dev)
+{
+    /* ---------------------------------------------------------------------- */
+    /* -------------------------    Disable UART     ------------------------ */
+    /* ---------------------------------------------------------------------- */
+    // disable UART
+    uint32_t val = ((uart_regs_t *)dev->vaddr)->cr;
+    val &= ~CR_UARTEN;
+    ((uart_regs_t *)dev->vaddr)->cr = val;
+
+    // wait till UART is not busy anymore
+    while (((uart_regs_t *)dev->vaddr)->fr & FR_BUSY);
+
+    // disable FIFO
+    val = ((uart_regs_t *)dev->vaddr)->lcrh;
+    val &= ~LCRH_FEN;
+    ((uart_regs_t *)dev->vaddr)->lcrh = val;
+
+    /* ---------------------------------------------------------------------- */
+    /* --------------------    Configure UART registers   ------------------- */
+    /* ---------------------------------------------------------------------- */
+    // Set control register (CR)
+    pl011_uart_cr_configure(dev);
+
+    // Set line control register (LCRH)
+    pl011_uart_lcrh_configure(dev);
+
+    // Set baudrate divider
+    pl011_uart_baudrate_div_configure(dev);
+
+    /* ---------------------------------------------------------------------- */
+    /* -------------------------    Enable UART     ------------------------- */
+    /* ---------------------------------------------------------------------- */
+    // enable FIFO
+    val = ((uart_regs_t *)dev->vaddr)->lcrh;
+    val |= LCRH_FEN;
+    ((uart_regs_t *)dev->vaddr)->lcrh = val;
+
+    // enable UART
+    val = ((uart_regs_t *)dev->vaddr)->cr;
+    val |= CR_UARTEN;
+    ((uart_regs_t *)dev->vaddr)->cr = val;
+
+    // Set Interrupt Mask Set/Clear Register (IMSC)
+    ((uart_regs_t *)dev->vaddr)->imsc = 0x10; // activate receive interrupt
+
+    return 0;
+}
+
+int pl011_uart_init(
+    const struct dev_defn *defn,
+    const ps_io_ops_t *ops,
+    ps_chardevice_t *dev
+)
+{
+    /* Attempt to map the virtual address, assure this works */
+    void *vaddr = chardev_map(defn, ops);
+    memset(dev, 0, sizeof(*dev));
+    if (vaddr == NULL) {
+        return -1;
+    }
+
+    // When mapping the virtual address space, the base addresses need to be
+    // 4k byte aligned. Since the real base addresses of the UART peripherals
+    // are not 4k byte aligned, we have to add the required offset.
+    uint32_t addr_offset = 0;
+    switch (defn->id) {
+    case 0:
+        addr_offset = UART0_OFFSET;
+        break;
+    // case 1: Mini UART
+    case 2:
+        addr_offset = UART2_OFFSET;
+        break;
+    case 3:
+        addr_offset = UART3_OFFSET;
+        break;
+    case 4:
+        addr_offset = UART4_OFFSET;
+        break;
+    case 5:
+        addr_offset = UART5_OFFSET;
+        break;
+    default:
+        ZF_LOGE("PL011 UART with ID %d does not exist!", defn->id);
+        return -1;
+        break;
+    }
+
+    /* Set up all the  device properties. */
+    dev->id         = defn->id;
+    dev->vaddr      = (void *)vaddr + addr_offset; // use real base address
+    dev->read       = &uart_read;
+    dev->write      = &uart_write;
+    dev->handle_irq = &pl011_uart_handle_irq;
+    dev->irqs       = defn->irqs;
+    dev->ioops      = *ops;
+    dev->flags      = SERIAL_AUTO_CR;
+
+    pl011_uart_configure(dev);
+
+    return 0;
+}
+
+int pl011_uart_getchar(ps_chardevice_t *d)
+{
+    int ch = EOF;
+
+    // only if receive fifo is not empty
+    if ((((uart_regs_t *)d->vaddr)->fr & FR_RXFE) == 0) {
+        ch = ((uart_regs_t *)d->vaddr)->dr & MASK(8);
+    }
+    return ch;
+}
+
+int pl011_uart_putchar(ps_chardevice_t *d, int c)
+{
+    // only if transmit fifo is not full
+    while ((((uart_regs_t *)d->vaddr)->fr & FR_TXFF) != 0);
+
+    ((uart_regs_t *)d->vaddr)->dr = c;
+    if (c == '\n' && (d->flags & SERIAL_AUTO_CR)) {
+        uart_putchar(d, '\r');
+    }
+
+    return c;
+}
diff --git a/libplatsupport/src/plat/bcm2711/pl011_serial.h b/libplatsupport/src/plat/bcm2711/pl011_serial.h
new file mode 100644
index 0000000..a3758b2
--- /dev/null
+++ b/libplatsupport/src/plat/bcm2711/pl011_serial.h
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2021, Hensoldt Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include "../../chardev.h"
+#include <autoconf.h>
+#include <platsupport/gen_config.h>
+
+int pl011_uart_init(const struct dev_defn *defn,
+                    const ps_io_ops_t *ops,
+                    ps_chardevice_t *dev);
+
+int pl011_uart_getchar(ps_chardevice_t *d);
+
+int pl011_uart_putchar(ps_chardevice_t *d, int c);
diff --git a/libplatsupport/src/plat/bcm2711/serial.c b/libplatsupport/src/plat/bcm2711/serial.c
new file mode 100644
index 0000000..b3f1854
--- /dev/null
+++ b/libplatsupport/src/plat/bcm2711/serial.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright (C) 2021, Hensoldt Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <stdlib.h>
+#include <platsupport/gpio.h>
+#include <platsupport/plat/gpio.h>
+#include <platsupport/serial.h>
+#include <platsupport/plat/serial.h>
+
+#include "serial.h"
+#include "mini_serial.h"
+#include "pl011_serial.h"
+
+typedef struct {
+    int (*uart_init)(const struct dev_defn *defn,
+                     const ps_io_ops_t *ops,
+                     ps_chardevice_t *dev);
+    int (*uart_getchar)(ps_chardevice_t *d);
+    int (*uart_putchar)(ps_chardevice_t *d, int c);
+} uart_funcs_t;
+
+uart_funcs_t uart_funcs;
+
+int uart_getchar(ps_chardevice_t *d)
+{
+    uart_funcs.uart_getchar(d);
+}
+
+int uart_putchar(ps_chardevice_t *d, int c)
+{
+    uart_funcs.uart_putchar(d, c);
+}
+
+/*
+ * Configure UART GPIO pins.
+ *
+ * On the RPi4, there are 6 UARTs: One miniUART (UART1) and 5 PL011 UARTs (UART0
+ * + UART2-5). There is also a possibility to configure these pins via the
+ * config.txt file statically. Since these pins might be used for other
+ * functionality than UART, it might be best to configure these pins here
+ * dynamically.
+ *
+ * BCM2711 TRM, Section 11.3. Primary UART Inputs and Outputs.
+ */
+int uart_gpio_configure(enum chardev_id id, const ps_io_ops_t *o)
+{
+    gpio_sys_t gpio_sys;
+    gpio_t gpio;
+
+    // We only configure the TX/RX pins for each UART peripheral and ignore flow
+    // control (CTS/RTS pins) for now.
+    int tx_pin = -1;
+    int rx_pin = -1;
+    int alt_function = -1;
+
+    /*
+     * GPIO pin configuration
+     *
+     * GPIO pins 14/15 are mapped accordingly: https://pinout.xyz/pinout/pin8_gpio14#
+     *
+     * This means:
+     *  UART0: these pins are RX/TX lines; pins must be configured for ALT0
+     *  UART1: these pins are RX/TX lines; pins must be configured for ALT5
+     *  UART5: these pins are CTS/RTS lines; we ignore cts/rts for now
+    */
+    switch (id) {
+    case 0:
+        // UART 0 uses GPIO pins 14-15
+        tx_pin = 14;
+        rx_pin = 15;
+        alt_function = BCM2711_GPIO_FSEL_ALT0;
+    case 1:
+        // UART 1 uses GPIO pins 14-15
+        tx_pin = 14;
+        rx_pin = 15;
+        alt_function = BCM2711_GPIO_FSEL_ALT5;
+    case 2:
+        // UART 2 uses GPIO pins 0-3
+        tx_pin = 0;
+        rx_pin = 1;
+        alt_function = BCM2711_GPIO_FSEL_ALT4;
+        break;
+    case 3:
+        // UART 3 uses GPIO pins 4-7
+        tx_pin = 4;
+        rx_pin = 5;
+        alt_function = BCM2711_GPIO_FSEL_ALT4;
+        break;
+    case 4:
+        // UART 4 uses GPIO pins 8-11
+        tx_pin = 8;
+        rx_pin = 9;
+        alt_function = BCM2711_GPIO_FSEL_ALT4;
+        break;
+    case 5:
+        // UART 5 uses GPIO pins 12-13
+        tx_pin = 12;
+        rx_pin = 13;
+        alt_function = BCM2711_GPIO_FSEL_ALT4;
+        break;
+    default:
+        ZF_LOGD("No pin configuration required!");
+        return 0;
+        break;
+    }
+
+    if (tx_pin < 0 || rx_pin < 0) {
+        ZF_LOGE("TX/RX pins wrongly configured!");
+        return -1;
+    }
+
+    if (alt_function < 0) {
+        ZF_LOGE("ALT function wrongly configured!");
+        return -1;
+    }
+
+    // GPIO initialization
+    int ret = gpio_sys_init((ps_io_ops_t *)o, &gpio_sys);
+    if (ret) {
+        ZF_LOGE("gpio_sys_init() failed: ret = %i", ret);
+        return -1;
+    }
+
+    // configure tx pin
+    gpio_sys.init(&gpio_sys, tx_pin, 0, &gpio);
+    bcm2711_gpio_fsel(&gpio, alt_function);
+
+    // configure rx pin
+    gpio_sys.init(&gpio_sys, rx_pin, 0, &gpio);
+    bcm2711_gpio_fsel(&gpio, alt_function);
+
+    return 0;
+}
+
+int uart_init(const struct dev_defn *defn,
+              const ps_io_ops_t *ops,
+              ps_chardevice_t *dev)
+{
+    switch (defn->id) {
+    case 1:
+        uart_funcs.uart_init    = &mini_uart_init;
+        uart_funcs.uart_getchar = &mini_uart_getchar;
+        uart_funcs.uart_putchar = &mini_uart_putchar;
+        break;
+    case 0:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+        uart_funcs.uart_init    = &pl011_uart_init;
+        uart_funcs.uart_getchar = &pl011_uart_getchar;
+        uart_funcs.uart_putchar = &pl011_uart_putchar;
+        break;
+    default:
+        ZF_LOGE("UART with id %d does not exist!", defn->id);
+        return -1;
+        break;
+    }
+
+    uart_gpio_configure(defn->id, ops);
+
+    uart_funcs.uart_init(defn, ops, dev);
+
+    return 0;
+}
diff --git a/libplatsupport/src/plat/bcm2711/serial.h b/libplatsupport/src/plat/bcm2711/serial.h
new file mode 100644
index 0000000..96ec4d5
--- /dev/null
+++ b/libplatsupport/src/plat/bcm2711/serial.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright (C) 2021, Hensoldt Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include "../../chardev.h"
+#include <autoconf.h>
+#include <platsupport/gen_config.h>
+
+#define UART0_IRQ       153
+#define UART1_IRQ       125
+#define UART2_IRQ       153
+#define UART3_IRQ       153
+#define UART4_IRQ       153
+#define UART5_IRQ       153
+
+#define PL011_UART_BASE 0xfe201000
+#define MINI_UART_BASE  0xfe215000
+
+#define UART0_OFFSET    0x0     // UART0: PL011
+#define UART1_OFFSET    0x40    // UART1: Mini UART
+#define UART2_OFFSET    0x400   // UART2: PL011
+#define UART3_OFFSET    0x600   // UART3: PL011
+#define UART4_OFFSET    0x800   // UART4: PL011
+#define UART5_OFFSET    0xa00   // UART5: PL011
+
+#define UART0_PADDR  (PL011_UART_BASE + UART0_OFFSET)   // 0xfe201000
+#define UART1_PADDR  (MINI_UART_BASE  + UART1_OFFSET)   // 0xfe215040
+#define UART2_PADDR  (PL011_UART_BASE + UART2_OFFSET)   // 0xfe201400
+#define UART3_PADDR  (PL011_UART_BASE + UART3_OFFSET)   // 0xfe201600
+#define UART4_PADDR  (PL011_UART_BASE + UART4_OFFSET)   // 0xfe201800
+#define UART5_PADDR  (PL011_UART_BASE + UART5_OFFSET)   // 0xfe201a00
+
+int uart_init(const struct dev_defn *defn, const ps_io_ops_t *ops, ps_chardevice_t *dev);
diff --git a/libplatsupport/src/plat/bcm2711/spt.c b/libplatsupport/src/plat/bcm2711/spt.c
new file mode 100644
index 0000000..3c78f3b
--- /dev/null
+++ b/libplatsupport/src/plat/bcm2711/spt.c
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright (C) 2021, Hensoldt Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <stdio.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <utils/util.h>
+#include "../../arch/arm/clock.h"
+#include <platsupport/timer.h>
+#include <platsupport/plat/spt.h>
+
+/* The arm timer on the BCM2711 is based on a SP804 timer with some modifications.
+ * Nothing seemed to have changed since the BCM2837 (except for the core_freq).
+
+    - Only one timer
+    - It only runs in continuous mode
+    - Can be set to either stop or continue in ARM debug halt mode
+    - Pre-scale options are only 1, 16 and 256
+    - CLK source is 250 MHz before prescale.
+        TODO: read comment in bcm2711/clock.c
+    - Has an additional register that will count up on each timer tick and
+        roll over without generating interrupts.  It has its own prescalar.
+
+    Functions by setting a value in the load register which the timer will move to the value
+    register and when the value counts down to zero, an interrupt will occur if interrupts are
+    enabled and the value from the load register will be copied back into the value register.
+
+ */
+
+enum {
+    /*
+        Width of the counter.
+            0: 16-bit counters
+            1: 32-bit counters
+    */
+    COUNTER_WIDTH_BIT = 1,
+    /*
+        The prescale bits select the prescale for the down counter.
+        Note: There are other pre-scale bits in this register (16:23) for
+                the separate free running up-counting counter.
+        00 : pre-scale is clock / 1 (No pre-scale)
+        01 : pre-scale is clock / 16
+        10 : pre-scale is clock / 256
+        11 : pre-scale is clock / 1
+    */
+    PRESCALE_BIT = 2,
+
+    /*
+        Interrupt enable bit.
+            0: Timer interrupt disabled
+            1: Timer interrupt enabled
+    */
+    TIMER_INTERRUPT_ENABLE = 5,
+
+    /*
+        Timer enable.
+            0: Disabled
+            1: Enabled
+    */
+    TIMER_ENABLE = 7,
+
+    /*
+        Timer behaviour when ARM is in debug halt mode:
+            0: Timers keep running
+            1: Timers halted.
+    */
+    ARM_DEBUG_HALT = 8,
+
+    /*
+        Whether the free-run counter is enabled.
+            0: Enabled
+            1: Disabled
+     */
+    FREE_RUN_ENABLE = 9,
+
+    /*
+        Free running scalar.  8 bits wide.  Reset value is 0x3E
+        Freq = clk/(prescale + 1)
+     */
+    FREE_RUN_PRESCALE = 16
+} control_reg;
+
+#define LOAD_WIDTH 32
+#define VALUE_WIDTH 32
+#define CTRL_WIDTH 24
+#define IRQ_CLEAR_WIDTH 32
+#define RAW_IRQ_WIDTH 1
+#define MASKED_IRQ_WIDTH 1
+#define PRE_DIVIDER_WIDTH 10
+
+#define TIMER_BASE_OFFSET 0x400
+
+int spt_start(spt_t *spt)
+{
+    if (spt == NULL) {
+        return EINVAL;
+    }
+    /* Enable timer */
+    spt->regs->ctrl = BIT(FREE_RUN_ENABLE) | BIT(COUNTER_WIDTH_BIT);
+    return 0;
+}
+
+int spt_stop(spt_t *spt)
+{
+    if (!spt) {
+        return EINVAL;
+    }
+    /* Disable timer */
+    spt->regs->ctrl = 0;
+    return 0;
+}
+
+/* Set up the timer to fire an interrupt every ns nanoseconds.
+ * The first such interrupt may arrive before ns nanoseconds
+ * have passed since calling. */
+int spt_set_timeout(spt_t *spt, uint64_t ns)
+{
+    if (!spt) {
+        return EINVAL;
+    }
+    uint64_t ticks = ns / (NS_IN_US / (spt->freq / MHZ));
+    uint32_t prescale_bits = 0;
+    spt->counter_start = ns;
+    if (ticks == 0) {
+        ZF_LOGE("ns too low: %lu\n", ns);
+        return EINVAL;
+    }
+
+    /* Prescale only has 3 values, so we need to calculate them here */
+    if (ticks >= (UINT32_MAX + 1)) {
+        ticks /= 16;
+        if (ticks >= (1ULL << 32)) {
+            ticks /= 16;
+            if (ticks >= (1ULL << 32)) {
+                ZF_LOGE("ns too high: %lu\n", ns);
+                return EINVAL;
+            } else {
+                prescale_bits = 2;
+            }
+        } else {
+            prescale_bits = 1;
+        }
+    }
+
+    /* Configure timer */
+    spt->regs->load = ticks;
+    spt->regs->pre_divider = 0;
+    spt->regs->irq_clear = 1;
+    spt->regs->ctrl = BIT(COUNTER_WIDTH_BIT) | (prescale_bits << PRESCALE_BIT) |
+                      BIT(TIMER_INTERRUPT_ENABLE) | BIT(FREE_RUN_ENABLE) | BIT(TIMER_ENABLE);
+
+    return 0;
+}
+
+int spt_handle_irq(spt_t *spt)
+{
+    if (!spt) {
+        return EINVAL;
+    }
+    if (spt->regs->masked_irq) {
+        spt->regs->irq_clear = 1;
+        spt->regs->ctrl &= ~(BIT(TIMER_ENABLE));
+    } else {
+        ZF_LOGW("handle irq called when no interrupt pending\n");
+        return EINVAL;
+    }
+    return 0;
+}
+
+uint64_t spt_get_time(spt_t *spt)
+{
+    uint64_t value = spt->regs->free_run_count;
+    /* convert raw count to ns. As we never change the free run prescaler we do not need to
+     * scale by it. We multiplly by mhz as the free run count is a 32-bit value so we will
+     * not overflow a 64-bit value at that point */
+    uint64_t ns = (value * MHZ / spt->freq) * NS_IN_US;
+    return ns;
+}
+
+int spt_init(spt_t *spt, spt_config_t config)
+{
+    clk_t *clk;
+
+    if (!spt || !config.vaddr) {
+        return EINVAL;
+    }
+
+    /* Save the mmio address */
+    spt->regs = (void *)((uintptr_t) config.vaddr) + TIMER_BASE_OFFSET;
+    clock_sys_t clk_sys;
+    clock_sys_init_default(&clk_sys);
+    clk = clk_get_clock(&clk_sys, CLK_SP804);
+    spt->freq = clk_get_freq(clk);
+
+    /* handle any pending irqs */
+    spt_handle_irq(spt);
+    return 0;
+}
diff --git a/libplatsupport/src/plat/bcm2711/system_timer.c b/libplatsupport/src/plat/bcm2711/system_timer.c
new file mode 100644
index 0000000..83f132d
--- /dev/null
+++ b/libplatsupport/src/plat/bcm2711/system_timer.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright (C) 2021, Hensoldt Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#include <errno.h>
+#include <stdlib.h>
+#include <utils/util.h>
+#include "../../arch/arm/clock.h"
+#include <platsupport/timer.h>
+#include <platsupport/plat/system_timer.h>
+
+/*
+ * The system timer on the BCM2711 does not differ from the system timer
+ * on older BCM283x platforms. Thus, system timer settings were copied from
+ * the bcm2837 platform port.
+ * The system timer on the BCM283[5-7] is fairly simple in its nature.
+ * It has a 64-bit free-running counter and 4 compare registers. When
+ * the lower 32 bits of the free-running counter match one of the
+ * compare registers, an associated IRQ is generated and an associated
+ * control bit is set in the control register.
+ */
+
+int system_timer_init(system_timer_t *timer, system_timer_config_t config)
+{
+    if (timer == NULL || config.vaddr == NULL) {
+        return EINVAL;
+    }
+
+    timer->regs = config.vaddr;
+
+    return 0;
+}
+
+uint64_t system_timer_get_time(system_timer_t *timer)
+{
+    if (timer == NULL) {
+        return EINVAL;
+    }
+
+    uint64_t initial_high = timer->regs->counter_high;
+    uint64_t low = timer->regs->counter_low;
+    uint64_t high = timer->regs->counter_high;
+    if (high != initial_high) {
+        /* get low again if high has ticked over. */
+        low = timer->regs->counter_low;
+    }
+
+    uint64_t ticks = (high << 32) | low;
+    uint64_t time = ticks * SYSTEM_TIMER_NS_PER_TICK;
+
+    return time;
+}
+
+int system_timer_set_timeout(system_timer_t *timer, uint64_t ns)
+{
+    if (timer == NULL) {
+        return EINVAL;
+    }
+
+    /* Can only set a timeout within the next 2^32 microseconds. */
+    uint64_t time = system_timer_get_time(timer);
+    uint64_t ticks = time / SYSTEM_TIMER_NS_PER_TICK;
+    uint64_t timeout_ticks = ns / SYSTEM_TIMER_NS_PER_TICK;
+    if (timeout_ticks < ticks) {
+        ZF_LOGE("Timeout in the past\n");
+        return ETIME;
+    } else if ((timeout_ticks - ticks) > UINT32_MAX) {
+        ZF_LOGE("Timeout too far in the future\n");
+        return ETIME;
+    }
+
+    /* Clear any existing interrupt. */
+    timer->regs->ctrl = BIT(SYSTEM_TIMER_MATCH);
+
+    uint32_t timeout = timeout_ticks & MASK(32);
+    timer->regs->compare[SYSTEM_TIMER_MATCH] = timeout;
+
+    time = system_timer_get_time(timer);
+    if (time >= ns && !(timer->regs->ctrl & BIT(SYSTEM_TIMER_MATCH))) {
+        timer->regs->ctrl = BIT(SYSTEM_TIMER_MATCH);
+        ZF_LOGE("Timeout missed\n");
+        return ETIME;
+    }
+
+    return 0;
+}
+
+int system_timer_handle_irq(system_timer_t *timer)
+{
+    if (timer == NULL) {
+        return EINVAL;
+    }
+
+    timer->regs->ctrl = BIT(SYSTEM_TIMER_MATCH);
+
+    return 0;
+}
+
+int system_timer_reset(system_timer_t *timer)
+{
+    if (timer == NULL) {
+        return EINVAL;
+    }
+
+    /* Just clear the one timer that is used. */
+    timer->regs->ctrl = BIT(SYSTEM_TIMER_MATCH);
+
+    return 0;
+}
diff --git a/libplatsupport/src/plat/bcm2837/chardev.c b/libplatsupport/src/plat/bcm2837/chardev.c
index f895518..e3753bd 100644
--- a/libplatsupport/src/plat/bcm2837/chardev.c
+++ b/libplatsupport/src/plat/bcm2837/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libplatsupport/src/plat/bcm2837/clock.c b/libplatsupport/src/plat/bcm2837/clock.c
index a110c8e..a46fa22 100644
--- a/libplatsupport/src/plat/bcm2837/clock.c
+++ b/libplatsupport/src/plat/bcm2837/clock.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <platsupport/i2c.h>
 
diff --git a/libplatsupport/src/plat/bcm2837/gpio.c b/libplatsupport/src/plat/bcm2837/gpio.c
new file mode 100644
index 0000000..cd8a663
--- /dev/null
+++ b/libplatsupport/src/plat/bcm2837/gpio.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2021, HENSOLDT Cyber GmbH
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <stdint.h>
+#include <utils/util.h>
+#include <platsupport/gpio.h>
+#include <platsupport/plat/gpio.h>
+#include "../../services.h"
+
+#define BCM2837_GPIO_PADDR  0x3f200000
+#define BCM2837_GPIO_SIZE   0x1000
+
+// Registers according to section 6.1 of BCM2835 TRM
+typedef volatile struct bcm2837_gpio_regs {
+    uint32_t gpfsel0;        /* +0x00 */
+    uint32_t gpfsel1;        /* +0x04 */
+    uint32_t gpfsel2;        /* +0x08 */
+    uint32_t gpfsel3;        /* +0x0c */
+    uint32_t gpfsel4;        /* +0x10 */
+    uint32_t gpfsel5;        /* +0x14 */
+    uint32_t unused0;
+    uint32_t gpset0;         /* +0x1c */
+    uint32_t gpset1;         /* +0x20 */
+    uint32_t unused1;
+    uint32_t gpclr0;         /* +0x28 */
+    uint32_t gpclr1;         /* +0x2c */
+    uint32_t unused2;
+    uint32_t gplev0;         /* +0x34 */
+    uint32_t gplev1;         /* +0x38 */
+    uint32_t unused3;
+    uint32_t gpeds0;         /* +0x40 */
+    uint32_t gpeds1;         /* +0x44 */
+    uint32_t unused4;
+    uint32_t gpren0;         /* +0x4c */
+    uint32_t gpren1;         /* +0x50 */
+    uint32_t unused5;
+    uint32_t gpfen0;         /* +0x58 */
+    uint32_t gpfen1;         /* +0x5c */
+    uint32_t unused6;
+    uint32_t gphen0;         /* +0x64 */
+    uint32_t gphen1;         /* +0x68 */
+    uint32_t unused7;
+    uint32_t gplen0;         /* +0x70 */
+    uint32_t gplen1;         /* +0x74 */
+    uint32_t unused8;
+    uint32_t gparen0;        /* +0x7c */
+    uint32_t gparen1;        /* +0x80 */
+    uint32_t unused9;
+    uint32_t gpafen0;        /* +0x88 */
+    uint32_t gpafen1;        /* +0x8c */
+    uint32_t unused10;
+    uint32_t gppud;          /* +0x94 */
+    uint32_t gppudclk0;      /* +0x98 */
+    uint32_t gppudclk1;      /* +0x9c */
+} bcm2837_gpio_regs_t;
+
+static struct bcm2837_gpio {
+    bcm2837_gpio_regs_t *bank[GPIO_NBANKS];
+} gpio_ctx;
+
+static bcm2837_gpio_regs_t *bcm2837_gpio_get_bank(gpio_t *gpio)
+{
+    assert(gpio);
+    assert(gpio->gpio_sys);
+    assert(gpio->gpio_sys->priv);
+    struct bcm2837_gpio *gpio_priv = (struct bcm2837_gpio *)gpio->gpio_sys->priv;
+    int port = 0;
+    return gpio_priv->bank[port];
+}
+
+static int bcm2837_gpio_init(gpio_sys_t *gpio_sys, int id, enum gpio_dir dir, gpio_t *gpio)
+{
+    assert(gpio);
+    assert(gpio_sys);
+    struct bcm2837_gpio *gpio_priv = (struct bcm2837_gpio *)gpio_sys->priv;
+    assert(gpio_priv);
+    if (id < 0 || id > MAX_GPIO_ID) {
+        ZF_LOGE("GPIO Pin ID is not in valid range!");
+        return -1;
+    }
+
+    gpio->id = id;
+    gpio->gpio_sys = gpio_sys;
+
+    return 0;
+}
+
+/*
+ * GPIO set level function
+ *
+ * See BCM2835 TRM, section 6 General Purpose I/O (GPIO):
+ * The bcm2837 SoC features 54 GPIO pins. The level of each of these pins can
+ * be set with the registers gpset0 (0x1c), gpset1 (0x20) and can be cleared
+ * with the registers gpclr0 (0x28), gpclr1 (0x2c). Each bit in one of these
+ * GPIO registers is responsible for setting/clearing the level of a GPIO pin.
+ * Separating the set and clear functions removes the need for read-modify-write
+ * operations.
+ *
+ * A prerequisite for using this function is to configure the respective GPIO
+ * pin to OUT (with the bcm2837_gpio_fsel function).
+ */
+static int bcm2837_gpio_set_level(gpio_t *gpio, enum gpio_level level)
+{
+    bcm2837_gpio_regs_t *bank = bcm2837_gpio_get_bank(gpio);
+    assert(bank);
+    int pin = gpio->id;
+    if (pin < 0 || pin > MAX_GPIO_ID) {
+        ZF_LOGE("GPIO Pin ID is not in valid range!");
+        return -1;
+    }
+
+    volatile uint32_t *paddr = (level == GPIO_LEVEL_HIGH) ? &(bank->gpset0) + (pin / 32)
+                               : &(bank->gpclr0) + (pin / 32);
+    uint8_t shift = (pin % 32);
+    *paddr = (1u << shift);
+
+    return 0;
+}
+
+/*
+ * GPIO read level function
+ *
+ * See BCM2835 TRM, section 6 General Purpose I/O (GPIO):
+ * The bcm2837 SoC features 54 GPIO pins. The level of each of these pins can
+ * be read with the registers gplev0 (0x34) and gplev1 (0x38). Each bit in one
+ * of these GPIO registers is responsible for reading the level of a GPIO pin.
+ * Separating the set and clear functions removes the need for read-modify-write
+ * operations.
+ *
+ * A prerequisite for using this function is to configure the respective GPIO
+ * pin to OUT (with the bcm2837_gpio_fsel function).
+ */
+static int bcm2837_gpio_read_level(gpio_t *gpio)
+{
+    bcm2837_gpio_regs_t *bank = bcm2837_gpio_get_bank(gpio);
+    assert(bank);
+    int pin = gpio->id;
+    if (pin < 0 || pin > MAX_GPIO_ID) {
+        ZF_LOGE("GPIO Pin ID is not in valid range!");
+        return -1;
+    }
+
+    volatile uint32_t *paddr = &(bank->gplev0) + (pin / 32);
+    uint8_t shift = pin % 32;
+    uint32_t value = *paddr;
+
+    return (value & (1u << shift)) ? GPIO_LEVEL_HIGH : GPIO_LEVEL_LOW;
+}
+
+/*
+ * GPIO function select
+ *
+ * See BCM2835 TRM, section 6.1 Register View:
+ * The bcm2837 has 6 GPIO function select registers. Each of these control
+ * registers controls 10 GPIO pins of a total of 54 GPIO pins. As a result each
+ * of these control registers has 10 sets of 3 bits per GPIO pin. Depending on
+ * the mode given, these 3 bits are set accordingly for a specific pin i:
+ *
+ * 000 = GPIO Pin i is an input
+ * 001 = GPIO Pin i is an output
+ * 100 = GPIO Pin i takes alternate function 0
+ * 101 = GPIO Pin i takes alternate function 1
+ * 110 = GPIO Pin i takes alternate function 2
+ * 111 = GPIO Pin i takes alternate function 3
+ * 011 = GPIO Pin i takes alternate function 4
+ * 010 = GPIO Pin i takes alternate function 5
+ *
+ * To calculate the 3 bits for Pin i use the following formula:
+ *      i / 10 + ((i % 10) * 3)
+ */
+int bcm2837_gpio_fsel(gpio_t *gpio, uint8_t mode)
+{
+    bcm2837_gpio_regs_t *bank = bcm2837_gpio_get_bank(gpio);
+    assert(bank);
+    int pin = gpio->id;
+    if (pin < 0 || pin > MAX_GPIO_ID) {
+        ZF_LOGE("GPIO Pin ID is not in valid range!");
+        return -1;
+    }
+
+    volatile uint32_t *paddr = &(bank->gpfsel0) + (pin / 10);
+    uint8_t  shift = (pin % 10) * 3;
+    uint32_t mask  = BCM2837_GPIO_FSEL_MASK << shift;
+    uint32_t value = mode << shift;
+
+    uint32_t v = *paddr;
+    v = (v & ~mask) | (value & mask);
+    *paddr = v;
+
+    return 0;
+}
+
+int bcm2837_gpio_init_common(gpio_sys_t *gpio_sys)
+{
+    gpio_sys->priv = (void *)&gpio_ctx;
+    gpio_sys->set_level = &bcm2837_gpio_set_level;
+    gpio_sys->read_level = &bcm2837_gpio_read_level;
+    gpio_sys->init = &bcm2837_gpio_init;
+    return 0;
+}
+
+int bcm2837_gpio_sys_init(void *bank1, gpio_sys_t *gpio_sys)
+{
+    if (bank1 != NULL) {
+        gpio_ctx.bank[GPIO_BANK1] = bank1;
+    }
+    return bcm2837_gpio_init_common(gpio_sys);
+}
+
+int gpio_sys_init(ps_io_ops_t *io_ops, gpio_sys_t *gpio_sys)
+{
+    MAP_IF_NULL(io_ops, BCM2837_GPIO, gpio_ctx.bank[0]);
+    return bcm2837_gpio_init_common(gpio_sys);
+}
diff --git a/libplatsupport/src/plat/bcm2837/ltimer.c b/libplatsupport/src/plat/bcm2837/ltimer.c
index 4c04a3d..7f0b620 100644
--- a/libplatsupport/src/plat/bcm2837/ltimer.c
+++ b/libplatsupport/src/plat/bcm2837/ltimer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 /* Implementation of a logical timer for omap platforms
  *
diff --git a/libplatsupport/src/plat/bcm2837/serial.c b/libplatsupport/src/plat/bcm2837/serial.c
index bba8108..b7ca835 100644
--- a/libplatsupport/src/plat/bcm2837/serial.c
+++ b/libplatsupport/src/plat/bcm2837/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdlib.h>
diff --git a/libplatsupport/src/plat/bcm2837/serial.h b/libplatsupport/src/plat/bcm2837/serial.h
index 8906364..1c856b3 100644
--- a/libplatsupport/src/plat/bcm2837/serial.h
+++ b/libplatsupport/src/plat/bcm2837/serial.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include "../../chardev.h"
diff --git a/libplatsupport/src/plat/bcm2837/spt.c b/libplatsupport/src/plat/bcm2837/spt.c
index 85e9706..059400f 100644
--- a/libplatsupport/src/plat/bcm2837/spt.c
+++ b/libplatsupport/src/plat/bcm2837/spt.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdio.h>
diff --git a/libplatsupport/src/plat/bcm2837/system_timer.c b/libplatsupport/src/plat/bcm2837/system_timer.c
index 036471d..b4ae673 100644
--- a/libplatsupport/src/plat/bcm2837/system_timer.c
+++ b/libplatsupport/src/plat/bcm2837/system_timer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <errno.h>
 #include <stdlib.h>
diff --git a/libplatsupport/src/plat/exynos4/clock.c b/libplatsupport/src/plat/exynos4/clock.c
index 8ebe86a..5b69213 100644
--- a/libplatsupport/src/plat/exynos4/clock.c
+++ b/libplatsupport/src/plat/exynos4/clock.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include "../../common.h"
diff --git a/libplatsupport/src/plat/exynos4/mux.c b/libplatsupport/src/plat/exynos4/mux.c
index 5984a6f..9514bd6 100644
--- a/libplatsupport/src/plat/exynos4/mux.c
+++ b/libplatsupport/src/plat/exynos4/mux.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include "../../mach/exynos/mux.h"
diff --git a/libplatsupport/src/plat/exynos4/src.c b/libplatsupport/src/plat/exynos4/src.c
index 69312eb..9a633ba 100644
--- a/libplatsupport/src/plat/exynos4/src.c
+++ b/libplatsupport/src/plat/exynos4/src.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <platsupport/src.h>
 #include "../../services.h"
diff --git a/libplatsupport/src/plat/exynos5/clock.c b/libplatsupport/src/plat/exynos5/clock.c
index b6d47ca..1ca0833 100644
--- a/libplatsupport/src/plat/exynos5/clock.c
+++ b/libplatsupport/src/plat/exynos5/clock.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include "../../arch/arm/clock.h"
 #include "../../mach/exynos/clock.h"
diff --git a/libplatsupport/src/plat/exynos5/exynos_5422_clock.h b/libplatsupport/src/plat/exynos5/exynos_5422_clock.h
index 1f090af..a6a336d 100644
--- a/libplatsupport/src/plat/exynos5/exynos_5422_clock.h
+++ b/libplatsupport/src/plat/exynos5/exynos_5422_clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/src/plat/exynos5/exynos_common_clock.h b/libplatsupport/src/plat/exynos5/exynos_common_clock.h
index 8f7068e..6c0643b 100644
--- a/libplatsupport/src/plat/exynos5/exynos_common_clock.h
+++ b/libplatsupport/src/plat/exynos5/exynos_common_clock.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/src/plat/exynos5/mux.c b/libplatsupport/src/plat/exynos5/mux.c
index 90d5709..d503dbb 100644
--- a/libplatsupport/src/plat/exynos5/mux.c
+++ b/libplatsupport/src/plat/exynos5/mux.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include "../../mach/exynos/mux.h"
 #include <platsupport/gpio.h>
diff --git a/libplatsupport/src/plat/exynos5/sysreg.c b/libplatsupport/src/plat/exynos5/sysreg.c
index 9dbadf9..38679c0 100644
--- a/libplatsupport/src/plat/exynos5/sysreg.c
+++ b/libplatsupport/src/plat/exynos5/sysreg.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <platsupport/plat/sysreg.h>
 #include "../../services.h"
diff --git a/libplatsupport/src/plat/fvp/chardev.c b/libplatsupport/src/plat/fvp/chardev.c
index a6ebd10..a0073d7 100644
--- a/libplatsupport/src/plat/fvp/chardev.c
+++ b/libplatsupport/src/plat/fvp/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libplatsupport/src/plat/fvp/clock_mux.c b/libplatsupport/src/plat/fvp/clock_mux.c
index edd7cdf..23a3c0b 100644
--- a/libplatsupport/src/plat/fvp/clock_mux.c
+++ b/libplatsupport/src/plat/fvp/clock_mux.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/mux.h>
diff --git a/libplatsupport/src/plat/fvp/ltimer.c b/libplatsupport/src/plat/fvp/ltimer.c
index c99324d..6ec6cdb 100644
--- a/libplatsupport/src/plat/fvp/ltimer.c
+++ b/libplatsupport/src/plat/fvp/ltimer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <stdio.h>
 #include <assert.h>
diff --git a/libplatsupport/src/plat/fvp/serial.c b/libplatsupport/src/plat/fvp/serial.c
index 910a9c2..5b8db1a 100644
--- a/libplatsupport/src/plat/fvp/serial.c
+++ b/libplatsupport/src/plat/fvp/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* Mostly copy/paste from the HiKey plat.
diff --git a/libplatsupport/src/plat/fvp/sp804.c b/libplatsupport/src/plat/fvp/sp804.c
index cc87fae..71ef268 100644
--- a/libplatsupport/src/plat/fvp/sp804.c
+++ b/libplatsupport/src/plat/fvp/sp804.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <stdio.h>
 #include <assert.h>
diff --git a/libplatsupport/src/plat/hifive/chardev.c b/libplatsupport/src/plat/hifive/chardev.c
index 9a08434..8a2e763 100644
--- a/libplatsupport/src/plat/hifive/chardev.c
+++ b/libplatsupport/src/plat/hifive/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libplatsupport/src/plat/hifive/ltimer.c b/libplatsupport/src/plat/hifive/ltimer.c
index b0ccbb7..ba145d6 100644
--- a/libplatsupport/src/plat/hifive/ltimer.c
+++ b/libplatsupport/src/plat/hifive/ltimer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 /* Implementation of a logical timer for HiFive Unleashed platform.
  *
diff --git a/libplatsupport/src/plat/hifive/pwm.c b/libplatsupport/src/plat/hifive/pwm.c
index 87bee7f..464be62 100644
--- a/libplatsupport/src/plat/hifive/pwm.c
+++ b/libplatsupport/src/plat/hifive/pwm.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdio.h>
diff --git a/libplatsupport/src/plat/hifive/uart.c b/libplatsupport/src/plat/hifive/uart.c
index 547163f..b6abdcb 100644
--- a/libplatsupport/src/plat/hifive/uart.c
+++ b/libplatsupport/src/plat/hifive/uart.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <autoconf.h>
diff --git a/libplatsupport/src/plat/hikey/chardev.c b/libplatsupport/src/plat/hikey/chardev.c
index 65fbd9f..71cc0f9 100644
--- a/libplatsupport/src/plat/hikey/chardev.c
+++ b/libplatsupport/src/plat/hikey/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libplatsupport/src/plat/hikey/dmt.c b/libplatsupport/src/plat/hikey/dmt.c
index 031ca9c..26f83ca 100644
--- a/libplatsupport/src/plat/hikey/dmt.c
+++ b/libplatsupport/src/plat/hikey/dmt.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <stdio.h>
 #include <assert.h>
diff --git a/libplatsupport/src/plat/hikey/ltimer.c b/libplatsupport/src/plat/hikey/ltimer.c
index b20b262..355d264 100644
--- a/libplatsupport/src/plat/hikey/ltimer.c
+++ b/libplatsupport/src/plat/hikey/ltimer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <stdio.h>
 #include <assert.h>
diff --git a/libplatsupport/src/plat/hikey/rtc.c b/libplatsupport/src/plat/hikey/rtc.c
index 7fb1632..51d06a7 100644
--- a/libplatsupport/src/plat/hikey/rtc.c
+++ b/libplatsupport/src/plat/hikey/rtc.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdio.h>
diff --git a/libplatsupport/src/plat/hikey/serial.c b/libplatsupport/src/plat/hikey/serial.c
index 7d57819..e9f30d7 100644
--- a/libplatsupport/src/plat/hikey/serial.c
+++ b/libplatsupport/src/plat/hikey/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <string.h>
diff --git a/libplatsupport/src/plat/imx31/chardev.c b/libplatsupport/src/plat/imx31/chardev.c
deleted file mode 100644
index a4fe120..0000000
--- a/libplatsupport/src/plat/imx31/chardev.c
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
- *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
- */
-
-/*
- * Contains definitions for all character devices on this
- * platform
- */
-
-#include "../../chardev.h"
-#include "../../common.h"
-#include <platsupport/serial.h>
-
-static const int uart1_irqs[] = {UART1_IRQ, -1};
-static const int uart2_irqs[] = {UART2_IRQ, -1};
-static const int uart3_irqs[] = {UART3_IRQ, -1};
-static const int uart4_irqs[] = {UART4_IRQ, -1};
-static const int uart5_irqs[] = {UART5_IRQ, -1};
-
-#define UART_DEFN(devid) {                     \
-        .id      = IMX31_UART##devid,          \
-        .paddr   = UART##devid##_PADDR,        \
-        .size    = (1<<12),                    \
-        .irqs    = uart##devid##_irqs,         \
-        .init_fn = &uart_init                  \
-    }
-
-static const struct dev_defn dev_defn[] = {
-    UART_DEFN(1),
-    UART_DEFN(2),
-    UART_DEFN(3),
-    UART_DEFN(4),
-    UART_DEFN(5)
-};
-
-/* It would be nice to reuse this, but it requires knowledge of the variable *
- * sized 'dev_defn'                                                          */
-struct ps_chardevice*
-ps_cdev_init(enum chardev_id id, const ps_io_ops_t* o,
-             struct ps_chardevice* d) {
-    unsigned int i;
-    for (i = 0; i < ARRAY_SIZE(dev_defn); i++) {
-        if (dev_defn[i].id == id) {
-            return (dev_defn[i].init_fn(dev_defn + i, o, d)) ? NULL : d;
-        }
-    }
-    return NULL;
-}
diff --git a/libplatsupport/src/plat/imx31/clock.c b/libplatsupport/src/plat/imx31/clock.c
deleted file mode 100644
index e50cd74..0000000
--- a/libplatsupport/src/plat/imx31/clock.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
- *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
- */
-#include "../../arch/arm/clock.h"
-#include "../../services.h"
-#include <assert.h>
-#include <string.h>
-#include <utils/util.h>
-
-static volatile struct clock_regs {
-    int dummy;
-} clk_regs;
-
-static int
-imx31_gate_enable(clock_sys_t* clock_sys, enum clock_gate gate, enum clock_gate_mode mode)
-{
-    return -1;
-}
-
-int
-clock_sys_init(ps_io_ops_t* o, clock_sys_t* clock_sys)
-{
-    clock_sys->priv = (void*)&clk_regs;
-    clock_sys->get_clock = &ps_get_clock;
-    clock_sys->gate_enable = &imx31_gate_enable;
-    return 0;
-}
-
-void
-clk_print_clock_tree(clock_sys_t* sys)
-{
-    clk_t *clk = clk_get_clock(sys, CLK_MASTER);
-    clk_print_tree(clk, "");
-}
-
-static struct clock master_clk = { CLK_OPS_DEFAULT(MASTER) };
-
-clk_t* ps_clocks[] = {
-    [CLK_MASTER]   = &master_clk,
-};
-
-freq_t ps_freq_default[] = {
-    [CLK_MASTER]   = 24 * MHZ,
-};
diff --git a/libplatsupport/src/plat/imx31/mux.c b/libplatsupport/src/plat/imx31/mux.c
deleted file mode 100644
index c6774c2..0000000
--- a/libplatsupport/src/plat/imx31/mux.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
- *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
- */
-#include <stdint.h>
-#include <utils/attribute.h>
-#include <platsupport/mux.h>
-#include "../../services.h"
-
-struct imx31_mux_regs {
-    int dummy;
-};
-
-static struct imx31_mux {
-    volatile struct imx31_mux_regs*    mux;
-} _mux;
-
-static inline struct imx31_mux* get_mux_priv(mux_sys_t* mux) {
-    return (struct imx31_mux*)mux->priv;
-}
-
-static inline void set_mux_priv(mux_sys_t* mux, struct imx31_mux* imx31_mux)
-{
-    assert(mux != NULL);
-    assert(imx31_mux != NULL);
-    mux->priv = imx31_mux;
-}
-
-static int
-imx31_mux_feature_enable(mux_sys_t* mux, mux_feature_t mux_feature, UNUSED enum mux_gpio_dir mgd)
-{
-    struct imx31_mux* m;
-    if (mux == NULL || mux->priv == NULL) {
-        return -1;
-    }
-    m = get_mux_priv(mux);
-
-    switch (mux_feature) {
-    default:
-        (void)m;
-        return -1;
-    }
-}
-
-static int
-imx31_mux_init_common(mux_sys_t* mux)
-{
-    set_mux_priv(mux, &_mux);
-    mux->feature_enable = &imx31_mux_feature_enable;
-    return 0;
-}
-
-int
-imx31_mux_init(void* bank1,
-               mux_sys_t* mux)
-{
-    (void)bank1;
-    return imx31_mux_init_common(mux);
-}
-
-int
-mux_sys_init(ps_io_ops_t* io_ops, UNUSED void *dependencies, mux_sys_t* mux)
-{
-    (void)io_ops;
-    return imx31_mux_init_common(mux);
-}
diff --git a/libplatsupport/src/plat/imx31/serial.c b/libplatsupport/src/plat/imx31/serial.c
deleted file mode 100644
index e8cd092..0000000
--- a/libplatsupport/src/plat/imx31/serial.c
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
- *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
- */
-
-#include <stdlib.h>
-#include <platsupport/serial.h>
-#include <string.h>
-
-#include "../../chardev.h"
-
-#define IMXUART_DLL             0x000
-#define IMXUART_RHR             0x000 /* UXRD */
-#define IMXUART_THR             0x040 /* UTXD */
-#define IMXUART_UCR1            0x080 /* Control reg */
-
-#define IMXUART_LSR             0x094 /* USR1 -- status reg */
-#define IMXUART_LSR_RXFIFIOE    (1<<9)
-#define IMXUART_LSR_RXOE        (1<<1)
-#define IMXUART_LSR_RXPE        (1<<2)
-#define IMXUART_LSR_RXFE        (1<<3)
-#define IMXUART_LSR_RXBI        (1<<4)
-#define IMXUART_LSR_TXFIFOE     (1<<13)
-#define IMXUART_LSR_TXSRE       (1<<6)
-#define IMXUART_LSR_RXFIFOSTS   (1<<7)
-
-#define UART_RHR_READY_MASK    (BIT(15))
-#define UART_BYTE_MASK           0xFF
-
-#define REG_PTR(base, offset)  ((volatile uint32_t *)((char*)(base) + (offset)))
-
-int uart_getchar(ps_chardevice_t* d)
-{
-    int character = -1;
-    uint32_t data = 0;
-
-    if (*REG_PTR(d->vaddr, IMXUART_LSR) & IMXUART_LSR_RXFIFIOE) {
-        data = *REG_PTR(d->vaddr, IMXUART_RHR);
-        if (data & UART_RHR_READY_MASK) {
-            character = data & UART_BYTE_MASK;
-        }
-    }
-
-    return character;
-}
-
-int uart_putchar(ps_chardevice_t* d, int c)
-{
-    if (*REG_PTR(d->vaddr, IMXUART_LSR) & IMXUART_LSR_TXFIFOE) {
-        *REG_PTR(d->vaddr, IMXUART_THR) = c;
-        if (c == '\n' && (d->flags & SERIAL_AUTO_CR)) {
-            uart_putchar(d, '\r');
-        }
-        return c;
-    } else {
-        return -1;
-    }
-}
-
-static void uart_handle_irq(ps_chardevice_t* d UNUSED)
-{
-    /* TODO */
-}
-
-int
-uart_init(const struct dev_defn* defn,
-          const ps_io_ops_t* ops,
-          ps_chardevice_t* dev)
-{
-
-    void* vaddr = chardev_map(defn, ops);
-    memset(dev, 0, sizeof(*dev));
-    if (vaddr == NULL) {
-        return -1;
-    }
-    dev->id         = defn->id;
-    dev->vaddr      = vaddr;
-    dev->read       = &uart_read;
-    dev->write      = &uart_write;
-    dev->handle_irq = &uart_handle_irq;
-    dev->irqs       = defn->irqs;
-    dev->ioops      = *ops;
-    dev->flags      = SERIAL_AUTO_CR;
-
-    /*
-     * Enable interrupts for receiver
-     */
-    *REG_PTR(dev->vaddr, IMXUART_UCR1) |= IMXUART_LSR_RXFIFIOE;
-    return 0;
-}
diff --git a/libplatsupport/src/plat/imx6/chardev.c b/libplatsupport/src/plat/imx6/chardev.c
index 2c0a1ac..df4a0b4 100644
--- a/libplatsupport/src/plat/imx6/chardev.c
+++ b/libplatsupport/src/plat/imx6/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libplatsupport/src/plat/imx6/clock.c b/libplatsupport/src/plat/imx6/clock.c
index df90152..a7559e9 100644
--- a/libplatsupport/src/plat/imx6/clock.c
+++ b/libplatsupport/src/plat/imx6/clock.c
@@ -1,13 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <platsupport/i2c.h>
 
@@ -23,58 +18,70 @@
 #define CCM_ANALOG_PADDR 0x020C8000
 #define CCM_ANALOG_SIZE      0x1000
 
-/* Generic PLL */
-#define PLL_LOCK          BIT(31)
-#define PLL_BYPASS        BIT(16)
+/* common flags for all PLLs */
+#define PLL_LOCK                BIT(31)
+#define PLL_BYPASS              BIT(16)
+#define PLL_GET_BYPASS_SRC(x)   (((x) >> 14) & 0x3)
+#define PLL_ENABLE              BIT(13)
+#define PLL_PWR_DOWN            BIT(12)
 
-/* SYS PLL */
-#define PLL_ARM_DIV_MASK  0x7F
-#define PLL_ARM_ENABLE    BIT(13)
+/* PLL_ARM (PLL1), up to 1.3 GHz */
+#define PLL_ARM_DIV_MASK        0x7F
+#define PLL_ARM_GET_DIV(x)      ((x) & PLL_ARM_DIV_MASK)
 
-/* ENET PLL */
-#define PLL_ENET_DIV_MASK 0x3
-#define PLL_ENET_ENABLE   BIT(13)
+/* PLL_SYS (also called PLL2 or PLL_528) runs at a fixed multiplier 22 based
+ * on the 24 MHz oscillator to create a 528 MHz a reference clock
+ * (24 MHz * 22 = 528 MHz). Other values than 22 are not supposed to be used.
+ */
+#define PLL_SYS_DIV_MASK        BIT(0)
+#define PLL_SYS_GET_DIV(x)      ((x) & PLL_SYS_DIV_MASK)
 
-/* USB */
-#define PLL_USB_DIV_MASK  0x3
-#define PLL_EN_USB_CLKS   BIT(6)
-#define PLL_USB_ENABLE    BIT(13)
-#define PLL_USB_POWER     BIT(12)
+/* PLL_SYS spread spectrum control (CCM_ANALOG_PLL_SYS_SS) */
+#define PLL_SYS_SS_STOP(x)      (((x) & 0xffff) << 16)
+#define PLL_SYS_SS_EN           BIT(15)
+#define PLL_SYS_SS_STEP(x)      ((x) & 0x7fff)
 
-/* Also known as PLL_SYS */
-#define PLL2_PADDR 0x020C8030
+/* PLL_ENET (PLL6), disabled on reset, runs at a fixed multiplier 20+(5/6)
+ * which based on the 24 MHz oscillator as reference clock gives a 500 MHz clock
+ * (24 MHz * (20+(5/6)) = 500 MHz). This use used to generate the frequencies
+ * 125 MHz (for PCIe and gigabit ethernet), 100 MHz (for SATA) and 50 or 25 MHz
+ * for the external ethernet interface.
+ */
+#define PLL_ENET_ENABLE_100M    BIT(20)
+#define PLL_ENET_ENABLE_125M    BIT(19)
+#define PLL_ENET_DIV_MASK       0x3
+#define PLL_ENET_GET_DIV(x)     ((x) & PLL_ENET_DIV_MASK)
 
-#define PLL2_CTRL_LOCK          BIT(31)
-#define PLL2_CTRL_PDFOFFSET_EN  BIT(18)
-#define PLL2_CTRL_BYPASS        BIT(16)
-#define PLL2_CTRL_BYPASS_SRC(x) ((x) << 14)
-#define PLL2_CTRL_ENABLE        BIT(13)
-#define PLL2_CTRL_PWR_DOWN      BIT(12)
-#define PLL2_CTRL_DIVSEL        BIT(0)
-#define PLL2_SS_STOP(x)         ((x) << 16)
-#define PLL2_SS_EN              BIT(15)
-#define PLL2_SS_STEP(x)         ((x) <<  0)
+/* PLL_USB. There is PLL3 (USB1_PLL or 480 PLL) that runs at a fixed multiplier
+ * 20 and based on the 24 MHz oscillator creates a 480 MHz reference clock
+ * (24 MHz * 20 = 480 MHz). It is used for USB0 PHY (OTG PHY) and also to create
+ * clocks for UART, CAN, other serial interfaces and audio interfaces.
+ * There is also 480_PLL2 (USB2_PLL), which provides clock exclusively to
+ * USB2 PHY (also known as HOST PHY) that also runs at a fixed multiplier of 20
+ * to generate a 480 MHz clock.
+ */
+#define PLL_USB_ENABLE_CLKS     BIT(6)
+#define PLL_USB_DIV_MASK        0x3
+#define PLL_USB_GET_DIV(x)      ((x) & PLL_USB_DIV_MASK)
 
-#define PLL_CLKGATE BIT(31)
-#define PLL_STABLE  BIT(30)
-#define PLL_FRAC(x) ((x) << 24)
+/* clock gating in CCM_CCGRn */
+#define CLKGATE_MODE_OFF        0x0
+#define CLKGATE_MODE_ON_RUN     0x1
+#define CLKGATE_MODE_RESERVED   0x2
+#define CLKGATE_MODE_ON_ALL     0x3
+#define CLKGATE_MODE_MASK       0x3
 
-#define CLKGATE_OFF    0x0
-#define CLKGATE_ON_RUN 0x2
-#define CLKGATE_ON_ALL 0x3
-#define CLKGATE_MASK   CLKGATE_ON_ALL
+/* CCM Clock Output Source (CCM_CCOSR) */
+#define CLKO1_SRC_AHB       0xBU
+#define CLKO1_SRC_IPG       0xCU
+#define CLKO1_SRC_MASK      0xFU /* bit 0-3 */
+#define CLKO1_ENABLE        BIT(7)
+#define CLKO_SEL            BIT(8) /* select CCM_CLKO1 or CCM_CLKO2 */
+#define CLKO2_SRC_MASK      (0x1FU << 16) /* bit 16-20 */
+#define CLKO2_SRC_MMDC_CH0  (0U << 16) /* b00000 for mmdc_ch0_clk_root */
+#define CLKO2_ENABLE        BIT(24)
 
-#define CLKO1_SRC_AHB       (0xBU << 0)
-#define CLKO1_SRC_IPG       (0xCU << 0)
-#define CLKO1_SRC_MASK      (0xFU << 0)
-#define CLKO1_ENABLE        (1U << 7)
-
-#define CLKO2_SRC_MMDC_CH0  (0U << 21)
-#define CLKO2_SRC_MASK      (0x1FU << 16)
-#define CLKO2_ENABLE        (1U << 24)
-#define CLKO_SEL            (1U << 8)
-
-struct ccm_regs {
+typedef volatile struct {
     uint32_t ccr;      /* 0x000 */
     uint32_t ccdr;     /* 0x004 */
     uint32_t csr;      /* 0x008 */
@@ -103,27 +110,27 @@
     uint32_t ccgr[7];  /* 0x068 */
     uint32_t res2[1];
     uint32_t cmeor;    /* 0x088 */
-};
+} ccm_regs_t;
 
-typedef struct {
-    uint32_t val;
-    uint32_t set;
-    uint32_t clr;
-    uint32_t tog;
+typedef volatile struct {
+    uint32_t val;                    /* 0x00 */
+    uint32_t set;                    /* 0x04 */
+    uint32_t clr;                    /* 0x08 */
+    uint32_t tog;                    /* 0x0C */
 } alg_sct_t;
 
-struct ccm_alg_usbphy_regs {
-    alg_sct_t vbus_detect;           /* +0x00 */
-    alg_sct_t chrg_detect;           /* +0x10 */
-    uint32_t vbus_detect_stat;       /* +0x20 */
+typedef volatile struct {
+    alg_sct_t vbus_detect;           /* 0x00 */
+    alg_sct_t chrg_detect;           /* 0x10 */
+    uint32_t vbus_detect_stat;       /* 0x20 */
     uint32_t res0[3];
-    uint32_t chrg_detect_stat;       /* +0x30 */
+    uint32_t chrg_detect_stat;       /* 0x30 */
     uint32_t res1[3];
     uint32_t res2[4];
     alg_sct_t misc;                  /* +0x50 */
-};
+} ccm_alg_usbphy_regs_t;
 
-struct ccm_alg_regs {
+typedef volatile struct {
     /* PLL_ARM */
     alg_sct_t pll_arm;               /* 0x000 */
     /* PLL_USB * 2 */
@@ -162,379 +169,788 @@
     uint32_t  res8[4];
     /* MISC2 */
     alg_sct_t misc2;                 /* 0x170 */
-    uint32_t  res9[11];
-    /* USB phy control - Implemented here for the sake of
-     * componentisation since it shares the same register space */
-    struct ccm_alg_usbphy_regs phy1; /* 0x1a0 */
-    struct ccm_alg_usbphy_regs phy2; /* 0x200 */
+    uint32_t  res9[8];
+    /* USB phy control is implemented here for the sake of componentisation
+     * since it shares the same register space.
+     */
+    ccm_alg_usbphy_regs_t phy[2];    /* 0x1a0, 0x200 */
     uint32_t digprog;                /* 0x260 */
-};
+} ccm_alg_regs_t;
 
-static volatile struct clock_regs {
-    struct ccm_regs     * ccm;
-    struct ccm_alg_regs * alg;
-} clk_regs = {.ccm = NULL, .alg = NULL};
-
-struct pll2_regs {
-    uint32_t ctrl;
-    uint32_t ctrl_s;
-    uint32_t ctrl_c;
-    uint32_t ctrl_t;
-    uint32_t ss;
-    uint32_t res0[3];
-    uint32_t num;
-    uint32_t res1[3];
-    uint32_t denom;
-    uint32_t res2[3];
-};
+static struct {
+    ccm_regs_t     *ccm;
+    ccm_alg_regs_t *alg;
+} clk_regs = { .ccm = NULL, .alg = NULL};
 
 static struct clock master_clk = { CLK_OPS_DEFAULT(MASTER) };
 
-/* ARM_CLK */
-static freq_t
-_arm_get_freq(clk_t* clk)
+static int change_pll(alg_sct_t *pll, uint32_t div_mask, uint32_t div)
 {
-    uint32_t div;
-    uint32_t fout, fin;
-    div = clk_regs.alg->pll_arm.val;
-    div &= PLL_ARM_DIV_MASK;
-    fin = clk_get_freq(clk->parent);
-    fout = fin * div / 2;
-    return fout;
-}
+    /* div must be within the mask */
+    if (0 != (div & (~div_mask))) {
+        ZF_LOGE("invaid PLL setting, mask=0x%x, div=0x%x", div_mask, div);
+        assert(0);
+        return -1;
+    }
 
-static freq_t
-_arm_set_freq(clk_t* clk, freq_t hz)
-{
-    uint32_t div;
-    uint32_t fin;
-    uint32_t v;
-
-    fin = clk_get_freq(clk->parent);
-    div = 2 * hz / fin;
-    div = INRANGE(54, div, 108);
     /* bypass on during clock manipulation */
-    clk_regs.alg->pll_arm.set = PLL_BYPASS;
-    /* Set the divisor */
-    v = clk_regs.alg->pll_arm.val & ~(PLL_ARM_DIV_MASK);
-    v |= div;
-    clk_regs.alg->pll_arm.val = v;
-    /* wait for lock */
-    while (!(clk_regs.alg->pll_arm.val & PLL_LOCK));
+    pll->set = PLL_BYPASS;
+    /* power down the PLL */
+    pll->set = PLL_PWR_DOWN;
+    /* set the divisor */
+    pll->clr = div_mask;
+    pll->set = div;
+    /* power up the PLL */
+    pll->clr = PLL_PWR_DOWN;
+
+    /* Wait for the PLL to stabilize. */
+    for (unsigned int loop_cnt = 0; /* nothing */ ; loop_cnt++) {
+        if (pll->val & PLL_LOCK) {
+            ZF_LOGD("got PLL_LOCK after %u loops", loop_cnt);
+            break;
+        }
+
+        /* The PLL usually stabilizes after a few thousand cycles. On the i.MX6
+         * Saber Light board it takes a bit over 1500 loop iterations. Abort
+         * waiting if the PLL does not stabilize. Leave the bypass as source,
+         * disable the PLL and also disable the output.
+         */
+        if (loop_cnt > 50000) {
+            pll->set = PLL_PWR_DOWN;
+            pll->clr = PLL_ENABLE;
+            ZF_LOGE("waiting for PLL_LOCK aborted");
+            return -1;
+        }
+    }
+
     /* bypass off */
-    clk_regs.alg->pll_arm.clr = PLL_BYPASS;
-    return clk_get_freq(clk);
+    pll-> clr = PLL_BYPASS;
+    /* ensure PLL output is enabled */
+    pll->set = PLL_ENABLE;
+
+    return 0;
 }
 
-static void
-_arm_recal(clk_t* clk UNUSED)
+
+/*
+ *------------------------------------------------------------------------------
+ * ARM_CLK
+ *------------------------------------------------------------------------------
+ */
+
+static freq_t _arm_get_freq(clk_t *clk)
 {
+    if (!clk_regs.alg) {
+        ZF_LOGE("clk_regs.alg is NULL, clocks not initialised properly");
+        return 0;
+    }
+
+    uint32_t v = clk_regs.alg->pll_arm.val;
+
+    /* clock output enabled? */
+    if (!(v & PLL_ENABLE)) {
+        /* we should never be here, because we are running on the ARM core */
+        return 0;
+    }
+
+    if (v & PLL_BYPASS) {
+        /* bypass on
+         * 0x0 source is 24MHz oscillator
+         * 0x1 source is CLK1_N/CLK1_P
+         * 0x2 source is CLK2_N/CLK2_P
+         * 0x3 source is CLK1_N/CLK1_P XOR CLK2_N/CLK2_P
+         */
+        unsigned int src = PLL_GET_BYPASS_SRC(v);
+        switch (src) {
+        case 0:
+            return 24 * MHZ;
+        default:
+            break;
+        }
+        ZF_LOGE("can't determine frequency for PLL_ARM bypass sources %u", src);
+        return 0;
+    }
+
+    /* PLL enabled, but powered down? */
+    if (v & PLL_PWR_DOWN) {
+        /* we should never be here, because we are running on the ARM core */
+        return 0;
+    }
+
+    /* valid divider range 54 to 108, F_out = F_in * div_select / 2 */
+    unsigned int div = PLL_ARM_GET_DIV(v);
+    if ((div < 54) || (div > 108)) {
+        ZF_LOGE("PLL_ARM divider out of valid range 54-108: %u", div);
+    }
+    freq_t f_in = clk_get_freq(clk->parent);
+    return f_in * div / 2;
+}
+
+static freq_t _arm_set_freq(clk_t *clk, freq_t hz)
+{
+    freq_t f_pre = clk_get_freq(clk);
+    ZF_LOGD("change PLL_ARM ('%s') from %u.%06u MHz to %u.%06u MHz",
+            clk->name,
+            (unsigned int)(f_pre / MHZ),
+            (unsigned int)(f_pre % MHZ),
+            (unsigned int)(hz / MHZ),
+            (unsigned int)(hz % MHZ));
+
+    if (!clk_regs.alg) {
+        ZF_LOGE("clk_regs.alg is NULL, clocks not initialised properly");
+        return 0;
+    }
+
+    alg_sct_t *pll = &clk_regs.alg->pll_arm;
+
+    freq_t fin = clk_get_freq(clk->parent);
+    unsigned int div = 2 * hz / fin;
+    if ((div < 54) || (div > 108)) {
+        ZF_LOGE("PLL_ARM divider out of valid range 54-108: %u", div);
+        return 0;
+    }
+
+    int ret = change_pll(pll, PLL_ARM_DIV_MASK, div);
+    if (0 != ret) {
+        ZF_LOGE("PLL_ARM change failed, code %d", ret);
+        return 0;
+    }
+
+    freq_t f_new = clk_get_freq(clk);
+    ZF_LOGD("PLL_ARM now running at %u.%06u MHz",
+            (unsigned int)(f_new / MHZ),
+            (unsigned int)(f_new % MHZ));
+    return f_new;
+}
+
+static void _arm_recal(clk_t *clk UNUSED)
+{
+    ZF_LOGE("PLL_ARM recal is not supported");
     assert(0);
 }
 
-static clk_t*
-_arm_init(clk_t* clk)
+static clk_t *_arm_init(clk_t *clk)
 {
     if (clk->priv == NULL) {
-        clk_t* parent;
+        clk_t *parent;
         parent = clk_get_clock(clk_get_clock_sys(clk), CLK_MASTER);
         clk_register_child(parent, clk);
-        clk->priv = (void*)&clk_regs;
+        clk->priv = (void *)&clk_regs;
     }
     return clk;
 }
 
 static struct clock arm_clk = { CLK_OPS(ARM, arm, NULL) };
 
-/* ENET_CLK */
 
-static freq_t
-_enet_get_freq(clk_t* clk)
+/*
+ *------------------------------------------------------------------------------
+ * ENET_CLK
+ *------------------------------------------------------------------------------
+ */
+
+static freq_t _enet_get_freq(clk_t *clk)
 {
-    uint32_t div;
-    uint32_t fin;
+    if (!clk_regs.alg) {
+        ZF_LOGE("clk_regs.alg is NULL, clocks not initialised properly");
+        return 0;
+    }
 
-    fin = clk_get_freq(clk->parent);
-    div = clk_regs.alg->pll_enet.val;
-    div &= PLL_ENET_DIV_MASK;
+    uint32_t v = clk_regs.alg->pll_enet.val;
+
+    /* clock output enabled? */
+    if (!(v & PLL_ENABLE)) {
+        return 0;
+    }
+
+    if (v & PLL_BYPASS) {
+        /* bypass on
+         * 0x0 source is 24MHz oscillator
+         * 0x1 source is CLK1_N/CLK1_P
+         * 0x2 source is CLK2_N/CLK2_P
+         * 0x3 source is CLK1_N/CLK1_P XOR CLK2_N/CLK2_P
+         */
+        unsigned int src = PLL_GET_BYPASS_SRC(v);
+        switch (src) {
+        case 0:
+            return 24 * MHZ;
+        default:
+            break;
+        }
+        ZF_LOGE("can't determine frequency for PLL_ENET bypass sources %u", src);
+        return 0;
+    }
+
+    /* PLL enabled, but powered down? */
+    if (v & PLL_PWR_DOWN) {
+        return 0;
+    }
+
+    unsigned int div = PLL_ENET_GET_DIV(v);
     switch (div) {
-    case 3:
-        return 5 * fin;
-    case 2:
-        return 4 * fin;
-    case 1:
-        return 2 * fin;
     case 0:
-        return 1 * fin;
+        return  25 * MHZ;
+    case 1:
+        return  50 * MHZ;
+    case 2:
+        return 100 * MHZ;
+    case 3:
+        return 125 * MHZ;
     default:
-        return 0 * fin;
+        break;
     }
+    ZF_LOGE("unsupported PLL_ENET divider %u", v);
+    return 0;
 }
 
-static freq_t
-_enet_set_freq(clk_t* clk, freq_t hz)
+static freq_t _enet_set_freq(clk_t *clk, freq_t hz)
 {
-    uint32_t div, fin;
-    uint32_t v;
-    if (clk_regs.alg == NULL) {
-        return clk_get_freq(clk);
+    freq_t f_pre = clk_get_freq(clk);
+    ZF_LOGD("change PLL_ENET ('%s') from %u.%06u MHz to %u.%06u MHz",
+            clk->name,
+            (unsigned int)(f_pre / MHZ),
+            (unsigned int)(f_pre % MHZ),
+            (unsigned int)(hz / MHZ),
+            (unsigned int)(hz % MHZ));
+
+    if (!clk_regs.alg) {
+        ZF_LOGE("clk_regs.alg is NULL, clocks not initialised properly");
+        return 0;
     }
-    fin = clk_get_freq(clk->parent);
-    if (hz >= 5 * fin) {
+
+#if defined(CONFIG_PLAT_IMX6DQ)
+
+    alg_sct_t *pll = &clk_regs.alg->pll_enet;
+
+    uint32_t div;
+    switch (hz) {
+    case 125 * MHZ:
         div = 3;
-    } else if (hz >= 4 * fin) {
+        break;
+    case 100 * MHZ:
         div = 2;
-    } else if (hz >= 2 * fin) {
+        break;
+    case  50 * MHZ:
         div = 1;
-    } else if (hz >= 1 * fin) {
+        break;
+    case  25 * MHZ:
         div = 0;
-    } else {
-        div = 0;
+        break;
+    default:
+        ZF_LOGE("unsupported PLL_ENET clock frequency %"PRIu64, (uint64_t)hz);
+        return 0;
     }
-    /* bypass on */
-    clk_regs.alg->pll_enet.set = PLL_BYPASS;
-    v = PLL_ENET_ENABLE | PLL_BYPASS;
-    clk_regs.alg->pll_enet.val = v;
-    /* Change the frequency */
-    v = clk_regs.alg->pll_enet.val & ~(PLL_ENET_DIV_MASK);
-    v |= div;
-    clk_regs.alg->pll_enet.val = v;
-    while (!(clk_regs.alg->pll_enet.val & PLL_LOCK));
-    /* bypass off */
-    clk_regs.alg->pll_enet.clr = PLL_BYPASS;
-    printf("Set ENET frequency to %ld Mhz... ", (long int)clk_get_freq(clk) / MHZ);
-    return clk_get_freq(clk);
+
+    // ENET requires ahb_clk_root to be at least 125 MHz. In the clock tree
+    // PLL_SYS feeds CLK_MMDC_CH0 which feeds CLK_AHB. For CLK_AHB the default
+    // divider is 4, set via CBCDR.AHB_PODF, so setting PLL_SYS to the standard
+    // 528 MHz will result in an AHB clock of 132 MHz.
+    clk_t *clk_ahb = clk_get_clock(clk->clk_sys, CLK_AHB);
+    freq_t f_ahb = clk_get_freq(clk_ahb);
+    if (f_ahb < (125 * MHZ)) {
+        ZF_LOGI("AHB clock is %u.%06u MHz (< 125 MHz), setting system PLL to 528 MHz",
+                (unsigned int)(f_ahb / MHZ),
+                (unsigned int)(f_ahb % MHZ));
+        clk_set_freq(clk_get_clock(clk->clk_sys, CLK_PLL2), 528 * MHZ);
+        f_ahb = clk_get_freq(clk_ahb);
+        if (f_ahb < (125 * MHZ)) {
+            ZF_LOGE("AHB clock is %u.%06u Hz, still < 125 MHz)",
+                    (unsigned int)(f_ahb / MHZ),
+                    (unsigned int)(f_ahb % MHZ));
+            return 0;
+        }
+    }
+
+    int ret = change_pll(pll, PLL_ENET_DIV_MASK, div);
+    if (0 != ret) {
+        ZF_LOGE("PLL_ENET change failed, code %d", ret);
+        return 0;
+    }
+
+    clk_gate_enable(clk_get_clock_sys(clk), enet_clock, CLKGATE_ON);
+
+#elif defined(CONFIG_PLAT_IMX6SX)
+
+    /* ENET requires enet_clk_root to be at least 133 MHz. However, we don't do
+     * anything here and just trust u-boot to have set things up properly.
+     *
+     * clk_regs.ccm->chsccdr = 0x00021148
+     *    15:17 Selector for ENET root clock pre-multiplexer, derive clock from
+     *            b000 PLL2
+     *            b001 pll3_sw_clk
+     *            b010 PLL5
+     *            b011 PLL2 PFD0
+     *            b100 PLL2 PFD2
+     *            b101 PLL3 PFD2
+     *            b110-b111 Reserved
+     *    14:12 Divider for ENET clock divider, should be updated when output
+     *          clock is gated. Divider is 1 to 8 calculated as "bxxx +1"
+     *     9:11 ENET root clock multiplexer, derive clock from
+     *            b000 divided pre-muxed ENET clock
+     *            b001 ipp_di0_clk
+     *            b010 ipp_di1_clk
+     *            b011 ldb_di0_clk
+     *            b100 ldb_di1_clk
+     *            b101-b111 Reserved
+     *
+     * CCM_CCGR3 relevant for ENETs:
+     *    18    ENET2_TX_CLK_DIR = 0 (disable ENET2 TX_CLK output driver)
+     *    17    ENET1_TX_CLK_DIR = 1 (enable ENET2 TX_CLK output driver)
+     *    14    ENET2_CLK_SEL = 0 (ENET2 TX reference clock driven by ref_enetpll1)
+     *    13    ENET1_CLK_SEL = 0 (ENET1 TX reference clock driven by ref_enetpll0)
+     *
+     * CCM_ANALOG_PLL_ENETn = 0x8030200f, relevant bits for ENETs:
+     *     31  PLL LOCK = 1
+     *     21  ENET_25M_REF_EN = 1
+     *     20  ENET2_125M_EN = 1
+     *     13  ENET1_125M_EN = 1
+     *     4:5 ENET2_DIV_SELECT = b11 (125 MHZ)
+     *     0:1 ENET1_DIV_SELECT = b11 (125 MHZ)
+     */
+    ZF_LOGW("changing PLL_ENET not is currently not implemented");
+
+#else
+#error "unknown i.MX6 SOC"
+#endif
+
+    freq_t f_new = clk_get_freq(clk);
+    ZF_LOGD("PLL_ENET now running at %u.%06u MHz",
+            (unsigned int)(f_new / MHZ),
+            (unsigned int)(f_new % MHZ));
+    return f_new;
 }
 
-static void
-_enet_recal(clk_t* clk UNUSED)
+static void _enet_recal(clk_t *clk UNUSED)
 {
+    ZF_LOGE("PLL_ENET recal is not supported");
     assert(0);
 }
 
-static clk_t*
-_enet_init(clk_t* clk)
+static clk_t *_enet_init(clk_t *clk)
 {
     if (clk->priv == NULL) {
-        clk_t* parent = clk_get_clock(clk_get_clock_sys(clk), CLK_MASTER);
+        clk_t *parent = clk_get_clock(clk_get_clock_sys(clk), CLK_MASTER);
         clk_register_child(parent, clk);
-        clk->priv = (void*)&clk_regs;
+        clk->priv = (void *)&clk_regs;
     }
     return clk;
 }
 
 static struct clock enet_clk = { CLK_OPS(ENET, enet, NULL) };
 
-/* PLL2_CLK */
-static freq_t
-_pll2_get_freq(clk_t* clk)
-{
-    uint32_t p, s;
-    struct pll2_regs *regs;
-    regs = (struct pll2_regs*)((uint32_t)clk_regs.alg + (PLL2_PADDR & 0xfff));
-    assert((regs->ctrl & PLL2_CTRL_LOCK) != 0);
-    assert((regs->ctrl & PLL2_CTRL_BYPASS) == 0);
-    assert((regs->ctrl & PLL2_CTRL_PWR_DOWN) == 0);
-    /* pdf offset? */
 
-    p = clk_get_freq(clk->parent);
-    if (regs->ctrl & PLL2_CTRL_DIVSEL) {
-        s = 22;
+/*
+ *------------------------------------------------------------------------------
+ * PLL_SYS
+ *------------------------------------------------------------------------------
+ */
+
+static freq_t _pll_sys_get_freq(clk_t *clk)
+{
+    if (!clk_regs.alg) {
+        ZF_LOGE("clk_regs.alg is NULL, clocks not initialised properly");
+        return 0;
+    }
+
+    uint32_t v = clk_regs.alg->pll_sys.val;
+
+    /* clock output enabled? */
+    if (!(v & PLL_ENABLE)) {
+        return 0;
+    }
+
+    if (v & PLL_BYPASS) {
+        /* bypass on
+         * 0x0 source is 24MHz oscillator
+         * 0x1 source is CLK1_N/CLK1_P
+         * 0x2 source is CLK2_N/CLK2_P
+         * 0x3 source is CLK1_N/CLK1_P XOR CLK2_N/CLK2_P
+         */
+        unsigned int src = PLL_GET_BYPASS_SRC(v);
+        switch (src) {
+        case 0:
+            return 24 * MHZ;
+        default:
+            break;
+        }
+        ZF_LOGE("can't determine frequency for PLL_SYS bypass sources %u", src);
+        return 0;
+    }
+
+    /* PLL enabled, but powered down? */
+    if (v & PLL_PWR_DOWN) {
+        return 0;
+    }
+
+    freq_t f_parent = clk_get_freq(clk->parent);
+    unsigned int div = PLL_SYS_GET_DIV(v);
+    switch (div) {
+    case 0:
+        return  f_parent * 20;
+    case 1:
+        return  f_parent * 22;
+    default:
+        break;
+    }
+    ZF_LOGE("unsupported PLL_SYS divisor %u", div);
+    return 0;
+}
+
+static freq_t _pll_sys_set_freq(clk_t *clk, freq_t hz)
+{
+    freq_t f_pre = clk_get_freq(clk);
+    ZF_LOGD("change PLL_SYS ('%s') from %u.%06u MHz to %u.%06u MHz",
+            clk->name,
+            (unsigned int)(f_pre / MHZ),
+            (unsigned int)(f_pre % MHZ),
+            (unsigned int)(hz / MHZ),
+            (unsigned int)(hz % MHZ));
+
+    if (!clk_regs.alg) {
+        ZF_LOGE("clk_regs.alg is NULL, clocks not initialised properly");
+        return 0;
+    }
+
+    alg_sct_t *pll = &clk_regs.alg->pll_sys;
+
+    if (24 * MHZ == hz) {
+        /* bypass PLL and use 24 MHz oscillator */
+        pll->set = PLL_BYPASS;
+        pll->set = PLL_PWR_DOWN;
+        pll->clr = PLL_ENET_DIV_MASK;
+        pll->set = PLL_ENABLE;
     } else {
-        s = 20;
+        uint32_t div;
+        switch (hz) {
+        case 480 * MHZ:
+            div = 0;
+            break; // 480 MHz = 20 * 24 MHz
+        case 528 * MHZ:
+            div = 1;
+            break; // 528 MHz = 22 * 24 MHz
+        default:
+            ZF_LOGE("unsupported PLL_SYS clock frequency %"PRIu64, (uint64_t)hz);
+            return 0;
+        }
+
+        int ret = change_pll(pll, PLL_SYS_DIV_MASK, div);
+        if (0 != ret) {
+            ZF_LOGE("PLL_SYS change failed, code %d", ret);
+            return 0;
+        }
     }
-    return p * s;
+
+    freq_t f_new = clk_get_freq(clk);
+    ZF_LOGD("PLL_SYS now running at %u.%06u MHz",
+            (unsigned int)(f_new / MHZ),
+            (unsigned int)(f_new % MHZ));
+    return f_new;
 }
 
-static freq_t
-_pll2_set_freq(clk_t* clk, freq_t hz)
+static void _pll_sys_recal(clk_t *clk UNUSED)
 {
-    uint32_t s;
-    if (clk_regs.alg == NULL) {
-        return clk_get_freq(clk);
-    }
-    s = hz / clk_get_freq(clk->parent);
-    (void)s; /* TODO implement */
-    assert(hz == 528 * MHZ);
-    return clk_get_freq(clk);
-}
-
-static void
-_pll2_recal(clk_t* clk UNUSED)
-{
+    ZF_LOGE("PLL_SYS recal is not supported");
     assert(0);
 }
 
-static clk_t*
-_pll2_init(clk_t* clk)
+static clk_t *_pll_sys_init(clk_t *clk)
 {
     if (clk->parent == NULL) {
-        clk_t* parent = clk_get_clock(clk_get_clock_sys(clk), CLK_MASTER);
+        clk_t *parent = clk_get_clock(clk_get_clock_sys(clk), CLK_MASTER);
         clk_register_child(parent, clk);
-        clk->priv = (void*)&clk_regs;
+        clk->priv = (void *)&clk_regs;
     }
+
+    // After a reset, the system PLL is not active and the clock signal comes
+    // from the 24 MHz oscillator. We don't reconfigure anything here, enabling
+    // the 528 MHz PLL must be done manually somewhere. Note that if U-Boot is
+    // used, it may have done this already.
+
     return clk;
 }
 
-static struct clock pll2_clk = { CLK_OPS(PLL2, pll2, NULL) };
+static struct clock pll_sys_clk = { CLK_OPS(PLL2, pll_sys, NULL) };
 
-/* MMDC_CH0_CLK */
-static freq_t
-_mmdc_ch0_get_freq(clk_t* clk)
+
+/*
+ *------------------------------------------------------------------------------
+ * MMDC_CH0_CLK
+ *------------------------------------------------------------------------------
+ */
+
+static freq_t _mmdc_ch0_get_freq(clk_t *clk)
 {
     return clk_get_freq(clk->parent);
 }
 
-static freq_t
-_mmdc_ch0_set_freq(clk_t* clk, freq_t hz)
+static freq_t _mmdc_ch0_set_freq(clk_t *clk, freq_t hz)
 {
-    /* TODO there is a mux here */
+    freq_t f_pre = clk_get_freq(clk);
+    ZF_LOGD("change MMDC_CH0_CLK ('%s') from %u.%06u MHz to %u.%06u MHz",
+            clk->name,
+            (unsigned int)(f_pre / MHZ),
+            (unsigned int)(f_pre % MHZ),
+            (unsigned int)(hz / MHZ),
+            (unsigned int)(hz % MHZ));
+
+    /* TODO: there are the two MUXers here:
+     *         - CCM Bus Clock Multiplexer CBCMR.PRE_PERIPH_CLK_SEL
+     *         - CCM Bus Clock Divider CBCDR.PERIPH_CLK_SEL
+     *       by default they route the clock PLL_SYS (PLL2)
+     */
     assert(hz == 528 * MHZ);
-    return clk_set_freq(clk->parent, hz);
+
+    freq_t f_new_parent = clk_set_freq(clk->parent, hz);
+    freq_t f_new = f_new_parent;
+    ZF_LOGD("MMDC_CH0_CLK now running at %u.%06u MHz",
+            (unsigned int)(f_new / MHZ),
+            (unsigned int)(f_new % MHZ));
+    return f_new;
 }
 
-static void
-_mmdc_ch0_recal(clk_t* clk UNUSED)
+static void _mmdc_ch0_recal(clk_t *clk UNUSED)
 {
+    ZF_LOGE("MMDC_CH0_CLK recal is not supported");
     assert(0);
 }
 
-static clk_t*
-_mmdc_ch0_init(clk_t* clk)
+static clk_t *_mmdc_ch0_init(clk_t *clk)
 {
     if (clk->parent == NULL) {
-        clk_t* parent = clk_get_clock(clk_get_clock_sys(clk), CLK_PLL2);
+        clk_t *parent = clk_get_clock(clk_get_clock_sys(clk), CLK_PLL2);
         clk_register_child(parent, clk);
-        clk->priv = (void*)&clk_regs;
+        clk->priv = (void *)&clk_regs;
     }
     return clk;
 }
 
 static struct clock mmdc_ch0_clk = { CLK_OPS(MMDC_CH0, mmdc_ch0, NULL) };
 
-/* AHB_CLK_ROOT */
-static freq_t
-_ahb_get_freq(clk_t* clk)
+
+/*
+ *------------------------------------------------------------------------------
+ * AHB_CLK_ROOT
+ *------------------------------------------------------------------------------
+ */
+
+static freq_t _ahb_get_freq(clk_t *clk)
 {
+    /* ToDo: read divider from CBCDR.AHB_PODF */
     return clk_get_freq(clk->parent) / 4;
 }
 
-static freq_t
-_ahb_set_freq(clk_t* clk, freq_t hz)
+static freq_t _ahb_set_freq(clk_t *clk, freq_t hz)
 {
-    return clk_set_freq(clk->parent, hz * 4);
+    freq_t f_pre = clk_get_freq(clk);
+    ZF_LOGD("change AHB_CLK_ROOT ('%s') from %u.%06u MHz to %u.%06u MHz",
+            clk->name,
+            (unsigned int)(f_pre / MHZ),
+            (unsigned int)(f_pre % MHZ),
+            (unsigned int)(hz / MHZ),
+            (unsigned int)(hz % MHZ));
+
+    /* ToDo: we assume the default value CBCDR.AHB_PODF = b011 has not been
+     * changed and thus the divider is 4 (132 MHZ * 4 = 528 MHz).
+     */
+    assert(hz == 132 * MHZ);
+
+    freq_t f_new_parent = clk_set_freq(clk->parent, hz * 4);
+    freq_t f_new = f_new_parent / 4;
+    ZF_LOGD("AHB_CLK_ROOT now running at %u.%06u MHz",
+            (unsigned int)(f_new / MHZ),
+            (unsigned int)(f_new % MHZ));
+    return f_new;
 }
 
-static void
-_ahb_recal(clk_t* clk UNUSED)
+static void _ahb_recal(clk_t *clk UNUSED)
 {
+    ZF_LOGE("AHB_CLK_ROOT recal is not supported");
     assert(0);
 }
 
-static clk_t*
-_ahb_init(clk_t* clk)
+static clk_t *_ahb_init(clk_t *clk)
 {
     if (clk->parent == NULL) {
-        clk_t* parent = clk_get_clock(clk_get_clock_sys(clk), CLK_MMDC_CH0);
+        clk_t *parent = clk_get_clock(clk_get_clock_sys(clk), CLK_MMDC_CH0);
         clk_register_child(parent, clk);
-        clk->priv = (void*)&clk_regs;
+        clk->priv = (void *)&clk_regs;
     }
     return clk;
 }
 
 static struct clock ahb_clk = { CLK_OPS(AHB, ahb, NULL) };
 
-/* IPG_CLK_ROOT */
-static freq_t
-_ipg_get_freq(clk_t* clk)
+
+/*
+ *------------------------------------------------------------------------------
+ * IPG_CLK_ROOT
+ *------------------------------------------------------------------------------
+ */
+
+static freq_t _ipg_get_freq(clk_t *clk)
 {
     return clk_get_freq(clk->parent) / 2;
 };
 
-static freq_t
-_ipg_set_freq(clk_t* clk, freq_t hz)
+static freq_t _ipg_set_freq(clk_t *clk, freq_t hz)
 {
-    return clk_set_freq(clk->parent, hz * 2);
+    freq_t f_pre = clk_get_freq(clk);
+    ZF_LOGD("change IPG_CLK_ROOT ('%s') from %u.%06u MHz to %u.%06u MHz",
+            clk->name,
+            (unsigned int)(f_pre / MHZ),
+            (unsigned int)(f_pre % MHZ),
+            (unsigned int)(hz / MHZ),
+            (unsigned int)(hz % MHZ));
+
+    freq_t f_new_parent = clk_set_freq(clk->parent, hz * 2);
+    freq_t f_new = f_new_parent / 2;
+    ZF_LOGD("IPG_CLK_ROOT now running at %u.%06u MHz",
+            (unsigned int)(f_new / MHZ),
+            (unsigned int)(f_new % MHZ));
+    return f_new;
 };
 
-static void
-_ipg_recal(clk_t* clk UNUSED)
+static void _ipg_recal(clk_t *clk UNUSED)
 {
+    ZF_LOGE("IPG_CLK_ROOT recal is not supported");
     assert(0);
 }
 
-static clk_t*
-_ipg_init(clk_t* clk)
+static clk_t *_ipg_init(clk_t *clk)
 {
     if (clk->parent == NULL) {
-        clk_t* parent = clk_get_clock(clk_get_clock_sys(clk), CLK_AHB);
+        clk_t *parent = clk_get_clock(clk_get_clock_sys(clk), CLK_AHB);
         clk_register_child(parent, clk);
-        clk->priv = (void*)&clk_regs;
+        clk->priv = (void *)&clk_regs;
     }
     return clk;
 }
 
 static struct clock ipg_clk = { CLK_OPS(IPG, ipg, NULL) };
 
-/* USB_CLK */
-static freq_t
-_usb_get_freq(clk_t* clk)
+
+/*
+ *------------------------------------------------------------------------------
+ * USB_CLK
+ *------------------------------------------------------------------------------
+ */
+
+static freq_t _usb_get_freq(clk_t *clk)
 {
-    volatile alg_sct_t* pll_usb;
-    pll_usb = clk_regs.alg->pll_usb;
-    if (clk->id == CLK_USB2) {
-        pll_usb++;
-    } else if (clk->id != CLK_USB1) {
-        assert(0);
+    unsigned int idx;
+    switch (clk->id) {
+    case CLK_USB1:
+        idx = 0;
+        break;
+    case CLK_USB2:
+        idx = 1;
+        break;
+    default:
+        ZF_LOGE("invalid USB clock ID: %u", clk->id);
         return 0;
     }
-    if (pll_usb->val & ~PLL_BYPASS) {
-        if (pll_usb->val & (PLL_USB_ENABLE | PLL_USB_POWER | PLL_EN_USB_CLKS)) {
-            uint32_t div = (pll_usb->val & PLL_USB_DIV_MASK) ? 22 : 20;
-            return clk_get_freq(clk->parent) * div;
-        }
+
+    if (!clk_regs.alg) {
+        ZF_LOGE("clk_regs.alg is NULL, clocks not initialised properly");
+        return 0;
     }
-    /* Not enabled or in bypass mode...
-     * We should only be in bypass when changing Fout */
+
+    uint32_t v = clk_regs.alg->pll_usb[idx].val;
+
+    /* clock output enabled? */
+    if (!(v & PLL_ENABLE)) {
+        return 0;
+    }
+
+    if (v & PLL_BYPASS) {
+        /* bypass on
+         * 0x0 source is 24MHz oscillator
+         * 0x1 source is CLK1_N/CLK1_P
+         * 0x2 source is CLK2_N/CLK2_P
+         * 0x3 source is CLK1_N/CLK1_P XOR CLK2_N/CLK2_P
+         */
+        unsigned int src = PLL_GET_BYPASS_SRC(v);
+        switch (src) {
+        case 0:
+            return 24 * MHZ;
+        default:
+            break;
+        }
+        ZF_LOGE("can't determine frequency for PLL_USB bypass sources %u", src);
+        return 0;
+    }
+
+    /* PLL enabled, but powered down? */
+    if (v & PLL_PWR_DOWN) {
+        return 0;
+    }
+
+    freq_t f_parent = clk_get_freq(clk->parent);
+    unsigned int div = PLL_USB_GET_DIV(v);
+    switch (div) {
+    case 0:
+        return  f_parent * 20;
+    case 1:
+        return  f_parent * 22;
+    default:
+        break;
+    }
+    ZF_LOGE("unsupported PLL_USB divider %u", v);
     return 0;
 }
 
-static freq_t
-_usb_set_freq(clk_t* clk, freq_t hz UNUSED)
+static freq_t _usb_set_freq(clk_t *clk, freq_t hz UNUSED)
 {
-    assert(!"Not implemented");
-    return clk_get_freq(clk);
+    freq_t f_pre = clk_get_freq(clk);
+    ZF_LOGD("change PLL_USB ('%s') from %u.%06u MHz to %u.%06u MHz",
+            clk->name,
+            (unsigned int)(f_pre / MHZ),
+            (unsigned int)(f_pre % MHZ),
+            (unsigned int)(hz / MHZ),
+            (unsigned int)(hz % MHZ));
+
+    ZF_LOGE("PLL_USB changing is not supported");
+    assert(0);
+
+    return f_pre;
 }
 
-static void
-_usb_recal(clk_t* clk UNUSED)
+static void _usb_recal(clk_t *clk UNUSED)
 {
+    ZF_LOGE("PLL_USB recal is not supported");
     assert(0);
 }
 
-static clk_t*
-_usb_init(clk_t* clk)
+static clk_t *_usb_init(clk_t *clk)
 {
-    volatile alg_sct_t* pll_usb;
     if (clk->parent == NULL) {
-        clk_t* parent = clk_get_clock(clk_get_clock_sys(clk), CLK_MASTER);
+        clk_t *parent = clk_get_clock(clk_get_clock_sys(clk), CLK_MASTER);
         clk_register_child(parent, clk);
-        clk->priv = (void*)&clk_regs;
+        clk->priv = (void *)&clk_regs;
     }
-    if (clk_regs.alg == NULL) {
-        ZF_LOGF("clk_regs.alg is NULL: Clocks likely not initialised properly");
+
+    unsigned int idx;
+    switch (clk->id) {
+    case CLK_USB1:
+        idx = 0;
+        break;
+    case CLK_USB2:
+        idx = 1;
+        break;
+    default:
+        ZF_LOGE("invalid USB clock ID: %u", clk->id);
         return NULL;
     }
+
+    if (!clk_regs.alg) {
+        ZF_LOGE("clk_regs.alg is NULL, clocks not initialised properly");
+        return NULL;
+    }
+    alg_sct_t *pll = &clk_regs.alg->pll_usb[idx];
+
     /* While we are here, gate the clocks */
-    pll_usb = clk_regs.alg->pll_usb;
-    if (clk->id == CLK_USB2) {
-        pll_usb++;
-    } else if (clk->id != CLK_USB1) {
-        assert(0);
-        return NULL;
-    }
-    pll_usb->clr = PLL_BYPASS;
-    pll_usb->set = PLL_USB_ENABLE | PLL_USB_POWER | PLL_EN_USB_CLKS;
+    pll->clr = PLL_BYPASS;
+    pll->set = PLL_ENABLE | PLL_PWR_DOWN | PLL_USB_ENABLE_CLKS;
     clk_gate_enable(clk_get_clock_sys(clk), usboh3, CLKGATE_ON);
     return clk;
 }
@@ -542,65 +958,87 @@
 static struct clock usb1_clk = { CLK_OPS(USB1, usb, NULL) };
 static struct clock usb2_clk = { CLK_OPS(USB2, usb, NULL) };
 
-/* clkox */
-static freq_t
-_clko_get_freq(clk_t* clk)
+
+/*
+ *------------------------------------------------------------------------------
+ * CLK_Ox
+ *------------------------------------------------------------------------------
+ */
+
+static int get_clko_bit_offset(unsigned int id)
 {
-    uint32_t fin = clk_get_freq(clk->parent);
-    uint32_t div;
-    switch (clk->id) {
+    switch (id) {
     case CLK_CLKO1:
-        div = (clk_regs.ccm->ccosr >> 4) & 0x7;
-        break;
+        return 4;
     case CLK_CLKO2:
-        div = (clk_regs.ccm->ccosr >> 21) & 0x7;
-        break;
-    default:
-        assert(!"Invalid clock");
-        return -1;
+        return 21;
     }
-    return fin / (div + 1);
+
+    ZF_LOGE("Invalid CLK_Ox id 0x%x", id);
+    return -1;
 }
 
-static freq_t
-_clko_set_freq(clk_t* clk, freq_t hz)
+static freq_t _clko_get_freq(clk_t *clk)
 {
-    uint32_t fin = clk_get_freq(clk->parent);
-    uint32_t div = (fin / hz) + 1;
-    uint32_t v = clk_regs.ccm->ccosr;
+    int shift = get_clko_bit_offset(clk->id);
+    if (shift < 0) {
+        ZF_LOGE("could not get CLK_Ox 0x%x clock bit offset", clk->id);
+        return 0;
+    }
+
+    uint32_t div = (clk_regs.ccm->ccosr >> shift) & 0x7;
+    freq_t f_parent = clk_get_freq(clk->parent);
+
+    return f_parent / (div + 1);
+}
+
+static freq_t _clko_set_freq(clk_t *clk, freq_t hz)
+{
+    freq_t f_pre = clk_get_freq(clk);
+    ZF_LOGD("change CLK_Ox ('%s') from %u.%06u MHz to %u.%06u MHz",
+            clk->name,
+            (unsigned int)(f_pre / MHZ),
+            (unsigned int)(f_pre % MHZ),
+            (unsigned int)(hz / MHZ),
+            (unsigned int)(hz % MHZ));
+
+    int shift = get_clko_bit_offset(clk->id);
+    if (shift < 0) {
+        ZF_LOGE("could not get CLK_Ox 0x%x clock bit offset", clk->id);
+        return 0;
+    }
+
+    freq_t f_parent = clk_get_freq(clk->parent);
+    uint32_t div = (f_parent / hz) + 1;
     if (div > 0x7) {
+        ZF_LOGW("required CLK_Ox clock divisor %u not possible, using max possible value 7", div);
         div = 0x7;
     }
-    switch (clk->id) {
-    case CLK_CLKO1:
-        v &= ~(0x7U << 4);
-        v |= div << 4;
-        break;
-    case CLK_CLKO2:
-        v &= ~(0x7U << 21);
-        v |= div << 21;
-        break;
-    default:
-        assert(!"Invalid clock");
-        return -1;
-    }
+
+    uint32_t v = clk_regs.ccm->ccosr;
+    v &= ~(0x7U << shift);
+    v |= div << shift;
     clk_regs.ccm->ccosr = v;
-    return clk_get_freq(clk);
+
+    freq_t f_new = clk_get_freq(clk);
+    ZF_LOGD("CLK_Ox now running at %u.%06u MHz",
+            (unsigned int)(f_new / MHZ),
+            (unsigned int)(f_new % MHZ));
+    return f_new;
 }
 
-static void
-_clko_recal(clk_t* clk UNUSED)
+static void _clko_recal(clk_t *clk UNUSED)
 {
+    ZF_LOGE("CLK_Ox recal is not supported");
     assert(0);
 }
 
-static clk_t*
-_clko_init(clk_t* clk)
+static clk_t *_clko_init(clk_t *clk)
 {
     assert(clk_get_clock_sys(clk));
     if (clk->parent == NULL) {
         /* We currently only support 1 src, but there are many to choose from */
-        clk_t* parent;
+        clk_t *parent;
         uint32_t v = clk_regs.ccm->ccosr;
         switch (clk->id) {
         case CLK_CLKO1:
@@ -622,7 +1060,8 @@
             v |= CLKO2_ENABLE;
             break;
         default:
-            assert(!"Invalid clock for operation");
+            ZF_LOGE("Invalid CLK_Ox clock id 0x%x", clk->id);
+            assert(0);
             return NULL;
         }
         clk_regs.ccm->ccosr = v;
@@ -634,45 +1073,70 @@
 static struct clock clko1_clk = { CLK_OPS(CLKO1, clko, NULL) };
 static struct clock clko2_clk = { CLK_OPS(CLKO2, clko, NULL) };
 
-static int
-imx6_gate_enable(clock_sys_t* clock_sys, enum clock_gate gate, enum clock_gate_mode mode)
+static int imx6_gate_enable(
+    clock_sys_t *clock_sys,
+    enum clock_gate gate,
+    enum clock_gate_mode mode)
 {
     assert(clk_regs.ccm);
-    assert(mode == CLKGATE_ON);
-    (void)assert(gate >= 0);
-    assert(gate < 112);
 
-    uint32_t v;
-    uint32_t reg = gate / 16;
+    if (gate > 112) {
+        ZF_LOGE("invalid gate %d", gate);
+        return -1;
+    }
+
+    uint32_t m;
+    switch (mode) {
+    case CLKGATE_ON:
+        m = CLKGATE_MODE_ON_ALL;
+        break;
+
+    case CLKGATE_IDLE:
+        ZF_LOGE("CLKGATE_IDLE not supported for gate %d", gate);
+        return -1;
+
+    case CLKGATE_SLEEP:
+        m = CLKGATE_MODE_ON_RUN;
+        break;
+
+    case CLKGATE_OFF:
+        m = CLKGATE_MODE_OFF;
+        break;
+
+    default:
+        ZF_LOGE("Invalid gate mode 0x%x for gate %d", mode, gate);
+        assert(0);
+        return -1;
+    }
+
+    uint32_t volatile *reg = &clk_regs.ccm->ccgr[gate / 16];
     uint32_t shift = (gate & 0xf) * 2;
-    v = clk_regs.ccm->ccgr[reg];
-    v &= ~(CLKGATE_MASK << shift);
-    v |= (CLKGATE_ON_ALL << shift);
-    clk_regs.ccm->ccgr[reg] = v;
+
+    /* clear mask and set net clock gating mode */
+    *reg = (*reg & ~(CLKGATE_MODE_MASK << shift)) | (m << shift);
+
     return 0;
 }
 
-int
-clock_sys_init(ps_io_ops_t* o, clock_sys_t* clock_sys)
+int clock_sys_init(ps_io_ops_t *o, clock_sys_t *clock_sys)
 {
-    MAP_IF_NULL(o, CCM       , clk_regs.ccm);
+    MAP_IF_NULL(o, CCM, clk_regs.ccm);
     MAP_IF_NULL(o, CCM_ANALOG, clk_regs.alg);
-    clock_sys->priv = (void*)&clk_regs;
+    clock_sys->priv = (void *)&clk_regs;
     clock_sys->get_clock = &ps_get_clock;
     clock_sys->gate_enable = &imx6_gate_enable;
     return 0;
 }
 
-void
-clk_print_clock_tree(clock_sys_t* sys)
+void clk_print_clock_tree(clock_sys_t *sys)
 {
     clk_t *clk = clk_get_clock(sys, CLK_MASTER);
     clk_print_tree(clk, "");
 }
 
-clk_t* ps_clocks[] = {
+clk_t *ps_clocks[] = {
     [CLK_MASTER]   = &master_clk,
-    [CLK_PLL2  ]   = &pll2_clk,
+    [CLK_PLL2]     = &pll_sys_clk,
     [CLK_MMDC_CH0] = &mmdc_ch0_clk,
     [CLK_AHB]      = &ahb_clk,
     [CLK_IPG]      = &ipg_clk,
@@ -684,13 +1148,12 @@
     [CLK_CLKO2]    = &clko2_clk,
 };
 
-/* These frequencies are NOT the recommended
- * frequencies. They are to be used when we
- * need to make assumptions about what u-boot
- * has left us with. */
+/* These frequencies are NOT the recommended frequencies. They are to be used
+ * when we need to make assumptions about what u-boot has left us with.
+ */
 freq_t ps_freq_default[] = {
     [CLK_MASTER]   =  24 * MHZ,
-    [CLK_PLL2  ]   = 528 * MHZ,
+    [CLK_PLL2]     = 528 * MHZ, /* PLL_SYS */
     [CLK_MMDC_CH0] = 528 * MHZ,
     [CLK_AHB]      = 132 * MHZ,
     [CLK_IPG]      =  66 * MHZ,
diff --git a/libplatsupport/src/plat/imx6/gpio.c b/libplatsupport/src/plat/imx6/gpio.c
index e930e3d..3b2df82 100644
--- a/libplatsupport/src/plat/imx6/gpio.c
+++ b/libplatsupport/src/plat/imx6/gpio.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdint.h>
@@ -46,6 +40,7 @@
     uint32_t direction;   /* +0x04 */
     uint32_t pad_status;  /* +0x08 */
     uint32_t int_cfg;     /* +0x0C */
+    uint32_t int_cfg2;    /* +0x10 */
     uint32_t int_mask;    /* +0x14 */
     uint32_t int_status;  /* +0x18 */
     uint32_t edge;        /* +0x1C */
diff --git a/libplatsupport/src/plat/imx6/i2c.c b/libplatsupport/src/plat/imx6/i2c.c
index dc3cd36..28a1913 100644
--- a/libplatsupport/src/plat/imx6/i2c.c
+++ b/libplatsupport/src/plat/imx6/i2c.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/i2c.h>
diff --git a/libplatsupport/src/plat/imx6/mux.c b/libplatsupport/src/plat/imx6/mux.c
index 2abc977..567c39b 100644
--- a/libplatsupport/src/plat/imx6/mux.c
+++ b/libplatsupport/src/plat/imx6/mux.c
@@ -1,13 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2020, HENSOLDT Cyber GmbH
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdint.h>
@@ -19,8 +14,23 @@
 #include "../../services.h"
 
 #define IMX6_IOMUXC_PADDR 0x020E0000
+
+#if defined(CONFIG_PLAT_IMX6DQ)
+
 #define IMX6_IOMUXC_SIZE  0x4000
 
+#elif defined(CONFIG_PLAT_IMX6SX)
+
+#define IMX6_IOMUXC_SIZE  0x1000
+
+#define IMX6_IOMUXC_GPR_PADDR 0x020E4000
+#define IMX6_IOMUXC_GPR_SIZE  0x1000
+
+#else
+#error "unknown i.MX6 SOC"
+#endif
+
+
 #define IOMUXC_MUXCTL_OFFSET        0x4C
 #define IOMUXC_PADCTL_OFFSET        0x360
 
@@ -33,6 +43,9 @@
 #define IOMUXC_IS_DAISY_MASK IOMUXC_IS_DAISY(0x3)
 
 struct imx6_iomuxc_regs {
+
+#if defined(CONFIG_PLAT_IMX6DQ)
+
     /*** GPR ***/
     uint32_t gpr0;                              /* +0x000 */
     uint32_t gpr1;                              /* +0x004 */
@@ -631,34 +644,621 @@
     uint32_t usb_otg_oc_select_input;           /* +0x944 */
     uint32_t usb_h1_oc_select_input;            /* +0x948 */
     uint32_t usdhc1_wp_on_select_input;         /* +0x94C */
+
+#elif defined(CONFIG_PLAT_IMX6SX)
+
+    /*** MUX control ***/
+    uint32_t res0[2];
+    uint32_t res1[3];
+    uint32_t sw_mux_ctl_pad_gpio1_io00;             /* +0x014 */
+    uint32_t sw_mux_ctl_pad_gpio1_io01;             /* +0x018 */
+    uint32_t sw_mux_ctl_pad_gpio1_io02;             /* +0x01C */
+    uint32_t sw_mux_ctl_pad_gpio1_io03;             /* +0x020 */
+    uint32_t sw_mux_ctl_pad_gpio1_io04;             /* +0x024 */
+    uint32_t sw_mux_ctl_pad_gpio1_io05;             /* +0x028 */
+    uint32_t sw_mux_ctl_pad_gpio1_io06;             /* +0x02C */
+    uint32_t sw_mux_ctl_pad_gpio1_io07;             /* +0x030 */
+    uint32_t sw_mux_ctl_pad_gpio1_io08;             /* +0x034 */
+    uint32_t sw_mux_ctl_pad_gpio1_io09;             /* +0x038 */
+    uint32_t sw_mux_ctl_pad_gpio1_io10;             /* +0x03C */
+    uint32_t sw_mux_ctl_pad_gpio1_io11;             /* +0x040 */
+    uint32_t sw_mux_ctl_pad_gpio1_io12;             /* +0x044 */
+    uint32_t sw_mux_ctl_pad_gpio1_io13;             /* +0x048 */
+    uint32_t sw_mux_ctl_pad_csi_data00;             /* +0x04C */
+    uint32_t sw_mux_ctl_pad_csi_data01;             /* +0x050 */
+    uint32_t sw_mux_ctl_pad_csi_data02;             /* +0x054 */
+    uint32_t sw_mux_ctl_pad_csi_data03;             /* +0x058 */
+    uint32_t sw_mux_ctl_pad_csi_data04;             /* +0x05C */
+    uint32_t sw_mux_ctl_pad_csi_data05;             /* +0x060 */
+    uint32_t sw_mux_ctl_pad_csi_data06;             /* +0x064 */
+    uint32_t sw_mux_ctl_pad_csi_data07;             /* +0x068 */
+    uint32_t sw_mux_ctl_pad_csi_hsync;              /* +0x06C */
+    uint32_t sw_mux_ctl_pad_csi_mclk;               /* +0x070 */
+    uint32_t sw_mux_ctl_pad_csi_pixclk;             /* +0x074 */
+    uint32_t sw_mux_ctl_pad_csi_vsync;              /* +0x078 */
+    uint32_t sw_mux_ctl_pad_enet1_col;              /* +0x07C */
+    uint32_t sw_mux_ctl_pad_enet1_crs;              /* +0x080 */
+    uint32_t sw_mux_ctl_pad_enet1_mdc;              /* +0x084 */
+    uint32_t sw_mux_ctl_pad_enet1_mdio;             /* +0x088 */
+    uint32_t sw_mux_ctl_pad_enet1_rx_clk;           /* +0x08C */
+    uint32_t sw_mux_ctl_pad_enet1_tx_clk;           /* +0x090 */
+    uint32_t sw_mux_ctl_pad_enet2_col;              /* +0x094 */
+    uint32_t sw_mux_ctl_pad_enet2_crs;              /* +0x098 */
+    uint32_t sw_mux_ctl_pad_enet2_rx_clk;           /* +0x09C */
+    uint32_t sw_mux_ctl_pad_enet2_tx_clk;           /* +0x0A0 */
+    uint32_t sw_mux_ctl_pad_key_col0;               /* +0x0A4 */
+    uint32_t sw_mux_ctl_pad_key_col1;               /* +0x0A8 */
+    uint32_t sw_mux_ctl_pad_key_col2;               /* +0x0AC */
+    uint32_t sw_mux_ctl_pad_key_col3;               /* +0x0B0 */
+    uint32_t sw_mux_ctl_pad_key_col4;               /* +0x0B4 */
+    uint32_t sw_mux_ctl_pad_key_row0;               /* +0x0B8 */
+    uint32_t sw_mux_ctl_pad_key_row1;               /* +0x0BC */
+    uint32_t sw_mux_ctl_pad_key_row2;               /* +0x0C0 */
+    uint32_t sw_mux_ctl_pad_key_row3;               /* +0x0C4 */
+    uint32_t sw_mux_ctl_pad_key_row4;               /* +0x0C8 */
+    uint32_t sw_mux_ctl_pad_lcd1_clk;               /* +0x0CC */
+    uint32_t sw_mux_ctl_pad_lcd1_data00;            /* +0x0D0 */
+    uint32_t sw_mux_ctl_pad_lcd1_data01;            /* +0x0D4 */
+    uint32_t sw_mux_ctl_pad_lcd1_data02;            /* +0x0D8 */
+    uint32_t sw_mux_ctl_pad_lcd1_data03;            /* +0x0DC */
+    uint32_t sw_mux_ctl_pad_lcd1_data04;            /* +0x0E0 */
+    uint32_t sw_mux_ctl_pad_lcd1_data05;            /* +0x0E4 */
+    uint32_t sw_mux_ctl_pad_lcd1_data06;            /* +0x0E8 */
+    uint32_t sw_mux_ctl_pad_lcd1_data07;            /* +0x0EC */
+    uint32_t sw_mux_ctl_pad_lcd1_data08;            /* +0x0F0 */
+    uint32_t sw_mux_ctl_pad_lcd1_data09;            /* +0x0F4 */
+    uint32_t sw_mux_ctl_pad_lcd1_data10;            /* +0x0F8 */
+    uint32_t sw_mux_ctl_pad_lcd1_data11;            /* +0x0FC */
+    uint32_t sw_mux_ctl_pad_lcd1_data12;            /* +0x100 */
+    uint32_t sw_mux_ctl_pad_lcd1_data13;            /* +0x104 */
+    uint32_t sw_mux_ctl_pad_lcd1_data14;            /* +0x108 */
+    uint32_t sw_mux_ctl_pad_lcd1_data15;            /* +0x10C */
+    uint32_t sw_mux_ctl_pad_lcd1_data16;            /* +0x110 */
+    uint32_t sw_mux_ctl_pad_lcd1_data17;            /* +0x114 */
+    uint32_t sw_mux_ctl_pad_lcd1_data18;            /* +0x118 */
+    uint32_t sw_mux_ctl_pad_lcd1_data19;            /* +0x11C */
+    uint32_t sw_mux_ctl_pad_lcd1_data20;            /* +0x120 */
+    uint32_t sw_mux_ctl_pad_lcd1_data21;            /* +0x124 */
+    uint32_t sw_mux_ctl_pad_lcd1_data22;            /* +0x128 */
+    uint32_t sw_mux_ctl_pad_lcd1_data23;            /* +0x12C */
+    uint32_t sw_mux_ctl_pad_lcd1_enable;            /* +0x130 */
+    uint32_t sw_mux_ctl_pad_lcd1_hsync;             /* +0x134 */
+    uint32_t sw_mux_ctl_pad_lcd1_reset;             /* +0x138 */
+    uint32_t sw_mux_ctl_pad_lcd1_vsync;             /* +0x13C */
+    uint32_t sw_mux_ctl_pad_nand_ale;               /* +0x140 */
+    uint32_t sw_mux_ctl_pad_nand_ce0_b;             /* +0x144 */
+    uint32_t sw_mux_ctl_pad_nand_ce1_b;             /* +0x148 */
+    uint32_t sw_mux_ctl_pad_nand_cle;               /* +0x14C */
+    uint32_t sw_mux_ctl_pad_nand_data00;            /* +0x150 */
+    uint32_t sw_mux_ctl_pad_nand_data01;            /* +0x154 */
+    uint32_t sw_mux_ctl_pad_nand_data02;            /* +0x158 */
+    uint32_t sw_mux_ctl_pad_nand_data03;            /* +0x15C */
+    uint32_t sw_mux_ctl_pad_nand_data04;            /* +0x160 */
+    uint32_t sw_mux_ctl_pad_nand_data05;            /* +0x164 */
+    uint32_t sw_mux_ctl_pad_nand_data06;            /* +0x168 */
+    uint32_t sw_mux_ctl_pad_nand_data07;            /* +0x16C */
+    uint32_t sw_mux_ctl_pad_nand_re_b;              /* +0x170 */
+    uint32_t sw_mux_ctl_pad_nand_ready_b;           /* +0x174 */
+    uint32_t sw_mux_ctl_pad_nand_we_b;              /* +0x178 */
+    uint32_t sw_mux_ctl_pad_nand_wp_b;              /* +0x17C */
+    uint32_t sw_mux_ctl_pad_qspi1a_data0;           /* +0x180 */
+    uint32_t sw_mux_ctl_pad_qspi1a_data1;           /* +0x184 */
+    uint32_t sw_mux_ctl_pad_qspi1a_data2;           /* +0x188 */
+    uint32_t sw_mux_ctl_pad_qspi1a_data3;           /* +0x18C */
+    uint32_t sw_mux_ctl_pad_qspi1a_dqs;             /* +0x190 */
+    uint32_t sw_mux_ctl_pad_qspi1a_sclk;            /* +0x194 */
+    uint32_t sw_mux_ctl_pad_qspi1a_ss0_b;           /* +0x198 */
+    uint32_t sw_mux_ctl_pad_qspi1a_ss1_b;           /* +0x19C */
+    uint32_t sw_mux_ctl_pad_qspi1b_data0;           /* +0x1A0 */
+    uint32_t sw_mux_ctl_pad_qspi1b_data1;           /* +0x1A4 */
+    uint32_t sw_mux_ctl_pad_qspi1b_data2;           /* +0x1A8 */
+    uint32_t sw_mux_ctl_pad_qspi1b_data3;           /* +0x1AC */
+    uint32_t sw_mux_ctl_pad_qspi1b_dqs;             /* +0x1B0 */
+    uint32_t sw_mux_ctl_pad_qspi1b_sclk;            /* +0x1B4 */
+    uint32_t sw_mux_ctl_pad_qspi1b_ss0_b;           /* +0x1B8 */
+    uint32_t sw_mux_ctl_pad_qspi1b_ss1_b;           /* +0x1BC */
+    uint32_t sw_mux_ctl_pad_rgmii1_rd0;             /* +0x1C0 */
+    uint32_t sw_mux_ctl_pad_rgmii1_rd1;             /* +0x1C4 */
+    uint32_t sw_mux_ctl_pad_rgmii1_rd2;             /* +0x1C8 */
+    uint32_t sw_mux_ctl_pad_rgmii1_rd3;             /* +0x1CC */
+    uint32_t sw_mux_ctl_pad_rgmii1_rx_ctl;          /* +0x1D0 */
+    uint32_t sw_mux_ctl_pad_rgmii1_rxc;             /* +0x1D4 */
+    uint32_t sw_mux_ctl_pad_rgmii1_td0;             /* +0x1D8 */
+    uint32_t sw_mux_ctl_pad_rgmii1_td1;             /* +0x1DC */
+    uint32_t sw_mux_ctl_pad_rgmii1_td2;             /* +0x1E0 */
+    uint32_t sw_mux_ctl_pad_rgmii1_td3;             /* +0x1E4 */
+    uint32_t sw_mux_ctl_pad_rgmii1_tx_ctl;          /* +0x1E8 */
+    uint32_t sw_mux_ctl_pad_rgmii1_txc;             /* +0x1EC */
+    uint32_t sw_mux_ctl_pad_rgmii2_rd0;             /* +0x1F0 */
+    uint32_t sw_mux_ctl_pad_rgmii2_rd1;             /* +0x1F4 */
+    uint32_t sw_mux_ctl_pad_rgmii2_rd2;             /* +0x1F8 */
+    uint32_t sw_mux_ctl_pad_rgmii2_rd3;             /* +0x1FC */
+    uint32_t sw_mux_ctl_pad_rgmii2_rx_ctl;          /* +0x200 */
+    uint32_t sw_mux_ctl_pad_rgmii2_rxc;             /* +0x204 */
+    uint32_t sw_mux_ctl_pad_rgmii2_td0;             /* +0x208 */
+    uint32_t sw_mux_ctl_pad_rgmii2_td1;             /* +0x20C */
+    uint32_t sw_mux_ctl_pad_rgmii2_td2;             /* +0x210 */
+    uint32_t sw_mux_ctl_pad_rgmii2_td3;             /* +0x214 */
+    uint32_t sw_mux_ctl_pad_rgmii2_tx_ctl;          /* +0x218 */
+    uint32_t sw_mux_ctl_pad_rgmii2_txc;             /* +0x21C */
+    uint32_t sw_mux_ctl_pad_sd1_clk;                /* +0x220 */
+    uint32_t sw_mux_ctl_pad_sd1_cmd;                /* +0x224 */
+    uint32_t sw_mux_ctl_pad_sd1_data0;              /* +0x228 */
+    uint32_t sw_mux_ctl_pad_sd1_data1;              /* +0x22C */
+    uint32_t sw_mux_ctl_pad_sd1_data2;              /* +0x230 */
+    uint32_t sw_mux_ctl_pad_sd1_data3;              /* +0x234 */
+    uint32_t sw_mux_ctl_pad_sd2_clk;                /* +0x238 */
+    uint32_t sw_mux_ctl_pad_sd2_cmd;                /* +0x23C */
+    uint32_t sw_mux_ctl_pad_sd2_data0;              /* +0x240 */
+    uint32_t sw_mux_ctl_pad_sd2_data1;              /* +0x244 */
+    uint32_t sw_mux_ctl_pad_sd2_data2;              /* +0x248 */
+    uint32_t sw_mux_ctl_pad_sd2_data3;              /* +0x24C */
+    uint32_t sw_mux_ctl_pad_sd3_clk;                /* +0x250 */
+    uint32_t sw_mux_ctl_pad_sd3_cmd;                /* +0x254 */
+    uint32_t sw_mux_ctl_pad_sd3_data0;              /* +0x258 */
+    uint32_t sw_mux_ctl_pad_sd3_data1;              /* +0x25C */
+    uint32_t sw_mux_ctl_pad_sd3_data2;              /* +0x260 */
+    uint32_t sw_mux_ctl_pad_sd3_data3;              /* +0x264 */
+    uint32_t sw_mux_ctl_pad_sd3_data4;              /* +0x268 */
+    uint32_t sw_mux_ctl_pad_sd3_data5;              /* +0x26C */
+    uint32_t sw_mux_ctl_pad_sd3_data6;              /* +0x270 */
+    uint32_t sw_mux_ctl_pad_sd3_data7;              /* +0x274 */
+    uint32_t sw_mux_ctl_pad_sd4_clk;                /* +0x278 */
+    uint32_t sw_mux_ctl_pad_sd4_cmd;                /* +0x27C */
+    uint32_t sw_mux_ctl_pad_sd4_data0;              /* +0x280 */
+    uint32_t sw_mux_ctl_pad_sd4_data1;              /* +0x284 */
+    uint32_t sw_mux_ctl_pad_sd4_data2;              /* +0x288 */
+    uint32_t sw_mux_ctl_pad_sd4_data3;              /* +0x28C */
+    uint32_t sw_mux_ctl_pad_sd4_data4;              /* +0x290 */
+    uint32_t sw_mux_ctl_pad_sd4_data5;              /* +0x294 */
+    uint32_t sw_mux_ctl_pad_sd4_data6;              /* +0x298 */
+    uint32_t sw_mux_ctl_pad_sd4_data7;              /* +0x29C */
+    uint32_t sw_mux_ctl_pad_sd4_reset_b;            /* +0x2A0 */
+    uint32_t sw_mux_ctl_pad_usb_h_data;             /* +0x2A4 */
+    uint32_t sw_mux_ctl_pad_usb_h_strobe;           /* +0x2A8 */
+    /*** Pad Control ***/
+    uint32_t sw_pad_ctl_pad_dram_addr00;            /* +0x2AC */
+    uint32_t sw_pad_ctl_pad_dram_addr01;            /* +0x2B0 */
+    uint32_t sw_pad_ctl_pad_dram_addr02;            /* +0x2B4 */
+    uint32_t sw_pad_ctl_pad_dram_addr03;            /* +0x2B8 */
+    uint32_t sw_pad_ctl_pad_dram_addr04;            /* +0x2BC */
+    uint32_t sw_pad_ctl_pad_dram_addr05;            /* +0x2C0 */
+    uint32_t sw_pad_ctl_pad_dram_addr06;            /* +0x2C4 */
+    uint32_t sw_pad_ctl_pad_dram_addr07;            /* +0x2C8 */
+    uint32_t sw_pad_ctl_pad_dram_addr08;            /* +0x2CC */
+    uint32_t sw_pad_ctl_pad_dram_addr09;            /* +0x2D0 */
+    uint32_t sw_pad_ctl_pad_dram_addr10;            /* +0x2D4 */
+    uint32_t sw_pad_ctl_pad_dram_addr11;            /* +0x2D8 */
+    uint32_t sw_pad_ctl_pad_dram_addr12;            /* +0x2DC */
+    uint32_t sw_pad_ctl_pad_dram_addr13;            /* +0x2E0 */
+    uint32_t sw_pad_ctl_pad_dram_addr14;            /* +0x2E4 */
+    uint32_t sw_pad_ctl_pad_dram_addr15;            /* +0x2E8 */
+    uint32_t sw_pad_ctl_pad_dram_dqm0;              /* +0x2EC */
+    uint32_t sw_pad_ctl_pad_dram_dqm1;              /* +0x2F0 */
+    uint32_t sw_pad_ctl_pad_dram_dqm2;              /* +0x2F4 */
+    uint32_t sw_pad_ctl_pad_dram_dqm3;              /* +0x2F8 */
+    uint32_t sw_pad_ctl_pad_dram_ras_b;             /* +0x2FC */
+    uint32_t sw_pad_ctl_pad_dram_cas_b;             /* +0x300 */
+    uint32_t sw_pad_ctl_pad_dram_cs0_b;             /* +0x304 */
+    uint32_t sw_pad_ctl_pad_dram_cs1_b;             /* +0x308 */
+    uint32_t sw_pad_ctl_pad_dram_sdwe_b;            /* +0x30C */
+    uint32_t sw_pad_ctl_pad_dram_odt0;              /* +0x310 */
+    uint32_t sw_pad_ctl_pad_dram_odt1;              /* +0x314 */
+    uint32_t sw_pad_ctl_pad_dram_sdba0;             /* +0x318 */
+    uint32_t sw_pad_ctl_pad_dram_sdba1;             /* +0x31C */
+    uint32_t sw_pad_ctl_pad_dram_sdba2;             /* +0x320 */
+    uint32_t sw_pad_ctl_pad_dram_sdcke0;            /* +0x324 */
+    uint32_t sw_pad_ctl_pad_dram_sdcke1;            /* +0x328 */
+    uint32_t sw_pad_ctl_pad_dram_sdclk0_p;          /* +0x32C */
+    uint32_t sw_pad_ctl_pad_dram_sdqs0_p;           /* +0x330 */
+    uint32_t sw_pad_ctl_pad_dram_sdqs1_p;           /* +0x334 */
+    uint32_t sw_pad_ctl_pad_dram_sdqs2_p;           /* +0x338 */
+    uint32_t sw_pad_ctl_pad_dram_sdqs3_p;           /* +0x33C */
+    uint32_t sw_pad_ctl_pad_dram_reset;             /* +0x340 */
+    uint32_t sw_pad_ctl_pad_jtag_mod;               /* +0x344 */
+    uint32_t sw_pad_ctl_pad_jtag_tck;               /* +0x348 */
+    uint32_t sw_pad_ctl_pad_jtag_tdi;               /* +0x34C */
+    uint32_t sw_pad_ctl_pad_jtag_tdo;               /* +0x350 */
+    uint32_t sw_pad_ctl_pad_jtag_tms;               /* +0x354 */
+    uint32_t sw_pad_ctl_pad_jtag_trst_b;            /* +0x358 */
+    uint32_t sw_pad_ctl_pad_gpio1_io00;             /* +0x35C */
+    uint32_t sw_pad_ctl_pad_gpio1_io01;             /* +0x360 */
+    uint32_t sw_pad_ctl_pad_gpio1_io02;             /* +0x364 */
+    uint32_t sw_pad_ctl_pad_gpio1_io03;             /* +0x368 */
+    uint32_t sw_pad_ctl_pad_gpio1_io04;             /* +0x36C */
+    uint32_t sw_pad_ctl_pad_gpio1_io05;             /* +0x370 */
+    uint32_t sw_pad_ctl_pad_gpio1_io06;             /* +0x374 */
+    uint32_t sw_pad_ctl_pad_gpio1_io07;             /* +0x378 */
+    uint32_t sw_pad_ctl_pad_gpio1_io08;             /* +0x37C */
+    uint32_t sw_pad_ctl_pad_gpio1_io09;             /* +0x380 */
+    uint32_t sw_pad_ctl_pad_gpio1_io10;             /* +0x384 */
+    uint32_t sw_pad_ctl_pad_gpio1_io11;             /* +0x388 */
+    uint32_t sw_pad_ctl_pad_gpio1_io12;             /* +0x38C */
+    uint32_t sw_pad_ctl_pad_gpio1_io13;             /* +0x390 */
+    uint32_t sw_pad_ctl_pad_csi_data00;             /* +0x394 */
+    uint32_t sw_pad_ctl_pad_csi_data01;             /* +0x398 */
+    uint32_t sw_pad_ctl_pad_csi_data02;             /* +0x39C */
+    uint32_t sw_pad_ctl_pad_csi_data03;             /* +0x3A0 */
+    uint32_t sw_pad_ctl_pad_csi_data04;             /* +0x3A4 */
+    uint32_t sw_pad_ctl_pad_csi_data05;             /* +0x3A8 */
+    uint32_t sw_pad_ctl_pad_csi_data06;             /* +0x3AC */
+    uint32_t sw_pad_ctl_pad_csi_data07;             /* +0x3B0 */
+    uint32_t sw_pad_ctl_pad_csi_hsync;              /* +0x3B4 */
+    uint32_t sw_pad_ctl_pad_csi_mclk;               /* +0x3B8 */
+    uint32_t sw_pad_ctl_pad_csi_pixclk;             /* +0x3BC */
+    uint32_t sw_pad_ctl_pad_csi_vsync;              /* +0x3C0 */
+    uint32_t sw_pad_ctl_pad_enet1_col;              /* +0x3C4 */
+    uint32_t sw_pad_ctl_pad_enet1_crs;              /* +0x3C8 */
+    uint32_t sw_pad_ctl_pad_enet1_mdc;              /* +0x3CC */
+    uint32_t sw_pad_ctl_pad_enet1_mdio;             /* +0x3D0 */
+    uint32_t sw_pad_ctl_pad_enet1_rx_clk;           /* +0x3D4 */
+    uint32_t sw_pad_ctl_pad_enet1_tx_clk;           /* +0x3D8 */
+    uint32_t sw_pad_ctl_pad_enet2_col;              /* +0x3DC */
+    uint32_t sw_pad_ctl_pad_enet2_crs;              /* +0x3E0 */
+    uint32_t sw_pad_ctl_pad_enet2_rx_clk;           /* +0x3E4 */
+    uint32_t sw_pad_ctl_pad_enet2_tx_clk;           /* +0x3E8 */
+    uint32_t sw_pad_ctl_pad_key_col0;               /* +0x3EC */
+    uint32_t sw_pad_ctl_pad_key_col1;               /* +0x3F0 */
+    uint32_t sw_pad_ctl_pad_key_col2;               /* +0x3F4 */
+    uint32_t sw_pad_ctl_pad_key_col3;               /* +0x3F8 */
+    uint32_t sw_pad_ctl_pad_key_col4;               /* +0x3FC */
+    uint32_t sw_pad_ctl_pad_key_row0;               /* +0x400 */
+    uint32_t sw_pad_ctl_pad_key_row1;               /* +0x404 */
+    uint32_t sw_pad_ctl_pad_key_row2;               /* +0x408 */
+    uint32_t sw_pad_ctl_pad_key_row3;               /* +0x40C */
+    uint32_t sw_pad_ctl_pad_key_row4;               /* +0x410 */
+    uint32_t sw_pad_ctl_pad_lcd1_clk;               /* +0x414 */
+    uint32_t sw_pad_ctl_pad_lcd1_data00;            /* +0x418 */
+    uint32_t sw_pad_ctl_pad_lcd1_data01;            /* +0x41C */
+    uint32_t sw_pad_ctl_pad_lcd1_data02;            /* +0x420 */
+    uint32_t sw_pad_ctl_pad_lcd1_data03;            /* +0x424 */
+    uint32_t sw_pad_ctl_pad_lcd1_data04;            /* +0x428 */
+    uint32_t sw_pad_ctl_pad_lcd1_data05;            /* +0x42C */
+    uint32_t sw_pad_ctl_pad_lcd1_data06;            /* +0x430 */
+    uint32_t sw_pad_ctl_pad_lcd1_data07;            /* +0x434 */
+    uint32_t sw_pad_ctl_pad_lcd1_data08;            /* +0x438 */
+    uint32_t sw_pad_ctl_pad_lcd1_data09;            /* +0x43C */
+    uint32_t sw_pad_ctl_pad_lcd1_data10;            /* +0x440 */
+    uint32_t sw_pad_ctl_pad_lcd1_data11;            /* +0x444 */
+    uint32_t sw_pad_ctl_pad_lcd1_data12;            /* +0x448 */
+    uint32_t sw_pad_ctl_pad_lcd1_data13;            /* +0x44C */
+    uint32_t sw_pad_ctl_pad_lcd1_data14;            /* +0x450 */
+    uint32_t sw_pad_ctl_pad_lcd1_data15;            /* +0x454 */
+    uint32_t sw_pad_ctl_pad_lcd1_data16;            /* +0x458 */
+    uint32_t sw_pad_ctl_pad_lcd1_data17;            /* +0x45C */
+    uint32_t sw_pad_ctl_pad_lcd1_data18;            /* +0x460 */
+    uint32_t sw_pad_ctl_pad_lcd1_data19;            /* +0x464 */
+    uint32_t sw_pad_ctl_pad_lcd1_data20;            /* +0x468 */
+    uint32_t sw_pad_ctl_pad_lcd1_data21;            /* +0x46C */
+    uint32_t sw_pad_ctl_pad_lcd1_data22;            /* +0x470 */
+    uint32_t sw_pad_ctl_pad_lcd1_data23;            /* +0x474 */
+    uint32_t sw_pad_ctl_pad_lcd1_enable;            /* +0x478 */
+    uint32_t sw_pad_ctl_pad_lcd1_hsync;             /* +0x47C */
+    uint32_t sw_pad_ctl_pad_lcd1_reset;             /* +0x480 */
+    uint32_t sw_pad_ctl_pad_lcd1_vsync;             /* +0x484 */
+    uint32_t sw_pad_ctl_pad_nand_ale;               /* +0x488 */
+    uint32_t sw_pad_ctl_pad_nand_ce0_b;             /* +0x48C */
+    uint32_t sw_pad_ctl_pad_nand_ce1_b;             /* +0x490 */
+    uint32_t sw_pad_ctl_pad_nand_cle;               /* +0x494 */
+    uint32_t sw_pad_ctl_pad_nand_data00;            /* +0x498 */
+    uint32_t sw_pad_ctl_pad_nand_data01;            /* +0x49C */
+    uint32_t sw_pad_ctl_pad_nand_data02;            /* +0x4A0 */
+    uint32_t sw_pad_ctl_pad_nand_data03;            /* +0x4A4 */
+    uint32_t sw_pad_ctl_pad_nand_data04;            /* +0x4A8 */
+    uint32_t sw_pad_ctl_pad_nand_data05;            /* +0x4AC */
+    uint32_t sw_pad_ctl_pad_nand_data06;            /* +0x4B0 */
+    uint32_t sw_pad_ctl_pad_nand_data07;            /* +0x4B4 */
+    uint32_t sw_pad_ctl_pad_nand_re_b;              /* +0x4B8 */
+    uint32_t sw_pad_ctl_pad_nand_ready_b;           /* +0x4BC */
+    uint32_t sw_pad_ctl_pad_nand_we_b;              /* +0x4C0 */
+    uint32_t sw_pad_ctl_pad_nand_wp_b;              /* +0x4C4 */
+    uint32_t sw_pad_ctl_pad_qspi1a_data0;           /* +0x4C8 */
+    uint32_t sw_pad_ctl_pad_qspi1a_data1;           /* +0x4CC */
+    uint32_t sw_pad_ctl_pad_qspi1a_data2;           /* +0x4D0 */
+    uint32_t sw_pad_ctl_pad_qspi1a_data3;           /* +0x4D4 */
+    uint32_t sw_pad_ctl_pad_qspi1a_dqs;             /* +0x4D8 */
+    uint32_t sw_pad_ctl_pad_qspi1a_sclk;            /* +0x4DC */
+    uint32_t sw_pad_ctl_pad_qspi1a_ss0_b;           /* +0x4E0 */
+    uint32_t sw_pad_ctl_pad_qspi1a_ss1_b;           /* +0x4E4 */
+    uint32_t sw_pad_ctl_pad_qspi1b_data0;           /* +0x4E8 */
+    uint32_t sw_pad_ctl_pad_qspi1b_data1;           /* +0x4EC */
+    uint32_t sw_pad_ctl_pad_qspi1b_data2;           /* +0x4F0 */
+    uint32_t sw_pad_ctl_pad_qspi1b_data3;           /* +0x4F4 */
+    uint32_t sw_pad_ctl_pad_qspi1b_dqs;             /* +0x4F8 */
+    uint32_t sw_pad_ctl_pad_qspi1b_sclk;            /* +0x4FC */
+    uint32_t sw_pad_ctl_pad_qspi1b_ss0_b;           /* +0x500 */
+    uint32_t sw_pad_ctl_pad_qspi1b_ss1_b;           /* +0x504 */
+    uint32_t sw_pad_ctl_pad_rgmii1_rd0;             /* +0x508 */
+    uint32_t sw_pad_ctl_pad_rgmii1_rd1;             /* +0x50C */
+    uint32_t sw_pad_ctl_pad_rgmii1_rd2;             /* +0x510 */
+    uint32_t sw_pad_ctl_pad_rgmii1_rd3;             /* +0x514 */
+    uint32_t sw_pad_ctl_pad_rgmii1_rx_ctl;          /* +0x518 */
+    uint32_t sw_pad_ctl_pad_rgmii1_rxc;             /* +0x51C */
+    uint32_t sw_pad_ctl_pad_rgmii1_td0;             /* +0x520 */
+    uint32_t sw_pad_ctl_pad_rgmii1_td1;             /* +0x524 */
+    uint32_t sw_pad_ctl_pad_rgmii1_td2;             /* +0x528 */
+    uint32_t sw_pad_ctl_pad_rgmii1_td3;             /* +0x52C */
+    uint32_t sw_pad_ctl_pad_rgmii1_tx_ctl;          /* +0x530 */
+    uint32_t sw_pad_ctl_pad_rgmii1_txc;             /* +0x534 */
+    uint32_t sw_pad_ctl_pad_rgmii2_rd0;             /* +0x538 */
+    uint32_t sw_pad_ctl_pad_rgmii2_rd1;             /* +0x53C */
+    uint32_t sw_pad_ctl_pad_rgmii2_rd2;             /* +0x540 */
+    uint32_t sw_pad_ctl_pad_rgmii2_rd3;             /* +0x544 */
+    uint32_t sw_pad_ctl_pad_rgmii2_rx_ctl;          /* +0x548 */
+    uint32_t sw_pad_ctl_pad_rgmii2_rxc;             /* +0x54C */
+    uint32_t sw_pad_ctl_pad_rgmii2_td0;             /* +0x550 */
+    uint32_t sw_pad_ctl_pad_rgmii2_td1;             /* +0x554 */
+    uint32_t sw_pad_ctl_pad_rgmii2_td2;             /* +0x558 */
+    uint32_t sw_pad_ctl_pad_rgmii2_td3;             /* +0x55C */
+    uint32_t sw_pad_ctl_pad_rgmii2_tx_ctl;          /* +0x560 */
+    uint32_t sw_pad_ctl_pad_rgmii2_txc;             /* +0x564 */
+    uint32_t sw_pad_ctl_pad_sd1_clk;                /* +0x568 */
+    uint32_t sw_pad_ctl_pad_sd1_cmd;                /* +0x56C */
+    uint32_t sw_pad_ctl_pad_sd1_data0;              /* +0x570 */
+    uint32_t sw_pad_ctl_pad_sd1_data1;              /* +0x574 */
+    uint32_t sw_pad_ctl_pad_sd1_data2;              /* +0x578 */
+    uint32_t sw_pad_ctl_pad_sd1_data3;              /* +0x57C */
+    uint32_t sw_pad_ctl_pad_sd2_clk;                /* +0x580 */
+    uint32_t sw_pad_ctl_pad_sd2_cmd;                /* +0x584 */
+    uint32_t sw_pad_ctl_pad_sd2_data0;              /* +0x588 */
+    uint32_t sw_pad_ctl_pad_sd2_data1;              /* +0x58C */
+    uint32_t sw_pad_ctl_pad_sd2_data2;              /* +0x590 */
+    uint32_t sw_pad_ctl_pad_sd2_data3;              /* +0x594 */
+    uint32_t sw_pad_ctl_pad_sd3_clk;                /* +0x598 */
+    uint32_t sw_pad_ctl_pad_sd3_cmd;                /* +0x59C */
+    uint32_t sw_pad_ctl_pad_sd3_data0;              /* +0x5A0 */
+    uint32_t sw_pad_ctl_pad_sd3_data1;              /* +0x5A4 */
+    uint32_t sw_pad_ctl_pad_sd3_data2;              /* +0x5A8 */
+    uint32_t sw_pad_ctl_pad_sd3_data3;              /* +0x5AC */
+    uint32_t sw_pad_ctl_pad_sd3_data4;              /* +0x5B0 */
+    uint32_t sw_pad_ctl_pad_sd3_data5;              /* +0x5B4 */
+    uint32_t sw_pad_ctl_pad_sd3_data6;              /* +0x5B8 */
+    uint32_t sw_pad_ctl_pad_sd3_data7;              /* +0x5BC */
+    uint32_t sw_pad_ctl_pad_sd4_clk;                /* +0x5C0 */
+    uint32_t sw_pad_ctl_pad_sd4_cmd;                /* +0x5C4 */
+    uint32_t sw_pad_ctl_pad_sd4_data0;              /* +0x5C8 */
+    uint32_t sw_pad_ctl_pad_sd4_data1;              /* +0x5CC */
+    uint32_t sw_pad_ctl_pad_sd4_data2;              /* +0x5D0 */
+    uint32_t sw_pad_ctl_pad_sd4_data3;              /* +0x5D4 */
+    uint32_t sw_pad_ctl_pad_sd4_data4;              /* +0x5D8 */
+    uint32_t sw_pad_ctl_pad_sd4_data5;              /* +0x5DC */
+    uint32_t sw_pad_ctl_pad_sd4_data6;              /* +0x5E0 */
+    uint32_t sw_pad_ctl_pad_sd4_data7;              /* +0x5E4 */
+    uint32_t sw_pad_ctl_pad_sd4_reset_b;            /* +0x5E8 */
+    uint32_t sw_pad_ctl_pad_usb_h_data;             /* +0x5EC */
+    uint32_t sw_pad_ctl_pad_usb_h_strobe;           /* +0x5F0 */
+    /*** Group ***/
+    uint32_t sw_pad_ctl_grp_addds;                  /* +0x5F4 */
+    uint32_t sw_pad_ctl_grp_ddrmode_ctl;            /* +0x5F8 */
+    uint32_t sw_pad_ctl_grp_ddrpke;                 /* +0x5FC */
+    uint32_t sw_pad_ctl_grp_ddrpk;                  /* +0x600 */
+    uint32_t sw_pad_ctl_grp_ddrhys;                 /* +0x604 */
+    uint32_t sw_pad_ctl_grp_ddrmode;                /* +0x608 */
+    uint32_t sw_pad_ctl_grp_b0ds;                   /* +0x60C */
+    uint32_t sw_pad_ctl_grp_b1ds;                   /* +0x610 */
+    uint32_t sw_pad_ctl_grp_ctlds;                  /* +0x614 */
+    uint32_t sw_pad_ctl_grp_ddr_type;               /* +0x618 */
+    uint32_t sw_pad_ctl_grp_b2ds;                   /* +0x61C */
+    uint32_t sw_pad_ctl_grp_b3ds;                   /* +0x620 */
+    /*** Select Input ***/
+    uint32_t anatop_usb_otg_id_select_input;        /* +0x624 */
+    uint32_t anatop_usb_h1_id_select_input;         /* +0x628 */
+    uint32_t audmux_p3_input_da_amx_select_input;    /* +0x62C */
+    uint32_t audmux_p3_input_db_amx_select_input;    /* +0x630 */
+    uint32_t audmux_p3_input_rxclk_amx_select_input; /* +0x634 */
+    uint32_t audmux_p3_input_rxfs_amx_select_input;  /* +0x638 */
+    uint32_t audmux_p3_input_txclk_amx_select_input; /* +0x63C */
+    uint32_t audmux_p3_input_txfs_amx_select_input;  /* +0x640 */
+    uint32_t audmux_p4_input_da_amx_select_input;    /* +0x644 */
+    uint32_t audmux_p4_input_db_amx_select_input;    /* +0x648 */
+    uint32_t audmux_p4_input_rxclk_amx_select_input; /* +0x64C */
+    uint32_t audmux_p4_input_rxfs_amx_select_input;  /* +0x650 */
+    uint32_t audmux_p4_input_txclk_amx_select_input; /* +0x654 */
+    uint32_t audmux_p4_input_txfs_amx_select_input;  /* +0x658 */
+    uint32_t audmux_p5_input_da_amx_select_input;    /* +0x65C */
+    uint32_t audmux_p5_input_db_amx_select_input;    /* +0x660 */
+    uint32_t audmux_p5_input_rxclk_amx_select_input; /* +0x664 */
+    uint32_t audmux_p5_input_rxfs_amx_select_input;  /* +0x668 */
+    uint32_t audmux_p5_input_txclk_amx_select_input; /* +0x66C */
+    uint32_t audmux_p5_input_txfs_amx_select_input;  /* +0x670 */
+    uint32_t audmux_p6_input_da_amx_select_input;    /* +0x674 */
+    uint32_t audmux_p6_input_db_amx_select_input;    /* +0x678 */
+    uint32_t audmux_p6_input_rxclk_amx_select_input; /* +0x67C */
+    uint32_t audmux_p6_input_rxfs_amx_select_input;  /* +0x680 */
+    uint32_t audmux_p6_input_txclk_amx_select_input; /* +0x684 */
+    uint32_t audmux_p6_input_txfs_amx_select_input;  /* +0x688 */
+    uint32_t can1_ipp_ind_canrx_select_input;       /* +0x68C */
+    uint32_t can2_ipp_ind_canrx_select_input;       /* +0x690 */
+    uint32_t res3[2];
+    uint32_t ccm_pmic_vfuncional_ready_select_input;       /* +0x69C */
+    uint32_t csi1_ipp_csi_d_select_input_0;       /* +0x6A0 */
+    uint32_t csi1_ipp_csi_d_select_input_1;       /* +0x6A4 */
+    uint32_t csi1_ipp_csi_d_select_input_2;       /* +0x6A8 */
+    uint32_t csi1_ipp_csi_d_select_input_3;       /* +0x6AC */
+    uint32_t csi1_ipp_csi_d_select_input_4;       /* +0x6B0 */
+    uint32_t csi1_ipp_csi_d_select_input_5;       /* +0x6B4 */
+    uint32_t csi1_ipp_csi_d_select_input_6;       /* +0x6B8 */
+    uint32_t csi1_ipp_csi_d_select_input_7;       /* +0x6BC */
+    uint32_t csi1_ipp_csi_d_select_input_8;       /* +0x6C0 */
+    uint32_t csi1_ipp_csi_d_select_input_9;       /* +0x6C4 */
+    uint32_t csi1_ipp_csi_d_select_input_11;       /* +0x6C8 */
+    uint32_t csi1_ipp_csi_d_select_input_12;       /* +0x6CC */
+    uint32_t csi1_ipp_csi_d_select_input_13;       /* +0x6D0 */
+    uint32_t csi1_ipp_csi_d_select_input_14;       /* +0x6D4 */
+    uint32_t csi1_ipp_csi_d_select_input_15;       /* +0x6D8 */
+    uint32_t csi1_ipp_csi_d_select_input_16;       /* +0x6DC */
+    uint32_t csi1_ipp_csi_d_select_input_17;       /* +0x6E0 */
+    uint32_t csi1_ipp_csi_d_select_input_18;       /* +0x6E4 */
+    uint32_t csi1_ipp_csi_d_select_input_19;       /* +0x6E8 */
+    uint32_t csi1_ipp_csi_d_select_input_20;       /* +0x6EC */
+    uint32_t csi1_ipp_csi_d_select_input_21;       /* +0x6F0 */
+    uint32_t csi1_ipp_csi_d_select_input_22;       /* +0x6F4 */
+    uint32_t csi1_ipp_csi_d_select_input_23;       /* +0x6F8 */
+    uint32_t csi1_ipp_csi_d_select_input_10;       /* +0x6FC */
+    uint32_t csi1_ipp_csi_hsync_select_input;       /* +0x700 */
+    uint32_t csi1_ipp_csi_pixclk_select_input;       /* +0x704 */
+    uint32_t csi1_ipp_csi_vsync_select_input;       /* +0x708 */
+    uint32_t csi1_ipp_csi_tvdecoder_in_field_select_input;       /* +0x70C */
+    uint32_t ecspi1_ipp_cspi_clk_in_select_input;   /* +0x710 */
+    uint32_t ecspi1_ipp_ind_miso_select_input;      /* +0x714 */
+    uint32_t ecspi1_ipp_ind_mosi_select_input;      /* +0x718 */
+    uint32_t ecspi1_ipp_ind_ss_b_select_input_0;    /* +0x71C */
+    uint32_t ecspi2_ipp_cspi_clk_in_select_input;   /* +0x720 */
+    uint32_t ecspi2_ipp_ind_miso_select_input;      /* +0x724 */
+    uint32_t ecspi2_ipp_ind_mosi_select_input;      /* +0x728 */
+    uint32_t ecspi2_ipp_ind_ss_b_select_input_0;    /* +0x72C */
+    uint32_t ecspi3_ipp_cspi_clk_in_select_input;   /* +0x730 */
+    uint32_t ecspi3_ipp_ind_miso_select_input;      /* +0x734 */
+    uint32_t ecspi3_ipp_ind_mosi_select_input;      /* +0x738 */
+    uint32_t ecspi3_ipp_ind_ss_b_select_input_0;    /* +0x73C */
+    uint32_t ecspi4_ipp_cspi_clk_in_select_input;   /* +0x740 */
+    uint32_t ecspi4_ipp_ind_miso_select_input;      /* +0x744 */
+    uint32_t ecspi4_ipp_ind_mosi_select_input;      /* +0x748 */
+    uint32_t ecspi4_ipp_ind_ss_b_select_input_0;    /* +0x74C */
+    uint32_t ecspi5_ipp_cspi_clk_in_select_input;   /* +0x750 */
+    uint32_t ecspi5_ipp_ind_miso_select_input;      /* +0x754 */
+    uint32_t ecspi5_ipp_ind_mosi_select_input;      /* +0x758 */
+    uint32_t ecspi5_ipp_ind_ss_b_select_input_0;    /* +0x75C */
+    uint32_t enet1_ipg_clk_rmii_select_input;       /* +0x760 */
+    uint32_t enet1_ipg_ind_mac0_mdio_select_input;  /* +0x764 */
+    uint32_t enet1_ipg_ind_mac0_rxclk_select_input; /* +0x768 */
+    uint32_t enet2_ipg_clk_rmii_select_input;       /* +0x76C */
+    uint32_t enet2_ipg_ind_mac0_mdio_select_input;  /* +0x770 */
+    uint32_t enet2_ipg_ind_mac0_rxclk_select_input; /* +0x774 */
+    uint32_t esai_ipp_ind_fsr_select_input;         /* +0x778 */
+    uint32_t esai_ipp_ind_fst_select_input;         /* +0x77C */
+    uint32_t esai_ipp_ind_hckr_select_input;        /* +0x780 */
+    uint32_t esai_ipp_ind_hckt_select_input;        /* +0x784 */
+    uint32_t esai_ipp_ind_sckr_select_input;        /* +0x788 */
+    uint32_t esai_ipp_ind_sckt_select_input;        /* +0x78C */
+    uint32_t esai_ipp_ind_sdo0_select_input;        /* +0x790 */
+    uint32_t esai_ipp_ind_sdo1_select_input;        /* +0x794 */
+    uint32_t esai_ipp_ind_sdo2_sdi3_select_input;   /* +0x798 */
+    uint32_t esai_ipp_ind_sdo3_sdi2_select_input;   /* +0x79C */
+    uint32_t esai_ipp_ind_sdo4_sdi1_select_input;   /* +0x7A0 */
+    uint32_t esai_ipp_ind_sdo5_sdi0_select_input;   /* +0x7A4 */
+    uint32_t i2c1_ipp_scl_in_select_input;          /* +0x7A8 */
+    uint32_t i2c1_ipp_sda_in_select_input;          /* +0x7AC */
+    uint32_t i2c2_ipp_scl_in_select_input;          /* +0x7B0 */
+    uint32_t i2c2_ipp_sda_in_select_input;          /* +0x7B4 */
+    uint32_t i2c3_ipp_scl_in_select_input;          /* +0x7B8 */
+    uint32_t i2c3_ipp_sda_in_select_input;          /* +0x7BC */
+    uint32_t i2c4_ipp_scl_in_select_input;          /* +0x7C0 */
+    uint32_t i2c4_ipp_sda_in_select_input;          /* +0x7C4 */
+    uint32_t kpp_ipp_ind_col_select_input_5;        /* +0x7C8 */
+    uint32_t kpp_ipp_ind_col_select_input_6;        /* +0x7CC */
+    uint32_t kpp_ipp_ind_col_select_input_7;        /* +0x7D0 */
+    uint32_t kpp_ipp_ind_row_select_input_5;        /* +0x7D4 */
+    uint32_t kpp_ipp_ind_row_select_input_6;        /* +0x7D8 */
+    uint32_t kpp_ipp_ind_row_select_input_7;        /* +0x7DC */
+    uint32_t lcd1_busy_select_input;                /* +0x7E0 */
+    uint32_t lcd2_busy_select_input;                /* +0x7E4 */
+    uint32_t mlb_mlb_clk_in_select_input;           /* +0x7E8 */
+    uint32_t mlb_mlb_data_in_select_input;          /* +0x7EC */
+    uint32_t mlb_mlb_sig_in_select_input;           /* +0x7F0 */
+    uint32_t sai1_ipp_ind_sai_rxbclk_select_input;  /* +0x7F4 */
+    uint32_t sai1_ipp_ind_sai_rxdata_select_input;  /* +0x7F8 */
+    uint32_t sai1_ipp_ind_sai_rxsync_select_input;  /* +0x7FC */
+    uint32_t sai1_ipp_ind_sai_txbclk_select_input;  /* +0x800 */
+    uint32_t sai1_ipp_ind_sai_txsync_select_input;  /* +0x804 */
+    uint32_t sai2_ipp_ind_sai_rxbclk_select_input;  /* +0x808 */
+    uint32_t sai2_ipp_ind_sai_rxdata_select_input;  /* +0x80C */
+    uint32_t sai2_ipp_ind_sai_rxsync_select_input;  /* +0x810 */
+    uint32_t sai2_ipp_ind_sai_txbclk_select_input;  /* +0x814 */
+    uint32_t sai2_ipp_ind_sai_txsync_select_input;  /* +0x818 */
+    uint32_t sdma_events_select_input_14;           /* +0x81C */
+    uint32_t sdma_events_select_input_15;           /* +0x820 */
+    uint32_t spdif_spdif_in1_select_input;          /* +0x824 */
+    uint32_t spdif_tx_clk2_select_input;            /* +0x828 */
+    uint32_t uart1_ipp_uart_rts_b_select_input;     /* +0x82C */
+    uint32_t uart1_ipp_uart_rxd_mux_select_input;   /* +0x830 */
+    uint32_t uart2_ipp_uart_rts_b_select_input;     /* +0x834 */
+    uint32_t uart2_ipp_uart_rxd_mux_select_input;   /* +0x838 */
+    uint32_t uart3_ipp_uart_rts_b_select_input;     /* +0x83C */
+    uint32_t uart3_ipp_uart_rxd_mux_select_input;   /* +0x840 */
+    uint32_t uart4_ipp_uart_rts_b_select_input;     /* +0x844 */
+    uint32_t uart4_ipp_uart_rxd_mux_select_input;   /* +0x848 */
+    uint32_t uart5_ipp_uart_rts_b_select_input;     /* +0x84C */
+    uint32_t uart5_ipp_uart_rxd_mux_select_input;   /* +0x850 */
+    uint32_t uart6_ipp_uart_rts_b_select_input;     /* +0x854 */
+    uint32_t uart6_ipp_uart_rxd_mux_select_input;   /* +0x858 */
+    uint32_t usb_ipp_ind_otg2_oc_select_input;      /* +0x85C */
+    uint32_t usb_ipp_ind_otg_oc_select_input;       /* +0x860 */
+    uint32_t usdhc1_ipp_card_det_select_input;      /* +0x864 */
+    uint32_t usdhc1_ipp_wp_on_select_input;         /* +0x868 */
+    uint32_t usdhc2_ipp_card_det_select_input;      /* +0x86C */
+    uint32_t usdhc2_ipp_wp_on_select_input;         /* +0x870 */
+    uint32_t usdhc4_ipp_card_det_select_input;      /* +0x874 */
+    uint32_t usdhc4_ipp_wp_on_select_input;         /* +0x878 */
+
+#else
+#error "unknown i.MX6 SOC"
+#endif
 };
 
+#ifdef CONFIG_PLAT_IMX6SX
+struct imx6sx_iomuxc_gpr_regs {
+    /*** GPR ***/
+    uint32_t gpr0;                              /* +0x000 */
+    uint32_t gpr1;                              /* +0x004 */
+    uint32_t gpr2;                              /* +0x008 */
+    uint32_t gpr3;                              /* +0x00C */
+    uint32_t gpr4;                              /* +0x010 */
+    uint32_t gpr5;                              /* +0x014 */
+    uint32_t gpr6;                              /* +0x018 */
+    uint32_t gpr7;                              /* +0x01C */
+    uint32_t gpr8;                              /* +0x020 */
+    uint32_t gpr9;                              /* +0x024 */
+    uint32_t gpr10;                             /* +0x028 */
+    uint32_t gpr11;                             /* +0x02C */
+    uint32_t gpr12;                             /* +0x030 */
+    uint32_t gpr13;                             /* +0x034 */
+};
+#endif
+
 static struct imx6_mux {
-    volatile struct imx6_iomuxc_regs* iomuxc;
+    volatile struct imx6_iomuxc_regs *iomuxc;
+#ifdef CONFIG_PLAT_IMX6SX
+    volatile struct imx6sx_iomuxc_gpr_regs *iomuxc_gpr;
+#endif
 } _mux;
 
-static inline struct imx6_mux* get_mux_priv(const mux_sys_t* mux) {
-    return (struct imx6_mux*)mux->priv;
+static inline struct imx6_mux *get_mux_priv(const mux_sys_t *mux)
+{
+    return (struct imx6_mux *)mux->priv;
 }
 
-static inline void set_mux_priv(mux_sys_t* mux, struct imx6_mux* imx6_mux)
+static inline void set_mux_priv(mux_sys_t *mux, struct imx6_mux *imx6_mux)
 {
     assert(mux != NULL);
     assert(imx6_mux != NULL);
     mux->priv = imx6_mux;
 }
 
-static int
-imx6_mux_feature_enable(const mux_sys_t* mux, mux_feature_t mux_feature, UNUSED enum mux_gpio_dir mgd)
+static int imx6_mux_feature_enable(const mux_sys_t *mux, mux_feature_t mux_feature, UNUSED enum mux_gpio_dir mgd)
 {
-    struct imx6_mux* m;
+    struct imx6_mux *m;
     if (mux == NULL || mux->priv == NULL) {
         return -1;
     }
     m = get_mux_priv(mux);
 
+#if defined(CONFIG_PLAT_IMX6DQ)
+
     assert(((int)&m->iomuxc->usdhc1_wp_on_select_input & 0xfff) == 0x94C);
+
+#elif defined(CONFIG_PLAT_IMX6SX)
+
+    assert(((int)&m->iomuxc->usdhc4_ipp_wp_on_select_input & 0xfff) == 0x878);
+
+#else
+#error "unknown i.MX6 SOC"
+#endif
+
     switch (mux_feature) {
+
+#if defined(CONFIG_PLAT_IMX6DQ)
+
     case MUX_I2C1:
         ZF_LOGD("Muxing for I2C1\n");
         m->iomuxc->i2c1_scl_in_select_input  = IOMUXC_IS_DAISY(0x0);
@@ -697,22 +1297,62 @@
         m->iomuxc->uart1_uart_rx_data_select_input  = IOMUXC_IS_DAISY(3);
         return 0;
 
+#elif defined(CONFIG_PLAT_IMX6SX)
+
+    case MUX_I2C1:
+        ZF_LOGD("Muxing for I2C1\n");
+        m->iomuxc->i2c1_ipp_scl_in_select_input  = IOMUXC_IS_DAISY(0x1);
+        m->iomuxc->sw_mux_ctl_pad_gpio1_io00 = IOMUXC_MUXCTL_MODE(0)
+                                               | IOMUXC_MUXCTL_FORCE_INPUT;
+
+        m->iomuxc->i2c1_ipp_sda_in_select_input  = IOMUXC_IS_DAISY(0x1);
+        m->iomuxc->sw_mux_ctl_pad_gpio1_io01 = IOMUXC_MUXCTL_MODE(0)
+                                               | IOMUXC_MUXCTL_FORCE_INPUT;
+        return 0;
+    case MUX_I2C2:
+        ZF_LOGD("Muxing for I2C2\n");
+        m->iomuxc->i2c2_ipp_scl_in_select_input = IOMUXC_IS_DAISY(0x1);
+        m->iomuxc->sw_mux_ctl_pad_gpio1_io02  = IOMUXC_MUXCTL_MODE(0)
+                                                | IOMUXC_MUXCTL_FORCE_INPUT;
+        m->iomuxc->i2c2_ipp_sda_in_select_input = IOMUXC_IS_DAISY(0x1);
+        m->iomuxc->sw_mux_ctl_pad_gpio1_io03  = IOMUXC_MUXCTL_MODE(0)
+                                                | IOMUXC_MUXCTL_FORCE_INPUT;
+        return 0;
+    case MUX_I2C3:
+        ZF_LOGD("Muxing for I2C3\n");
+        m->iomuxc->i2c3_ipp_scl_in_select_input = IOMUXC_IS_DAISY(0x2);
+        m->iomuxc->sw_mux_ctl_pad_key_col4    = IOMUXC_MUXCTL_MODE(2)
+                                                | IOMUXC_MUXCTL_FORCE_INPUT;
+        m->iomuxc->i2c3_ipp_sda_in_select_input = IOMUXC_IS_DAISY(0x2);
+        m->iomuxc->sw_mux_ctl_pad_key_row4    = IOMUXC_MUXCTL_MODE(2)
+                                                | IOMUXC_MUXCTL_FORCE_INPUT;
+        return 0;
+    case MUX_GPIO11_CLKO1:
+        ZF_LOGD("Muxing CLKO1 to MUX11\n");
+        m->iomuxc->sw_mux_ctl_pad_gpio1_io11    = IOMUXC_MUXCTL_MODE(3);
+        return 0;
+
+#else
+#error "unknown i.MX6 SOC"
+#endif
+
     default:
         return -1;
     }
 }
 
-int
-imx6_mux_enable_gpio(mux_sys_t* mux_sys, int gpio_id)
+int imx6_mux_enable_gpio(mux_sys_t *mux_sys, int gpio_id)
 {
-    static struct imx6_mux* m;
+    static struct imx6_mux *m;
     volatile uint32_t *reg;
     assert(mux_sys);
-    m = (struct imx6_mux*)mux_sys->priv;
+    m = (struct imx6_mux *)mux_sys->priv;
     assert(m);
     /* Surely there is a mathematical formula for finding the register to be set? */
     switch (gpio_id) {
 
+#if defined(CONFIG_PLAT_IMX6DQ)
+
     case GPIOID(GPIO_BANK1,  0):
         reg = &m->iomuxc->sw_mux_ctl_pad_gpio00;
         break;
@@ -783,6 +1423,79 @@
         reg = &m->iomuxc->sw_mux_ctl_pad_nand_data07;
         break;
 
+#elif defined(CONFIG_PLAT_IMX6SX)
+
+    case GPIOID(GPIO_BANK1,  0):
+        reg = &m->iomuxc->sw_mux_ctl_pad_gpio1_io00;
+        break;
+    case GPIOID(GPIO_BANK1,  1):
+        reg = &m->iomuxc->sw_mux_ctl_pad_gpio1_io01;
+        break;
+    case GPIOID(GPIO_BANK1,  2):
+        reg = &m->iomuxc->sw_mux_ctl_pad_gpio1_io02;
+        break;
+    case GPIOID(GPIO_BANK1,  3):
+        reg = &m->iomuxc->sw_mux_ctl_pad_gpio1_io03;
+        break;
+    case GPIOID(GPIO_BANK1,  4):
+        reg = &m->iomuxc->sw_mux_ctl_pad_gpio1_io04;
+        break;
+    case GPIOID(GPIO_BANK1,  5):
+        reg = &m->iomuxc->sw_mux_ctl_pad_gpio1_io05;
+        break;
+    case GPIOID(GPIO_BANK1,  6):
+        reg = &m->iomuxc->sw_mux_ctl_pad_gpio1_io06;
+        break;
+    case GPIOID(GPIO_BANK1,  7):
+        reg = &m->iomuxc->sw_mux_ctl_pad_gpio1_io07;
+        break;
+    case GPIOID(GPIO_BANK1,  8):
+        reg = &m->iomuxc->sw_mux_ctl_pad_gpio1_io08;
+        break;
+    case GPIOID(GPIO_BANK1,  9):
+        reg = &m->iomuxc->sw_mux_ctl_pad_gpio1_io09;
+        break;
+    case GPIOID(GPIO_BANK1,  10):
+        reg = &m->iomuxc->sw_mux_ctl_pad_gpio1_io10;
+        break;
+    case GPIOID(GPIO_BANK1,  11):
+        reg = &m->iomuxc->sw_mux_ctl_pad_gpio1_io11;
+        break;
+    case GPIOID(GPIO_BANK1,  12):
+        reg = &m->iomuxc->sw_mux_ctl_pad_gpio1_io12;
+        break;
+    case GPIOID(GPIO_BANK1,  13):
+        reg = &m->iomuxc->sw_mux_ctl_pad_gpio1_io13;
+        break;
+
+    case GPIOID(GPIO_BANK4,  4):
+        reg = &m->iomuxc->sw_mux_ctl_pad_nand_data00;
+        break;
+    case GPIOID(GPIO_BANK4,  5):
+        reg = &m->iomuxc->sw_mux_ctl_pad_nand_data01;
+        break;
+    case GPIOID(GPIO_BANK4,  6):
+        reg = &m->iomuxc->sw_mux_ctl_pad_nand_data02;
+        break;
+    case GPIOID(GPIO_BANK4,  7):
+        reg = &m->iomuxc->sw_mux_ctl_pad_nand_data03;
+        break;
+    case GPIOID(GPIO_BANK4,  8):
+        reg = &m->iomuxc->sw_mux_ctl_pad_nand_data04;
+        break;
+    case GPIOID(GPIO_BANK4,  9):
+        reg = &m->iomuxc->sw_mux_ctl_pad_nand_data05;
+        break;
+    case GPIOID(GPIO_BANK4,  10):
+        reg = &m->iomuxc->sw_mux_ctl_pad_nand_data06;
+        break;
+    case GPIOID(GPIO_BANK4,  11):
+        reg = &m->iomuxc->sw_mux_ctl_pad_nand_data07;
+        break;
+#else
+#error Invalid platform defined.
+#endif
+
     default:
         ZF_LOGD("Unable to mux GPIOID 0x%x\n", gpio_id);
         return -1;
@@ -791,8 +1504,9 @@
     return 0;
 }
 
-static void *imx6_mux_get_vaddr(const mux_sys_t *mux) {
-    struct imx6_mux* m;
+static void *imx6_mux_get_vaddr(const mux_sys_t *mux)
+{
+    struct imx6_mux *m;
     if (mux == NULL || mux->priv == NULL) {
         return NULL;
     }
@@ -800,8 +1514,7 @@
     return (void *)m->iomuxc;
 }
 
-static int
-imx6_mux_init_common(mux_sys_t* mux)
+static int imx6_mux_init_common(mux_sys_t *mux)
 {
     set_mux_priv(mux, &_mux);
     mux->feature_enable = &imx6_mux_feature_enable;
@@ -809,8 +1522,7 @@
     return 0;
 }
 
-int
-imx6_mux_init(void* iomuxc, mux_sys_t* mux)
+int imx6_mux_init(void *iomuxc, mux_sys_t *mux)
 {
     if (iomuxc != NULL) {
         _mux.iomuxc = iomuxc;
@@ -818,9 +1530,24 @@
     return imx6_mux_init_common(mux);
 }
 
-int
-mux_sys_init(ps_io_ops_t* io_ops, UNUSED void *dependencies, mux_sys_t* mux)
+#ifdef CONFIG_PLAT_IMX6SX
+int imx6sx_mux_init_split(void *iomuxc, void *iomuxc_gpr, mux_sys_t *mux)
+{
+    if (iomuxc != NULL) {
+        _mux.iomuxc = iomuxc;
+    }
+    if (iomuxc_gpr != NULL) {
+        _mux.iomuxc_gpr = iomuxc_gpr;
+    }
+    return imx6_mux_init_common(mux);
+}
+#endif
+
+int mux_sys_init(ps_io_ops_t *io_ops, UNUSED void *dependencies, mux_sys_t *mux)
 {
     MAP_IF_NULL(io_ops, IMX6_IOMUXC, _mux.iomuxc);
+#ifdef CONFIG_PLAT_IMX6SX
+    MAP_IF_NULL(io_ops, IMX6_IOMUXC_GPR, _mux.iomuxc_gpr);
+#endif
     return imx6_mux_init_common(mux);
 }
diff --git a/libplatsupport/src/plat/imx6/mux.h b/libplatsupport/src/plat/imx6/mux.h
index 216e883..f1c511e 100644
--- a/libplatsupport/src/plat/imx6/mux.h
+++ b/libplatsupport/src/plat/imx6/mux.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/mux.h>
diff --git a/libplatsupport/src/plat/imx6/src.c b/libplatsupport/src/plat/imx6/src.c
index d71cece..540bc56 100644
--- a/libplatsupport/src/plat/imx6/src.c
+++ b/libplatsupport/src/plat/imx6/src.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <platsupport/src.h>
 
diff --git a/libplatsupport/src/plat/imx7/chardev.c b/libplatsupport/src/plat/imx7/chardev.c
index 5f1a3c9..10f9e1d 100644
--- a/libplatsupport/src/plat/imx7/chardev.c
+++ b/libplatsupport/src/plat/imx7/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libplatsupport/src/plat/imx7/gpio.c b/libplatsupport/src/plat/imx7/gpio.c
index b28c9ee..dd28349 100644
--- a/libplatsupport/src/plat/imx7/gpio.c
+++ b/libplatsupport/src/plat/imx7/gpio.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdint.h>
diff --git a/libplatsupport/src/plat/imx7/i2c.c b/libplatsupport/src/plat/imx7/i2c.c
index 8a8ae5a..1685e55 100644
--- a/libplatsupport/src/plat/imx7/i2c.c
+++ b/libplatsupport/src/plat/imx7/i2c.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/i2c.h>
diff --git a/libplatsupport/src/plat/imx8m/chardev.c b/libplatsupport/src/plat/imx8m/chardev.c
index c7bc8d1..6ed9646 100644
--- a/libplatsupport/src/plat/imx8m/chardev.c
+++ b/libplatsupport/src/plat/imx8m/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libplatsupport/src/plat/imx8m/clock.c b/libplatsupport/src/plat/imx8m/clock.c
index 177b3ac..9ccc5d7 100644
--- a/libplatsupport/src/plat/imx8m/clock.c
+++ b/libplatsupport/src/plat/imx8m/clock.c
@@ -1,15 +1,9 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <platsupport/clock.h>
 
-clk_t *ps_clocks[];
-freq_t ps_freq_default[];
+clk_t *ps_clocks[] = {};
+freq_t ps_freq_default[] = {};
diff --git a/libplatsupport/src/plat/odroidc2/chardev.c b/libplatsupport/src/plat/odroidc2/chardev.c
index dd18147..cccf464 100644
--- a/libplatsupport/src/plat/odroidc2/chardev.c
+++ b/libplatsupport/src/plat/odroidc2/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libplatsupport/src/plat/odroidc2/ltimer.c b/libplatsupport/src/plat/odroidc2/ltimer.c
index 5cf033a..81bedb2 100644
--- a/libplatsupport/src/plat/odroidc2/ltimer.c
+++ b/libplatsupport/src/plat/odroidc2/ltimer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/ltimer.h>
diff --git a/libplatsupport/src/plat/odroidc2/meson_timer.c b/libplatsupport/src/plat/odroidc2/meson_timer.c
index 3bf1608..409095f 100644
--- a/libplatsupport/src/plat/odroidc2/meson_timer.c
+++ b/libplatsupport/src/plat/odroidc2/meson_timer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <errno.h>
diff --git a/libplatsupport/src/plat/odroidc2/serial.c b/libplatsupport/src/plat/odroidc2/serial.c
index c7c4135..92cd388 100644
--- a/libplatsupport/src/plat/odroidc2/serial.c
+++ b/libplatsupport/src/plat/odroidc2/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <string.h>
diff --git a/libplatsupport/src/plat/odroidc4 b/libplatsupport/src/plat/odroidc4
new file mode 120000
index 0000000..a5dd83c
--- /dev/null
+++ b/libplatsupport/src/plat/odroidc4
@@ -0,0 +1 @@
+odroidc2
\ No newline at end of file
diff --git a/libplatsupport/src/plat/omap3/chardev.c b/libplatsupport/src/plat/omap3/chardev.c
index 6280e2b..34b29b4 100644
--- a/libplatsupport/src/plat/omap3/chardev.c
+++ b/libplatsupport/src/plat/omap3/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /*
diff --git a/libplatsupport/src/plat/omap3/clock.c b/libplatsupport/src/plat/omap3/clock.c
index 42cb482..0d18058 100644
--- a/libplatsupport/src/plat/omap3/clock.c
+++ b/libplatsupport/src/plat/omap3/clock.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include "../../arch/arm/clock.h"
 #include "../../services.h"
diff --git a/libplatsupport/src/plat/omap3/mux.c b/libplatsupport/src/plat/omap3/mux.c
index 7470733..1d458e1 100644
--- a/libplatsupport/src/plat/omap3/mux.c
+++ b/libplatsupport/src/plat/omap3/mux.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <stdint.h>
 #include <utils/attribute.h>
diff --git a/libplatsupport/src/plat/omap3/serial.c b/libplatsupport/src/plat/omap3/serial.c
index 201bf36..25bbdcf 100644
--- a/libplatsupport/src/plat/omap3/serial.c
+++ b/libplatsupport/src/plat/omap3/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include "../../chardev.h"
diff --git a/libplatsupport/src/plat/omap3/timerdev.h b/libplatsupport/src/plat/omap3/timerdev.h
index 1dd3f8f..8ebf7ec 100644
--- a/libplatsupport/src/plat/omap3/timerdev.h
+++ b/libplatsupport/src/plat/omap3/timerdev.h
@@ -1,11 +1,5 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
diff --git a/libplatsupport/src/plat/pc99/acpi/acpi.c b/libplatsupport/src/plat/pc99/acpi/acpi.c
index 01a908e..0e99d1f 100644
--- a/libplatsupport/src/plat/pc99/acpi/acpi.c
+++ b/libplatsupport/src/plat/pc99/acpi/acpi.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/plat/acpi/acpi.h>
diff --git a/libplatsupport/src/plat/pc99/acpi/acpi.h b/libplatsupport/src/plat/pc99/acpi/acpi.h
index 32bbe52..1103762 100644
--- a/libplatsupport/src/plat/pc99/acpi/acpi.h
+++ b/libplatsupport/src/plat/pc99/acpi/acpi.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /*
diff --git a/libplatsupport/src/plat/pc99/acpi/browser.c b/libplatsupport/src/plat/pc99/acpi/browser.c
index 363a18c..48c28f6 100644
--- a/libplatsupport/src/plat/pc99/acpi/browser.c
+++ b/libplatsupport/src/plat/pc99/acpi/browser.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include "browser.h"
diff --git a/libplatsupport/src/plat/pc99/acpi/browser.h b/libplatsupport/src/plat/pc99/acpi/browser.h
index 7699d87..2d2f205 100644
--- a/libplatsupport/src/plat/pc99/acpi/browser.h
+++ b/libplatsupport/src/plat/pc99/acpi/browser.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/plat/acpi/acpi.h>
diff --git a/libplatsupport/src/plat/pc99/acpi/printer.c b/libplatsupport/src/plat/pc99/acpi/printer.c
index 81415c9..76d8c18 100644
--- a/libplatsupport/src/plat/pc99/acpi/printer.c
+++ b/libplatsupport/src/plat/pc99/acpi/printer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include "printer.h"
diff --git a/libplatsupport/src/plat/pc99/acpi/printer.h b/libplatsupport/src/plat/pc99/acpi/printer.h
index 8e34aac..b303f85 100644
--- a/libplatsupport/src/plat/pc99/acpi/printer.h
+++ b/libplatsupport/src/plat/pc99/acpi/printer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <autoconf.h>
diff --git a/libplatsupport/src/plat/pc99/acpi/regions.c b/libplatsupport/src/plat/pc99/acpi/regions.c
index bfdc4d3..18d438c 100644
--- a/libplatsupport/src/plat/pc99/acpi/regions.c
+++ b/libplatsupport/src/plat/pc99/acpi/regions.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/plat/acpi/regions.h>
diff --git a/libplatsupport/src/plat/pc99/acpi/regions.h b/libplatsupport/src/plat/pc99/acpi/regions.h
index 728d8ae..92fc9d9 100644
--- a/libplatsupport/src/plat/pc99/acpi/regions.h
+++ b/libplatsupport/src/plat/pc99/acpi/regions.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/src/plat/pc99/acpi/walker.c b/libplatsupport/src/plat/pc99/acpi/walker.c
index 5b3b050..9e0f871 100644
--- a/libplatsupport/src/plat/pc99/acpi/walker.c
+++ b/libplatsupport/src/plat/pc99/acpi/walker.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/plat/acpi/acpi.h>
diff --git a/libplatsupport/src/plat/pc99/acpi/walker.h b/libplatsupport/src/plat/pc99/acpi/walker.h
index 64fa036..5f29a88 100644
--- a/libplatsupport/src/plat/pc99/acpi/walker.h
+++ b/libplatsupport/src/plat/pc99/acpi/walker.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdbool.h>
diff --git a/libplatsupport/src/plat/pc99/chardev.c b/libplatsupport/src/plat/pc99/chardev.c
index 67a9277..561f9d0 100644
--- a/libplatsupport/src/plat/pc99/chardev.c
+++ b/libplatsupport/src/plat/pc99/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /*
diff --git a/libplatsupport/src/plat/pc99/ega.c b/libplatsupport/src/plat/pc99/ega.c
index 1297666..5133820 100644
--- a/libplatsupport/src/plat/pc99/ega.c
+++ b/libplatsupport/src/plat/pc99/ega.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 /*
  * Implementation of an 80x25 EGA text mode. All the functions are named with 'serial' since
diff --git a/libplatsupport/src/plat/pc99/ega.h b/libplatsupport/src/plat/pc99/ega.h
index 084bc15..92efd01 100644
--- a/libplatsupport/src/plat/pc99/ega.h
+++ b/libplatsupport/src/plat/pc99/ega.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/src/plat/pc99/hpet.c b/libplatsupport/src/plat/pc99/hpet.c
index 0fa7a53..a54b697 100644
--- a/libplatsupport/src/plat/pc99/hpet.c
+++ b/libplatsupport/src/plat/pc99/hpet.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <autoconf.h>
@@ -106,22 +100,22 @@
 
 static inline uint64_t *hpet_get_general_config(void *vaddr)
 {
-    return (uint64_t*)((uintptr_t)vaddr + GENERAL_CONFIG_REG);
+    return (uint64_t *)((uintptr_t)vaddr + GENERAL_CONFIG_REG);
 }
 
 static inline uint64_t *hpet_get_main_counter(void *vaddr)
 {
-    return (uint64_t*)((uintptr_t)vaddr + MAIN_COUNTER_REG);
+    return (uint64_t *)((uintptr_t)vaddr + MAIN_COUNTER_REG);
 }
 
 static inline uint64_t *hpet_get_cap_id(void *vaddr)
 {
-    return (uint64_t*)((uintptr_t)vaddr + CAP_ID_REG);
+    return (uint64_t *)((uintptr_t)vaddr + CAP_ID_REG);
 }
 
 static inline hpet_timer_t *hpet_get_hpet_timer(void *vaddr, unsigned int timer)
 {
-    return ((hpet_timer_t*)((uintptr_t)vaddr + TIMERS_OFFSET)) + timer;
+    return ((hpet_timer_t *)((uintptr_t)vaddr + TIMERS_OFFSET)) + timer;
 }
 
 int hpet_start(const hpet_t *hpet)
@@ -129,7 +123,10 @@
 
     hpet_timer_t *timer = hpet_get_hpet_timer(hpet->base_addr, 0);
     /* enable the global timer */
-    *hpet_get_general_config(hpet->base_addr) |= BIT(ENABLE_CNF);
+    /* volatile is used here to try and prevent the compiler from satisfying this
+       bitwise operation via byte only reads and writes. */
+    volatile uint64_t *general_config = hpet_get_general_config(hpet->base_addr);
+    *general_config |= BIT(ENABLE_CNF);
 
     /* make sure the comparator is 0 before we turn time0 on*/
     timer->comparator = 0llu;
@@ -166,7 +163,8 @@
         time = *hpet_get_main_counter(hpet->base_addr);
         COMPILER_MEMORY_ACQUIRE();
         /* race condition on 32-bit systems: check the bottom 32 bits didn't overflow */
-    } while (CONFIG_WORD_SIZE == 32 && ((uint32_t) (time >> 32llu)) != ((uint32_t *)hpet_get_main_counter(hpet->base_addr))[1]);
+    } while (CONFIG_WORD_SIZE == 32
+             && ((uint32_t)(time >> 32llu)) != ((uint32_t *)hpet_get_main_counter(hpet->base_addr))[1]);
 
     return time * hpet->period_ns;
 }
@@ -262,7 +260,7 @@
     COMPILER_MEMORY_RELEASE();
 
     /* read the period of the timer (its in femptoseconds) and calculate no of ticks per ns */
-    uint32_t tick_period_fs = (uint32_t) (*hpet_get_cap_id(hpet->base_addr) >> 32llu);
+    uint32_t tick_period_fs = (uint32_t)(*hpet_get_cap_id(hpet->base_addr) >> 32llu);
     hpet->period_ns = tick_period_fs / 1000000;
 
     return 0;
diff --git a/libplatsupport/src/plat/pc99/keyboard_chardev.c b/libplatsupport/src/plat/pc99/keyboard_chardev.c
index 4dc95f7..442fa18 100644
--- a/libplatsupport/src/plat/pc99/keyboard_chardev.c
+++ b/libplatsupport/src/plat/pc99/keyboard_chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include "keyboard_chardev.h"
diff --git a/libplatsupport/src/plat/pc99/keyboard_chardev.h b/libplatsupport/src/plat/pc99/keyboard_chardev.h
index aa69380..d99667d 100644
--- a/libplatsupport/src/plat/pc99/keyboard_chardev.h
+++ b/libplatsupport/src/plat/pc99/keyboard_chardev.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/src/plat/pc99/keyboard_ps2.c b/libplatsupport/src/plat/pc99/keyboard_ps2.c
index 728262d..964c6dd 100644
--- a/libplatsupport/src/plat/pc99/keyboard_ps2.c
+++ b/libplatsupport/src/plat/pc99/keyboard_ps2.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include "keyboard_ps2.h"
diff --git a/libplatsupport/src/plat/pc99/keyboard_ps2.h b/libplatsupport/src/plat/pc99/keyboard_ps2.h
index 92aa85c..c533a3b 100644
--- a/libplatsupport/src/plat/pc99/keyboard_ps2.h
+++ b/libplatsupport/src/plat/pc99/keyboard_ps2.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/src/plat/pc99/keyboard_vkey.c b/libplatsupport/src/plat/pc99/keyboard_vkey.c
index b41d6ef..008ae9c 100644
--- a/libplatsupport/src/plat/pc99/keyboard_vkey.c
+++ b/libplatsupport/src/plat/pc99/keyboard_vkey.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include "keyboard_vkey.h"
diff --git a/libplatsupport/src/plat/pc99/keyboard_vkey.h b/libplatsupport/src/plat/pc99/keyboard_vkey.h
index 308d46b..cccbe93 100644
--- a/libplatsupport/src/plat/pc99/keyboard_vkey.h
+++ b/libplatsupport/src/plat/pc99/keyboard_vkey.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/src/plat/pc99/ltimer.c b/libplatsupport/src/plat/pc99/ltimer.c
index f93f1a8..cff1a19 100644
--- a/libplatsupport/src/plat/pc99/ltimer.c
+++ b/libplatsupport/src/plat/pc99/ltimer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 /* Implementation of a logical timer for pc99 platforms
  *
diff --git a/libplatsupport/src/plat/pc99/pit.c b/libplatsupport/src/plat/pc99/pit.c
index 3f986b2..513e032 100644
--- a/libplatsupport/src/plat/pc99/pit.c
+++ b/libplatsupport/src/plat/pc99/pit.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <errno.h>
diff --git a/libplatsupport/src/plat/pc99/rtc.c b/libplatsupport/src/plat/pc99/rtc.c
index 9d78b43..44b22cb 100644
--- a/libplatsupport/src/plat/pc99/rtc.c
+++ b/libplatsupport/src/plat/pc99/rtc.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* Some code from here was taken from http://wiki.osdev.org/CMOS
@@ -26,7 +20,7 @@
 static inline int current_year()
 {
 #ifdef __DATE__
-    return atoi(__DATE__ + 7);
+    return atoi(&__DATE__[7]);
 #else
     return 2014;
 #endif
@@ -144,6 +138,6 @@
         ZF_LOGE("ACPI has no FADT header. Your BIOS is broken");
         return 0;
     }
-    acpi_fadt_t *fadt = (acpi_fadt_t*)header;
+    acpi_fadt_t *fadt = (acpi_fadt_t *)header;
     return fadt->century;
 }
diff --git a/libplatsupport/src/plat/pc99/serial.c b/libplatsupport/src/plat/pc99/serial.c
index da31d1a..22888c8 100644
--- a/libplatsupport/src/plat/pc99/serial.c
+++ b/libplatsupport/src/plat/pc99/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdlib.h>
diff --git a/libplatsupport/src/plat/polarfire/chardev.c b/libplatsupport/src/plat/polarfire/chardev.c
index 835ff0a..743fb7e 100644
--- a/libplatsupport/src/plat/polarfire/chardev.c
+++ b/libplatsupport/src/plat/polarfire/chardev.c
@@ -1,11 +1,7 @@
 /*
  * Copyright 2020, DornerWorks
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DORNERWORKS_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libplatsupport/src/plat/polarfire/uart.c b/libplatsupport/src/plat/polarfire/uart.c
index de7182b..6ad4ec6 100644
--- a/libplatsupport/src/plat/polarfire/uart.c
+++ b/libplatsupport/src/plat/polarfire/uart.c
@@ -1,11 +1,7 @@
 /*
  * Copyright 2020, DornerWorks
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DORNERWORKS_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <autoconf.h>
diff --git a/libplatsupport/src/plat/qemu-arm-virt/chardev.c b/libplatsupport/src/plat/qemu-arm-virt/chardev.c
index b323fc6..2a44074 100644
--- a/libplatsupport/src/plat/qemu-arm-virt/chardev.c
+++ b/libplatsupport/src/plat/qemu-arm-virt/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libplatsupport/src/plat/qemu-arm-virt/serial.c b/libplatsupport/src/plat/qemu-arm-virt/serial.c
index 260d704..47b665e 100644
--- a/libplatsupport/src/plat/qemu-arm-virt/serial.c
+++ b/libplatsupport/src/plat/qemu-arm-virt/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* Mostly copy/paste from the HiKey plat.
diff --git a/libplatsupport/src/plat/rocketchip/chardev.c b/libplatsupport/src/plat/rocketchip/chardev.c
index 3b54e7a..0ad021d 100644
--- a/libplatsupport/src/plat/rocketchip/chardev.c
+++ b/libplatsupport/src/plat/rocketchip/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include "../../chardev.h"
diff --git a/libplatsupport/src/plat/rocketchip/serial.c b/libplatsupport/src/plat/rocketchip/serial.c
index 47b24c2..921b151 100644
--- a/libplatsupport/src/plat/rocketchip/serial.c
+++ b/libplatsupport/src/plat/rocketchip/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdlib.h>
diff --git a/libplatsupport/src/plat/rockpro64/chardev.c b/libplatsupport/src/plat/rockpro64/chardev.c
index 6bf3d7c..c6885bf 100644
--- a/libplatsupport/src/plat/rockpro64/chardev.c
+++ b/libplatsupport/src/plat/rockpro64/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libplatsupport/src/plat/rockpro64/ltimer.c b/libplatsupport/src/plat/rockpro64/ltimer.c
index 1a67514..df9c169 100644
--- a/libplatsupport/src/plat/rockpro64/ltimer.c
+++ b/libplatsupport/src/plat/rockpro64/ltimer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* Implementation of a logical timer for rockpro64
diff --git a/libplatsupport/src/plat/rockpro64/serial.c b/libplatsupport/src/plat/rockpro64/serial.c
index 7b4a808..a7a2462 100644
--- a/libplatsupport/src/plat/rockpro64/serial.c
+++ b/libplatsupport/src/plat/rockpro64/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <string.h>
diff --git a/libplatsupport/src/plat/rockpro64/timer.c b/libplatsupport/src/plat/rockpro64/timer.c
index d3f6baf..b9f8562 100644
--- a/libplatsupport/src/plat/rockpro64/timer.c
+++ b/libplatsupport/src/plat/rockpro64/timer.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdio.h>
diff --git a/libplatsupport/src/plat/spike/chardev.c b/libplatsupport/src/plat/spike/chardev.c
index 9690fc0..5cffafc 100644
--- a/libplatsupport/src/plat/spike/chardev.c
+++ b/libplatsupport/src/plat/spike/chardev.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include "../../chardev.h"
 #include "../../common.h"
diff --git a/libplatsupport/src/plat/spike/serial.c b/libplatsupport/src/plat/spike/serial.c
index aa2b0e7..aceb9c6 100644
--- a/libplatsupport/src/plat/spike/serial.c
+++ b/libplatsupport/src/plat/spike/serial.c
@@ -1,23 +1,19 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <stdlib.h>
 #include <platsupport/serial.h>
 #include <platsupport/plat/serial.h>
+#include "../../chardev.h"
 #include <string.h>
 
 
-int uart_init(const struct dev_defn* defn,
-              const ps_io_ops_t* ops,
-              ps_chardevice_t* dev)
+int uart_init(
+    const struct dev_defn *defn UNUSED,
+    const ps_io_ops_t *ops UNUSED,
+    ps_chardevice_t *dev UNUSED)
 {
     return 0;
 }
diff --git a/libplatsupport/src/plat/tk1/clock.c b/libplatsupport/src/plat/tk1/clock.c
index 4cb01d0..8836ca9 100644
--- a/libplatsupport/src/plat/tk1/clock.c
+++ b/libplatsupport/src/plat/tk1/clock.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdio.h>
diff --git a/libplatsupport/src/plat/tk1/gpio.c b/libplatsupport/src/plat/tk1/gpio.c
index 6d7e817..c4d28fc 100644
--- a/libplatsupport/src/plat/tk1/gpio.c
+++ b/libplatsupport/src/plat/tk1/gpio.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <stddef.h>
 
diff --git a/libplatsupport/src/plat/tk1/i2c.c b/libplatsupport/src/plat/tk1/i2c.c
index 9f1bdf6..47b78d3 100644
--- a/libplatsupport/src/plat/tk1/i2c.c
+++ b/libplatsupport/src/plat/tk1/i2c.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <stdbool.h>
 #include <assert.h>
diff --git a/libplatsupport/src/plat/tk1/mux.c b/libplatsupport/src/plat/tk1/mux.c
index 58567c1..8f28564 100644
--- a/libplatsupport/src/plat/tk1/mux.c
+++ b/libplatsupport/src/plat/tk1/mux.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <autoconf.h>
diff --git a/libplatsupport/src/plat/tk1/mux_gpio_priv.h b/libplatsupport/src/plat/tk1/mux_gpio_priv.h
index e5f4bb0..82b256a 100644
--- a/libplatsupport/src/plat/tk1/mux_gpio_priv.h
+++ b/libplatsupport/src/plat/tk1/mux_gpio_priv.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libplatsupport/src/plat/tk1/mux_gpio_shared.c b/libplatsupport/src/plat/tk1/mux_gpio_shared.c
index 6823968..b6c1d4e 100644
--- a/libplatsupport/src/plat/tk1/mux_gpio_shared.c
+++ b/libplatsupport/src/plat/tk1/mux_gpio_shared.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <platsupport/plat/mux.h>
 
diff --git a/libplatsupport/src/plat/tk1/spi.c b/libplatsupport/src/plat/tk1/spi.c
index d6e2043..dd21472 100644
--- a/libplatsupport/src/plat/tk1/spi.c
+++ b/libplatsupport/src/plat/tk1/spi.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdio.h>
diff --git a/libplatsupport/src/plat/tqma8xqp1gb/chardev.c b/libplatsupport/src/plat/tqma8xqp1gb/chardev.c
new file mode 100644
index 0000000..9ead618
--- /dev/null
+++ b/libplatsupport/src/plat/tqma8xqp1gb/chardev.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2021, Breakaway Consulting Pty. Ltd.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+/*
+ * TQMa8XQP support a single UART (UART1 on the iMX8).
+ *
+ * Although there are four UARTs in the SoC only UART1
+ * is configured by the bootloader software to be powered-on
+ * and available in a root-server.
+ *
+ * Powering on additional UARTs requires an implementation
+ * of the SCFW API to make calls on the SCU chipset, which
+ * is beyond the scope of this platform port.
+ */
+#include "../../chardev.h"
+
+static const struct dev_defn defn = {
+    .id = PS_SERIAL_DEFAULT,
+    .paddr = 0x5a070000,
+    /* Note: The actual register block is 64k in size, but
+     * chardev_map only supports mapping a single page-size
+     * register block, and in practise there aren't very
+     * many registers anyway! */
+    .size = BIT(12),
+    .init_fn = uart_init,
+};
+
+struct ps_chardevice *
+ps_cdev_init(enum chardev_id id, const ps_io_ops_t *o, struct ps_chardevice *d)
+{
+    if (id != PS_SERIAL_DEFAULT) {
+        /*
+         * Only the PS_SERIAL_DEFAULT is supported, so return error
+         * on any other value
+         */
+        return NULL;
+    }
+
+    return (defn.init_fn(&defn, o, d)) ? NULL : d;
+}
diff --git a/libplatsupport/src/plat/tqma8xqp1gb/gpt.c b/libplatsupport/src/plat/tqma8xqp1gb/gpt.c
new file mode 100644
index 0000000..3068f62
--- /dev/null
+++ b/libplatsupport/src/plat/tqma8xqp1gb/gpt.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2021, Breakaway Consulting Pty. Ltd.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#include <platsupport/plat/gpt.h>
+#include <platsupport/io.h>
+#include <platsupport/irq.h>
+#include <platsupport/fdt.h>
+
+#include <utils/util.h>
+
+#define CR_CLK_SRC_HIGH_FREQ (2 << 6)
+#define CR_EN (1)
+#define TICKS_PER_MICROSECOND 24
+/* When no specific timeout is in place, interrupt at 1Hz */
+#define DEFAULT_IRQ_PERIOD (TICKS_PER_MICROSECOND * 1000 * 1000)
+
+#define MODULE_LABEL "tqma8xqp1gb.gpt: "
+#define CLEANUP_FAIL_TEXT MODULE_LABEL "Failed to cleanup the GPT after failing to initialise it"
+
+struct gpt_regs {
+    uint32_t cr;
+    uint32_t pr;
+    uint32_t sr;
+    uint32_t ir;
+    uint32_t ocr1;
+    uint32_t ocr2;
+    uint32_t ocr3;
+    uint32_t icr1;
+    uint32_t icr2;
+    uint32_t cnt;
+};
+
+static inline uint64_t ns_to_ticks(uint64_t ns)
+{
+    /* NOTE: this assumes that 'ns is less than 2 ** 64 / TICKS_PER_MICROSECOND
+     * which seems reasonable given it would be a value of around 24 years.
+     *
+     * NOTE: this can return a value of more than 2 ** 32, the caller must check
+     * that the returned tick value is actually usable in practise!
+     */
+    return (ns * TICKS_PER_MICROSECOND / 1000);
+}
+
+int gpt_get_time(gpt_t *gpt, uint64_t *time)
+{
+    assert(gpt != NULL);
+    assert(time != NULL);
+
+    /* returns the time in nanoseconds */
+    uint64_t total_ticks = gpt->counted_ticks + gpt->regs->cnt;
+    /* NOTE: This assume total ticks is never more than
+     * 2 ** 64 / 1000. Which seems reasonable as that would
+     * be an uptime of more than 24 years */
+    uint64_t ns = total_ticks * 1000 / TICKS_PER_MICROSECOND;
+    *time = ns;
+    return 0;
+}
+
+int gpt_set_timeout(gpt_t *gpt, uint64_t ns, timeout_type_t type)
+{
+    uint64_t new_timeout;
+    uint32_t extra_ticks;
+    enum gpt_timeout_type timeout_type;
+
+    assert(gpt != NULL);
+
+    if (type == TIMEOUT_ABSOLUTE) {
+        uint64_t now;
+        gpt_get_time(gpt, &now);
+        if (now > ns) {
+            return EINVAL;
+        }
+        ns -= now;
+        timeout_type = GPT_TIMEOUT_ONESHOT;
+    } else if (type == TIMEOUT_PERIODIC) {
+        timeout_type = GPT_TIMEOUT_PERIODIC;
+    } else if (type == TIMEOUT_RELATIVE) {
+        timeout_type = GPT_TIMEOUT_ONESHOT;
+    } else {
+        return EINVAL;
+    }
+
+    new_timeout = ns_to_ticks(ns);
+    if (new_timeout > UINT32_MAX) {
+        printf("returning einvali: new_timeout: %lx\n", new_timeout);
+        return EINVAL;
+    }
+    extra_ticks = gpt->regs->cnt;
+    gpt->regs->ocr1 = new_timeout;
+    gpt->current_timeout = new_timeout;
+    gpt->counted_ticks += extra_ticks;
+    gpt->timeout_type = timeout_type;
+
+    return 0;
+}
+
+int gpt_reset(gpt_t *gpt)
+{
+    assert(gpt != NULL);
+    gpt->current_timeout = DEFAULT_IRQ_PERIOD;
+    gpt->counted_ticks = 0;
+    gpt->timeout_type = GPT_TIMEOUT_NONE;
+    gpt->regs->ocr1 = gpt->current_timeout;
+    return 0;
+}
+
+static int gpt_start(gpt_t *gpt)
+{
+    gpt->regs->pr = 0; /* no scaling */
+    gpt->regs->ir = 1; /* interrupt zero enable */
+    gpt->regs->ocr1 = gpt->current_timeout;
+    gpt->regs->cr = CR_CLK_SRC_HIGH_FREQ | CR_EN;
+
+    return 0;
+}
+
+static int gpt_stop(gpt_t *gpt)
+{
+    gpt->regs->cr = 0;
+    return 0;
+}
+
+void gpt_destroy(gpt_t *gpt)
+{
+    assert(gpt != NULL);
+
+    if (gpt->regs) {
+        ZF_LOGF_IF(gpt_stop(gpt), MODULE_LABEL "failed to stop the GPT before de-allocating it");
+        ps_io_unmap(&gpt->io_ops.io_mapper, (void *) gpt->regs, (size_t) gpt->pmem.length);
+    }
+
+    if (gpt->irq_id != PS_INVALID_IRQ_ID) {
+        ZF_LOGF_IF(ps_irq_unregister(&gpt->io_ops.irq_ops, gpt->irq_id), MODULE_LABEL "failed to unregister IRQ");
+    }
+
+    ps_free(&gpt->io_ops.malloc_ops, sizeof * gpt, gpt);
+}
+
+static void handle_irq(void *data, ps_irq_acknowledge_fn_t acknowledge_fn, void *ack_data)
+{
+    assert(data != NULL);
+    gpt_t *gpt = data;
+
+    /*
+     * ack the interrupt by clearing the status register
+     * Note: No need to read the status register; it can only
+     * have the one output match bit set.
+     *
+     * Can then ack it with the interrupt controller
+     */
+    gpt->regs->sr = gpt->regs->sr;
+    acknowledge_fn(ack_data);
+
+    /* Add current_timeout */
+    gpt->counted_ticks += gpt->current_timeout;
+
+    if (gpt->timeout_type != GPT_TIMEOUT_NONE && gpt->user_callback) {
+        gpt->user_callback(gpt->user_callback_token, LTIMER_TIMEOUT_EVENT);
+    }
+
+    if (gpt->timeout_type == GPT_TIMEOUT_ONESHOT) {
+        /* got back to normal handling if we just have one-shot timer */
+        uint32_t extra_ticks;
+        extra_ticks = gpt->regs->cnt;
+        gpt->regs->ocr1 = DEFAULT_IRQ_PERIOD;
+        gpt->current_timeout = DEFAULT_IRQ_PERIOD;
+        gpt->counted_ticks += extra_ticks;
+        gpt->timeout_type = GPT_TIMEOUT_NONE;
+    }
+}
+
+static int allocate_register_callback(pmem_region_t pmem, unsigned curr_num, size_t num_regs, void *token)
+{
+    assert(token != NULL);
+    gpt_t *gpt = token;
+
+    /* Should only be called once. I.e. only one register field */
+    if (curr_num != 0) {
+        ZF_LOGE(MODULE_LABEL "allocate_register_callback called with multiple set of registers");
+        return EIO;
+    }
+
+    gpt->pmem = pmem;
+
+    gpt->regs = ps_pmem_map(&gpt->io_ops, pmem, false, PS_MEM_NORMAL);
+    if (!gpt->regs) {
+        ZF_LOGE(MODULE_LABEL "failed to map in registers");
+        return EIO;
+    }
+
+    return 0;
+}
+
+static int allocate_irq_callback(ps_irq_t irq, unsigned curr_num, size_t num_irqs, void *token)
+{
+    assert(token != NULL);
+    gpt_t *gpt = token;
+
+    /* Should only be called once. I.e. only one interrupt field */
+    if (curr_num != 0) {
+        ZF_LOGE(MODULE_LABEL "allocate_register_callback called with multiple set of registers");
+        return EIO;
+    }
+
+    gpt->irq_id = ps_irq_register(&gpt->io_ops.irq_ops, irq, handle_irq, gpt);
+    if (gpt->irq_id < 0) {
+        ZF_LOGE(MODULE_LABEL "failed to register interrupt with the IRQ interface");
+        return EIO;
+    }
+
+    return 0;
+}
+
+int gpt_init(gpt_t *gpt, char *fdt_path, ps_io_ops_t ops, ltimer_callback_fn_t user_callback, void *user_callback_token)
+{
+    assert(gpt != NULL);
+
+    ps_fdt_cookie_t *cookie = NULL;
+
+    gpt->io_ops = ops;
+    gpt->irq_id = PS_INVALID_IRQ_ID;
+    gpt->user_callback = user_callback;
+    gpt->user_callback_token = user_callback_token;
+
+    int error = ps_fdt_read_path(&gpt->io_ops.io_fdt, &ops.malloc_ops, fdt_path, &cookie);
+    if (error) {
+        ZF_LOGE(MODULE_LABEL "failed to read path (%d, %s)", error, fdt_path);
+        return ENODEV;
+    }
+
+    error = ps_fdt_walk_registers(&gpt->io_ops.io_fdt, cookie, allocate_register_callback, gpt);
+    if (error) {
+        ZF_LOGE(MODULE_LABEL "error allocating registers (%d, %s)", error, fdt_path);
+        ZF_LOGF_IF(ps_fdt_cleanup_cookie(&gpt->io_ops.malloc_ops, cookie), CLEANUP_FAIL_TEXT);
+
+        return ENODEV;
+    }
+
+    error = ps_fdt_walk_irqs(&gpt->io_ops.io_fdt, cookie, allocate_irq_callback, gpt);
+    if (error) {
+        ZF_LOGE(MODULE_LABEL "error allocating interrupts (%d, %s)", error, fdt_path);
+        ZF_LOGF_IF(ps_fdt_cleanup_cookie(&ops.malloc_ops, cookie), CLEANUP_FAIL_TEXT);
+
+        return ENODEV;
+    }
+
+    ZF_LOGF_IF(ps_fdt_cleanup_cookie(&gpt->io_ops.malloc_ops, cookie),
+               MODULE_LABEL "failed to cleanup the FDT cookie after initialisation");
+
+    gpt->counted_ticks = 0;
+    gpt->current_timeout = DEFAULT_IRQ_PERIOD;
+    gpt->timeout_type = GPT_TIMEOUT_NONE;
+
+    gpt_start(gpt);
+
+    return 0;
+}
diff --git a/libplatsupport/src/plat/tqma8xqp1gb/ltimer.c b/libplatsupport/src/plat/tqma8xqp1gb/ltimer.c
new file mode 100644
index 0000000..6ad3bb0
--- /dev/null
+++ b/libplatsupport/src/plat/tqma8xqp1gb/ltimer.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2021, Breakaway Consulting Pty. Ltd.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+#include <platsupport/ltimer.h>
+#include <platsupport/plat/gpt.h>
+#include <platsupport/io.h>
+
+#define MODULE_LABEL "tqma8xqp1gb.ltimer: "
+#define GPT_0_PATH "/gpt@0x5d140000"
+
+static int get_time(void *data, uint64_t *time)
+{
+    return gpt_get_time((gpt_t *)data, time);
+}
+
+static int set_timeout(void *data, uint64_t ns, timeout_type_t type)
+{
+    return gpt_set_timeout((gpt_t *)data, ns, type);
+}
+
+static int reset(void *data)
+{
+    return gpt_reset((gpt_t *)data);
+}
+
+static void destroy(void *data)
+{
+    gpt_destroy((gpt_t *)data);
+}
+
+int ltimer_default_init(ltimer_t *ltimer, ps_io_ops_t ops, ltimer_callback_fn_t callback, void *callback_token)
+{
+    assert(ltimer != NULL);
+    gpt_t *gpt;
+    int error;
+
+    error = ps_calloc(&ops.malloc_ops, 1, sizeof * gpt, (void **) &gpt);
+    if (error) {
+        return error;
+    }
+
+    error = gpt_init(gpt, GPT_0_PATH, ops, callback, callback_token);
+    if (error != 0) {
+        ps_free(&ops.malloc_ops, sizeof * gpt, (void *)gpt);
+        return error;
+    }
+
+    ltimer->get_time = get_time;
+    ltimer->set_timeout = set_timeout;
+    ltimer->reset = reset;
+    ltimer->destroy = destroy;
+    ltimer->data = gpt;
+
+    return 0;
+}
diff --git a/libplatsupport/src/plat/tqma8xqp1gb/serial.c b/libplatsupport/src/plat/tqma8xqp1gb/serial.c
new file mode 100644
index 0000000..4e82e33
--- /dev/null
+++ b/libplatsupport/src/plat/tqma8xqp1gb/serial.c
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2021, Data61, CSIRO (ABN 41 687 119 230)
+ * Copyright 2021, Breakaway Consulting Pty. Ltd.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+/*
+ * A simple implementation of the `serial` interface for the
+ * i.MX8X low-power UART.
+ *
+ * The driver is non-interrupt driven, with polling to ensure
+ * FIFO is available.
+ *
+ * This implementation makes the assumption that bootloader
+ * software has correctly configured the UART.
+ *
+ * Technical Reference:
+ *   i.MX 8DualX/8DualXPlus/8QuadXPlus Applications Processor Reference Manual
+ *   Revision 0 (IMX8DQXPRM.pdf)
+ *   Chapter 16.13 (page 7908)
+ */
+#include <string.h>
+#include <stdlib.h>
+#include <platsupport/serial.h>
+#include "../../chardev.h"
+
+#define STAT 0x14
+#define TRANSMIT_RECEIVE 0x1c
+
+#define STAT_TDRE   (1 << 23) /* Transmit Data Register Empty Flag */
+#define STAT_RDRF   (1 << 21) /* Receive Data Register Full Flag   */
+
+#define UART_REG(d, x) ((volatile uint32_t *)((d->vaddr) + (x)))
+
+int uart_getchar(ps_chardevice_t *d)
+{
+    /* Wait until received. */
+    while (!(*UART_REG(d, STAT) & STAT_RDRF)) { }
+    return *UART_REG(d, TRANSMIT_RECEIVE);
+}
+
+int uart_putchar(ps_chardevice_t *d, int c)
+{
+    if (c == '\n' && (d->flags & SERIAL_AUTO_CR)) {
+        uart_putchar(d, '\r');
+    }
+
+    /* Wait to be able to transmit. */
+    while (!(*UART_REG(d, STAT) & STAT_TDRE)) { }
+    *UART_REG(d, TRANSMIT_RECEIVE) = c;
+}
+
+
+static void uart_handle_irq(ps_chardevice_t *d UNUSED)
+{
+    /* Not needed, UART drive is not interrupt driven. */
+}
+
+int uart_init(const struct dev_defn *defn,
+              const ps_io_ops_t *ops,
+              ps_chardevice_t *dev)
+{
+    /* Attempt to map the UART registers into the virtual address space */
+    void *vaddr = chardev_map(defn, ops);
+    if (vaddr == NULL) {
+        /* if this is not possible return error immediately */
+        return -1;
+    }
+
+    /* Initialize the ps_chardevice structure appropriately */
+    memset(dev, 0, sizeof * dev);
+    dev->id = defn->id;
+    dev->vaddr = (void *)vaddr;
+    dev->read = &uart_read;
+    dev->write = &uart_write;
+    dev->handle_irq = &uart_handle_irq;
+    dev->irqs = NULL;
+    dev->ioops = *ops;
+    dev->flags = SERIAL_AUTO_CR;
+
+    /*
+     * Note: The UART has been configured and intialized by U-boot;
+     * no configuration required.
+     */
+    return 0;
+}
diff --git a/libplatsupport/src/plat/tx2/clock.c b/libplatsupport/src/plat/tx2/clock.c
index f834e29..a760d5a 100644
--- a/libplatsupport/src/plat/tx2/clock.c
+++ b/libplatsupport/src/plat/tx2/clock.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2019, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2019, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/clock.h>
diff --git a/libplatsupport/src/plat/zynq7000/clock.c b/libplatsupport/src/plat/zynq7000/clock.c
index 153a46d..73a0ffb 100644
--- a/libplatsupport/src/plat/zynq7000/clock.c
+++ b/libplatsupport/src/plat/zynq7000/clock.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include "src.h"
 #include "../../arch/arm/clock.h"
diff --git a/libplatsupport/src/plat/zynq7000/devcfg.c b/libplatsupport/src/plat/zynq7000/devcfg.c
index 3bf1e00..0b297f6 100644
--- a/libplatsupport/src/plat/zynq7000/devcfg.c
+++ b/libplatsupport/src/plat/zynq7000/devcfg.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/io.h>
diff --git a/libplatsupport/src/plat/zynq7000/devcfg.h b/libplatsupport/src/plat/zynq7000/devcfg.h
index 491465d..7fb015a 100644
--- a/libplatsupport/src/plat/zynq7000/devcfg.h
+++ b/libplatsupport/src/plat/zynq7000/devcfg.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/src/plat/zynq7000/src.c b/libplatsupport/src/plat/zynq7000/src.c
index b8d8138..b34ae10 100644
--- a/libplatsupport/src/plat/zynq7000/src.c
+++ b/libplatsupport/src/plat/zynq7000/src.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include "src.h"
 
diff --git a/libplatsupport/src/plat/zynq7000/src.h b/libplatsupport/src/plat/zynq7000/src.h
index 6c73393..d6d9c85 100644
--- a/libplatsupport/src/plat/zynq7000/src.h
+++ b/libplatsupport/src/plat/zynq7000/src.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <platsupport/src.h>
diff --git a/libplatsupport/src/plat/zynq7000/tmu.c b/libplatsupport/src/plat/zynq7000/tmu.c
index 4b1ebfe..70b6c57 100644
--- a/libplatsupport/src/plat/zynq7000/tmu.c
+++ b/libplatsupport/src/plat/zynq7000/tmu.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdint.h>
diff --git a/libplatsupport/src/plat/zynq7000/xadc.c b/libplatsupport/src/plat/zynq7000/xadc.c
index bf72685..13f875c 100644
--- a/libplatsupport/src/plat/zynq7000/xadc.c
+++ b/libplatsupport/src/plat/zynq7000/xadc.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stdint.h>
diff --git a/libplatsupport/src/plat/zynq7000/xadc.h b/libplatsupport/src/plat/zynq7000/xadc.h
index a5842fb..0b39cef 100644
--- a/libplatsupport/src/plat/zynq7000/xadc.h
+++ b/libplatsupport/src/plat/zynq7000/xadc.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/src/plat/zynqmp/clock.c b/libplatsupport/src/plat/zynqmp/clock.c
index 50b295f..33be9bf 100644
--- a/libplatsupport/src/plat/zynqmp/clock.c
+++ b/libplatsupport/src/plat/zynqmp/clock.c
@@ -1,12 +1,9 @@
 /*
  * Copyright 2017, DornerWorks
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DORNERWORKS_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
+
 /*
  * This data was produced by DornerWorks, Ltd. of Grand Rapids, MI, USA under
  * a DARPA SBIR, Contract Number D16PC00107.
diff --git a/libplatsupport/src/serial.c b/libplatsupport/src/serial.c
index 7f346cf..2b356ce 100644
--- a/libplatsupport/src/serial.c
+++ b/libplatsupport/src/serial.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <string.h>
diff --git a/libplatsupport/src/services.h b/libplatsupport/src/services.h
index 5cea5e1..e17bc00 100644
--- a/libplatsupport/src/services.h
+++ b/libplatsupport/src/services.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libplatsupport/src/tqueue.c b/libplatsupport/src/tqueue.c
index b0f3e66..50e6b9c 100644
--- a/libplatsupport/src/tqueue.c
+++ b/libplatsupport/src/tqueue.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <utils/sglib.h>
diff --git a/libplatsupport/tools/device_header_gen.py b/libplatsupport/tools/device_header_gen.py
index fe603a7..0d0dd4f 100644
--- a/libplatsupport/tools/device_header_gen.py
+++ b/libplatsupport/tools/device_header_gen.py
@@ -1,15 +1,9 @@
 #!/usr/bin/env python3
 
 #
-# Copyright 2020, Data61
-# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-# ABN 41 687 119 230.
+# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
 #
-# This software may be distributed and modified according to the terms of
-# the BSD 2-Clause license. Note that NO WARRANTY is provided.
-# See "LICENSE_BSD2.txt" for details.
-#
-# @TAG(DATA61_BSD)
+# SPDX-License-Identifier: BSD-2-Clause
 #
 
 import builtins
@@ -21,15 +15,9 @@
 from jinja2 import Environment, BaseLoader
 
 HEADER_TEMPLATE = '''/*
- * Copyright 2020, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* This file is auto-generated by device_header_gen.py in libplatsupport. */
diff --git a/libplatsupport/tools/device_lists/gpio/exynos5422.yaml b/libplatsupport/tools/device_lists/gpio/exynos5422.yaml
index 1264ffd..0cc9043 100644
--- a/libplatsupport/tools/device_lists/gpio/exynos5422.yaml
+++ b/libplatsupport/tools/device_lists/gpio/exynos5422.yaml
@@ -1,13 +1,7 @@
 #
-# Copyright 2020, Data61
-# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-# ABN 41 687 119 230.
+# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
 #
-# This software may be distributed and modified according to the terms of
-# the BSD 2-Clause license. Note that NO WARRANTY is provided.
-# See "LICENSE_BSD2.txt" for details.
-#
-# @TAG(DATA61_BSD)
+# SPDX-License-Identifier: BSD-2-Clause
 #
 
 # List of GPIO pins for the Exynos5422 platform
diff --git a/libplatsupport/tools/helpers.cmake b/libplatsupport/tools/helpers.cmake
index 991abad..64622f6 100644
--- a/libplatsupport/tools/helpers.cmake
+++ b/libplatsupport/tools/helpers.cmake
@@ -1,13 +1,7 @@
 #
-# Copyright 2020, Data61
-# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-# ABN 41 687 119 230.
+# Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
 #
-# This software may be distributed and modified according to the terms of
-# the BSD 2-Clause license. Note that NO WARRANTY is provided.
-# See "LICENSE_BSD2.txt" for details.
-#
-# @TAG(DATA61_BSD)
+# SPDX-License-Identifier: BSD-2-Clause
 #
 
 cmake_minimum_required(VERSION 3.8.2)
diff --git a/libutils/CMakeLists.txt b/libutils/CMakeLists.txt
index 576405a..42cb807 100644
--- a/libutils/CMakeLists.txt
+++ b/libutils/CMakeLists.txt
@@ -1,13 +1,7 @@
 #
-# Copyright 2017, Data61
-# Commonwealth Scientific and Industrial Research Organisation (CSIRO)
-# ABN 41 687 119 230.
+# Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
 #
-# This software may be distributed and modified according to the terms of
-# the BSD 2-Clause license. Note that NO WARRANTY is provided.
-# See "LICENSE_BSD2.txt" for details.
-#
-# @TAG(DATA61_BSD)
+# SPDX-License-Identifier: BSD-2-Clause
 #
 
 cmake_minimum_required(VERSION 3.7.2)
diff --git a/libutils/LICENSE_BSD2.txt b/libutils/LICENSE_BSD2.txt
deleted file mode 100644
index 9823020..0000000
--- a/libutils/LICENSE_BSD2.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Files described as being under the "BSD 2-Clause" license fall under the
-following license.
-
------------------------------------------------------------------------
-
-Copyright (c) 2014 National ICT Australia and other contributors.
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-1. Redistributions of source code must retain the above copyright
-   notice, this list of conditions and the following disclaimer.
-
-2. 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.
-
-THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
diff --git a/libutils/arch_include/arm/utils/arch/io.h b/libutils/arch_include/arm/utils/arch/io.h
index e1de637..206eeef 100644
--- a/libutils/arch_include/arm/utils/arch/io.h
+++ b/libutils/arch_include/arm/utils/arch/io.h
@@ -1,14 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
-* @TAG(DATA61_BSD)
-*/
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
 
 #pragma once
 
diff --git a/libutils/arch_include/arm/utils/arch/stack.h b/libutils/arch_include/arm/utils/arch/stack.h
index 8166832..fd386ca 100644
--- a/libutils/arch_include/arm/utils/arch/stack.h
+++ b/libutils/arch_include/arm/utils/arch/stack.h
@@ -1,14 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- *# @TAG(DATA61_BSD)
- #*/
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
 
 #pragma once
 
diff --git a/libutils/arch_include/arm/utils/arch/ud.h b/libutils/arch_include/arm/utils/arch/ud.h
index 2950873..dfb1a9a 100644
--- a/libutils/arch_include/arm/utils/arch/ud.h
+++ b/libutils/arch_include/arm/utils/arch/ud.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/arch_include/riscv/utils/arch/stack.h b/libutils/arch_include/riscv/utils/arch/stack.h
index 498621d..7eb74b2 100644
--- a/libutils/arch_include/riscv/utils/arch/stack.h
+++ b/libutils/arch_include/riscv/utils/arch/stack.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/arch_include/riscv/utils/arch/ud.h b/libutils/arch_include/riscv/utils/arch/ud.h
index f4e1723..8c471f0 100644
--- a/libutils/arch_include/riscv/utils/arch/ud.h
+++ b/libutils/arch_include/riscv/utils/arch/ud.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #pragma once
 
diff --git a/libutils/arch_include/x86/utils/arch/stack.h b/libutils/arch_include/x86/utils/arch/stack.h
index 9f7ed7d..cb8e1fe 100644
--- a/libutils/arch_include/x86/utils/arch/stack.h
+++ b/libutils/arch_include/x86/utils/arch/stack.h
@@ -1,14 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- *# @TAG(DATA61_BSD)
- #*/
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
 
 #pragma once
 
diff --git a/libutils/arch_include/x86/utils/arch/ud.h b/libutils/arch_include/x86/utils/arch/ud.h
index 72c8a89..e42feae 100644
--- a/libutils/arch_include/x86/utils/arch/ud.h
+++ b/libutils/arch_include/x86/utils/arch/ud.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/doc/ZFLOG.md b/libutils/doc/ZFLOG.md
index 73c2608..b2fd85b 100644
--- a/libutils/doc/ZFLOG.md
+++ b/libutils/doc/ZFLOG.md
@@ -1,4 +1,8 @@
-/* @TAG(CUSTOM) */
+<!--
+   Copyright (c) 2017 wonder-mice
+   SPDX-License-Identifier: MIT
+-->
+
 zf_log
 ========
 
@@ -70,8 +74,7 @@
 05-06 00:54:33.825 35864  1299 I hello.MAIN 6e6720656c69742e00                ng elit.?
 ```
 
-More examples available in [examples](examples) folder. For more details see
-comments in [zf_log/zf_log.h](zf_log/zf_log.h) file.
+For more details see comments in [zf_log/zf_log.h](../include/utils/zf_log.h) file.
 
 Usage
 --------
@@ -81,34 +84,14 @@
 The simplest way of using this library is to embed its sources into existing
 project. For that, copy the following files to your source tree:
 
-* [zf_log.h](zf_log/zf_log.h)
-* [zf_log.c](zf_log/zf_log.c)
+* [zf_log.h](../include/utils/zf_log.h)
+* [zf_log.c](../src/zf_log.c)
 
 See comments in those files for configuration macros. One particularly useful
 option when embedding into a library project is `ZF_LOG_LIBRARY_PREFIX`. It
 could be used to decorate zf_log exported symbols to avoid linker conflicts
 (when that library project is used in other project that is also uses zf_log).
 
-### Embedding with CMake
-
-Another options is avaibale for projects that are using CMake. Copy
-[zf_log](zf_log) folder to you source tree and add it with `add_subdirectory()`
-call in one of your CMakeLists.txt files. Also see
-[zf_log/CMakeLists.txt](zf_log/CMakeLists.txt) for available `ZF_LOG_`
-configuration options. For example:
-
-```
-set(ZF_LOG_ANDROID_LOG ON)
-add_subdirectory(zf_log)
-```
-
-This will add `zf_log` library target. For each target that uses zf_log in
-corresponding CMakeLists.txt file add:
-
-```cmake
-target_link_libraries(my_target zf_log)
-```
-
 ### Installation
 
 Another option is to build and install the library:
@@ -218,10 +201,7 @@
 * Android Log (via android/log.h)
 * Apple System Log (iOS, OS X via asl.h)
 
-See [examples/custom_output.c] for an example of custom output function.
-
-[zf_log/zf_log.c]: zf_log/zf_log.c
-[examples/custom_output.c]: examples/custom_output.c
+[zf_log/zf_log.c]: ../src/zf_log.c
 
 Why zf?
 --------
diff --git a/libutils/doc/sglib.html b/libutils/doc/sglib.html
index c42f37f..5f1d5a8 100644
--- a/libutils/doc/sglib.html
+++ b/libutils/doc/sglib.html
@@ -1,4 +1,12 @@
-<!--@TAG(CUSTOM)-->
+<!--
+  Copyright Marian Vittek
+  SPDX-License-Identifier: BSD-2-Clause
+
+  http://sglib.sourceforge.net/#license says "you can use Sglib under the terms
+  of any license defined as an open source license by the Open Source Initiative
+  (see http://www.opensource.org/)"
+-->
+
 <HTML>
 
 <HEAD>
diff --git a/libutils/include/utils/ansi.h b/libutils/include/utils/ansi.h
index 21a458c..8ea527f 100644
--- a/libutils/include/utils/ansi.h
+++ b/libutils/include/utils/ansi.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/ansi_color.h b/libutils/include/utils/ansi_color.h
index f2f67f4..79e7e8b 100644
--- a/libutils/include/utils/ansi_color.h
+++ b/libutils/include/utils/ansi_color.h
@@ -1,4 +1,5 @@
-/* @TAG(CUSTOM) */
+/* SPDX-License-Identifier: MIT */
+
 /* Copyright (c) 2012, Ryan Fox
  *
  * Permission is hereby granted, free of charge, to any person obtaining
diff --git a/libutils/include/utils/arith.h b/libutils/include/utils/arith.h
index d7b4819..96ce665 100644
--- a/libutils/include/utils/arith.h
+++ b/libutils/include/utils/arith.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
@@ -24,6 +18,7 @@
 #include <utils/stringify.h>
 
 #define BIT(n) (1ul<<(n))
+#define LLBIT(n) (1ull<<(n))
 
 #define MASK_UNSAFE(x) ((BIT(x) - 1ul))
 
@@ -33,8 +28,8 @@
  * creating masks that are larger than what is possible with MASK_UNSAFE, as
  * MASK_UNSAFE cannot create a MASK that is all 1's */
 #define MASK(n) \
-    ({  typeof (n) _n = (n); \
-        (void)assert(_n <= (sizeof(unsigned long) * 8)); \
+    __extension__ ({  typeof (n) _n = (n); \
+        (void)assert((unsigned long)_n <= (sizeof(unsigned long) * 8)); \
         (void)assert(_n > 0); \
         MASK_UNSAFE(_n - 1) | BIT(_n - 1); \
     })
diff --git a/libutils/include/utils/assume.h b/libutils/include/utils/assume.h
index ead93aa..90ec6f1 100644
--- a/libutils/include/utils/assume.h
+++ b/libutils/include/utils/assume.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/attribute.h b/libutils/include/utils/attribute.h
index 6218a2c..cbf7c26 100644
--- a/libutils/include/utils/attribute.h
+++ b/libutils/include/utils/attribute.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
@@ -16,43 +10,43 @@
 
 /* Stub out Clang feature macros for GCC. */
 #ifndef __has_attribute
-  #define __has_attribute(attrib) 0
+#define __has_attribute(attrib) 0
 #endif
 #ifndef __has_extension
-  #define __has_extension(ext) 0
+#define __has_extension(ext) 0
 #endif
 #ifndef __has_feature
-  #define __has_feature(feature) 0
+#define __has_feature(feature) 0
 #endif
 
 #define ALIAS(sym)   __attribute__((alias(#sym)))
 #define ALIGN(n)     __attribute__((__aligned__(n)))
-#define ALLOC_SIZE(args...) __attribute__((alloc_size(args)))
-#define ASSUME_ALIGNED(args...) __attribute__((assume_aligned(args)))
+#define ALLOC_SIZE(...) __attribute__((alloc_size(__VA_ARGS__)))
+#define ASSUME_ALIGNED(...) __attribute__((assume_aligned(__VA_ARGS__)))
 #define NO_INLINE        __attribute__((noinline))
 #define ALWAYS_INLINE __attribute__((always_inline))
 #define CLEANUP(fn)  __attribute__((cleanup(fn)))
 #if (defined(__clang__) && __has_attribute(cold)) || (!defined(__clang__) && defined(__GNUC__))
-  #define COLD       __attribute__((cold))
+#define COLD       __attribute__((cold))
 #else
-  #define COLD       /* ignored */
+#define COLD       /* ignored */
 #endif
 #define DEPRECATED(msg) __attribute__((deprecated(msg)))
 #if defined(__clang__) && __has_extension(attribute_unavailable_with_message)
-  #define ERROR(msg)   __attribute__((unavailable(msg)))
+#define ERROR(msg)   __attribute__((unavailable(msg)))
 #elif defined(__GNUC__)
-  #define ERROR(msg)   __attribute__((error(msg)))
+#define ERROR(msg)   __attribute__((error(msg)))
 #else
-  /* No good compile-time error feature. Just emit garbage that will force an unclean error. */
-  #define ERROR(msg)  __COMPILE_TIME_ERROR_SUPPORT_UNAVAILABLE(msg)
+/* No good compile-time error feature. Just emit garbage that will force an unclean error. */
+#define ERROR(msg)  __COMPILE_TIME_ERROR_SUPPORT_UNAVAILABLE(msg)
 #endif
 #if (defined(__clang__) && __has_attribute(hot)) || (!defined(__clang__) && defined(__GNUC__))
-  #define HOT        __attribute__((hot))
+#define HOT        __attribute__((hot))
 #else
-  #define HOT        /* ignored */
+#define HOT        /* ignored */
 #endif
 #define MALLOC       __attribute__((malloc))
-#define NONNULL(args...) __attribute__((__nonnull__(args)))
+#define NONNULL(...) __attribute__((__nonnull__(__VA_ARGS__)))
 #define NONNULL_ALL  __attribute__((__nonnull__))
 #define NORETURN     __attribute__((__noreturn__))
 #define PACKED       __attribute__((__packed__))
@@ -64,9 +58,9 @@
 #define UNUSED       __attribute__((__unused__))
 #define USED         __attribute__((__used__))
 #if defined(__clang__) && !__has_attribute(externally_visible)
-  #define VISIBLE /* ignored */
+#define VISIBLE /* ignored */
 #else
-  #define VISIBLE __attribute__((__externally_visible__))
+#define VISIBLE __attribute__((__externally_visible__))
 #endif
 #define WARNING(msg) __attribute__((warning(msg)))
 #define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
diff --git a/libutils/include/utils/auto.h b/libutils/include/utils/auto.h
index b87726a..768e77a 100644
--- a/libutils/include/utils/auto.h
+++ b/libutils/include/utils/auto.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/base64.h b/libutils/include/utils/base64.h
new file mode 100644
index 0000000..c79790a
--- /dev/null
+++ b/libutils/include/utils/base64.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stddef.h>
+#include <utils/arith.h>
+
+/* A streaming base64 encoder */
+
+typedef struct {
+    FILE *output;
+    uint16_t buffer;
+    size_t bits;
+} base64_t;
+
+#define BASE64_LOOKUP (\
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
+    "abcdefghijklmnopqrstuvwxyz" \
+    "0123456789+/" \
+)
+
+/* Create a new base64 streamer that streams to the given output */
+static inline base64_t base64_new(FILE *output)
+{
+    return (base64_t) {
+        .output = output,
+        .buffer = 0,
+        .bits = 0,
+    };
+}
+
+/* Lookup the character for a given bit pattern */
+static inline uint8_t base64_lookup(uint8_t bit)
+{
+    return BASE64_LOOKUP[bit & MASK(6)];
+}
+
+/* Write a byte to a base64 stream */
+static inline int base64_putbyte(base64_t *streamer, uint8_t byte)
+{
+    /* Buffer the byte */
+    streamer->buffer <<= 8;
+    streamer->buffer |= byte;
+    streamer->bits += 8;
+
+    /* Write any bits to the output */
+    while (streamer->bits >= 6) {
+        streamer->bits -= 6;
+        uint8_t part = streamer->buffer >> streamer->bits;
+        fputc(base64_lookup(part), streamer->output);
+    }
+
+    return 0;
+}
+
+/* Write any remaining data to the output */
+static inline int base64_terminate(base64_t *streamer)
+{
+    if (streamer->bits > 0) {
+        size_t padding = 6 - streamer->bits;
+        streamer->buffer <<= padding;
+        fputc(base64_lookup(streamer->buffer), streamer->output);
+        while (padding > 0) {
+            fputc('=', streamer->output);
+            padding -= 2;
+        }
+    }
+
+    /* Reset the streamer */
+    streamer->bits = 0;
+
+    return 0;
+}
diff --git a/libutils/include/utils/builtin.h b/libutils/include/utils/builtin.h
index e3442d5..4af7e0c 100644
--- a/libutils/include/utils/builtin.h
+++ b/libutils/include/utils/builtin.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/cbor64.h b/libutils/include/utils/cbor64.h
new file mode 100644
index 0000000..96fd002
--- /dev/null
+++ b/libutils/include/utils/cbor64.h
@@ -0,0 +1,473 @@
+/*
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <stdint.h>
+#include <string.h>
+#include <stdbool.h>
+#include <utils/arith.h>
+#include <utils/base64.h>
+
+/*
+ * Streaming base64 CBOR encoder
+ *
+ * This implementation is intended to allow structured data to be
+ * streamed out via a serial connection in a manner that minimises the
+ * number of actual bytes that must be written to the output.
+ *
+ * Data is streamed to an output as base64 encoded CBOR which can then
+ * be extracted from a serial log and decoded offline.
+ */
+
+typedef struct {
+    base64_t streamer;
+} cbor64_t;
+
+/* Major types of CBOR items */
+typedef enum {
+    CBOR64_MT_UNSIGNED_INT = 0,
+    CBOR64_MT_NEGATIVE_INT = 1,
+    CBOR64_MT_BYTE_STRING = 2,
+    CBOR64_MT_UTF8_STRING = 3,
+    CBOR64_MT_ARRAY = 4,
+    CBOR64_MT_MAP = 5,
+    CBOR64_MT_TAG = 6,
+    CBOR64_MT_FLOAT = 7,
+    CBOR64_MT_SIMPLE = 7,
+    CBOR64_MT_BREAK = 7,
+} cbor64_mt_t;
+
+/* Additional information identifiers */
+typedef enum {
+    /* Values below 24 are integer literals */
+    CBOR64_AI_INT_LITERAL_MAX = 24,
+    /* Numeric value sizes */
+    CBOR64_AI_UINT8_T = 24,
+    CBOR64_AI_UINT16_T = 25,
+    CBOR64_AI_UINT32_T = 26,
+    CBOR64_AI_UINT64_T = 27,
+    /* Simple value indicated in next bytes */
+    CBOR64_AI_SIMPLE_BYTE = 24,
+    /* Float sizes */
+    CBOR64_AI_FLOAT16_T = 25, /* IEEE 754 Half-precision */
+    CBOR64_AI_FLOAT32_T = 26, /* IEEE 754 Single-precision */
+    CBOR64_AI_FLOAT64_T = 27, /* IEEE 754 Double-precision */
+    /* Array/map length specifier */
+    CBOR64_AI_INDEFINITE_LENGTH = 31,
+} cbor64_ai_t;
+
+/* Simple values */
+typedef enum {
+    /* Boolean */
+    CBOR64_SIMPLE_FALSE = 20,
+    CBOR64_SIMPLE_TRUE = 21,
+    /* Null */
+    CBOR64_SIMPLE_NULL = 22,
+    /* Undefined */
+    CBOR64_SIMPLE_UNDEFINED = 23,
+} cbor64_simple_t;
+
+/* tags */
+typedef enum {
+    /* Semantic descriptors */
+
+    /* Date & time (encoded as UTF-8 string) */
+    CBOR64_TAG_DATETIME_UTF8 = 0,
+    /* Date & time encoded relative to an epoch */
+    CBOR64_TAG_DATETIME_EPOCH = 1,
+    /* Big integers (encoded as bytes) */
+    CBOR64_TAG_POSITIVE_BIGNUM = 2,
+    CBOR64_TAG_NEGATIVE_BIGNUM = 3,
+    /* Decimal fraction (encoded as array 2 integers (mantissa, base 10 scale)) */
+    CBOR64_TAG_DECIMAL_FRACTION = 4,
+    /* Big float (encoded as array 2 integers (mantissa, base 2 scale)) */
+    CBOR64_TAG_BIG_FLOAT = 4,
+
+    /* Encoding hints */
+
+    /* Encode byte string children as base64url */
+    CBOR64_TAG_ENCODE_BASE64URL = 21,
+    /* Encode byte string children as base64 */
+    CBOR64_TAG_ENCODE_BASE64 = 22,
+    /* Encode byte string children as base16 */
+    CBOR64_TAG_ENCODE_BASE16 = 23,
+    /* Byte string encodes CBOR item */
+    CBOR64_TAG_ENCODE_CBOR = 24,
+
+    /* UTF-8 String descriptors */
+
+    /* String is a URI */
+    CBOR64_TAG_UTF8_URI = 32,
+    /* String is a base64url */
+    CBOR64_TAG_UTF8_BASE64URL = 33,
+    /* String is a base64 */
+    CBOR64_TAG_UTF8_BASE64 = 34,
+    /* String is a PCRE/ECMA262 regular expression */
+    CBOR64_TAG_UTF8_RE = 35,
+    /* String MIME message */
+    CBOR64_TAG_UTF8_MIME = 36,
+
+    /* Shared values */
+
+    /* A value that may later be referenced */
+    CBOR64_TAG_SHAREABLE = 28,
+    /* A reference to a previously shared value */
+    CBOR64_TAG_SHARED_VALUE = 29,
+
+    /* String referneces */
+
+    /* A reference to a previously tagged string */
+    CBOR64_TAG_STRING_REF = 25,
+    /* A domain containing string references */
+    CBOR64_TAG_STRING_REF_DOMAIN = 256,
+
+    /* Self-described CBOR (magic bytes) */
+    CBOR64_TAG_SELF_DESCRIBED = 55799,
+} cbor64_tag_t;
+
+/*
+ * Inline implementation
+ * =====================
+ */
+
+/* Generate the initial byte indicating the type of the following data */
+int cbor64_initial_byte(base64_t *streamer, cbor64_mt_t type, uint8_t data);
+
+/* Send a break byte to terminate indefinite-length item */
+int cbor64_send_break(base64_t *streamer);
+
+/* This sends a numeric item to the streamer using big-endian encoding */
+int cbor64_send_item(base64_t *streamer, cbor64_mt_t type, uint64_t number);
+
+/* Send a type array of bytes (UTF8 or bytes) */
+int cbor64_send_typed_bytes(base64_t *streamer, cbor64_mt_t type, unsigned char *buffer, size_t length);
+
+/* Send a simple value in one or two bytes */
+int cbor64_send_simple(base64_t *streamer, cbor64_simple_t value);
+
+/*
+ * External API
+ * ============
+ */
+
+
+/*
+ * Send a tag for the following item
+ *
+ * A tag is a single item describing the next item in the stream. It
+ * can denote some particular semantic meaning for the subsequent item
+ * or that the item is to be encoded in some particular manner when
+ * translated to JSON (see cbor64_tag_t).
+ */
+static inline int cbor64_tag(base64_t *streamer, cbor64_tag_t tag)
+{
+    return cbor64_send_item(streamer, CBOR64_MT_TAG, tag);
+}
+
+/*
+ * Simple types
+ * ------------
+ */
+
+/* Send a boolean value */
+static inline int cbor64_bool(base64_t *streamer, int boolean)
+{
+    uint8_t value = CBOR64_SIMPLE_FALSE;
+    if (boolean) {
+        value = CBOR64_SIMPLE_TRUE;
+    }
+    return cbor64_send_simple(streamer, value);
+}
+
+/* Send a null */
+static inline int cbor64_null(base64_t *streamer)
+{
+    return cbor64_send_simple(streamer, CBOR64_SIMPLE_NULL);
+}
+
+/* Send an undefined */
+static inline int cbor64_undefined(base64_t *streamer)
+{
+    return cbor64_send_simple(streamer, CBOR64_SIMPLE_UNDEFINED);
+}
+
+/*
+ * Integer types
+ * -------------
+ */
+
+/* Send an unsigned integer value */
+static inline int cbor64_uint(base64_t *streamer, uint64_t number)
+{
+    return cbor64_send_item(streamer, CBOR64_MT_UNSIGNED_INT, number);
+}
+
+/* Send a signed integer value */
+static inline int cbor64_int(base64_t *streamer, int64_t number)
+{
+    cbor64_mt_t type = CBOR64_MT_UNSIGNED_INT;
+    if (number < 0) {
+        type = CBOR64_MT_NEGATIVE_INT;
+        number = (-1) - number;
+    }
+
+    return cbor64_send_item(streamer, type, number);
+}
+
+/*
+ * IEEE 754 Float types
+ * --------------------
+ */
+
+/* Send a single-precision float value */
+int cbor64_float(base64_t *streamer, float number);
+
+/* Send a double-precision float value */
+int cbor64_double(base64_t *streamer, double number);
+
+/*
+ * Byte arrays
+ * -----------
+ *
+ * The following functions describe 3 kinds of byte array:
+ *  - Raw bytes (bytes)
+ *  - C strings that are not guaranteed to be UTF8 (string)
+ *  - UTF-8 C strings (utf8)
+ *
+ * Each has a function that will stream a single array along with its
+ * size which can be used directly. Additionally, a series of 'chunks'
+ * can be sent without the need to know the number of chunks. A series
+ * of chunks must start with a call to 'cbor64_<kind>_chunks_start' and
+ * finish with a call to 'cbor64_<kind>_chunks_start' with only calls to
+ * the corresponding 'cbor64_<kind>' in-between.
+ *
+ * For example:
+ *
+ *     cbor64_utf8_chunks_start(streamer);
+ *     cbor64_utf8(streamer, "Hello,");
+ *     cbor64_utf8(streamer, "world!");
+ *     cbor64_utf8_chunks_end(streamer);
+ */
+
+/* send an array of bytes */
+static inline int cbor64_bytes(base64_t *streamer, unsigned char *buffer, size_t length)
+{
+    return cbor64_send_typed_bytes(streamer, CBOR64_MT_BYTE_STRING, buffer, length);
+}
+
+/* Start chunked bytes */
+static inline int cbor64_byte_chunks_start(base64_t *streamer)
+{
+    return cbor64_send_item(streamer, CBOR64_MT_BYTE_STRING, CBOR64_AI_INDEFINITE_LENGTH);
+}
+
+/* End chunked string */
+static inline int cbor64_byte_chunks_end(base64_t *streamer)
+{
+    return cbor64_send_break(streamer);
+}
+
+/* Send a non-UTF-8 string */
+static inline int cbor64_string(base64_t *streamer, char *text)
+{
+    return cbor64_bytes(streamer, (unsigned char *) text, strlen(text));
+}
+
+/* Start chunked string */
+static inline int cbor64_string_chunks_start(base64_t *streamer)
+{
+    return cbor64_send_item(streamer, CBOR64_MT_BYTE_STRING, CBOR64_AI_INDEFINITE_LENGTH);
+}
+
+/* End chunked string */
+static inline int cbor64_string_chunks_end(base64_t *streamer)
+{
+    return cbor64_send_break(streamer);
+}
+
+/* Send a UTF-8 string */
+static inline int cbor64_utf8(base64_t *streamer, char *text)
+{
+    return cbor64_send_typed_bytes(streamer, CBOR64_MT_UTF8_STRING, (unsigned char *) text, strlen(text));
+}
+
+/* Start chunked UTF-8 string */
+static inline int cbor64_utf8_chunks_start(base64_t *streamer)
+{
+    return cbor64_send_item(streamer, CBOR64_MT_UTF8_STRING, CBOR64_AI_INDEFINITE_LENGTH);
+}
+
+/* End chunked UTF-8 string */
+static inline int cbor64_utf8_chunks_end(base64_t *streamer)
+{
+    return cbor64_send_break(streamer);
+}
+
+/*
+ * Arrays
+ * ------
+ *
+ * Arrays are a series of items. An array of known length need only
+ * start with a call to 'cbor64_array_length'.
+ *
+ *     cbor64_array_length(streamer, 2);
+ *     cbor64_uint(streamer, 12);
+ *     cbor64_uint(streamer, 28);
+ *
+ * If the length is unknown, the array can be started with
+ * 'cbor64_array_start' and completed with a call to 'cbor64_array_end'.
+ *
+ *     cbor64_array_start(streamer);
+ *     cbor64_uint(streamer, 15);
+ *     cbor64_uint(streamer, 10538);
+ *     cbor64_array_end(streamer);
+ */
+
+/* Start an array of unknown length */
+static inline int cbor64_array_start(base64_t *streamer)
+{
+    return cbor64_initial_byte(streamer, CBOR64_MT_ARRAY, CBOR64_AI_INDEFINITE_LENGTH);
+}
+
+/* End an array of unknown length */
+static inline int cbor64_array_end(base64_t *streamer)
+{
+    return cbor64_send_break(streamer);
+}
+
+/* Start an array of known length */
+static inline int cbor64_array_length(base64_t *streamer, uint64_t length)
+{
+    return cbor64_send_item(streamer, CBOR64_MT_ARRAY, length);
+}
+
+/*
+ * Maps
+ * ----
+ *
+ * Maps are a series of key-value pairs. The keys may be of any type.
+ *
+ * A map of known length need only start with a call to
+ * 'cbor64_map_length'.
+ *
+ *     cbor64_map_length(streamer, 2);
+ *     cbor64_utf8(streamer, "x");
+ *     cbor64_uint(streamer, 48);
+ *     cbor64_utf8(streamer, "y");
+ *     cbor64_uint(streamer, 97);
+ *
+ * If the length is unknown, the map can be started with
+ * 'cbor64_map_start' and completed with a call to 'cbor64_map_end'.
+ *
+ *     cbor64_map_start(streamer);
+ *     cbor64_utf8(streamer, "x");
+ *     cbor64_uint(streamer, 48);
+ *     cbor64_utf8(streamer, "y");
+ *     cbor64_uint(streamer, 97);
+ *     cbor64_map_end(streamer);
+ */
+
+/* Start a map of unknown length */
+static inline int cbor64_map_start(base64_t *streamer)
+{
+    return cbor64_initial_byte(streamer, CBOR64_MT_MAP, CBOR64_AI_INDEFINITE_LENGTH);
+}
+
+/* End a map of unknown length */
+static inline int cbor64_map_end(base64_t *streamer)
+{
+    return cbor64_send_break(streamer);
+}
+
+/* Start a map of known length */
+static inline int cbor64_map_length(base64_t *streamer, uint64_t length)
+{
+    return cbor64_send_item(streamer, CBOR64_MT_MAP, length);
+}
+
+/*
+ * String reference domains
+ * ========================
+ *
+ * String reference domains allow reduced encoding of strings by only
+ * emitting each encoded string once and then using tagged numeric
+ * references to previous occurrences of strings.
+ *
+ * The current implementation is suboptimal but avoid allocation by
+ * using a static allocation of the strings used.
+ *
+ * Within a string reference domain, all strings must be emitted using
+ * 'cbor64_string_ref' or 'cbor64_utf8_ref' emitter. To emit a sized
+ * byte array or data containing strings not in the domain, you can
+ * create a new null domain that contains no references.
+ *
+ * Using shared values
+ * -------------------
+ *
+ * If the tooling used does not support string reference domains but
+ * does support shared values, this can be used to implement similar
+ * semantics, however only one domain using shared values can exist in a
+ * dataset.
+ */
+
+/* Tracks the strings which have already been emitted and their index. */
+typedef struct {
+    char **strings;
+    /* Use shared values rather than string references */
+    bool shared_values;
+    uint64_t emitted;
+} cbor64_domain_t;
+
+/* Start a new domain with no inner string references */
+static inline int cbor64_null_domain(base64_t *streamer)
+{
+    return cbor64_tag(streamer, CBOR64_TAG_STRING_REF_DOMAIN);
+}
+
+/*
+ * Create a new string reference domain
+ *
+ * The provided array of strings must not be used again within this
+ * domain in a nested fashion.
+ *
+ * The array of strings must be terminated with a NULL.
+ */
+static inline int cbor64_string_ref_domain(base64_t *streamer, char **strings, cbor64_domain_t *domain)
+{
+    domain->strings = strings;
+    domain->emitted = 0;
+    domain->shared_values = false;
+
+    return cbor64_tag(streamer, CBOR64_TAG_STRING_REF_DOMAIN);
+}
+
+/*
+ * Create a new shared value domain
+ *
+ * There must be no more than one shared value domain in an output.
+ *
+ * The provided array of strings must not be used again within this
+ * domain in a nested fashion.
+ *
+ * The array of strings must be terminated with a NULL.
+ */
+static inline void cbor64_shared_value_domain(char **strings, cbor64_domain_t *domain)
+{
+    domain->strings = strings;
+    domain->emitted = 0;
+    domain->shared_values = true;
+}
+
+/*
+ * Emit a string reference
+ */
+int cbor64_string_ref(base64_t *streamer, cbor64_domain_t *domain, char *string);
+
+/*
+ * Emit a utf8 reference
+ */
+int cbor64_utf8_ref(base64_t *streamer, cbor64_domain_t *domain, char *string);
diff --git a/libutils/include/utils/circular_buffer.h b/libutils/include/utils/circular_buffer.h
index b281293..52d41e1 100644
--- a/libutils/include/utils/circular_buffer.h
+++ b/libutils/include/utils/circular_buffer.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /**
diff --git a/libutils/include/utils/colour.h b/libutils/include/utils/colour.h
index 47794c5..4722d72 100644
--- a/libutils/include/utils/colour.h
+++ b/libutils/include/utils/colour.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/compile_time.h b/libutils/include/utils/compile_time.h
index 434cca6..756abfd 100644
--- a/libutils/include/utils/compile_time.h
+++ b/libutils/include/utils/compile_time.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/config.h b/libutils/include/utils/config.h
index e83435e..0078bc2 100644
--- a/libutils/include/utils/config.h
+++ b/libutils/include/utils/config.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_GPL)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/debug.h b/libutils/include/utils/debug.h
index b749687..8daf17e 100644
--- a/libutils/include/utils/debug.h
+++ b/libutils/include/utils/debug.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/fence.h b/libutils/include/utils/fence.h
index 7d7564e..2baaaab 100644
--- a/libutils/include/utils/fence.h
+++ b/libutils/include/utils/fence.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/force.h b/libutils/include/utils/force.h
index d115b76..5424985 100644
--- a/libutils/include/utils/force.h
+++ b/libutils/include/utils/force.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/formats.h b/libutils/include/utils/formats.h
index 5bac3f4..8f9d3d1 100644
--- a/libutils/include/utils/formats.h
+++ b/libutils/include/utils/formats.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/frequency.h b/libutils/include/utils/frequency.h
index 30a0e38..cf8c878 100644
--- a/libutils/include/utils/frequency.h
+++ b/libutils/include/utils/frequency.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/io.h b/libutils/include/utils/io.h
index bb04d28..0bd7e45 100644
--- a/libutils/include/utils/io.h
+++ b/libutils/include/utils/io.h
@@ -1,14 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
-* @TAG(DATA61_BSD)
-*/
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
 
 #pragma once
 
diff --git a/libutils/include/utils/linear_algebra.h b/libutils/include/utils/linear_algebra.h
index 6bea10d..1279258 100644
--- a/libutils/include/utils/linear_algebra.h
+++ b/libutils/include/utils/linear_algebra.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* A simple vector math library
diff --git a/libutils/include/utils/list.h b/libutils/include/utils/list.h
index e5fec72..57285fa 100644
--- a/libutils/include/utils/list.h
+++ b/libutils/include/utils/list.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* Bog standard singly-linked-list implementation. */
diff --git a/libutils/include/utils/math.h b/libutils/include/utils/math.h
index 2714e2b..dd3fc3e 100644
--- a/libutils/include/utils/math.h
+++ b/libutils/include/utils/math.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/page.h b/libutils/include/utils/page.h
index b928c86..e147a70 100644
--- a/libutils/include/utils/page.h
+++ b/libutils/include/utils/page.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
@@ -21,12 +15,18 @@
 #define SIZE_BITS_TO_BYTES(size_bits) (BIT(size_bits))
 #define BYTES_TO_SIZE_BITS(bytes) (LOG_BASE_2(bytes))
 
+#define PAGE_BITS_1G 30
 #define PAGE_BITS_4M 22
+#define PAGE_BITS_2M 21
 #define PAGE_BITS_4K 12
 #define PAGE_SIZE_4K (SIZE_BITS_TO_BYTES(PAGE_BITS_4K))
+#define PAGE_SIZE_2M (SIZE_BITS_TO_BYTES(PAGE_BITS_2M))
 #define PAGE_MASK_4K (PAGE_SIZE_4K - 1)
+#define PAGE_MASK_2M (PAGE_SIZE_2M - 1)
 #define PAGE_ALIGN_4K(addr) ((addr) & ~PAGE_MASK_4K)
+#define PAGE_ALIGN_2M(addr) ((addr) & ~PAGE_MASK_2M)
 #define IS_ALIGNED_4K(addr) IS_ALIGNED(addr, PAGE_BITS_4K)
+#define IS_ALIGNED_2M(addr) IS_ALIGNED(addr, PAGE_BITS_2M)
 
 #define MiB_TO_BYTES(x) (1024 * 1024 * ((size_t)x))
 
diff --git a/libutils/include/utils/print.h b/libutils/include/utils/print.h
index 6509aec..6538917 100644
--- a/libutils/include/utils/print.h
+++ b/libutils/include/utils/print.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/sglib.h b/libutils/include/utils/sglib.h
index 607d6f0..d409f87 100644
--- a/libutils/include/utils/sglib.h
+++ b/libutils/include/utils/sglib.h
@@ -1,4 +1,12 @@
-/* @TAG(CUSTOM) */
+/*
+ * Copyright Marian Vittek
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * http://sglib.sourceforge.net/#license says "you can use Sglib under the terms
+ * of any license defined as an open source license by the Open Source Initiative
+ * (see http://www.opensource.org/)"
+ */
+
 /*
 
   This is SGLIB version 1.0.4
diff --git a/libutils/include/utils/stack.h b/libutils/include/utils/stack.h
index fa98511..e08cd77 100644
--- a/libutils/include/utils/stack.h
+++ b/libutils/include/utils/stack.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/stringify.h b/libutils/include/utils/stringify.h
index aff8214..6efb933 100644
--- a/libutils/include/utils/stringify.h
+++ b/libutils/include/utils/stringify.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* Macros related to string- and token-construction operations. */
diff --git a/libutils/include/utils/temperature.h b/libutils/include/utils/temperature.h
index 63775ce..3d52731 100644
--- a/libutils/include/utils/temperature.h
+++ b/libutils/include/utils/temperature.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/time.h b/libutils/include/utils/time.h
index d602417..b299661 100644
--- a/libutils/include/utils/time.h
+++ b/libutils/include/utils/time.h
@@ -1,42 +1,78 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
 
+#include <stdint.h>
+
+/*
+ * Time should use a 64-bit data type, because a 32-bit type can overflow too
+ * easily for longer timeouts. However, there are no hard-coded assumptions
+ * about this in here. Postfixing values with "lu" or "llu" is configurable to
+ * allow aligning this with the runtme library definitions for uint64_t and
+ * PRIu64. The macro SEL4_TIME_UINT_TYPE() defaults to UINT64_C(), which is a
+ * common way runtime libraries defines 64-bit datatypes:
+ *
+ *     #if defined(target_is_32_bit_with_LLP64)
+ *         typedef unsigned long long int   uint64_t
+ *         #define UINT64_C(v)              v ## ull
+ *         #define PRIu64                   "ull"
+ *
+ *     #elif defined(target_is_64_bit_with_LP64)
+ *         typedef unsigned long int        uint64_t
+ *         #define UINT64_C(v)              v ## ul
+ *         #define PRIu64                   "ul"
+ *     ...
+ *     #endif
+ *
+ * See also https://en.wikipedia.org/wiki/64-bit_computing for commonly used
+ * 64-bit data models. The seL4 kernel uses "long long" for 64-bit types, see
+ * file <sel4-kernel>/include/stdint.h. The userspace is not required to follow
+ * this, musllibc uses "long long" on 32-bit targets and "long" on 64-bit
+ * targets.
+ */
+#ifndef SEL4_TIME_UINT_TYPE
+#define SEL4_TIME_UINT_TYPE(v)  UINT64_C(v)
+#endif
+
 /* seconds */
-#define SEC_IN_MINUTE 60llu
-#define NS_IN_MINUTE (SEC_IN_MINUTE*NS_IN_S)
+#define SEC_IN_MINUTE   SEL4_TIME_UINT_TYPE(60)
 
 /* milliseconds */
-#define MS_IN_S 1000llu
+#define MS_IN_S         SEL4_TIME_UINT_TYPE(1000)
+#define MS_IN_MINUTE    (MS_IN_S * SEC_IN_MINUTE)   /* =6e4 */
 
 /* microseconds */
-#define US_IN_MS 1000llu
-#define US_IN_S  1000000llu
+#define US_IN_MS        SEL4_TIME_UINT_TYPE(1000)
+#define US_IN_S         (US_IN_MS * MS_IN_S)
+#define US_IN_MINUTE    (US_IN_MS * MS_IN_MINUTE)   /* =6e7 */
 
 /* nanoseconds */
-#define NS_IN_US 1000llu
-#define NS_IN_MS 1000000llu
-#define NS_IN_S  1000000000llu
+#define NS_IN_US        SEL4_TIME_UINT_TYPE(1000)
+#define NS_IN_MS        (NS_IN_US * US_IN_MS)
+#define NS_IN_S         (NS_IN_US * US_IN_S)
+#define NS_IN_MINUTE    (NS_IN_US * US_IN_MINUTE)   /* =6e10 > 2^32 (=4e9) */
 
 /* picoseconds */
-#define PS_IN_NS 1000llu
-#define PS_IN_US 1000000llu
-#define PS_IN_MS 1000000000llu
-#define PS_IN_S  1000000000000llu
+#define PS_IN_NS        SEL4_TIME_UINT_TYPE(1000)
+#define PS_IN_US        (PS_IN_NS * NS_IN_US)
+#define PS_IN_MS        (PS_IN_NS * NS_IN_MS)
+#define PS_IN_S         (PS_IN_NS * NS_IN_S)        /* =1e12 > 2^32 (=4e9) */
+#define PS_IN_MINUTE    (PS_IN_NS * NS_IN_MINUTE)   /* =6e13 > 2^32 (=4e9) */
 
 /* femptoseconds */
-#define FS_IN_PS 1000llu
-#define FS_IN_NS 1000000llu
-#define FS_IN_US 1000000000llu
-#define FS_IN_MS 1000000000000llu
-#define FS_IN_S  1000000000000000llu
+#define FS_IN_PS        SEL4_TIME_UINT_TYPE(1000)
+#define FS_IN_NS        (FS_IN_PS * PS_IN_NS)
+#define FS_IN_US        (FS_IN_PS * PS_IN_US)
+#define FS_IN_MS        (FS_IN_PS * PS_IN_MS)       /* =1e12 > 2^32 (=4e9) */
+#define FS_IN_S         (FS_IN_PS * PS_IN_S)        /* =1e15 > 2^32 (=4e9) */
+#define FS_IN_MINUTE    (FS_IN_PS * PS_IN_MINUTE)   /* =6e16 > 2^32 (=4e9) */
+
+/* Note that the maximum value for uint64_t is 1.8e19. FS_IN_MINUTE is 6e16,
+ * which is still in range. There are 1e18 atto-seconds in one second, which
+ * eventually gets close to the uint64_t range, the 6e19 atto-seconds in a
+ * minute exceed it.
+ */
diff --git a/libutils/include/utils/ud.h b/libutils/include/utils/ud.h
index 65ecd9c..ddeab8d 100644
--- a/libutils/include/utils/ud.h
+++ b/libutils/include/utils/ud.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/uthash.h b/libutils/include/utils/uthash.h
index 8c04f2d..44aeaa4 100644
--- a/libutils/include/utils/uthash.h
+++ b/libutils/include/utils/uthash.h
@@ -1,4 +1,4 @@
-/* @TAG(OTHER_NON_STANDARD) */
+/* SPDX-License-Identifier: BSD-1-Clause */
 /*
 Copyright (c) 2003-2018, Troy D. Hanson     http://troydhanson.github.com/uthash/
 All rights reserved.
diff --git a/libutils/include/utils/util.h b/libutils/include/utils/util.h
index 9e75ace..74e3219 100644
--- a/libutils/include/utils/util.h
+++ b/libutils/include/utils/util.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
@@ -65,5 +59,5 @@
  * all ZF_LOG output, settings it to ZF_LOG_FATAL will
  * only display fatal outputs.
  */
-#define LOG_ERROR(args...) ZF_LOGE(args)
-#define LOG_INFO(args...) ZF_LOGI(args)
+#define LOG_ERROR(...) ZF_LOGE(__VA_ARGS__)
+#define LOG_INFO(...) ZF_LOGI(__VA_ARGS__)
diff --git a/libutils/include/utils/verification.h b/libutils/include/utils/verification.h
index 6d6585c..3dbb972 100644
--- a/libutils/include/utils/verification.h
+++ b/libutils/include/utils/verification.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/xml.h b/libutils/include/utils/xml.h
index 04e4aa0..450ba42 100644
--- a/libutils/include/utils/xml.h
+++ b/libutils/include/utils/xml.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 /* Basic XML-related functionality. If this ever grows beyond simple helpers, we should switch to
diff --git a/libutils/include/utils/zf_log.h b/libutils/include/utils/zf_log.h
index a1fe8c8..5cc501e 100644
--- a/libutils/include/utils/zf_log.h
+++ b/libutils/include/utils/zf_log.h
@@ -1,5 +1,8 @@
-/* @TAG(CUSTOM) */
-/* zf log taken from: https://github.com/wonder-mice/zf_log
+/*
+ * SPDX-License-Identifier: MIT
+ * Copyright (c) 2017 wonder-mice
+ *
+ * zf log taken from: https://github.com/wonder-mice/zf_log
  *
  * "Software source code can not be printed on paper and sticked to a cat."
  */
@@ -295,13 +298,13 @@
 	#define _ZF_LOG_IMP(lvl, tag, ...) \
 			do { \
 				if (ZF_LOG_OUTPUT(lvl)) \
-					_zf_log_write_d(__FUNCTION__, __FILE__, __LINE__, \
+					_zf_log_write_d(__func__, __FILE__, __LINE__, \
 							lvl, tag, __VA_ARGS__); \
 			} while (0)
 	#define _ZF_LOG_MEM_IMP(lvl, tag, d, d_sz, ...) \
 			do { \
 				if (ZF_LOG_OUTPUT(lvl)) \
-					_zf_log_write_mem_d(__FUNCTION__, __FILE__, __LINE__, \
+					_zf_log_write_mem_d(__func__, __FILE__, __LINE__, \
 							lvl, tag, d, d_sz, __VA_ARGS__); \
 			} while (0)
 #endif
diff --git a/libutils/include/utils/zf_log_config.h b/libutils/include/utils/zf_log_config.h
index 48e03e2..a06849d 100644
--- a/libutils/include/utils/zf_log_config.h
+++ b/libutils/include/utils/zf_log_config.h
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #pragma once
diff --git a/libutils/include/utils/zf_log_if.h b/libutils/include/utils/zf_log_if.h
index f7653fb..aa3ef1b 100644
--- a/libutils/include/utils/zf_log_if.h
+++ b/libutils/include/utils/zf_log_if.h
@@ -1,13 +1,8 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * SPDX-License-Identifier: MIT
+ * Copyright (c) 2017 wonder-mice
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * zf log taken from: https://github.com/wonder-mice/zf_log
  */
 
 #pragma once
diff --git a/libutils/src/arch/arm/stack.c b/libutils/src/arch/arm/stack.c
index af34ec2..f798a8b 100644
--- a/libutils/src/arch/arm/stack.c
+++ b/libutils/src/arch/arm/stack.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <autoconf.h>
diff --git a/libutils/src/arch/riscv/stack.c b/libutils/src/arch/riscv/stack.c
index d96df0d..890755b 100644
--- a/libutils/src/arch/riscv/stack.c
+++ b/libutils/src/arch/riscv/stack.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2018, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2018, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <autoconf.h>
 #include <utils/gen_config.h>
diff --git a/libutils/src/arch/x86/stack.c b/libutils/src/arch/x86/stack.c
index 1d8de7b..bf18c64 100644
--- a/libutils/src/arch/x86/stack.c
+++ b/libutils/src/arch/x86/stack.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <autoconf.h>
diff --git a/libutils/src/cbor64.c b/libutils/src/cbor64.c
new file mode 100644
index 0000000..06f54a2
--- /dev/null
+++ b/libutils/src/cbor64.c
@@ -0,0 +1,255 @@
+/*
+ * Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <utils/cbor64.h>
+
+/* Generate the initial byte indicating the type of the following data */
+int cbor64_initial_byte(base64_t *streamer, cbor64_mt_t type, uint8_t data)
+{
+    return base64_putbyte(streamer, (type << 5) | (data & MASK(5)));
+}
+
+/* Send a break byte to terminate indefinite-length item */
+int cbor64_send_break(base64_t *streamer)
+{
+    return cbor64_initial_byte(streamer, CBOR64_MT_BREAK, CBOR64_AI_INDEFINITE_LENGTH);
+}
+
+int cbor64_send_item(base64_t *streamer, cbor64_mt_t type, uint64_t number)
+{
+    uint8_t additional_info;
+    size_t size;
+
+    if (number < CBOR64_AI_INT_LITERAL_MAX) {
+        /* Encode number in item byte */
+        additional_info = number;
+        size = 0;
+    } else if (number < LLBIT(8)) {
+        /* Encode number as uint8_t */
+        additional_info = CBOR64_AI_UINT8_T;
+        size = 8;
+    } else if (number < LLBIT(16)) {
+        /* Encode number as uint16_t */
+        additional_info = CBOR64_AI_UINT16_T;
+        size = 16;
+    } else if (number < LLBIT(32)) {
+        /* Encode number as uint32_t */
+        additional_info = CBOR64_AI_UINT32_T;
+        size = 32;
+    } else {
+        /* Encode number as uint64_t */
+        additional_info = CBOR64_AI_UINT64_T;
+        size = 64;
+    }
+
+    int err = cbor64_initial_byte(streamer, type, additional_info);
+    if (err != 0) {
+        return err;
+    }
+
+    while (size > 0) {
+        size -= 8;
+        err = base64_putbyte(streamer, (number >> size) & MASK(8));
+        if (err != 0) {
+            return err;
+        }
+    }
+
+    return err;
+}
+
+
+/* Send a bytearray */
+int cbor64_send_typed_bytes(base64_t *streamer, cbor64_mt_t type, unsigned char *buffer, size_t length)
+{
+    int err = cbor64_send_item(streamer, type, length);
+    if (err != 0) {
+        return err;
+    }
+
+    while (length > 0) {
+        err = base64_putbyte(streamer, *buffer);
+        if (err != 0) {
+            return err;
+        }
+
+        length -= 1;
+        buffer += 1;
+    }
+
+    return 0;
+}
+
+/* Send a special value in one or two bytes */
+int cbor64_send_simple(base64_t *streamer, cbor64_simple_t value)
+{
+    if ((uint8_t)value < CBOR64_AI_SIMPLE_BYTE) {
+        return cbor64_initial_byte(streamer, CBOR64_MT_SIMPLE, value);
+    } else {
+        int err = cbor64_initial_byte(streamer, CBOR64_MT_SIMPLE, CBOR64_AI_SIMPLE_BYTE);
+        if (err == 0) {
+            err = base64_putbyte(streamer, value);
+        }
+        return err;
+    }
+}
+
+static inline int send_endian_bytes(base64_t *streamer, unsigned char *bytes, size_t length)
+{
+    for (unsigned int b = 0; b < length; b += 1) {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+        int err = base64_putbyte(streamer, bytes[length - (b + 1)]);
+#else
+        int err = base64_putbyte(streamer, bytes[b]);
+#endif
+        if (err != 0) {
+            return err;
+        }
+    }
+
+    return 0;
+}
+
+/* Send a single-precision float value */
+int cbor64_float(base64_t *streamer, float number)
+{
+    int err = cbor64_initial_byte(streamer, CBOR64_MT_FLOAT, CBOR64_AI_FLOAT32_T);
+    if (err == 0) {
+        err = send_endian_bytes(streamer, (void *)&number, 4);
+    }
+    return err;
+}
+
+/* Send a double-precision float value */
+int cbor64_double(base64_t *streamer, double number)
+{
+    int err = cbor64_initial_byte(streamer, CBOR64_MT_FLOAT, CBOR64_AI_FLOAT64_T);
+    if (err == 0) {
+        err = send_endian_bytes(streamer, (void *)&number, 8);
+    }
+    return err;
+}
+
+/* Find the index for a given string */
+static size_t find_reference(cbor64_domain_t *domain, char *string)
+{
+    size_t index = 0;
+    while (domain->strings[index] != NULL) {
+        if (string == domain->strings[index] || strcmp(string, domain->strings[index]) == 0) {
+            /* Found matching string */
+            break;
+        }
+        index += 1;
+    }
+
+    return index;
+}
+
+/*
+ * Emit a new string and update the array
+ */
+static int new_reference(base64_t *streamer, cbor64_domain_t *domain, size_t index)
+{
+    /*
+     * If the string reference would be no less than the raw string
+     * encoding, don't actually track the string in the references.
+     */
+    size_t length = strlen(domain->strings[index]);
+    uint64_t next_ref = domain->emitted;
+
+    bool is_referenced = true;
+    if (next_ref < 24) {
+        is_referenced = length >= 3;
+    } else if (next_ref < BIT(8)) {
+        is_referenced = length >= 4;
+    } else if (next_ref < BIT(16)) {
+        is_referenced = length >= 5;
+    } else if (next_ref < LLBIT(32)) {
+        is_referenced = length >= 7;
+    } else {
+        is_referenced = length >= 11;
+    }
+
+    if (is_referenced) {
+        char *temp = domain->strings[next_ref];
+        domain->strings[next_ref] = domain->strings[index];
+        domain->strings[index] = temp;
+        domain->emitted += 1;
+
+        if (domain->shared_values) {
+            return cbor64_tag(streamer, CBOR64_TAG_SHAREABLE);
+        } else {
+            return 0;
+        }
+    } else {
+        return 0;
+    }
+}
+
+typedef struct {
+    bool emit_literal;
+    int error;
+} emit_reference_ret_t;
+
+/*
+ * Emit a reference to a string
+ */
+static emit_reference_ret_t emit_reference(base64_t *streamer, cbor64_domain_t *domain, char *string)
+{
+    size_t index = find_reference(domain, string);
+    emit_reference_ret_t ret = {
+        .emit_literal = false,
+        .error = 0,
+    };
+
+    if (domain->strings[index] == NULL) {
+        /* String not in index, just emit it its own namespace */
+        if (!domain->shared_values) {
+            ret.error = cbor64_tag(streamer, CBOR64_TAG_STRING_REF_DOMAIN);
+        }
+        ret.emit_literal = true;
+    } else if (index < domain->emitted) {
+        /* String already emitted, emit reference */
+        if (domain->shared_values) {
+            ret.error = cbor64_tag(streamer, CBOR64_TAG_SHARED_VALUE);
+        } else {
+            ret.error = cbor64_tag(streamer, CBOR64_TAG_STRING_REF);
+        }
+        if (ret.error == 0) {
+            ret.error = cbor64_int(streamer, index);
+        }
+    } else {
+        /* Create a new reference */
+        ret.error = new_reference(streamer, domain, index);
+        ret.emit_literal = true;
+    }
+
+    return ret;
+}
+
+/*
+ * Emit a string reference
+ */
+int cbor64_string_ref(base64_t *streamer, cbor64_domain_t *domain, char *string)
+{
+    emit_reference_ret_t ret = emit_reference(streamer, domain, string);
+    if (ret.error == 0 && ret.emit_literal) {
+        ret.error = cbor64_string(streamer, string);
+    }
+    return ret.error;
+}
+
+/*
+ * Emit a utf8 reference
+ */
+int cbor64_utf8_ref(base64_t *streamer, cbor64_domain_t *domain, char *string)
+{
+    emit_reference_ret_t ret = emit_reference(streamer, domain, string);
+    if (ret.error == 0 && ret.emit_literal) {
+        ret.error = cbor64_utf8(streamer, string);
+    }
+    return ret.error;
+}
diff --git a/libutils/src/debug.c b/libutils/src/debug.c
index 97ce69f..d156f5f 100644
--- a/libutils/src/debug.c
+++ b/libutils/src/debug.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 #include <utils/debug.h>
 #include <stdint.h>
@@ -20,12 +14,11 @@
 #define MD_BYTES_PER_LINE (sizeof(uint32_t) * 4)
 #define MD_GROUPING       4
 
-static void
-md_print_line(void* address, int word_size)
+static void md_print_line(void *address, int word_size)
 {
     uint8_t line[MD_BYTES_PER_LINE];
-    int num_objects = MD_BYTES_PER_LINE / word_size;
-    int object;
+    unsigned num_objects = MD_BYTES_PER_LINE / word_size;
+    unsigned object;
     printf("%p: ", address);
     for (object = 0; object < num_objects; object++) {
         int object_offset = object * word_size;
@@ -34,25 +27,25 @@
         }
         switch (word_size) {
         case 1: {
-            uint8_t temp = *(volatile uint8_t*)(address + object_offset);
+            uint8_t temp = *(volatile uint8_t *)((uintptr_t)address + object_offset);
             printf("0x%02x ", temp);
             memcpy(&line[object_offset], &temp, sizeof(temp));
             break;
         }
         case 2: {
-            uint16_t temp = *(volatile uint16_t*)(address + object_offset);
+            uint16_t temp = *(volatile uint16_t *)((uintptr_t)address + object_offset);
             printf("0x%04x ", temp);
             memcpy(&line[object_offset], &temp, sizeof(temp));
             break;
         }
         case 4: {
-            uint32_t temp = *(volatile uint32_t*)(address + object_offset);
+            uint32_t temp = *(volatile uint32_t *)((uintptr_t)address + object_offset);
             printf("0x%08x ", temp);
             memcpy(&line[object_offset], &temp, sizeof(temp));
             break;
         }
         case 8: {
-            uint64_t temp = *(volatile uint64_t*)(address + object_offset);
+            uint64_t temp = *(volatile uint64_t *)((uintptr_t)address + object_offset);
             printf("0x%016"PRIx64" ", temp);
             memcpy(&line[object_offset], &temp, sizeof(temp));
             break;
@@ -71,22 +64,20 @@
     printf("|\n");
 }
 
-void
-utils_memory_dump(void* address, size_t bytes, int word_size)
+void utils_memory_dump(void *address, size_t bytes, int word_size)
 {
-    void* a;
     if (word_size == 1 || word_size == 2 || word_size == 4 || word_size == 8) {
         /* Notify the caller if 'bytes' is not a multple of MD_BYTES_PER_LINE */
         if (bytes % MD_BYTES_PER_LINE) {
             int extra_bytes = MD_BYTES_PER_LINE - (bytes % MD_BYTES_PER_LINE);
-            LOG_INFO("Rounding displayed bytes from %zu up to %zu", bytes, bytes + extra_bytes);
+            ZF_LOGI("Rounding displayed bytes from %zu up to %zu", bytes, bytes + extra_bytes);
             bytes += extra_bytes;
         }
         /* Print each line */
-        for (a = address; a < address + bytes; a += MD_BYTES_PER_LINE) {
-            md_print_line(a, word_size);
+        for (size_t i = 0; i < bytes; i += MD_BYTES_PER_LINE) {
+            md_print_line(&((uint8_t *)address)[i], word_size);
         }
     } else {
-        LOG_ERROR("Invalid word size (%d). Valid options are [1, 2, 4, 8]", word_size);
+        ZF_LOGE("Invalid word size (%d). Valid options are [1, 2, 4, 8]", word_size);
     }
 }
diff --git a/libutils/src/list.c b/libutils/src/list.c
index 6e8d8c2..36afaee 100644
--- a/libutils/src/list.c
+++ b/libutils/src/list.c
@@ -1,19 +1,14 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <assert.h>
 #include <stdbool.h>
 #include <stdlib.h>
 #include <utils/list.h>
+#include <utils/attribute.h>
 
 typedef struct list_node node_t;
 
@@ -141,7 +136,7 @@
     return 0;
 }
 
-int list_destroy(list_t *l)
+int list_destroy(UNUSED list_t *l)
 {
     /* Nothing required. */
     return 0;
diff --git a/libutils/src/xml.c b/libutils/src/xml.c
index 0803735..4d3aaf6 100644
--- a/libutils/src/xml.c
+++ b/libutils/src/xml.c
@@ -1,13 +1,7 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * Copyright 2017, Data61, CSIRO (ABN 41 687 119 230)
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * SPDX-License-Identifier: BSD-2-Clause
  */
 
 #include <stddef.h>
diff --git a/libutils/src/zf_log.c b/libutils/src/zf_log.c
index 6742263..7d449d6 100644
--- a/libutils/src/zf_log.c
+++ b/libutils/src/zf_log.c
@@ -1,14 +1,10 @@
 /*
- * Copyright 2017, Data61
- * Commonwealth Scientific and Industrial Research Organisation (CSIRO)
- * ABN 41 687 119 230.
+ * SPDX-License-Identifier: MIT
+ * Copyright (c) 2017 wonder-mice
  *
- * This software may be distributed and modified according to the terms of
- * the BSD 2-Clause license. Note that NO WARRANTY is provided.
- * See "LICENSE_BSD2.txt" for details.
- *
- * @TAG(DATA61_BSD)
+ * zf log taken from: https://github.com/wonder-mice/zf_log
  */
+
 #include <utils/zf_log_config.h>
 
 /* Controls Android log (android/log.h) support. When defined, must be 1