public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH edk2-platforms 00/13] Silicon/NXP: Import NXP i.MX6 Package
@ 2018-07-20  6:33 Chris Co
  2018-07-20  6:33 ` [PATCH edk2-platforms 01/13] Silicon/NXP: Add i.MX6 SoC header files Chris Co
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: Chris Co @ 2018-07-20  6:33 UTC (permalink / raw)
  To: edk2-devel@lists.01.org; +Cc: Ard Biesheuvel, Leif Lindholm, Michael D Kinney

REF: https://github.com/christopherco/edk2-platforms/tree/import_imx6_v1

This patch set is the 3rd in the overall series of patches to generate
UEFI firmware that supports Windows 10 IoT Core on Solidrun's Hummingboard
Edge board running NXP's i.MX6Q SoC.

Patch Series:
1. import Platform/Microsoft
2. import Silicon/NXP/iMXPlatformPkg
3. import Silicon/NXP/iMX6Pkg
4. import Platform/Solidrun/HummingboardEdge_iMX6Q_2GB

This patch set imports our iMX6Pkg package which contains modules that
support the NXP i.MX6 SoC. Platforms that use the i.MX6 SoC are expected to
include this package and make platform-specific overrides that pertain
to their board. This package currently supports the i.MX6 Solo, SoloX, Dual,
DualLite, Quad variants.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Christopher Co <christopher.co@microsoft.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>

Christopher Co (13):
  Silicon/NXP: Add i.MX6 SoC header files
  Silicon/NXP: Add i.MX6 GPT and EPIT timer headers
  Silicon/NXP: Add iMX6Pkg dec
  Silicon/NXP: Add i.MX6 Timer DXE driver
  Silicon/NXP: Add i.MX6 GPT Timer library
  Silicon/NXP: Add i.MX6 USB Phy Library
  Silicon/NXP: Add i.MX6 I/O MUX library
  Silicon/NXP: Add i.MX6 Clock Library
  Silicon/NXP: Add i.MX6 ACPI tables
  Silicon/NXP: Add i.MX6 Board init library
  Silicon/NXP: Add i.MX6 PCIe DXE driver
  Silicon/NXP: Add i.MX6 GOP driver
  Silicon/NXP: Add i.MX6 common dsc and fdf files

 Silicon/NXP/iMX6Pkg/AcpiTables/Csrt.aslc                       |  470 ++++
 Silicon/NXP/iMX6Pkg/AcpiTables/Dbg2.aslc                       |  148 ++
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Common.inc                 |  112 +
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Enet.inc                   |  111 +
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Gfx.inc                    |   58 +
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Gpio.inc                   |   47 +
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-I2c.inc                    |   64 +
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-PCIe.inc                   |  483 ++++
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Platform.inc               |  121 +
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Pwm.inc                    |   80 +
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Sdhc.inc                   |  225 ++
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Spi.inc                    |   98 +
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-TrEE.inc                   |   36 +
 Silicon/NXP/iMX6Pkg/AcpiTables/Fadt.aslc                       |   56 +
 Silicon/NXP/iMX6Pkg/AcpiTables/Madt.aslc                       |  124 +
 Silicon/NXP/iMX6Pkg/AcpiTables/Mcfg.aslc                       |  148 ++
 Silicon/NXP/iMX6Pkg/AcpiTables/Spcr.aslc                       |   92 +
 Silicon/NXP/iMX6Pkg/AcpiTables/Tpm2.aslc                       |   69 +
 Silicon/NXP/iMX6Pkg/Drivers/GOP/CPMem.c                        |  327 +++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/CPMem.h                        |  276 +++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Ddc.c                          |   58 +
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Ddc.h                          |   27 +
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Display.c                      |  442 ++++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Display.h                      |  171 ++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayController.c            |  388 +++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayController.h            |  312 +++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayInterface.c             |  444 ++++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayInterface.h             |  182 ++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Edid.c                         |   82 +
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Edid.h                         |   31 +
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Hdmi.c                         |  608 +++++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Hdmi.h                         |  537 +++++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/IoMux.c                        |   83 +
 Silicon/NXP/iMX6Pkg/Drivers/GOP/IoMux.h                        |   31 +
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Ipu.h                          |  236 ++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Lvds.c                         |   81 +
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Lvds.h                         |   72 +
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Osal.c                         |   38 +
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Osal.h                         |   74 +
 Silicon/NXP/iMX6Pkg/Drivers/GOP/iMX6GOP.inf                    |   71 +
 Silicon/NXP/iMX6Pkg/Drivers/GOP/iMXVideoDxe.c                  |  488 ++++
 Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.c        | 1219 ++++++++++
 Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.h        |  163 ++
 Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.inf      |   66 +
 Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/Timer.c                   |  268 +++
 Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/TimerDxe.inf              |   55 +
 Silicon/NXP/iMX6Pkg/Include/common_epit.h                      |  158 ++
 Silicon/NXP/iMX6Pkg/Include/common_gpt.h                       |  314 +++
 Silicon/NXP/iMX6Pkg/Include/iMX6.h                             |   39 +
 Silicon/NXP/iMX6Pkg/Include/iMX6BoardLib.h                     |   36 +
 Silicon/NXP/iMX6Pkg/Include/iMX6ClkPwr.h                       |  574 +++++
 Silicon/NXP/iMX6Pkg/Include/iMX6IoMux.h                        |  202 ++
 Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_DQ.h                     | 2464 +++++++++++++++++++
 Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_SDL.h                    | 2482 ++++++++++++++++++++
 Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_SX.h                     | 2275 ++++++++++++++++++
 Silicon/NXP/iMX6Pkg/Include/iMX6UsbPhy.h                       |   20 +
 Silicon/NXP/iMX6Pkg/Include/iMX6_DQ.h                          | 1686 +++++++++++++
 Silicon/NXP/iMX6Pkg/Include/iMX6_SDL.h                         | 1657 +++++++++++++
 Silicon/NXP/iMX6Pkg/Include/iMX6_SX.h                          | 1762 ++++++++++++++
 Silicon/NXP/iMX6Pkg/Library/TimerLib/TimerLib.c                |  257 ++
 Silicon/NXP/iMX6Pkg/Library/TimerLib/TimerLib.inf              |   37 +
 Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6BoardHelper.S     |   94 +
 Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6BoardMem.c        |  106 +
 Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6Common.c          |   92 +
 Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6QBoardCoreDef.c   |  107 +
 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwr.c         |  501 ++++
 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwrLib.inf    |   46 +
 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwr_private.h |  203 ++
 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6DQClkPwr.inc     | 1278 ++++++++++
 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6SDLClkPwr.inc    | 1231 ++++++++++
 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6SXClkPwr.inc     |  665 ++++++
 Silicon/NXP/iMX6Pkg/Library/iMX6IoMuxLib/iMX6IoMux.c           |  163 ++
 Silicon/NXP/iMX6Pkg/Library/iMX6IoMuxLib/iMX6IoMuxLib.inf      |   41 +
 Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhy.c         |  364 +++
 Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhyLib.inf    |   43 +
 Silicon/NXP/iMX6Pkg/iMX6CommonDsc.inc                          |  918 ++++++++
 Silicon/NXP/iMX6Pkg/iMX6CommonFdf.inc                          |  385 +++
 Silicon/NXP/iMX6Pkg/iMX6ConfigDsc.inc                          |  115 +
 Silicon/NXP/iMX6Pkg/iMX6Pkg.dec                                |  100 +
 79 files changed, 29787 insertions(+)
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Csrt.aslc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Dbg2.aslc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Common.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Enet.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Gfx.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Gpio.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-I2c.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-PCIe.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Platform.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Pwm.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Sdhc.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Spi.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-TrEE.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Fadt.aslc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Madt.aslc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Mcfg.aslc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Spcr.aslc
 create mode 100644 Silicon/NXP/iMX6Pkg/AcpiTables/Tpm2.aslc
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/CPMem.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/CPMem.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/Ddc.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/Ddc.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/Display.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/Display.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayController.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayController.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayInterface.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayInterface.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/Edid.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/Edid.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/Hdmi.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/Hdmi.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/IoMux.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/IoMux.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/Ipu.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/Lvds.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/Lvds.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/Osal.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/Osal.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/iMX6GOP.inf
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/GOP/iMXVideoDxe.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.inf
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/Timer.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/TimerDxe.inf
 create mode 100644 Silicon/NXP/iMX6Pkg/Include/common_epit.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Include/common_gpt.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Include/iMX6.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Include/iMX6BoardLib.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Include/iMX6ClkPwr.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Include/iMX6IoMux.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_DQ.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_SDL.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_SX.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Include/iMX6UsbPhy.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Include/iMX6_DQ.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Include/iMX6_SDL.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Include/iMX6_SX.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Library/TimerLib/TimerLib.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Library/TimerLib/TimerLib.inf
 create mode 100644 Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6BoardHelper.S
 create mode 100644 Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6BoardMem.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6Common.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6QBoardCoreDef.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwr.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwrLib.inf
 create mode 100644 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwr_private.h
 create mode 100644 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6DQClkPwr.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6SDLClkPwr.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6SXClkPwr.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/Library/iMX6IoMuxLib/iMX6IoMux.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Library/iMX6IoMuxLib/iMX6IoMuxLib.inf
 create mode 100644 Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhy.c
 create mode 100644 Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhyLib.inf
 create mode 100644 Silicon/NXP/iMX6Pkg/iMX6CommonDsc.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/iMX6CommonFdf.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/iMX6ConfigDsc.inc
 create mode 100644 Silicon/NXP/iMX6Pkg/iMX6Pkg.dec

-- 
2.16.2.gvfs.1.33.gf5370f1



^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH edk2-platforms 01/13] Silicon/NXP: Add i.MX6 SoC header files
  2018-07-20  6:33 [PATCH edk2-platforms 00/13] Silicon/NXP: Import NXP i.MX6 Package Chris Co
@ 2018-07-20  6:33 ` Chris Co
  2018-07-20  6:33 ` [PATCH edk2-platforms 02/13] Silicon/NXP: Add i.MX6 GPT and EPIT timer headers Chris Co
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chris Co @ 2018-07-20  6:33 UTC (permalink / raw)
  To: edk2-devel@lists.01.org; +Cc: Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This adds includes for NXP i.MX6 SoC family, specifically Dual/Quad,
Solo/DualLite, and SoloX families.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Christopher Co <christopher.co@microsoft.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/NXP/iMX6Pkg/Include/iMX6.h          |   39 +
 Silicon/NXP/iMX6Pkg/Include/iMX6BoardLib.h  |   36 +
 Silicon/NXP/iMX6Pkg/Include/iMX6ClkPwr.h    |  574 +++++
 Silicon/NXP/iMX6Pkg/Include/iMX6IoMux.h     |  202 ++
 Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_DQ.h  | 2464 +++++++++++++++++++
 Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_SDL.h | 2482 ++++++++++++++++++++
 Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_SX.h  | 2275 ++++++++++++++++++
 Silicon/NXP/iMX6Pkg/Include/iMX6UsbPhy.h    |   20 +
 Silicon/NXP/iMX6Pkg/Include/iMX6_DQ.h       | 1686 +++++++++++++
 Silicon/NXP/iMX6Pkg/Include/iMX6_SDL.h      | 1657 +++++++++++++
 Silicon/NXP/iMX6Pkg/Include/iMX6_SX.h       | 1762 ++++++++++++++
 11 files changed, 13197 insertions(+)

diff --git a/Silicon/NXP/iMX6Pkg/Include/iMX6.h b/Silicon/NXP/iMX6Pkg/Include/iMX6.h
new file mode 100644
index 000000000000..0d94e5209f4d
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Include/iMX6.h
@@ -0,0 +1,39 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __IMX6_H__
+#define __IMX6_H__
+
+//
+// Platform specific definition
+//
+#define EFI_ACPI_OEM_TABLE_ID                   SIGNATURE_64('I','M','X','6','E','D','K','2') // OEM table id 8 bytes long
+#define EFI_ACPI_OEM_REVISION                   0x01000101
+#define EFI_ACPI_CREATOR_ID                     SIGNATURE_32('I','M','X','6')
+#define EFI_ACPI_CREATOR_REVISION               0x00000001
+
+#if defined(CPU_IMX6DQ)
+#include "iMX6_DQ.h"
+#elif defined(CPU_IMX6SDL)
+#include "iMX6_SDL.h"
+#elif defined(CPU_IMX6SX)
+#include "iMX6_SX.h"
+#else
+#error iMX6 CPU Type Not Defined! (Preprocessor Flag)
+#endif
+
+#define SERIAL_DEBUG_PORT_INIT_MSG "\r\nDebug Serial Port Init\r\n"
+#define SERIAL_PORT_INIT_MSG "UART"
+
+#endif // __IMX6_H__
diff --git a/Silicon/NXP/iMX6Pkg/Include/iMX6BoardLib.h b/Silicon/NXP/iMX6Pkg/Include/iMX6BoardLib.h
new file mode 100644
index 000000000000..821d87ed94a4
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Include/iMX6BoardLib.h
@@ -0,0 +1,36 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _IMX6_BOARD_LIB_H_
+#define _IMX6_BOARD_LIB_H_
+
+/*
+  Mandatory functions to implement by the board library.
+*/
+
+VOID ImxClkPwrInit ();
+
+/*
+  Optional functions to implement by the board library.
+  The default implementation of these functions if not overridden is NOOP.
+*/
+
+VOID SdhcInit ();
+VOID EhciInit ();
+VOID I2cInit ();
+VOID SpiInit ();
+VOID PcieInit ();
+VOID SetupAudio ();
+
+#endif // _IMX6_BOARD_LIB_H_
diff --git a/Silicon/NXP/iMX6Pkg/Include/iMX6ClkPwr.h b/Silicon/NXP/iMX6Pkg/Include/iMX6ClkPwr.h
new file mode 100644
index 000000000000..7ae5396d553d
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Include/iMX6ClkPwr.h
@@ -0,0 +1,574 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Copyright 2018 NXP
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _IMX6_CLK_PWR_H_
+#define _IMX6_CLK_PWR_H_
+
+#ifdef CPU_IMX6DQ
+//
+// Clock signal definitions
+//
+typedef enum {
+  IMX_CLK_NONE,
+  IMX_OSC_CLK,
+  IMX_PLL1_MAIN_CLK,
+  IMX_PLL2_MAIN_CLK,
+  IMX_PLL2_PFD0,
+  IMX_PLL2_PFD1,
+  IMX_PLL2_PFD2,
+  IMX_PLL3_MAIN_CLK,
+  IMX_PLL3_PFD0,
+  IMX_PLL3_PFD1,
+  IMX_PLL3_PFD2,
+  IMX_PLL3_PFD3,
+  IMX_PLL4_MAIN_CLK,
+  IMX_PLL5_MAIN_CLK,
+  IMX_CLK1,
+  IMX_CLK2,
+  IMX_PLL1_SW_CLK,
+  IMX_STEP_CLK,
+  IMX_PLL3_SW_CLK,
+  IMX_AXI_ALT,
+  IMX_AXI_CLK_ROOT,
+  IMX_PERIPH_CLK2,
+  IMX_PERIPH_CLK,
+  IMX_PRE_PERIPH_CLK,
+  IMX_PRE_PERIPH2_CLK,
+  IMX_PERIPH2_CLK,
+  IMX_ARM_CLK_ROOT,
+  IMX_MMDC_CH0_CLK_ROOT,
+  IMX_MMDC_CH1_CLK_ROOT,
+  IMX_AHB_CLK_ROOT,
+  IMX_IPG_CLK_ROOT,
+  IMX_PERCLK_CLK_ROOT,
+  IMX_USDHC1_CLK_ROOT,
+  IMX_USDHC2_CLK_ROOT,
+  IMX_USDHC3_CLK_ROOT,
+  IMX_USDHC4_CLK_ROOT,
+  IMX_SSI1_CLK_ROOT,
+  IMX_SSI2_CLK_ROOT,
+  IMX_SSI3_CLK_ROOT,
+  IMX_GPU2D_AXI_CLK_ROOT,
+  IMX_GPU3D_AXI_CLK_ROOT,
+  IMX_PCIE_AXI_CLK_ROOT,
+  IMX_VDO_AXI_CLK_ROOT,
+  IMX_IPU1_HSP_CLK_ROOT,
+  IMX_IPU2_HSP_CLK_ROOT,
+  IMX_GPU2D_CORE_CLK_ROOT,
+  IMX_ACLK_EIM_SLOW_CLK_ROOT,
+  IMX_ACLK_CLK_ROOT,
+  IMX_ENFC_CLK_ROOT,
+  IMX_GPU3D_CORE_CLK_ROOT,
+  IMX_GPU3D_SHADER_CLK_ROOT,
+  IMX_VPU_AXI_CLK_ROOT,
+  IMX_IPU1_DI0_CLK_ROOT,
+  IMX_IPU1_DI1_CLK_ROOT,
+  IMX_IPU2_DI0_CLK_ROOT,
+  IMX_IPU2_DI1_CLK_ROOT,
+  IMX_LDB_DI0_SERIAL_CLK_ROOT,
+  IMX_LDB_DI0_IPU,
+  IMX_LDB_DI1_SERIAL_CLK_ROOT,
+  IMX_LDB_DI1_IPU,
+  IMX_SPDIF0_CLK_ROOT,
+  IMX_SPDIF1_CLK_ROOT,
+  IMX_ESAI_CLK_ROOT,
+  IMX_HSI_TX_CLK_ROOT,
+  IMX_CAN_CLK_ROOT,
+  IMX_ECSPI_CLK_ROOT,
+  IMX_UART_CLK_ROOT,
+  IMX_VIDEO_27M_CLK_ROOT,
+  IMX_CLK_MAX,
+} IMX_CLK;
+
+//
+// Clock gate definitions
+//
+typedef enum {
+  IMX_AIPS_TZ1_CLK_ENABLE,
+  IMX_AIPS_TZ2_CLK_ENABLE,
+  IMX_APBHDMA_HCLK_ENABLE,
+  IMX_ASRC_CLK_ENABLE,
+  IMX_CAAM_SECURE_MEM_CLK_ENABLE,
+  IMX_CAAM_WRAPPER_ACLK_ENABLE,
+  IMX_CAAM_WRAPPER_IPG_ENABLE,
+  IMX_CAN1_CLK_ENABLE,
+  IMX_CAN1_SERIAL_CLK_ENABLE,
+  IMX_CAN2_CLK_ENABLE,
+  IMX_CAN2_SERIAL_CLK_ENABLE,
+  IMX_ARM_DBG_CLK_ENABLE,
+  IMX_DCIC1_CLK_ENABLE,
+  IMX_DCIC2_CLK_ENABLE,
+  IMX_DTCP_CLK_ENABLE,
+  IMX_ECSPI1_CLK_ENABLE,
+  IMX_ECSPI2_CLK_ENABLE,
+  IMX_ECSPI3_CLK_ENABLE,
+  IMX_ECSPI4_CLK_ENABLE,
+  IMX_ECSPI5_CLK_ENABLE,
+  IMX_ENET_CLK_ENABLE,
+  IMX_EPIT1_CLK_ENABLE,
+  IMX_EPIT2_CLK_ENABLE,
+  IMX_ESAI_CLK_ENABLE,
+  IMX_GPT_CLK_ENABLE,
+  IMX_GPT_SERIAL_CLK_ENABLE,
+  IMX_GPU2D_CLK_ENABLE,
+  IMX_GPU3D_CLK_ENABLE,
+  IMX_HDMI_TX_ENABLE,
+  IMX_HDMI_TX_ISFRCLK_ENABLE,
+  IMX_I2C1_SERIAL_CLK_ENABLE,
+  IMX_I2C2_SERIAL_CLK_ENABLE,
+  IMX_I2C3_SERIAL_CLK_ENABLE,
+  IMX_IIM_CLK_ENABLE,
+  IMX_IOMUX_IPT_CLK_IO_ENABLE,
+  IMX_IPMUX1_CLK_ENABLE,
+  IMX_IPMUX2_CLK_ENABLE,
+  IMX_IPMUX3_CLK_ENABLE,
+  IMX_IPSYNC_IP2APB_TZASC1_IPG_MASTER_CLK_ENABLE,
+  IMX_IPSYNC_IP2APB_TZASC2_IPG_MASTER_CLK_ENABLE,
+  IMX_IPSYNC_VDOA_IPG_MASTER_CLK_ENABLE,
+  IMX_IPU1_CLK_ENABLE,
+  IMX_IPU1_DI0_CLK_ENABLE,
+  IMX_IPU1_DI1_CLK_ENABLE,
+  IMX_IPU2_CLK_ENABLE,
+  IMX_IPU2_DI0_CLK_ENABLE,
+  IMX_IPU2_DI1_CLK_ENABLE,
+  IMX_LDB_DI0_CLK_ENABLE,
+  IMX_LDB_DI1_CLK_ENABLE,
+  IMX_MIPI_CORE_CFG_CLK_ENABLE,
+  IMX_MLB_CLK_ENABLE,
+  IMX_MMDC_CORE_ACLK_FAST_CORE_P0_ENABLE,
+  IMX_MMDC_CORE_IPG_CLK_P0_ENABLE,
+  IMX_OCRAM_CLK_ENABLE,
+  IMX_OPENVGAXICLK_CLK_ROOT_ENABLE,
+  IMX_PCIE_ROOT_ENABLE,
+  IMX_PL301_MX6QFAST1_S133CLK_ENABLE,
+  IMX_PL301_MX6QPER1_BCHCLK_ENABLE,
+  IMX_PL301_MX6QPER2_MAINCLK_ENABLE,
+  IMX_PWM1_CLK_ENABLE,
+  IMX_PWM2_CLK_ENABLE,
+  IMX_PWM3_CLK_ENABLE,
+  IMX_PWM4_CLK_ENABLE,
+  IMX_RAWNAND_U_BCH_INPUT_APB_CLK_ENABLE,
+  IMX_RAWNAND_U_GPMI_BCH_INPUT_BCH_CLK_ENABLE,
+  IMX_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_CLK_ENABLE,
+  IMX_RAWNAND_U_GPMI_INPUT_APB_CLK_ENABLE,
+  IMX_ROM_CLK_ENABLE,
+  IMX_SATA_CLK_ENABLE,
+  IMX_SDMA_CLK_ENABLE,
+  IMX_SPBA_CLK_ENABLE,
+  IMX_SPDIF_CLK_ENABLE,
+  IMX_SSI1_CLK_ENABLE,
+  IMX_SSI2_CLK_ENABLE,
+  IMX_SSI3_CLK_ENABLE,
+  IMX_UART_CLK_ENABLE,
+  IMX_UART_SERIAL_CLK_ENABLE,
+  IMX_USBOH3_CLK_ENABLE,
+  IMX_USDHC1_CLK_ENABLE,
+  IMX_USDHC2_CLK_ENABLE,
+  IMX_USDHC3_CLK_ENABLE,
+  IMX_USDHC4_CLK_ENABLE,
+  IMX_EIM_SLOW_CLK_ENABLE,
+  IMX_VDOAXICLK_CLK_ENABLE,
+  IMX_VPU_CLK_ENABLE,
+  IMX_CLK_GATE_MAX,
+} IMX_CLK_GATE;
+
+#elif defined(CPU_IMX6SDL)
+//
+// Clock signal definitions for iMX6 Solo and DualLite
+//
+typedef enum {
+  IMX_CLK_NONE,
+  IMX_OSC_CLK,
+  IMX_PLL1_MAIN_CLK,
+  IMX_PLL2_MAIN_CLK,
+  IMX_PLL2_PFD0,
+  IMX_PLL2_PFD1,
+  IMX_PLL2_PFD2,
+  IMX_PLL3_MAIN_CLK,
+  IMX_PLL3_PFD0,
+  IMX_PLL3_PFD1,
+  IMX_PLL3_PFD2,
+  IMX_PLL3_PFD3,
+  IMX_PLL4_MAIN_CLK,
+  IMX_PLL5_MAIN_CLK,
+  IMX_CLK1,
+  IMX_CLK2,
+  IMX_PLL1_SW_CLK,
+  IMX_STEP_CLK,
+  IMX_PLL3_SW_CLK,
+  IMX_AXI_ALT,
+  IMX_AXI_CLK_ROOT,
+  IMX_PERIPH_CLK2,
+  IMX_PERIPH_CLK,
+  IMX_PRE_PERIPH_CLK,
+  IMX_PRE_PERIPH2_CLK,
+  IMX_PERIPH2_CLK,
+  IMX_ARM_CLK_ROOT,
+  IMX_MMDC_CH0_CLK_ROOT,
+  IMX_MMDC_CH1_CLK_ROOT,
+  IMX_AHB_CLK_ROOT,
+  IMX_IPG_CLK_ROOT,
+  IMX_PERCLK_CLK_ROOT,
+  IMX_USDHC1_CLK_ROOT,
+  IMX_USDHC2_CLK_ROOT,
+  IMX_USDHC3_CLK_ROOT,
+  IMX_USDHC4_CLK_ROOT,
+  IMX_SSI1_CLK_ROOT,
+  IMX_SSI2_CLK_ROOT,
+  IMX_SSI3_CLK_ROOT,
+  IMX_GPU2D_AXI_CLK_ROOT,
+  IMX_GPU3D_AXI_CLK_ROOT,
+  IMX_PCIE_AXI_CLK_ROOT,
+  IMX_VDO_AXI_CLK_ROOT,
+  IMX_IPU1_HSP_CLK_ROOT,
+  IMX_GPU2D_CORE_CLK_ROOT,
+  IMX_ACLK_EIM_SLOW_CLK_ROOT,
+  IMX_ACLK_CLK_ROOT,
+  IMX_ENFC_CLK_ROOT,
+  IMX_GPU3D_CORE_CLK_ROOT,
+  IMX_GPU3D_SHADER_CLK_ROOT,
+  IMX_VPU_AXI_CLK_ROOT,
+  IMX_IPU1_DI0_CLK_ROOT,
+  IMX_IPU1_DI1_CLK_ROOT,
+  IMX_LDB_DI0_SERIAL_CLK_ROOT,
+  IMX_LDB_DI0_IPU,
+  IMX_LDB_DI1_SERIAL_CLK_ROOT,
+  IMX_LDB_DI1_IPU,
+  IMX_SPDIF0_CLK_ROOT,
+  IMX_SPDIF1_CLK_ROOT,
+  IMX_ESAI_CLK_ROOT,
+  IMX_HSI_TX_CLK_ROOT,
+  IMX_CAN_CLK_ROOT,
+  IMX_ECSPI_CLK_ROOT,
+  IMX_UART_CLK_ROOT,
+  IMX_VIDEO_27M_CLK_ROOT,
+  IMX_CLK_MAX,
+} IMX_CLK;
+
+//
+// Clock gate definitions
+//
+typedef enum {
+  IMX_AIPS_TZ1_CLK_ENABLE,
+  IMX_AIPS_TZ2_CLK_ENABLE,
+  IMX_APBHDMA_HCLK_ENABLE,
+  IMX_ASRC_CLK_ENABLE,
+  IMX_CAAM_SECURE_MEM_CLK_ENABLE,
+  IMX_CAAM_WRAPPER_ACLK_ENABLE,
+  IMX_CAAM_WRAPPER_IPG_ENABLE,
+  IMX_CAN1_CLK_ENABLE,
+  IMX_CAN1_SERIAL_CLK_ENABLE,
+  IMX_CAN2_CLK_ENABLE,
+  IMX_CAN2_SERIAL_CLK_ENABLE,
+  IMX_ARM_DBG_CLK_ENABLE,
+  IMX_DCIC1_CLK_ENABLE,
+  IMX_DCIC2_CLK_ENABLE,
+  IMX_DTCP_CLK_ENABLE,
+  IMX_ECSPI1_CLK_ENABLE,
+  IMX_ECSPI2_CLK_ENABLE,
+  IMX_ECSPI3_CLK_ENABLE,
+  IMX_ECSPI4_CLK_ENABLE,
+  IMX_ECSPI5_CLK_ENABLE,
+  IMX_ENET_CLK_ENABLE,
+  IMX_EPIT1_CLK_ENABLE,
+  IMX_EPIT2_CLK_ENABLE,
+  IMX_ESAI_CLK_ENABLE,
+  IMX_GPT_CLK_ENABLE,
+  IMX_GPT_SERIAL_CLK_ENABLE,
+  IMX_GPU2D_CLK_ENABLE,
+  IMX_GPU3D_CLK_ENABLE,
+  IMX_HDMI_TX_ENABLE,
+  IMX_HDMI_TX_ISFRCLK_ENABLE,
+  IMX_I2C1_SERIAL_CLK_ENABLE,
+  IMX_I2C2_SERIAL_CLK_ENABLE,
+  IMX_I2C3_SERIAL_CLK_ENABLE,
+  IMX_I2C4_SERIAL_CLK_ENABLE,
+  IMX_IIM_CLK_ENABLE,
+  IMX_IOMUX_IPT_CLK_IO_ENABLE,
+  IMX_IPMUX1_CLK_ENABLE,
+  IMX_IPMUX2_CLK_ENABLE,
+  IMX_IPMUX3_CLK_ENABLE,
+  IMX_IPSYNC_IP2APB_TZASC1_IPG_MASTER_CLK_ENABLE,
+  IMX_IPSYNC_IP2APB_TZASC2_IPG_MASTER_CLK_ENABLE,
+  IMX_IPSYNC_VDOA_IPG_MASTER_CLK_ENABLE,
+  IMX_IPU1_CLK_ENABLE,
+  IMX_IPU1_DI0_CLK_ENABLE,
+  IMX_IPU1_DI1_CLK_ENABLE,
+  IMX_LDB_DI0_CLK_ENABLE,
+  IMX_LDB_DI1_CLK_ENABLE,
+  IMX_MIPI_CORE_CFG_CLK_ENABLE,
+  IMX_MLB_CLK_ENABLE,
+  IMX_MMDC_CORE_ACLK_FAST_CORE_P0_ENABLE,
+  IMX_MMDC_CORE_IPG_CLK_P0_ENABLE,
+  IMX_OCRAM_CLK_ENABLE,
+  IMX_OPENVGAXICLK_CLK_ROOT_ENABLE,
+  IMX_PCIE_ROOT_ENABLE,
+  IMX_PL301_MX6QFAST1_S133CLK_ENABLE,
+  IMX_PL301_MX6QPER1_BCHCLK_ENABLE,
+  IMX_PL301_MX6QPER2_MAINCLK_ENABLE,
+  IMX_PWM1_CLK_ENABLE,
+  IMX_PWM2_CLK_ENABLE,
+  IMX_PWM3_CLK_ENABLE,
+  IMX_PWM4_CLK_ENABLE,
+  IMX_RAWNAND_U_BCH_INPUT_APB_CLK_ENABLE,
+  IMX_RAWNAND_U_GPMI_BCH_INPUT_BCH_CLK_ENABLE,
+  IMX_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_CLK_ENABLE,
+  IMX_RAWNAND_U_GPMI_INPUT_APB_CLK_ENABLE,
+  IMX_ROM_CLK_ENABLE,
+  IMX_SATA_CLK_ENABLE,
+  IMX_SDMA_CLK_ENABLE,
+  IMX_SPBA_CLK_ENABLE,
+  IMX_SPDIF_CLK_ENABLE,
+  IMX_SSI1_CLK_ENABLE,
+  IMX_SSI2_CLK_ENABLE,
+  IMX_SSI3_CLK_ENABLE,
+  IMX_UART_CLK_ENABLE,
+  IMX_UART_SERIAL_CLK_ENABLE,
+  IMX_USBOH3_CLK_ENABLE,
+  IMX_USDHC1_CLK_ENABLE,
+  IMX_USDHC2_CLK_ENABLE,
+  IMX_USDHC3_CLK_ENABLE,
+  IMX_USDHC4_CLK_ENABLE,
+  IMX_EIM_SLOW_CLK_ENABLE,
+  IMX_VDOAXICLK_CLK_ENABLE,
+  IMX_VPU_CLK_ENABLE,
+  IMX_CLK_GATE_MAX,
+} IMX_CLK_GATE;
+
+#elif defined(CPU_IMX6SX)
+//
+// Clock signal definitions
+//
+typedef enum {
+  IMX_CLK_NONE,
+  IMX_OSC_CLK,
+  IMX_PLL1_MAIN_CLK,
+  IMX_PLL2_MAIN_CLK,
+  IMX_PLL2_PFD0,
+  IMX_PLL2_PFD1,
+  IMX_PLL2_PFD2,
+  IMX_PLL2_PFD3,
+  IMX_PLL3_MAIN_CLK,
+  IMX_PLL3_PFD0,
+  IMX_PLL3_PFD1,
+  IMX_PLL3_PFD2,
+  IMX_PLL3_PFD3,
+  IMX_PLL4_MAIN_CLK,
+  IMX_PLL5_MAIN_CLK,
+  IMX_CLK1, // SX RM.p512
+  IMX_CLK2, // SX RM.p512
+  IMX_PLL1_SW_CLK, // SX RM.p795
+  IMX_STEP_CLK, // SX RM.p795
+  IMX_PLL3_SW_CLK, // SX RM.p795
+  IMX_PERIPH_CLK2, // SX RM.p797
+  IMX_PERIPH_CLK, // SX RM.p797
+  IMX_PRE_PERIPH_CLK, // SX RM.p797
+  IMX_ARM_CLK_ROOT,
+  IMX_MMDC_CLK_ROOT,
+  IMX_FABRIC_CLK_ROOT,
+  IMX_OCRAM_CLK_ROOT,
+  IMX_PCIE_CLK_ROOT,
+  IMX_AHB_CLK_ROOT,
+  IMX_PERCLK_CLK_ROOT,
+  IMX_IPG_CLK_ROOT,
+  IMX_USDHC1_CLK_ROOT,
+  IMX_USDHC2_CLK_ROOT,
+  IMX_USDHC3_CLK_ROOT,
+  IMX_USDHC4_CLK_ROOT,
+  IMX_ACLK_EIM_SLOW_CLK_ROOT,
+  IMX_GPU_AXI_CLK_ROOT,
+  IMX_GPU_CORE_CLK_ROOT,
+  IMX_VID_CLK_ROOT,
+  IMX_ESAI_CLK_ROOT,
+  IMX_AUDIO_CLK_ROOT,
+  IMX_SPDIF0_CLK_ROOT,
+  IMX_SSI1_CLK_ROOT,
+  IMX_SSI2_CLK_ROOT,
+  IMX_SSI3_CLK_ROOT,
+  IMX_LCDIF2_PIX_CLK_ROOT,
+  IMX_LCDIF1_PIX_CLK_ROOT,
+  IMX_LVDS_CLK_ROOT,
+  IMX_M4_CLK_ROOT,
+  IMX_ENET_CLK_ROOT,
+  IMX_QSPI1_CLK_ROOT,
+  IMX_QSPI2_CLK_ROOT,
+  IMX_DISPLAY_CLK_ROOT,
+  IMX_CSI_CLK_ROOT,
+  IMX_CAN_CLK_ROOT,
+  IMX_ECSPI_CLK_ROOT,
+  IMX_UART_CLK_ROOT,
+  IMX_CLK_MAX,
+} IMX_CLK; // SX RM.p777 Figure 19-2 Clock Tree
+
+//
+// Clock gate definitions
+//
+typedef enum {
+  IMX_AIPS_TZ1_CLK_ENABLE,
+  IMX_AIPS_TZ2_CLK_ENABLE,
+  IMX_APBHDMA_HCLK_ENABLE,
+  IMX_ASRC_CLK_ENABLE,
+  IMX_CAAM_SECURE_MEM_CLK_ENABLE,
+  IMX_CAAM_WRAPPER_ACLK_ENABLE,
+  IMX_CAAM_WRAPPER_IPG_ENABLE,
+  IMX_CAN1_CLK_ENABLE,
+  IMX_CAN1_SERIAL_CLK_ENABLE,
+  IMX_CAN2_CLK_ENABLE,
+  IMX_CAN2_SERIAL_CLK_ENABLE,
+  IMX_ARM_DBG_CLK_ENABLE,
+  IMX_DCIC1_CLK_ENABLE,
+  IMX_DCIC2_CLK_ENABLE,
+  IMX_AIPS_TZ3_CLK_ENABLE,
+  IMX_ECSPI1_CLK_ENABLE,
+  IMX_ECSPI2_CLK_ENABLE,
+  IMX_ECSPI3_CLK_ENABLE,
+  IMX_ECSPI4_CLK_ENABLE,
+  IMX_ECSPI5_CLK_ENABLE,
+  IMX_EPIT1_CLK_ENABLE,
+  IMX_EPIT2_CLK_ENABLE,
+  IMX_ESAI_CLK_ENABLE,
+  IMX_WAKEUP_CLK_ENABLE,
+  IMX_GPT_CLK_ENABLE,
+  IMX_GPT_SERIAL_CLK_ENABLE,
+  IMX_GPU_CLK_ENABLE,
+  IMX_OCRAM_S_CLK_ENABLE,
+  IMX_CANFD_CLK_ENABLE,
+  IMX_CSI_CLK_ENABLE,
+  IMX_I2C1_SERIAL_CLK_ENABLE,
+  IMX_I2C2_SERIAL_CLK_ENABLE,
+  IMX_I2C3_SERIAL_CLK_ENABLE,
+  IMX_IIM_CLK_ENABLE,
+  IMX_IOMUX_IPT_CLK_IO_ENABLE,
+  IMX_IPMUX1_CLK_ENABLE,
+  IMX_IPMUX2_CLK_ENABLE,
+  IMX_IPMUX3_CLK_ENABLE,
+  IMX_IPSYNC_IP2APB_TZASC1_IPG_MASTER_CLK_ENABLE,
+  IMX_LCD_CLK_ENABLE,
+  IMX_PXP_CLK_ENABLE,
+  IMX_M4_CLK_ENABLE,
+  IMX_ENET_CLK_ENABLE,
+  IMX_DISP_AXI_CLK_ENABLE,
+  IMX_LCDIF2_PIX_CLK_ENABLE,
+  IMX_LCDIF1_PIX_CLK_ENABLE,
+  IMX_LDB_DI0_CLK_ENABLE,
+  IMX_QSPI1_CLK_ENABLE,
+  IMX_MLB_CLK_ENABLE,
+  IMX_MMDC_CORE_ACLK_FAST_CORE_P0_ENABLE,
+  IMX_MMDC_CORE_IPG_CLK_P0_ENABLE,
+  IMX_MMDC_CORE_IPG_CLK_P1_ENABLE,
+  IMX_OCRAM_CLK_ENABLE,
+  IMX_PCIE_ROOT_ENABLE,
+  IMX_QSPI2_CLK_ENABLE,
+  IMX_PL301_MX6QPER1_BCHCLK_ENABLE,
+  IMX_PL301_MX6QPER2_MAINCLK_ENABLE,
+  IMX_PWM1_CLK_ENABLE,
+  IMX_PWM2_CLK_ENABLE,
+  IMX_PWM3_CLK_ENABLE,
+  IMX_PWM4_CLK_ENABLE,
+  IMX_RAWNAND_U_BCH_INPUT_APB_CLK_ENABLE,
+  IMX_RAWNAND_U_GPMI_BCH_INPUT_BCH_CLK_ENABLE,
+  IMX_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_CLK_ENABLE,
+  IMX_RAWNAND_U_GPMI_INPUT_APB_CLK_ENABLE,
+  IMX_ROM_CLK_ENABLE,
+  IMX_SDMA_CLK_ENABLE,
+  IMX_SPBA_CLK_ENABLE,
+  IMX_SPDIF_AND_AUDIO_CLK_ENABLE,
+  IMX_SSI1_CLK_ENABLE,
+  IMX_SSI2_CLK_ENABLE,
+  IMX_SSI3_CLK_ENABLE,
+  IMX_UART_CLK_ENABLE,
+  IMX_UART_SERIAL_CLK_ENABLE,
+  IMX_SAI1_CLK_ENABLE,
+  IMX_SAI2_CLK_ENABLE,
+  IMX_USBOH3_CLK_ENABLE,
+  IMX_USDHC1_CLK_ENABLE,
+  IMX_USDHC2_CLK_ENABLE,
+  IMX_USDHC3_CLK_ENABLE,
+  IMX_USDHC4_CLK_ENABLE,
+  IMX_EIM_SLOW_CLK_ENABLE,
+  IMX_PWM8_CLK_ENABLE,
+  IMX_VADC_CLK_ENABLE,
+  IMX_GIS_CLK_ENABLE,
+  IMX_I2C4_SERIAL_CLK_ENABLE,
+  IMX_PWM5_CLK_ENABLE,
+  IMX_PWM6_CLK_ENABLE,
+  IMX_PWM7_CLK_ENABLE,
+  IMX_CLK_GATE_MAX,
+} IMX_CLK_GATE;
+#else
+#error iMX6 CPU Type Not Defined!
+#endif
+
+typedef enum {
+  IMX_CLOCK_GATE_STATE_OFF = 0x0,
+  IMX_CLOCK_GATE_STATE_ON_RUN = 0x1,
+  IMX_CLOCK_GATE_STATE_ON = 0x3,
+} IMX_CLOCK_GATE_STATE;
+
+VOID ImxClkPwrSetClockGate (IMX_CLK_GATE ClockGate, IMX_CLOCK_GATE_STATE State);
+
+// Set multiple clock gates to a given state
+VOID
+ImxClkPwrSetClockGates (
+  const IMX_CLK_GATE *ClockGateList,
+  UINTN ClockGateCount,
+  IMX_CLOCK_GATE_STATE State
+  );
+
+IMX_CLOCK_GATE_STATE ImxClkPwrGetClockGate (IMX_CLK_GATE ClockGate);
+
+typedef struct {
+  UINT32 Frequency;
+  IMX_CLK Parent;
+} IMX_CLOCK_INFO;
+
+EFI_STATUS
+ImxClkPwrGetClockInfo (
+  IMX_CLK ClockId,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS ImxClkPwrGpuEnable ();
+
+EFI_STATUS ImxClkPwrIpuDIxEnable ();
+
+EFI_STATUS ImxClkPwrIpuLDBxEnable ();
+
+// The valid value for PLL loop divider is 27-54 so define the range of valid
+// frequency for PLL5 below before divider is applied.
+#define PLL5_MIN_FREQ 648000000
+#define PLL5_MAX_FREQ 1296000000
+EFI_STATUS ImxSetPll5ReferenceRate (UINT32 ClockRate);
+
+EFI_STATUS ImxClkPwrClkOut1Enable (IMX_CLK Clock, UINT32 Divider);
+
+VOID ImxClkPwrClkOut1Disable ();
+
+EFI_STATUS ImxClkPwrValidateClocks ();
+
+CONST CHAR16 *StringFromImxClk (IMX_CLK Value);
+
+#ifdef CPU_IMX6SX
+VOID ImxClkPwrLcdClockDisable ();
+VOID ImxClkPwrLcdClockEnable ();
+
+EFI_STATUS
+ImxSetLcdIfClockRate (
+    UINT32 ClockRate
+    ); // CPU_IMX6SX
+#else
+#endif
+
+#endif // _IMX6_CLK_PWR_H_
diff --git a/Silicon/NXP/iMX6Pkg/Include/iMX6IoMux.h b/Silicon/NXP/iMX6Pkg/Include/iMX6IoMux.h
new file mode 100644
index 000000000000..c585ec3dbdb1
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Include/iMX6IoMux.h
@@ -0,0 +1,202 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _IMX6_IOMUX_H_
+#define _IMX6_IOMUX_H_
+
+//
+// IOMux common definition
+//
+#include <iMXIoMux.h>
+
+//
+// GPIO common definition
+//
+#include <iMXGpio.h>
+
+#if defined(CPU_IMX6DQ)
+#include "iMX6IoMux_DQ.h"
+#elif defined(CPU_IMX6SX)
+#include "iMX6IoMux_SX.h"
+#elif defined(CPU_IMX6SDL)
+#include "iMX6IoMux_SDL.h"
+#else
+#error CPU Preprocessor Flag Not Defined
+#endif
+
+typedef UINT64 IMX_PADCFG;
+
+//
+// Pad control settings
+//
+typedef enum {
+  IMX_HYS_DISABLED,
+  IMX_HYS_ENABLED,
+} IMX_HYS;
+
+typedef enum {
+  IMX_PUS_100K_OHM_PD,
+  IMX_PUS_47K_OHM_PU,
+  IMX_PUS_100K_OHM_PU,
+  IMX_PUS_22K_OHM_PU,
+} IMX_PUS;
+
+typedef enum {
+  IMX_PUE_KEEP,
+  IMX_PUE_PULL,
+} IMX_PUE;
+
+typedef enum {
+  IMX_PKE_DISABLE,
+  IMX_PKE_ENABLE,
+} IMX_PKE;
+
+typedef enum {
+  IMX_ODE_DISABLE,
+  IMX_ODE_ENABLE,
+} IMX_ODE;
+
+typedef enum {
+  IMX_SPEED_LOW,
+  IMX_SPEED_MEDIUM = 2,
+  IMX_SPEED_MAXIMUM,
+} IMX_SPEED;
+
+typedef enum {
+  IMX_DSE_HIZ,
+  IMX_DSE_260_OHM,
+  IMX_DSE_130_OHM,
+  IMX_DSE_90_OHM,
+  IMX_DSE_60_OHM,
+  IMX_DSE_50_OHM,
+  IMX_DSE_40_OHM,
+  IMX_DSE_33_OHM,
+} IMX_DSE;
+
+typedef enum {
+  IMX_SRE_SLOW,
+  IMX_SRE_FAST,
+} IMX_SRE;
+
+typedef enum {
+    IMX_SION_DISABLED,
+    IMX_SION_ENABLED,
+} IMX_IOMUXC_CTL_SION;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    UINT32 SRE : 1;
+    UINT32 reserved0 : 2;
+    UINT32 DSE : 3;
+    UINT32 SPEED : 2;
+    UINT32 reserved1 : 3;
+    UINT32 ODE : 1 ;
+    UINT32 PKE : 1;
+    UINT32 PUE : 1;
+    UINT32 PUS : 2;
+    UINT32 HYS : 1;
+    UINT32 reserved2 : 15;
+  } Fields;
+} IMX_IOMUXC_PAD_CTL;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    UINT32 MUX_MODE : 3;
+    UINT32 reserved0 : 1;
+    UINT32 SION : 1;
+    UINT32 reserved1 : 27;
+  } Fields;
+} IMX_IOMUXC_MUX_CTL;
+
+typedef struct {
+  UINT32 DAISY : 3;
+  UINT32 reserved : 29;
+} IMX_IOMUXC_SEL_INP_CTL;
+
+#define _IMX_SEL_INP_VALUE(InpSel) \
+          (((InpSel) >> 8) & 0x07)
+
+#define _IMX_SEL_INP_REGISTER(InpSel) \
+          ((((InpSel) & 0xFF) * 4) + IOMUXC_SELECT_INPUT_BASE_ADDRESS)
+
+#define _IMX_MAKE_INP_SEL(InpSelReg, InpSelVal) \
+          (((((InpSelReg) - IOMUXC_SELECT_INPUT_BASE_ADDRESS) / 4) & 0xFF) | \
+          (((InpSelVal) & 0x7) << 8))
+
+#define _IMX_MAKE_MUX_CTL(Sion, MuxAlt) \
+          (((MuxAlt) & 0x7) | \
+          (((Sion) & 0x1) << 4))
+
+#define _IMX_MAKE_PAD_CTL(Sre, Dse, Speed, Ode, Pke, Pue, Pus, Hys) \
+          (((Sre) & 0x1) | \
+          (((Dse) & 0x7) << 3) | \
+          (((Speed) & 0x3) << 6) | \
+          (((Ode) & 0x1) << 11) | \
+          (((Pke) & 0x1) << 12) | \
+          (((Pue) & 0x1) << 13) | \
+          (((Pus) & 0x3) << 14) | \
+          (((Hys) & 0x1) << 16))
+
+/**
+  Define a configuration for a pad, including drive settings,
+  MUX setting and Select Input setting and offset.
+
+  Sre - IMX_SRE - Slew Rate setting
+  Dse - IMX_DSE - Drive strength
+  Speed - IMX_SPEED - Pad speed setting
+  Ode - IMX_ODE - Open drain enable
+  Pke - IMX_PKE - Pull/Keeper enable
+  Pue - IMX_PUE - Pull/Keep mode select
+  Pus - IMX_PUS - Pull strength
+  Hys - IMX_HYS - Hysteresis enable/disable
+  Sion - Software Input on Field
+  MuxAlt- Alternate function number
+  SelInpReg - select input register offset div 4
+  SelInpVal - select input value
+
+**/
+#define _IMX_MAKE_PADCFG_INPSEL(Sre, Dse, Speed, Ode, Pke, Pue, Pus, Hys, Sion, MuxAlt, SelInpReg, SelInpValue) \
+          (_IMX_MAKE_PAD_CTL(Sre, Dse, Speed, Ode, Pke, Pue, Pus, Hys) | \
+           (_IMX_MAKE_MUX_CTL(Sion, MuxAlt) << 17) | \
+           (_IMX_MAKE_INP_SEL(SelInpReg, SelInpValue) << 22))
+
+#define _IMX_MAKE_PADCFG(Sre, Dse, Speed, Ode, Pke, Pue, Pus, Hys, Sion, MuxAlt) \
+          (_IMX_MAKE_PAD_CTL(Sre, Dse, Speed, Ode, Pke, Pue, Pus, Hys) | \
+           _IMX_MAKE_MUX_CTL(Sion, MuxAlt) << 17)
+
+#define _IMX_MAKE_PADCFG2(PadCtl, Sion, MuxAlt) \
+          ((PadCtl) | \
+           _IMX_MAKE_MUX_CTL(Sion, MuxAlt) << 17)
+
+#define _IMX_PADCFG_PAD_CTL(PadCfg) ((PadCfg) & 0x0001F8F9)
+#define _IMX_PADCFG_MUX_CTL(PadCfg) (((PadCfg) >> 17) & 0x00000017)
+#define _IMX_PADCFG_SEL_INP(PadCfg) (((PadCfg) >> 22) & 0x000007FF)
+
+/**
+  Put a pad in the specified configuration.
+
+  For example, to configure GPIO0 as CCM_CLK01 output:
+    ImxPadConfig (IMX_PAD_GPIO_0, IMX_PAD_GPIO_0_CCM_CLKO1);
+
+**/
+VOID ImxPadConfig (IMX_PAD Pad, IMX_PADCFG PadConfig);
+
+/**
+  Dumps to console the specified PAD mux/control configuration.
+**/
+VOID ImxPadDumpConfig (char *PadName, IMX_PAD Pad);
+
+#endif // _IMX6_IOMUX_H_
diff --git a/Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_DQ.h b/Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_DQ.h
new file mode 100644
index 000000000000..33b79926fbba
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_DQ.h
@@ -0,0 +1,2464 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _IMX6_IOMUX_DQ_H_
+#define _IMX6_IOMUX_DQ_H_
+
+//
+// SELECT INPUT defines
+
+#define EIM_DATA21_ALT6 0x0 // Selecting ALT6 mode of pad EIM_D21 for I2C1_SCL
+#define CSI0_DAT9_ALT4 0x1 // Selecting ALT4 mode of pad CSI0_DAT9 for I2C1_SCL
+
+#define EIM_DATA28_ALT1 0x0 // Selecting ALT1 mode of pad EIM_D28 for I2C1_SDA
+#define CSI0_DAT8_ALT4 0x1 // Selecting ALT4 mode of pad CSI0_DAT8 for I2C1_SDA
+
+#define EIM_EB2_B_ALT6 0x0 // Selecting ALT6 mode of pad EIM_EB2 for I2C2_SCL
+#define KEY_COL3_ALT4 0x1 // Selecting ALT4 mode of pad KEY_COL3 for I2C2_SCL
+
+#define EIM_DATA16_ALT6 0x0 // Selecting ALT6 mode of pad EIM_D16 for I2C2_SDA
+#define KEY_ROW3_ALT4 0x1 // Selecting ALT4 mode of pad KEY_ROW3 for I2C2_SDA
+
+#define EIM_DATA17_ALT6 0x0 // Selecting ALT6 mode of pad EIM_D17 for I2C3_SCL
+#define GPIO03_ALT2 0x1 // Selecting ALT2 mode of pad GPIO_3 for I2C3_SCL
+#define GPIO05_ALT6 0x2 // Selecting ALT6 mode of pad GPIO_5 for I2C3_SCL
+
+#define EIM_DATA18_ALT6 0x0 // Selecting ALT6 mode of pad EIM_D18 for I2C3_SDA
+#define GPIO06_ALT2 0x1 // Selecting ALT2 mode of pad GPIO_6 for I2C3_SDA
+#define GPIO16_ALT6 0x2 // Selecting ALT6 mode of pad GPIO_16 for I2C3_SDA
+
+#define DISP0_DATA19_ALT3 0
+#define KEY_ROW1_ALT2 1
+
+#define DISP0_DATA17_ALT3 0
+#define KEY_ROW0_ALT2 1
+
+#define DISP0_DATA16_ALT3 0
+#define KEY_COL0_ALT2 1
+
+#define DISP0_DATA18_ALT3 0
+#define KEY_COL1_ALT2 1
+
+#define EIM_DATA21_ALT4 0
+#define KEY_COL4_ALT2 1
+
+#define EIM_DATA30_ALT6 0
+#define GPIO03_ALT6 1
+
+#define RGMII_TX_CTL_ALT7 0
+#define GPIO16_ALT2 1
+
+#define CSI0_DATA10_ALT3 0 // Selecting ALT3 mode of pad CSI0_DAT10 for UART1_TX_DATA.
+#define CSI0_DATA11_ALT3 1 // Selecting ALT3 mode of pad CSI0_DAT11 for UART1_RX_DATA.
+#define SD3_DATA7_ALT1 2 // Selecting ALT1 mode of pad SD3_DAT7 for UART1_TX_DATA.
+#define SD3_DATA6_ALT1 3 // Selecting ALT1 mode of pad SD3_DAT6 for UART1_RX_DATA.
+
+#define EIM_DATA26_ALT4 0 // Selecting ALT4 mode of pad EIM_D26 for UART2_TX_DATA.
+#define EIM_DATA27_ALT4 1 // Selecting ALT4 mode of pad EIM_D27 for UART2_RX_DATA.
+#define GPIO07_ALT4 2 // Selecting ALT4 mode of pad GPIO_7 for UART2_TX_DATA.
+#define GPIO08_ALT4 3 // Selecting ALT4 mode of pad GPIO_8 for UART2_RX_DATA.
+#define SD3_DATA5_ALT1 4 // Selecting ALT1 mode of pad SD3_DAT5 for UART2_TX_DATA.
+#define SD3_DATA4_ALT1 5 // Selecting ALT1 mode of pad SD3_DAT4 for UART2_RX_DATA.
+#define SD4_DATA4_ALT2 6 // Selecting ALT2 mode of pad SD4_DAT4 for UART2_RX_DATA.
+#define SD4_DATA7_ALT2 7 // Selecting ALT2 mode of pad SD4_DAT7 for UART2_TX_DATA.
+
+#define EIM_DATA24_ALT2 0 // Selecting ALT2 mode of pad EIM_D24 for UART3_TX_DATA.
+#define EIM_DATA25_ALT2 1 // Selecting ALT2 mode of pad EIM_D25 for UART3_RX_DATA.
+#define SD4_CMD_ALT2 2 // Selecting ALT2 mode of pad SD4_CMD for UART3_TX_DATA.
+#define SD4_CLK_ALT2 3 // Selecting ALT2 mode of pad SD4_CLK for UART3_RX_DATA.
+
+
+//
+// AUD5 select input register defines.
+//
+typedef enum {
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO00)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO00)
+   IMX_PAD_GPIO_0 = _IMX_PAD(0x5F0, 0x220), // CCM_CLKO1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO01)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO01)
+   IMX_PAD_GPIO_1 = _IMX_PAD(0x5F4, 0x224), // ESAI_RX_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO02)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO02)
+   IMX_PAD_GPIO_2 = _IMX_PAD(0x604, 0x234), // ESAI_TX_FS
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO03)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO03)
+   IMX_PAD_GPIO_3 = _IMX_PAD(0x5FC, 0x22C), // ESAI_RX_HF_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO04)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO04)
+   IMX_PAD_GPIO_4 = _IMX_PAD(0x608, 0x238), // ESAI_TX_HF_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO05)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO05)
+   IMX_PAD_GPIO_5 = _IMX_PAD(0x60C, 0x23C), // ESAI_TX2_RX3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO06)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO06)
+   IMX_PAD_GPIO_6 = _IMX_PAD(0x600, 0x230), // ESAI_TX_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO07)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO07)
+   IMX_PAD_GPIO_7 = _IMX_PAD(0x610, 0x240), // ESAI_TX4_RX1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO08)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO08)
+   IMX_PAD_GPIO_8 = _IMX_PAD(0x614, 0x244), // ESAI_TX5_RX0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO09)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO09)
+   IMX_PAD_GPIO_9 = _IMX_PAD(0x5F8, 0x228), // ESAI_RX_FS
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_CLK)
+   IMX_PAD_SD2_CLK = _IMX_PAD(0x73C, 0x354), // SD2_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_CMD)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_CMD)
+   IMX_PAD_SD2_CMD = _IMX_PAD(0x740, 0x358), // SD2_CMD
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_DATA3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_DATA3)
+   IMX_PAD_SD2_DAT3 = _IMX_PAD(0x744, 0x35C), // SD2_DATA3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_DATA2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_DATA2)
+   IMX_PAD_SD2_DAT2 = _IMX_PAD(0x364, 0x50), // SD2_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_DATA1)
+   IMX_PAD_SD2_DAT1 = _IMX_PAD(0x360, 0x4C), // SD2_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_DATA0)
+   IMX_PAD_SD2_DAT0 = _IMX_PAD(0x368, 0x54), // SD2_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_DATA0)
+   IMX_PAD_SD1_DAT0 = _IMX_PAD(0x728, 0x340), // SD1_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_DATA1)
+   IMX_PAD_SD1_DAT1 = _IMX_PAD(0x724, 0x33C), // SD1_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_CMD)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_CMD)
+   IMX_PAD_SD1_CMD = _IMX_PAD(0x730, 0x348), // SD1_CMD
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_DATA2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_DATA2)
+   IMX_PAD_SD1_DAT2 = _IMX_PAD(0x734, 0x34C), // SD1_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_CLK)
+   IMX_PAD_SD1_CLK = _IMX_PAD(0x738, 0x350), // SD1_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_DATA3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_DATA3)
+   IMX_PAD_SD1_DAT3 = _IMX_PAD(0x72C, 0x344), // SD1_DATA3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_MDIO)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_MDIO)
+   IMX_PAD_ENET_MDIO = _IMX_PAD(0x4E4, 0x1D0), // ENET_MDIO
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_REF_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_REF_CLK)
+   IMX_PAD_ENET_REF_CLK = _IMX_PAD(0x4E8, 0x1D4), // ENET_TX_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_RX_ER)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_RX_ER)
+   IMX_PAD_ENET_RX_ER = _IMX_PAD(0x4EC, 0x1D8), // USB_OTG_ID
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_CRS_DV)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_CRS_DV)
+   IMX_PAD_ENET_CRS_DV = _IMX_PAD(0x4F0, 0x1DC), // ENET_RX_EN
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_RX_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_RX_DATA1)
+   IMX_PAD_ENET_RXD1 = _IMX_PAD(0x4F4, 0x1E0), // MLB_SIG
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_RX_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_RX_DATA0)
+   IMX_PAD_ENET_RXD0 = _IMX_PAD(0x4F8, 0x1E4), // XTALOSC_OSC32K_32K_OUT
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_TX_EN)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_TX_EN)
+   IMX_PAD_ENET_TX_EN = _IMX_PAD(0x4FC, 0x1E8), // ENET_TX_EN
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_TX_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_TX_DATA1)
+   IMX_PAD_ENET_TXD1 = _IMX_PAD(0x500, 0x1EC), // MLB_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_TX_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_TX_DATA0)
+   IMX_PAD_ENET_TXD0 = _IMX_PAD(0x504, 0x1F0), // ENET_TX_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_MDC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_MDC)
+   IMX_PAD_ENET_MDC = _IMX_PAD(0x508, 0x1F4), // MLB_DATA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA00)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA00)
+   IMX_PAD_NANDF_D0 = _IMX_PAD(0x6E4, 0x2FC), // NAND_DATA00
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA01)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA01)
+   IMX_PAD_NANDF_D1 = _IMX_PAD(0x6E8, 0x300), // NAND_DATA01
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA02)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA02)
+   IMX_PAD_NANDF_D2 = _IMX_PAD(0x6EC, 0x304), // NAND_DATA02
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA03)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA03)
+   IMX_PAD_NANDF_D3 = _IMX_PAD(0x6F0, 0x308), // NAND_DATA03
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA04)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA04)
+   IMX_PAD_NANDF_D4 = _IMX_PAD(0x6F4, 0x30C), // NAND_DATA04
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA05)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA05)
+   IMX_PAD_NANDF_D5 = _IMX_PAD(0x6F8, 0x310), // NAND_DATA05
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA06)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA06)
+   IMX_PAD_NANDF_D6 = _IMX_PAD(0x6FC, 0x314), // NAND_DATA06
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA07)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA07)
+   IMX_PAD_NANDF_D7 = _IMX_PAD(0x700, 0x318), // NAND_DATA07
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA0)
+   IMX_PAD_SD4_DAT0 = _IMX_PAD(0x704, 0x31C), // SD4_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA1)
+   IMX_PAD_SD4_DAT1 = _IMX_PAD(0x708, 0x320), // SD4_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA2)
+   IMX_PAD_SD4_DAT2 = _IMX_PAD(0x70C, 0x324), // SD4_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA3)
+   IMX_PAD_SD4_DAT3 = _IMX_PAD(0x710, 0x328), // SD4_DATA3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA4)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA4)
+   IMX_PAD_SD4_DAT4 = _IMX_PAD(0x714, 0x32C), // SD4_DATA4
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA5)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA5)
+   IMX_PAD_SD4_DAT5 = _IMX_PAD(0x718, 0x330), // SD4_DATA5
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA6)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA6)
+   IMX_PAD_SD4_DAT6 = _IMX_PAD(0x71C, 0x334), // SD4_DATA6
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA7)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA7)
+   IMX_PAD_SD4_DAT7 = _IMX_PAD(0x720, 0x338), // SD4_DATA7
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR22)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR22)
+   IMX_PAD_EIM_A22 = _IMX_PAD(0x3F0, 0xDC), // EIM_ADDR22
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR21)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR21)
+   IMX_PAD_EIM_A21 = _IMX_PAD(0x3F4, 0xE0), // EIM_ADDR21
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR20)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR20)
+   IMX_PAD_EIM_A20 = _IMX_PAD(0x3F8, 0xE4), // EIM_ADDR20
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR19)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR19)
+   IMX_PAD_EIM_A19 = _IMX_PAD(0x3FC, 0xE8), // EIM_ADDR19
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR18)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR18)
+   IMX_PAD_EIM_A18 = _IMX_PAD(0x400, 0xEC), // EIM_ADDR18
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR17)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR17)
+   IMX_PAD_EIM_A17 = _IMX_PAD(0x404, 0xF0), // EIM_ADDR17
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR16)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR16)
+   IMX_PAD_EIM_A16 = _IMX_PAD(0x408, 0xF4), // EIM_ADDR16
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_CS0_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_CS0_B)
+   IMX_PAD_EIM_CS0 = _IMX_PAD(0x40C, 0xF8), // EIM_CS0_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_CS1_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_CS1_B)
+   IMX_PAD_EIM_CS1 = _IMX_PAD(0x410, 0xFC), // EIM_CS1_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_OE_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_OE_B)
+   IMX_PAD_EIM_OE = _IMX_PAD(0x414, 0x100), // EIM_OE_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_RW)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_RW)
+   IMX_PAD_EIM_RW = _IMX_PAD(0x418, 0x104), // EIM_RW
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_LBA_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_LBA_B)
+   IMX_PAD_EIM_LBA = _IMX_PAD(0x41C, 0x108), // EIM_LBA_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_EB0_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_EB0_B)
+   IMX_PAD_EIM_EB0 = _IMX_PAD(0x420, 0x10C), // EIM_EB0_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_EB1_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_EB1_B)
+   IMX_PAD_EIM_EB1 = _IMX_PAD(0x424, 0x110), // EIM_EB1_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_EB2_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_EB2_B)
+   IMX_PAD_EIM_EB2 = _IMX_PAD(0x3A0, 0x8C), // EIM_EB2_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_EB3_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_EB3_B)
+   IMX_PAD_EIM_EB3 = _IMX_PAD(0x3C4, 0xB0), // EIM_EB3_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD00)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD00)
+   IMX_PAD_EIM_DA0 = _IMX_PAD(0x428, 0x114), // EIM_AD00
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD01)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD01)
+   IMX_PAD_EIM_DA1 = _IMX_PAD(0x42C, 0x118), // EIM_AD01
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD02)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD02)
+   IMX_PAD_EIM_DA2 = _IMX_PAD(0x430, 0x11C), // EIM_AD02
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD03)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD03)
+   IMX_PAD_EIM_DA3 = _IMX_PAD(0x434, 0x120), // EIM_AD03
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD04)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD04)
+   IMX_PAD_EIM_DA4 = _IMX_PAD(0x438, 0x124), // EIM_AD04
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD05)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD05)
+   IMX_PAD_EIM_DA5 = _IMX_PAD(0x43C, 0x128), // EIM_AD05
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD06)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD06)
+   IMX_PAD_EIM_DA6 = _IMX_PAD(0x440, 0x12C), // EIM_AD06
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD07)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD07)
+   IMX_PAD_EIM_DA7 = _IMX_PAD(0x444, 0x130), // EIM_AD07
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD08)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD08)
+   IMX_PAD_EIM_DA8 = _IMX_PAD(0x448, 0x134), // EIM_AD08
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD09)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD09)
+   IMX_PAD_EIM_DA9 = _IMX_PAD(0x44C, 0x138), // EIM_AD09
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD10)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD10)
+   IMX_PAD_EIM_DA10 = _IMX_PAD(0x450, 0x13C), // EIM_AD10
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD11)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD11)
+   IMX_PAD_EIM_DA11 = _IMX_PAD(0x454, 0x140), // EIM_AD11
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD12)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD12)
+   IMX_PAD_EIM_DA12 = _IMX_PAD(0x458, 0x144), // EIM_AD12
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD13)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD13)
+   IMX_PAD_EIM_DA13 = _IMX_PAD(0x45C, 0x148), // EIM_AD13
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD14)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD14)
+   IMX_PAD_EIM_DA14 = _IMX_PAD(0x460, 0x14C), // EIM_AD14
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD15)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD15)
+   IMX_PAD_EIM_DA15 = _IMX_PAD(0x464, 0x150), // EIM_AD15
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA16)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA16)
+   IMX_PAD_EIM_D16 = _IMX_PAD(0x3A4, 0x90), // EIM_DATA16
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA17)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA17)
+   IMX_PAD_EIM_D17 = _IMX_PAD(0x3A8, 0x94), // EIM_DATA17
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA18)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA18)
+   IMX_PAD_EIM_D18 = _IMX_PAD(0x3AC, 0x98), // EIM_DATA18
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA19)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA19)
+   IMX_PAD_EIM_D19 = _IMX_PAD(0x3B0, 0x9C), // EIM_DATA19
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA20)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA20)
+   IMX_PAD_EIM_D20 = _IMX_PAD(0x3B4, 0xA0), // EIM_DATA20
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA21)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA21)
+   IMX_PAD_EIM_D21 = _IMX_PAD(0x3B8, 0xA4), // EIM_DATA21
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA22)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA22)
+   IMX_PAD_EIM_D22 = _IMX_PAD(0x3BC, 0xA8), // EIM_DATA22
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA23)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA23)
+   IMX_PAD_EIM_D23 = _IMX_PAD(0x3C0, 0xAC), // EIM_DATA23
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA24)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA24)
+   IMX_PAD_EIM_D24 = _IMX_PAD(0x3C8, 0xB4), // EIM_DATA24
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA25)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA25)
+   IMX_PAD_EIM_D25 = _IMX_PAD(0x3CC, 0xB8), // EIM_DATA25
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA26)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA26)
+   IMX_PAD_EIM_D26 = _IMX_PAD(0x3D0, 0xBC), // EIM_DATA26
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA27)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA27)
+   IMX_PAD_EIM_D27 = _IMX_PAD(0x3D4, 0xC0), // EIM_DATA27
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA28)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA28)
+   IMX_PAD_EIM_D28 = _IMX_PAD(0x3D8, 0xC4), // EIM_DATA28
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA29)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA29)
+   IMX_PAD_EIM_D29 = _IMX_PAD(0x3DC, 0xC8), // EIM_DATA29
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA30)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA30)
+   IMX_PAD_EIM_D30 = _IMX_PAD(0x3E0, 0xCC), // EIM_DATA30
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA31)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA31)
+   IMX_PAD_EIM_D31 = _IMX_PAD(0x3E4, 0xD0), // EIM_DATA31
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO19)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO19)
+   IMX_PAD_GPIO_19 = _IMX_PAD(0x624, 0x254), // KEY_COL5
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_COL0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_COL0)
+   IMX_PAD_KEY_COL0 = _IMX_PAD(0x5C8, 0x1F8), // ECSPI1_SCLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_ROW0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_ROW0)
+   IMX_PAD_KEY_ROW0 = _IMX_PAD(0x5CC, 0x1FC), // ECSPI1_MOSI
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_COL1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_COL1)
+   IMX_PAD_KEY_COL1 = _IMX_PAD(0x5D0, 0x200), // ECSPI1_MISO
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_ROW1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_ROW1)
+   IMX_PAD_KEY_ROW1 = _IMX_PAD(0x5D4, 0x204), // ECSPI1_SS0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_COL2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_COL2)
+   IMX_PAD_KEY_COL2 = _IMX_PAD(0x5D8, 0x208), // ECSPI1_SS1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_ROW2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_ROW2)
+   IMX_PAD_KEY_ROW2 = _IMX_PAD(0x5DC, 0x20C), // ECSPI1_SS2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_COL3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_COL3)
+   IMX_PAD_KEY_COL3 = _IMX_PAD(0x5E0, 0x210), // ECSPI1_SS3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_ROW3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_ROW3)
+   IMX_PAD_KEY_ROW3 = _IMX_PAD(0x5E4, 0x214), // XTALOSC_OSC32K_32K_OUT
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_COL4)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_COL4)
+   IMX_PAD_KEY_COL4 = _IMX_PAD(0x5E8, 0x218), // FLEXCAN2_TX
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_ROW4)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_ROW4)
+   IMX_PAD_KEY_ROW4 = _IMX_PAD(0x5EC, 0x21C), // FLEXCAN2_RX
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DI0_DISP_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DI0_DISP_CLK)
+   IMX_PAD_DI0_DISP_CLK = _IMX_PAD(0x470, 0x15C), // IPU1_DI0_DISP_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DI0_PIN15)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DI0_PIN15)
+   IMX_PAD_DI0_PIN15 = _IMX_PAD(0x474, 0x160), // IPU1_DI0_PIN15
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DI0_PIN02)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DI0_PIN02)
+   IMX_PAD_DI0_PIN2 = _IMX_PAD(0x478, 0x164), // IPU1_DI0_PIN02
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DI0_PIN03)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DI0_PIN03)
+   IMX_PAD_DI0_PIN3 = _IMX_PAD(0x47C, 0x168), // IPU1_DI0_PIN03
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DI0_PIN04)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DI0_PIN04)
+   IMX_PAD_DI0_PIN4 = _IMX_PAD(0x480, 0x16C), // IPU1_DI0_PIN04
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA00)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA00)
+   IMX_PAD_DISP0_DAT0 = _IMX_PAD(0x484, 0x170), // IPU1_DISP0_DATA00
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA01)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA01)
+   IMX_PAD_DISP0_DAT1 = _IMX_PAD(0x488, 0x174), // IPU1_DISP0_DATA01
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA02)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA02)
+   IMX_PAD_DISP0_DAT2 = _IMX_PAD(0x48C, 0x178), // IPU1_DISP0_DATA02
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA03)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA03)
+   IMX_PAD_DISP0_DAT3 = _IMX_PAD(0x490, 0x17C), // IPU1_DISP0_DATA03
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA04)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA04)
+   IMX_PAD_DISP0_DAT4 = _IMX_PAD(0x494, 0x180), // IPU1_DISP0_DATA04
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA05)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA05)
+   IMX_PAD_DISP0_DAT5 = _IMX_PAD(0x498, 0x184), // IPU1_DISP0_DATA05
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA06)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA06)
+   IMX_PAD_DISP0_DAT6 = _IMX_PAD(0x49C, 0x188), // IPU1_DISP0_DATA06
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA07)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA07)
+   IMX_PAD_DISP0_DAT7 = _IMX_PAD(0x4A0, 0x18C), // IPU1_DISP0_DATA07
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA08)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA08)
+   IMX_PAD_DISP0_DAT8 = _IMX_PAD(0x4A4, 0x190), // IPU1_DISP0_DATA08
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA09)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA09)
+   IMX_PAD_DISP0_DAT9 = _IMX_PAD(0x4A8, 0x194), // IPU1_DISP0_DATA09
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA10)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA10)
+   IMX_PAD_DISP0_DAT10 = _IMX_PAD(0x4AC, 0x198), // IPU1_DISP0_DATA10
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT_B)
+   IMX_PAD_EIM_WAIT = _IMX_PAD(0x468, 0x154), // EIM_WAIT_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR25)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR25)
+   IMX_PAD_EIM_A25 = _IMX_PAD(0x39C, 0x88), // EIM_ADDR25
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR24)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR24)
+   IMX_PAD_EIM_A24 = _IMX_PAD(0x3E8, 0xD4), // EIM_ADDR24
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA11)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA11)
+   IMX_PAD_DISP0_DAT11 = _IMX_PAD(0x4B0, 0x19C), // IPU1_DISP0_DATA11
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA12)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA12)
+   IMX_PAD_DISP0_DAT12 = _IMX_PAD(0x4B4, 0x1A0), // IPU1_DISP0_DATA12
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA13)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA13)
+   IMX_PAD_DISP0_DAT13 = _IMX_PAD(0x4B8, 0x1A4), // IPU1_DISP0_DATA13
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA14)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA14)
+   IMX_PAD_DISP0_DAT14 = _IMX_PAD(0x4BC, 0x1A8), // IPU1_DISP0_DATA14
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA15)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA15)
+   IMX_PAD_DISP0_DAT15 = _IMX_PAD(0x4C0, 0x1AC), // IPU1_DISP0_DATA15
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA16)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA16)
+   IMX_PAD_DISP0_DAT16 = _IMX_PAD(0x4C4, 0x1B0), // IPU1_DISP0_DATA16
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA17)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA17)
+   IMX_PAD_DISP0_DAT17 = _IMX_PAD(0x4C8, 0x1B4), // IPU1_DISP0_DATA17
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA18)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA18)
+   IMX_PAD_DISP0_DAT18 = _IMX_PAD(0x4CC, 0x1B8), // IPU1_DISP0_DATA18
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA19)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA19)
+   IMX_PAD_DISP0_DAT19 = _IMX_PAD(0x4D0, 0x1BC), // IPU1_DISP0_DATA19
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA20)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA20)
+   IMX_PAD_DISP0_DAT20 = _IMX_PAD(0x4D4, 0x1C0), // IPU1_DISP0_DATA20
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA21)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA21)
+   IMX_PAD_DISP0_DAT21 = _IMX_PAD(0x4D8, 0x1C4), // IPU1_DISP0_DATA21
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA22)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA22)
+   IMX_PAD_DISP0_DAT22 = _IMX_PAD(0x4DC, 0x1C8), // IPU1_DISP0_DATA22
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA23)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA23)
+   IMX_PAD_DISP0_DAT23 = _IMX_PAD(0x4E0, 0x1CC), // IPU1_DISP0_DATA23
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_PIXCLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_PIXCLK)
+   IMX_PAD_CSI0_PIXCLK = _IMX_PAD(0x628, 0x258), // IPU1_CSI0_PIXCLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_HSYNC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_HSYNC)
+   IMX_PAD_CSI0_MCLK = _IMX_PAD(0x62C, 0x25C), // IPU1_CSI0_HSYNC
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA_EN)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA_EN)
+   IMX_PAD_CSI0_DATA_EN = _IMX_PAD(0x630, 0x260), // IPU1_CSI0_DATA_EN
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_VSYNC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_VSYNC)
+   IMX_PAD_CSI0_VSYNC = _IMX_PAD(0x634, 0x264), // IPU1_CSI0_VSYNC
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA04)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA04)
+   IMX_PAD_CSI0_DAT4 = _IMX_PAD(0x638, 0x268), // IPU1_CSI0_DATA04
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA05)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA05)
+   IMX_PAD_CSI0_DAT5 = _IMX_PAD(0x63C, 0x26C), // IPU1_CSI0_DATA05
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA06)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA06)
+   IMX_PAD_CSI0_DAT6 = _IMX_PAD(0x640, 0x270), // IPU1_CSI0_DATA06
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA07)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA07)
+   IMX_PAD_CSI0_DAT7 = _IMX_PAD(0x644, 0x274), // IPU1_CSI0_DATA07
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA08)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA08)
+   IMX_PAD_CSI0_DAT8 = _IMX_PAD(0x648, 0x278), // IPU1_CSI0_DATA08
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA09)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA09)
+   IMX_PAD_CSI0_DAT9 = _IMX_PAD(0x64C, 0x27C), // IPU1_CSI0_DATA09
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA10)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA10)
+   IMX_PAD_CSI0_DAT10 = _IMX_PAD(0x650, 0x280), // IPU1_CSI0_DATA10
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA11)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA11)
+   IMX_PAD_CSI0_DAT11 = _IMX_PAD(0x654, 0x284), // IPU1_CSI0_DATA11
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA12)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA12)
+   IMX_PAD_CSI0_DAT12 = _IMX_PAD(0x658, 0x288), // IPU1_CSI0_DATA12
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA13)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA13)
+   IMX_PAD_CSI0_DAT13 = _IMX_PAD(0x65C, 0x28C), // IPU1_CSI0_DATA13
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA14)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA14)
+   IMX_PAD_CSI0_DAT14 = _IMX_PAD(0x660, 0x290), // IPU1_CSI0_DATA14
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA15)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA15)
+   IMX_PAD_CSI0_DAT15 = _IMX_PAD(0x664, 0x294), // IPU1_CSI0_DATA15
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA16)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA16)
+   IMX_PAD_CSI0_DAT16 = _IMX_PAD(0x668, 0x298), // IPU1_CSI0_DATA16
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA17)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA17)
+   IMX_PAD_CSI0_DAT17 = _IMX_PAD(0x66C, 0x29C), // IPU1_CSI0_DATA17
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA18)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA18)
+   IMX_PAD_CSI0_DAT18 = _IMX_PAD(0x670, 0x2A0), // IPU1_CSI0_DATA18
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA19)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA19)
+   IMX_PAD_CSI0_DAT19 = _IMX_PAD(0x674, 0x2A4), // IPU1_CSI0_DATA19
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR23)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR23)
+   IMX_PAD_EIM_A23 = _IMX_PAD(0x3EC, 0xD8), // EIM_ADDR23
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_CLE)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_CLE)
+   IMX_PAD_NANDF_CLE = _IMX_PAD(0x6BC, 0x2D4), // NAND_CLE
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_ALE)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_ALE)
+   IMX_PAD_NANDF_ALE = _IMX_PAD(0x6C0, 0x2D8), // NAND_ALE
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_WP_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_WP_B)
+   IMX_PAD_NANDF_WP_B = _IMX_PAD(0x6C4, 0x2DC), // NAND_WP_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_READY_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_READY_B)
+   IMX_PAD_NANDF_RB0 = _IMX_PAD(0x6C8, 0x2E0), // NAND_READY_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_CS0_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_CS0_B)
+   IMX_PAD_NANDF_CS0 = _IMX_PAD(0x6CC, 0x2E4), // NAND_CE0_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_CS1_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_CS1_B)
+   IMX_PAD_NANDF_CS1 = _IMX_PAD(0x6D0, 0x2E8), // NAND_CE1_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_CS2_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_CS2_B)
+   IMX_PAD_NANDF_CS2 = _IMX_PAD(0x6D4, 0x2EC), // NAND_CE2_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_CS3_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_CS3_B)
+   IMX_PAD_NANDF_CS3 = _IMX_PAD(0x6D8, 0x2F0), // NAND_CE3_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA7)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA7)
+   IMX_PAD_SD3_DAT7 = _IMX_PAD(0x690, 0x2A8), // SD3_DATA7
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA6)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA6)
+   IMX_PAD_SD3_DAT6 = _IMX_PAD(0x694, 0x2AC), // SD3_DATA6
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_TXC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_TXC)
+   IMX_PAD_RGMII_TXC = _IMX_PAD(0x36C, 0x58), // USB_H2_DATA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_TD0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_TD0)
+   IMX_PAD_RGMII_TD0 = _IMX_PAD(0x370, 0x5C), // HSI_TX_READY
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_TD1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_TD1)
+   IMX_PAD_RGMII_TD1 = _IMX_PAD(0x374, 0x60), // HSI_RX_FLAG
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_TD2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_TD2)
+   IMX_PAD_RGMII_TD2 = _IMX_PAD(0x378, 0x64), // HSI_RX_DATA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_TD3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_TD3)
+   IMX_PAD_RGMII_TD3 = _IMX_PAD(0x37C, 0x68), // HSI_RX_WAKE
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_RX_CTL)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_RX_CTL)
+   IMX_PAD_RGMII_RX_CTL = _IMX_PAD(0x380, 0x6C), // USB_H3_DATA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_RD0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_RD0)
+   IMX_PAD_RGMII_RD0 = _IMX_PAD(0x384, 0x70), // HSI_RX_READY
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_TX_CTL)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_TX_CTL)
+   IMX_PAD_RGMII_TX_CTL = _IMX_PAD(0x388, 0x74), // USB_H2_STROBE
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_RD1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_RD1)
+   IMX_PAD_RGMII_RD1 = _IMX_PAD(0x38C, 0x78), // HSI_TX_FLAG
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_RD2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_RD2)
+   IMX_PAD_RGMII_RD2 = _IMX_PAD(0x390, 0x7C), // HSI_TX_DATA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_RD3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_RD3)
+   IMX_PAD_RGMII_RD3 = _IMX_PAD(0x394, 0x80), // HSI_TX_WAKE
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_RXC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_RXC)
+   IMX_PAD_RGMII_RXC = _IMX_PAD(0x398, 0x84), // USB_H3_STROBE
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK)
+   IMX_PAD_EIM_BCLK = _IMX_PAD(0x46C, 0x158), // EIM_BCLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA5)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA5)
+   IMX_PAD_SD3_DAT5 = _IMX_PAD(0x698, 0x2B0), // SD3_DATA5
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA4)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA4)
+   IMX_PAD_SD3_DAT4 = _IMX_PAD(0x69C, 0x2B4), // SD3_DATA4
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_CMD)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_CMD)
+   IMX_PAD_SD3_CMD = _IMX_PAD(0x6A0, 0x2B8), // SD3_CMD
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_CLK)
+   IMX_PAD_SD3_CLK = _IMX_PAD(0x6A4, 0x2BC), // SD3_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA0)
+   IMX_PAD_SD3_DAT0 = _IMX_PAD(0x6A8, 0x2C0), // SD3_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA1)
+   IMX_PAD_SD3_DAT1 = _IMX_PAD(0x6AC, 0x2C4), // SD3_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA2)
+   IMX_PAD_SD3_DAT2 = _IMX_PAD(0x6B0, 0x2C8), // SD3_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA3)
+   IMX_PAD_SD3_DAT3 = _IMX_PAD(0x6B4, 0x2CC), // SD3_DATA3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_RESET)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_RESET)
+   IMX_PAD_SD3_RST = _IMX_PAD(0x6B8, 0x2D0), // SD3_RESET
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_CMD)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_CMD)
+   IMX_PAD_SD4_CMD = _IMX_PAD(0x6DC, 0x2F4), // SD4_CMD
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_CLK)
+   IMX_PAD_SD4_CLK = _IMX_PAD(0x6E0, 0x2F8), // SD4_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO16)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO16)
+   IMX_PAD_GPIO_16 = _IMX_PAD(0x618, 0x248), // ESAI_TX3_RX2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO17)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO17)
+   IMX_PAD_GPIO_17 = _IMX_PAD(0x61C, 0x24C), // ESAI_TX0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO18)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO18)
+   IMX_PAD_GPIO_18 = _IMX_PAD(0x620, 0x250), // ESAI_TX1
+} IMX_PAD;
+
+//
+// Alternate function numbers
+//
+
+typedef enum {
+   IMX_IOMUXC_GPIO_0_ALT0_CCM_CLKO1 = 0,
+   IMX_IOMUXC_GPIO_0_ALT2_KEY_COL5 = 2,
+   IMX_IOMUXC_GPIO_0_ALT3_ASRC_EXT_CLK = 3,
+   IMX_IOMUXC_GPIO_0_ALT4_EPIT1_OUT = 4,
+   IMX_IOMUXC_GPIO_0_ALT5_GPIO1_IO00 = 5,
+   IMX_IOMUXC_GPIO_0_ALT6_USB_H1_PWR = 6,
+   IMX_IOMUXC_GPIO_0_ALT7_SNVS_VIO_5 = 7,
+} IMX_IOMUXC_GPIO_0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_1_ALT0_ESAI_RX_CLK = 0,
+   IMX_IOMUXC_GPIO_1_ALT1_WDOG2_B = 1,
+   IMX_IOMUXC_GPIO_1_ALT2_KEY_ROW5 = 2,
+   IMX_IOMUXC_GPIO_1_ALT3_USB_OTG_ID = 3,
+   IMX_IOMUXC_GPIO_1_ALT4_PWM2_OUT = 4,
+   IMX_IOMUXC_GPIO_1_ALT5_GPIO1_IO01 = 5,
+   IMX_IOMUXC_GPIO_1_ALT6_SD1_CD_B = 6,
+} IMX_IOMUXC_GPIO_1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_2_ALT0_ESAI_TX_FS = 0,
+   IMX_IOMUXC_GPIO_2_ALT2_KEY_ROW6 = 2,
+   IMX_IOMUXC_GPIO_2_ALT5_GPIO1_IO02 = 5,
+   IMX_IOMUXC_GPIO_2_ALT6_SD2_WP = 6,
+   IMX_IOMUXC_GPIO_2_ALT7_MLB_DATA = 7,
+} IMX_IOMUXC_GPIO_2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_3_ALT0_ESAI_RX_HF_CLK = 0,
+   IMX_IOMUXC_GPIO_3_ALT2_I2C3_SCL = 2,
+   IMX_IOMUXC_GPIO_3_ALT3_XTALOSC_REF_CLK_24M = 3,
+   IMX_IOMUXC_GPIO_3_ALT4_CCM_CLKO2 = 4,
+   IMX_IOMUXC_GPIO_3_ALT5_GPIO1_IO03 = 5,
+   IMX_IOMUXC_GPIO_3_ALT6_USB_H1_OC = 6,
+   IMX_IOMUXC_GPIO_3_ALT7_MLB_CLK = 7,
+} IMX_IOMUXC_GPIO_3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_4_ALT0_ESAI_TX_HF_CLK = 0,
+   IMX_IOMUXC_GPIO_4_ALT2_KEY_COL7 = 2,
+   IMX_IOMUXC_GPIO_4_ALT5_GPIO1_IO04 = 5,
+   IMX_IOMUXC_GPIO_4_ALT6_SD2_CD_B = 6,
+} IMX_IOMUXC_GPIO_4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_5_ALT0_ESAI_TX2_RX3 = 0,
+   IMX_IOMUXC_GPIO_5_ALT2_KEY_ROW7 = 2,
+   IMX_IOMUXC_GPIO_5_ALT3_CCM_CLKO1 = 3,
+   IMX_IOMUXC_GPIO_5_ALT5_GPIO1_IO05 = 5,
+   IMX_IOMUXC_GPIO_5_ALT6_I2C3_SCL = 6,
+   IMX_IOMUXC_GPIO_5_ALT7_ARM_EVENTI = 7,
+} IMX_IOMUXC_GPIO_5_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_6_ALT0_ESAI_TX_CLK = 0,
+   IMX_IOMUXC_GPIO_6_ALT1 = 1,
+   IMX_IOMUXC_GPIO_6_ALT2_I2C3_SDA = 2,
+   IMX_IOMUXC_GPIO_6_ALT5_GPIO1_IO06 = 5,
+   IMX_IOMUXC_GPIO_6_ALT6_SD2_LCTL = 6,
+   IMX_IOMUXC_GPIO_6_ALT7_MLB_SIG = 7,
+} IMX_IOMUXC_GPIO_6_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_7_ALT0_ESAI_TX4_RX1 = 0,
+   IMX_IOMUXC_GPIO_7_ALT1_ECSPI5_RDY = 1,
+   IMX_IOMUXC_GPIO_7_ALT2_EPIT1_OUT = 2,
+   IMX_IOMUXC_GPIO_7_ALT3_FLEXCAN1_TX = 3,
+   IMX_IOMUXC_GPIO_7_ALT4_UART2_TX_DATA = 4,
+   IMX_IOMUXC_GPIO_7_ALT5_GPIO1_IO07 = 5,
+   IMX_IOMUXC_GPIO_7_ALT6_SPDIF_LOCK = 6,
+   IMX_IOMUXC_GPIO_7_ALT7_USB_OTG_HOST_MODE = 7,
+} IMX_IOMUXC_GPIO_7_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_8_ALT0_ESAI_TX5_RX0 = 0,
+   IMX_IOMUXC_GPIO_8_ALT1_XTALOSC_REF_CLK_32K = 1,
+   IMX_IOMUXC_GPIO_8_ALT2_EPIT2_OUT = 2,
+   IMX_IOMUXC_GPIO_8_ALT3_FLEXCAN1_RX = 3,
+   IMX_IOMUXC_GPIO_8_ALT4_UART2_RX_DATA = 4,
+   IMX_IOMUXC_GPIO_8_ALT5_GPIO1_IO08 = 5,
+   IMX_IOMUXC_GPIO_8_ALT6_SPDIF_SR_CLK = 6,
+   IMX_IOMUXC_GPIO_8_ALT7_USB_OTG_PWR_CTL_WAKE = 7,
+} IMX_IOMUXC_GPIO_8_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_9_ALT0_ESAI_RX_FS = 0,
+   IMX_IOMUXC_GPIO_9_ALT1_WDOG1_B = 1,
+   IMX_IOMUXC_GPIO_9_ALT2_KEY_COL6 = 2,
+   IMX_IOMUXC_GPIO_9_ALT3_CCM_REF_EN_B = 3,
+   IMX_IOMUXC_GPIO_9_ALT4_PWM1_OUT = 4,
+   IMX_IOMUXC_GPIO_9_ALT5_GPIO1_IO09 = 5,
+   IMX_IOMUXC_GPIO_9_ALT6_SD1_WP = 6,
+} IMX_IOMUXC_GPIO_9_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_CLK_ALT0_SD2_CLK = 0,
+   IMX_IOMUXC_SD2_CLK_ALT1_ECSPI5_SCLK = 1,
+   IMX_IOMUXC_SD2_CLK_ALT2_KEY_COL5 = 2,
+   IMX_IOMUXC_SD2_CLK_ALT3_AUD4_RXFS = 3,
+   IMX_IOMUXC_SD2_CLK_ALT5_GPIO1_IO10 = 5,
+} IMX_IOMUXC_SD2_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_CMD_ALT0_SD2_CMD = 0,
+   IMX_IOMUXC_SD2_CMD_ALT1_ECSPI5_MOSI = 1,
+   IMX_IOMUXC_SD2_CMD_ALT2_KEY_ROW5 = 2,
+   IMX_IOMUXC_SD2_CMD_ALT3_AUD4_RXC = 3,
+   IMX_IOMUXC_SD2_CMD_ALT5_GPIO1_IO11 = 5,
+} IMX_IOMUXC_SD2_CMD_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_DAT3_ALT0_SD2_DATA3 = 0,
+   IMX_IOMUXC_SD2_DAT3_ALT1_ECSPI5_SS3 = 1,
+   IMX_IOMUXC_SD2_DAT3_ALT2_KEY_COL6 = 2,
+   IMX_IOMUXC_SD2_DAT3_ALT3_AUD4_TXC = 3,
+   IMX_IOMUXC_SD2_DAT3_ALT5_GPIO1_IO12 = 5,
+} IMX_IOMUXC_SD2_DAT3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_DAT2_ALT0_SD2_DATA2 = 0,
+   IMX_IOMUXC_SD2_DAT2_ALT1_ECSPI5_SS1 = 1,
+   IMX_IOMUXC_SD2_DAT2_ALT2_EIM_CS3_B = 2,
+   IMX_IOMUXC_SD2_DAT2_ALT3_AUD4_TXD = 3,
+   IMX_IOMUXC_SD2_DAT2_ALT4_KEY_ROW6 = 4,
+   IMX_IOMUXC_SD2_DAT2_ALT5_GPIO1_IO13 = 5,
+} IMX_IOMUXC_SD2_DAT2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_DAT1_ALT0_SD2_DATA1 = 0,
+   IMX_IOMUXC_SD2_DAT1_ALT1_ECSPI5_SS0 = 1,
+   IMX_IOMUXC_SD2_DAT1_ALT2_EIM_CS2_B = 2,
+   IMX_IOMUXC_SD2_DAT1_ALT3_AUD4_TXFS = 3,
+   IMX_IOMUXC_SD2_DAT1_ALT4_KEY_COL7 = 4,
+   IMX_IOMUXC_SD2_DAT1_ALT5_GPIO1_IO14 = 5,
+} IMX_IOMUXC_SD2_DAT1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_DAT0_ALT0_SD2_DATA0 = 0,
+   IMX_IOMUXC_SD2_DAT0_ALT1_ECSPI5_MISO = 1,
+   IMX_IOMUXC_SD2_DAT0_ALT3_AUD4_RXD = 3,
+   IMX_IOMUXC_SD2_DAT0_ALT4_KEY_ROW7 = 4,
+   IMX_IOMUXC_SD2_DAT0_ALT5_GPIO1_IO15 = 5,
+   IMX_IOMUXC_SD2_DAT0_ALT6_DCIC2_OUT = 6,
+} IMX_IOMUXC_SD2_DAT0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_DAT0_ALT0_SD1_DATA0 = 0,
+   IMX_IOMUXC_SD1_DAT0_ALT1_ECSPI5_MISO = 1,
+   IMX_IOMUXC_SD1_DAT0_ALT3_GPT_CAPTURE1 = 3,
+   IMX_IOMUXC_SD1_DAT0_ALT5_GPIO1_IO16 = 5,
+} IMX_IOMUXC_SD1_DAT0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_DAT1_ALT0_SD1_DATA1 = 0,
+   IMX_IOMUXC_SD1_DAT1_ALT1_ECSPI5_SS0 = 1,
+   IMX_IOMUXC_SD1_DAT1_ALT2_PWM3_OUT = 2,
+   IMX_IOMUXC_SD1_DAT1_ALT3_GPT_CAPTURE2 = 3,
+   IMX_IOMUXC_SD1_DAT1_ALT5_GPIO1_IO17 = 5,
+} IMX_IOMUXC_SD1_DAT1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_CMD_ALT0_SD1_CMD = 0,
+   IMX_IOMUXC_SD1_CMD_ALT1_ECSPI5_MOSI = 1,
+   IMX_IOMUXC_SD1_CMD_ALT2_PWM4_OUT = 2,
+   IMX_IOMUXC_SD1_CMD_ALT3_GPT_COMPARE1 = 3,
+   IMX_IOMUXC_SD1_CMD_ALT5_GPIO1_IO18 = 5,
+} IMX_IOMUXC_SD1_CMD_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_DAT2_ALT0_SD1_DATA2 = 0,
+   IMX_IOMUXC_SD1_DAT2_ALT1_ECSPI5_SS1 = 1,
+   IMX_IOMUXC_SD1_DAT2_ALT2_GPT_COMPARE2 = 2,
+   IMX_IOMUXC_SD1_DAT2_ALT3_PWM2_OUT = 3,
+   IMX_IOMUXC_SD1_DAT2_ALT4_WDOG1_B = 4,
+   IMX_IOMUXC_SD1_DAT2_ALT5_GPIO1_IO19 = 5,
+   IMX_IOMUXC_SD1_DAT2_ALT6_WDOG1_RESET_B_DEB = 6,
+} IMX_IOMUXC_SD1_DAT2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_CLK_ALT0_SD1_CLK = 0,
+   IMX_IOMUXC_SD1_CLK_ALT1_ECSPI5_SCLK = 1,
+   IMX_IOMUXC_SD1_CLK_ALT2_XTALOSC_OSC32K_32K_OUT = 2,
+   IMX_IOMUXC_SD1_CLK_ALT3_GPT_CLKIN = 3,
+   IMX_IOMUXC_SD1_CLK_ALT5_GPIO1_IO20 = 5,
+} IMX_IOMUXC_SD1_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_DAT3_ALT0_SD1_DATA3 = 0,
+   IMX_IOMUXC_SD1_DAT3_ALT1_ECSPI5_SS2 = 1,
+   IMX_IOMUXC_SD1_DAT3_ALT2_GPT_COMPARE3 = 2,
+   IMX_IOMUXC_SD1_DAT3_ALT3_PWM1_OUT = 3,
+   IMX_IOMUXC_SD1_DAT3_ALT4_WDOG2_B = 4,
+   IMX_IOMUXC_SD1_DAT3_ALT5_GPIO1_IO21 = 5,
+   IMX_IOMUXC_SD1_DAT3_ALT6_WDOG2_RESET_B_DEB = 6,
+} IMX_IOMUXC_SD1_DAT3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_MDIO_ALT1_ENET_MDIO = 1,
+   IMX_IOMUXC_ENET_MDIO_ALT2_ESAI_RX_CLK = 2,
+   IMX_IOMUXC_ENET_MDIO_ALT4_ENET_1588_EVENT1_OUT = 4,
+   IMX_IOMUXC_ENET_MDIO_ALT5_GPIO1_IO22 = 5,
+   IMX_IOMUXC_ENET_MDIO_ALT6_SPDIF_LOCK = 6,
+} IMX_IOMUXC_ENET_MDIO_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_REF_CLK_ALT1_ENET_TX_CLK = 1,
+   IMX_IOMUXC_ENET_REF_CLK_ALT2_ESAI_RX_FS = 2,
+   IMX_IOMUXC_ENET_REF_CLK_ALT5_GPIO1_IO23 = 5,
+   IMX_IOMUXC_ENET_REF_CLK_ALT6_SPDIF_SR_CLK = 6,
+} IMX_IOMUXC_ENET_REF_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_RX_ER_ALT0_USB_OTG_ID = 0,
+   IMX_IOMUXC_ENET_RX_ER_ALT1_ENET_RX_ER = 1,
+   IMX_IOMUXC_ENET_RX_ER_ALT2_ESAI_RX_HF_CLK = 2,
+   IMX_IOMUXC_ENET_RX_ER_ALT3_SPDIF_IN = 3,
+   IMX_IOMUXC_ENET_RX_ER_ALT4_ENET_1588_EVENT2_OUT = 4,
+   IMX_IOMUXC_ENET_RX_ER_ALT5_GPIO1_IO24 = 5,
+} IMX_IOMUXC_ENET_RX_ER_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_CRS_DV_ALT1_ENET_RX_EN = 1,
+   IMX_IOMUXC_ENET_CRS_DV_ALT2_ESAI_TX_CLK = 2,
+   IMX_IOMUXC_ENET_CRS_DV_ALT3_SPDIF_EXT_CLK = 3,
+   IMX_IOMUXC_ENET_CRS_DV_ALT5_GPIO1_IO25 = 5,
+} IMX_IOMUXC_ENET_CRS_DV_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_RXD1_ALT0_MLB_SIG = 0,
+   IMX_IOMUXC_ENET_RXD1_ALT1_ENET_RX_DATA1 = 1,
+   IMX_IOMUXC_ENET_RXD1_ALT2_ESAI_TX_FS = 2,
+   IMX_IOMUXC_ENET_RXD1_ALT4_ENET_1588_EVENT3_OUT = 4,
+   IMX_IOMUXC_ENET_RXD1_ALT5_GPIO1_IO26 = 5,
+} IMX_IOMUXC_ENET_RXD1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_RXD0_ALT0_XTALOSC_OSC32K_32K_OUT = 0,
+   IMX_IOMUXC_ENET_RXD0_ALT1_ENET_RX_DATA0 = 1,
+   IMX_IOMUXC_ENET_RXD0_ALT2_ESAI_TX_HF_CLK = 2,
+   IMX_IOMUXC_ENET_RXD0_ALT3_SPDIF_OUT = 3,
+   IMX_IOMUXC_ENET_RXD0_ALT5_GPIO1_IO27 = 5,
+} IMX_IOMUXC_ENET_RXD0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_TX_EN_ALT1_ENET_TX_EN = 1,
+   IMX_IOMUXC_ENET_TX_EN_ALT2_ESAI_TX3_RX2 = 2,
+   IMX_IOMUXC_ENET_TX_EN_ALT5_GPIO1_IO28 = 5,
+} IMX_IOMUXC_ENET_TX_EN_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_TXD1_ALT0_MLB_CLK = 0,
+   IMX_IOMUXC_ENET_TXD1_ALT1_ENET_TX_DATA1 = 1,
+   IMX_IOMUXC_ENET_TXD1_ALT2_ESAI_TX2_RX3 = 2,
+   IMX_IOMUXC_ENET_TXD1_ALT4_ENET_1588_EVENT0_IN = 4,
+   IMX_IOMUXC_ENET_TXD1_ALT5_GPIO1_IO29 = 5,
+} IMX_IOMUXC_ENET_TXD1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_TXD0_ALT1_ENET_TX_DATA0 = 1,
+   IMX_IOMUXC_ENET_TXD0_ALT2_ESAI_TX4_RX1 = 2,
+   IMX_IOMUXC_ENET_TXD0_ALT5_GPIO1_IO30 = 5,
+} IMX_IOMUXC_ENET_TXD0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_MDC_ALT0_MLB_DATA = 0,
+   IMX_IOMUXC_ENET_MDC_ALT1_ENET_MDC = 1,
+   IMX_IOMUXC_ENET_MDC_ALT2_ESAI_TX5_RX0 = 2,
+   IMX_IOMUXC_ENET_MDC_ALT4_ENET_1588_EVENT1_IN = 4,
+   IMX_IOMUXC_ENET_MDC_ALT5_GPIO1_IO31 = 5,
+} IMX_IOMUXC_ENET_MDC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_D0_ALT0_NAND_DATA00 = 0,
+   IMX_IOMUXC_NANDF_D0_ALT1_SD1_DATA4 = 1,
+   IMX_IOMUXC_NANDF_D0_ALT5_GPIO2_IO00 = 5,
+} IMX_IOMUXC_NANDF_D0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_D1_ALT0_NAND_DATA01 = 0,
+   IMX_IOMUXC_NANDF_D1_ALT1_SD1_DATA5 = 1,
+   IMX_IOMUXC_NANDF_D1_ALT5_GPIO2_IO01 = 5,
+} IMX_IOMUXC_NANDF_D1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_D2_ALT0_NAND_DATA02 = 0,
+   IMX_IOMUXC_NANDF_D2_ALT1_SD1_DATA6 = 1,
+   IMX_IOMUXC_NANDF_D2_ALT5_GPIO2_IO02 = 5,
+} IMX_IOMUXC_NANDF_D2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_D3_ALT0_NAND_DATA03 = 0,
+   IMX_IOMUXC_NANDF_D3_ALT1_SD1_DATA7 = 1,
+   IMX_IOMUXC_NANDF_D3_ALT5_GPIO2_IO03 = 5,
+} IMX_IOMUXC_NANDF_D3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_D4_ALT0_NAND_DATA04 = 0,
+   IMX_IOMUXC_NANDF_D4_ALT1_SD2_DATA4 = 1,
+   IMX_IOMUXC_NANDF_D4_ALT5_GPIO2_IO04 = 5,
+} IMX_IOMUXC_NANDF_D4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_D5_ALT0_NAND_DATA05 = 0,
+   IMX_IOMUXC_NANDF_D5_ALT1_SD2_DATA5 = 1,
+   IMX_IOMUXC_NANDF_D5_ALT5_GPIO2_IO05 = 5,
+} IMX_IOMUXC_NANDF_D5_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_D6_ALT0_NAND_DATA06 = 0,
+   IMX_IOMUXC_NANDF_D6_ALT1_SD2_DATA6 = 1,
+   IMX_IOMUXC_NANDF_D6_ALT5_GPIO2_IO06 = 5,
+} IMX_IOMUXC_NANDF_D6_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_D7_ALT0_NAND_DATA07 = 0,
+   IMX_IOMUXC_NANDF_D7_ALT1_SD2_DATA7 = 1,
+   IMX_IOMUXC_NANDF_D7_ALT5_GPIO2_IO07 = 5,
+} IMX_IOMUXC_NANDF_D7_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DAT0_ALT1_SD4_DATA0 = 1,
+   IMX_IOMUXC_SD4_DAT0_ALT2_NAND_DQS = 2,
+   IMX_IOMUXC_SD4_DAT0_ALT5_GPIO2_IO08 = 5,
+} IMX_IOMUXC_SD4_DAT0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DAT1_ALT1_SD4_DATA1 = 1,
+   IMX_IOMUXC_SD4_DAT1_ALT2_PWM3_OUT = 2,
+   IMX_IOMUXC_SD4_DAT1_ALT5_GPIO2_IO09 = 5,
+} IMX_IOMUXC_SD4_DAT1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DAT2_ALT1_SD4_DATA2 = 1,
+   IMX_IOMUXC_SD4_DAT2_ALT2_PWM4_OUT = 2,
+   IMX_IOMUXC_SD4_DAT2_ALT5_GPIO2_IO10 = 5,
+} IMX_IOMUXC_SD4_DAT2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DAT3_ALT1_SD4_DATA3 = 1,
+   IMX_IOMUXC_SD4_DAT3_ALT5_GPIO2_IO11 = 5,
+} IMX_IOMUXC_SD4_DAT3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DAT4_ALT1_SD4_DATA4 = 1,
+   IMX_IOMUXC_SD4_DAT4_ALT2_UART2_RX_DATA = 2,
+   IMX_IOMUXC_SD4_DAT4_ALT5_GPIO2_IO12 = 5,
+} IMX_IOMUXC_SD4_DAT4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DAT5_ALT1_SD4_DATA5 = 1,
+   IMX_IOMUXC_SD4_DAT5_ALT2_UART2_RTS_B = 2,
+   IMX_IOMUXC_SD4_DAT5_ALT5_GPIO2_IO13 = 5,
+} IMX_IOMUXC_SD4_DAT5_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DAT6_ALT1_SD4_DATA6 = 1,
+   IMX_IOMUXC_SD4_DAT6_ALT2_UART2_CTS_B = 2,
+   IMX_IOMUXC_SD4_DAT6_ALT5_GPIO2_IO14 = 5,
+} IMX_IOMUXC_SD4_DAT6_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DAT7_ALT1_SD4_DATA7 = 1,
+   IMX_IOMUXC_SD4_DAT7_ALT2_UART2_TX_DATA = 2,
+   IMX_IOMUXC_SD4_DAT7_ALT5_GPIO2_IO15 = 5,
+} IMX_IOMUXC_SD4_DAT7_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A22_ALT0_EIM_ADDR22 = 0,
+   IMX_IOMUXC_EIM_A22_ALT1_IPU1_DISP1_DATA17 = 1,
+   IMX_IOMUXC_EIM_A22_ALT2_IPU2_CSI1_DATA17 = 2,
+   IMX_IOMUXC_EIM_A22_ALT5_GPIO2_IO16 = 5,
+   IMX_IOMUXC_EIM_A22_ALT7_SRC_BOOT_CFG22 = 7,
+} IMX_IOMUXC_EIM_A22_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A21_ALT0_EIM_ADDR21 = 0,
+   IMX_IOMUXC_EIM_A21_ALT1_IPU1_DISP1_DATA16 = 1,
+   IMX_IOMUXC_EIM_A21_ALT2_IPU2_CSI1_DATA16 = 2,
+   IMX_IOMUXC_EIM_A21_ALT5_GPIO2_IO17 = 5,
+   IMX_IOMUXC_EIM_A21_ALT7_SRC_BOOT_CFG21 = 7,
+} IMX_IOMUXC_EIM_A21_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A20_ALT0_EIM_ADDR20 = 0,
+   IMX_IOMUXC_EIM_A20_ALT1_IPU1_DISP1_DATA15 = 1,
+   IMX_IOMUXC_EIM_A20_ALT2_IPU2_CSI1_DATA15 = 2,
+   IMX_IOMUXC_EIM_A20_ALT5_GPIO2_IO18 = 5,
+   IMX_IOMUXC_EIM_A20_ALT7_SRC_BOOT_CFG20 = 7,
+} IMX_IOMUXC_EIM_A20_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A19_ALT0_EIM_ADDR19 = 0,
+   IMX_IOMUXC_EIM_A19_ALT1_IPU1_DISP1_DATA14 = 1,
+   IMX_IOMUXC_EIM_A19_ALT2_IPU2_CSI1_DATA14 = 2,
+   IMX_IOMUXC_EIM_A19_ALT5_GPIO2_IO19 = 5,
+   IMX_IOMUXC_EIM_A19_ALT7_SRC_BOOT_CFG19 = 7,
+} IMX_IOMUXC_EIM_A19_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A18_ALT0_EIM_ADDR18 = 0,
+   IMX_IOMUXC_EIM_A18_ALT1_IPU1_DISP1_DATA13 = 1,
+   IMX_IOMUXC_EIM_A18_ALT2_IPU2_CSI1_DATA13 = 2,
+   IMX_IOMUXC_EIM_A18_ALT5_GPIO2_IO20 = 5,
+   IMX_IOMUXC_EIM_A18_ALT7_SRC_BOOT_CFG18 = 7,
+} IMX_IOMUXC_EIM_A18_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A17_ALT0_EIM_ADDR17 = 0,
+   IMX_IOMUXC_EIM_A17_ALT1_IPU1_DISP1_DATA12 = 1,
+   IMX_IOMUXC_EIM_A17_ALT2_IPU2_CSI1_DATA12 = 2,
+   IMX_IOMUXC_EIM_A17_ALT5_GPIO2_IO21 = 5,
+   IMX_IOMUXC_EIM_A17_ALT7_SRC_BOOT_CFG17 = 7,
+} IMX_IOMUXC_EIM_A17_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A16_ALT0_EIM_ADDR16 = 0,
+   IMX_IOMUXC_EIM_A16_ALT1_IPU1_DI1_DISP_CLK = 1,
+   IMX_IOMUXC_EIM_A16_ALT2_IPU2_CSI1_PIXCLK = 2,
+   IMX_IOMUXC_EIM_A16_ALT5_GPIO2_IO22 = 5,
+   IMX_IOMUXC_EIM_A16_ALT7_SRC_BOOT_CFG16 = 7,
+} IMX_IOMUXC_EIM_A16_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_CS0_ALT0_EIM_CS0_B = 0,
+   IMX_IOMUXC_EIM_CS0_ALT1_IPU1_DI1_PIN05 = 1,
+   IMX_IOMUXC_EIM_CS0_ALT2_ECSPI2_SCLK = 2,
+   IMX_IOMUXC_EIM_CS0_ALT5_GPIO2_IO23 = 5,
+} IMX_IOMUXC_EIM_CS0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_CS1_ALT0_EIM_CS1_B = 0,
+   IMX_IOMUXC_EIM_CS1_ALT1_IPU1_DI1_PIN06 = 1,
+   IMX_IOMUXC_EIM_CS1_ALT2_ECSPI2_MOSI = 2,
+   IMX_IOMUXC_EIM_CS1_ALT5_GPIO2_IO24 = 5,
+} IMX_IOMUXC_EIM_CS1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_OE_ALT0_EIM_OE_B = 0,
+   IMX_IOMUXC_EIM_OE_ALT1_IPU1_DI1_PIN07 = 1,
+   IMX_IOMUXC_EIM_OE_ALT2_ECSPI2_MISO = 2,
+   IMX_IOMUXC_EIM_OE_ALT5_GPIO2_IO25 = 5,
+} IMX_IOMUXC_EIM_OE_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_RW_ALT0_EIM_RW = 0,
+   IMX_IOMUXC_EIM_RW_ALT1_IPU1_DI1_PIN08 = 1,
+   IMX_IOMUXC_EIM_RW_ALT2_ECSPI2_SS0 = 2,
+   IMX_IOMUXC_EIM_RW_ALT5_GPIO2_IO26 = 5,
+   IMX_IOMUXC_EIM_RW_ALT7_SRC_BOOT_CFG29 = 7,
+} IMX_IOMUXC_EIM_RW_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_LBA_ALT0_EIM_LBA_B = 0,
+   IMX_IOMUXC_EIM_LBA_ALT1_IPU1_DI1_PIN17 = 1,
+   IMX_IOMUXC_EIM_LBA_ALT2_ECSPI2_SS1 = 2,
+   IMX_IOMUXC_EIM_LBA_ALT5_GPIO2_IO27 = 5,
+   IMX_IOMUXC_EIM_LBA_ALT7_SRC_BOOT_CFG26 = 7,
+} IMX_IOMUXC_EIM_LBA_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_EB0_ALT0_EIM_EB0_B = 0,
+   IMX_IOMUXC_EIM_EB0_ALT1_IPU1_DISP1_DATA11 = 1,
+   IMX_IOMUXC_EIM_EB0_ALT2_IPU2_CSI1_DATA11 = 2,
+   IMX_IOMUXC_EIM_EB0_ALT4_CCM_PMIC_READY = 4,
+   IMX_IOMUXC_EIM_EB0_ALT5_GPIO2_IO28 = 5,
+   IMX_IOMUXC_EIM_EB0_ALT7_SRC_BOOT_CFG27 = 7,
+} IMX_IOMUXC_EIM_EB0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_EB1_ALT0_EIM_EB1_B = 0,
+   IMX_IOMUXC_EIM_EB1_ALT1_IPU1_DISP1_DATA10 = 1,
+   IMX_IOMUXC_EIM_EB1_ALT2_IPU2_CSI1_DATA10 = 2,
+   IMX_IOMUXC_EIM_EB1_ALT5_GPIO2_IO29 = 5,
+   IMX_IOMUXC_EIM_EB1_ALT7_SRC_BOOT_CFG28 = 7,
+} IMX_IOMUXC_EIM_EB1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_EB2_ALT0_EIM_EB2_B = 0,
+   IMX_IOMUXC_EIM_EB2_ALT1_ECSPI1_SS0 = 1,
+   IMX_IOMUXC_EIM_EB2_ALT3_IPU2_CSI1_DATA19 = 3,
+   IMX_IOMUXC_EIM_EB2_ALT4_HDMI_TX_DDC_SCL = 4,
+   IMX_IOMUXC_EIM_EB2_ALT5_GPIO2_IO30 = 5,
+   IMX_IOMUXC_EIM_EB2_ALT6_I2C2_SCL = 6,
+   IMX_IOMUXC_EIM_EB2_ALT7_SRC_BOOT_CFG30 = 7,
+} IMX_IOMUXC_EIM_EB2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_EB3_ALT0_EIM_EB3_B = 0,
+   IMX_IOMUXC_EIM_EB3_ALT1_ECSPI4_RDY = 1,
+   IMX_IOMUXC_EIM_EB3_ALT2_UART3_RTS_B = 2,
+   IMX_IOMUXC_EIM_EB3_ALT3_UART1_RI_B = 3,
+   IMX_IOMUXC_EIM_EB3_ALT4_IPU2_CSI1_HSYNC = 4,
+   IMX_IOMUXC_EIM_EB3_ALT5_GPIO2_IO31 = 5,
+   IMX_IOMUXC_EIM_EB3_ALT6_IPU1_DI1_PIN03 = 6,
+   IMX_IOMUXC_EIM_EB3_ALT7_SRC_BOOT_CFG31 = 7,
+} IMX_IOMUXC_EIM_EB3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA0_ALT0_EIM_AD00 = 0,
+   IMX_IOMUXC_EIM_DA0_ALT1_IPU1_DISP1_DATA09 = 1,
+   IMX_IOMUXC_EIM_DA0_ALT2_IPU2_CSI1_DATA09 = 2,
+   IMX_IOMUXC_EIM_DA0_ALT5_GPIO3_IO00 = 5,
+   IMX_IOMUXC_EIM_DA0_ALT7_SRC_BOOT_CFG00 = 7,
+} IMX_IOMUXC_EIM_DA0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA1_ALT0_EIM_AD01 = 0,
+   IMX_IOMUXC_EIM_DA1_ALT1_IPU1_DISP1_DATA08 = 1,
+   IMX_IOMUXC_EIM_DA1_ALT2_IPU2_CSI1_DATA08 = 2,
+   IMX_IOMUXC_EIM_DA1_ALT5_GPIO3_IO01 = 5,
+   IMX_IOMUXC_EIM_DA1_ALT7_SRC_BOOT_CFG01 = 7,
+} IMX_IOMUXC_EIM_DA1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA2_ALT0_EIM_AD02 = 0,
+   IMX_IOMUXC_EIM_DA2_ALT1_IPU1_DISP1_DATA07 = 1,
+   IMX_IOMUXC_EIM_DA2_ALT2_IPU2_CSI1_DATA07 = 2,
+   IMX_IOMUXC_EIM_DA2_ALT5_GPIO3_IO02 = 5,
+   IMX_IOMUXC_EIM_DA2_ALT7_SRC_BOOT_CFG02 = 7,
+} IMX_IOMUXC_EIM_DA2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA3_ALT0_EIM_AD03 = 0,
+   IMX_IOMUXC_EIM_DA3_ALT1_IPU1_DISP1_DATA06 = 1,
+   IMX_IOMUXC_EIM_DA3_ALT2_IPU2_CSI1_DATA06 = 2,
+   IMX_IOMUXC_EIM_DA3_ALT5_GPIO3_IO03 = 5,
+   IMX_IOMUXC_EIM_DA3_ALT7_SRC_BOOT_CFG03 = 7,
+} IMX_IOMUXC_EIM_DA3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA4_ALT0_EIM_AD04 = 0,
+   IMX_IOMUXC_EIM_DA4_ALT1_IPU1_DISP1_DATA05 = 1,
+   IMX_IOMUXC_EIM_DA4_ALT2_IPU2_CSI1_DATA05 = 2,
+   IMX_IOMUXC_EIM_DA4_ALT5_GPIO3_IO04 = 5,
+   IMX_IOMUXC_EIM_DA4_ALT7_SRC_BOOT_CFG04 = 7,
+} IMX_IOMUXC_EIM_DA4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA5_ALT0_EIM_AD05 = 0,
+   IMX_IOMUXC_EIM_DA5_ALT1_IPU1_DISP1_DATA04 = 1,
+   IMX_IOMUXC_EIM_DA5_ALT2_IPU2_CSI1_DATA04 = 2,
+   IMX_IOMUXC_EIM_DA5_ALT5_GPIO3_IO05 = 5,
+   IMX_IOMUXC_EIM_DA5_ALT7_SRC_BOOT_CFG05 = 7,
+} IMX_IOMUXC_EIM_DA5_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA6_ALT0_EIM_AD06 = 0,
+   IMX_IOMUXC_EIM_DA6_ALT1_IPU1_DISP1_DATA03 = 1,
+   IMX_IOMUXC_EIM_DA6_ALT2_IPU2_CSI1_DATA03 = 2,
+   IMX_IOMUXC_EIM_DA6_ALT5_GPIO3_IO06 = 5,
+   IMX_IOMUXC_EIM_DA6_ALT7_SRC_BOOT_CFG06 = 7,
+} IMX_IOMUXC_EIM_DA6_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA7_ALT0_EIM_AD07 = 0,
+   IMX_IOMUXC_EIM_DA7_ALT1_IPU1_DISP1_DATA02 = 1,
+   IMX_IOMUXC_EIM_DA7_ALT2_IPU2_CSI1_DATA02 = 2,
+   IMX_IOMUXC_EIM_DA7_ALT5_GPIO3_IO07 = 5,
+   IMX_IOMUXC_EIM_DA7_ALT7_SRC_BOOT_CFG07 = 7,
+} IMX_IOMUXC_EIM_DA7_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA8_ALT0_EIM_AD08 = 0,
+   IMX_IOMUXC_EIM_DA8_ALT1_IPU1_DISP1_DATA01 = 1,
+   IMX_IOMUXC_EIM_DA8_ALT2_IPU2_CSI1_DATA01 = 2,
+   IMX_IOMUXC_EIM_DA8_ALT5_GPIO3_IO08 = 5,
+   IMX_IOMUXC_EIM_DA8_ALT7_SRC_BOOT_CFG08 = 7,
+} IMX_IOMUXC_EIM_DA8_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA9_ALT0_EIM_AD09 = 0,
+   IMX_IOMUXC_EIM_DA9_ALT1_IPU1_DISP1_DATA00 = 1,
+   IMX_IOMUXC_EIM_DA9_ALT2_IPU2_CSI1_DATA00 = 2,
+   IMX_IOMUXC_EIM_DA9_ALT5_GPIO3_IO09 = 5,
+   IMX_IOMUXC_EIM_DA9_ALT7_SRC_BOOT_CFG09 = 7,
+} IMX_IOMUXC_EIM_DA9_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA10_ALT0_EIM_AD10 = 0,
+   IMX_IOMUXC_EIM_DA10_ALT1_IPU1_DI1_PIN15 = 1,
+   IMX_IOMUXC_EIM_DA10_ALT2_IPU2_CSI1_DATA_EN = 2,
+   IMX_IOMUXC_EIM_DA10_ALT5_GPIO3_IO10 = 5,
+   IMX_IOMUXC_EIM_DA10_ALT7_SRC_BOOT_CFG10 = 7,
+} IMX_IOMUXC_EIM_DA10_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA11_ALT0_EIM_AD11 = 0,
+   IMX_IOMUXC_EIM_DA11_ALT1_IPU1_DI1_PIN02 = 1,
+   IMX_IOMUXC_EIM_DA11_ALT2_IPU2_CSI1_HSYNC = 2,
+   IMX_IOMUXC_EIM_DA11_ALT5_GPIO3_IO11 = 5,
+   IMX_IOMUXC_EIM_DA11_ALT7_SRC_BOOT_CFG11 = 7,
+} IMX_IOMUXC_EIM_DA11_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA12_ALT0_EIM_AD12 = 0,
+   IMX_IOMUXC_EIM_DA12_ALT1_IPU1_DI1_PIN03 = 1,
+   IMX_IOMUXC_EIM_DA12_ALT2_IPU2_CSI1_VSYNC = 2,
+   IMX_IOMUXC_EIM_DA12_ALT5_GPIO3_IO12 = 5,
+   IMX_IOMUXC_EIM_DA12_ALT7_SRC_BOOT_CFG12 = 7,
+} IMX_IOMUXC_EIM_DA12_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA13_ALT0_EIM_AD13 = 0,
+   IMX_IOMUXC_EIM_DA13_ALT1_IPU1_DI1_D0_CS = 1,
+   IMX_IOMUXC_EIM_DA13_ALT5_GPIO3_IO13 = 5,
+   IMX_IOMUXC_EIM_DA13_ALT7_SRC_BOOT_CFG13 = 7,
+} IMX_IOMUXC_EIM_DA13_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA14_ALT0_EIM_AD14 = 0,
+   IMX_IOMUXC_EIM_DA14_ALT1_IPU1_DI1_D1_CS = 1,
+   IMX_IOMUXC_EIM_DA14_ALT5_GPIO3_IO14 = 5,
+   IMX_IOMUXC_EIM_DA14_ALT7_SRC_BOOT_CFG14 = 7,
+} IMX_IOMUXC_EIM_DA14_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA15_ALT0_EIM_AD15 = 0,
+   IMX_IOMUXC_EIM_DA15_ALT1_IPU1_DI1_PIN01 = 1,
+   IMX_IOMUXC_EIM_DA15_ALT2_IPU1_DI1_PIN04 = 2,
+   IMX_IOMUXC_EIM_DA15_ALT5_GPIO3_IO15 = 5,
+   IMX_IOMUXC_EIM_DA15_ALT7_SRC_BOOT_CFG15 = 7,
+} IMX_IOMUXC_EIM_DA15_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D16_ALT0_EIM_DATA16 = 0,
+   IMX_IOMUXC_EIM_D16_ALT1_ECSPI1_SCLK = 1,
+   IMX_IOMUXC_EIM_D16_ALT2_IPU1_DI0_PIN05 = 2,
+   IMX_IOMUXC_EIM_D16_ALT3_IPU2_CSI1_DATA18 = 3,
+   IMX_IOMUXC_EIM_D16_ALT4_HDMI_TX_DDC_SDA = 4,
+   IMX_IOMUXC_EIM_D16_ALT5_GPIO3_IO16 = 5,
+   IMX_IOMUXC_EIM_D16_ALT6_I2C2_SDA = 6,
+} IMX_IOMUXC_EIM_D16_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D17_ALT0_EIM_DATA17 = 0,
+   IMX_IOMUXC_EIM_D17_ALT1_ECSPI1_MISO = 1,
+   IMX_IOMUXC_EIM_D17_ALT2_IPU1_DI0_PIN06 = 2,
+   IMX_IOMUXC_EIM_D17_ALT3_IPU2_CSI1_PIXCLK = 3,
+   IMX_IOMUXC_EIM_D17_ALT4_DCIC1_OUT = 4,
+   IMX_IOMUXC_EIM_D17_ALT5_GPIO3_IO17 = 5,
+   IMX_IOMUXC_EIM_D17_ALT6_I2C3_SCL = 6,
+} IMX_IOMUXC_EIM_D17_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D18_ALT0_EIM_DATA18 = 0,
+   IMX_IOMUXC_EIM_D18_ALT1_ECSPI1_MOSI = 1,
+   IMX_IOMUXC_EIM_D18_ALT2_IPU1_DI0_PIN07 = 2,
+   IMX_IOMUXC_EIM_D18_ALT3_IPU2_CSI1_DATA17 = 3,
+   IMX_IOMUXC_EIM_D18_ALT4_IPU1_DI1_D0_CS = 4,
+   IMX_IOMUXC_EIM_D18_ALT5_GPIO3_IO18 = 5,
+   IMX_IOMUXC_EIM_D18_ALT6_I2C3_SDA = 6,
+} IMX_IOMUXC_EIM_D18_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D19_ALT0_EIM_DATA19 = 0,
+   IMX_IOMUXC_EIM_D19_ALT1_ECSPI1_SS1 = 1,
+   IMX_IOMUXC_EIM_D19_ALT2_IPU1_DI0_PIN08 = 2,
+   IMX_IOMUXC_EIM_D19_ALT3_IPU2_CSI1_DATA16 = 3,
+   IMX_IOMUXC_EIM_D19_ALT4_UART1_CTS_B = 4,
+   IMX_IOMUXC_EIM_D19_ALT5_GPIO3_IO19 = 5,
+   IMX_IOMUXC_EIM_D19_ALT6_EPIT1_OUT = 6,
+} IMX_IOMUXC_EIM_D19_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D20_ALT0_EIM_DATA20 = 0,
+   IMX_IOMUXC_EIM_D20_ALT1_ECSPI4_SS0 = 1,
+   IMX_IOMUXC_EIM_D20_ALT2_IPU1_DI0_PIN16 = 2,
+   IMX_IOMUXC_EIM_D20_ALT3_IPU2_CSI1_DATA15 = 3,
+   IMX_IOMUXC_EIM_D20_ALT4_UART1_RTS_B = 4,
+   IMX_IOMUXC_EIM_D20_ALT5_GPIO3_IO20 = 5,
+   IMX_IOMUXC_EIM_D20_ALT6_EPIT2_OUT = 6,
+} IMX_IOMUXC_EIM_D20_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D21_ALT0_EIM_DATA21 = 0,
+   IMX_IOMUXC_EIM_D21_ALT1_ECSPI4_SCLK = 1,
+   IMX_IOMUXC_EIM_D21_ALT2_IPU1_DI0_PIN17 = 2,
+   IMX_IOMUXC_EIM_D21_ALT3_IPU2_CSI1_DATA11 = 3,
+   IMX_IOMUXC_EIM_D21_ALT4_USB_OTG_OC = 4,
+   IMX_IOMUXC_EIM_D21_ALT5_GPIO3_IO21 = 5,
+   IMX_IOMUXC_EIM_D21_ALT6_I2C1_SCL = 6,
+   IMX_IOMUXC_EIM_D21_ALT7_SPDIF_IN = 7,
+} IMX_IOMUXC_EIM_D21_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D22_ALT0_EIM_DATA22 = 0,
+   IMX_IOMUXC_EIM_D22_ALT1_ECSPI4_MISO = 1,
+   IMX_IOMUXC_EIM_D22_ALT2_IPU1_DI0_PIN01 = 2,
+   IMX_IOMUXC_EIM_D22_ALT3_IPU2_CSI1_DATA10 = 3,
+   IMX_IOMUXC_EIM_D22_ALT4_USB_OTG_PWR = 4,
+   IMX_IOMUXC_EIM_D22_ALT5_GPIO3_IO22 = 5,
+   IMX_IOMUXC_EIM_D22_ALT6_SPDIF_OUT = 6,
+} IMX_IOMUXC_EIM_D22_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D23_ALT0_EIM_DATA23 = 0,
+   IMX_IOMUXC_EIM_D23_ALT1_IPU1_DI0_D0_CS = 1,
+   IMX_IOMUXC_EIM_D23_ALT2_UART3_CTS_B = 2,
+   IMX_IOMUXC_EIM_D23_ALT3_UART1_DCD_B = 3,
+   IMX_IOMUXC_EIM_D23_ALT4_IPU2_CSI1_DATA_EN = 4,
+   IMX_IOMUXC_EIM_D23_ALT5_GPIO3_IO23 = 5,
+   IMX_IOMUXC_EIM_D23_ALT6_IPU1_DI1_PIN02 = 6,
+   IMX_IOMUXC_EIM_D23_ALT7_IPU1_DI1_PIN14 = 7,
+} IMX_IOMUXC_EIM_D23_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D24_ALT0_EIM_DATA24 = 0,
+   IMX_IOMUXC_EIM_D24_ALT1_ECSPI4_SS2 = 1,
+   IMX_IOMUXC_EIM_D24_ALT2_UART3_TX_DATA = 2,
+   IMX_IOMUXC_EIM_D24_ALT3_ECSPI1_SS2 = 3,
+   IMX_IOMUXC_EIM_D24_ALT4_ECSPI2_SS2 = 4,
+   IMX_IOMUXC_EIM_D24_ALT5_GPIO3_IO24 = 5,
+   IMX_IOMUXC_EIM_D24_ALT6_AUD5_RXFS = 6,
+   IMX_IOMUXC_EIM_D24_ALT7_UART1_DTR_B = 7,
+} IMX_IOMUXC_EIM_D24_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D25_ALT0_EIM_DATA25 = 0,
+   IMX_IOMUXC_EIM_D25_ALT1_ECSPI4_SS3 = 1,
+   IMX_IOMUXC_EIM_D25_ALT2_UART3_RX_DATA = 2,
+   IMX_IOMUXC_EIM_D25_ALT3_ECSPI1_SS3 = 3,
+   IMX_IOMUXC_EIM_D25_ALT4_ECSPI2_SS3 = 4,
+   IMX_IOMUXC_EIM_D25_ALT5_GPIO3_IO25 = 5,
+   IMX_IOMUXC_EIM_D25_ALT6_AUD5_RXC = 6,
+   IMX_IOMUXC_EIM_D25_ALT7_UART1_DSR_B = 7,
+} IMX_IOMUXC_EIM_D25_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D26_ALT0_EIM_DATA26 = 0,
+   IMX_IOMUXC_EIM_D26_ALT1_IPU1_DI1_PIN11 = 1,
+   IMX_IOMUXC_EIM_D26_ALT2_IPU1_CSI0_DATA01 = 2,
+   IMX_IOMUXC_EIM_D26_ALT3_IPU2_CSI1_DATA14 = 3,
+   IMX_IOMUXC_EIM_D26_ALT4_UART2_TX_DATA = 4,
+   IMX_IOMUXC_EIM_D26_ALT5_GPIO3_IO26 = 5,
+   IMX_IOMUXC_EIM_D26_ALT6_IPU1_SISG2 = 6,
+   IMX_IOMUXC_EIM_D26_ALT7_IPU1_DISP1_DATA22 = 7,
+} IMX_IOMUXC_EIM_D26_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D27_ALT0_EIM_DATA27 = 0,
+   IMX_IOMUXC_EIM_D27_ALT1_IPU1_DI1_PIN13 = 1,
+   IMX_IOMUXC_EIM_D27_ALT2_IPU1_CSI0_DATA00 = 2,
+   IMX_IOMUXC_EIM_D27_ALT3_IPU2_CSI1_DATA13 = 3,
+   IMX_IOMUXC_EIM_D27_ALT4_UART2_RX_DATA = 4,
+   IMX_IOMUXC_EIM_D27_ALT5_GPIO3_IO27 = 5,
+   IMX_IOMUXC_EIM_D27_ALT6_IPU1_SISG3 = 6,
+   IMX_IOMUXC_EIM_D27_ALT7_IPU1_DISP1_DATA23 = 7,
+} IMX_IOMUXC_EIM_D27_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D28_ALT0_EIM_DATA28 = 0,
+   IMX_IOMUXC_EIM_D28_ALT1_I2C1_SDA = 1,
+   IMX_IOMUXC_EIM_D28_ALT2_ECSPI4_MOSI = 2,
+   IMX_IOMUXC_EIM_D28_ALT3_IPU2_CSI1_DATA12 = 3,
+   IMX_IOMUXC_EIM_D28_ALT4_UART2_CTS_B = 4,
+   IMX_IOMUXC_EIM_D28_ALT5_GPIO3_IO28 = 5,
+   IMX_IOMUXC_EIM_D28_ALT6_IPU1_EXT_TRIG = 6,
+   IMX_IOMUXC_EIM_D28_ALT7_IPU1_DI0_PIN13 = 7,
+} IMX_IOMUXC_EIM_D28_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D29_ALT0_EIM_DATA29 = 0,
+   IMX_IOMUXC_EIM_D29_ALT1_IPU1_DI1_PIN15 = 1,
+   IMX_IOMUXC_EIM_D29_ALT2_ECSPI4_SS0 = 2,
+   IMX_IOMUXC_EIM_D29_ALT4_UART2_RTS_B = 4,
+   IMX_IOMUXC_EIM_D29_ALT5_GPIO3_IO29 = 5,
+   IMX_IOMUXC_EIM_D29_ALT6_IPU2_CSI1_VSYNC = 6,
+   IMX_IOMUXC_EIM_D29_ALT7_IPU1_DI0_PIN14 = 7,
+} IMX_IOMUXC_EIM_D29_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D30_ALT0_EIM_DATA30 = 0,
+   IMX_IOMUXC_EIM_D30_ALT1_IPU1_DISP1_DATA21 = 1,
+   IMX_IOMUXC_EIM_D30_ALT2_IPU1_DI0_PIN11 = 2,
+   IMX_IOMUXC_EIM_D30_ALT3_IPU1_CSI0_DATA03 = 3,
+   IMX_IOMUXC_EIM_D30_ALT4_UART3_CTS_B = 4,
+   IMX_IOMUXC_EIM_D30_ALT5_GPIO3_IO30 = 5,
+   IMX_IOMUXC_EIM_D30_ALT6_USB_H1_OC = 6,
+} IMX_IOMUXC_EIM_D30_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D31_ALT0_EIM_DATA31 = 0,
+   IMX_IOMUXC_EIM_D31_ALT1_IPU1_DISP1_DATA20 = 1,
+   IMX_IOMUXC_EIM_D31_ALT2_IPU1_DI0_PIN12 = 2,
+   IMX_IOMUXC_EIM_D31_ALT3_IPU1_CSI0_DATA02 = 3,
+   IMX_IOMUXC_EIM_D31_ALT4_UART3_RTS_B = 4,
+   IMX_IOMUXC_EIM_D31_ALT5_GPIO3_IO31 = 5,
+   IMX_IOMUXC_EIM_D31_ALT6_USB_H1_PWR = 6,
+} IMX_IOMUXC_EIM_D31_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_19_ALT0_KEY_COL5 = 0,
+   IMX_IOMUXC_GPIO_19_ALT1_ENET_1588_EVENT0_OUT = 1,
+   IMX_IOMUXC_GPIO_19_ALT2_SPDIF_OUT = 2,
+   IMX_IOMUXC_GPIO_19_ALT3_CCM_CLKO1 = 3,
+   IMX_IOMUXC_GPIO_19_ALT4_ECSPI1_RDY = 4,
+   IMX_IOMUXC_GPIO_19_ALT5_GPIO4_IO05 = 5,
+   IMX_IOMUXC_GPIO_19_ALT6_ENET_TX_ER = 6,
+} IMX_IOMUXC_GPIO_19_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_COL0_ALT0_ECSPI1_SCLK = 0,
+   IMX_IOMUXC_KEY_COL0_ALT1_ENET_RX_DATA3 = 1,
+   IMX_IOMUXC_KEY_COL0_ALT2_AUD5_TXC = 2,
+   IMX_IOMUXC_KEY_COL0_ALT3_KEY_COL0 = 3,
+   IMX_IOMUXC_KEY_COL0_ALT4_UART4_TX_DATA = 4,
+   IMX_IOMUXC_KEY_COL0_ALT5_GPIO4_IO06 = 5,
+   IMX_IOMUXC_KEY_COL0_ALT6_DCIC1_OUT = 6,
+} IMX_IOMUXC_KEY_COL0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_ROW0_ALT0_ECSPI1_MOSI = 0,
+   IMX_IOMUXC_KEY_ROW0_ALT1_ENET_TX_DATA3 = 1,
+   IMX_IOMUXC_KEY_ROW0_ALT2_AUD5_TXD = 2,
+   IMX_IOMUXC_KEY_ROW0_ALT3_KEY_ROW0 = 3,
+   IMX_IOMUXC_KEY_ROW0_ALT4_UART4_RX_DATA = 4,
+   IMX_IOMUXC_KEY_ROW0_ALT5_GPIO4_IO07 = 5,
+   IMX_IOMUXC_KEY_ROW0_ALT6_DCIC2_OUT = 6,
+} IMX_IOMUXC_KEY_ROW0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_COL1_ALT0_ECSPI1_MISO = 0,
+   IMX_IOMUXC_KEY_COL1_ALT1_ENET_MDIO = 1,
+   IMX_IOMUXC_KEY_COL1_ALT2_AUD5_TXFS = 2,
+   IMX_IOMUXC_KEY_COL1_ALT3_KEY_COL1 = 3,
+   IMX_IOMUXC_KEY_COL1_ALT4_UART5_TX_DATA = 4,
+   IMX_IOMUXC_KEY_COL1_ALT5_GPIO4_IO08 = 5,
+   IMX_IOMUXC_KEY_COL1_ALT6_SD1_VSELECT = 6,
+} IMX_IOMUXC_KEY_COL1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_ROW1_ALT0_ECSPI1_SS0 = 0,
+   IMX_IOMUXC_KEY_ROW1_ALT1_ENET_COL = 1,
+   IMX_IOMUXC_KEY_ROW1_ALT2_AUD5_RXD = 2,
+   IMX_IOMUXC_KEY_ROW1_ALT3_KEY_ROW1 = 3,
+   IMX_IOMUXC_KEY_ROW1_ALT4_UART5_RX_DATA = 4,
+   IMX_IOMUXC_KEY_ROW1_ALT5_GPIO4_IO09 = 5,
+   IMX_IOMUXC_KEY_ROW1_ALT6_SD2_VSELECT = 6,
+} IMX_IOMUXC_KEY_ROW1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_COL2_ALT0_ECSPI1_SS1 = 0,
+   IMX_IOMUXC_KEY_COL2_ALT1_ENET_RX_DATA2 = 1,
+   IMX_IOMUXC_KEY_COL2_ALT2_FLEXCAN1_TX = 2,
+   IMX_IOMUXC_KEY_COL2_ALT3_KEY_COL2 = 3,
+   IMX_IOMUXC_KEY_COL2_ALT4_ENET_MDC = 4,
+   IMX_IOMUXC_KEY_COL2_ALT5_GPIO4_IO10 = 5,
+   IMX_IOMUXC_KEY_COL2_ALT6_USB_H1_PWR_CTL_WAKE = 6,
+} IMX_IOMUXC_KEY_COL2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_ROW2_ALT0_ECSPI1_SS2 = 0,
+   IMX_IOMUXC_KEY_ROW2_ALT1_ENET_TX_DATA2 = 1,
+   IMX_IOMUXC_KEY_ROW2_ALT2_FLEXCAN1_RX = 2,
+   IMX_IOMUXC_KEY_ROW2_ALT3_KEY_ROW2 = 3,
+   IMX_IOMUXC_KEY_ROW2_ALT4_SD2_VSELECT = 4,
+   IMX_IOMUXC_KEY_ROW2_ALT5_GPIO4_IO11 = 5,
+   IMX_IOMUXC_KEY_ROW2_ALT6_HDMI_TX_CEC_LINE = 6,
+} IMX_IOMUXC_KEY_ROW2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_COL3_ALT0_ECSPI1_SS3 = 0,
+   IMX_IOMUXC_KEY_COL3_ALT1_ENET_CRS = 1,
+   IMX_IOMUXC_KEY_COL3_ALT2_HDMI_TX_DDC_SCL = 2,
+   IMX_IOMUXC_KEY_COL3_ALT3_KEY_COL3 = 3,
+   IMX_IOMUXC_KEY_COL3_ALT4_I2C2_SCL = 4,
+   IMX_IOMUXC_KEY_COL3_ALT5_GPIO4_IO12 = 5,
+   IMX_IOMUXC_KEY_COL3_ALT6_SPDIF_IN = 6,
+} IMX_IOMUXC_KEY_COL3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_ROW3_ALT0_XTALOSC_OSC32K_32K_OUT = 0,
+   IMX_IOMUXC_KEY_ROW3_ALT1_ASRC_EXT_CLK = 1,
+   IMX_IOMUXC_KEY_ROW3_ALT2_HDMI_TX_DDC_SDA = 2,
+   IMX_IOMUXC_KEY_ROW3_ALT3_KEY_ROW3 = 3,
+   IMX_IOMUXC_KEY_ROW3_ALT4_I2C2_SDA = 4,
+   IMX_IOMUXC_KEY_ROW3_ALT5_GPIO4_IO13 = 5,
+   IMX_IOMUXC_KEY_ROW3_ALT6_SD1_VSELECT = 6,
+} IMX_IOMUXC_KEY_ROW3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_COL4_ALT0_FLEXCAN2_TX = 0,
+   IMX_IOMUXC_KEY_COL4_ALT1_IPU1_SISG4 = 1,
+   IMX_IOMUXC_KEY_COL4_ALT2_USB_OTG_OC = 2,
+   IMX_IOMUXC_KEY_COL4_ALT3_KEY_COL4 = 3,
+   IMX_IOMUXC_KEY_COL4_ALT4_UART5_RTS_B = 4,
+   IMX_IOMUXC_KEY_COL4_ALT5_GPIO4_IO14 = 5,
+} IMX_IOMUXC_KEY_COL4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_ROW4_ALT0_FLEXCAN2_RX = 0,
+   IMX_IOMUXC_KEY_ROW4_ALT1_IPU1_SISG5 = 1,
+   IMX_IOMUXC_KEY_ROW4_ALT2_USB_OTG_PWR = 2,
+   IMX_IOMUXC_KEY_ROW4_ALT3_KEY_ROW4 = 3,
+   IMX_IOMUXC_KEY_ROW4_ALT4_UART5_CTS_B = 4,
+   IMX_IOMUXC_KEY_ROW4_ALT5_GPIO4_IO15 = 5,
+} IMX_IOMUXC_KEY_ROW4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DI0_DISP_CLK_ALT0_IPU1_DI0_DISP_CLK = 0,
+   IMX_IOMUXC_DI0_DISP_CLK_ALT1_IPU2_DI0_DISP_CLK = 1,
+   IMX_IOMUXC_DI0_DISP_CLK_ALT5_GPIO4_IO16 = 5,
+} IMX_IOMUXC_DI0_DISP_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DI0_PIN15_ALT0_IPU1_DI0_PIN15 = 0,
+   IMX_IOMUXC_DI0_PIN15_ALT1_IPU2_DI0_PIN15 = 1,
+   IMX_IOMUXC_DI0_PIN15_ALT2_AUD6_TXC = 2,
+   IMX_IOMUXC_DI0_PIN15_ALT5_GPIO4_IO17 = 5,
+} IMX_IOMUXC_DI0_PIN15_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DI0_PIN2_ALT0_IPU1_DI0_PIN02 = 0,
+   IMX_IOMUXC_DI0_PIN2_ALT1_IPU2_DI0_PIN02 = 1,
+   IMX_IOMUXC_DI0_PIN2_ALT2_AUD6_TXD = 2,
+   IMX_IOMUXC_DI0_PIN2_ALT5_GPIO4_IO18 = 5,
+} IMX_IOMUXC_DI0_PIN2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DI0_PIN3_ALT0_IPU1_DI0_PIN03 = 0,
+   IMX_IOMUXC_DI0_PIN3_ALT1_IPU2_DI0_PIN03 = 1,
+   IMX_IOMUXC_DI0_PIN3_ALT2_AUD6_TXFS = 2,
+   IMX_IOMUXC_DI0_PIN3_ALT5_GPIO4_IO19 = 5,
+} IMX_IOMUXC_DI0_PIN3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DI0_PIN4_ALT0_IPU1_DI0_PIN04 = 0,
+   IMX_IOMUXC_DI0_PIN4_ALT1_IPU2_DI0_PIN04 = 1,
+   IMX_IOMUXC_DI0_PIN4_ALT2_AUD6_RXD = 2,
+   IMX_IOMUXC_DI0_PIN4_ALT3_SD1_WP = 3,
+   IMX_IOMUXC_DI0_PIN4_ALT5_GPIO4_IO20 = 5,
+} IMX_IOMUXC_DI0_PIN4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT0_ALT0_IPU1_DISP0_DATA00 = 0,
+   IMX_IOMUXC_DISP0_DAT0_ALT1_IPU2_DISP0_DATA00 = 1,
+   IMX_IOMUXC_DISP0_DAT0_ALT2_ECSPI3_SCLK = 2,
+   IMX_IOMUXC_DISP0_DAT0_ALT5_GPIO4_IO21 = 5,
+} IMX_IOMUXC_DISP0_DAT0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT1_ALT0_IPU1_DISP0_DATA01 = 0,
+   IMX_IOMUXC_DISP0_DAT1_ALT1_IPU2_DISP0_DATA01 = 1,
+   IMX_IOMUXC_DISP0_DAT1_ALT2_ECSPI3_MOSI = 2,
+   IMX_IOMUXC_DISP0_DAT1_ALT5_GPIO4_IO22 = 5,
+} IMX_IOMUXC_DISP0_DAT1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT2_ALT0_IPU1_DISP0_DATA02 = 0,
+   IMX_IOMUXC_DISP0_DAT2_ALT1_IPU2_DISP0_DATA02 = 1,
+   IMX_IOMUXC_DISP0_DAT2_ALT2_ECSPI3_MISO = 2,
+   IMX_IOMUXC_DISP0_DAT2_ALT5_GPIO4_IO23 = 5,
+} IMX_IOMUXC_DISP0_DAT2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT3_ALT0_IPU1_DISP0_DATA03 = 0,
+   IMX_IOMUXC_DISP0_DAT3_ALT1_IPU2_DISP0_DATA03 = 1,
+   IMX_IOMUXC_DISP0_DAT3_ALT2_ECSPI3_SS0 = 2,
+   IMX_IOMUXC_DISP0_DAT3_ALT5_GPIO4_IO24 = 5,
+} IMX_IOMUXC_DISP0_DAT3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT4_ALT0_IPU1_DISP0_DATA04 = 0,
+   IMX_IOMUXC_DISP0_DAT4_ALT1_IPU2_DISP0_DATA04 = 1,
+   IMX_IOMUXC_DISP0_DAT4_ALT2_ECSPI3_SS1 = 2,
+   IMX_IOMUXC_DISP0_DAT4_ALT5_GPIO4_IO25 = 5,
+} IMX_IOMUXC_DISP0_DAT4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT5_ALT0_IPU1_DISP0_DATA05 = 0,
+   IMX_IOMUXC_DISP0_DAT5_ALT1_IPU2_DISP0_DATA05 = 1,
+   IMX_IOMUXC_DISP0_DAT5_ALT2_ECSPI3_SS2 = 2,
+   IMX_IOMUXC_DISP0_DAT5_ALT3_AUD6_RXFS = 3,
+   IMX_IOMUXC_DISP0_DAT5_ALT5_GPIO4_IO26 = 5,
+} IMX_IOMUXC_DISP0_DAT5_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT6_ALT0_IPU1_DISP0_DATA06 = 0,
+   IMX_IOMUXC_DISP0_DAT6_ALT1_IPU2_DISP0_DATA06 = 1,
+   IMX_IOMUXC_DISP0_DAT6_ALT2_ECSPI3_SS3 = 2,
+   IMX_IOMUXC_DISP0_DAT6_ALT3_AUD6_RXC = 3,
+   IMX_IOMUXC_DISP0_DAT6_ALT5_GPIO4_IO27 = 5,
+} IMX_IOMUXC_DISP0_DAT6_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT7_ALT0_IPU1_DISP0_DATA07 = 0,
+   IMX_IOMUXC_DISP0_DAT7_ALT1_IPU2_DISP0_DATA07 = 1,
+   IMX_IOMUXC_DISP0_DAT7_ALT2_ECSPI3_RDY = 2,
+   IMX_IOMUXC_DISP0_DAT7_ALT5_GPIO4_IO28 = 5,
+} IMX_IOMUXC_DISP0_DAT7_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT8_ALT0_IPU1_DISP0_DATA08 = 0,
+   IMX_IOMUXC_DISP0_DAT8_ALT1_IPU2_DISP0_DATA08 = 1,
+   IMX_IOMUXC_DISP0_DAT8_ALT2_PWM1_OUT = 2,
+   IMX_IOMUXC_DISP0_DAT8_ALT3_WDOG1_B = 3,
+   IMX_IOMUXC_DISP0_DAT8_ALT5_GPIO4_IO29 = 5,
+} IMX_IOMUXC_DISP0_DAT8_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT9_ALT0_IPU1_DISP0_DATA09 = 0,
+   IMX_IOMUXC_DISP0_DAT9_ALT1_IPU2_DISP0_DATA09 = 1,
+   IMX_IOMUXC_DISP0_DAT9_ALT2_PWM2_OUT = 2,
+   IMX_IOMUXC_DISP0_DAT9_ALT3_WDOG2_B = 3,
+   IMX_IOMUXC_DISP0_DAT9_ALT5_GPIO4_IO30 = 5,
+} IMX_IOMUXC_DISP0_DAT9_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT10_ALT0_IPU1_DISP0_DATA10 = 0,
+   IMX_IOMUXC_DISP0_DAT10_ALT1_IPU2_DISP0_DATA10 = 1,
+   IMX_IOMUXC_DISP0_DAT10_ALT5_GPIO4_IO31 = 5,
+} IMX_IOMUXC_DISP0_DAT10_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_WAIT_ALT0_EIM_WAIT_B = 0,
+   IMX_IOMUXC_EIM_WAIT_ALT1_EIM_DTACK_B = 1,
+   IMX_IOMUXC_EIM_WAIT_ALT5_GPIO5_IO00 = 5,
+   IMX_IOMUXC_EIM_WAIT_ALT7_SRC_BOOT_CFG25 = 7,
+} IMX_IOMUXC_EIM_WAIT_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A25_ALT0_EIM_ADDR25 = 0,
+   IMX_IOMUXC_EIM_A25_ALT1_ECSPI4_SS1 = 1,
+   IMX_IOMUXC_EIM_A25_ALT2_ECSPI2_RDY = 2,
+   IMX_IOMUXC_EIM_A25_ALT3_IPU1_DI1_PIN12 = 3,
+   IMX_IOMUXC_EIM_A25_ALT4_IPU1_DI0_D1_CS = 4,
+   IMX_IOMUXC_EIM_A25_ALT5_GPIO5_IO02 = 5,
+   IMX_IOMUXC_EIM_A25_ALT6_HDMI_TX_CEC_LINE = 6,
+} IMX_IOMUXC_EIM_A25_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A24_ALT0_EIM_ADDR24 = 0,
+   IMX_IOMUXC_EIM_A24_ALT1_IPU1_DISP1_DATA19 = 1,
+   IMX_IOMUXC_EIM_A24_ALT2_IPU2_CSI1_DATA19 = 2,
+   IMX_IOMUXC_EIM_A24_ALT3_IPU2_SISG2 = 3,
+   IMX_IOMUXC_EIM_A24_ALT4_IPU1_SISG2 = 4,
+   IMX_IOMUXC_EIM_A24_ALT5_GPIO5_IO04 = 5,
+   IMX_IOMUXC_EIM_A24_ALT7_SRC_BOOT_CFG24 = 7,
+} IMX_IOMUXC_EIM_A24_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT11_ALT0_IPU1_DISP0_DATA11 = 0,
+   IMX_IOMUXC_DISP0_DAT11_ALT1_IPU2_DISP0_DATA11 = 1,
+   IMX_IOMUXC_DISP0_DAT11_ALT5_GPIO5_IO05 = 5,
+} IMX_IOMUXC_DISP0_DAT11_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT12_ALT0_IPU1_DISP0_DATA12 = 0,
+   IMX_IOMUXC_DISP0_DAT12_ALT1_IPU2_DISP0_DATA12 = 1,
+   IMX_IOMUXC_DISP0_DAT12_ALT5_GPIO5_IO06 = 5,
+} IMX_IOMUXC_DISP0_DAT12_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT13_ALT0_IPU1_DISP0_DATA13 = 0,
+   IMX_IOMUXC_DISP0_DAT13_ALT1_IPU2_DISP0_DATA13 = 1,
+   IMX_IOMUXC_DISP0_DAT13_ALT3_AUD5_RXFS = 3,
+   IMX_IOMUXC_DISP0_DAT13_ALT5_GPIO5_IO07 = 5,
+} IMX_IOMUXC_DISP0_DAT13_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT14_ALT0_IPU1_DISP0_DATA14 = 0,
+   IMX_IOMUXC_DISP0_DAT14_ALT1_IPU2_DISP0_DATA14 = 1,
+   IMX_IOMUXC_DISP0_DAT14_ALT3_AUD5_RXC = 3,
+   IMX_IOMUXC_DISP0_DAT14_ALT5_GPIO5_IO08 = 5,
+} IMX_IOMUXC_DISP0_DAT14_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT15_ALT0_IPU1_DISP0_DATA15 = 0,
+   IMX_IOMUXC_DISP0_DAT15_ALT1_IPU2_DISP0_DATA15 = 1,
+   IMX_IOMUXC_DISP0_DAT15_ALT2_ECSPI1_SS1 = 2,
+   IMX_IOMUXC_DISP0_DAT15_ALT3_ECSPI2_SS1 = 3,
+   IMX_IOMUXC_DISP0_DAT15_ALT5_GPIO5_IO09 = 5,
+} IMX_IOMUXC_DISP0_DAT15_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT16_ALT0_IPU1_DISP0_DATA16 = 0,
+   IMX_IOMUXC_DISP0_DAT16_ALT1_IPU2_DISP0_DATA16 = 1,
+   IMX_IOMUXC_DISP0_DAT16_ALT2_ECSPI2_MOSI = 2,
+   IMX_IOMUXC_DISP0_DAT16_ALT3_AUD5_TXC = 3,
+   IMX_IOMUXC_DISP0_DAT16_ALT4_SDMA_EXT_EVENT0 = 4,
+   IMX_IOMUXC_DISP0_DAT16_ALT5_GPIO5_IO10 = 5,
+} IMX_IOMUXC_DISP0_DAT16_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT17_ALT0_IPU1_DISP0_DATA17 = 0,
+   IMX_IOMUXC_DISP0_DAT17_ALT1_IPU2_DISP0_DATA17 = 1,
+   IMX_IOMUXC_DISP0_DAT17_ALT2_ECSPI2_MISO = 2,
+   IMX_IOMUXC_DISP0_DAT17_ALT3_AUD5_TXD = 3,
+   IMX_IOMUXC_DISP0_DAT17_ALT4_SDMA_EXT_EVENT1 = 4,
+   IMX_IOMUXC_DISP0_DAT17_ALT5_GPIO5_IO11 = 5,
+} IMX_IOMUXC_DISP0_DAT17_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT18_ALT0_IPU1_DISP0_DATA18 = 0,
+   IMX_IOMUXC_DISP0_DAT18_ALT1_IPU2_DISP0_DATA18 = 1,
+   IMX_IOMUXC_DISP0_DAT18_ALT2_ECSPI2_SS0 = 2,
+   IMX_IOMUXC_DISP0_DAT18_ALT3_AUD5_TXFS = 3,
+   IMX_IOMUXC_DISP0_DAT18_ALT4_AUD4_RXFS = 4,
+   IMX_IOMUXC_DISP0_DAT18_ALT5_GPIO5_IO12 = 5,
+   IMX_IOMUXC_DISP0_DAT18_ALT7_EIM_CS2_B = 7,
+} IMX_IOMUXC_DISP0_DAT18_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT19_ALT0_IPU1_DISP0_DATA19 = 0,
+   IMX_IOMUXC_DISP0_DAT19_ALT1_IPU2_DISP0_DATA19 = 1,
+   IMX_IOMUXC_DISP0_DAT19_ALT2_ECSPI2_SCLK = 2,
+   IMX_IOMUXC_DISP0_DAT19_ALT3_AUD5_RXD = 3,
+   IMX_IOMUXC_DISP0_DAT19_ALT4_AUD4_RXC = 4,
+   IMX_IOMUXC_DISP0_DAT19_ALT5_GPIO5_IO13 = 5,
+   IMX_IOMUXC_DISP0_DAT19_ALT7_EIM_CS3_B = 7,
+} IMX_IOMUXC_DISP0_DAT19_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT20_ALT0_IPU1_DISP0_DATA20 = 0,
+   IMX_IOMUXC_DISP0_DAT20_ALT1_IPU2_DISP0_DATA20 = 1,
+   IMX_IOMUXC_DISP0_DAT20_ALT2_ECSPI1_SCLK = 2,
+   IMX_IOMUXC_DISP0_DAT20_ALT3_AUD4_TXC = 3,
+   IMX_IOMUXC_DISP0_DAT20_ALT5_GPIO5_IO14 = 5,
+} IMX_IOMUXC_DISP0_DAT20_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT21_ALT0_IPU1_DISP0_DATA21 = 0,
+   IMX_IOMUXC_DISP0_DAT21_ALT1_IPU2_DISP0_DATA21 = 1,
+   IMX_IOMUXC_DISP0_DAT21_ALT2_ECSPI1_MOSI = 2,
+   IMX_IOMUXC_DISP0_DAT21_ALT3_AUD4_TXD = 3,
+   IMX_IOMUXC_DISP0_DAT21_ALT5_GPIO5_IO15 = 5,
+} IMX_IOMUXC_DISP0_DAT21_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT22_ALT0_IPU1_DISP0_DATA22 = 0,
+   IMX_IOMUXC_DISP0_DAT22_ALT1_IPU2_DISP0_DATA22 = 1,
+   IMX_IOMUXC_DISP0_DAT22_ALT2_ECSPI1_MISO = 2,
+   IMX_IOMUXC_DISP0_DAT22_ALT3_AUD4_TXFS = 3,
+   IMX_IOMUXC_DISP0_DAT22_ALT5_GPIO5_IO16 = 5,
+} IMX_IOMUXC_DISP0_DAT22_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT23_ALT0_IPU1_DISP0_DATA23 = 0,
+   IMX_IOMUXC_DISP0_DAT23_ALT1_IPU2_DISP0_DATA23 = 1,
+   IMX_IOMUXC_DISP0_DAT23_ALT2_ECSPI1_SS0 = 2,
+   IMX_IOMUXC_DISP0_DAT23_ALT3_AUD4_RXD = 3,
+   IMX_IOMUXC_DISP0_DAT23_ALT5_GPIO5_IO17 = 5,
+} IMX_IOMUXC_DISP0_DAT23_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_PIXCLK_ALT0_IPU1_CSI0_PIXCLK = 0,
+   IMX_IOMUXC_CSI0_PIXCLK_ALT5_GPIO5_IO18 = 5,
+   IMX_IOMUXC_CSI0_PIXCLK_ALT7_ARM_EVENTO = 7,
+} IMX_IOMUXC_CSI0_PIXCLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_MCLK_ALT0_IPU1_CSI0_HSYNC = 0,
+   IMX_IOMUXC_CSI0_MCLK_ALT3_CCM_CLKO1 = 3,
+   IMX_IOMUXC_CSI0_MCLK_ALT5_GPIO5_IO19 = 5,
+   IMX_IOMUXC_CSI0_MCLK_ALT7_ARM_TRACE_CTL = 7,
+} IMX_IOMUXC_CSI0_MCLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DATA_EN_ALT0_IPU1_CSI0_DATA_EN = 0,
+   IMX_IOMUXC_CSI0_DATA_EN_ALT1_EIM_DATA00 = 1,
+   IMX_IOMUXC_CSI0_DATA_EN_ALT5_GPIO5_IO20 = 5,
+   IMX_IOMUXC_CSI0_DATA_EN_ALT7_ARM_TRACE_CLK = 7,
+} IMX_IOMUXC_CSI0_DATA_EN_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_VSYNC_ALT0_IPU1_CSI0_VSYNC = 0,
+   IMX_IOMUXC_CSI0_VSYNC_ALT1_EIM_DATA01 = 1,
+   IMX_IOMUXC_CSI0_VSYNC_ALT5_GPIO5_IO21 = 5,
+   IMX_IOMUXC_CSI0_VSYNC_ALT7_ARM_TRACE00 = 7,
+} IMX_IOMUXC_CSI0_VSYNC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT4_ALT0_IPU1_CSI0_DATA04 = 0,
+   IMX_IOMUXC_CSI0_DAT4_ALT1_EIM_DATA02 = 1,
+   IMX_IOMUXC_CSI0_DAT4_ALT2_ECSPI1_SCLK = 2,
+   IMX_IOMUXC_CSI0_DAT4_ALT3_KEY_COL5 = 3,
+   IMX_IOMUXC_CSI0_DAT4_ALT4_AUD3_TXC = 4,
+   IMX_IOMUXC_CSI0_DAT4_ALT5_GPIO5_IO22 = 5,
+   IMX_IOMUXC_CSI0_DAT4_ALT7_ARM_TRACE01 = 7,
+} IMX_IOMUXC_CSI0_DAT4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT5_ALT0_IPU1_CSI0_DATA05 = 0,
+   IMX_IOMUXC_CSI0_DAT5_ALT1_EIM_DATA03 = 1,
+   IMX_IOMUXC_CSI0_DAT5_ALT2_ECSPI1_MOSI = 2,
+   IMX_IOMUXC_CSI0_DAT5_ALT3_KEY_ROW5 = 3,
+   IMX_IOMUXC_CSI0_DAT5_ALT4_AUD3_TXD = 4,
+   IMX_IOMUXC_CSI0_DAT5_ALT5_GPIO5_IO23 = 5,
+   IMX_IOMUXC_CSI0_DAT5_ALT7_ARM_TRACE02 = 7,
+} IMX_IOMUXC_CSI0_DAT5_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT6_ALT0_IPU1_CSI0_DATA06 = 0,
+   IMX_IOMUXC_CSI0_DAT6_ALT1_EIM_DATA04 = 1,
+   IMX_IOMUXC_CSI0_DAT6_ALT2_ECSPI1_MISO = 2,
+   IMX_IOMUXC_CSI0_DAT6_ALT3_KEY_COL6 = 3,
+   IMX_IOMUXC_CSI0_DAT6_ALT4_AUD3_TXFS = 4,
+   IMX_IOMUXC_CSI0_DAT6_ALT5_GPIO5_IO24 = 5,
+   IMX_IOMUXC_CSI0_DAT6_ALT7_ARM_TRACE03 = 7,
+} IMX_IOMUXC_CSI0_DAT6_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT7_ALT0_IPU1_CSI0_DATA07 = 0,
+   IMX_IOMUXC_CSI0_DAT7_ALT1_EIM_DATA05 = 1,
+   IMX_IOMUXC_CSI0_DAT7_ALT2_ECSPI1_SS0 = 2,
+   IMX_IOMUXC_CSI0_DAT7_ALT3_KEY_ROW6 = 3,
+   IMX_IOMUXC_CSI0_DAT7_ALT4_AUD3_RXD = 4,
+   IMX_IOMUXC_CSI0_DAT7_ALT5_GPIO5_IO25 = 5,
+   IMX_IOMUXC_CSI0_DAT7_ALT7_ARM_TRACE04 = 7,
+} IMX_IOMUXC_CSI0_DAT7_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT8_ALT0_IPU1_CSI0_DATA08 = 0,
+   IMX_IOMUXC_CSI0_DAT8_ALT1_EIM_DATA06 = 1,
+   IMX_IOMUXC_CSI0_DAT8_ALT2_ECSPI2_SCLK = 2,
+   IMX_IOMUXC_CSI0_DAT8_ALT3_KEY_COL7 = 3,
+   IMX_IOMUXC_CSI0_DAT8_ALT4_I2C1_SDA = 4,
+   IMX_IOMUXC_CSI0_DAT8_ALT5_GPIO5_IO26 = 5,
+   IMX_IOMUXC_CSI0_DAT8_ALT7_ARM_TRACE05 = 7,
+} IMX_IOMUXC_CSI0_DAT8_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT9_ALT0_IPU1_CSI0_DATA09 = 0,
+   IMX_IOMUXC_CSI0_DAT9_ALT1_EIM_DATA07 = 1,
+   IMX_IOMUXC_CSI0_DAT9_ALT2_ECSPI2_MOSI = 2,
+   IMX_IOMUXC_CSI0_DAT9_ALT3_KEY_ROW7 = 3,
+   IMX_IOMUXC_CSI0_DAT9_ALT4_I2C1_SCL = 4,
+   IMX_IOMUXC_CSI0_DAT9_ALT5_GPIO5_IO27 = 5,
+   IMX_IOMUXC_CSI0_DAT9_ALT7_ARM_TRACE06 = 7,
+} IMX_IOMUXC_CSI0_DAT9_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT10_ALT0_IPU1_CSI0_DATA10 = 0,
+   IMX_IOMUXC_CSI0_DAT10_ALT1_AUD3_RXC = 1,
+   IMX_IOMUXC_CSI0_DAT10_ALT2_ECSPI2_MISO = 2,
+   IMX_IOMUXC_CSI0_DAT10_ALT3_UART1_TX_DATA = 3,
+   IMX_IOMUXC_CSI0_DAT10_ALT5_GPIO5_IO28 = 5,
+   IMX_IOMUXC_CSI0_DAT10_ALT7_ARM_TRACE07 = 7,
+} IMX_IOMUXC_CSI0_DAT10_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT11_ALT0_IPU1_CSI0_DATA11 = 0,
+   IMX_IOMUXC_CSI0_DAT11_ALT1_AUD3_RXFS = 1,
+   IMX_IOMUXC_CSI0_DAT11_ALT2_ECSPI2_SS0 = 2,
+   IMX_IOMUXC_CSI0_DAT11_ALT3_UART1_RX_DATA = 3,
+   IMX_IOMUXC_CSI0_DAT11_ALT5_GPIO5_IO29 = 5,
+   IMX_IOMUXC_CSI0_DAT11_ALT7_ARM_TRACE08 = 7,
+} IMX_IOMUXC_CSI0_DAT11_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT12_ALT0_IPU1_CSI0_DATA12 = 0,
+   IMX_IOMUXC_CSI0_DAT12_ALT1_EIM_DATA08 = 1,
+   IMX_IOMUXC_CSI0_DAT12_ALT3_UART4_TX_DATA = 3,
+   IMX_IOMUXC_CSI0_DAT12_ALT5_GPIO5_IO30 = 5,
+   IMX_IOMUXC_CSI0_DAT12_ALT7_ARM_TRACE09 = 7,
+} IMX_IOMUXC_CSI0_DAT12_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT13_ALT0_IPU1_CSI0_DATA13 = 0,
+   IMX_IOMUXC_CSI0_DAT13_ALT1_EIM_DATA09 = 1,
+   IMX_IOMUXC_CSI0_DAT13_ALT3_UART4_RX_DATA = 3,
+   IMX_IOMUXC_CSI0_DAT13_ALT5_GPIO5_IO31 = 5,
+   IMX_IOMUXC_CSI0_DAT13_ALT7_ARM_TRACE10 = 7,
+} IMX_IOMUXC_CSI0_DAT13_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT14_ALT0_IPU1_CSI0_DATA14 = 0,
+   IMX_IOMUXC_CSI0_DAT14_ALT1_EIM_DATA10 = 1,
+   IMX_IOMUXC_CSI0_DAT14_ALT3_UART5_TX_DATA = 3,
+   IMX_IOMUXC_CSI0_DAT14_ALT5_GPIO6_IO00 = 5,
+   IMX_IOMUXC_CSI0_DAT14_ALT7_ARM_TRACE11 = 7,
+} IMX_IOMUXC_CSI0_DAT14_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT15_ALT0_IPU1_CSI0_DATA15 = 0,
+   IMX_IOMUXC_CSI0_DAT15_ALT1_EIM_DATA11 = 1,
+   IMX_IOMUXC_CSI0_DAT15_ALT3_UART5_RX_DATA = 3,
+   IMX_IOMUXC_CSI0_DAT15_ALT5_GPIO6_IO01 = 5,
+   IMX_IOMUXC_CSI0_DAT15_ALT7_ARM_TRACE12 = 7,
+} IMX_IOMUXC_CSI0_DAT15_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT16_ALT0_IPU1_CSI0_DATA16 = 0,
+   IMX_IOMUXC_CSI0_DAT16_ALT1_EIM_DATA12 = 1,
+   IMX_IOMUXC_CSI0_DAT16_ALT3_UART4_RTS_B = 3,
+   IMX_IOMUXC_CSI0_DAT16_ALT5_GPIO6_IO02 = 5,
+   IMX_IOMUXC_CSI0_DAT16_ALT7_ARM_TRACE13 = 7,
+} IMX_IOMUXC_CSI0_DAT16_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT17_ALT0_IPU1_CSI0_DATA17 = 0,
+   IMX_IOMUXC_CSI0_DAT17_ALT1_EIM_DATA13 = 1,
+   IMX_IOMUXC_CSI0_DAT17_ALT3_UART4_CTS_B = 3,
+   IMX_IOMUXC_CSI0_DAT17_ALT5_GPIO6_IO03 = 5,
+   IMX_IOMUXC_CSI0_DAT17_ALT7_ARM_TRACE14 = 7,
+} IMX_IOMUXC_CSI0_DAT17_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT18_ALT0_IPU1_CSI0_DATA18 = 0,
+   IMX_IOMUXC_CSI0_DAT18_ALT1_EIM_DATA14 = 1,
+   IMX_IOMUXC_CSI0_DAT18_ALT3_UART5_RTS_B = 3,
+   IMX_IOMUXC_CSI0_DAT18_ALT5_GPIO6_IO04 = 5,
+   IMX_IOMUXC_CSI0_DAT18_ALT7_ARM_TRACE15 = 7,
+} IMX_IOMUXC_CSI0_DAT18_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT19_ALT0_IPU1_CSI0_DATA19 = 0,
+   IMX_IOMUXC_CSI0_DAT19_ALT1_EIM_DATA15 = 1,
+   IMX_IOMUXC_CSI0_DAT19_ALT3_UART5_CTS_B = 3,
+   IMX_IOMUXC_CSI0_DAT19_ALT5_GPIO6_IO05 = 5,
+} IMX_IOMUXC_CSI0_DAT19_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A23_ALT0_EIM_ADDR23 = 0,
+   IMX_IOMUXC_EIM_A23_ALT1_IPU1_DISP1_DATA18 = 1,
+   IMX_IOMUXC_EIM_A23_ALT2_IPU2_CSI1_DATA18 = 2,
+   IMX_IOMUXC_EIM_A23_ALT3_IPU2_SISG3 = 3,
+   IMX_IOMUXC_EIM_A23_ALT4_IPU1_SISG3 = 4,
+   IMX_IOMUXC_EIM_A23_ALT5_GPIO6_IO06 = 5,
+   IMX_IOMUXC_EIM_A23_ALT7_SRC_BOOT_CFG23 = 7,
+} IMX_IOMUXC_EIM_A23_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_CLE_ALT0_NAND_CLE = 0,
+   IMX_IOMUXC_NANDF_CLE_ALT1_IPU2_SISG4 = 1,
+   IMX_IOMUXC_NANDF_CLE_ALT5_GPIO6_IO07 = 5,
+} IMX_IOMUXC_NANDF_CLE_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_ALE_ALT0_NAND_ALE = 0,
+   IMX_IOMUXC_NANDF_ALE_ALT1_SD4_RESET = 1,
+   IMX_IOMUXC_NANDF_ALE_ALT5_GPIO6_IO08 = 5,
+} IMX_IOMUXC_NANDF_ALE_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_WP_B_ALT0_NAND_WP_B = 0,
+   IMX_IOMUXC_NANDF_WP_B_ALT1_IPU2_SISG5 = 1,
+   IMX_IOMUXC_NANDF_WP_B_ALT5_GPIO6_IO09 = 5,
+} IMX_IOMUXC_NANDF_WP_B_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_RB0_ALT0_NAND_READY_B = 0,
+   IMX_IOMUXC_NANDF_RB0_ALT1_IPU2_DI0_PIN01 = 1,
+   IMX_IOMUXC_NANDF_RB0_ALT5_GPIO6_IO10 = 5,
+} IMX_IOMUXC_NANDF_RB0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_CS0_ALT0_NAND_CE0_B = 0,
+   IMX_IOMUXC_NANDF_CS0_ALT5_GPIO6_IO11 = 5,
+} IMX_IOMUXC_NANDF_CS0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_CS1_ALT0_NAND_CE1_B = 0,
+   IMX_IOMUXC_NANDF_CS1_ALT1_SD4_VSELECT = 1,
+   IMX_IOMUXC_NANDF_CS1_ALT2_SD3_VSELECT = 2,
+   IMX_IOMUXC_NANDF_CS1_ALT5_GPIO6_IO14 = 5,
+} IMX_IOMUXC_NANDF_CS1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_CS2_ALT0_NAND_CE2_B = 0,
+   IMX_IOMUXC_NANDF_CS2_ALT1_IPU1_SISG0 = 1,
+   IMX_IOMUXC_NANDF_CS2_ALT2_ESAI_TX0 = 2,
+   IMX_IOMUXC_NANDF_CS2_ALT3_EIM_CRE = 3,
+   IMX_IOMUXC_NANDF_CS2_ALT4_CCM_CLKO2 = 4,
+   IMX_IOMUXC_NANDF_CS2_ALT5_GPIO6_IO15 = 5,
+   IMX_IOMUXC_NANDF_CS2_ALT6_IPU2_SISG0 = 6,
+} IMX_IOMUXC_NANDF_CS2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_CS3_ALT0_NAND_CE3_B = 0,
+   IMX_IOMUXC_NANDF_CS3_ALT1_IPU1_SISG1 = 1,
+   IMX_IOMUXC_NANDF_CS3_ALT2_ESAI_TX1 = 2,
+   IMX_IOMUXC_NANDF_CS3_ALT3_EIM_ADDR26 = 3,
+   IMX_IOMUXC_NANDF_CS3_ALT5_GPIO6_IO16 = 5,
+   IMX_IOMUXC_NANDF_CS3_ALT6_IPU2_SISG1 = 6,
+} IMX_IOMUXC_NANDF_CS3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DAT7_ALT0_SD3_DATA7 = 0,
+   IMX_IOMUXC_SD3_DAT7_ALT1_UART1_TX_DATA = 1,
+   IMX_IOMUXC_SD3_DAT7_ALT5_GPIO6_IO17 = 5,
+} IMX_IOMUXC_SD3_DAT7_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DAT6_ALT0_SD3_DATA6 = 0,
+   IMX_IOMUXC_SD3_DAT6_ALT1_UART1_RX_DATA = 1,
+   IMX_IOMUXC_SD3_DAT6_ALT5_GPIO6_IO18 = 5,
+} IMX_IOMUXC_SD3_DAT6_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_TXC_ALT0_USB_H2_DATA = 0,
+   IMX_IOMUXC_RGMII_TXC_ALT1_RGMII_TXC = 1,
+   IMX_IOMUXC_RGMII_TXC_ALT2_SPDIF_EXT_CLK = 2,
+   IMX_IOMUXC_RGMII_TXC_ALT5_GPIO6_IO19 = 5,
+   IMX_IOMUXC_RGMII_TXC_ALT7_XTALOSC_REF_CLK_24M = 7,
+} IMX_IOMUXC_RGMII_TXC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_TD0_ALT0_HSI_TX_READY = 0,
+   IMX_IOMUXC_RGMII_TD0_ALT1_RGMII_TD0 = 1,
+   IMX_IOMUXC_RGMII_TD0_ALT5_GPIO6_IO20 = 5,
+} IMX_IOMUXC_RGMII_TD0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_TD1_ALT0_HSI_RX_FLAG = 0,
+   IMX_IOMUXC_RGMII_TD1_ALT1_RGMII_TD1 = 1,
+   IMX_IOMUXC_RGMII_TD1_ALT5_GPIO6_IO21 = 5,
+} IMX_IOMUXC_RGMII_TD1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_TD2_ALT0_HSI_RX_DATA = 0,
+   IMX_IOMUXC_RGMII_TD2_ALT1_RGMII_TD2 = 1,
+   IMX_IOMUXC_RGMII_TD2_ALT5_GPIO6_IO22 = 5,
+} IMX_IOMUXC_RGMII_TD2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_TD3_ALT0_HSI_RX_WAKE = 0,
+   IMX_IOMUXC_RGMII_TD3_ALT1_RGMII_TD3 = 1,
+   IMX_IOMUXC_RGMII_TD3_ALT5_GPIO6_IO23 = 5,
+} IMX_IOMUXC_RGMII_TD3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_RX_CTL_ALT0_USB_H3_DATA = 0,
+   IMX_IOMUXC_RGMII_RX_CTL_ALT1_RGMII_RX_CTL = 1,
+   IMX_IOMUXC_RGMII_RX_CTL_ALT5_GPIO6_IO24 = 5,
+} IMX_IOMUXC_RGMII_RX_CTL_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_RD0_ALT0_HSI_RX_READY = 0,
+   IMX_IOMUXC_RGMII_RD0_ALT1_RGMII_RD0 = 1,
+   IMX_IOMUXC_RGMII_RD0_ALT5_GPIO6_IO25 = 5,
+} IMX_IOMUXC_RGMII_RD0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_TX_CTL_ALT0_USB_H2_STROBE = 0,
+   IMX_IOMUXC_RGMII_TX_CTL_ALT1_RGMII_TX_CTL = 1,
+   IMX_IOMUXC_RGMII_TX_CTL_ALT5_GPIO6_IO26 = 5,
+   IMX_IOMUXC_RGMII_TX_CTL_ALT7_ENET_REF_CLK = 7,
+} IMX_IOMUXC_RGMII_TX_CTL_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_RD1_ALT0_HSI_TX_FLAG = 0,
+   IMX_IOMUXC_RGMII_RD1_ALT1_RGMII_RD1 = 1,
+   IMX_IOMUXC_RGMII_RD1_ALT5_GPIO6_IO27 = 5,
+} IMX_IOMUXC_RGMII_RD1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_RD2_ALT0_HSI_TX_DATA = 0,
+   IMX_IOMUXC_RGMII_RD2_ALT1_RGMII_RD2 = 1,
+   IMX_IOMUXC_RGMII_RD2_ALT5_GPIO6_IO28 = 5,
+} IMX_IOMUXC_RGMII_RD2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_RD3_ALT0_HSI_TX_WAKE = 0,
+   IMX_IOMUXC_RGMII_RD3_ALT1_RGMII_RD3 = 1,
+   IMX_IOMUXC_RGMII_RD3_ALT5_GPIO6_IO29 = 5,
+} IMX_IOMUXC_RGMII_RD3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_RXC_ALT0_USB_H3_STROBE = 0,
+   IMX_IOMUXC_RGMII_RXC_ALT1_RGMII_RXC = 1,
+   IMX_IOMUXC_RGMII_RXC_ALT5_GPIO6_IO30 = 5,
+} IMX_IOMUXC_RGMII_RXC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_BCLK_ALT0_EIM_BCLK = 0,
+   IMX_IOMUXC_EIM_BCLK_ALT1_IPU1_DI1_PIN16 = 1,
+   IMX_IOMUXC_EIM_BCLK_ALT5_GPIO6_IO31 = 5,
+} IMX_IOMUXC_EIM_BCLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DAT5_ALT0_SD3_DATA5 = 0,
+   IMX_IOMUXC_SD3_DAT5_ALT1_UART2_TX_DATA = 1,
+   IMX_IOMUXC_SD3_DAT5_ALT5_GPIO7_IO00 = 5,
+} IMX_IOMUXC_SD3_DAT5_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DAT4_ALT0_SD3_DATA4 = 0,
+   IMX_IOMUXC_SD3_DAT4_ALT1_UART2_RX_DATA = 1,
+   IMX_IOMUXC_SD3_DAT4_ALT5_GPIO7_IO01 = 5,
+} IMX_IOMUXC_SD3_DAT4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_CMD_ALT0_SD3_CMD = 0,
+   IMX_IOMUXC_SD3_CMD_ALT1_UART2_CTS_B = 1,
+   IMX_IOMUXC_SD3_CMD_ALT2_FLEXCAN1_TX = 2,
+   IMX_IOMUXC_SD3_CMD_ALT5_GPIO7_IO02 = 5,
+} IMX_IOMUXC_SD3_CMD_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_CLK_ALT0_SD3_CLK = 0,
+   IMX_IOMUXC_SD3_CLK_ALT1_UART2_RTS_B = 1,
+   IMX_IOMUXC_SD3_CLK_ALT2_FLEXCAN1_RX = 2,
+   IMX_IOMUXC_SD3_CLK_ALT5_GPIO7_IO03 = 5,
+} IMX_IOMUXC_SD3_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DAT0_ALT0_SD3_DATA0 = 0,
+   IMX_IOMUXC_SD3_DAT0_ALT1_UART1_CTS_B = 1,
+   IMX_IOMUXC_SD3_DAT0_ALT2_FLEXCAN2_TX = 2,
+   IMX_IOMUXC_SD3_DAT0_ALT5_GPIO7_IO04 = 5,
+} IMX_IOMUXC_SD3_DAT0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DAT1_ALT0_SD3_DATA1 = 0,
+   IMX_IOMUXC_SD3_DAT1_ALT1_UART1_RTS_B = 1,
+   IMX_IOMUXC_SD3_DAT1_ALT2_FLEXCAN2_RX = 2,
+   IMX_IOMUXC_SD3_DAT1_ALT5_GPIO7_IO05 = 5,
+} IMX_IOMUXC_SD3_DAT1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DAT2_ALT0_SD3_DATA2 = 0,
+   IMX_IOMUXC_SD3_DAT2_ALT5_GPIO7_IO06 = 5,
+} IMX_IOMUXC_SD3_DAT2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DAT3_ALT0_SD3_DATA3 = 0,
+   IMX_IOMUXC_SD3_DAT3_ALT1_UART3_CTS_B = 1,
+   IMX_IOMUXC_SD3_DAT3_ALT5_GPIO7_IO07 = 5,
+} IMX_IOMUXC_SD3_DAT3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_RST_ALT0_SD3_RESET = 0,
+   IMX_IOMUXC_SD3_RST_ALT1_UART3_RTS_B = 1,
+   IMX_IOMUXC_SD3_RST_ALT5_GPIO7_IO08 = 5,
+} IMX_IOMUXC_SD3_RST_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_CMD_ALT0_SD4_CMD = 0,
+   IMX_IOMUXC_SD4_CMD_ALT1_NAND_RE_B = 1,
+   IMX_IOMUXC_SD4_CMD_ALT2_UART3_TX_DATA = 2,
+   IMX_IOMUXC_SD4_CMD_ALT5_GPIO7_IO09 = 5,
+} IMX_IOMUXC_SD4_CMD_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_CLK_ALT0_SD4_CLK = 0,
+   IMX_IOMUXC_SD4_CLK_ALT1_NAND_WE_B = 1,
+   IMX_IOMUXC_SD4_CLK_ALT2_UART3_RX_DATA = 2,
+   IMX_IOMUXC_SD4_CLK_ALT5_GPIO7_IO10 = 5,
+} IMX_IOMUXC_SD4_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_16_ALT0_ESAI_TX3_RX2 = 0,
+   IMX_IOMUXC_GPIO_16_ALT1_ENET_1588_EVENT2_IN = 1,
+   IMX_IOMUXC_GPIO_16_ALT2_ENET_REF_CLK = 2,
+   IMX_IOMUXC_GPIO_16_ALT3_SD1_LCTL = 3,
+   IMX_IOMUXC_GPIO_16_ALT4_SPDIF_IN = 4,
+   IMX_IOMUXC_GPIO_16_ALT5_GPIO7_IO11 = 5,
+   IMX_IOMUXC_GPIO_16_ALT6_I2C3_SDA = 6,
+   IMX_IOMUXC_GPIO_16_ALT7_JTAG_DE_B = 7,
+} IMX_IOMUXC_GPIO_16_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_17_ALT0_ESAI_TX0 = 0,
+   IMX_IOMUXC_GPIO_17_ALT1_ENET_1588_EVENT3_IN = 1,
+   IMX_IOMUXC_GPIO_17_ALT2_CCM_PMIC_READY = 2,
+   IMX_IOMUXC_GPIO_17_ALT3_SDMA_EXT_EVENT0 = 3,
+   IMX_IOMUXC_GPIO_17_ALT4_SPDIF_OUT = 4,
+   IMX_IOMUXC_GPIO_17_ALT5_GPIO7_IO12 = 5,
+} IMX_IOMUXC_GPIO_17_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_18_ALT0_ESAI_TX1 = 0,
+   IMX_IOMUXC_GPIO_18_ALT1_ENET_RX_CLK = 1,
+   IMX_IOMUXC_GPIO_18_ALT2_SD3_VSELECT = 2,
+   IMX_IOMUXC_GPIO_18_ALT3_SDMA_EXT_EVENT1 = 3,
+   IMX_IOMUXC_GPIO_18_ALT4_ASRC_EXT_CLK = 4,
+   IMX_IOMUXC_GPIO_18_ALT5_GPIO7_IO13 = 5,
+   IMX_IOMUXC_GPIO_18_ALT6_SNVS_VIO_5_CTL = 6,
+} IMX_IOMUXC_GPIO_18_ALT;
+
+typedef enum {
+    IMX_IOMUXC_ECSPI1_MISO_EIM_DATA17_ALT1 = 0,
+    IMX_IOMUXC_ECSPI1_MISO_DISP0_DATA22_ALT2 = 1,
+    IMX_IOMUXC_ECSPI1_MISO_KEY_COL1_ALT0 = 2,
+    IMX_IOMUXC_ECSPI1_MISO_CSI0_DATA06_ALT2 = 3,
+} IMX_IOMUXC_ECSPI1_MISO_SELECT_INPUT;
+
+typedef enum {
+    IMX_IOMUXC_ECSPI2_MISO_EIM_OE_B_ALT2 = 0,
+    IMX_IOMUXC_ECSPI2_MISO_DISP0_DATA17_ALT2 = 1,
+    IMX_IOMUXC_ECSPI2_MISO_CSI0_DATA10_ALT2 = 2,
+} IMX_IOMUXC_ECSPI2_MISO_SELECT_INPUT;
+
+#endif // _IMX6_IOMUX_DQ_H_
diff --git a/Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_SDL.h b/Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_SDL.h
new file mode 100644
index 000000000000..b8a0379ff811
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_SDL.h
@@ -0,0 +1,2482 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _IMX6_IOMUX_SDL_H_
+#define _IMX6_IOMUX_SDL_H_
+
+//
+// SELECT INPUT defines
+
+#define EIM_DATA21_ALT6 0x0 // Selecting ALT6 mode of pad EIM_D21 for I2C1_SCL
+#define CSI0_DAT9_ALT4 0x1 // Selecting ALT4 mode of pad CSI0_DAT9 for I2C1_SCL
+
+#define EIM_DATA28_ALT1 0x0 // Selecting ALT1 mode of pad EIM_D28 for I2C1_SDA
+#define CSI0_DAT8_ALT4 0x1 // Selecting ALT4 mode of pad CSI0_DAT8 for I2C1_SDA
+
+#define EIM_EB2_B_ALT6 0x0 // Selecting ALT6 mode of pad EIM_EB2 for I2C2_SCL
+#define KEY_COL3_ALT4 0x1 // Selecting ALT4 mode of pad KEY_COL3 for I2C2_SCL
+
+#define EIM_DATA16_ALT6 0x0 // Selecting ALT6 mode of pad EIM_D16 for I2C2_SDA
+#define KEY_ROW3_ALT4 0x1 // Selecting ALT4 mode of pad KEY_ROW3 for I2C2_SDA
+
+#define EIM_DATA17_ALT6 0x0 // Selecting ALT6 mode of pad EIM_D17 for I2C3_SCL
+#define GPIO03_ALT2 0x1 // Selecting ALT2 mode of pad GPIO_3 for I2C3_SCL
+#define GPIO05_ALT6 0x2 // Selecting ALT6 mode of pad GPIO_5 for I2C3_SCL
+
+#define EIM_DATA18_ALT6 0x0 // Selecting ALT6 mode of pad EIM_D18 for I2C3_SDA
+#define GPIO06_ALT2 0x1 // Selecting ALT2 mode of pad GPIO_6 for I2C3_SDA
+#define GPIO16_ALT6 0x2 // Selecting ALT6 mode of pad GPIO_16 for I2C3_SDA
+
+#define ENET_TX_EN_ALT9  0x0 // Selecting ALT9 mode of pad ENET_TX_EN for I2C4_SCL
+#define GPIO07_ALT8      0x1 // Selecting ALT8 mode of pad GPIO_7 for I2C4_SCL
+#define NAND_WP_B_ALT9   0x2 // Selecting ALT9 mode of pad NANDF_WP_B for I2C4_SCL
+
+#define ENET_TX_DATA1_ALT9  0x0 // Selecting ALT9 mode of pad ENET_TXD1 for I2C4_SDA
+#define GPIO08_ALT8         0x1 // Selecting ALT9 mode of pad GPIO_8 for I2C4_SDA
+#define NAND_CS3_B_ALT9     0x2 // Selecting ALT9 mode of pad NANDF_CS3 for I2C4_SDA
+
+#define DISP0_DATA19_ALT3 0
+#define KEY_ROW1_ALT2 1
+
+#define DISP0_DATA17_ALT3 0
+#define KEY_ROW0_ALT2 1
+
+#define DISP0_DATA16_ALT3 0
+#define KEY_COL0_ALT2 1
+
+#define DISP0_DATA18_ALT3 0
+#define KEY_COL1_ALT2 1
+
+#define EIM_DATA21_ALT4 0
+#define KEY_COL4_ALT2 1
+
+#define EIM_DATA30_ALT6 0
+#define GPIO03_ALT6 1
+
+#define RGMII_TX_CTL_ALT7 0
+#define GPIO16_ALT2 1
+
+#define CSI0_DATA10_ALT3 0 // Selecting ALT3 mode of pad CSI0_DAT10 for UART1_TX_DATA.
+#define CSI0_DATA11_ALT3 1 // Selecting ALT3 mode of pad CSI0_DAT11 for UART1_RX_DATA.
+#define SD3_DATA7_ALT1 2 // Selecting ALT1 mode of pad SD3_DAT7 for UART1_TX_DATA.
+#define SD3_DATA6_ALT1 3 // Selecting ALT1 mode of pad SD3_DAT6 for UART1_RX_DATA.
+
+#define EIM_DATA26_ALT4 0 // Selecting ALT4 mode of pad EIM_D26 for UART2_TX_DATA.
+#define EIM_DATA27_ALT4 1 // Selecting ALT4 mode of pad EIM_D27 for UART2_RX_DATA.
+#define GPIO07_ALT4 2 // Selecting ALT4 mode of pad GPIO_7 for UART2_TX_DATA.
+#define GPIO08_ALT4 3 // Selecting ALT4 mode of pad GPIO_8 for UART2_RX_DATA.
+#define SD3_DATA5_ALT1 4 // Selecting ALT1 mode of pad SD3_DAT5 for UART2_TX_DATA.
+#define SD3_DATA4_ALT1 5 // Selecting ALT1 mode of pad SD3_DAT4 for UART2_RX_DATA.
+#define SD4_DATA4_ALT2 6 // Selecting ALT2 mode of pad SD4_DAT4 for UART2_RX_DATA.
+#define SD4_DATA7_ALT2 7 // Selecting ALT2 mode of pad SD4_DAT7 for UART2_TX_DATA.
+
+#define EIM_DATA24_ALT2 0 // Selecting ALT2 mode of pad EIM_D24 for UART3_TX_DATA.
+#define EIM_DATA25_ALT2 1 // Selecting ALT2 mode of pad EIM_D25 for UART3_RX_DATA.
+#define SD4_CMD_ALT2 2 // Selecting ALT2 mode of pad SD4_CMD for UART3_TX_DATA.
+#define SD4_CLK_ALT2 3 // Selecting ALT2 mode of pad SD4_CLK for UART3_RX_DATA.
+
+
+//
+// AUD5 select input register defines.
+//
+typedef enum {
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO00)   IOMUXC_SW_PAD_CTL_PAD_GPIO00 20E05DCh
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO00)       IOMUXC_SW_MUX_CTL_PAD_GPIO00 20E020Ch
+   IMX_PAD_GPIO_0 = _IMX_PAD(0x5DC, 0x20C), // CCM_CLKO1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO01)   IOMUXC_SW_PAD_CTL_PAD_GPIO01 20E05E0h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO01)       IOMUXC_SW_MUX_CTL_PAD_GPIO01 20E0210h
+   IMX_PAD_GPIO_1 = _IMX_PAD(0x5E0, 0x210), // ESAI_RX_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO02)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO02)
+   IMX_PAD_GPIO_2 = _IMX_PAD(0x604, 0x234), // ESAI_TX_FS
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO03)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO03)
+   IMX_PAD_GPIO_3 = _IMX_PAD(0x5FC, 0x22C), // ESAI_RX_HF_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO04)       IOMUXC_SW_PAD_CTL_PAD_GPIO04 20E05FCh
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO04)           IOMUXC_SW_MUX_CTL_PAD_GPIO04 20E022Ch
+   IMX_PAD_GPIO_4 = _IMX_PAD(0x5FC, 0x22C), // ESAI_TX_HF_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO05)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO05)
+   IMX_PAD_GPIO_5 = _IMX_PAD(0x60C, 0x23C), // ESAI_TX2_RX3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO06)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO06)
+   IMX_PAD_GPIO_6 = _IMX_PAD(0x600, 0x230), // ESAI_TX_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO07)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO07)
+   IMX_PAD_GPIO_7 = _IMX_PAD(0x610, 0x240), // ESAI_TX4_RX1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO08)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO08)
+   IMX_PAD_GPIO_8 = _IMX_PAD(0x614, 0x244), // ESAI_TX5_RX0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO09)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO09)
+   IMX_PAD_GPIO_9 = _IMX_PAD(0x5F8, 0x228), // ESAI_RX_FS
+
+//   SD host controller2 on DualLite
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_CLK)  IOMUXC_SW_MUX_CTL_PAD_SD2_CLK 20E02F4h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_CLK)      IOMUXC_SW_PAD_CTL_PAD_SD2_CLK 20E06DCh
+   IMX_PAD_SD2_CLK = _IMX_PAD(0x6DC, 0x2F4), // SD2_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_CMD)      IOMUXC_SW_MUX_CTL_PAD_SD2_CMD 20E02F8h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_CMD)          IOMUXC_SW_PAD_CTL_PAD_SD2_CMD 20E06E0h
+   IMX_PAD_SD2_CMD = _IMX_PAD(0x6E0, 0x2F8), // SD2_CMD
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_DATA0)    IOMUXC_SW_MUX_CTL_PAD_SD2_DATA0 20E02FCh
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_DATA0)        IOMUXC_SW_PAD_CTL_PAD_SD2_DATA0 20E06E4h
+   IMX_PAD_SD2_DAT0 = _IMX_PAD(0x6E4, 0x2FC), // SD2_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_DATA1)    IOMUXC_SW_MUX_CTL_PAD_SD2_DATA1 20E0300h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_DATA1)        IOMUXC_SW_PAD_CTL_PAD_SD2_DATA1 20E06E8h
+   IMX_PAD_SD2_DAT1 = _IMX_PAD(0x6E8, 0x300), // SD2_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_DATA2)    IOMUXC_SW_MUX_CTL_PAD_SD2_DATA2 20E0304h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_DATA2)        IOMUXC_SW_PAD_CTL_PAD_SD2_DATA2 20E06ECh
+   IMX_PAD_SD2_DAT2 = _IMX_PAD(0x6EC, 0x304), // SD2_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_DATA3)    IOMUXC_SW_MUX_CTL_PAD_SD2_DATA3 20E0308h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_DATA3)        IOMUXC_SW_PAD_CTL_PAD_SD2_DATA3 20E06F0h
+   IMX_PAD_SD2_DAT3 = _IMX_PAD(0x6F0, 0x308), // SD2_DATA3
+
+//   SD host controller1 on DualLite
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_DATA0)
+   IMX_PAD_SD1_DAT0 = _IMX_PAD(0x728, 0x340), // SD1_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_DATA1)
+   IMX_PAD_SD1_DAT1 = _IMX_PAD(0x724, 0x33C), // SD1_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_CMD)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_CMD)
+   IMX_PAD_SD1_CMD = _IMX_PAD(0x730, 0x348), // SD1_CMD
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_DATA2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_DATA2)
+   IMX_PAD_SD1_DAT2 = _IMX_PAD(0x734, 0x34C), // SD1_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_CLK)
+   IMX_PAD_SD1_CLK = _IMX_PAD(0x738, 0x350), // SD1_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_DATA3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_DATA3)
+   IMX_PAD_SD1_DAT3 = _IMX_PAD(0x72C, 0x344), // SD1_DATA3
+
+// Ethernet controller on DualLite
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_MDIO)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_MDIO)
+   IMX_PAD_ENET_MDIO = _IMX_PAD(0x4E4, 0x1D0), // ENET_MDIO
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_REF_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_REF_CLK)
+   IMX_PAD_ENET_REF_CLK = _IMX_PAD(0x4E8, 0x1D4), // ENET_TX_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_RX_ER)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_RX_ER)
+   IMX_PAD_ENET_RX_ER = _IMX_PAD(0x4EC, 0x1D8), // USB_OTG_ID
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_CRS_DV)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_CRS_DV)
+   IMX_PAD_ENET_CRS_DV = _IMX_PAD(0x4F0, 0x1DC), // ENET_RX_EN
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_RX_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_RX_DATA1)
+   IMX_PAD_ENET_RXD1 = _IMX_PAD(0x4F4, 0x1E0), // MLB_SIG
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_RX_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_RX_DATA0)
+   IMX_PAD_ENET_RXD0 = _IMX_PAD(0x4F8, 0x1E4), // XTALOSC_OSC32K_32K_OUT
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_TX_EN)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_TX_EN)
+   IMX_PAD_ENET_TX_EN = _IMX_PAD(0x4FC, 0x1E8), // ENET_TX_EN
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_TX_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_TX_DATA1)
+   IMX_PAD_ENET_TXD1 = _IMX_PAD(0x500, 0x1EC), // MLB_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_TX_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_TX_DATA0)
+   IMX_PAD_ENET_TXD0 = _IMX_PAD(0x504, 0x1F0), // ENET_TX_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET_MDC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET_MDC)
+   IMX_PAD_ENET_MDC = _IMX_PAD(0x508, 0x1F4), // MLB_DATA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA00)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA00)
+   IMX_PAD_NANDF_D0 = _IMX_PAD(0x6E4, 0x2FC), // NAND_DATA00
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA01)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA01)
+   IMX_PAD_NANDF_D1 = _IMX_PAD(0x6E8, 0x300), // NAND_DATA01
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA02)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA02)
+   IMX_PAD_NANDF_D2 = _IMX_PAD(0x6EC, 0x304), // NAND_DATA02
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA03)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA03)
+   IMX_PAD_NANDF_D3 = _IMX_PAD(0x6F0, 0x308), // NAND_DATA03
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA04)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA04)
+   IMX_PAD_NANDF_D4 = _IMX_PAD(0x6F4, 0x30C), // NAND_DATA04
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA05)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA05)
+   IMX_PAD_NANDF_D5 = _IMX_PAD(0x6F8, 0x310), // NAND_DATA05
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA06)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA06)
+   IMX_PAD_NANDF_D6 = _IMX_PAD(0x6FC, 0x314), // NAND_DATA06
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA07)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA07)
+   IMX_PAD_NANDF_D7 = _IMX_PAD(0x700, 0x318), // NAND_DATA07
+
+//   SD host controller4 on DualLite
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA0)
+   IMX_PAD_SD4_DAT0 = _IMX_PAD(0x704, 0x31C), // SD4_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA1)
+   IMX_PAD_SD4_DAT1 = _IMX_PAD(0x708, 0x320), // SD4_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA2)
+   IMX_PAD_SD4_DAT2 = _IMX_PAD(0x70C, 0x324), // SD4_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA3)    IOMUXC_SW_PAD_CTL_PAD_SD4_DATA3 20E0734h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA3)        IOMUXC_SW_MUX_CTL_PAD_SD4_DATA3 20E034Ch
+   IMX_PAD_SD4_DAT3 = _IMX_PAD(0x734, 0x34C), // SD4_DATA3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA4)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA4)
+   IMX_PAD_SD4_DAT4 = _IMX_PAD(0x714, 0x32C), // SD4_DATA4
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA5)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA5)
+   IMX_PAD_SD4_DAT5 = _IMX_PAD(0x718, 0x330), // SD4_DATA5
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA6)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA6)
+   IMX_PAD_SD4_DAT6 = _IMX_PAD(0x71C, 0x334), // SD4_DATA6
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA7)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA7)
+   IMX_PAD_SD4_DAT7 = _IMX_PAD(0x720, 0x338), // SD4_DATA7
+
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR22)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR22)
+   IMX_PAD_EIM_A22 = _IMX_PAD(0x3F0, 0xDC), // EIM_ADDR22
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR21)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR21)
+   IMX_PAD_EIM_A21 = _IMX_PAD(0x3F4, 0xE0), // EIM_ADDR21
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR20)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR20)
+   IMX_PAD_EIM_A20 = _IMX_PAD(0x3F8, 0xE4), // EIM_ADDR20
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR19)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR19)
+   IMX_PAD_EIM_A19 = _IMX_PAD(0x3FC, 0xE8), // EIM_ADDR19
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR18)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR18)
+   IMX_PAD_EIM_A18 = _IMX_PAD(0x400, 0xEC), // EIM_ADDR18
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR17)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR17)
+   IMX_PAD_EIM_A17 = _IMX_PAD(0x404, 0xF0), // EIM_ADDR17
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR16)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR16)
+   IMX_PAD_EIM_A16 = _IMX_PAD(0x408, 0xF4), // EIM_ADDR16
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_CS0_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_CS0_B)
+   IMX_PAD_EIM_CS0 = _IMX_PAD(0x40C, 0xF8), // EIM_CS0_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_CS1_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_CS1_B)
+   IMX_PAD_EIM_CS1 = _IMX_PAD(0x410, 0xFC), // EIM_CS1_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_OE_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_OE_B)
+   IMX_PAD_EIM_OE = _IMX_PAD(0x414, 0x100), // EIM_OE_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_RW)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_RW)
+   IMX_PAD_EIM_RW = _IMX_PAD(0x418, 0x104), // EIM_RW
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_LBA_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_LBA_B)
+   IMX_PAD_EIM_LBA = _IMX_PAD(0x41C, 0x108), // EIM_LBA_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_EB0_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_EB0_B)
+   IMX_PAD_EIM_EB0 = _IMX_PAD(0x420, 0x10C), // EIM_EB0_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_EB1_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_EB1_B)
+   IMX_PAD_EIM_EB1 = _IMX_PAD(0x424, 0x110), // EIM_EB1_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_EB2_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_EB2_B)
+   IMX_PAD_EIM_EB2 = _IMX_PAD(0x3A0, 0x8C), // EIM_EB2_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_EB3_B)    IOMUXC_SW_PAD_CTL_PAD_EIM_EB3_B 20E05A0h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_EB3_B)        IOMUXC_SW_MUX_CTL_PAD_EIM_EB3_B 20E01D0h
+   IMX_PAD_EIM_EB3 = _IMX_PAD(0x5A0, 0x1D0), // EIM_EB3_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD00)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD00)
+   IMX_PAD_EIM_DA0 = _IMX_PAD(0x428, 0x114), // EIM_AD00
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD01)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD01)
+   IMX_PAD_EIM_DA1 = _IMX_PAD(0x42C, 0x118), // EIM_AD01
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD02)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD02)
+   IMX_PAD_EIM_DA2 = _IMX_PAD(0x430, 0x11C), // EIM_AD02
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD03)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD03)
+   IMX_PAD_EIM_DA3 = _IMX_PAD(0x434, 0x120), // EIM_AD03
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD04)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD04)
+   IMX_PAD_EIM_DA4 = _IMX_PAD(0x438, 0x124), // EIM_AD04
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD05)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD05)
+   IMX_PAD_EIM_DA5 = _IMX_PAD(0x43C, 0x128), // EIM_AD05
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD06)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD06)
+   IMX_PAD_EIM_DA6 = _IMX_PAD(0x440, 0x12C), // EIM_AD06
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD07)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD07)
+   IMX_PAD_EIM_DA7 = _IMX_PAD(0x444, 0x130), // EIM_AD07
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD08)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD08)
+   IMX_PAD_EIM_DA8 = _IMX_PAD(0x448, 0x134), // EIM_AD08
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD09)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD09)
+   IMX_PAD_EIM_DA9 = _IMX_PAD(0x44C, 0x138), // EIM_AD09
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD10)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD10)
+   IMX_PAD_EIM_DA10 = _IMX_PAD(0x450, 0x13C), // EIM_AD10
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD11)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD11)
+   IMX_PAD_EIM_DA11 = _IMX_PAD(0x454, 0x140), // EIM_AD11
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD12)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD12)
+   IMX_PAD_EIM_DA12 = _IMX_PAD(0x458, 0x144), // EIM_AD12
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD13)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD13)
+   IMX_PAD_EIM_DA13 = _IMX_PAD(0x45C, 0x148), // EIM_AD13
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD14)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD14)
+   IMX_PAD_EIM_DA14 = _IMX_PAD(0x460, 0x14C), // EIM_AD14
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_AD15)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_AD15)
+   IMX_PAD_EIM_DA15 = _IMX_PAD(0x464, 0x150), // EIM_AD15
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA16)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA16)
+   IMX_PAD_EIM_D16 = _IMX_PAD(0x3A4, 0x90), // EIM_DATA16
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA17)   IOMUXC_SW_PAD_CTL_PAD_EIM_DATA17 20E0518h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA17)       IOMUXC_SW_MUX_CTL_PAD_EIM_DATA17 20E0148h
+   IMX_PAD_EIM_D17 = _IMX_PAD(0x518, 0x148), // EIM_DATA17
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA18)   IOMUXC_SW_PAD_CTL_PAD_EIM_DATA18 20E051Ch
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA18)       IOMUXC_SW_MUX_CTL_PAD_EIM_DATA18 20E014C
+   IMX_PAD_EIM_D18 = _IMX_PAD(0x51C, 0x14C), // EIM_DATA18
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA19)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA19)
+   IMX_PAD_EIM_D19 = _IMX_PAD(0x3B0, 0x9C), // EIM_DATA19
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA20)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA20)
+   IMX_PAD_EIM_D20 = _IMX_PAD(0x3B4, 0xA0), // EIM_DATA20
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA21)   IOMUXC_SW_PAD_CTL_PAD_EIM_DATA21 20E0528h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA21)       IOMUXC_SW_MUX_CTL_PAD_EIM_DATA21 20E0158h
+   IMX_PAD_EIM_D21 = _IMX_PAD(0x528, 0x158), // EIM_DATA21
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA22)   IOMUXC_SW_PAD_CTL_PAD_EIM_DATA22 20E052Ch
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA22)       IOMUXC_SW_MUX_CTL_PAD_EIM_DATA22 20E015Ch
+   IMX_PAD_EIM_D22 = _IMX_PAD(0x52C, 0x15C), // EIM_DATA22
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA23)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA23)
+   IMX_PAD_EIM_D23 = _IMX_PAD(0x3C0, 0xAC), // EIM_DATA23
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA24)       IOMUXC_SW_PAD_CTL_PAD_EIM_DATA24 20E0534h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA24)           IOMUXC_SW_MUX_CTL_PAD_EIM_DATA24 20E0164h
+   IMX_PAD_EIM_D24 = _IMX_PAD(0x534, 0x164), // EIM_DATA24
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA25)       IOMUXC_SW_PAD_CTL_PAD_EIM_DATA25 20E0538h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA25)           IOMUXC_SW_MUX_CTL_PAD_EIM_DATA25 20E0168h
+   IMX_PAD_EIM_D25 = _IMX_PAD(0x538, 0x168), // EIM_DATA25
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA26)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA26)
+   IMX_PAD_EIM_D26 = _IMX_PAD(0x3D0, 0xBC), // EIM_DATA26
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA27)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA27)
+   IMX_PAD_EIM_D27 = _IMX_PAD(0x3D4, 0xC0), // EIM_DATA27
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA28)   IOMUXC_SW_PAD_CTL_PAD_EIM_DATA28 20E0544h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA28)       IOMUXC_SW_MUX_CTL_PAD_EIM_DATA28 20E0174h
+   IMX_PAD_EIM_D28 = _IMX_PAD(0x5448, 0x174), // EIM_DATA28
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA29)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA29)
+   IMX_PAD_EIM_D29 = _IMX_PAD(0x3DC, 0xC8), // EIM_DATA29
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA30)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA30)
+   IMX_PAD_EIM_D30 = _IMX_PAD(0x3E0, 0xCC), // EIM_DATA30
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_DATA31)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_DATA31)
+   IMX_PAD_EIM_D31 = _IMX_PAD(0x3E4, 0xD0), // EIM_DATA31
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO19)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO19)
+   IMX_PAD_GPIO_19 = _IMX_PAD(0x624, 0x254), // KEY_COL5
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_COL0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_COL0)
+   IMX_PAD_KEY_COL0 = _IMX_PAD(0x5C8, 0x1F8), // ECSPI1_SCLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_ROW0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_ROW0)
+   IMX_PAD_KEY_ROW0 = _IMX_PAD(0x5CC, 0x1FC), // ECSPI1_MOSI
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_COL1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_COL1)
+   IMX_PAD_KEY_COL1 = _IMX_PAD(0x5D0, 0x200), // ECSPI1_MISO
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_ROW1)     IOMUXC_SW_PAD_CTL_PAD_KEY_ROW1 20E0644h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_ROW1)         IOMUXC_SW_MUX_CTL_PAD_KEY_ROW1 20E025Ch
+   IMX_PAD_KEY_ROW1 = _IMX_PAD(0x644, 0x25C), // ECSPI1_SS0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_COL2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_COL2)
+   IMX_PAD_KEY_COL2 = _IMX_PAD(0x5D8, 0x208), // ECSPI1_SS1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_ROW2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_ROW2)
+   IMX_PAD_KEY_ROW2 = _IMX_PAD(0x5DC, 0x20C), // ECSPI1_SS2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_COL3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_COL3)
+   IMX_PAD_KEY_COL3 = _IMX_PAD(0x5E0, 0x210), // ECSPI1_SS3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_ROW3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_ROW3)
+   IMX_PAD_KEY_ROW3 = _IMX_PAD(0x5E4, 0x214), // XTALOSC_OSC32K_32K_OUT
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_COL4)     IOMUXC_SW_PAD_CTL_PAD_KEY_COL4 20E063Ch
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_COL4)         IOMUXC_SW_MUX_CTL_PAD_KEY_COL4 20E0254h
+   IMX_PAD_KEY_COL4 = _IMX_PAD(0x63C, 0x254), // FLEXCAN2_TX
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_ROW4)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_ROW4)
+   IMX_PAD_KEY_ROW4 = _IMX_PAD(0x5EC, 0x21C), // FLEXCAN2_RX
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DI0_DISP_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DI0_DISP_CLK)
+   IMX_PAD_DI0_DISP_CLK = _IMX_PAD(0x470, 0x15C), // IPU1_DI0_DISP_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DI0_PIN15)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DI0_PIN15)
+   IMX_PAD_DI0_PIN15 = _IMX_PAD(0x474, 0x160), // IPU1_DI0_PIN15
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DI0_PIN02)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DI0_PIN02)
+   IMX_PAD_DI0_PIN2 = _IMX_PAD(0x478, 0x164), // IPU1_DI0_PIN02
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DI0_PIN03)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DI0_PIN03)
+   IMX_PAD_DI0_PIN3 = _IMX_PAD(0x47C, 0x168), // IPU1_DI0_PIN03
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DI0_PIN04)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DI0_PIN04)
+   IMX_PAD_DI0_PIN4 = _IMX_PAD(0x480, 0x16C), // IPU1_DI0_PIN04
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA00)         IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA00 20E03C4h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA00)             IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA00 20E00B0h
+   IMX_PAD_DISP0_DAT0 = _IMX_PAD(0x3C4, 0xB0), // IPU1_DISP0_DATA00
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA01)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA01)
+   IMX_PAD_DISP0_DAT1 = _IMX_PAD(0x488, 0x174), // IPU1_DISP0_DATA01
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA02)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA02)
+   IMX_PAD_DISP0_DAT2 = _IMX_PAD(0x48C, 0x178), // IPU1_DISP0_DATA02
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA03)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA03)
+   IMX_PAD_DISP0_DAT3 = _IMX_PAD(0x490, 0x17C), // IPU1_DISP0_DATA03
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA04)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA04)
+   IMX_PAD_DISP0_DAT4 = _IMX_PAD(0x494, 0x180), // IPU1_DISP0_DATA04
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA05)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA05)
+   IMX_PAD_DISP0_DAT5 = _IMX_PAD(0x498, 0x184), // IPU1_DISP0_DATA05
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA06)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA06)
+   IMX_PAD_DISP0_DAT6 = _IMX_PAD(0x49C, 0x188), // IPU1_DISP0_DATA06
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA07)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA07)
+   IMX_PAD_DISP0_DAT7 = _IMX_PAD(0x4A0, 0x18C), // IPU1_DISP0_DATA07
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA08)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA08)
+   IMX_PAD_DISP0_DAT8 = _IMX_PAD(0x4A4, 0x190), // IPU1_DISP0_DATA08
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA09)         IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA09 20E0420h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA09)             IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA09 20E010Ch
+   IMX_PAD_DISP0_DAT9 = _IMX_PAD(0x420, 0x10C), // IPU1_DISP0_DATA09
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA10)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA10)
+   IMX_PAD_DISP0_DAT10 = _IMX_PAD(0x4AC, 0x198), // IPU1_DISP0_DATA10
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT_B)
+   IMX_PAD_EIM_WAIT = _IMX_PAD(0x468, 0x154), // EIM_WAIT_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR25)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR25)
+   IMX_PAD_EIM_A25 = _IMX_PAD(0x39C, 0x88), // EIM_ADDR25
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR24)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR24)
+   IMX_PAD_EIM_A24 = _IMX_PAD(0x3E8, 0xD4), // EIM_ADDR24
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA11)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA11)
+   IMX_PAD_DISP0_DAT11 = _IMX_PAD(0x4B0, 0x19C), // IPU1_DISP0_DATA11
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA12)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA12)
+   IMX_PAD_DISP0_DAT12 = _IMX_PAD(0x4B4, 0x1A0), // IPU1_DISP0_DATA12
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA13)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA13)
+   IMX_PAD_DISP0_DAT13 = _IMX_PAD(0x4B8, 0x1A4), // IPU1_DISP0_DATA13
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA14)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA14)
+   IMX_PAD_DISP0_DAT14 = _IMX_PAD(0x4BC, 0x1A8), // IPU1_DISP0_DATA14
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA15)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA15)
+   IMX_PAD_DISP0_DAT15 = _IMX_PAD(0x4C0, 0x1AC), // IPU1_DISP0_DATA15
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA16)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA16)
+   IMX_PAD_DISP0_DAT16 = _IMX_PAD(0x4C4, 0x1B0), // IPU1_DISP0_DATA16
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA17)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA17)
+   IMX_PAD_DISP0_DAT17 = _IMX_PAD(0x4C8, 0x1B4), // IPU1_DISP0_DATA17
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA18)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA18)
+   IMX_PAD_DISP0_DAT18 = _IMX_PAD(0x4CC, 0x1B8), // IPU1_DISP0_DATA18
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA19)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA19)
+   IMX_PAD_DISP0_DAT19 = _IMX_PAD(0x4D0, 0x1BC), // IPU1_DISP0_DATA19
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA20)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA20)
+   IMX_PAD_DISP0_DAT20 = _IMX_PAD(0x4D4, 0x1C0), // IPU1_DISP0_DATA20
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA21)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA21)
+   IMX_PAD_DISP0_DAT21 = _IMX_PAD(0x4D8, 0x1C4), // IPU1_DISP0_DATA21
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA22)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA22)
+   IMX_PAD_DISP0_DAT22 = _IMX_PAD(0x4DC, 0x1C8), // IPU1_DISP0_DATA22
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_DISP0_DATA23)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_DISP0_DATA23)
+   IMX_PAD_DISP0_DAT23 = _IMX_PAD(0x4E0, 0x1CC), // IPU1_DISP0_DATA23
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_PIXCLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_PIXCLK)
+   IMX_PAD_CSI0_PIXCLK = _IMX_PAD(0x628, 0x258), // IPU1_CSI0_PIXCLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_HSYNC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_HSYNC)
+   IMX_PAD_CSI0_MCLK = _IMX_PAD(0x62C, 0x25C), // IPU1_CSI0_HSYNC
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA_EN)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA_EN)
+   IMX_PAD_CSI0_DATA_EN = _IMX_PAD(0x630, 0x260), // IPU1_CSI0_DATA_EN
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_VSYNC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_VSYNC)
+   IMX_PAD_CSI0_VSYNC = _IMX_PAD(0x634, 0x264), // IPU1_CSI0_VSYNC
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA04)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA04)
+   IMX_PAD_CSI0_DAT4 = _IMX_PAD(0x638, 0x268), // IPU1_CSI0_DATA04
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA05)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA05)
+   IMX_PAD_CSI0_DAT5 = _IMX_PAD(0x63C, 0x26C), // IPU1_CSI0_DATA05
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA06)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA06)
+   IMX_PAD_CSI0_DAT6 = _IMX_PAD(0x640, 0x270), // IPU1_CSI0_DATA06
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA07)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA07)
+   IMX_PAD_CSI0_DAT7 = _IMX_PAD(0x644, 0x274), // IPU1_CSI0_DATA07
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA08)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA08)
+   IMX_PAD_CSI0_DAT8 = _IMX_PAD(0x648, 0x278), // IPU1_CSI0_DATA08
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA09)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA09)
+   IMX_PAD_CSI0_DAT9 = _IMX_PAD(0x64C, 0x27C), // IPU1_CSI0_DATA09
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA10)          IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA10 20E0360h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA10)              IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA10 20E004Ch
+   IMX_PAD_CSI0_DAT10 = _IMX_PAD(0x360, 0x4C), // IPU1_CSI0_DATA10
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA11)          IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA11 20E0364h
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA11)              IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA11 20E0050h
+   IMX_PAD_CSI0_DAT11 = _IMX_PAD(0x364, 0x50), // IPU1_CSI0_DATA11
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA12)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA12)
+   IMX_PAD_CSI0_DAT12 = _IMX_PAD(0x658, 0x288), // IPU1_CSI0_DATA12
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA13)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA13)
+   IMX_PAD_CSI0_DAT13 = _IMX_PAD(0x65C, 0x28C), // IPU1_CSI0_DATA13
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA14)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA14)
+   IMX_PAD_CSI0_DAT14 = _IMX_PAD(0x660, 0x290), // IPU1_CSI0_DATA14
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA15)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA15)
+   IMX_PAD_CSI0_DAT15 = _IMX_PAD(0x664, 0x294), // IPU1_CSI0_DATA15
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA16)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA16)
+   IMX_PAD_CSI0_DAT16 = _IMX_PAD(0x668, 0x298), // IPU1_CSI0_DATA16
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA17)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA17)
+   IMX_PAD_CSI0_DAT17 = _IMX_PAD(0x66C, 0x29C), // IPU1_CSI0_DATA17
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA18)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA18)
+   IMX_PAD_CSI0_DAT18 = _IMX_PAD(0x670, 0x2A0), // IPU1_CSI0_DATA18
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA19)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA19)
+   IMX_PAD_CSI0_DAT19 = _IMX_PAD(0x674, 0x2A4), // IPU1_CSI0_DATA19
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_ADDR23)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_ADDR23)
+   IMX_PAD_EIM_A23 = _IMX_PAD(0x3EC, 0xD8), // EIM_ADDR23
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_CLE)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_CLE)
+   IMX_PAD_NANDF_CLE = _IMX_PAD(0x6BC, 0x2D4), // NAND_CLE
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_ALE)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_ALE)
+   IMX_PAD_NANDF_ALE = _IMX_PAD(0x6C0, 0x2D8), // NAND_ALE
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_WP_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_WP_B)
+   IMX_PAD_NANDF_WP_B = _IMX_PAD(0x6C4, 0x2DC), // NAND_WP_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_READY_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_READY_B)
+   IMX_PAD_NANDF_RB0 = _IMX_PAD(0x6C8, 0x2E0), // NAND_READY_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_CS0_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_CS0_B)
+   IMX_PAD_NANDF_CS0 = _IMX_PAD(0x6CC, 0x2E4), // NAND_CE0_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_CS1_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_CS1_B)
+   IMX_PAD_NANDF_CS1 = _IMX_PAD(0x6D0, 0x2E8), // NAND_CE1_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_CS2_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_CS2_B)
+   IMX_PAD_NANDF_CS2 = _IMX_PAD(0x6D4, 0x2EC), // NAND_CE2_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_CS3_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_CS3_B)
+   IMX_PAD_NANDF_CS3 = _IMX_PAD(0x6D8, 0x2F0), // NAND_CE3_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA7)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA7)
+   IMX_PAD_SD3_DAT7 = _IMX_PAD(0x690, 0x2A8), // SD3_DATA7
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA6)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA6)
+   IMX_PAD_SD3_DAT6 = _IMX_PAD(0x694, 0x2AC), // SD3_DATA6
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_TXC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_TXC)
+   IMX_PAD_RGMII_TXC = _IMX_PAD(0x36C, 0x58), // USB_H2_DATA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_TD0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_TD0)
+   IMX_PAD_RGMII_TD0 = _IMX_PAD(0x370, 0x5C), // HSI_TX_READY
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_TD1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_TD1)
+   IMX_PAD_RGMII_TD1 = _IMX_PAD(0x374, 0x60), // HSI_RX_FLAG
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_TD2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_TD2)
+   IMX_PAD_RGMII_TD2 = _IMX_PAD(0x378, 0x64), // HSI_RX_DATA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_TD3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_TD3)
+   IMX_PAD_RGMII_TD3 = _IMX_PAD(0x37C, 0x68), // HSI_RX_WAKE
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_RX_CTL)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_RX_CTL)
+   IMX_PAD_RGMII_RX_CTL = _IMX_PAD(0x380, 0x6C), // USB_H3_DATA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_RD0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_RD0)
+   IMX_PAD_RGMII_RD0 = _IMX_PAD(0x384, 0x70), // HSI_RX_READY
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_TX_CTL)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_TX_CTL)
+   IMX_PAD_RGMII_TX_CTL = _IMX_PAD(0x388, 0x74), // USB_H2_STROBE
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_RD1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_RD1)
+   IMX_PAD_RGMII_RD1 = _IMX_PAD(0x38C, 0x78), // HSI_TX_FLAG
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_RD2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_RD2)
+   IMX_PAD_RGMII_RD2 = _IMX_PAD(0x390, 0x7C), // HSI_TX_DATA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_RD3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_RD3)
+   IMX_PAD_RGMII_RD3 = _IMX_PAD(0x394, 0x80), // HSI_TX_WAKE
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII_RXC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII_RXC)
+   IMX_PAD_RGMII_RXC = _IMX_PAD(0x398, 0x84), // USB_H3_STROBE
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK)
+   IMX_PAD_EIM_BCLK = _IMX_PAD(0x46C, 0x158), // EIM_BCLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA5)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA5)
+   IMX_PAD_SD3_DAT5 = _IMX_PAD(0x698, 0x2B0), // SD3_DATA5
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA4)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA4)
+   IMX_PAD_SD3_DAT4 = _IMX_PAD(0x69C, 0x2B4), // SD3_DATA4
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_CMD)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_CMD)
+   IMX_PAD_SD3_CMD = _IMX_PAD(0x6A0, 0x2B8), // SD3_CMD
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_CLK)
+   IMX_PAD_SD3_CLK = _IMX_PAD(0x6A4, 0x2BC), // SD3_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA0)
+   IMX_PAD_SD3_DAT0 = _IMX_PAD(0x6A8, 0x2C0), // SD3_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA1)
+   IMX_PAD_SD3_DAT1 = _IMX_PAD(0x6AC, 0x2C4), // SD3_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA2)
+   IMX_PAD_SD3_DAT2 = _IMX_PAD(0x6B0, 0x2C8), // SD3_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA3)
+   IMX_PAD_SD3_DAT3 = _IMX_PAD(0x6B4, 0x2CC), // SD3_DATA3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_RESET)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_RESET)
+   IMX_PAD_SD3_RST = _IMX_PAD(0x6B8, 0x2D0), // SD3_RESET
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_CMD)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_CMD)
+   IMX_PAD_SD4_CMD = _IMX_PAD(0x6DC, 0x2F4), // SD4_CMD
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_CLK)
+   IMX_PAD_SD4_CLK = _IMX_PAD(0x6E0, 0x2F8), // SD4_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO16)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO16)
+   IMX_PAD_GPIO_16 = _IMX_PAD(0x618, 0x248), // ESAI_TX3_RX2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO17)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO17)
+   IMX_PAD_GPIO_17 = _IMX_PAD(0x61C, 0x24C), // ESAI_TX0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO18)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO18)
+   IMX_PAD_GPIO_18 = _IMX_PAD(0x620, 0x250), // ESAI_TX1
+} IMX_PAD;
+
+//
+// Alternate function numbers
+//
+
+typedef enum {
+   IMX_IOMUXC_GPIO_0_ALT0_CCM_CLKO1 = 0,
+   IMX_IOMUXC_GPIO_0_ALT2_KEY_COL5 = 2,
+   IMX_IOMUXC_GPIO_0_ALT3_ASRC_EXT_CLK = 3,
+   IMX_IOMUXC_GPIO_0_ALT4_EPIT1_OUT = 4,
+   IMX_IOMUXC_GPIO_0_ALT5_GPIO1_IO00 = 5,
+   IMX_IOMUXC_GPIO_0_ALT6_USB_H1_PWR = 6,
+   IMX_IOMUXC_GPIO_0_ALT7_SNVS_VIO_5 = 7,
+} IMX_IOMUXC_GPIO_0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_1_ALT0_ESAI_RX_CLK = 0,
+   IMX_IOMUXC_GPIO_1_ALT1_WDOG2_B = 1,
+   IMX_IOMUXC_GPIO_1_ALT2_KEY_ROW5 = 2,
+   IMX_IOMUXC_GPIO_1_ALT3_USB_OTG_ID = 3,
+   IMX_IOMUXC_GPIO_1_ALT4_PWM2_OUT = 4,
+   IMX_IOMUXC_GPIO_1_ALT5_GPIO1_IO01 = 5,
+   IMX_IOMUXC_GPIO_1_ALT6_SD1_CD_B = 6, // in
+} IMX_IOMUXC_GPIO_1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_2_ALT0_ESAI_TX_FS = 0,
+   IMX_IOMUXC_GPIO_2_ALT2_KEY_ROW6 = 2,
+   IMX_IOMUXC_GPIO_2_ALT5_GPIO1_IO02 = 5,
+   IMX_IOMUXC_GPIO_2_ALT6_SD2_WP = 6,
+   IMX_IOMUXC_GPIO_2_ALT7_MLB_DATA = 7,
+} IMX_IOMUXC_GPIO_2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_3_ALT0_ESAI_RX_HF_CLK = 0,
+   IMX_IOMUXC_GPIO_3_ALT2_I2C3_SCL = 2,
+   IMX_IOMUXC_GPIO_3_ALT3_XTALOSC_REF_CLK_24M = 3,
+   IMX_IOMUXC_GPIO_3_ALT4_CCM_CLKO2 = 4,
+   IMX_IOMUXC_GPIO_3_ALT5_GPIO1_IO03 = 5,
+   IMX_IOMUXC_GPIO_3_ALT6_USB_H1_OC = 6,
+   IMX_IOMUXC_GPIO_3_ALT7_MLB_CLK = 7,
+} IMX_IOMUXC_GPIO_3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_4_ALT0_ESAI_TX_HF_CLK = 0,
+   IMX_IOMUXC_GPIO_4_ALT2_KEY_COL7 = 2,
+   IMX_IOMUXC_GPIO_4_ALT5_GPIO1_IO04 = 5,
+   IMX_IOMUXC_GPIO_4_ALT6_SD2_CD_B = 6,
+} IMX_IOMUXC_GPIO_4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_5_ALT0_ESAI_TX2_RX3 = 0,
+   IMX_IOMUXC_GPIO_5_ALT2_KEY_ROW7 = 2,
+   IMX_IOMUXC_GPIO_5_ALT3_CCM_CLKO1 = 3,
+   IMX_IOMUXC_GPIO_5_ALT5_GPIO1_IO05 = 5,
+   IMX_IOMUXC_GPIO_5_ALT6_I2C3_SCL = 6,
+   IMX_IOMUXC_GPIO_5_ALT7_ARM_EVENTI = 7,
+} IMX_IOMUXC_GPIO_5_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_6_ALT0_ESAI_TX_CLK = 0,
+   IMX_IOMUXC_GPIO_6_ALT2_I2C3_SDA = 2,
+   IMX_IOMUXC_GPIO_6_ALT5_GPIO1_IO06 = 5,
+   IMX_IOMUXC_GPIO_6_ALT6_SD2_LCTL = 6,
+   IMX_IOMUXC_GPIO_6_ALT7_MLB_SIG = 7,
+} IMX_IOMUXC_GPIO_6_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_7_ALT0_ESAI_TX4_RX1 = 0,
+   IMX_IOMUXC_GPIO_7_ALT1_ECSPI5_RDY = 1,
+   IMX_IOMUXC_GPIO_7_ALT2_EPIT1_OUT = 2,
+   IMX_IOMUXC_GPIO_7_ALT3_FLEXCAN1_TX = 3,
+   IMX_IOMUXC_GPIO_7_ALT4_UART2_TX_DATA = 4,
+   IMX_IOMUXC_GPIO_7_ALT5_GPIO1_IO07 = 5,
+   IMX_IOMUXC_GPIO_7_ALT6_SPDIF_LOCK = 6,
+   IMX_IOMUXC_GPIO_7_ALT7_USB_OTG_HOST_MODE = 7,
+} IMX_IOMUXC_GPIO_7_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_8_ALT0_ESAI_TX5_RX0 = 0,
+   IMX_IOMUXC_GPIO_8_ALT1_XTALOSC_REF_CLK_32K = 1,
+   IMX_IOMUXC_GPIO_8_ALT2_EPIT2_OUT = 2,
+   IMX_IOMUXC_GPIO_8_ALT3_FLEXCAN1_RX = 3,
+   IMX_IOMUXC_GPIO_8_ALT4_UART2_RX_DATA = 4,
+   IMX_IOMUXC_GPIO_8_ALT5_GPIO1_IO08 = 5,
+   IMX_IOMUXC_GPIO_8_ALT6_SPDIF_SR_CLK = 6,
+   IMX_IOMUXC_GPIO_8_ALT7_USB_OTG_PWR_CTL_WAKE = 7,
+} IMX_IOMUXC_GPIO_8_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_9_ALT0_ESAI_RX_FS = 0,
+   IMX_IOMUXC_GPIO_9_ALT1_WDOG1_B = 1,
+   IMX_IOMUXC_GPIO_9_ALT2_KEY_COL6 = 2,
+   IMX_IOMUXC_GPIO_9_ALT3_CCM_REF_EN_B = 3,
+   IMX_IOMUXC_GPIO_9_ALT4_PWM1_OUT = 4,
+   IMX_IOMUXC_GPIO_9_ALT5_GPIO1_IO09 = 5,
+   IMX_IOMUXC_GPIO_9_ALT6_SD1_WP = 6,
+} IMX_IOMUXC_GPIO_9_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_CLK_ALT0_SD2_CLK = 0,
+   IMX_IOMUXC_SD2_CLK_ALT1_ECSPI5_SCLK = 1,
+   IMX_IOMUXC_SD2_CLK_ALT2_KEY_COL5 = 2,
+   IMX_IOMUXC_SD2_CLK_ALT3_AUD4_RXFS = 3,
+   IMX_IOMUXC_SD2_CLK_ALT5_GPIO1_IO10 = 5,
+} IMX_IOMUXC_SD2_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_CMD_ALT0_SD2_CMD = 0,
+   IMX_IOMUXC_SD2_CMD_ALT1_ECSPI5_MOSI = 1,
+   IMX_IOMUXC_SD2_CMD_ALT2_KEY_ROW5 = 2,
+   IMX_IOMUXC_SD2_CMD_ALT3_AUD4_RXC = 3,
+   IMX_IOMUXC_SD2_CMD_ALT5_GPIO1_IO11 = 5,
+} IMX_IOMUXC_SD2_CMD_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_DAT3_ALT0_SD2_DATA3 = 0,
+   IMX_IOMUXC_SD2_DAT3_ALT1_ECSPI5_SS3 = 1,
+   IMX_IOMUXC_SD2_DAT3_ALT2_KEY_COL6 = 2,
+   IMX_IOMUXC_SD2_DAT3_ALT3_AUD4_TXC = 3,
+   IMX_IOMUXC_SD2_DAT3_ALT5_GPIO1_IO12 = 5,
+} IMX_IOMUXC_SD2_DAT3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_DAT2_ALT0_SD2_DATA2 = 0,
+   IMX_IOMUXC_SD2_DAT2_ALT1_ECSPI5_SS1 = 1,
+   IMX_IOMUXC_SD2_DAT2_ALT2_EIM_CS3_B = 2,
+   IMX_IOMUXC_SD2_DAT2_ALT3_AUD4_TXD = 3,
+   IMX_IOMUXC_SD2_DAT2_ALT4_KEY_ROW6 = 4,
+   IMX_IOMUXC_SD2_DAT2_ALT5_GPIO1_IO13 = 5,
+} IMX_IOMUXC_SD2_DAT2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_DAT1_ALT0_SD2_DATA1 = 0,
+   IMX_IOMUXC_SD2_DAT1_ALT1_ECSPI5_SS0 = 1,
+   IMX_IOMUXC_SD2_DAT1_ALT2_EIM_CS2_B = 2,
+   IMX_IOMUXC_SD2_DAT1_ALT3_AUD4_TXFS = 3,
+   IMX_IOMUXC_SD2_DAT1_ALT4_KEY_COL7 = 4,
+   IMX_IOMUXC_SD2_DAT1_ALT5_GPIO1_IO14 = 5,
+} IMX_IOMUXC_SD2_DAT1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_DAT0_ALT0_SD2_DATA0 = 0,
+   IMX_IOMUXC_SD2_DAT0_ALT1_ECSPI5_MISO = 1,
+   IMX_IOMUXC_SD2_DAT0_ALT3_AUD4_RXD = 3,
+   IMX_IOMUXC_SD2_DAT0_ALT4_KEY_ROW7 = 4,
+   IMX_IOMUXC_SD2_DAT0_ALT5_GPIO1_IO15 = 5,
+   IMX_IOMUXC_SD2_DAT0_ALT6_DCIC2_OUT = 6,
+} IMX_IOMUXC_SD2_DAT0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_DAT0_ALT0_SD1_DATA0 = 0,
+   IMX_IOMUXC_SD1_DAT0_ALT1_ECSPI5_MISO = 1,
+   IMX_IOMUXC_SD1_DAT0_ALT3_GPT_CAPTURE1 = 3,
+   IMX_IOMUXC_SD1_DAT0_ALT5_GPIO1_IO16 = 5,
+} IMX_IOMUXC_SD1_DAT0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_DAT1_ALT0_SD1_DATA1 = 0,
+   IMX_IOMUXC_SD1_DAT1_ALT1_ECSPI5_SS0 = 1,
+   IMX_IOMUXC_SD1_DAT1_ALT2_PWM3_OUT = 2,
+   IMX_IOMUXC_SD1_DAT1_ALT3_GPT_CAPTURE2 = 3,
+   IMX_IOMUXC_SD1_DAT1_ALT5_GPIO1_IO17 = 5,
+} IMX_IOMUXC_SD1_DAT1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_CMD_ALT0_SD1_CMD = 0, // in and out
+   IMX_IOMUXC_SD1_CMD_ALT1_ECSPI5_MOSI = 1,
+   IMX_IOMUXC_SD1_CMD_ALT2_PWM4_OUT = 2,
+   IMX_IOMUXC_SD1_CMD_ALT3_GPT_COMPARE1 = 3,
+   IMX_IOMUXC_SD1_CMD_ALT5_GPIO1_IO18 = 5,
+} IMX_IOMUXC_SD1_CMD_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_DAT2_ALT0_SD1_DATA2 = 0,
+   IMX_IOMUXC_SD1_DAT2_ALT1_ECSPI5_SS1 = 1,
+   IMX_IOMUXC_SD1_DAT2_ALT2_GPT_COMPARE2 = 2,
+   IMX_IOMUXC_SD1_DAT2_ALT3_PWM2_OUT = 3,
+   IMX_IOMUXC_SD1_DAT2_ALT4_WDOG1_B = 4,
+   IMX_IOMUXC_SD1_DAT2_ALT5_GPIO1_IO19 = 5,
+   IMX_IOMUXC_SD1_DAT2_ALT6_WDOG1_RESET_B_DEB = 6,
+} IMX_IOMUXC_SD1_DAT2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_CLK_ALT0_SD1_CLK = 0, // out
+   IMX_IOMUXC_SD1_CLK_ALT1_ECSPI5_SCLK = 1,
+   IMX_IOMUXC_SD1_CLK_ALT2_XTALOSC_OSC32K_32K_OUT = 2,
+   IMX_IOMUXC_SD1_CLK_ALT3_GPT_CLKIN = 3,
+   IMX_IOMUXC_SD1_CLK_ALT5_GPIO1_IO20 = 5,
+} IMX_IOMUXC_SD1_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_DAT3_ALT0_SD1_DATA3 = 0,
+   IMX_IOMUXC_SD1_DAT3_ALT1_ECSPI5_SS2 = 1,
+   IMX_IOMUXC_SD1_DAT3_ALT2_GPT_COMPARE3 = 2,
+   IMX_IOMUXC_SD1_DAT3_ALT3_PWM1_OUT = 3,
+   IMX_IOMUXC_SD1_DAT3_ALT4_WDOG2_B = 4,
+   IMX_IOMUXC_SD1_DAT3_ALT5_GPIO1_IO21 = 5,
+   IMX_IOMUXC_SD1_DAT3_ALT6_WDOG2_RESET_B_DEB = 6,
+} IMX_IOMUXC_SD1_DAT3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_MDIO_ALT1_ENET_MDIO = 1,
+   IMX_IOMUXC_ENET_MDIO_ALT2_ESAI_RX_CLK = 2,
+   IMX_IOMUXC_ENET_MDIO_ALT4_ENET_1588_EVENT1_OUT = 4,
+   IMX_IOMUXC_ENET_MDIO_ALT5_GPIO1_IO22 = 5,
+   IMX_IOMUXC_ENET_MDIO_ALT6_SPDIF_LOCK = 6,
+} IMX_IOMUXC_ENET_MDIO_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_REF_CLK_ALT1_ENET_TX_CLK = 1,
+   IMX_IOMUXC_ENET_REF_CLK_ALT2_ESAI_RX_FS = 2,
+   IMX_IOMUXC_ENET_REF_CLK_ALT5_GPIO1_IO23 = 5,
+   IMX_IOMUXC_ENET_REF_CLK_ALT6_SPDIF_SR_CLK = 6,
+} IMX_IOMUXC_ENET_REF_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_RX_ER_ALT0_USB_OTG_ID = 0,
+   IMX_IOMUXC_ENET_RX_ER_ALT1_ENET_RX_ER = 1,
+   IMX_IOMUXC_ENET_RX_ER_ALT2_ESAI_RX_HF_CLK = 2,
+   IMX_IOMUXC_ENET_RX_ER_ALT3_SPDIF_IN = 3,
+   IMX_IOMUXC_ENET_RX_ER_ALT4_ENET_1588_EVENT2_OUT = 4,
+   IMX_IOMUXC_ENET_RX_ER_ALT5_GPIO1_IO24 = 5,
+} IMX_IOMUXC_ENET_RX_ER_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_CRS_DV_ALT1_ENET_RX_EN = 1,
+   IMX_IOMUXC_ENET_CRS_DV_ALT2_ESAI_TX_CLK = 2,
+   IMX_IOMUXC_ENET_CRS_DV_ALT3_SPDIF_EXT_CLK = 3,
+   IMX_IOMUXC_ENET_CRS_DV_ALT5_GPIO1_IO25 = 5,
+} IMX_IOMUXC_ENET_CRS_DV_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_RXD1_ALT0_MLB_SIG = 0,
+   IMX_IOMUXC_ENET_RXD1_ALT1_ENET_RX_DATA1 = 1,
+   IMX_IOMUXC_ENET_RXD1_ALT2_ESAI_TX_FS = 2,
+   IMX_IOMUXC_ENET_RXD1_ALT4_ENET_1588_EVENT3_OUT = 4,
+   IMX_IOMUXC_ENET_RXD1_ALT5_GPIO1_IO26 = 5,
+} IMX_IOMUXC_ENET_RXD1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_RXD0_ALT0_XTALOSC_OSC32K_32K_OUT = 0,
+   IMX_IOMUXC_ENET_RXD0_ALT1_ENET_RX_DATA0 = 1,
+   IMX_IOMUXC_ENET_RXD0_ALT2_ESAI_TX_HF_CLK = 2,
+   IMX_IOMUXC_ENET_RXD0_ALT3_SPDIF_OUT = 3,
+   IMX_IOMUXC_ENET_RXD0_ALT5_GPIO1_IO27 = 5,
+} IMX_IOMUXC_ENET_RXD0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_TX_EN_ALT1_ENET_TX_EN = 1,
+   IMX_IOMUXC_ENET_TX_EN_ALT2_ESAI_TX3_RX2 = 2,
+   IMX_IOMUXC_ENET_TX_EN_ALT5_GPIO1_IO28 = 5,
+} IMX_IOMUXC_ENET_TX_EN_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_TXD1_ALT0_MLB_CLK = 0,
+   IMX_IOMUXC_ENET_TXD1_ALT1_ENET_TX_DATA1 = 1,
+   IMX_IOMUXC_ENET_TXD1_ALT2_ESAI_TX2_RX3 = 2,
+   IMX_IOMUXC_ENET_TXD1_ALT4_ENET_1588_EVENT0_IN = 4,
+   IMX_IOMUXC_ENET_TXD1_ALT5_GPIO1_IO29 = 5,
+} IMX_IOMUXC_ENET_TXD1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_TXD0_ALT1_ENET_TX_DATA0 = 1,
+   IMX_IOMUXC_ENET_TXD0_ALT2_ESAI_TX4_RX1 = 2,
+   IMX_IOMUXC_ENET_TXD0_ALT5_GPIO1_IO30 = 5,
+} IMX_IOMUXC_ENET_TXD0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET_MDC_ALT0_MLB_DATA = 0,
+   IMX_IOMUXC_ENET_MDC_ALT1_ENET_MDC = 1,
+   IMX_IOMUXC_ENET_MDC_ALT2_ESAI_TX5_RX0 = 2,
+   IMX_IOMUXC_ENET_MDC_ALT4_ENET_1588_EVENT1_IN = 4,
+   IMX_IOMUXC_ENET_MDC_ALT5_GPIO1_IO31 = 5,
+} IMX_IOMUXC_ENET_MDC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_D0_ALT0_NAND_DATA00 = 0,
+   IMX_IOMUXC_NANDF_D0_ALT1_SD1_DATA4 = 1,
+   IMX_IOMUXC_NANDF_D0_ALT5_GPIO2_IO00 = 5,
+} IMX_IOMUXC_NANDF_D0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_D1_ALT0_NAND_DATA01 = 0,
+   IMX_IOMUXC_NANDF_D1_ALT1_SD1_DATA5 = 1,
+   IMX_IOMUXC_NANDF_D1_ALT5_GPIO2_IO01 = 5,
+} IMX_IOMUXC_NANDF_D1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_D2_ALT0_NAND_DATA02 = 0,
+   IMX_IOMUXC_NANDF_D2_ALT1_SD1_DATA6 = 1,
+   IMX_IOMUXC_NANDF_D2_ALT5_GPIO2_IO02 = 5,
+} IMX_IOMUXC_NANDF_D2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_D3_ALT0_NAND_DATA03 = 0,
+   IMX_IOMUXC_NANDF_D3_ALT1_SD1_DATA7 = 1,
+   IMX_IOMUXC_NANDF_D3_ALT5_GPIO2_IO03 = 5,
+} IMX_IOMUXC_NANDF_D3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_D4_ALT0_NAND_DATA04 = 0,
+   IMX_IOMUXC_NANDF_D4_ALT1_SD2_DATA4 = 1,
+   IMX_IOMUXC_NANDF_D4_ALT5_GPIO2_IO04 = 5,
+} IMX_IOMUXC_NANDF_D4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_D5_ALT0_NAND_DATA05 = 0,
+   IMX_IOMUXC_NANDF_D5_ALT1_SD2_DATA5 = 1,
+   IMX_IOMUXC_NANDF_D5_ALT5_GPIO2_IO05 = 5,
+} IMX_IOMUXC_NANDF_D5_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_D6_ALT0_NAND_DATA06 = 0,
+   IMX_IOMUXC_NANDF_D6_ALT1_SD2_DATA6 = 1,
+   IMX_IOMUXC_NANDF_D6_ALT5_GPIO2_IO06 = 5,
+} IMX_IOMUXC_NANDF_D6_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_D7_ALT0_NAND_DATA07 = 0,
+   IMX_IOMUXC_NANDF_D7_ALT1_SD2_DATA7 = 1,
+   IMX_IOMUXC_NANDF_D7_ALT5_GPIO2_IO07 = 5,
+} IMX_IOMUXC_NANDF_D7_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DAT0_ALT1_SD4_DATA0 = 1,
+   IMX_IOMUXC_SD4_DAT0_ALT2_NAND_DQS = 2,
+   IMX_IOMUXC_SD4_DAT0_ALT5_GPIO2_IO08 = 5,
+} IMX_IOMUXC_SD4_DAT0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DAT1_ALT1_SD4_DATA1 = 1,
+   IMX_IOMUXC_SD4_DAT1_ALT2_PWM3_OUT = 2,
+   IMX_IOMUXC_SD4_DAT1_ALT5_GPIO2_IO09 = 5,
+} IMX_IOMUXC_SD4_DAT1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DAT2_ALT1_SD4_DATA2 = 1,
+   IMX_IOMUXC_SD4_DAT2_ALT2_PWM4_OUT = 2,
+   IMX_IOMUXC_SD4_DAT2_ALT5_GPIO2_IO10 = 5,
+} IMX_IOMUXC_SD4_DAT2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DAT3_ALT1_SD4_DATA3 = 1,
+   IMX_IOMUXC_SD4_DAT3_ALT5_GPIO2_IO11 = 5,
+} IMX_IOMUXC_SD4_DAT3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DAT4_ALT1_SD4_DATA4 = 1,
+   IMX_IOMUXC_SD4_DAT4_ALT2_UART2_RX_DATA = 2,
+   IMX_IOMUXC_SD4_DAT4_ALT5_GPIO2_IO12 = 5,
+} IMX_IOMUXC_SD4_DAT4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DAT5_ALT1_SD4_DATA5 = 1,
+   IMX_IOMUXC_SD4_DAT5_ALT2_UART2_RTS_B = 2,
+   IMX_IOMUXC_SD4_DAT5_ALT5_GPIO2_IO13 = 5,
+} IMX_IOMUXC_SD4_DAT5_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DAT6_ALT1_SD4_DATA6 = 1,
+   IMX_IOMUXC_SD4_DAT6_ALT2_UART2_CTS_B = 2,
+   IMX_IOMUXC_SD4_DAT6_ALT5_GPIO2_IO14 = 5,
+} IMX_IOMUXC_SD4_DAT6_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DAT7_ALT1_SD4_DATA7 = 1,
+   IMX_IOMUXC_SD4_DAT7_ALT2_UART2_TX_DATA = 2,
+   IMX_IOMUXC_SD4_DAT7_ALT5_GPIO2_IO15 = 5,
+} IMX_IOMUXC_SD4_DAT7_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A22_ALT0_EIM_ADDR22 = 0,
+   IMX_IOMUXC_EIM_A22_ALT1_IPU1_DISP1_DATA17 = 1,
+   IMX_IOMUXC_EIM_A22_ALT2_IPU1_CSI1_DATA17 = 2,
+   IMX_IOMUXC_EIM_A22_ALT5_GPIO2_IO16 = 5,
+   IMX_IOMUXC_EIM_A22_ALT7_SRC_BOOT_CFG22 = 7,
+   IMX_IOMUXC_EIM_A22_ALT8_EPDC_GDSP = 8,
+} IMX_IOMUXC_EIM_A22_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A21_ALT0_EIM_ADDR21 = 0,
+   IMX_IOMUXC_EIM_A21_ALT1_IPU1_DISP1_DATA16 = 1,
+   IMX_IOMUXC_EIM_A21_ALT2_IPU1_CSI1_DATA16 = 2,
+   IMX_IOMUXC_EIM_A21_ALT5_GPIO2_IO17 = 5,
+   IMX_IOMUXC_EIM_A21_ALT7_SRC_BOOT_CFG21 = 7,
+   IMX_IOMUXC_EIM_A21_ALT8_EPDC_GDCLK = 8
+} IMX_IOMUXC_EIM_A21_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A20_ALT0_EIM_ADDR20 = 0,
+   IMX_IOMUXC_EIM_A20_ALT1_IPU1_DISP1_DATA15 = 1,
+   IMX_IOMUXC_EIM_A20_ALT2_IPU1_CSI1_DATA15 = 2,
+   IMX_IOMUXC_EIM_A20_ALT5_GPIO2_IO18 = 5,
+   IMX_IOMUXC_EIM_A20_ALT7_SRC_BOOT_CFG20 = 7,
+   IMX_IOMUXC_EIM_A20_ALT8_EPDC_PWR_CTRL2 = 8
+} IMX_IOMUXC_EIM_A20_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A19_ALT0_EIM_ADDR19 = 0,
+   IMX_IOMUXC_EIM_A19_ALT1_IPU1_DISP1_DATA14 = 1,
+   IMX_IOMUXC_EIM_A19_ALT2_IPU1_CSI1_DATA14 = 2,
+   IMX_IOMUXC_EIM_A19_ALT5_GPIO2_IO19 = 5,
+   IMX_IOMUXC_EIM_A19_ALT7_SRC_BOOT_CFG19 = 7,
+   IMX_IOMUXC_EIM_A19_ALT8_EPDC_PWR_CTRL1 = 8
+} IMX_IOMUXC_EIM_A19_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A18_ALT0_EIM_ADDR18 = 0,
+   IMX_IOMUXC_EIM_A18_ALT1_IPU1_DISP1_DATA13 = 1,
+   IMX_IOMUXC_EIM_A18_ALT2_IPU1_CSI1_DATA13 = 2,
+   IMX_IOMUXC_EIM_A18_ALT5_GPIO2_IO20 = 5,
+   IMX_IOMUXC_EIM_A18_ALT7_SRC_BOOT_CFG18 = 7,
+   IMX_IOMUXC_EIM_A18_ALT8_EPDC_PWR_CTRL0 = 8
+} IMX_IOMUXC_EIM_A18_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A17_ALT0_EIM_ADDR17 = 0,
+   IMX_IOMUXC_EIM_A17_ALT1_IPU1_DISP1_DATA12 = 1,
+   IMX_IOMUXC_EIM_A17_ALT2_IPU1_CSI1_DATA12 = 2,
+   IMX_IOMUXC_EIM_A17_ALT5_GPIO2_IO21 = 5,
+   IMX_IOMUXC_EIM_A17_ALT7_SRC_BOOT_CFG17 = 7,
+   IMX_IOMUXC_EIM_A17_ALT8_EPDC_PWR_STAT = 8
+} IMX_IOMUXC_EIM_A17_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A16_ALT0_EIM_ADDR16 = 0,
+   IMX_IOMUXC_EIM_A16_ALT1_IPU1_DI1_DISP_CLK = 1,
+   IMX_IOMUXC_EIM_A16_ALT2_IPU1_CSI1_PIXCLK = 2,
+   IMX_IOMUXC_EIM_A16_ALT5_GPIO2_IO22 = 5,
+   IMX_IOMUXC_EIM_A16_ALT7_SRC_BOOT_CFG16 = 7,
+   IMX_IOMUXC_EIM_A16_ALT8_EPDC_DATA00 = 8
+} IMX_IOMUXC_EIM_A16_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_CS0_ALT0_EIM_CS0_B = 0,
+   IMX_IOMUXC_EIM_CS0_ALT1_IPU1_DI1_PIN05 = 1,
+   IMX_IOMUXC_EIM_CS0_ALT2_ECSPI2_SCLK = 2,
+   IMX_IOMUXC_EIM_CS0_ALT5_GPIO2_IO23 = 5,
+} IMX_IOMUXC_EIM_CS0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_CS1_ALT0_EIM_CS1_B = 0,
+   IMX_IOMUXC_EIM_CS1_ALT1_IPU1_DI1_PIN06 = 1,
+   IMX_IOMUXC_EIM_CS1_ALT2_ECSPI2_MOSI = 2,
+   IMX_IOMUXC_EIM_CS1_ALT5_GPIO2_IO24 = 5,
+} IMX_IOMUXC_EIM_CS1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_OE_ALT0_EIM_OE_B = 0,
+   IMX_IOMUXC_EIM_OE_ALT1_IPU1_DI1_PIN07 = 1,
+   IMX_IOMUXC_EIM_OE_ALT2_ECSPI2_MISO = 2,
+   IMX_IOMUXC_EIM_OE_ALT5_GPIO2_IO25 = 5,
+} IMX_IOMUXC_EIM_OE_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_RW_ALT0_EIM_RW = 0,
+   IMX_IOMUXC_EIM_RW_ALT1_IPU1_DI1_PIN08 = 1,
+   IMX_IOMUXC_EIM_RW_ALT2_ECSPI2_SS0 = 2,
+   IMX_IOMUXC_EIM_RW_ALT5_GPIO2_IO26 = 5,
+   IMX_IOMUXC_EIM_RW_ALT7_SRC_BOOT_CFG29 = 7,
+} IMX_IOMUXC_EIM_RW_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_LBA_ALT0_EIM_LBA_B = 0,
+   IMX_IOMUXC_EIM_LBA_ALT1_IPU1_DI1_PIN17 = 1,
+   IMX_IOMUXC_EIM_LBA_ALT2_ECSPI2_SS1 = 2,
+   IMX_IOMUXC_EIM_LBA_ALT5_GPIO2_IO27 = 5,
+   IMX_IOMUXC_EIM_LBA_ALT7_SRC_BOOT_CFG26 = 7,
+} IMX_IOMUXC_EIM_LBA_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_EB0_ALT0_EIM_EB0_B = 0,
+   IMX_IOMUXC_EIM_EB0_ALT1_IPU1_DISP1_DATA11 = 1,
+   IMX_IOMUXC_EIM_EB0_ALT2_IPU1_CSI1_DATA11 = 2,
+   IMX_IOMUXC_EIM_EB0_ALT4_CCM_PMIC_READY = 4,
+   IMX_IOMUXC_EIM_EB0_ALT5_GPIO2_IO28 = 5,
+   IMX_IOMUXC_EIM_EB0_ALT7_SRC_BOOT_CFG27 = 7,
+   IMX_IOMUXC_EIM_EB0_ALT8_EPDC_PWR_COM = 8
+} IMX_IOMUXC_EIM_EB0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_EB1_ALT0_EIM_EB1_B = 0,
+   IMX_IOMUXC_EIM_EB1_ALT1_IPU1_DISP1_DATA10 = 1,
+   IMX_IOMUXC_EIM_EB1_ALT2_IPU1_CSI1_DATA10 = 2,
+   IMX_IOMUXC_EIM_EB1_ALT5_GPIO2_IO29 = 5,
+   IMX_IOMUXC_EIM_EB1_ALT7_SRC_BOOT_CFG28 = 7,
+   IMX_IOMUXC_EIM_EB1_ALT8_EPDC_SDSHR = 8
+} IMX_IOMUXC_EIM_EB1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_EB2_ALT0_EIM_EB2_B = 0,
+   IMX_IOMUXC_EIM_EB2_ALT1_ECSPI1_SS0 = 1,
+   IMX_IOMUXC_EIM_EB2_ALT3_IPU1_CSI1_DATA19 = 3,
+   IMX_IOMUXC_EIM_EB2_ALT4_HDMI_TX_DDC_SCL = 4,
+   IMX_IOMUXC_EIM_EB2_ALT5_GPIO2_IO30 = 5,
+   IMX_IOMUXC_EIM_EB2_ALT6_I2C2_SCL = 6,
+   IMX_IOMUXC_EIM_EB2_ALT7_SRC_BOOT_CFG30 = 7,
+   IMX_IOMUXC_EIM_EB2_ALT8_EPDC_DATA05 = 8
+} IMX_IOMUXC_EIM_EB2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_EB3_ALT0_EIM_EB3_B = 0,
+   IMX_IOMUXC_EIM_EB3_ALT1_ECSPI4_RDY = 1,
+   IMX_IOMUXC_EIM_EB3_ALT2_UART3_RTS_B = 2,
+   IMX_IOMUXC_EIM_EB3_ALT3_UART1_RI_B = 3,
+   IMX_IOMUXC_EIM_EB3_ALT4_IPU1_CSI1_HSYNC = 4,
+   IMX_IOMUXC_EIM_EB3_ALT5_GPIO2_IO31 = 5,
+   IMX_IOMUXC_EIM_EB3_ALT6_IPU1_DI1_PIN03 = 6,
+   IMX_IOMUXC_EIM_EB3_ALT7_SRC_BOOT_CFG31 = 7,
+   IMX_IOMUXC_EIM_EB3_ALT8_EPDC_SDCE0 = 8,
+   IMX_IOMUXC_EIM_EB3_ALT9_EIM_ACLK_FREERUN = 9
+} IMX_IOMUXC_EIM_EB3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA0_ALT0_EIM_AD00 = 0,
+   IMX_IOMUXC_EIM_DA0_ALT1_IPU1_DISP1_DATA09 = 1,
+   IMX_IOMUXC_EIM_DA0_ALT2_IPU1_CSI1_DATA09 = 2,
+   IMX_IOMUXC_EIM_DA0_ALT5_GPIO3_IO00 = 5,
+   IMX_IOMUXC_EIM_DA0_ALT7_SRC_BOOT_CFG00 = 7,
+   IMX_IOMUXC_EIM_DA0_ALT8_EPDC_SDCLK_N = 8
+} IMX_IOMUXC_EIM_DA0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA1_ALT0_EIM_AD01 = 0,
+   IMX_IOMUXC_EIM_DA1_ALT1_IPU1_DISP1_DATA08 = 1,
+   IMX_IOMUXC_EIM_DA1_ALT2_IPU1_CSI1_DATA08 = 2,
+   IMX_IOMUXC_EIM_DA1_ALT5_GPIO3_IO01 = 5,
+   IMX_IOMUXC_EIM_DA1_ALT7_SRC_BOOT_CFG01 = 7,
+   IMX_IOMUXC_EIM_DA1_ALT8_EPDC_SDLE = 8
+} IMX_IOMUXC_EIM_DA1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA2_ALT0_EIM_AD02 = 0,
+   IMX_IOMUXC_EIM_DA2_ALT1_IPU1_DISP1_DATA07 = 1,
+   IMX_IOMUXC_EIM_DA2_ALT2_IPU1_CSI1_DATA07 = 2,
+   IMX_IOMUXC_EIM_DA2_ALT5_GPIO3_IO02 = 5,
+   IMX_IOMUXC_EIM_DA2_ALT7_SRC_BOOT_CFG02 = 7,
+   IMX_IOMUXC_EIM_DA2_ALT8_EPDC_BDR02 = 8
+} IMX_IOMUXC_EIM_DA2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA3_ALT0_EIM_AD03 = 0,
+   IMX_IOMUXC_EIM_DA3_ALT1_IPU1_DISP1_DATA06 = 1,
+   IMX_IOMUXC_EIM_DA3_ALT2_IPU1_CSI1_DATA06 = 2,
+   IMX_IOMUXC_EIM_DA3_ALT5_GPIO3_IO03 = 5,
+   IMX_IOMUXC_EIM_DA3_ALT7_SRC_BOOT_CFG03 = 7,
+   IMX_IOMUXC_EIM_DA3_ALT8_EPDC_BDR1 = 8
+} IMX_IOMUXC_EIM_DA3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA4_ALT0_EIM_AD04 = 0,
+   IMX_IOMUXC_EIM_DA4_ALT1_IPU1_DISP1_DATA05 = 1,
+   IMX_IOMUXC_EIM_DA4_ALT2_IPU1_CSI1_DATA05 = 2,
+   IMX_IOMUXC_EIM_DA4_ALT5_GPIO3_IO04 = 5,
+   IMX_IOMUXC_EIM_DA4_ALT7_SRC_BOOT_CFG04 = 7,
+   IMX_IOMUXC_EIM_DA4_ALT8_EPDC_SDCE0 = 8
+} IMX_IOMUXC_EIM_DA4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA5_ALT0_EIM_AD05 = 0,
+   IMX_IOMUXC_EIM_DA5_ALT1_IPU1_DISP1_DATA04 = 1,
+   IMX_IOMUXC_EIM_DA5_ALT2_IPU1_CSI1_DATA04 = 2,
+   IMX_IOMUXC_EIM_DA5_ALT5_GPIO3_IO05 = 5,
+   IMX_IOMUXC_EIM_DA5_ALT7_SRC_BOOT_CFG05 = 7,
+   IMX_IOMUXC_EIM_DA5_ALT8_EPDC_SDCE1 = 8
+} IMX_IOMUXC_EIM_DA5_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA6_ALT0_EIM_AD06 = 0,
+   IMX_IOMUXC_EIM_DA6_ALT1_IPU1_DISP1_DATA03 = 1,
+   IMX_IOMUXC_EIM_DA6_ALT2_IPU1_CSI1_DATA03 = 2,
+   IMX_IOMUXC_EIM_DA6_ALT5_GPIO3_IO06 = 5,
+   IMX_IOMUXC_EIM_DA6_ALT7_SRC_BOOT_CFG06 = 7,
+   IMX_IOMUXC_EIM_DA6_ALT8_EPDC_SDCE2 = 8
+} IMX_IOMUXC_EIM_DA6_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA7_ALT0_EIM_AD07 = 0,
+   IMX_IOMUXC_EIM_DA7_ALT1_IPU1_DISP1_DATA02 = 1,
+   IMX_IOMUXC_EIM_DA7_ALT2_IPU1_CSI1_DATA02 = 2,
+   IMX_IOMUXC_EIM_DA7_ALT5_GPIO3_IO07 = 5,
+   IMX_IOMUXC_EIM_DA7_ALT7_SRC_BOOT_CFG07 = 7,
+   IMX_IOMUXC_EIM_DA7_ALT8_EPDC_SDCE37 = 8
+} IMX_IOMUXC_EIM_DA7_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA8_ALT0_EIM_AD08 = 0,
+   IMX_IOMUXC_EIM_DA8_ALT1_IPU1_DISP1_DATA01 = 1,
+   IMX_IOMUXC_EIM_DA8_ALT2_IPU1_CSI1_DATA01 = 2,
+   IMX_IOMUXC_EIM_DA8_ALT5_GPIO3_IO08 = 5,
+   IMX_IOMUXC_EIM_DA8_ALT7_SRC_BOOT_CFG08 = 7,
+   IMX_IOMUXC_EIM_DA8_ALT8_EPDC_SDCE4 = 8
+} IMX_IOMUXC_EIM_DA8_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA9_ALT0_EIM_AD09 = 0,
+   IMX_IOMUXC_EIM_DA9_ALT1_IPU1_DISP1_DATA00 = 1,
+   IMX_IOMUXC_EIM_DA9_ALT2_IPU1_CSI1_DATA00 = 2,
+   IMX_IOMUXC_EIM_DA9_ALT5_GPIO3_IO09 = 5,
+   IMX_IOMUXC_EIM_DA9_ALT7_SRC_BOOT_CFG09 = 7,
+   IMX_IOMUXC_EIM_DA9_ALT8_EPDC_SDCE5 = 8
+} IMX_IOMUXC_EIM_DA9_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA10_ALT0_EIM_AD10 = 0,
+   IMX_IOMUXC_EIM_DA10_ALT1_IPU1_DI1_PIN15 = 1,
+   IMX_IOMUXC_EIM_DA10_ALT2_IPU1_CSI1_DATA_EN = 2,
+   IMX_IOMUXC_EIM_DA10_ALT5_GPIO3_IO10 = 5,
+   IMX_IOMUXC_EIM_DA10_ALT7_SRC_BOOT_CFG10 = 7,
+   IMX_IOMUXC_EIM_DA10_ALT8_EPDC_DATA01 = 8
+} IMX_IOMUXC_EIM_DA10_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA11_ALT0_EIM_AD11 = 0,
+   IMX_IOMUXC_EIM_DA11_ALT1_IPU1_DI1_PIN02 = 1,
+   IMX_IOMUXC_EIM_DA11_ALT2_IPU1_CSI1_HSYNC = 2,
+   IMX_IOMUXC_EIM_DA11_ALT5_GPIO3_IO11 = 5,
+   IMX_IOMUXC_EIM_DA11_ALT7_SRC_BOOT_CFG11 = 7,
+   IMX_IOMUXC_EIM_DA11_ALT8_EPDC_DATA03 = 8
+} IMX_IOMUXC_EIM_DA11_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA12_ALT0_EIM_AD12 = 0,
+   IMX_IOMUXC_EIM_DA12_ALT1_IPU1_DI1_PIN03 = 1,
+   IMX_IOMUXC_EIM_DA12_ALT2_IPU1_CSI1_VSYNC = 2,
+   IMX_IOMUXC_EIM_DA12_ALT5_GPIO3_IO12 = 5,
+   IMX_IOMUXC_EIM_DA12_ALT7_SRC_BOOT_CFG12 = 7,
+   IMX_IOMUXC_EIM_DA12_ALT8_EPDC_DATA02 = 8
+} IMX_IOMUXC_EIM_DA12_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA13_ALT0_EIM_AD13 = 0,
+   IMX_IOMUXC_EIM_DA13_ALT1_IPU1_DI1_D0_CS = 1,
+   IMX_IOMUXC_EIM_DA13_ALT5_GPIO3_IO13 = 5,
+   IMX_IOMUXC_EIM_DA13_ALT7_SRC_BOOT_CFG13 = 7,
+} IMX_IOMUXC_EIM_DA13_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA14_ALT0_EIM_AD14 = 0,
+   IMX_IOMUXC_EIM_DA14_ALT1_IPU1_DI1_D1_CS = 1,
+   IMX_IOMUXC_EIM_DA14_ALT5_GPIO3_IO14 = 5,
+   IMX_IOMUXC_EIM_DA14_ALT7_SRC_BOOT_CFG14 = 7,
+} IMX_IOMUXC_EIM_DA14_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_DA15_ALT0_EIM_AD15 = 0,
+   IMX_IOMUXC_EIM_DA15_ALT1_IPU1_DI1_PIN01 = 1,
+   IMX_IOMUXC_EIM_DA15_ALT2_IPU1_DI1_PIN04 = 2,
+   IMX_IOMUXC_EIM_DA15_ALT5_GPIO3_IO15 = 5,
+   IMX_IOMUXC_EIM_DA15_ALT7_SRC_BOOT_CFG15 = 7,
+} IMX_IOMUXC_EIM_DA15_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D16_ALT0_EIM_DATA16 = 0,
+   IMX_IOMUXC_EIM_D16_ALT1_ECSPI1_SCLK = 1,
+   IMX_IOMUXC_EIM_D16_ALT2_IPU1_DI0_PIN05 = 2,
+   IMX_IOMUXC_EIM_D16_ALT3_IPU1_CSI1_DATA18 = 3,
+   IMX_IOMUXC_EIM_D16_ALT4_HDMI_TX_DDC_SDA = 4,
+   IMX_IOMUXC_EIM_D16_ALT5_GPIO3_IO16 = 5,
+   IMX_IOMUXC_EIM_D16_ALT6_I2C2_SDA = 6,
+   IMX_IOMUXC_EIM_D16_ALT8_EPDC_DATA10 = 8
+} IMX_IOMUXC_EIM_D16_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D17_ALT0_EIM_DATA17 = 0,
+   IMX_IOMUXC_EIM_D17_ALT1_ECSPI1_MISO = 1,
+   IMX_IOMUXC_EIM_D17_ALT2_IPU1_DI0_PIN06 = 2,
+   IMX_IOMUXC_EIM_D17_ALT3_IPU1_CSI1_PIXCLK = 3,
+   IMX_IOMUXC_EIM_D17_ALT4_DCIC1_OUT = 4,
+   IMX_IOMUXC_EIM_D17_ALT5_GPIO3_IO17 = 5,
+   IMX_IOMUXC_EIM_D17_ALT6_I2C3_SCL = 6,
+   IMX_IOMUXC_EIM_D17_ALT8_EPDC_VCOM0 = 8
+} IMX_IOMUXC_EIM_D17_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D18_ALT0_EIM_DATA18 = 0,
+   IMX_IOMUXC_EIM_D18_ALT1_ECSPI1_MOSI = 1,
+   IMX_IOMUXC_EIM_D18_ALT2_IPU1_DI0_PIN07 = 2,
+   IMX_IOMUXC_EIM_D18_ALT3_IPU1_CSI1_DATA17 = 3,
+   IMX_IOMUXC_EIM_D18_ALT4_IPU1_DI1_D0_CS = 4,
+   IMX_IOMUXC_EIM_D18_ALT5_GPIO3_IO18 = 5,
+   IMX_IOMUXC_EIM_D18_ALT6_I2C3_SDA = 6,
+   IMX_IOMUXC_EIM_D18_ALT8_EPDC_VCOM1 = 8
+} IMX_IOMUXC_EIM_D18_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D19_ALT0_EIM_DATA19 = 0,
+   IMX_IOMUXC_EIM_D19_ALT1_ECSPI1_SS1 = 1,
+   IMX_IOMUXC_EIM_D19_ALT2_IPU1_DI0_PIN08 = 2,
+   IMX_IOMUXC_EIM_D19_ALT3_IPU1_CSI1_DATA16 = 3,
+   IMX_IOMUXC_EIM_D19_ALT4_UART1_CTS_B = 4,
+   IMX_IOMUXC_EIM_D19_ALT5_GPIO3_IO19 = 5,
+   IMX_IOMUXC_EIM_D19_ALT6_EPIT1_OUT = 6,
+   IMX_IOMUXC_EIM_D19_ALT8_EPDC_DATA12 = 8
+} IMX_IOMUXC_EIM_D19_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D20_ALT0_EIM_DATA20 = 0,
+   IMX_IOMUXC_EIM_D20_ALT1_ECSPI4_SS0 = 1,
+   IMX_IOMUXC_EIM_D20_ALT2_IPU1_DI0_PIN16 = 2,
+   IMX_IOMUXC_EIM_D20_ALT3_IPU1_CSI1_DATA15 = 3,
+   IMX_IOMUXC_EIM_D20_ALT4_UART1_RTS_B = 4,
+   IMX_IOMUXC_EIM_D20_ALT5_GPIO3_IO20 = 5,
+   IMX_IOMUXC_EIM_D20_ALT6_EPIT2_OUT = 6
+} IMX_IOMUXC_EIM_D20_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D21_ALT0_EIM_DATA21 = 0,
+   IMX_IOMUXC_EIM_D21_ALT1_ECSPI4_SCLK = 1,
+   IMX_IOMUXC_EIM_D21_ALT2_IPU1_DI0_PIN17 = 2,
+   IMX_IOMUXC_EIM_D21_ALT3_IPU1_CSI1_DATA11 = 3,
+   IMX_IOMUXC_EIM_D21_ALT4_USB_OTG_OC = 4,
+   IMX_IOMUXC_EIM_D21_ALT5_GPIO3_IO21 = 5,
+   IMX_IOMUXC_EIM_D21_ALT6_I2C1_SCL = 6,
+   IMX_IOMUXC_EIM_D21_ALT7_SPDIF_IN = 7,
+} IMX_IOMUXC_EIM_D21_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D22_ALT0_EIM_DATA22 = 0,
+   IMX_IOMUXC_EIM_D22_ALT1_ECSPI4_MISO = 1,
+   IMX_IOMUXC_EIM_D22_ALT2_IPU1_DI0_PIN01 = 2,
+   IMX_IOMUXC_EIM_D22_ALT3_IPU1_CSI1_DATA10 = 3,
+   IMX_IOMUXC_EIM_D22_ALT4_USB_OTG_PWR = 4,
+   IMX_IOMUXC_EIM_D22_ALT5_GPIO3_IO22 = 5,
+   IMX_IOMUXC_EIM_D22_ALT6_SPDIF_OUT = 6,
+   IMX_IOMUXC_EIM_D22_ALT8_EPDC_SDCE6 = 8
+} IMX_IOMUXC_EIM_D22_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D23_ALT0_EIM_DATA23 = 0,
+   IMX_IOMUXC_EIM_D23_ALT1_IPU1_DI0_D0_CS = 1,
+   IMX_IOMUXC_EIM_D23_ALT2_UART3_CTS_B = 2,
+   IMX_IOMUXC_EIM_D23_ALT3_UART1_DCD_B = 3,
+   IMX_IOMUXC_EIM_D23_ALT4_IPU1_CSI1_DATA_EN = 4,
+   IMX_IOMUXC_EIM_D23_ALT5_GPIO3_IO23 = 5,
+   IMX_IOMUXC_EIM_D23_ALT6_IPU1_DI1_PIN02 = 6,
+   IMX_IOMUXC_EIM_D23_ALT7_IPU1_DI1_PIN14 = 7,
+   IMX_IOMUXC_EIM_D23_ALT8_EPDC_DATA11 = 8
+} IMX_IOMUXC_EIM_D23_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D24_ALT0_EIM_DATA24 = 0,
+   IMX_IOMUXC_EIM_D24_ALT1_ECSPI4_SS2 = 1,
+   IMX_IOMUXC_EIM_D24_ALT2_UART3_TX_DATA = 2,
+   IMX_IOMUXC_EIM_D24_ALT3_ECSPI1_SS2 = 3,
+   IMX_IOMUXC_EIM_D24_ALT4_ECSPI2_SS2 = 4,
+   IMX_IOMUXC_EIM_D24_ALT5_GPIO3_IO24 = 5,
+   IMX_IOMUXC_EIM_D24_ALT6_AUD5_RXFS = 6,
+   IMX_IOMUXC_EIM_D24_ALT7_UART1_DTR_B = 7,
+} IMX_IOMUXC_EIM_D24_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D25_ALT0_EIM_DATA25 = 0,
+   IMX_IOMUXC_EIM_D25_ALT1_ECSPI4_SS3 = 1,
+   IMX_IOMUXC_EIM_D25_ALT2_UART3_RX_DATA = 2,
+   IMX_IOMUXC_EIM_D25_ALT3_ECSPI1_SS3 = 3,
+   IMX_IOMUXC_EIM_D25_ALT4_ECSPI2_SS3 = 4,
+   IMX_IOMUXC_EIM_D25_ALT5_GPIO3_IO25 = 5,
+   IMX_IOMUXC_EIM_D25_ALT6_AUD5_RXC = 6,
+   IMX_IOMUXC_EIM_D25_ALT7_UART1_DSR_B = 7,
+} IMX_IOMUXC_EIM_D25_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D26_ALT0_EIM_DATA26 = 0,
+   IMX_IOMUXC_EIM_D26_ALT1_IPU1_DI1_PIN11 = 1,
+   IMX_IOMUXC_EIM_D26_ALT2_IPU1_CSI0_DATA01 = 2,
+   IMX_IOMUXC_EIM_D26_ALT3_IPU1_CSI1_DATA14 = 3,
+   IMX_IOMUXC_EIM_D26_ALT4_UART2_TX_DATA = 4,
+   IMX_IOMUXC_EIM_D26_ALT5_GPIO3_IO26 = 5,
+   IMX_IOMUXC_EIM_D26_ALT6_IPU1_SISG2 = 6,
+   IMX_IOMUXC_EIM_D26_ALT7_IPU1_DISP1_DATA22 = 7,
+   IMX_IOMUXC_EIM_D26_ALT8_EPDC_SDOE = 8
+} IMX_IOMUXC_EIM_D26_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D27_ALT0_EIM_DATA27 = 0,
+   IMX_IOMUXC_EIM_D27_ALT1_IPU1_DI1_PIN13 = 1,
+   IMX_IOMUXC_EIM_D27_ALT2_IPU1_CSI0_DATA00 = 2,
+   IMX_IOMUXC_EIM_D27_ALT3_IPU1_CSI1_DATA13 = 3,
+   IMX_IOMUXC_EIM_D27_ALT4_UART2_RX_DATA = 4,
+   IMX_IOMUXC_EIM_D27_ALT5_GPIO3_IO27 = 5,
+   IMX_IOMUXC_EIM_D27_ALT6_IPU1_SISG3 = 6,
+   IMX_IOMUXC_EIM_D27_ALT7_IPU1_DISP1_DATA23 = 7,
+   IMX_IOMUXC_EIM_D27_ALT8_EPDC_SDOE = 8
+} IMX_IOMUXC_EIM_D27_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D28_ALT0_EIM_DATA28 = 0,
+   IMX_IOMUXC_EIM_D28_ALT1_I2C1_SDA = 1,
+   IMX_IOMUXC_EIM_D28_ALT2_ECSPI4_MOSI = 2,
+   IMX_IOMUXC_EIM_D28_ALT3_IPU1_CSI1_DATA12 = 3,
+   IMX_IOMUXC_EIM_D28_ALT4_UART2_CTS_B = 4,
+   IMX_IOMUXC_EIM_D28_ALT5_GPIO3_IO28 = 5,
+   IMX_IOMUXC_EIM_D28_ALT6_IPU1_EXT_TRIG = 6,
+   IMX_IOMUXC_EIM_D28_ALT7_IPU1_DI0_PIN13 = 7,
+   IMX_IOMUXC_EIM_D28_ALT8_EPDC_PWR_CTRL3 = 8
+} IMX_IOMUXC_EIM_D28_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D29_ALT0_EIM_DATA29 = 0,
+   IMX_IOMUXC_EIM_D29_ALT1_IPU1_DI1_PIN15 = 1,
+   IMX_IOMUXC_EIM_D29_ALT2_ECSPI4_SS0 = 2,
+   IMX_IOMUXC_EIM_D29_ALT4_UART2_RTS_B = 4,
+   IMX_IOMUXC_EIM_D29_ALT5_GPIO3_IO29 = 5,
+   IMX_IOMUXC_EIM_D29_ALT6_IPU1_CSI1_VSYNC = 6,
+   IMX_IOMUXC_EIM_D29_ALT7_IPU1_DI0_PIN14 = 7,
+   IMX_IOMUXC_EIM_D29_ALT8_EPDC_PWR_WAKE = 8
+} IMX_IOMUXC_EIM_D29_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D30_ALT0_EIM_DATA30 = 0,
+   IMX_IOMUXC_EIM_D30_ALT1_IPU1_DISP1_DATA21 = 1,
+   IMX_IOMUXC_EIM_D30_ALT2_IPU1_DI0_PIN11 = 2,
+   IMX_IOMUXC_EIM_D30_ALT3_IPU1_CSI0_DATA03 = 3,
+   IMX_IOMUXC_EIM_D30_ALT4_UART3_CTS_B = 4,
+   IMX_IOMUXC_EIM_D30_ALT5_GPIO3_IO30 = 5,
+   IMX_IOMUXC_EIM_D30_ALT6_USB_H1_OC = 6,
+} IMX_IOMUXC_EIM_D30_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_D31_ALT0_EIM_DATA31 = 0,
+   IMX_IOMUXC_EIM_D31_ALT1_IPU1_DISP1_DATA20 = 1,
+   IMX_IOMUXC_EIM_D31_ALT2_IPU1_DI0_PIN12 = 2,
+   IMX_IOMUXC_EIM_D31_ALT3_IPU1_CSI0_DATA02 = 3,
+   IMX_IOMUXC_EIM_D31_ALT4_UART3_RTS_B = 4,
+   IMX_IOMUXC_EIM_D31_ALT5_GPIO3_IO31 = 5,
+   IMX_IOMUXC_EIM_D31_ALT6_USB_H1_PWR = 6,
+} IMX_IOMUXC_EIM_D31_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_19_ALT0_KEY_COL5 = 0,
+   IMX_IOMUXC_GPIO_19_ALT1_ENET_1588_EVENT0_OUT = 1,
+   IMX_IOMUXC_GPIO_19_ALT2_SPDIF_OUT = 2,
+   IMX_IOMUXC_GPIO_19_ALT3_CCM_CLKO1 = 3,
+   IMX_IOMUXC_GPIO_19_ALT4_ECSPI1_RDY = 4,
+   IMX_IOMUXC_GPIO_19_ALT5_GPIO4_IO05 = 5,
+   IMX_IOMUXC_GPIO_19_ALT6_ENET_TX_ER = 6,
+} IMX_IOMUXC_GPIO_19_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_COL0_ALT0_ECSPI1_SCLK = 0,
+   IMX_IOMUXC_KEY_COL0_ALT1_ENET_RX_DATA3 = 1,
+   IMX_IOMUXC_KEY_COL0_ALT2_AUD5_TXC = 2,
+   IMX_IOMUXC_KEY_COL0_ALT3_KEY_COL0 = 3,
+   IMX_IOMUXC_KEY_COL0_ALT4_UART4_TX_DATA = 4,
+   IMX_IOMUXC_KEY_COL0_ALT5_GPIO4_IO06 = 5,
+   IMX_IOMUXC_KEY_COL0_ALT6_DCIC1_OUT = 6,
+} IMX_IOMUXC_KEY_COL0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_ROW0_ALT0_ECSPI1_MOSI = 0,
+   IMX_IOMUXC_KEY_ROW0_ALT1_ENET_TX_DATA3 = 1,
+   IMX_IOMUXC_KEY_ROW0_ALT2_AUD5_TXD = 2,
+   IMX_IOMUXC_KEY_ROW0_ALT3_KEY_ROW0 = 3,
+   IMX_IOMUXC_KEY_ROW0_ALT4_UART4_RX_DATA = 4,
+   IMX_IOMUXC_KEY_ROW0_ALT5_GPIO4_IO07 = 5,
+   IMX_IOMUXC_KEY_ROW0_ALT6_DCIC2_OUT = 6,
+} IMX_IOMUXC_KEY_ROW0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_COL1_ALT0_ECSPI1_MISO = 0,
+   IMX_IOMUXC_KEY_COL1_ALT1_ENET_MDIO = 1,
+   IMX_IOMUXC_KEY_COL1_ALT2_AUD5_TXFS = 2,
+   IMX_IOMUXC_KEY_COL1_ALT3_KEY_COL1 = 3,
+   IMX_IOMUXC_KEY_COL1_ALT4_UART5_TX_DATA = 4,
+   IMX_IOMUXC_KEY_COL1_ALT5_GPIO4_IO08 = 5,
+   IMX_IOMUXC_KEY_COL1_ALT6_SD1_VSELECT = 6,    // out
+} IMX_IOMUXC_KEY_COL1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_ROW1_ALT0_ECSPI1_SS0 = 0,
+   IMX_IOMUXC_KEY_ROW1_ALT1_ENET_COL = 1,
+   IMX_IOMUXC_KEY_ROW1_ALT2_AUD5_RXD = 2,
+   IMX_IOMUXC_KEY_ROW1_ALT3_KEY_ROW1 = 3,
+   IMX_IOMUXC_KEY_ROW1_ALT4_UART5_RX_DATA = 4,
+   IMX_IOMUXC_KEY_ROW1_ALT5_GPIO4_IO09 = 5,
+   IMX_IOMUXC_KEY_ROW1_ALT6_SD2_VSELECT = 6,
+} IMX_IOMUXC_KEY_ROW1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_COL2_ALT0_ECSPI1_SS1 = 0,
+   IMX_IOMUXC_KEY_COL2_ALT1_ENET_RX_DATA2 = 1,
+   IMX_IOMUXC_KEY_COL2_ALT2_FLEXCAN1_TX = 2,
+   IMX_IOMUXC_KEY_COL2_ALT3_KEY_COL2 = 3,
+   IMX_IOMUXC_KEY_COL2_ALT4_ENET_MDC = 4,
+   IMX_IOMUXC_KEY_COL2_ALT5_GPIO4_IO10 = 5,
+   IMX_IOMUXC_KEY_COL2_ALT6_USB_H1_PWR_CTL_WAKE = 6,
+} IMX_IOMUXC_KEY_COL2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_ROW2_ALT0_ECSPI1_SS2 = 0,
+   IMX_IOMUXC_KEY_ROW2_ALT1_ENET_TX_DATA2 = 1,
+   IMX_IOMUXC_KEY_ROW2_ALT2_FLEXCAN1_RX = 2,
+   IMX_IOMUXC_KEY_ROW2_ALT3_KEY_ROW2 = 3,
+   IMX_IOMUXC_KEY_ROW2_ALT4_SD2_VSELECT = 4,
+   IMX_IOMUXC_KEY_ROW2_ALT5_GPIO4_IO11 = 5,
+   IMX_IOMUXC_KEY_ROW2_ALT6_HDMI_TX_CEC_LINE = 6,
+} IMX_IOMUXC_KEY_ROW2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_COL3_ALT0_ECSPI1_SS3 = 0,
+   IMX_IOMUXC_KEY_COL3_ALT1_ENET_CRS = 1,
+   IMX_IOMUXC_KEY_COL3_ALT2_HDMI_TX_DDC_SCL = 2,
+   IMX_IOMUXC_KEY_COL3_ALT3_KEY_COL3 = 3,
+   IMX_IOMUXC_KEY_COL3_ALT4_I2C2_SCL = 4,
+   IMX_IOMUXC_KEY_COL3_ALT5_GPIO4_IO12 = 5,
+   IMX_IOMUXC_KEY_COL3_ALT6_SPDIF_IN = 6,
+} IMX_IOMUXC_KEY_COL3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_ROW3_ALT0_XTALOSC_OSC32K_32K_OUT = 0,
+   IMX_IOMUXC_KEY_ROW3_ALT1_ASRC_EXT_CLK = 1,
+   IMX_IOMUXC_KEY_ROW3_ALT2_HDMI_TX_DDC_SDA = 2,
+   IMX_IOMUXC_KEY_ROW3_ALT3_KEY_ROW3 = 3,
+   IMX_IOMUXC_KEY_ROW3_ALT4_I2C2_SDA = 4,
+   IMX_IOMUXC_KEY_ROW3_ALT5_GPIO4_IO13 = 5,
+   IMX_IOMUXC_KEY_ROW3_ALT6_SD1_VSELECT = 6,
+} IMX_IOMUXC_KEY_ROW3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_COL4_ALT0_FLEXCAN2_TX = 0,
+   IMX_IOMUXC_KEY_COL4_ALT1_IPU1_SISG4 = 1,
+   IMX_IOMUXC_KEY_COL4_ALT2_USB_OTG_OC = 2,
+   IMX_IOMUXC_KEY_COL4_ALT3_KEY_COL4 = 3,
+   IMX_IOMUXC_KEY_COL4_ALT4_UART5_RTS_B = 4,
+   IMX_IOMUXC_KEY_COL4_ALT5_GPIO4_IO14 = 5,
+} IMX_IOMUXC_KEY_COL4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_ROW4_ALT0_FLEXCAN2_RX = 0,
+   IMX_IOMUXC_KEY_ROW4_ALT1_IPU1_SISG5 = 1,
+   IMX_IOMUXC_KEY_ROW4_ALT2_USB_OTG_PWR = 2,
+   IMX_IOMUXC_KEY_ROW4_ALT3_KEY_ROW4 = 3,
+   IMX_IOMUXC_KEY_ROW4_ALT4_UART5_CTS_B = 4,
+   IMX_IOMUXC_KEY_ROW4_ALT5_GPIO4_IO15 = 5,
+} IMX_IOMUXC_KEY_ROW4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DI0_DISP_CLK_ALT0_IPU1_DI0_DISP_CLK = 0,
+   IMX_IOMUXC_DI0_DISP_CLK_ALT5_GPIO4_IO16 = 5,
+} IMX_IOMUXC_DI0_DISP_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DI0_PIN15_ALT0_IPU1_DI0_PIN15 = 0,
+   IMX_IOMUXC_DI0_PIN15_ALT2_AUD6_TXC = 2,
+   IMX_IOMUXC_DI0_PIN15_ALT5_GPIO4_IO17 = 5,
+} IMX_IOMUXC_DI0_PIN15_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DI0_PIN2_ALT0_IPU1_DI0_PIN02 = 0,
+   IMX_IOMUXC_DI0_PIN2_ALT2_AUD6_TXD = 2,
+   IMX_IOMUXC_DI0_PIN2_ALT5_GPIO4_IO18 = 5,
+} IMX_IOMUXC_DI0_PIN2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DI0_PIN3_ALT0_IPU1_DI0_PIN03 = 0,
+   IMX_IOMUXC_DI0_PIN3_ALT2_AUD6_TXFS = 2,
+   IMX_IOMUXC_DI0_PIN3_ALT5_GPIO4_IO19 = 5,
+} IMX_IOMUXC_DI0_PIN3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DI0_PIN4_ALT0_IPU1_DI0_PIN04 = 0,
+   IMX_IOMUXC_DI0_PIN4_ALT2_AUD6_RXD = 2,
+   IMX_IOMUXC_DI0_PIN4_ALT3_SD1_WP = 3,     // in
+   IMX_IOMUXC_DI0_PIN4_ALT5_GPIO4_IO20 = 5,
+} IMX_IOMUXC_DI0_PIN4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT0_ALT0_IPU1_DISP0_DATA00 = 0,
+   IMX_IOMUXC_DISP0_DAT0_ALT2_ECSPI3_SCLK = 2,
+   IMX_IOMUXC_DISP0_DAT0_ALT5_GPIO4_IO21 = 5,
+} IMX_IOMUXC_DISP0_DAT0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT1_ALT0_IPU1_DISP0_DATA01 = 0,
+   IMX_IOMUXC_DISP0_DAT1_ALT2_ECSPI3_MOSI = 2,
+   IMX_IOMUXC_DISP0_DAT1_ALT5_GPIO4_IO22 = 5,
+} IMX_IOMUXC_DISP0_DAT1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT2_ALT0_IPU1_DISP0_DATA02 = 0,
+   IMX_IOMUXC_DISP0_DAT2_ALT2_ECSPI3_MISO = 2,
+   IMX_IOMUXC_DISP0_DAT2_ALT5_GPIO4_IO23 = 5,
+} IMX_IOMUXC_DISP0_DAT2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT3_ALT0_IPU1_DISP0_DATA03 = 0,
+   IMX_IOMUXC_DISP0_DAT3_ALT2_ECSPI3_SS0 = 2,
+   IMX_IOMUXC_DISP0_DAT3_ALT5_GPIO4_IO24 = 5,
+} IMX_IOMUXC_DISP0_DAT3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT4_ALT0_IPU1_DISP0_DATA04 = 0,
+   IMX_IOMUXC_DISP0_DAT4_ALT2_ECSPI3_SS1 = 2,
+   IMX_IOMUXC_DISP0_DAT4_ALT5_GPIO4_IO25 = 5,
+} IMX_IOMUXC_DISP0_DAT4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT5_ALT0_IPU1_DISP0_DATA05 = 0,
+   IMX_IOMUXC_DISP0_DAT5_ALT2_ECSPI3_SS2 = 2,
+   IMX_IOMUXC_DISP0_DAT5_ALT3_AUD6_RXFS = 3,
+   IMX_IOMUXC_DISP0_DAT5_ALT5_GPIO4_IO26 = 5,
+} IMX_IOMUXC_DISP0_DAT5_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT6_ALT0_IPU1_DISP0_DATA06 = 0,
+   IMX_IOMUXC_DISP0_DAT6_ALT2_ECSPI3_SS3 = 2,
+   IMX_IOMUXC_DISP0_DAT6_ALT3_AUD6_RXC = 3,
+   IMX_IOMUXC_DISP0_DAT6_ALT5_GPIO4_IO27 = 5,
+} IMX_IOMUXC_DISP0_DAT6_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT7_ALT0_IPU1_DISP0_DATA07 = 0,
+   IMX_IOMUXC_DISP0_DAT7_ALT2_ECSPI3_RDY = 2,
+   IMX_IOMUXC_DISP0_DAT7_ALT5_GPIO4_IO28 = 5,
+} IMX_IOMUXC_DISP0_DAT7_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT8_ALT0_IPU1_DISP0_DATA08 = 0,
+   IMX_IOMUXC_DISP0_DAT8_ALT2_PWM1_OUT = 2,
+   IMX_IOMUXC_DISP0_DAT8_ALT3_WDOG1_B = 3,
+   IMX_IOMUXC_DISP0_DAT8_ALT5_GPIO4_IO29 = 5,
+} IMX_IOMUXC_DISP0_DAT8_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT9_ALT0_IPU1_DISP0_DATA09 = 0,
+   IMX_IOMUXC_DISP0_DAT9_ALT2_PWM2_OUT = 2,
+   IMX_IOMUXC_DISP0_DAT9_ALT3_WDOG2_B = 3,
+   IMX_IOMUXC_DISP0_DAT9_ALT5_GPIO4_IO30 = 5,
+} IMX_IOMUXC_DISP0_DAT9_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT10_ALT0_IPU1_DISP0_DATA10 = 0,
+   IMX_IOMUXC_DISP0_DAT10_ALT5_GPIO4_IO31 = 5,
+} IMX_IOMUXC_DISP0_DAT10_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_WAIT_ALT0_EIM_WAIT_B = 0,
+   IMX_IOMUXC_EIM_WAIT_ALT1_EIM_DTACK_B = 1,
+   IMX_IOMUXC_EIM_WAIT_ALT5_GPIO5_IO00 = 5,
+   IMX_IOMUXC_EIM_WAIT_ALT7_SRC_BOOT_CFG25 = 7,
+} IMX_IOMUXC_EIM_WAIT_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A25_ALT0_EIM_ADDR25 = 0,
+   IMX_IOMUXC_EIM_A25_ALT1_ECSPI4_SS1 = 1,
+   IMX_IOMUXC_EIM_A25_ALT2_ECSPI2_RDY = 2,
+   IMX_IOMUXC_EIM_A25_ALT3_IPU1_DI1_PIN12 = 3,
+   IMX_IOMUXC_EIM_A25_ALT4_IPU1_DI0_D1_CS = 4,
+   IMX_IOMUXC_EIM_A25_ALT5_GPIO5_IO02 = 5,
+   IMX_IOMUXC_EIM_A25_ALT6_HDMI_TX_CEC_LINE = 6,
+} IMX_IOMUXC_EIM_A25_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A24_ALT0_EIM_ADDR24 = 0,
+   IMX_IOMUXC_EIM_A24_ALT1_IPU1_DISP1_DATA19 = 1,
+   IMX_IOMUXC_EIM_A24_ALT2_IPU1_CSI1_DATA19 = 2,
+   IMX_IOMUXC_EIM_A24_ALT4_IPU1_SISG2 = 4,
+   IMX_IOMUXC_EIM_A24_ALT5_GPIO5_IO04 = 5,
+   IMX_IOMUXC_EIM_A24_ALT7_SRC_BOOT_CFG24 = 7,
+} IMX_IOMUXC_EIM_A24_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT11_ALT0_IPU1_DISP0_DATA11 = 0,
+   IMX_IOMUXC_DISP0_DAT11_ALT5_GPIO5_IO05 = 5,
+} IMX_IOMUXC_DISP0_DAT11_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT12_ALT0_IPU1_DISP0_DATA12 = 0,
+   IMX_IOMUXC_DISP0_DAT12_ALT5_GPIO5_IO06 = 5,
+} IMX_IOMUXC_DISP0_DAT12_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT13_ALT0_IPU1_DISP0_DATA13 = 0,
+   IMX_IOMUXC_DISP0_DAT13_ALT3_AUD5_RXFS = 3,
+   IMX_IOMUXC_DISP0_DAT13_ALT5_GPIO5_IO07 = 5,
+} IMX_IOMUXC_DISP0_DAT13_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT14_ALT0_IPU1_DISP0_DATA14 = 0,
+   IMX_IOMUXC_DISP0_DAT14_ALT3_AUD5_RXC = 3,
+   IMX_IOMUXC_DISP0_DAT14_ALT5_GPIO5_IO08 = 5,
+} IMX_IOMUXC_DISP0_DAT14_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT15_ALT0_IPU1_DISP0_DATA15 = 0,
+   IMX_IOMUXC_DISP0_DAT15_ALT2_ECSPI1_SS1 = 2,
+   IMX_IOMUXC_DISP0_DAT15_ALT3_ECSPI2_SS1 = 3,
+   IMX_IOMUXC_DISP0_DAT15_ALT5_GPIO5_IO09 = 5,
+} IMX_IOMUXC_DISP0_DAT15_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT16_ALT0_IPU1_DISP0_DATA16 = 0,
+   IMX_IOMUXC_DISP0_DAT16_ALT2_ECSPI2_MOSI = 2,
+   IMX_IOMUXC_DISP0_DAT16_ALT3_AUD5_TXC = 3,
+   IMX_IOMUXC_DISP0_DAT16_ALT4_SDMA_EXT_EVENT0 = 4,
+   IMX_IOMUXC_DISP0_DAT16_ALT5_GPIO5_IO10 = 5,
+} IMX_IOMUXC_DISP0_DAT16_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT17_ALT0_IPU1_DISP0_DATA17 = 0,
+   IMX_IOMUXC_DISP0_DAT17_ALT2_ECSPI2_MISO = 2,
+   IMX_IOMUXC_DISP0_DAT17_ALT3_AUD5_TXD = 3,
+   IMX_IOMUXC_DISP0_DAT17_ALT4_SDMA_EXT_EVENT1 = 4,
+   IMX_IOMUXC_DISP0_DAT17_ALT5_GPIO5_IO11 = 5,
+} IMX_IOMUXC_DISP0_DAT17_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT18_ALT0_IPU1_DISP0_DATA18 = 0,
+   IMX_IOMUXC_DISP0_DAT18_ALT2_ECSPI2_SS0 = 2,
+   IMX_IOMUXC_DISP0_DAT18_ALT3_AUD5_TXFS = 3,
+   IMX_IOMUXC_DISP0_DAT18_ALT4_AUD4_RXFS = 4,
+   IMX_IOMUXC_DISP0_DAT18_ALT5_GPIO5_IO12 = 5,
+   IMX_IOMUXC_DISP0_DAT18_ALT7_EIM_CS2_B = 7,
+} IMX_IOMUXC_DISP0_DAT18_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT19_ALT0_IPU1_DISP0_DATA19 = 0,
+   IMX_IOMUXC_DISP0_DAT19_ALT2_ECSPI2_SCLK = 2,
+   IMX_IOMUXC_DISP0_DAT19_ALT3_AUD5_RXD = 3,
+   IMX_IOMUXC_DISP0_DAT19_ALT4_AUD4_RXC = 4,
+   IMX_IOMUXC_DISP0_DAT19_ALT5_GPIO5_IO13 = 5,
+   IMX_IOMUXC_DISP0_DAT19_ALT7_EIM_CS3_B = 7,
+} IMX_IOMUXC_DISP0_DAT19_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT20_ALT0_IPU1_DISP0_DATA20 = 0,
+   IMX_IOMUXC_DISP0_DAT20_ALT2_ECSPI1_SCLK = 2,
+   IMX_IOMUXC_DISP0_DAT20_ALT3_AUD4_TXC = 3,
+   IMX_IOMUXC_DISP0_DAT20_ALT5_GPIO5_IO14 = 5,
+} IMX_IOMUXC_DISP0_DAT20_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT21_ALT0_IPU1_DISP0_DATA21 = 0,
+   IMX_IOMUXC_DISP0_DAT21_ALT2_ECSPI1_MOSI = 2,
+   IMX_IOMUXC_DISP0_DAT21_ALT3_AUD4_TXD = 3,
+   IMX_IOMUXC_DISP0_DAT21_ALT5_GPIO5_IO15 = 5,
+} IMX_IOMUXC_DISP0_DAT21_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT22_ALT0_IPU1_DISP0_DATA22 = 0,
+   IMX_IOMUXC_DISP0_DAT22_ALT2_ECSPI1_MISO = 2,
+   IMX_IOMUXC_DISP0_DAT22_ALT3_AUD4_TXFS = 3,
+   IMX_IOMUXC_DISP0_DAT22_ALT5_GPIO5_IO16 = 5,
+} IMX_IOMUXC_DISP0_DAT22_ALT;
+
+typedef enum {
+   IMX_IOMUXC_DISP0_DAT23_ALT0_IPU1_DISP0_DATA23 = 0,
+   IMX_IOMUXC_DISP0_DAT23_ALT2_ECSPI1_SS0 = 2,
+   IMX_IOMUXC_DISP0_DAT23_ALT3_AUD4_RXD = 3,
+   IMX_IOMUXC_DISP0_DAT23_ALT5_GPIO5_IO17 = 5,
+} IMX_IOMUXC_DISP0_DAT23_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_PIXCLK_ALT0_IPU1_CSI0_PIXCLK = 0,
+   IMX_IOMUXC_CSI0_PIXCLK_ALT5_GPIO5_IO18 = 5,
+   IMX_IOMUXC_CSI0_PIXCLK_ALT7_ARM_EVENTO = 7,
+} IMX_IOMUXC_CSI0_PIXCLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_MCLK_ALT0_IPU1_CSI0_HSYNC = 0,
+   IMX_IOMUXC_CSI0_MCLK_ALT3_CCM_CLKO1 = 3,
+   IMX_IOMUXC_CSI0_MCLK_ALT5_GPIO5_IO19 = 5,
+   IMX_IOMUXC_CSI0_MCLK_ALT7_ARM_TRACE_CTL = 7,
+} IMX_IOMUXC_CSI0_MCLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DATA_EN_ALT0_IPU1_CSI0_DATA_EN = 0,
+   IMX_IOMUXC_CSI0_DATA_EN_ALT1_EIM_DATA00 = 1,
+   IMX_IOMUXC_CSI0_DATA_EN_ALT5_GPIO5_IO20 = 5,
+   IMX_IOMUXC_CSI0_DATA_EN_ALT7_ARM_TRACE_CLK = 7,
+} IMX_IOMUXC_CSI0_DATA_EN_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_VSYNC_ALT0_IPU1_CSI0_VSYNC = 0,
+   IMX_IOMUXC_CSI0_VSYNC_ALT1_EIM_DATA01 = 1,
+   IMX_IOMUXC_CSI0_VSYNC_ALT5_GPIO5_IO21 = 5,
+   IMX_IOMUXC_CSI0_VSYNC_ALT7_ARM_TRACE00 = 7,
+} IMX_IOMUXC_CSI0_VSYNC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT4_ALT0_IPU1_CSI0_DATA04 = 0,
+   IMX_IOMUXC_CSI0_DAT4_ALT1_EIM_DATA02 = 1,
+   IMX_IOMUXC_CSI0_DAT4_ALT2_ECSPI1_SCLK = 2,
+   IMX_IOMUXC_CSI0_DAT4_ALT3_KEY_COL5 = 3,
+   IMX_IOMUXC_CSI0_DAT4_ALT4_AUD3_TXC = 4,
+   IMX_IOMUXC_CSI0_DAT4_ALT5_GPIO5_IO22 = 5,
+   IMX_IOMUXC_CSI0_DAT4_ALT7_ARM_TRACE01 = 7,
+} IMX_IOMUXC_CSI0_DAT4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT5_ALT0_IPU1_CSI0_DATA05 = 0,
+   IMX_IOMUXC_CSI0_DAT5_ALT1_EIM_DATA03 = 1,
+   IMX_IOMUXC_CSI0_DAT5_ALT2_ECSPI1_MOSI = 2,
+   IMX_IOMUXC_CSI0_DAT5_ALT3_KEY_ROW5 = 3,
+   IMX_IOMUXC_CSI0_DAT5_ALT4_AUD3_TXD = 4,
+   IMX_IOMUXC_CSI0_DAT5_ALT5_GPIO5_IO23 = 5,
+   IMX_IOMUXC_CSI0_DAT5_ALT7_ARM_TRACE02 = 7,
+} IMX_IOMUXC_CSI0_DAT5_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT6_ALT0_IPU1_CSI0_DATA06 = 0,
+   IMX_IOMUXC_CSI0_DAT6_ALT1_EIM_DATA04 = 1,
+   IMX_IOMUXC_CSI0_DAT6_ALT2_ECSPI1_MISO = 2,
+   IMX_IOMUXC_CSI0_DAT6_ALT3_KEY_COL6 = 3,
+   IMX_IOMUXC_CSI0_DAT6_ALT4_AUD3_TXFS = 4,
+   IMX_IOMUXC_CSI0_DAT6_ALT5_GPIO5_IO24 = 5,
+   IMX_IOMUXC_CSI0_DAT6_ALT7_ARM_TRACE03 = 7,
+} IMX_IOMUXC_CSI0_DAT6_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT7_ALT0_IPU1_CSI0_DATA07 = 0,
+   IMX_IOMUXC_CSI0_DAT7_ALT1_EIM_DATA05 = 1,
+   IMX_IOMUXC_CSI0_DAT7_ALT2_ECSPI1_SS0 = 2,
+   IMX_IOMUXC_CSI0_DAT7_ALT3_KEY_ROW6 = 3,
+   IMX_IOMUXC_CSI0_DAT7_ALT4_AUD3_RXD = 4,
+   IMX_IOMUXC_CSI0_DAT7_ALT5_GPIO5_IO25 = 5,
+   IMX_IOMUXC_CSI0_DAT7_ALT7_ARM_TRACE04 = 7,
+} IMX_IOMUXC_CSI0_DAT7_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT8_ALT0_IPU1_CSI0_DATA08 = 0,
+   IMX_IOMUXC_CSI0_DAT8_ALT1_EIM_DATA06 = 1,
+   IMX_IOMUXC_CSI0_DAT8_ALT2_ECSPI2_SCLK = 2,
+   IMX_IOMUXC_CSI0_DAT8_ALT3_KEY_COL7 = 3,
+   IMX_IOMUXC_CSI0_DAT8_ALT4_I2C1_SDA = 4,
+   IMX_IOMUXC_CSI0_DAT8_ALT5_GPIO5_IO26 = 5,
+   IMX_IOMUXC_CSI0_DAT8_ALT7_ARM_TRACE05 = 7,
+} IMX_IOMUXC_CSI0_DAT8_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT9_ALT0_IPU1_CSI0_DATA09 = 0,
+   IMX_IOMUXC_CSI0_DAT9_ALT1_EIM_DATA07 = 1,
+   IMX_IOMUXC_CSI0_DAT9_ALT2_ECSPI2_MOSI = 2,
+   IMX_IOMUXC_CSI0_DAT9_ALT3_KEY_ROW7 = 3,
+   IMX_IOMUXC_CSI0_DAT9_ALT4_I2C1_SCL = 4,
+   IMX_IOMUXC_CSI0_DAT9_ALT5_GPIO5_IO27 = 5,
+   IMX_IOMUXC_CSI0_DAT9_ALT7_ARM_TRACE06 = 7,
+} IMX_IOMUXC_CSI0_DAT9_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT10_ALT0_IPU1_CSI0_DATA10 = 0,
+   IMX_IOMUXC_CSI0_DAT10_ALT1_AUD3_RXC = 1,
+   IMX_IOMUXC_CSI0_DAT10_ALT2_ECSPI2_MISO = 2,
+   IMX_IOMUXC_CSI0_DAT10_ALT3_UART1_TX_DATA = 3,
+   IMX_IOMUXC_CSI0_DAT10_ALT5_GPIO5_IO28 = 5,
+   IMX_IOMUXC_CSI0_DAT10_ALT7_ARM_TRACE07 = 7,
+} IMX_IOMUXC_CSI0_DAT10_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT11_ALT0_IPU1_CSI0_DATA11 = 0,
+   IMX_IOMUXC_CSI0_DAT11_ALT1_AUD3_RXFS = 1,
+   IMX_IOMUXC_CSI0_DAT11_ALT2_ECSPI2_SS0 = 2,
+   IMX_IOMUXC_CSI0_DAT11_ALT3_UART1_RX_DATA = 3,
+   IMX_IOMUXC_CSI0_DAT11_ALT5_GPIO5_IO29 = 5,
+   IMX_IOMUXC_CSI0_DAT11_ALT7_ARM_TRACE08 = 7,
+} IMX_IOMUXC_CSI0_DAT11_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT12_ALT0_IPU1_CSI0_DATA12 = 0,
+   IMX_IOMUXC_CSI0_DAT12_ALT1_EIM_DATA08 = 1,
+   IMX_IOMUXC_CSI0_DAT12_ALT3_UART4_TX_DATA = 3,
+   IMX_IOMUXC_CSI0_DAT12_ALT5_GPIO5_IO30 = 5,
+   IMX_IOMUXC_CSI0_DAT12_ALT7_ARM_TRACE09 = 7,
+} IMX_IOMUXC_CSI0_DAT12_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT13_ALT0_IPU1_CSI0_DATA13 = 0,
+   IMX_IOMUXC_CSI0_DAT13_ALT1_EIM_DATA09 = 1,
+   IMX_IOMUXC_CSI0_DAT13_ALT3_UART4_RX_DATA = 3,
+   IMX_IOMUXC_CSI0_DAT13_ALT5_GPIO5_IO31 = 5,
+   IMX_IOMUXC_CSI0_DAT13_ALT7_ARM_TRACE10 = 7,
+} IMX_IOMUXC_CSI0_DAT13_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT14_ALT0_IPU1_CSI0_DATA14 = 0,
+   IMX_IOMUXC_CSI0_DAT14_ALT1_EIM_DATA10 = 1,
+   IMX_IOMUXC_CSI0_DAT14_ALT3_UART5_TX_DATA = 3,
+   IMX_IOMUXC_CSI0_DAT14_ALT5_GPIO6_IO00 = 5,
+   IMX_IOMUXC_CSI0_DAT14_ALT7_ARM_TRACE11 = 7,
+} IMX_IOMUXC_CSI0_DAT14_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT15_ALT0_IPU1_CSI0_DATA15 = 0,
+   IMX_IOMUXC_CSI0_DAT15_ALT1_EIM_DATA11 = 1,
+   IMX_IOMUXC_CSI0_DAT15_ALT3_UART5_RX_DATA = 3,
+   IMX_IOMUXC_CSI0_DAT15_ALT5_GPIO6_IO01 = 5,
+   IMX_IOMUXC_CSI0_DAT15_ALT7_ARM_TRACE12 = 7,
+} IMX_IOMUXC_CSI0_DAT15_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT16_ALT0_IPU1_CSI0_DATA16 = 0,
+   IMX_IOMUXC_CSI0_DAT16_ALT1_EIM_DATA12 = 1,
+   IMX_IOMUXC_CSI0_DAT16_ALT3_UART4_RTS_B = 3,
+   IMX_IOMUXC_CSI0_DAT16_ALT5_GPIO6_IO02 = 5,
+   IMX_IOMUXC_CSI0_DAT16_ALT7_ARM_TRACE13 = 7,
+} IMX_IOMUXC_CSI0_DAT16_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT17_ALT0_IPU1_CSI0_DATA17 = 0,
+   IMX_IOMUXC_CSI0_DAT17_ALT1_EIM_DATA13 = 1,
+   IMX_IOMUXC_CSI0_DAT17_ALT3_UART4_CTS_B = 3,
+   IMX_IOMUXC_CSI0_DAT17_ALT5_GPIO6_IO03 = 5,
+   IMX_IOMUXC_CSI0_DAT17_ALT7_ARM_TRACE14 = 7,
+} IMX_IOMUXC_CSI0_DAT17_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT18_ALT0_IPU1_CSI0_DATA18 = 0,
+   IMX_IOMUXC_CSI0_DAT18_ALT1_EIM_DATA14 = 1,
+   IMX_IOMUXC_CSI0_DAT18_ALT3_UART5_RTS_B = 3,
+   IMX_IOMUXC_CSI0_DAT18_ALT5_GPIO6_IO04 = 5,
+   IMX_IOMUXC_CSI0_DAT18_ALT7_ARM_TRACE15 = 7,
+} IMX_IOMUXC_CSI0_DAT18_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI0_DAT19_ALT0_IPU1_CSI0_DATA19 = 0,
+   IMX_IOMUXC_CSI0_DAT19_ALT1_EIM_DATA15 = 1,
+   IMX_IOMUXC_CSI0_DAT19_ALT3_UART5_CTS_B = 3,
+   IMX_IOMUXC_CSI0_DAT19_ALT5_GPIO6_IO05 = 5,
+} IMX_IOMUXC_CSI0_DAT19_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_A23_ALT0_EIM_ADDR23 = 0,
+   IMX_IOMUXC_EIM_A23_ALT1_IPU1_DISP1_DATA18 = 1,
+   IMX_IOMUXC_EIM_A23_ALT2_IPU1_CSI1_DATA18 = 2,
+   IMX_IOMUXC_EIM_A23_ALT4_IPU1_SISG3 = 4,
+   IMX_IOMUXC_EIM_A23_ALT5_GPIO6_IO06 = 5,
+   IMX_IOMUXC_EIM_A23_ALT7_SRC_BOOT_CFG23 = 7,
+   IMX_IOMUXC_EIM_A23_ALT8_EPDC_GDOE = 8
+} IMX_IOMUXC_EIM_A23_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_CLE_ALT0_NAND_CLE = 0,
+   IMX_IOMUXC_NANDF_CLE_ALT5_GPIO6_IO07 = 5,
+} IMX_IOMUXC_NANDF_CLE_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_ALE_ALT0_NAND_ALE = 0,
+   IMX_IOMUXC_NANDF_ALE_ALT1_SD4_RESET = 1,
+   IMX_IOMUXC_NANDF_ALE_ALT5_GPIO6_IO08 = 5,
+} IMX_IOMUXC_NANDF_ALE_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_WP_B_ALT0_NAND_WP_B = 0,
+   IMX_IOMUXC_NANDF_WP_B_ALT5_GPIO6_IO09 = 5,
+   IMX_IOMUXC_NANDF_WP_B_ALT9_I2C4_SCL = 9
+} IMX_IOMUXC_NANDF_WP_B_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_RB0_ALT0_NAND_READY_B = 0,
+   IMX_IOMUXC_NANDF_RB0_ALT5_GPIO6_IO10 = 5,
+} IMX_IOMUXC_NANDF_RB0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_CS0_ALT0_NAND_CE0_B = 0,
+   IMX_IOMUXC_NANDF_CS0_ALT5_GPIO6_IO11 = 5,
+} IMX_IOMUXC_NANDF_CS0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_CS1_ALT0_NAND_CE1_B = 0,
+   IMX_IOMUXC_NANDF_CS1_ALT1_SD4_VSELECT = 1,
+   IMX_IOMUXC_NANDF_CS1_ALT2_SD3_VSELECT = 2,
+   IMX_IOMUXC_NANDF_CS1_ALT5_GPIO6_IO14 = 5,
+} IMX_IOMUXC_NANDF_CS1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_CS2_ALT0_NAND_CE2_B = 0,
+   IMX_IOMUXC_NANDF_CS2_ALT1_IPU1_SISG0 = 1,
+   IMX_IOMUXC_NANDF_CS2_ALT2_ESAI_TX0 = 2,
+   IMX_IOMUXC_NANDF_CS2_ALT3_EIM_CRE = 3,
+   IMX_IOMUXC_NANDF_CS2_ALT4_CCM_CLKO2 = 4,
+   IMX_IOMUXC_NANDF_CS2_ALT5_GPIO6_IO15 = 5
+} IMX_IOMUXC_NANDF_CS2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NANDF_CS3_ALT0_NAND_CE3_B = 0,
+   IMX_IOMUXC_NANDF_CS3_ALT1_IPU1_SISG1 = 1,
+   IMX_IOMUXC_NANDF_CS3_ALT2_ESAI_TX1 = 2,
+   IMX_IOMUXC_NANDF_CS3_ALT3_EIM_ADDR26 = 3,
+   IMX_IOMUXC_NANDF_CS3_ALT5_GPIO6_IO16 = 5,
+   IMX_IOMUXC_NANDF_CS3_ALT6_I2C4_SDA = 9,
+} IMX_IOMUXC_NANDF_CS3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DAT7_ALT0_SD3_DATA7 = 0,
+   IMX_IOMUXC_SD3_DAT7_ALT1_UART1_TX_DATA = 1,
+   IMX_IOMUXC_SD3_DAT7_ALT5_GPIO6_IO17 = 5,
+} IMX_IOMUXC_SD3_DAT7_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DAT6_ALT0_SD3_DATA6 = 0,
+   IMX_IOMUXC_SD3_DAT6_ALT1_UART1_RX_DATA = 1,
+   IMX_IOMUXC_SD3_DAT6_ALT5_GPIO6_IO18 = 5,
+} IMX_IOMUXC_SD3_DAT6_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_TXC_ALT0_USB_H2_DATA = 0,
+   IMX_IOMUXC_RGMII_TXC_ALT1_RGMII_TXC = 1,
+   IMX_IOMUXC_RGMII_TXC_ALT2_SPDIF_EXT_CLK = 2,
+   IMX_IOMUXC_RGMII_TXC_ALT5_GPIO6_IO19 = 5,
+   IMX_IOMUXC_RGMII_TXC_ALT7_XTALOSC_REF_CLK_24M = 7,
+} IMX_IOMUXC_RGMII_TXC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_TD0_ALT0_HSI_TX_READY = 0,
+   IMX_IOMUXC_RGMII_TD0_ALT1_RGMII_TD0 = 1,
+   IMX_IOMUXC_RGMII_TD0_ALT5_GPIO6_IO20 = 5,
+} IMX_IOMUXC_RGMII_TD0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_TD1_ALT0_HSI_RX_FLAG = 0,
+   IMX_IOMUXC_RGMII_TD1_ALT1_RGMII_TD1 = 1,
+   IMX_IOMUXC_RGMII_TD1_ALT5_GPIO6_IO21 = 5,
+} IMX_IOMUXC_RGMII_TD1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_TD2_ALT0_HSI_RX_DATA = 0,
+   IMX_IOMUXC_RGMII_TD2_ALT1_RGMII_TD2 = 1,
+   IMX_IOMUXC_RGMII_TD2_ALT5_GPIO6_IO22 = 5,
+} IMX_IOMUXC_RGMII_TD2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_TD3_ALT0_HSI_RX_WAKE = 0,
+   IMX_IOMUXC_RGMII_TD3_ALT1_RGMII_TD3 = 1,
+   IMX_IOMUXC_RGMII_TD3_ALT5_GPIO6_IO23 = 5,
+} IMX_IOMUXC_RGMII_TD3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_RX_CTL_ALT0_USB_H3_DATA = 0,
+   IMX_IOMUXC_RGMII_RX_CTL_ALT1_RGMII_RX_CTL = 1,
+   IMX_IOMUXC_RGMII_RX_CTL_ALT5_GPIO6_IO24 = 5,
+} IMX_IOMUXC_RGMII_RX_CTL_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_RD0_ALT0_HSI_RX_READY = 0,
+   IMX_IOMUXC_RGMII_RD0_ALT1_RGMII_RD0 = 1,
+   IMX_IOMUXC_RGMII_RD0_ALT5_GPIO6_IO25 = 5,
+} IMX_IOMUXC_RGMII_RD0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_TX_CTL_ALT0_USB_H2_STROBE = 0,
+   IMX_IOMUXC_RGMII_TX_CTL_ALT1_RGMII_TX_CTL = 1,
+   IMX_IOMUXC_RGMII_TX_CTL_ALT5_GPIO6_IO26 = 5,
+   IMX_IOMUXC_RGMII_TX_CTL_ALT7_ENET_REF_CLK = 7,
+} IMX_IOMUXC_RGMII_TX_CTL_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_RD1_ALT0_HSI_TX_FLAG = 0,
+   IMX_IOMUXC_RGMII_RD1_ALT1_RGMII_RD1 = 1,
+   IMX_IOMUXC_RGMII_RD1_ALT5_GPIO6_IO27 = 5,
+} IMX_IOMUXC_RGMII_RD1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_RD2_ALT0_HSI_TX_DATA = 0,
+   IMX_IOMUXC_RGMII_RD2_ALT1_RGMII_RD2 = 1,
+   IMX_IOMUXC_RGMII_RD2_ALT5_GPIO6_IO28 = 5,
+} IMX_IOMUXC_RGMII_RD2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_RD3_ALT0_HSI_TX_WAKE = 0,
+   IMX_IOMUXC_RGMII_RD3_ALT1_RGMII_RD3 = 1,
+   IMX_IOMUXC_RGMII_RD3_ALT5_GPIO6_IO29 = 5,
+} IMX_IOMUXC_RGMII_RD3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII_RXC_ALT0_USB_H3_STROBE = 0,
+   IMX_IOMUXC_RGMII_RXC_ALT1_RGMII_RXC = 1,
+   IMX_IOMUXC_RGMII_RXC_ALT5_GPIO6_IO30 = 5,
+} IMX_IOMUXC_RGMII_RXC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_EIM_BCLK_ALT0_EIM_BCLK = 0,
+   IMX_IOMUXC_EIM_BCLK_ALT1_IPU1_DI1_PIN16 = 1,
+   IMX_IOMUXC_EIM_BCLK_ALT5_GPIO6_IO31 = 5,
+} IMX_IOMUXC_EIM_BCLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DAT5_ALT0_SD3_DATA5 = 0,
+   IMX_IOMUXC_SD3_DAT5_ALT1_UART2_TX_DATA = 1,
+   IMX_IOMUXC_SD3_DAT5_ALT5_GPIO7_IO00 = 5,
+} IMX_IOMUXC_SD3_DAT5_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DAT4_ALT0_SD3_DATA4 = 0,
+   IMX_IOMUXC_SD3_DAT4_ALT1_UART2_RX_DATA = 1,
+   IMX_IOMUXC_SD3_DAT4_ALT5_GPIO7_IO01 = 5,
+} IMX_IOMUXC_SD3_DAT4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_CMD_ALT0_SD3_CMD = 0,
+   IMX_IOMUXC_SD3_CMD_ALT1_UART2_CTS_B = 1,
+   IMX_IOMUXC_SD3_CMD_ALT2_FLEXCAN1_TX = 2,
+   IMX_IOMUXC_SD3_CMD_ALT5_GPIO7_IO02 = 5,
+} IMX_IOMUXC_SD3_CMD_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_CLK_ALT0_SD3_CLK = 0,
+   IMX_IOMUXC_SD3_CLK_ALT1_UART2_RTS_B = 1,
+   IMX_IOMUXC_SD3_CLK_ALT2_FLEXCAN1_RX = 2,
+   IMX_IOMUXC_SD3_CLK_ALT5_GPIO7_IO03 = 5,
+} IMX_IOMUXC_SD3_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DAT0_ALT0_SD3_DATA0 = 0,
+   IMX_IOMUXC_SD3_DAT0_ALT1_UART1_CTS_B = 1,
+   IMX_IOMUXC_SD3_DAT0_ALT2_FLEXCAN2_TX = 2,
+   IMX_IOMUXC_SD3_DAT0_ALT5_GPIO7_IO04 = 5,
+} IMX_IOMUXC_SD3_DAT0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DAT1_ALT0_SD3_DATA1 = 0,
+   IMX_IOMUXC_SD3_DAT1_ALT1_UART1_RTS_B = 1,
+   IMX_IOMUXC_SD3_DAT1_ALT2_FLEXCAN2_RX = 2,
+   IMX_IOMUXC_SD3_DAT1_ALT5_GPIO7_IO05 = 5,
+} IMX_IOMUXC_SD3_DAT1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DAT2_ALT0_SD3_DATA2 = 0,
+   IMX_IOMUXC_SD3_DAT2_ALT5_GPIO7_IO06 = 5,
+} IMX_IOMUXC_SD3_DAT2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DAT3_ALT0_SD3_DATA3 = 0,
+   IMX_IOMUXC_SD3_DAT3_ALT1_UART3_CTS_B = 1,
+   IMX_IOMUXC_SD3_DAT3_ALT5_GPIO7_IO07 = 5,
+} IMX_IOMUXC_SD3_DAT3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_RST_ALT0_SD3_RESET = 0,
+   IMX_IOMUXC_SD3_RST_ALT1_UART3_RTS_B = 1,
+   IMX_IOMUXC_SD3_RST_ALT5_GPIO7_IO08 = 5,
+} IMX_IOMUXC_SD3_RST_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_CMD_ALT0_SD4_CMD = 0,
+   IMX_IOMUXC_SD4_CMD_ALT1_NAND_RE_B = 1,
+   IMX_IOMUXC_SD4_CMD_ALT2_UART3_TX_DATA = 2,
+   IMX_IOMUXC_SD4_CMD_ALT5_GPIO7_IO09 = 5,
+} IMX_IOMUXC_SD4_CMD_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_CLK_ALT0_SD4_CLK = 0,
+   IMX_IOMUXC_SD4_CLK_ALT1_NAND_WE_B = 1,
+   IMX_IOMUXC_SD4_CLK_ALT2_UART3_RX_DATA = 2,
+   IMX_IOMUXC_SD4_CLK_ALT5_GPIO7_IO10 = 5,
+} IMX_IOMUXC_SD4_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_16_ALT0_ESAI_TX3_RX2 = 0,
+   IMX_IOMUXC_GPIO_16_ALT1_ENET_1588_EVENT2_IN = 1,
+   IMX_IOMUXC_GPIO_16_ALT2_ENET_REF_CLK = 2,
+   IMX_IOMUXC_GPIO_16_ALT3_SD1_LCTL = 3,    // out LED
+   IMX_IOMUXC_GPIO_16_ALT4_SPDIF_IN = 4,
+   IMX_IOMUXC_GPIO_16_ALT5_GPIO7_IO11 = 5,
+   IMX_IOMUXC_GPIO_16_ALT6_I2C3_SDA = 6,
+   IMX_IOMUXC_GPIO_16_ALT7_JTAG_DE_B = 7,
+} IMX_IOMUXC_GPIO_16_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_17_ALT0_ESAI_TX0 = 0,
+   IMX_IOMUXC_GPIO_17_ALT1_ENET_1588_EVENT3_IN = 1,
+   IMX_IOMUXC_GPIO_17_ALT2_CCM_PMIC_READY = 2,
+   IMX_IOMUXC_GPIO_17_ALT3_SDMA_EXT_EVENT0 = 3,
+   IMX_IOMUXC_GPIO_17_ALT4_SPDIF_OUT = 4,
+   IMX_IOMUXC_GPIO_17_ALT5_GPIO7_IO12 = 5,
+} IMX_IOMUXC_GPIO_17_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO_18_ALT0_ESAI_TX1 = 0,
+   IMX_IOMUXC_GPIO_18_ALT1_ENET_RX_CLK = 1,
+   IMX_IOMUXC_GPIO_18_ALT2_SD3_VSELECT = 2,
+   IMX_IOMUXC_GPIO_18_ALT3_SDMA_EXT_EVENT1 = 3,
+   IMX_IOMUXC_GPIO_18_ALT4_ASRC_EXT_CLK = 4,
+   IMX_IOMUXC_GPIO_18_ALT5_GPIO7_IO13 = 5,
+   IMX_IOMUXC_GPIO_18_ALT6_SNVS_VIO_5_CTL = 6,
+} IMX_IOMUXC_GPIO_18_ALT;
+
+typedef enum {
+    IMX_IOMUXC_ECSPI1_MISO_EIM_DATA17_ALT1 = 0,
+    IMX_IOMUXC_ECSPI1_MISO_DISP0_DATA22_ALT2 = 1,
+    IMX_IOMUXC_ECSPI1_MISO_KEY_COL1_ALT0 = 2,
+    IMX_IOMUXC_ECSPI1_MISO_CSI0_DATA06_ALT2 = 3,
+} IMX_IOMUXC_ECSPI1_MISO_SELECT_INPUT;
+
+typedef enum {
+    IMX_IOMUXC_ECSPI2_MISO_EIM_OE_B_ALT2 = 0,
+    IMX_IOMUXC_ECSPI2_MISO_DISP0_DATA17_ALT2 = 1,
+    IMX_IOMUXC_ECSPI2_MISO_CSI0_DATA10_ALT2 = 2,
+} IMX_IOMUXC_ECSPI2_MISO_SELECT_INPUT;
+
+#endif // _IMX6_IOMUX_SDL_H_
diff --git a/Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_SX.h b/Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_SX.h
new file mode 100644
index 000000000000..aa3732f16b18
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Include/iMX6IoMux_SX.h
@@ -0,0 +1,2275 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _IMX6_IOMUX_SX_H_
+#define _IMX6_IOMUX_SX_H_
+
+//
+// IMX_PAD register defines.
+//
+typedef enum {
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO00)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO00)
+   IMX_PAD_GPIO1_IO00 = _IMX_PAD(0x35C, 0x14), // I2C1_SCL
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO01)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO01)
+   IMX_PAD_GPIO1_IO01 = _IMX_PAD(0x360, 0x18), // I2C1_SDA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO02)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO02)
+   IMX_PAD_GPIO1_IO02 = _IMX_PAD(0x364, 0x1C), // I2C2_SCL
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO03)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO03)
+   IMX_PAD_GPIO1_IO03 = _IMX_PAD(0x368, 0x20), // I2C2_SDA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO04)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO04)
+   IMX_PAD_GPIO1_IO04 = _IMX_PAD(0x36C, 0x24), // UART1_TX_DATA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO05)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO05)
+   IMX_PAD_GPIO1_IO05 = _IMX_PAD(0x370, 0x28), // UART1_RX_DATA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO06)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO06)
+   IMX_PAD_GPIO1_IO06 = _IMX_PAD(0x374, 0x2C), // UART2_TX_DATA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO07)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO07)
+   IMX_PAD_GPIO1_IO07 = _IMX_PAD(0x378, 0x30), // UART2_RX_DATA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO08)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO08)
+   IMX_PAD_GPIO1_IO08 = _IMX_PAD(0x37C, 0x34), // USB_OTG1_OC
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO09)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO09)
+   IMX_PAD_GPIO1_IO09 = _IMX_PAD(0x380, 0x38), // USB_OTG1_PWR
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO10)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO10)
+   IMX_PAD_GPIO1_IO10 = _IMX_PAD(0x384, 0x3C), // USB_OTG1_ID
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO11)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO11)
+   IMX_PAD_GPIO1_IO11 = _IMX_PAD(0x388, 0x40), // USB_OTG2_OC
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO12)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO12)
+   IMX_PAD_GPIO1_IO12 = _IMX_PAD(0x38C, 0x44), // USB_OTG2_PWR
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_GPIO1_IO13)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_GPIO1_IO13)
+   IMX_PAD_GPIO1_IO13 = _IMX_PAD(0x390, 0x48), // WDOG1_ANY
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI_DATA00)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI_DATA00)
+   IMX_PAD_CSI_DATA00 = _IMX_PAD(0x394, 0x4C), // CSI1_DATA02
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI_DATA01)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI_DATA01)
+   IMX_PAD_CSI_DATA01 = _IMX_PAD(0x398, 0x50), // CSI1_DATA03
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI_DATA02)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI_DATA02)
+   IMX_PAD_CSI_DATA02 = _IMX_PAD(0x39C, 0x54), // CSI1_DATA04
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI_DATA03)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI_DATA03)
+   IMX_PAD_CSI_DATA03 = _IMX_PAD(0x3A0, 0x58), // CSI1_DATA05
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI_DATA04)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI_DATA04)
+   IMX_PAD_CSI_DATA04 = _IMX_PAD(0x3A4, 0x5C), // CSI1_DATA06
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI_DATA05)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI_DATA05)
+   IMX_PAD_CSI_DATA05 = _IMX_PAD(0x3A8, 0x60), // CSI1_DATA07
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI_DATA06)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI_DATA06)
+   IMX_PAD_CSI_DATA06 = _IMX_PAD(0x3AC, 0x64), // CSI1_DATA08
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI_DATA07)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI_DATA07)
+   IMX_PAD_CSI_DATA07 = _IMX_PAD(0x3B0, 0x68), // CSI1_DATA09
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI_HSYNC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI_HSYNC)
+   IMX_PAD_CSI_HSYNC = _IMX_PAD(0x3B4, 0x6C), // CSI1_HSYNC
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI_MCLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI_MCLK)
+   IMX_PAD_CSI_MCLK = _IMX_PAD(0x3B8, 0x70), // CSI1_MCLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI_PIXCLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI_PIXCLK)
+   IMX_PAD_CSI_PIXCLK = _IMX_PAD(0x3BC, 0x74), // CSI1_PIXCLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_CSI_VSYNC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_CSI_VSYNC)
+   IMX_PAD_CSI_VSYNC = _IMX_PAD(0x3C0, 0x78), // CSI1_VSYNC
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET1_COL)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET1_COL)
+   IMX_PAD_ENET1_COL = _IMX_PAD(0x3C4, 0x7C), // ENET1_COL
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET1_CRS)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET1_CRS)
+   IMX_PAD_ENET1_CRS = _IMX_PAD(0x3C8, 0x80), // ENET1_CRS
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET1_MDC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET1_MDC)
+   IMX_PAD_ENET1_MDC = _IMX_PAD(0x3CC, 0x84), // ENET1_MDC
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET1_MDIO)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET1_MDIO)
+   IMX_PAD_ENET1_MDIO = _IMX_PAD(0x3D0, 0x88), // ENET1_MDIO
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET1_RX_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET1_RX_CLK)
+   IMX_PAD_ENET1_RX_CLK = _IMX_PAD(0x3D4, 0x8C), // ENET1_RX_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET1_TX_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET1_TX_CLK)
+   IMX_PAD_ENET1_TX_CLK = _IMX_PAD(0x3D8, 0x90), // ENET1_TX_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET2_COL)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET2_COL)
+   IMX_PAD_ENET2_COL = _IMX_PAD(0x3DC, 0x94), // ENET2_COL
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET2_CRS)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET2_CRS)
+   IMX_PAD_ENET2_CRS = _IMX_PAD(0x3E0, 0x98), // ENET2_CRS
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET2_RX_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET2_RX_CLK)
+   IMX_PAD_ENET2_RX_CLK = _IMX_PAD(0x3E4, 0x9C), // ENET2_RX_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_ENET2_TX_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_ENET2_TX_CLK)
+   IMX_PAD_ENET2_TX_CLK = _IMX_PAD(0x3E8, 0xA0), // ENET2_TX_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_COL0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_COL0)
+   IMX_PAD_KEY_COL0 = _IMX_PAD(0x3EC, 0xA4), // KPP_COL0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_COL1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_COL1)
+   IMX_PAD_KEY_COL1 = _IMX_PAD(0x3F0, 0xA8), // KPP_COL1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_COL2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_COL2)
+   IMX_PAD_KEY_COL2 = _IMX_PAD(0x3F4, 0xAC), // KPP_COL2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_COL3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_COL3)
+   IMX_PAD_KEY_COL3 = _IMX_PAD(0x3F8, 0xB0), // KPP_COL3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_COL4)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_COL4)
+   IMX_PAD_KEY_COL4 = _IMX_PAD(0x3FC, 0xB4), // KPP_COL4
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_ROW0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_ROW0)
+   IMX_PAD_KEY_ROW0 = _IMX_PAD(0x400, 0xB8), // KPP_ROW0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_ROW1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_ROW1)
+   IMX_PAD_KEY_ROW1 = _IMX_PAD(0x404, 0xBC), // KPP_ROW1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_ROW2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_ROW2)
+   IMX_PAD_KEY_ROW2 = _IMX_PAD(0x408, 0xC0), // KPP_ROW2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_ROW3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_ROW3)
+   IMX_PAD_KEY_ROW3 = _IMX_PAD(0x40C, 0xC4), // KPP_ROW3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_KEY_ROW4)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_KEY_ROW4)
+   IMX_PAD_KEY_ROW4 = _IMX_PAD(0x410, 0xC8), // KPP_ROW4
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_CLK)
+   IMX_PAD_LCD1_CLK = _IMX_PAD(0x414, 0xCC), // LCD1_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA00)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA00)
+   IMX_PAD_LCD1_DATA00 = _IMX_PAD(0x418, 0xD0), // LCD1_DATA00
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA01)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA01)
+   IMX_PAD_LCD1_DATA01 = _IMX_PAD(0x41C, 0xD4), // LCD1_DATA01
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA02)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA02)
+   IMX_PAD_LCD1_DATA02 = _IMX_PAD(0x420, 0xD8), // LCD1_DATA02
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA03)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA03)
+   IMX_PAD_LCD1_DATA03 = _IMX_PAD(0x424, 0xDC), // LCD1_DATA03
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA04)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA04)
+   IMX_PAD_LCD1_DATA04 = _IMX_PAD(0x428, 0xE0), // LCD1_DATA04
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA05)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA05)
+   IMX_PAD_LCD1_DATA05 = _IMX_PAD(0x42C, 0xE4), // LCD1_DATA05
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA06)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA06)
+   IMX_PAD_LCD1_DATA06 = _IMX_PAD(0x430, 0xE8), // LCD1_DATA06
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA07)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA07)
+   IMX_PAD_LCD1_DATA07 = _IMX_PAD(0x434, 0xEC), // LCD1_DATA07
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA08)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA08)
+   IMX_PAD_LCD1_DATA08 = _IMX_PAD(0x438, 0xF0), // LCD1_DATA08
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA09)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA09)
+   IMX_PAD_LCD1_DATA09 = _IMX_PAD(0x43C, 0xF4), // LCD1_DATA09
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA10)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA10)
+   IMX_PAD_LCD1_DATA10 = _IMX_PAD(0x440, 0xF8), // LCD1_DATA10
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA11)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA11)
+   IMX_PAD_LCD1_DATA11 = _IMX_PAD(0x444, 0xFC), // LCD1_DATA11
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA12)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA12)
+   IMX_PAD_LCD1_DATA12 = _IMX_PAD(0x448, 0x100), // LCD1_DATA12
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA13)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA13)
+   IMX_PAD_LCD1_DATA13 = _IMX_PAD(0x44C, 0x104), // LCD1_DATA13
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA14)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA14)
+   IMX_PAD_LCD1_DATA14 = _IMX_PAD(0x450, 0x108), // LCD1_DATA14
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA15)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA15)
+   IMX_PAD_LCD1_DATA15 = _IMX_PAD(0x454, 0x10C), // LCD1_DATA15
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA16)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA16)
+   IMX_PAD_LCD1_DATA16 = _IMX_PAD(0x458, 0x110), // LCD1_DATA16
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA17)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA17)
+   IMX_PAD_LCD1_DATA17 = _IMX_PAD(0x45C, 0x114), // LCD1_DATA17
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA18)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA18)
+   IMX_PAD_LCD1_DATA18 = _IMX_PAD(0x460, 0x118), // LCD1_DATA18
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA19)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA19)
+   IMX_PAD_LCD1_DATA19 = _IMX_PAD(0x464, 0x11C), // LCD1_DATA19
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA20)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA20)
+   IMX_PAD_LCD1_DATA20 = _IMX_PAD(0x468, 0x120), // LCD1_DATA20
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA21)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA21)
+   IMX_PAD_LCD1_DATA21 = _IMX_PAD(0x46C, 0x124), // LCD1_DATA21
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA22)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA22)
+   IMX_PAD_LCD1_DATA22 = _IMX_PAD(0x470, 0x128), // LCD1_DATA22
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_DATA23)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_DATA23)
+   IMX_PAD_LCD1_DATA23 = _IMX_PAD(0x474, 0x12C), // LCD1_DATA23
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_ENABLE)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_ENABLE)
+   IMX_PAD_LCD1_ENABLE = _IMX_PAD(0x478, 0x130), // LCD1_ENABLE
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_HSYNC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_HSYNC)
+   IMX_PAD_LCD1_HSYNC = _IMX_PAD(0x47C, 0x134), // LCD1_HSYNC
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_RESET)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_RESET)
+   IMX_PAD_LCD1_RESET = _IMX_PAD(0x480, 0x138), // LCD1_RESET
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_LCD1_VSYNC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_LCD1_VSYNC)
+   IMX_PAD_LCD1_VSYNC = _IMX_PAD(0x484, 0x13C), // LCD1_VSYNC
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_ALE)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_ALE)
+   IMX_PAD_NAND_ALE = _IMX_PAD(0x488, 0x140), // NAND_ALE
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_CE0_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_CE0_B)
+   IMX_PAD_NAND_CE0_B = _IMX_PAD(0x48C, 0x144), // NAND_CE0_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_CE1_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_CE1_B)
+   IMX_PAD_NAND_CE1_B = _IMX_PAD(0x490, 0x148), // NAND_CE1_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_CLE)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_CLE)
+   IMX_PAD_NAND_CLE = _IMX_PAD(0x494, 0x14C), // NAND_CLE
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA00)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA00)
+   IMX_PAD_NAND_DATA00 = _IMX_PAD(0x498, 0x150), // NAND_DATA00
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA01)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA01)
+   IMX_PAD_NAND_DATA01 = _IMX_PAD(0x49C, 0x154), // NAND_DATA01
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA02)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA02)
+   IMX_PAD_NAND_DATA02 = _IMX_PAD(0x4A0, 0x158), // NAND_DATA02
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA03)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA03)
+   IMX_PAD_NAND_DATA03 = _IMX_PAD(0x4A4, 0x15C), // NAND_DATA03
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA04)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA04)
+   IMX_PAD_NAND_DATA04 = _IMX_PAD(0x4A8, 0x160), // NAND_DATA04
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA05)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA05)
+   IMX_PAD_NAND_DATA05 = _IMX_PAD(0x4AC, 0x164), // NAND_DATA05
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA06)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA06)
+   IMX_PAD_NAND_DATA06 = _IMX_PAD(0x4B0, 0x168), // NAND_DATA06
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_DATA07)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_DATA07)
+   IMX_PAD_NAND_DATA07 = _IMX_PAD(0x4B4, 0x16C), // NAND_DATA07
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_RE_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_RE_B)
+   IMX_PAD_NAND_RE_B = _IMX_PAD(0x4B8, 0x170), // NAND_RE_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_READY_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_READY_B)
+   IMX_PAD_NAND_READY_B = _IMX_PAD(0x4BC, 0x174), // NAND_READY_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_WE_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_WE_B)
+   IMX_PAD_NAND_WE_B = _IMX_PAD(0x4C0, 0x178), // NAND_WE_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_NAND_WP_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_NAND_WP_B)
+   IMX_PAD_NAND_WP_B = _IMX_PAD(0x4C4, 0x17C), // NAND_WP_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_QSPI1A_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_QSPI1A_DATA0)
+   IMX_PAD_QSPI1A_DATA0 = _IMX_PAD(0x4C8, 0x180), // QSPI1A_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_QSPI1A_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_QSPI1A_DATA1)
+   IMX_PAD_QSPI1A_DATA1 = _IMX_PAD(0x4CC, 0x184), // QSPI1A_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_QSPI1A_DATA2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_QSPI1A_DATA2)
+   IMX_PAD_QSPI1A_DATA2 = _IMX_PAD(0x4D0, 0x188), // QSPI1A_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_QSPI1A_DATA3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_QSPI1A_DATA3)
+   IMX_PAD_QSPI1A_DATA3 = _IMX_PAD(0x4D4, 0x18C), // QSPI1A_DATA3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_QSPI1A_DQS)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_QSPI1A_DQS)
+   IMX_PAD_QSPI1A_DQS = _IMX_PAD(0x4D8, 0x190), // QSPI1A_DQS
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_QSPI1A_SCLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_QSPI1A_SCLK)
+   IMX_PAD_QSPI1A_SCLK = _IMX_PAD(0x4DC, 0x194), // QSPI1A_SCLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_QSPI1A_SS0_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_QSPI1A_SS0_B)
+   IMX_PAD_QSPI1A_SS0_B = _IMX_PAD(0x4E0, 0x198), // QSPI1A_SS0_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_QSPI1A_SS1_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_QSPI1A_SS1_B)
+   IMX_PAD_QSPI1A_SS1_B = _IMX_PAD(0x4E4, 0x19C), // QSPI1A_SS1_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_QSPI1B_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_QSPI1B_DATA0)
+   IMX_PAD_QSPI1B_DATA0 = _IMX_PAD(0x4E8, 0x1A0), // QSPI1B_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_QSPI1B_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_QSPI1B_DATA1)
+   IMX_PAD_QSPI1B_DATA1 = _IMX_PAD(0x4EC, 0x1A4), // QSPI1B_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_QSPI1B_DATA2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_QSPI1B_DATA2)
+   IMX_PAD_QSPI1B_DATA2 = _IMX_PAD(0x4F0, 0x1A8), // QSPI1B_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_QSPI1B_DATA3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_QSPI1B_DATA3)
+   IMX_PAD_QSPI1B_DATA3 = _IMX_PAD(0x4F4, 0x1AC), // QSPI1B_DATA3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_QSPI1B_DQS)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_QSPI1B_DQS)
+   IMX_PAD_QSPI1B_DQS = _IMX_PAD(0x4F8, 0x1B0), // QSPI1B_DQS
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_QSPI1B_SCLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_QSPI1B_SCLK)
+   IMX_PAD_QSPI1B_SCLK = _IMX_PAD(0x4FC, 0x1B4), // QSPI1B_SCLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_QSPI1B_SS0_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_QSPI1B_SS0_B)
+   IMX_PAD_QSPI1B_SS0_B = _IMX_PAD(0x500, 0x1B8), // QSPI1B_SS0_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_QSPI1B_SS1_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_QSPI1B_SS1_B)
+   IMX_PAD_QSPI1B_SS1_B = _IMX_PAD(0x504, 0x1BC), // QSPI1B_SS1_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII1_RD0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII1_RD0)
+   IMX_PAD_RGMII1_RD0 = _IMX_PAD(0x508, 0x1C0), // ENET1_RX_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII1_RD1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII1_RD1)
+   IMX_PAD_RGMII1_RD1 = _IMX_PAD(0x50C, 0x1C4), // ENET1_RX_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII1_RD2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII1_RD2)
+   IMX_PAD_RGMII1_RD2 = _IMX_PAD(0x510, 0x1C8), // ENET1_RX_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII1_RD3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII1_RD3)
+   IMX_PAD_RGMII1_RD3 = _IMX_PAD(0x514, 0x1CC), // ENET1_RX_DATA3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII1_RX_CTL)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII1_RX_CTL)
+   IMX_PAD_RGMII1_RX_CTL = _IMX_PAD(0x518, 0x1D0), // ENET1_RX_EN
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII1_RXC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII1_RXC)
+   IMX_PAD_RGMII1_RXC = _IMX_PAD(0x51C, 0x1D4), // ENET1_RGMII_RXC
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII1_TD0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII1_TD0)
+   IMX_PAD_RGMII1_TD0 = _IMX_PAD(0x520, 0x1D8), // ENET1_TX_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII1_TD1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII1_TD1)
+   IMX_PAD_RGMII1_TD1 = _IMX_PAD(0x524, 0x1DC), // ENET1_TX_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII1_TD2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII1_TD2)
+   IMX_PAD_RGMII1_TD2 = _IMX_PAD(0x528, 0x1E0), // ENET1_TX_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII1_TD3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII1_TD3)
+   IMX_PAD_RGMII1_TD3 = _IMX_PAD(0x52C, 0x1E4), // ENET1_TX_DATA3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII1_TX_CTL)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII1_TX_CTL)
+   IMX_PAD_RGMII1_TX_CTL = _IMX_PAD(0x530, 0x1E8), // ENET1_TX_EN
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII1_TXC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII1_TXC)
+   IMX_PAD_RGMII1_TXC = _IMX_PAD(0x534, 0x1EC), // ENET1_RGMII_TXC
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII2_RD0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII2_RD0)
+   IMX_PAD_RGMII2_RD0 = _IMX_PAD(0x538, 0x1F0), // ENET2_RX_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII2_RD1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII2_RD1)
+   IMX_PAD_RGMII2_RD1 = _IMX_PAD(0x53C, 0x1F4), // ENET2_RX_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII2_RD2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII2_RD2)
+   IMX_PAD_RGMII2_RD2 = _IMX_PAD(0x540, 0x1F8), // ENET2_RX_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII2_RD3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII2_RD3)
+   IMX_PAD_RGMII2_RD3 = _IMX_PAD(0x544, 0x1FC), // ENET2_RX_DATA3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII2_RX_CTL)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII2_RX_CTL)
+   IMX_PAD_RGMII2_RX_CTL = _IMX_PAD(0x548, 0x200), // ENET2_RX_EN
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII2_RXC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII2_RXC)
+   IMX_PAD_RGMII2_RXC = _IMX_PAD(0x54C, 0x204), // ENET2_RGMII_RXC
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII2_TD0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII2_TD0)
+   IMX_PAD_RGMII2_TD0 = _IMX_PAD(0x550, 0x208), // ENET2_TX_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII2_TD1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII2_TD1)
+   IMX_PAD_RGMII2_TD1 = _IMX_PAD(0x554, 0x20C), // ENET2_TX_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII2_TD2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII2_TD2)
+   IMX_PAD_RGMII2_TD2 = _IMX_PAD(0x558, 0x210), // ENET2_TX_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII2_TD3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII2_TD3)
+   IMX_PAD_RGMII2_TD3 = _IMX_PAD(0x55C, 0x214), // ENET2_TX_DATA3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII2_TX_CTL)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII2_TX_CTL)
+   IMX_PAD_RGMII2_TX_CTL = _IMX_PAD(0x560, 0x218), // ENET2_TX_EN
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_RGMII2_TXC)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_RGMII2_TXC)
+   IMX_PAD_RGMII2_TXC = _IMX_PAD(0x564, 0x21C), // ENET2_RGMII_TXC
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_CLK)
+   IMX_PAD_SD1_CLK = _IMX_PAD(0x568, 0x220), // SD1_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_CMD)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_CMD)
+   IMX_PAD_SD1_CMD = _IMX_PAD(0x56C, 0x224), // SD1_CMD
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_DATA0)
+   IMX_PAD_SD1_DATA0 = _IMX_PAD(0x570, 0x228), // SD1_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_DATA1)
+   IMX_PAD_SD1_DATA1 = _IMX_PAD(0x574, 0x22C), // SD1_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_DATA2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_DATA2)
+   IMX_PAD_SD1_DATA2 = _IMX_PAD(0x578, 0x230), // SD1_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD1_DATA3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD1_DATA3)
+   IMX_PAD_SD1_DATA3 = _IMX_PAD(0x57C, 0x234), // SD1_DATA3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_CLK)
+   IMX_PAD_SD2_CLK = _IMX_PAD(0x580, 0x238), // SD2_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_CMD)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_CMD)
+   IMX_PAD_SD2_CMD = _IMX_PAD(0x584, 0x23C), // SD2_CMD
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_DATA0)
+   IMX_PAD_SD2_DATA0 = _IMX_PAD(0x588, 0x240), // SD2_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_DATA1)
+   IMX_PAD_SD2_DATA1 = _IMX_PAD(0x58C, 0x244), // SD2_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_DATA2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_DATA2)
+   IMX_PAD_SD2_DATA2 = _IMX_PAD(0x590, 0x248), // SD2_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD2_DATA3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD2_DATA3)
+   IMX_PAD_SD2_DATA3 = _IMX_PAD(0x594, 0x24C), // SD2_DATA3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_CLK)
+   IMX_PAD_SD4_CLK = _IMX_PAD(0x5C0, 0x278), // SD4_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_CMD)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_CMD)
+   IMX_PAD_SD4_CMD = _IMX_PAD(0x5C4, 0x27C), // SD4_CMD
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA0)
+   IMX_PAD_SD4_DATA0 = _IMX_PAD(0x5C8, 0x280), // SD4_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA1)
+   IMX_PAD_SD4_DATA1 = _IMX_PAD(0x5CC, 0x284), // SD4_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA2)
+   IMX_PAD_SD4_DATA2 = _IMX_PAD(0x5D0, 0x288), // SD4_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA3)
+   IMX_PAD_SD4_DATA3 = _IMX_PAD(0x5D4, 0x28C), // SD4_DATA3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA4)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA4)
+   IMX_PAD_SD4_DATA4 = _IMX_PAD(0x5D8, 0x290), // SD4_DATA4
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA5)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA5)
+   IMX_PAD_SD4_DATA5 = _IMX_PAD(0x5DC, 0x294), // SD4_DATA5
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA6)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA6)
+   IMX_PAD_SD4_DATA6 = _IMX_PAD(0x5E0, 0x298), // SD4_DATA6
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_DATA7)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_DATA7)
+   IMX_PAD_SD4_DATA7 = _IMX_PAD(0x5E4, 0x29C), // SD4_DATA7
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD4_RESET_B)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD4_RESET_B)
+   IMX_PAD_SD4_RESET_B = _IMX_PAD(0x5E8, 0x2A0), // SD4_RESET_B
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_CLK)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_CLK)
+   IMX_PAD_SD3_CLK = _IMX_PAD(0x598, 0x250), // SD3_CLK
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_CMD)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_CMD)
+   IMX_PAD_SD3_CMD = _IMX_PAD(0x59C, 0x254), // SD3_CMD
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA0)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA0)
+   IMX_PAD_SD3_DATA0 = _IMX_PAD(0x5A0, 0x258), // SD3_DATA0
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA1)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA1)
+   IMX_PAD_SD3_DATA1 = _IMX_PAD(0x5A4, 0x25C), // SD3_DATA1
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA2)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA2)
+   IMX_PAD_SD3_DATA2 = _IMX_PAD(0x5A8, 0x260), // SD3_DATA2
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA3)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA3)
+   IMX_PAD_SD3_DATA3 = _IMX_PAD(0x5AC, 0x264), // SD3_DATA3
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA4)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA4)
+   IMX_PAD_SD3_DATA4 = _IMX_PAD(0x5B0, 0x268), // SD3_DATA4
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA5)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA5)
+   IMX_PAD_SD3_DATA5 = _IMX_PAD(0x5B4, 0x26C), // SD3_DATA5
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA6)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA6)
+   IMX_PAD_SD3_DATA6 = _IMX_PAD(0x5B8, 0x270), // SD3_DATA6
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_SD3_DATA7)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_SD3_DATA7)
+   IMX_PAD_SD3_DATA7 = _IMX_PAD(0x5BC, 0x274), // SD3_DATA7
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_USB_H_DATA)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_USB_H_DATA)
+   IMX_PAD_USB_H_DATA = _IMX_PAD(0x5EC, 0x2A4), // USB_H_DATA
+
+   // Pad Control Register (IOMUXC_SW_PAD_CTL_PAD_USB_H_STROBE)
+   // Pad Mux Register (IOMUXC_SW_MUX_CTL_PAD_USB_H_STROBE)
+   IMX_PAD_USB_H_STROBE = _IMX_PAD(0x5F0, 0x2A8), // USB_H_STROBE
+
+} IMX_PAD;
+
+//
+// Alternate function numbers
+//
+
+// Alternate function numbers
+typedef enum {
+   IMX_IOMUXC_GPIO1_IO00_ALT0_I2C1_SCL = 0,
+   IMX_IOMUXC_GPIO1_IO00_ALT1_SD1_VSELECT = 1,
+   IMX_IOMUXC_GPIO1_IO00_ALT2_SPDIF_LOCK = 2,
+   IMX_IOMUXC_GPIO1_IO00_ALT4_WDOG1_ANY = 4,
+   IMX_IOMUXC_GPIO1_IO00_ALT5_GPIO1_IO00 = 5,
+   IMX_IOMUXC_GPIO1_IO00_ALT6_SNVS_VIO_5 = 6,
+} IMX_IOMUXC_GPIO1_IO00_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO1_IO01_ALT0_I2C1_SDA = 0,
+   IMX_IOMUXC_GPIO1_IO01_ALT1_SD1_RESET_B = 1,
+   IMX_IOMUXC_GPIO1_IO01_ALT2_SPDIF_SR_CLK = 2,
+   IMX_IOMUXC_GPIO1_IO01_ALT4_WDOG3_B = 4,
+   IMX_IOMUXC_GPIO1_IO01_ALT5_GPIO1_IO01 = 5,
+   IMX_IOMUXC_GPIO1_IO01_ALT6_SNVS_VIO_5_CTL = 6,
+} IMX_IOMUXC_GPIO1_IO01_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO1_IO02_ALT0_I2C2_SCL = 0,
+   IMX_IOMUXC_GPIO1_IO02_ALT1_SD1_CD_B = 1,
+   IMX_IOMUXC_GPIO1_IO02_ALT2_CSI2_MCLK = 2,
+   IMX_IOMUXC_GPIO1_IO02_ALT4_WDOG1_B = 4,
+   IMX_IOMUXC_GPIO1_IO02_ALT5_GPIO1_IO02 = 5,
+   IMX_IOMUXC_GPIO1_IO02_ALT6_CCM_REF_EN_B = 6,
+} IMX_IOMUXC_GPIO1_IO02_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO1_IO03_ALT0_I2C2_SDA = 0,
+   IMX_IOMUXC_GPIO1_IO03_ALT1_SD1_WP = 1,
+   IMX_IOMUXC_GPIO1_IO03_ALT2_ENET1_REF_CLK_25M = 2,
+   IMX_IOMUXC_GPIO1_IO03_ALT4_WDOG2_B = 4,
+   IMX_IOMUXC_GPIO1_IO03_ALT5_GPIO1_IO03 = 5,
+} IMX_IOMUXC_GPIO1_IO03_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO1_IO04_ALT0_UART1_TX_DATA = 0,
+   IMX_IOMUXC_GPIO1_IO04_ALT1_SD2_RESET_B = 1,
+   IMX_IOMUXC_GPIO1_IO04_ALT2_ENET1_MDC = 2,
+   IMX_IOMUXC_GPIO1_IO04_ALT4_ENET2_REF_CLK2 = 4,
+   IMX_IOMUXC_GPIO1_IO04_ALT5_GPIO1_IO04 = 5,
+} IMX_IOMUXC_GPIO1_IO04_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO1_IO05_ALT0_UART1_RX_DATA = 0,
+   IMX_IOMUXC_GPIO1_IO05_ALT1_SD2_VSELECT = 1,
+   IMX_IOMUXC_GPIO1_IO05_ALT2_ENET1_MDIO = 2,
+   IMX_IOMUXC_GPIO1_IO05_ALT3_ASRC_EXT_CLK = 3,
+   IMX_IOMUXC_GPIO1_IO05_ALT4_ENET1_REF_CLK1 = 4,
+   IMX_IOMUXC_GPIO1_IO05_ALT5_GPIO1_IO05 = 5,
+} IMX_IOMUXC_GPIO1_IO05_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO1_IO06_ALT0_UART2_TX_DATA = 0,
+   IMX_IOMUXC_GPIO1_IO06_ALT1_SD2_CD_B = 1,
+   IMX_IOMUXC_GPIO1_IO06_ALT2_ENET2_MDC = 2,
+   IMX_IOMUXC_GPIO1_IO06_ALT3_CSI1_MCLK = 3,
+   IMX_IOMUXC_GPIO1_IO06_ALT4_UART1_RTS_B = 4,
+   IMX_IOMUXC_GPIO1_IO06_ALT5_GPIO1_IO06 = 5,
+} IMX_IOMUXC_GPIO1_IO06_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO1_IO07_ALT0_UART2_RX_DATA = 0,
+   IMX_IOMUXC_GPIO1_IO07_ALT1_SD2_WP = 1,
+   IMX_IOMUXC_GPIO1_IO07_ALT2_ENET2_MDIO = 2,
+   IMX_IOMUXC_GPIO1_IO07_ALT3_AUDIO_CLK_OUT = 3,
+   IMX_IOMUXC_GPIO1_IO07_ALT4_UART1_CTS_B = 4,
+   IMX_IOMUXC_GPIO1_IO07_ALT5_GPIO1_IO07 = 5,
+   IMX_IOMUXC_GPIO1_IO07_ALT7_DCIC2_OUT = 7,
+} IMX_IOMUXC_GPIO1_IO07_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO1_IO08_ALT0_USB_OTG1_OC = 0,
+   IMX_IOMUXC_GPIO1_IO08_ALT1_WDOG1_B = 1,
+   IMX_IOMUXC_GPIO1_IO08_ALT2_SDMA_EXT_EVENT0 = 2,
+   IMX_IOMUXC_GPIO1_IO08_ALT3_CCM_PMIC_READY = 3,
+   IMX_IOMUXC_GPIO1_IO08_ALT4_UART2_RTS_B = 4,
+   IMX_IOMUXC_GPIO1_IO08_ALT5_GPIO1_IO08 = 5,
+   IMX_IOMUXC_GPIO1_IO08_ALT7_DCIC1_OUT = 7,
+} IMX_IOMUXC_GPIO1_IO08_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO1_IO09_ALT0_USB_OTG1_PWR = 0,
+   IMX_IOMUXC_GPIO1_IO09_ALT1_WDOG2_B = 1,
+   IMX_IOMUXC_GPIO1_IO09_ALT2_SDMA_EXT_EVENT1 = 2,
+   IMX_IOMUXC_GPIO1_IO09_ALT4_UART2_CTS_B = 4,
+   IMX_IOMUXC_GPIO1_IO09_ALT5_GPIO1_IO09 = 5,
+} IMX_IOMUXC_GPIO1_IO09_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO1_IO10_ALT0_USB_OTG1_ID = 0,
+   IMX_IOMUXC_GPIO1_IO10_ALT1_SPDIF_EXT_CLK = 1,
+   IMX_IOMUXC_GPIO1_IO10_ALT2_PWM1_OUT = 2,
+   IMX_IOMUXC_GPIO1_IO10_ALT4_CSI1_FIELD = 4,
+   IMX_IOMUXC_GPIO1_IO10_ALT5_GPIO1_IO10 = 5,
+} IMX_IOMUXC_GPIO1_IO10_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO1_IO11_ALT0_USB_OTG2_OC = 0,
+   IMX_IOMUXC_GPIO1_IO11_ALT1_SPDIF_IN = 1,
+   IMX_IOMUXC_GPIO1_IO11_ALT2_PWM2_OUT = 2,
+   IMX_IOMUXC_GPIO1_IO11_ALT3_CCM_CLKO1 = 3,
+   IMX_IOMUXC_GPIO1_IO11_ALT4_MLB_DATA = 4,
+   IMX_IOMUXC_GPIO1_IO11_ALT5_GPIO1_IO11 = 5,
+} IMX_IOMUXC_GPIO1_IO11_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO1_IO12_ALT0_USB_OTG2_PWR = 0,
+   IMX_IOMUXC_GPIO1_IO12_ALT1_SPDIF_OUT = 1,
+   IMX_IOMUXC_GPIO1_IO12_ALT2_PWM3_OUT = 2,
+   IMX_IOMUXC_GPIO1_IO12_ALT3_CCM_CLKO2 = 3,
+   IMX_IOMUXC_GPIO1_IO12_ALT4_MLB_CLK = 4,
+   IMX_IOMUXC_GPIO1_IO12_ALT5_GPIO1_IO12 = 5,
+} IMX_IOMUXC_GPIO1_IO12_ALT;
+
+typedef enum {
+   IMX_IOMUXC_GPIO1_IO13_ALT0_WDOG1_ANY = 0,
+   IMX_IOMUXC_GPIO1_IO13_ALT1_USB_OTG2_ID = 1,
+   IMX_IOMUXC_GPIO1_IO13_ALT2_PWM4_OUT = 2,
+   IMX_IOMUXC_GPIO1_IO13_ALT4_MLB_SIG = 4,
+   IMX_IOMUXC_GPIO1_IO13_ALT5_GPIO1_IO13 = 5,
+} IMX_IOMUXC_GPIO1_IO13_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI_DATA00_ALT0_CSI1_DATA02 = 0,
+   IMX_IOMUXC_CSI_DATA00_ALT1_ESAI_TX_CLK = 1,
+   IMX_IOMUXC_CSI_DATA00_ALT2_AUD6_TXC = 2,
+   IMX_IOMUXC_CSI_DATA00_ALT3_I2C1_SCL = 3,
+   IMX_IOMUXC_CSI_DATA00_ALT4_UART6_RI_B = 4,
+   IMX_IOMUXC_CSI_DATA00_ALT5_GPIO1_IO14 = 5,
+   IMX_IOMUXC_CSI_DATA00_ALT6_EIM_DATA23 = 6,
+   IMX_IOMUXC_CSI_DATA00_ALT7_SAI1_TX_BCLK = 7,
+} IMX_IOMUXC_CSI_DATA00_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI_DATA01_ALT0_CSI1_DATA03 = 0,
+   IMX_IOMUXC_CSI_DATA01_ALT1_ESAI_TX_FS = 1,
+   IMX_IOMUXC_CSI_DATA01_ALT2_AUD6_TXFS = 2,
+   IMX_IOMUXC_CSI_DATA01_ALT3_I2C1_SDA = 3,
+   IMX_IOMUXC_CSI_DATA01_ALT4_UART6_DSR_B = 4,
+   IMX_IOMUXC_CSI_DATA01_ALT5_GPIO1_IO15 = 5,
+   IMX_IOMUXC_CSI_DATA01_ALT6_EIM_DATA22 = 6,
+   IMX_IOMUXC_CSI_DATA01_ALT7_SAI1_TX_SYNC = 7,
+} IMX_IOMUXC_CSI_DATA01_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI_DATA02_ALT0_CSI1_DATA04 = 0,
+   IMX_IOMUXC_CSI_DATA02_ALT1_ESAI_RX_CLK = 1,
+   IMX_IOMUXC_CSI_DATA02_ALT2_AUD6_RXC = 2,
+   IMX_IOMUXC_CSI_DATA02_ALT3_KPP_COL5 = 3,
+   IMX_IOMUXC_CSI_DATA02_ALT4_UART6_DTR_B = 4,
+   IMX_IOMUXC_CSI_DATA02_ALT5_GPIO1_IO16 = 5,
+   IMX_IOMUXC_CSI_DATA02_ALT6_EIM_DATA21 = 6,
+   IMX_IOMUXC_CSI_DATA02_ALT7_SAI1_RX_BCLK = 7,
+} IMX_IOMUXC_CSI_DATA02_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI_DATA03_ALT0_CSI1_DATA05 = 0,
+   IMX_IOMUXC_CSI_DATA03_ALT1_ESAI_RX_FS = 1,
+   IMX_IOMUXC_CSI_DATA03_ALT2_AUD6_RXFS = 2,
+   IMX_IOMUXC_CSI_DATA03_ALT3_KPP_ROW5 = 3,
+   IMX_IOMUXC_CSI_DATA03_ALT4_UART6_DCD_B = 4,
+   IMX_IOMUXC_CSI_DATA03_ALT5_GPIO1_IO17 = 5,
+   IMX_IOMUXC_CSI_DATA03_ALT6_EIM_DATA20 = 6,
+   IMX_IOMUXC_CSI_DATA03_ALT7_SAI1_RX_SYNC = 7,
+} IMX_IOMUXC_CSI_DATA03_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI_DATA04_ALT0_CSI1_DATA06 = 0,
+   IMX_IOMUXC_CSI_DATA04_ALT1_ESAI_TX1 = 1,
+   IMX_IOMUXC_CSI_DATA04_ALT2_SPDIF_OUT = 2,
+   IMX_IOMUXC_CSI_DATA04_ALT3_KPP_COL6 = 3,
+   IMX_IOMUXC_CSI_DATA04_ALT4_UART6_RX_DATA = 4,
+   IMX_IOMUXC_CSI_DATA04_ALT5_GPIO1_IO18 = 5,
+   IMX_IOMUXC_CSI_DATA04_ALT6_EIM_DATA19 = 6,
+   IMX_IOMUXC_CSI_DATA04_ALT7_PWM5_OUT = 7,
+} IMX_IOMUXC_CSI_DATA04_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI_DATA05_ALT0_CSI1_DATA07 = 0,
+   IMX_IOMUXC_CSI_DATA05_ALT1_ESAI_TX4_RX1 = 1,
+   IMX_IOMUXC_CSI_DATA05_ALT2_SPDIF_IN = 2,
+   IMX_IOMUXC_CSI_DATA05_ALT3_KPP_ROW6 = 3,
+   IMX_IOMUXC_CSI_DATA05_ALT4_UART6_TX_DATA = 4,
+   IMX_IOMUXC_CSI_DATA05_ALT5_GPIO1_IO19 = 5,
+   IMX_IOMUXC_CSI_DATA05_ALT6_EIM_DATA18 = 6,
+   IMX_IOMUXC_CSI_DATA05_ALT7_PWM6_OUT = 7,
+} IMX_IOMUXC_CSI_DATA05_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI_DATA06_ALT0_CSI1_DATA08 = 0,
+   IMX_IOMUXC_CSI_DATA06_ALT1_ESAI_TX2_RX3 = 1,
+   IMX_IOMUXC_CSI_DATA06_ALT2_I2C4_SCL = 2,
+   IMX_IOMUXC_CSI_DATA06_ALT3_KPP_COL7 = 3,
+   IMX_IOMUXC_CSI_DATA06_ALT4_UART6_RTS_B = 4,
+   IMX_IOMUXC_CSI_DATA06_ALT5_GPIO1_IO20 = 5,
+   IMX_IOMUXC_CSI_DATA06_ALT6_EIM_DATA17 = 6,
+   IMX_IOMUXC_CSI_DATA06_ALT7_DCIC2_OUT = 7,
+} IMX_IOMUXC_CSI_DATA06_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI_DATA07_ALT0_CSI1_DATA09 = 0,
+   IMX_IOMUXC_CSI_DATA07_ALT1_ESAI_TX3_RX2 = 1,
+   IMX_IOMUXC_CSI_DATA07_ALT2_I2C4_SDA = 2,
+   IMX_IOMUXC_CSI_DATA07_ALT3_KPP_ROW7 = 3,
+   IMX_IOMUXC_CSI_DATA07_ALT4_UART6_CTS_B = 4,
+   IMX_IOMUXC_CSI_DATA07_ALT5_GPIO1_IO21 = 5,
+   IMX_IOMUXC_CSI_DATA07_ALT6_EIM_DATA16 = 6,
+   IMX_IOMUXC_CSI_DATA07_ALT7_DCIC1_OUT = 7,
+} IMX_IOMUXC_CSI_DATA07_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI_HSYNC_ALT0_CSI1_HSYNC = 0,
+   IMX_IOMUXC_CSI_HSYNC_ALT1_ESAI_TX0 = 1,
+   IMX_IOMUXC_CSI_HSYNC_ALT2_AUD6_TXD = 2,
+   IMX_IOMUXC_CSI_HSYNC_ALT3_UART4_RTS_B = 3,
+   IMX_IOMUXC_CSI_HSYNC_ALT4_MQS_LEFT = 4,
+   IMX_IOMUXC_CSI_HSYNC_ALT5_GPIO1_IO22 = 5,
+   IMX_IOMUXC_CSI_HSYNC_ALT6_EIM_DATA25 = 6,
+   IMX_IOMUXC_CSI_HSYNC_ALT7_SAI1_TX_DATA0 = 7,
+} IMX_IOMUXC_CSI_HSYNC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI_MCLK_ALT0_CSI1_MCLK = 0,
+   IMX_IOMUXC_CSI_MCLK_ALT1_ESAI_TX_HF_CLK = 1,
+   IMX_IOMUXC_CSI_MCLK_ALT3_UART4_RX_DATA = 3,
+   IMX_IOMUXC_CSI_MCLK_ALT4_XTALOSC_REF_CLK_32K = 4,
+   IMX_IOMUXC_CSI_MCLK_ALT5_GPIO1_IO23 = 5,
+   IMX_IOMUXC_CSI_MCLK_ALT6_EIM_DATA26 = 6,
+   IMX_IOMUXC_CSI_MCLK_ALT7_CSI1_FIELD = 7,
+} IMX_IOMUXC_CSI_MCLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI_PIXCLK_ALT0_CSI1_PIXCLK = 0,
+   IMX_IOMUXC_CSI_PIXCLK_ALT1_ESAI_RX_HF_CLK = 1,
+   IMX_IOMUXC_CSI_PIXCLK_ALT2_AUDIO_CLK_OUT = 2,
+   IMX_IOMUXC_CSI_PIXCLK_ALT3_UART4_TX_DATA = 3,
+   IMX_IOMUXC_CSI_PIXCLK_ALT4_XTALOSC_REF_CLK_24M = 4,
+   IMX_IOMUXC_CSI_PIXCLK_ALT5_GPIO1_IO24 = 5,
+   IMX_IOMUXC_CSI_PIXCLK_ALT6_EIM_DATA27 = 6,
+   IMX_IOMUXC_CSI_PIXCLK_ALT7_ESAI_TX_HF_CLK = 7,
+} IMX_IOMUXC_CSI_PIXCLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_CSI_VSYNC_ALT0_CSI1_VSYNC = 0,
+   IMX_IOMUXC_CSI_VSYNC_ALT1_ESAI_TX5_RX0 = 1,
+   IMX_IOMUXC_CSI_VSYNC_ALT2_AUD6_RXD = 2,
+   IMX_IOMUXC_CSI_VSYNC_ALT3_UART4_CTS_B = 3,
+   IMX_IOMUXC_CSI_VSYNC_ALT4_MQS_RIGHT = 4,
+   IMX_IOMUXC_CSI_VSYNC_ALT5_GPIO1_IO25 = 5,
+   IMX_IOMUXC_CSI_VSYNC_ALT6_EIM_DATA24 = 6,
+   IMX_IOMUXC_CSI_VSYNC_ALT7_SAI1_RX_DATA0 = 7,
+} IMX_IOMUXC_CSI_VSYNC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET1_COL_ALT0_ENET1_COL = 0,
+   IMX_IOMUXC_ENET1_COL_ALT1_ENET2_MDC = 1,
+   IMX_IOMUXC_ENET1_COL_ALT2_AUD4_TXC = 2,
+   IMX_IOMUXC_ENET1_COL_ALT3_UART1_RI_B = 3,
+   IMX_IOMUXC_ENET1_COL_ALT4_SPDIF_EXT_CLK = 4,
+   IMX_IOMUXC_ENET1_COL_ALT5_GPIO2_IO00 = 5,
+   IMX_IOMUXC_ENET1_COL_ALT6_CSI2_DATA23 = 6,
+   IMX_IOMUXC_ENET1_COL_ALT7_LCD2_DATA16 = 7,
+} IMX_IOMUXC_ENET1_COL_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET1_CRS_ALT0_ENET1_CRS = 0,
+   IMX_IOMUXC_ENET1_CRS_ALT1_ENET2_MDIO = 1,
+   IMX_IOMUXC_ENET1_CRS_ALT2_AUD4_TXD = 2,
+   IMX_IOMUXC_ENET1_CRS_ALT3_UART1_DCD_B = 3,
+   IMX_IOMUXC_ENET1_CRS_ALT4_SPDIF_LOCK = 4,
+   IMX_IOMUXC_ENET1_CRS_ALT5_GPIO2_IO01 = 5,
+   IMX_IOMUXC_ENET1_CRS_ALT6_CSI2_DATA22 = 6,
+   IMX_IOMUXC_ENET1_CRS_ALT7_LCD2_DATA17 = 7,
+} IMX_IOMUXC_ENET1_CRS_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET1_MDC_ALT0_ENET1_MDC = 0,
+   IMX_IOMUXC_ENET1_MDC_ALT1_ENET2_MDC = 1,
+   IMX_IOMUXC_ENET1_MDC_ALT2_AUD3_RXFS = 2,
+   IMX_IOMUXC_ENET1_MDC_ALT3_XTALOSC_REF_CLK_24M = 3,
+   IMX_IOMUXC_ENET1_MDC_ALT4_EPIT2_OUT = 4,
+   IMX_IOMUXC_ENET1_MDC_ALT5_GPIO2_IO02 = 5,
+   IMX_IOMUXC_ENET1_MDC_ALT6_USB_OTG1_PWR = 6,
+   IMX_IOMUXC_ENET1_MDC_ALT7_PWM7_OUT = 7,
+} IMX_IOMUXC_ENET1_MDC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET1_MDIO_ALT0_ENET1_MDIO = 0,
+   IMX_IOMUXC_ENET1_MDIO_ALT1_ENET2_MDIO = 1,
+   IMX_IOMUXC_ENET1_MDIO_ALT2_AUDIO_CLK_OUT = 2,
+   IMX_IOMUXC_ENET1_MDIO_ALT4_EPIT1_OUT = 4,
+   IMX_IOMUXC_ENET1_MDIO_ALT5_GPIO2_IO03 = 5,
+   IMX_IOMUXC_ENET1_MDIO_ALT6_USB_OTG1_OC = 6,
+   IMX_IOMUXC_ENET1_MDIO_ALT7_PWM8_OUT = 7,
+} IMX_IOMUXC_ENET1_MDIO_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET1_RX_CLK_ALT0_ENET1_RX_CLK = 0,
+   IMX_IOMUXC_ENET1_RX_CLK_ALT1_ENET1_REF_CLK_25M = 1,
+   IMX_IOMUXC_ENET1_RX_CLK_ALT2_AUD4_TXFS = 2,
+   IMX_IOMUXC_ENET1_RX_CLK_ALT3_UART1_DSR_B = 3,
+   IMX_IOMUXC_ENET1_RX_CLK_ALT4_SPDIF_OUT = 4,
+   IMX_IOMUXC_ENET1_RX_CLK_ALT5_GPIO2_IO04 = 5,
+   IMX_IOMUXC_ENET1_RX_CLK_ALT6_CSI2_DATA21 = 6,
+   IMX_IOMUXC_ENET1_RX_CLK_ALT7_LCD2_DATA18 = 7,
+} IMX_IOMUXC_ENET1_RX_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET1_TX_CLK_ALT0_ENET1_TX_CLK = 0,
+   IMX_IOMUXC_ENET1_TX_CLK_ALT1_ENET1_REF_CLK1 = 1,
+   IMX_IOMUXC_ENET1_TX_CLK_ALT2_AUD4_RXD = 2,
+   IMX_IOMUXC_ENET1_TX_CLK_ALT3_UART1_DTR_B = 3,
+   IMX_IOMUXC_ENET1_TX_CLK_ALT4_SPDIF_SR_CLK = 4,
+   IMX_IOMUXC_ENET1_TX_CLK_ALT5_GPIO2_IO05 = 5,
+   IMX_IOMUXC_ENET1_TX_CLK_ALT6_CSI2_DATA20 = 6,
+   IMX_IOMUXC_ENET1_TX_CLK_ALT7_LCD2_DATA19 = 7,
+} IMX_IOMUXC_ENET1_TX_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET2_COL_ALT0_ENET2_COL = 0,
+   IMX_IOMUXC_ENET2_COL_ALT1_ENET1_MDC = 1,
+   IMX_IOMUXC_ENET2_COL_ALT2_AUD4_RXC = 2,
+   IMX_IOMUXC_ENET2_COL_ALT3_UART1_RX_DATA = 3,
+   IMX_IOMUXC_ENET2_COL_ALT4_SPDIF_IN = 4,
+   IMX_IOMUXC_ENET2_COL_ALT5_GPIO2_IO06 = 5,
+   IMX_IOMUXC_ENET2_COL_ALT6_USB_OTG1_ID = 6,
+   IMX_IOMUXC_ENET2_COL_ALT7_LCD2_DATA20 = 7,
+} IMX_IOMUXC_ENET2_COL_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET2_CRS_ALT0_ENET2_CRS = 0,
+   IMX_IOMUXC_ENET2_CRS_ALT1_ENET1_MDIO = 1,
+   IMX_IOMUXC_ENET2_CRS_ALT2_AUD4_RXFS = 2,
+   IMX_IOMUXC_ENET2_CRS_ALT3_UART1_TX_DATA = 3,
+   IMX_IOMUXC_ENET2_CRS_ALT4_MLB_SIG = 4,
+   IMX_IOMUXC_ENET2_CRS_ALT5_GPIO2_IO07 = 5,
+   IMX_IOMUXC_ENET2_CRS_ALT6_USB_OTG2_ID = 6,
+   IMX_IOMUXC_ENET2_CRS_ALT7_LCD2_DATA21 = 7,
+} IMX_IOMUXC_ENET2_CRS_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET2_RX_CLK_ALT0_ENET2_RX_CLK = 0,
+   IMX_IOMUXC_ENET2_RX_CLK_ALT1_ENET2_REF_CLK_25M = 1,
+   IMX_IOMUXC_ENET2_RX_CLK_ALT2_I2C3_SCL = 2,
+   IMX_IOMUXC_ENET2_RX_CLK_ALT3_UART1_RTS_B = 3,
+   IMX_IOMUXC_ENET2_RX_CLK_ALT4_MLB_DATA = 4,
+   IMX_IOMUXC_ENET2_RX_CLK_ALT5_GPIO2_IO08 = 5,
+   IMX_IOMUXC_ENET2_RX_CLK_ALT6_USB_OTG2_OC = 6,
+   IMX_IOMUXC_ENET2_RX_CLK_ALT7_LCD2_DATA22 = 7,
+} IMX_IOMUXC_ENET2_RX_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_ENET2_TX_CLK_ALT0_ENET2_TX_CLK = 0,
+   IMX_IOMUXC_ENET2_TX_CLK_ALT1_ENET2_REF_CLK2 = 1,
+   IMX_IOMUXC_ENET2_TX_CLK_ALT2_I2C3_SDA = 2,
+   IMX_IOMUXC_ENET2_TX_CLK_ALT3_UART1_CTS_B = 3,
+   IMX_IOMUXC_ENET2_TX_CLK_ALT4_MLB_CLK = 4,
+   IMX_IOMUXC_ENET2_TX_CLK_ALT5_GPIO2_IO09 = 5,
+   IMX_IOMUXC_ENET2_TX_CLK_ALT6_USB_OTG2_PWR = 6,
+   IMX_IOMUXC_ENET2_TX_CLK_ALT7_LCD2_DATA23 = 7,
+} IMX_IOMUXC_ENET2_TX_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_COL0_ALT0_KPP_COL0 = 0,
+   IMX_IOMUXC_KEY_COL0_ALT1_SD3_CD_B = 1,
+   IMX_IOMUXC_KEY_COL0_ALT2_UART6_RTS_B = 2,
+   IMX_IOMUXC_KEY_COL0_ALT3_ECSPI1_SCLK = 3,
+   IMX_IOMUXC_KEY_COL0_ALT4_AUD5_TXC = 4,
+   IMX_IOMUXC_KEY_COL0_ALT5_GPIO2_IO10 = 5,
+   IMX_IOMUXC_KEY_COL0_ALT6_SDMA_EXT_EVENT1 = 6,
+   IMX_IOMUXC_KEY_COL0_ALT7_SAI2_TX_BCLK = 7,
+} IMX_IOMUXC_KEY_COL0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_COL1_ALT0_KPP_COL1 = 0,
+   IMX_IOMUXC_KEY_COL1_ALT1_SD3_RESET_B = 1,
+   IMX_IOMUXC_KEY_COL1_ALT2_UART6_TX_DATA = 2,
+   IMX_IOMUXC_KEY_COL1_ALT3_ECSPI1_MISO = 3,
+   IMX_IOMUXC_KEY_COL1_ALT4_AUD5_TXFS = 4,
+   IMX_IOMUXC_KEY_COL1_ALT5_GPIO2_IO11 = 5,
+   IMX_IOMUXC_KEY_COL1_ALT6_SD3_RESET = 6,
+   IMX_IOMUXC_KEY_COL1_ALT7_SAI2_TX_SYNC = 7,
+} IMX_IOMUXC_KEY_COL1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_COL2_ALT0_KPP_COL2 = 0,
+   IMX_IOMUXC_KEY_COL2_ALT1_SD4_CD_B = 1,
+   IMX_IOMUXC_KEY_COL2_ALT2_UART5_RTS_B = 2,
+   IMX_IOMUXC_KEY_COL2_ALT3_CAN1_TX = 3,
+   IMX_IOMUXC_KEY_COL2_ALT5_GPIO2_IO12 = 5,
+   IMX_IOMUXC_KEY_COL2_ALT6_EIM_DATA30 = 6,
+   IMX_IOMUXC_KEY_COL2_ALT7_ECSPI1_RDY = 7,
+} IMX_IOMUXC_KEY_COL2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_COL3_ALT0_KPP_COL3 = 0,
+   IMX_IOMUXC_KEY_COL3_ALT1_SD4_LCTL = 1,
+   IMX_IOMUXC_KEY_COL3_ALT2_UART5_TX_DATA = 2,
+   IMX_IOMUXC_KEY_COL3_ALT3_CAN2_TX = 3,
+   IMX_IOMUXC_KEY_COL3_ALT5_GPIO2_IO13 = 5,
+   IMX_IOMUXC_KEY_COL3_ALT6_EIM_DATA28 = 6,
+   IMX_IOMUXC_KEY_COL3_ALT7_ECSPI1_SS2 = 7,
+} IMX_IOMUXC_KEY_COL3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_COL4_ALT0_KPP_COL4 = 0,
+   IMX_IOMUXC_KEY_COL4_ALT1_ENET2_MDC = 1,
+   IMX_IOMUXC_KEY_COL4_ALT2_I2C3_SCL = 2,
+   IMX_IOMUXC_KEY_COL4_ALT3_SD2_LCTL = 3,
+   IMX_IOMUXC_KEY_COL4_ALT4_AUD5_RXC = 4,
+   IMX_IOMUXC_KEY_COL4_ALT5_GPIO2_IO14 = 5,
+   IMX_IOMUXC_KEY_COL4_ALT6_EIM_CRE = 6,
+   IMX_IOMUXC_KEY_COL4_ALT7_SAI2_RX_BCLK = 7,
+} IMX_IOMUXC_KEY_COL4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_ROW0_ALT0_KPP_ROW0 = 0,
+   IMX_IOMUXC_KEY_ROW0_ALT1_SD3_WP = 1,
+   IMX_IOMUXC_KEY_ROW0_ALT2_UART6_CTS_B = 2,
+   IMX_IOMUXC_KEY_ROW0_ALT3_ECSPI1_MOSI = 3,
+   IMX_IOMUXC_KEY_ROW0_ALT4_AUD5_TXD = 4,
+   IMX_IOMUXC_KEY_ROW0_ALT5_GPIO2_IO15 = 5,
+   IMX_IOMUXC_KEY_ROW0_ALT6_SDMA_EXT_EVENT0 = 6,
+   IMX_IOMUXC_KEY_ROW0_ALT7_SAI2_TX_DATA0 = 7,
+} IMX_IOMUXC_KEY_ROW0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_ROW1_ALT0_KPP_ROW1 = 0,
+   IMX_IOMUXC_KEY_ROW1_ALT1_SD4_VSELECT = 1,
+   IMX_IOMUXC_KEY_ROW1_ALT2_UART6_RX_DATA = 2,
+   IMX_IOMUXC_KEY_ROW1_ALT3_ECSPI1_SS0 = 3,
+   IMX_IOMUXC_KEY_ROW1_ALT4_AUD5_RXD = 4,
+   IMX_IOMUXC_KEY_ROW1_ALT5_GPIO2_IO16 = 5,
+   IMX_IOMUXC_KEY_ROW1_ALT6_EIM_DATA31 = 6,
+   IMX_IOMUXC_KEY_ROW1_ALT7_SAI2_RX_DATA0 = 7,
+} IMX_IOMUXC_KEY_ROW1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_ROW2_ALT0_KPP_ROW2 = 0,
+   IMX_IOMUXC_KEY_ROW2_ALT1_SD4_WP = 1,
+   IMX_IOMUXC_KEY_ROW2_ALT2_UART5_CTS_B = 2,
+   IMX_IOMUXC_KEY_ROW2_ALT3_CAN1_RX = 3,
+   IMX_IOMUXC_KEY_ROW2_ALT5_GPIO2_IO17 = 5,
+   IMX_IOMUXC_KEY_ROW2_ALT6_EIM_DATA29 = 6,
+   IMX_IOMUXC_KEY_ROW2_ALT7_ECSPI1_SS3 = 7,
+} IMX_IOMUXC_KEY_ROW2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_ROW3_ALT0_KPP_ROW3 = 0,
+   IMX_IOMUXC_KEY_ROW3_ALT1_SD3_LCTL = 1,
+   IMX_IOMUXC_KEY_ROW3_ALT2_UART5_RX_DATA = 2,
+   IMX_IOMUXC_KEY_ROW3_ALT3_CAN2_RX = 3,
+   IMX_IOMUXC_KEY_ROW3_ALT5_GPIO2_IO18 = 5,
+   IMX_IOMUXC_KEY_ROW3_ALT6_EIM_DTACK_B = 6,
+   IMX_IOMUXC_KEY_ROW3_ALT7_ECSPI1_SS1 = 7,
+} IMX_IOMUXC_KEY_ROW3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_KEY_ROW4_ALT0_KPP_ROW4 = 0,
+   IMX_IOMUXC_KEY_ROW4_ALT1_ENET2_MDIO = 1,
+   IMX_IOMUXC_KEY_ROW4_ALT2_I2C3_SDA = 2,
+   IMX_IOMUXC_KEY_ROW4_ALT3_SD1_LCTL = 3,
+   IMX_IOMUXC_KEY_ROW4_ALT4_AUD5_RXFS = 4,
+   IMX_IOMUXC_KEY_ROW4_ALT5_GPIO2_IO19 = 5,
+   IMX_IOMUXC_KEY_ROW4_ALT6_EIM_ACLK_FREERUN = 6,
+   IMX_IOMUXC_KEY_ROW4_ALT7_SAI2_RX_SYNC = 7,
+} IMX_IOMUXC_KEY_ROW4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_CLK_ALT0_LCD1_CLK = 0,
+   IMX_IOMUXC_LCD1_CLK_ALT1_LCD1_WR_RWN = 1,
+   IMX_IOMUXC_LCD1_CLK_ALT2_AUD3_RXC = 2,
+   IMX_IOMUXC_LCD1_CLK_ALT3_ENET1_1588_EVENT2_IN = 3,
+   IMX_IOMUXC_LCD1_CLK_ALT4_CSI1_DATA16 = 4,
+   IMX_IOMUXC_LCD1_CLK_ALT5_GPIO3_IO00 = 5,
+   IMX_IOMUXC_LCD1_CLK_ALT6_SD1_WP = 6,
+} IMX_IOMUXC_LCD1_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA00_ALT0_LCD1_DATA00 = 0,
+   IMX_IOMUXC_LCD1_DATA00_ALT1_EIM_CS1_B = 1,
+   IMX_IOMUXC_LCD1_DATA00_ALT2_ARM_M4_TRACE0 = 2,
+   IMX_IOMUXC_LCD1_DATA00_ALT3_ARM_A9_TRACE00 = 3,
+   IMX_IOMUXC_LCD1_DATA00_ALT4_CSI1_DATA20 = 4,
+   IMX_IOMUXC_LCD1_DATA00_ALT5_GPIO3_IO01 = 5,
+   IMX_IOMUXC_LCD1_DATA00_ALT6_SRC_BOOT_CFG00 = 6,
+} IMX_IOMUXC_LCD1_DATA00_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA01_ALT0_LCD1_DATA01 = 0,
+   IMX_IOMUXC_LCD1_DATA01_ALT1_EIM_CS2_B = 1,
+   IMX_IOMUXC_LCD1_DATA01_ALT2_ARM_M4_TRACE1 = 2,
+   IMX_IOMUXC_LCD1_DATA01_ALT3_ARM_A9_TRACE01 = 3,
+   IMX_IOMUXC_LCD1_DATA01_ALT4_CSI1_DATA21 = 4,
+   IMX_IOMUXC_LCD1_DATA01_ALT5_GPIO3_IO02 = 5,
+   IMX_IOMUXC_LCD1_DATA01_ALT6_SRC_BOOT_CFG01 = 6,
+} IMX_IOMUXC_LCD1_DATA01_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA02_ALT0_LCD1_DATA02 = 0,
+   IMX_IOMUXC_LCD1_DATA02_ALT1_EIM_CS3_B = 1,
+   IMX_IOMUXC_LCD1_DATA02_ALT2_ARM_M4_TRACE2 = 2,
+   IMX_IOMUXC_LCD1_DATA02_ALT3_ARM_A9_TRACE02 = 3,
+   IMX_IOMUXC_LCD1_DATA02_ALT4_CSI1_DATA22 = 4,
+   IMX_IOMUXC_LCD1_DATA02_ALT5_GPIO3_IO03 = 5,
+   IMX_IOMUXC_LCD1_DATA02_ALT6_SRC_BOOT_CFG02 = 6,
+} IMX_IOMUXC_LCD1_DATA02_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA03_ALT0_LCD1_DATA03 = 0,
+   IMX_IOMUXC_LCD1_DATA03_ALT1_EIM_ADDR24 = 1,
+   IMX_IOMUXC_LCD1_DATA03_ALT2_ARM_M4_TRACE3 = 2,
+   IMX_IOMUXC_LCD1_DATA03_ALT3_ARM_A9_TRACE03 = 3,
+   IMX_IOMUXC_LCD1_DATA03_ALT4_CSI1_DATA23 = 4,
+   IMX_IOMUXC_LCD1_DATA03_ALT5_GPIO3_IO04 = 5,
+   IMX_IOMUXC_LCD1_DATA03_ALT6_SRC_BOOT_CFG03 = 6,
+} IMX_IOMUXC_LCD1_DATA03_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA04_ALT0_LCD1_DATA04 = 0,
+   IMX_IOMUXC_LCD1_DATA04_ALT1_EIM_ADDR25 = 1,
+   IMX_IOMUXC_LCD1_DATA04_ALT3_ARM_A9_TRACE04 = 3,
+   IMX_IOMUXC_LCD1_DATA04_ALT4_CSI1_VSYNC = 4,
+   IMX_IOMUXC_LCD1_DATA04_ALT5_GPIO3_IO05 = 5,
+   IMX_IOMUXC_LCD1_DATA04_ALT6_SRC_BOOT_CFG04 = 6,
+} IMX_IOMUXC_LCD1_DATA04_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA05_ALT0_LCD1_DATA05 = 0,
+   IMX_IOMUXC_LCD1_DATA05_ALT1_EIM_ADDR26 = 1,
+   IMX_IOMUXC_LCD1_DATA05_ALT3_ARM_A9_TRACE05 = 3,
+   IMX_IOMUXC_LCD1_DATA05_ALT4_CSI1_HSYNC = 4,
+   IMX_IOMUXC_LCD1_DATA05_ALT5_GPIO3_IO06 = 5,
+   IMX_IOMUXC_LCD1_DATA05_ALT6_SRC_BOOT_CFG05 = 6,
+} IMX_IOMUXC_LCD1_DATA05_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA06_ALT0_LCD1_DATA06 = 0,
+   IMX_IOMUXC_LCD1_DATA06_ALT1_EIM_EB2_B = 1,
+   IMX_IOMUXC_LCD1_DATA06_ALT3_ARM_A9_TRACE06 = 3,
+   IMX_IOMUXC_LCD1_DATA06_ALT4_CSI1_PIXCLK = 4,
+   IMX_IOMUXC_LCD1_DATA06_ALT5_GPIO3_IO07 = 5,
+   IMX_IOMUXC_LCD1_DATA06_ALT6_SRC_BOOT_CFG06 = 6,
+} IMX_IOMUXC_LCD1_DATA06_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA07_ALT0_LCD1_DATA07 = 0,
+   IMX_IOMUXC_LCD1_DATA07_ALT1_EIM_EB3_B = 1,
+   IMX_IOMUXC_LCD1_DATA07_ALT3_ARM_A9_TRACE07 = 3,
+   IMX_IOMUXC_LCD1_DATA07_ALT4_CSI1_MCLK = 4,
+   IMX_IOMUXC_LCD1_DATA07_ALT5_GPIO3_IO08 = 5,
+   IMX_IOMUXC_LCD1_DATA07_ALT6_SRC_BOOT_CFG07 = 6,
+} IMX_IOMUXC_LCD1_DATA07_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA08_ALT0_LCD1_DATA08 = 0,
+   IMX_IOMUXC_LCD1_DATA08_ALT1_EIM_AD08 = 1,
+   IMX_IOMUXC_LCD1_DATA08_ALT3_ARM_A9_TRACE08 = 3,
+   IMX_IOMUXC_LCD1_DATA08_ALT4_CSI1_DATA09 = 4,
+   IMX_IOMUXC_LCD1_DATA08_ALT5_GPIO3_IO09 = 5,
+   IMX_IOMUXC_LCD1_DATA08_ALT6_SRC_BOOT_CFG08 = 6,
+} IMX_IOMUXC_LCD1_DATA08_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA09_ALT0_LCD1_DATA09 = 0,
+   IMX_IOMUXC_LCD1_DATA09_ALT1_EIM_AD09 = 1,
+   IMX_IOMUXC_LCD1_DATA09_ALT3_ARM_A9_TRACE09 = 3,
+   IMX_IOMUXC_LCD1_DATA09_ALT4_CSI1_DATA08 = 4,
+   IMX_IOMUXC_LCD1_DATA09_ALT5_GPIO3_IO10 = 5,
+   IMX_IOMUXC_LCD1_DATA09_ALT6_SRC_BOOT_CFG09 = 6,
+} IMX_IOMUXC_LCD1_DATA09_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA10_ALT0_LCD1_DATA10 = 0,
+   IMX_IOMUXC_LCD1_DATA10_ALT1_EIM_AD10 = 1,
+   IMX_IOMUXC_LCD1_DATA10_ALT3_ARM_A9_TRACE10 = 3,
+   IMX_IOMUXC_LCD1_DATA10_ALT4_CSI1_DATA07 = 4,
+   IMX_IOMUXC_LCD1_DATA10_ALT5_GPIO3_IO11 = 5,
+   IMX_IOMUXC_LCD1_DATA10_ALT6_SRC_BOOT_CFG10 = 6,
+} IMX_IOMUXC_LCD1_DATA10_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA11_ALT0_LCD1_DATA11 = 0,
+   IMX_IOMUXC_LCD1_DATA11_ALT1_EIM_AD11 = 1,
+   IMX_IOMUXC_LCD1_DATA11_ALT3_ARM_A9_TRACE11 = 3,
+   IMX_IOMUXC_LCD1_DATA11_ALT4_CSI1_DATA06 = 4,
+   IMX_IOMUXC_LCD1_DATA11_ALT5_GPIO3_IO12 = 5,
+   IMX_IOMUXC_LCD1_DATA11_ALT6_SRC_BOOT_CFG11 = 6,
+} IMX_IOMUXC_LCD1_DATA11_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA12_ALT0_LCD1_DATA12 = 0,
+   IMX_IOMUXC_LCD1_DATA12_ALT1_EIM_AD12 = 1,
+   IMX_IOMUXC_LCD1_DATA12_ALT3_ARM_A9_TRACE12 = 3,
+   IMX_IOMUXC_LCD1_DATA12_ALT4_CSI1_DATA05 = 4,
+   IMX_IOMUXC_LCD1_DATA12_ALT5_GPIO3_IO13 = 5,
+   IMX_IOMUXC_LCD1_DATA12_ALT6_SRC_BOOT_CFG12 = 6,
+} IMX_IOMUXC_LCD1_DATA12_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA13_ALT0_LCD1_DATA13 = 0,
+   IMX_IOMUXC_LCD1_DATA13_ALT1_EIM_AD13 = 1,
+   IMX_IOMUXC_LCD1_DATA13_ALT3_ARM_A9_TRACE13 = 3,
+   IMX_IOMUXC_LCD1_DATA13_ALT4_CSI1_DATA04 = 4,
+   IMX_IOMUXC_LCD1_DATA13_ALT5_GPIO3_IO14 = 5,
+   IMX_IOMUXC_LCD1_DATA13_ALT6_SRC_BOOT_CFG13 = 6,
+} IMX_IOMUXC_LCD1_DATA13_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA14_ALT0_LCD1_DATA14 = 0,
+   IMX_IOMUXC_LCD1_DATA14_ALT1_EIM_AD14 = 1,
+   IMX_IOMUXC_LCD1_DATA14_ALT3_ARM_A9_TRACE14 = 3,
+   IMX_IOMUXC_LCD1_DATA14_ALT4_CSI1_DATA03 = 4,
+   IMX_IOMUXC_LCD1_DATA14_ALT5_GPIO3_IO15 = 5,
+   IMX_IOMUXC_LCD1_DATA14_ALT6_SRC_BOOT_CFG14 = 6,
+} IMX_IOMUXC_LCD1_DATA14_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA15_ALT0_LCD1_DATA15 = 0,
+   IMX_IOMUXC_LCD1_DATA15_ALT1_EIM_AD15 = 1,
+   IMX_IOMUXC_LCD1_DATA15_ALT3_ARM_A9_TRACE15 = 3,
+   IMX_IOMUXC_LCD1_DATA15_ALT4_CSI1_DATA02 = 4,
+   IMX_IOMUXC_LCD1_DATA15_ALT5_GPIO3_IO16 = 5,
+   IMX_IOMUXC_LCD1_DATA15_ALT6_SRC_BOOT_CFG15 = 6,
+} IMX_IOMUXC_LCD1_DATA15_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA16_ALT0_LCD1_DATA16 = 0,
+   IMX_IOMUXC_LCD1_DATA16_ALT1_EIM_ADDR16 = 1,
+   IMX_IOMUXC_LCD1_DATA16_ALT2_ARM_M4_TRACE_CLK = 2,
+   IMX_IOMUXC_LCD1_DATA16_ALT3_ARM_A9_TRACE_CLK = 3,
+   IMX_IOMUXC_LCD1_DATA16_ALT4_CSI1_DATA01 = 4,
+   IMX_IOMUXC_LCD1_DATA16_ALT5_GPIO3_IO17 = 5,
+   IMX_IOMUXC_LCD1_DATA16_ALT6_SRC_BOOT_CFG24 = 6,
+} IMX_IOMUXC_LCD1_DATA16_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA17_ALT0_LCD1_DATA17 = 0,
+   IMX_IOMUXC_LCD1_DATA17_ALT1_EIM_ADDR17 = 1,
+   IMX_IOMUXC_LCD1_DATA17_ALT3_ARM_A9_TRACE_CTL = 3,
+   IMX_IOMUXC_LCD1_DATA17_ALT4_CSI1_DATA00 = 4,
+   IMX_IOMUXC_LCD1_DATA17_ALT5_GPIO3_IO18 = 5,
+   IMX_IOMUXC_LCD1_DATA17_ALT6_SRC_BOOT_CFG25 = 6,
+} IMX_IOMUXC_LCD1_DATA17_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA18_ALT0_LCD1_DATA18 = 0,
+   IMX_IOMUXC_LCD1_DATA18_ALT1_EIM_ADDR18 = 1,
+   IMX_IOMUXC_LCD1_DATA18_ALT2_ARM_M4_EVENTO = 2,
+   IMX_IOMUXC_LCD1_DATA18_ALT3_ARM_A9_EVENTO = 3,
+   IMX_IOMUXC_LCD1_DATA18_ALT4_CSI1_DATA15 = 4,
+   IMX_IOMUXC_LCD1_DATA18_ALT5_GPIO3_IO19 = 5,
+   IMX_IOMUXC_LCD1_DATA18_ALT6_SRC_BOOT_CFG26 = 6,
+} IMX_IOMUXC_LCD1_DATA18_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA19_ALT0_LCD1_DATA19 = 0,
+   IMX_IOMUXC_LCD1_DATA19_ALT1_EIM_ADDR19 = 1,
+   IMX_IOMUXC_LCD1_DATA19_ALT2_ARM_M4_TRACE_SWO = 2,
+   IMX_IOMUXC_LCD1_DATA19_ALT4_CSI1_DATA14 = 4,
+   IMX_IOMUXC_LCD1_DATA19_ALT5_GPIO3_IO20 = 5,
+   IMX_IOMUXC_LCD1_DATA19_ALT6_SRC_BOOT_CFG27 = 6,
+} IMX_IOMUXC_LCD1_DATA19_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA20_ALT0_LCD1_DATA20 = 0,
+   IMX_IOMUXC_LCD1_DATA20_ALT1_EIM_ADDR20 = 1,
+   IMX_IOMUXC_LCD1_DATA20_ALT2_PWM8_OUT = 2,
+   IMX_IOMUXC_LCD1_DATA20_ALT3_ENET1_1588_EVENT2_OUT = 3,
+   IMX_IOMUXC_LCD1_DATA20_ALT4_CSI1_DATA13 = 4,
+   IMX_IOMUXC_LCD1_DATA20_ALT5_GPIO3_IO21 = 5,
+   IMX_IOMUXC_LCD1_DATA20_ALT6_SRC_BOOT_CFG28 = 6,
+} IMX_IOMUXC_LCD1_DATA20_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA21_ALT0_LCD1_DATA21 = 0,
+   IMX_IOMUXC_LCD1_DATA21_ALT1_EIM_ADDR21 = 1,
+   IMX_IOMUXC_LCD1_DATA21_ALT2_PWM7_OUT = 2,
+   IMX_IOMUXC_LCD1_DATA21_ALT3_ENET1_1588_EVENT3_OUT = 3,
+   IMX_IOMUXC_LCD1_DATA21_ALT4_CSI1_DATA12 = 4,
+   IMX_IOMUXC_LCD1_DATA21_ALT5_GPIO3_IO22 = 5,
+   IMX_IOMUXC_LCD1_DATA21_ALT6_SRC_BOOT_CFG29 = 6,
+} IMX_IOMUXC_LCD1_DATA21_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA22_ALT0_LCD1_DATA22 = 0,
+   IMX_IOMUXC_LCD1_DATA22_ALT1_EIM_ADDR22 = 1,
+   IMX_IOMUXC_LCD1_DATA22_ALT2_PWM6_OUT = 2,
+   IMX_IOMUXC_LCD1_DATA22_ALT3_ENET2_1588_EVENT2_OUT = 3,
+   IMX_IOMUXC_LCD1_DATA22_ALT4_CSI1_DATA11 = 4,
+   IMX_IOMUXC_LCD1_DATA22_ALT5_GPIO3_IO23 = 5,
+   IMX_IOMUXC_LCD1_DATA22_ALT6_SRC_BOOT_CFG30 = 6,
+} IMX_IOMUXC_LCD1_DATA22_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_DATA23_ALT0_LCD1_DATA23 = 0,
+   IMX_IOMUXC_LCD1_DATA23_ALT1_EIM_ADDR23 = 1,
+   IMX_IOMUXC_LCD1_DATA23_ALT2_PWM5_OUT = 2,
+   IMX_IOMUXC_LCD1_DATA23_ALT3_ENET2_1588_EVENT3_OUT = 3,
+   IMX_IOMUXC_LCD1_DATA23_ALT4_CSI1_DATA10 = 4,
+   IMX_IOMUXC_LCD1_DATA23_ALT5_GPIO3_IO24 = 5,
+   IMX_IOMUXC_LCD1_DATA23_ALT6_SRC_BOOT_CFG31 = 6,
+} IMX_IOMUXC_LCD1_DATA23_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_ENABLE_ALT0_LCD1_ENABLE = 0,
+   IMX_IOMUXC_LCD1_ENABLE_ALT1_LCD1_RD_E = 1,
+   IMX_IOMUXC_LCD1_ENABLE_ALT2_AUD3_TXC = 2,
+   IMX_IOMUXC_LCD1_ENABLE_ALT3_ENET1_1588_EVENT3_IN = 3,
+   IMX_IOMUXC_LCD1_ENABLE_ALT4_CSI1_DATA17 = 4,
+   IMX_IOMUXC_LCD1_ENABLE_ALT5_GPIO3_IO25 = 5,
+   IMX_IOMUXC_LCD1_ENABLE_ALT6_SD1_CD_B = 6,
+} IMX_IOMUXC_LCD1_ENABLE_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_HSYNC_ALT0_LCD1_HSYNC = 0,
+   IMX_IOMUXC_LCD1_HSYNC_ALT1_LCD1_RS = 1,
+   IMX_IOMUXC_LCD1_HSYNC_ALT2_AUD3_TXD = 2,
+   IMX_IOMUXC_LCD1_HSYNC_ALT3_ENET2_1588_EVENT2_IN = 3,
+   IMX_IOMUXC_LCD1_HSYNC_ALT4_CSI1_DATA18 = 4,
+   IMX_IOMUXC_LCD1_HSYNC_ALT5_GPIO3_IO26 = 5,
+   IMX_IOMUXC_LCD1_HSYNC_ALT6_SD2_WP = 6,
+} IMX_IOMUXC_LCD1_HSYNC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_RESET_ALT0_LCD1_RESET = 0,
+   IMX_IOMUXC_LCD1_RESET_ALT1_LCD1_CS = 1,
+   IMX_IOMUXC_LCD1_RESET_ALT2_AUD3_RXD = 2,
+   IMX_IOMUXC_LCD1_RESET_ALT3_ARM_A9_EVENTI = 3,
+   IMX_IOMUXC_LCD1_RESET_ALT4_ARM_M4_EVENTI = 4,
+   IMX_IOMUXC_LCD1_RESET_ALT5_GPIO3_IO27 = 5,
+   IMX_IOMUXC_LCD1_RESET_ALT6_CCM_PMIC_READY = 6,
+} IMX_IOMUXC_LCD1_RESET_ALT;
+
+typedef enum {
+   IMX_IOMUXC_LCD1_VSYNC_ALT0_LCD1_VSYNC = 0,
+   IMX_IOMUXC_LCD1_VSYNC_ALT1_LCD1_BUSY = 1,
+   IMX_IOMUXC_LCD1_VSYNC_ALT2_AUD3_TXFS = 2,
+   IMX_IOMUXC_LCD1_VSYNC_ALT3_ENET2_1588_EVENT3_IN = 3,
+   IMX_IOMUXC_LCD1_VSYNC_ALT4_CSI1_DATA19 = 4,
+   IMX_IOMUXC_LCD1_VSYNC_ALT5_GPIO3_IO28 = 5,
+   IMX_IOMUXC_LCD1_VSYNC_ALT6_SD2_CD_B = 6,
+} IMX_IOMUXC_LCD1_VSYNC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NAND_ALE_ALT0_NAND_ALE = 0,
+   IMX_IOMUXC_NAND_ALE_ALT1_I2C3_SDA = 1,
+   IMX_IOMUXC_NAND_ALE_ALT2_QSPI2A_SS0_B = 2,
+   IMX_IOMUXC_NAND_ALE_ALT3_ECSPI2_SS0 = 3,
+   IMX_IOMUXC_NAND_ALE_ALT4_ESAI_TX3_RX2 = 4,
+   IMX_IOMUXC_NAND_ALE_ALT5_GPIO4_IO00 = 5,
+   IMX_IOMUXC_NAND_ALE_ALT6_EIM_CS0_B = 6,
+} IMX_IOMUXC_NAND_ALE_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NAND_CE0_B_ALT0_NAND_CE0_B = 0,
+   IMX_IOMUXC_NAND_CE0_B_ALT1_SD2_VSELECT = 1,
+   IMX_IOMUXC_NAND_CE0_B_ALT2_QSPI2A_DATA2 = 2,
+   IMX_IOMUXC_NAND_CE0_B_ALT3_AUD4_TXC = 3,
+   IMX_IOMUXC_NAND_CE0_B_ALT4_ESAI_TX_CLK = 4,
+   IMX_IOMUXC_NAND_CE0_B_ALT5_GPIO4_IO01 = 5,
+   IMX_IOMUXC_NAND_CE0_B_ALT6_EIM_LBA_B = 6,
+} IMX_IOMUXC_NAND_CE0_B_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NAND_CE1_B_ALT0_NAND_CE1_B = 0,
+   IMX_IOMUXC_NAND_CE1_B_ALT1_SD3_RESET_B = 1,
+   IMX_IOMUXC_NAND_CE1_B_ALT2_QSPI2A_DATA3 = 2,
+   IMX_IOMUXC_NAND_CE1_B_ALT3_AUD4_TXD = 3,
+   IMX_IOMUXC_NAND_CE1_B_ALT4_ESAI_TX0 = 4,
+   IMX_IOMUXC_NAND_CE1_B_ALT5_GPIO4_IO02 = 5,
+   IMX_IOMUXC_NAND_CE1_B_ALT6_EIM_OE = 6,
+} IMX_IOMUXC_NAND_CE1_B_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NAND_CLE_ALT0_NAND_CLE = 0,
+   IMX_IOMUXC_NAND_CLE_ALT1_I2C3_SCL = 1,
+   IMX_IOMUXC_NAND_CLE_ALT2_QSPI2A_SCLK = 2,
+   IMX_IOMUXC_NAND_CLE_ALT3_ECSPI2_SCLK = 3,
+   IMX_IOMUXC_NAND_CLE_ALT4_ESAI_TX2_RX3 = 4,
+   IMX_IOMUXC_NAND_CLE_ALT5_GPIO4_IO03 = 5,
+   IMX_IOMUXC_NAND_CLE_ALT6_EIM_BCLK = 6,
+} IMX_IOMUXC_NAND_CLE_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NAND_DATA00_ALT0_NAND_DATA00 = 0,
+   IMX_IOMUXC_NAND_DATA00_ALT1_SD1_DATA4 = 1,
+   IMX_IOMUXC_NAND_DATA00_ALT2_QSPI2B_DATA1 = 2,
+   IMX_IOMUXC_NAND_DATA00_ALT3_ECSPI5_MISO = 3,
+   IMX_IOMUXC_NAND_DATA00_ALT4_ESAI_RX_CLK = 4,
+   IMX_IOMUXC_NAND_DATA00_ALT5_GPIO4_IO04 = 5,
+   IMX_IOMUXC_NAND_DATA00_ALT6_EIM_AD00 = 6,
+} IMX_IOMUXC_NAND_DATA00_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NAND_DATA01_ALT0_NAND_DATA01 = 0,
+   IMX_IOMUXC_NAND_DATA01_ALT1_SD1_DATA5 = 1,
+   IMX_IOMUXC_NAND_DATA01_ALT2_QSPI2B_DATA0 = 2,
+   IMX_IOMUXC_NAND_DATA01_ALT3_ECSPI5_MOSI = 3,
+   IMX_IOMUXC_NAND_DATA01_ALT4_ESAI_RX_FS = 4,
+   IMX_IOMUXC_NAND_DATA01_ALT5_GPIO4_IO05 = 5,
+   IMX_IOMUXC_NAND_DATA01_ALT6_EIM_AD01 = 6,
+} IMX_IOMUXC_NAND_DATA01_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NAND_DATA02_ALT0_NAND_DATA02 = 0,
+   IMX_IOMUXC_NAND_DATA02_ALT1_SD1_DATA6 = 1,
+   IMX_IOMUXC_NAND_DATA02_ALT2_QSPI2B_SCLK = 2,
+   IMX_IOMUXC_NAND_DATA02_ALT3_ECSPI5_SCLK = 3,
+   IMX_IOMUXC_NAND_DATA02_ALT4_ESAI_TX_HF_CLK = 4,
+   IMX_IOMUXC_NAND_DATA02_ALT5_GPIO4_IO06 = 5,
+   IMX_IOMUXC_NAND_DATA02_ALT6_EIM_AD02 = 6,
+} IMX_IOMUXC_NAND_DATA02_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NAND_DATA03_ALT0_NAND_DATA03 = 0,
+   IMX_IOMUXC_NAND_DATA03_ALT1_SD1_DATA7 = 1,
+   IMX_IOMUXC_NAND_DATA03_ALT2_QSPI2B_SS0_B = 2,
+   IMX_IOMUXC_NAND_DATA03_ALT3_ECSPI5_SS0 = 3,
+   IMX_IOMUXC_NAND_DATA03_ALT4_ESAI_RX_HF_CLK = 4,
+   IMX_IOMUXC_NAND_DATA03_ALT5_GPIO4_IO07 = 5,
+   IMX_IOMUXC_NAND_DATA03_ALT6_EIM_AD03 = 6,
+} IMX_IOMUXC_NAND_DATA03_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NAND_DATA04_ALT0_NAND_DATA04 = 0,
+   IMX_IOMUXC_NAND_DATA04_ALT1_SD2_DATA4 = 1,
+   IMX_IOMUXC_NAND_DATA04_ALT2_QSPI2B_SS1_B = 2,
+   IMX_IOMUXC_NAND_DATA04_ALT3_UART3_RTS_B = 3,
+   IMX_IOMUXC_NAND_DATA04_ALT4_AUD4_RXFS = 4,
+   IMX_IOMUXC_NAND_DATA04_ALT5_GPIO4_IO08 = 5,
+   IMX_IOMUXC_NAND_DATA04_ALT6_EIM_AD04 = 6,
+} IMX_IOMUXC_NAND_DATA04_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NAND_DATA05_ALT0_NAND_DATA05 = 0,
+   IMX_IOMUXC_NAND_DATA05_ALT1_SD2_DATA5 = 1,
+   IMX_IOMUXC_NAND_DATA05_ALT2_QSPI2B_DQS = 2,
+   IMX_IOMUXC_NAND_DATA05_ALT3_UART3_CTS_B = 3,
+   IMX_IOMUXC_NAND_DATA05_ALT4_AUD4_RXC = 4,
+   IMX_IOMUXC_NAND_DATA05_ALT5_GPIO4_IO09 = 5,
+   IMX_IOMUXC_NAND_DATA05_ALT6_EIM_AD05 = 6,
+} IMX_IOMUXC_NAND_DATA05_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NAND_DATA06_ALT0_NAND_DATA06 = 0,
+   IMX_IOMUXC_NAND_DATA06_ALT1_SD2_DATA6 = 1,
+   IMX_IOMUXC_NAND_DATA06_ALT2_QSPI2A_SS1_B = 2,
+   IMX_IOMUXC_NAND_DATA06_ALT3_UART3_RX_DATA = 3,
+   IMX_IOMUXC_NAND_DATA06_ALT4_PWM3_OUT = 4,
+   IMX_IOMUXC_NAND_DATA06_ALT5_GPIO4_IO10 = 5,
+   IMX_IOMUXC_NAND_DATA06_ALT6_EIM_AD06 = 6,
+} IMX_IOMUXC_NAND_DATA06_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NAND_DATA07_ALT0_NAND_DATA07 = 0,
+   IMX_IOMUXC_NAND_DATA07_ALT1_SD2_DATA7 = 1,
+   IMX_IOMUXC_NAND_DATA07_ALT2_QSPI2A_DQS = 2,
+   IMX_IOMUXC_NAND_DATA07_ALT3_UART3_TX_DATA = 3,
+   IMX_IOMUXC_NAND_DATA07_ALT4_PWM4_OUT = 4,
+   IMX_IOMUXC_NAND_DATA07_ALT5_GPIO4_IO11 = 5,
+   IMX_IOMUXC_NAND_DATA07_ALT6_EIM_AD07 = 6,
+} IMX_IOMUXC_NAND_DATA07_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NAND_RE_B_ALT0_NAND_RE_B = 0,
+   IMX_IOMUXC_NAND_RE_B_ALT1_SD2_RESET_B = 1,
+   IMX_IOMUXC_NAND_RE_B_ALT2_QSPI2B_DATA3 = 2,
+   IMX_IOMUXC_NAND_RE_B_ALT3_AUD4_TXFS = 3,
+   IMX_IOMUXC_NAND_RE_B_ALT4_ESAI_TX_FS = 4,
+   IMX_IOMUXC_NAND_RE_B_ALT5_GPIO4_IO12 = 5,
+   IMX_IOMUXC_NAND_RE_B_ALT6_EIM_RW = 6,
+} IMX_IOMUXC_NAND_RE_B_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NAND_READY_B_ALT0_NAND_READY_B = 0,
+   IMX_IOMUXC_NAND_READY_B_ALT1_SD1_VSELECT = 1,
+   IMX_IOMUXC_NAND_READY_B_ALT2_QSPI2A_DATA1 = 2,
+   IMX_IOMUXC_NAND_READY_B_ALT3_ECSPI2_MISO = 3,
+   IMX_IOMUXC_NAND_READY_B_ALT4_ESAI_TX1 = 4,
+   IMX_IOMUXC_NAND_READY_B_ALT5_GPIO4_IO13 = 5,
+   IMX_IOMUXC_NAND_READY_B_ALT6_EIM_EB1_B = 6,
+} IMX_IOMUXC_NAND_READY_B_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NAND_WE_B_ALT0_NAND_WE_B = 0,
+   IMX_IOMUXC_NAND_WE_B_ALT1_SD4_VSELECT = 1,
+   IMX_IOMUXC_NAND_WE_B_ALT2_QSPI2B_DATA2 = 2,
+   IMX_IOMUXC_NAND_WE_B_ALT3_AUD4_RXD = 3,
+   IMX_IOMUXC_NAND_WE_B_ALT4_ESAI_TX5_RX0 = 4,
+   IMX_IOMUXC_NAND_WE_B_ALT5_GPIO4_IO14 = 5,
+   IMX_IOMUXC_NAND_WE_B_ALT6_EIM_WAIT = 6,
+} IMX_IOMUXC_NAND_WE_B_ALT;
+
+typedef enum {
+   IMX_IOMUXC_NAND_WP_B_ALT0_NAND_WP_B = 0,
+   IMX_IOMUXC_NAND_WP_B_ALT1_SD1_RESET_B = 1,
+   IMX_IOMUXC_NAND_WP_B_ALT2_QSPI2A_DATA0 = 2,
+   IMX_IOMUXC_NAND_WP_B_ALT3_ECSPI2_MOSI = 3,
+   IMX_IOMUXC_NAND_WP_B_ALT4_ESAI_TX4_RX1 = 4,
+   IMX_IOMUXC_NAND_WP_B_ALT5_GPIO4_IO15 = 5,
+   IMX_IOMUXC_NAND_WP_B_ALT6_EIM_EB0_B = 6,
+} IMX_IOMUXC_NAND_WP_B_ALT;
+
+typedef enum {
+   IMX_IOMUXC_QSPI1A_DATA0_ALT0_QSPI1A_DATA0 = 0,
+   IMX_IOMUXC_QSPI1A_DATA0_ALT1_USB_OTG2_OC = 1,
+   IMX_IOMUXC_QSPI1A_DATA0_ALT2_ECSPI1_MOSI = 2,
+   IMX_IOMUXC_QSPI1A_DATA0_ALT3_ESAI_TX4_RX1 = 3,
+   IMX_IOMUXC_QSPI1A_DATA0_ALT4_CSI1_DATA14 = 4,
+   IMX_IOMUXC_QSPI1A_DATA0_ALT5_GPIO4_IO16 = 5,
+   IMX_IOMUXC_QSPI1A_DATA0_ALT6_EIM_DATA06 = 6,
+} IMX_IOMUXC_QSPI1A_DATA0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_QSPI1A_DATA1_ALT0_QSPI1A_DATA1 = 0,
+   IMX_IOMUXC_QSPI1A_DATA1_ALT1_USB_OTG1_ID = 1,
+   IMX_IOMUXC_QSPI1A_DATA1_ALT2_ECSPI1_MISO = 2,
+   IMX_IOMUXC_QSPI1A_DATA1_ALT3_ESAI_TX1 = 3,
+   IMX_IOMUXC_QSPI1A_DATA1_ALT4_CSI1_DATA13 = 4,
+   IMX_IOMUXC_QSPI1A_DATA1_ALT5_GPIO4_IO17 = 5,
+   IMX_IOMUXC_QSPI1A_DATA1_ALT6_EIM_DATA05 = 6,
+} IMX_IOMUXC_QSPI1A_DATA1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_QSPI1A_DATA2_ALT0_QSPI1A_DATA2 = 0,
+   IMX_IOMUXC_QSPI1A_DATA2_ALT1_USB_OTG1_PWR = 1,
+   IMX_IOMUXC_QSPI1A_DATA2_ALT2_ECSPI5_SS1 = 2,
+   IMX_IOMUXC_QSPI1A_DATA2_ALT3_ESAI_TX_CLK = 3,
+   IMX_IOMUXC_QSPI1A_DATA2_ALT4_CSI1_DATA12 = 4,
+   IMX_IOMUXC_QSPI1A_DATA2_ALT5_GPIO4_IO18 = 5,
+   IMX_IOMUXC_QSPI1A_DATA2_ALT6_EIM_DATA04 = 6,
+} IMX_IOMUXC_QSPI1A_DATA2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_QSPI1A_DATA3_ALT0_QSPI1A_DATA3 = 0,
+   IMX_IOMUXC_QSPI1A_DATA3_ALT1_USB_OTG1_OC = 1,
+   IMX_IOMUXC_QSPI1A_DATA3_ALT2_ECSPI5_SS2 = 2,
+   IMX_IOMUXC_QSPI1A_DATA3_ALT3_ESAI_TX0 = 3,
+   IMX_IOMUXC_QSPI1A_DATA3_ALT4_CSI1_DATA11 = 4,
+   IMX_IOMUXC_QSPI1A_DATA3_ALT5_GPIO4_IO19 = 5,
+   IMX_IOMUXC_QSPI1A_DATA3_ALT6_EIM_DATA03 = 6,
+} IMX_IOMUXC_QSPI1A_DATA3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_QSPI1A_DQS_ALT0_QSPI1A_DQS = 0,
+   IMX_IOMUXC_QSPI1A_DQS_ALT1_CAN2_TX = 1,
+   IMX_IOMUXC_QSPI1A_DQS_ALT3_ECSPI5_MOSI = 3,
+   IMX_IOMUXC_QSPI1A_DQS_ALT4_CSI1_DATA15 = 4,
+   IMX_IOMUXC_QSPI1A_DQS_ALT5_GPIO4_IO20 = 5,
+   IMX_IOMUXC_QSPI1A_DQS_ALT6_EIM_DATA07 = 6,
+} IMX_IOMUXC_QSPI1A_DQS_ALT;
+
+typedef enum {
+   IMX_IOMUXC_QSPI1A_SCLK_ALT0_QSPI1A_SCLK = 0,
+   IMX_IOMUXC_QSPI1A_SCLK_ALT1_USB_OTG2_ID = 1,
+   IMX_IOMUXC_QSPI1A_SCLK_ALT2_ECSPI1_SCLK = 2,
+   IMX_IOMUXC_QSPI1A_SCLK_ALT3_ESAI_TX2_RX3 = 3,
+   IMX_IOMUXC_QSPI1A_SCLK_ALT4_CSI1_DATA01 = 4,
+   IMX_IOMUXC_QSPI1A_SCLK_ALT5_GPIO4_IO21 = 5,
+   IMX_IOMUXC_QSPI1A_SCLK_ALT6_EIM_DATA00 = 6,
+} IMX_IOMUXC_QSPI1A_SCLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_QSPI1A_SS0_B_ALT0_QSPI1A_SS0_B = 0,
+   IMX_IOMUXC_QSPI1A_SS0_B_ALT1_USB_OTG2_PWR = 1,
+   IMX_IOMUXC_QSPI1A_SS0_B_ALT2_ECSPI1_SS0 = 2,
+   IMX_IOMUXC_QSPI1A_SS0_B_ALT3_ESAI_TX3_RX2 = 3,
+   IMX_IOMUXC_QSPI1A_SS0_B_ALT4_CSI1_DATA00 = 4,
+   IMX_IOMUXC_QSPI1A_SS0_B_ALT5_GPIO4_IO22 = 5,
+   IMX_IOMUXC_QSPI1A_SS0_B_ALT6_EIM_DATA01 = 6,
+} IMX_IOMUXC_QSPI1A_SS0_B_ALT;
+
+typedef enum {
+   IMX_IOMUXC_QSPI1A_SS1_B_ALT0_QSPI1A_SS1_B = 0,
+   IMX_IOMUXC_QSPI1A_SS1_B_ALT1_CAN1_RX = 1,
+   IMX_IOMUXC_QSPI1A_SS1_B_ALT3_ECSPI5_MISO = 3,
+   IMX_IOMUXC_QSPI1A_SS1_B_ALT4_CSI1_DATA10 = 4,
+   IMX_IOMUXC_QSPI1A_SS1_B_ALT5_GPIO4_IO23 = 5,
+   IMX_IOMUXC_QSPI1A_SS1_B_ALT6_EIM_DATA02 = 6,
+} IMX_IOMUXC_QSPI1A_SS1_B_ALT;
+
+typedef enum {
+   IMX_IOMUXC_QSPI1B_DATA0_ALT0_QSPI1B_DATA0 = 0,
+   IMX_IOMUXC_QSPI1B_DATA0_ALT1_UART3_CTS_B = 1,
+   IMX_IOMUXC_QSPI1B_DATA0_ALT2_ECSPI3_MOSI = 2,
+   IMX_IOMUXC_QSPI1B_DATA0_ALT3_ESAI_RX_FS = 3,
+   IMX_IOMUXC_QSPI1B_DATA0_ALT4_CSI1_DATA22 = 4,
+   IMX_IOMUXC_QSPI1B_DATA0_ALT5_GPIO4_IO24 = 5,
+   IMX_IOMUXC_QSPI1B_DATA0_ALT6_EIM_DATA14 = 6,
+} IMX_IOMUXC_QSPI1B_DATA0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_QSPI1B_DATA1_ALT0_QSPI1B_DATA1 = 0,
+   IMX_IOMUXC_QSPI1B_DATA1_ALT1_UART3_RTS_B = 1,
+   IMX_IOMUXC_QSPI1B_DATA1_ALT2_ECSPI3_MISO = 2,
+   IMX_IOMUXC_QSPI1B_DATA1_ALT3_ESAI_RX_CLK = 3,
+   IMX_IOMUXC_QSPI1B_DATA1_ALT4_CSI1_DATA21 = 4,
+   IMX_IOMUXC_QSPI1B_DATA1_ALT5_GPIO4_IO25 = 5,
+   IMX_IOMUXC_QSPI1B_DATA1_ALT6_EIM_DATA13 = 6,
+} IMX_IOMUXC_QSPI1B_DATA1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_QSPI1B_DATA2_ALT0_QSPI1B_DATA2 = 0,
+   IMX_IOMUXC_QSPI1B_DATA2_ALT1_I2C2_SDA = 1,
+   IMX_IOMUXC_QSPI1B_DATA2_ALT2_ECSPI5_RDY = 2,
+   IMX_IOMUXC_QSPI1B_DATA2_ALT3_ESAI_TX5_RX0 = 3,
+   IMX_IOMUXC_QSPI1B_DATA2_ALT4_CSI1_DATA20 = 4,
+   IMX_IOMUXC_QSPI1B_DATA2_ALT5_GPIO4_IO26 = 5,
+   IMX_IOMUXC_QSPI1B_DATA2_ALT6_EIM_DATA12 = 6,
+} IMX_IOMUXC_QSPI1B_DATA2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_QSPI1B_DATA3_ALT0_QSPI1B_DATA3 = 0,
+   IMX_IOMUXC_QSPI1B_DATA3_ALT1_I2C2_SCL = 1,
+   IMX_IOMUXC_QSPI1B_DATA3_ALT2_ECSPI5_SS3 = 2,
+   IMX_IOMUXC_QSPI1B_DATA3_ALT3_ESAI_TX_FS = 3,
+   IMX_IOMUXC_QSPI1B_DATA3_ALT4_CSI1_DATA19 = 4,
+   IMX_IOMUXC_QSPI1B_DATA3_ALT5_GPIO4_IO27 = 5,
+   IMX_IOMUXC_QSPI1B_DATA3_ALT6_EIM_DATA11 = 6,
+} IMX_IOMUXC_QSPI1B_DATA3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_QSPI1B_DQS_ALT0_QSPI1B_DQS = 0,
+   IMX_IOMUXC_QSPI1B_DQS_ALT1_CAN1_TX = 1,
+   IMX_IOMUXC_QSPI1B_DQS_ALT3_ECSPI5_SS0 = 3,
+   IMX_IOMUXC_QSPI1B_DQS_ALT4_CSI1_DATA23 = 4,
+   IMX_IOMUXC_QSPI1B_DQS_ALT5_GPIO4_IO28 = 5,
+   IMX_IOMUXC_QSPI1B_DQS_ALT6_EIM_DATA15 = 6,
+} IMX_IOMUXC_QSPI1B_DQS_ALT;
+
+typedef enum {
+   IMX_IOMUXC_QSPI1B_SCLK_ALT0_QSPI1B_SCLK = 0,
+   IMX_IOMUXC_QSPI1B_SCLK_ALT1_UART3_RX_DATA = 1,
+   IMX_IOMUXC_QSPI1B_SCLK_ALT2_ECSPI3_SCLK = 2,
+   IMX_IOMUXC_QSPI1B_SCLK_ALT3_ESAI_RX_HF_CLK = 3,
+   IMX_IOMUXC_QSPI1B_SCLK_ALT4_CSI1_DATA16 = 4,
+   IMX_IOMUXC_QSPI1B_SCLK_ALT5_GPIO4_IO29 = 5,
+   IMX_IOMUXC_QSPI1B_SCLK_ALT6_EIM_DATA08 = 6,
+} IMX_IOMUXC_QSPI1B_SCLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_QSPI1B_SS0_B_ALT0_QSPI1B_SS0_B = 0,
+   IMX_IOMUXC_QSPI1B_SS0_B_ALT1_UART3_TX_DATA = 1,
+   IMX_IOMUXC_QSPI1B_SS0_B_ALT2_ECSPI3_SS0 = 2,
+   IMX_IOMUXC_QSPI1B_SS0_B_ALT3_ESAI_TX_HF_CLK = 3,
+   IMX_IOMUXC_QSPI1B_SS0_B_ALT4_CSI1_DATA17 = 4,
+   IMX_IOMUXC_QSPI1B_SS0_B_ALT5_GPIO4_IO30 = 5,
+   IMX_IOMUXC_QSPI1B_SS0_B_ALT6_EIM_DATA09 = 6,
+} IMX_IOMUXC_QSPI1B_SS0_B_ALT;
+
+typedef enum {
+   IMX_IOMUXC_QSPI1B_SS1_B_ALT0_QSPI1B_SS1_B = 0,
+   IMX_IOMUXC_QSPI1B_SS1_B_ALT1_CAN2_RX = 1,
+   IMX_IOMUXC_QSPI1B_SS1_B_ALT3_ECSPI5_SCLK = 3,
+   IMX_IOMUXC_QSPI1B_SS1_B_ALT4_CSI1_DATA18 = 4,
+   IMX_IOMUXC_QSPI1B_SS1_B_ALT5_GPIO4_IO31 = 5,
+   IMX_IOMUXC_QSPI1B_SS1_B_ALT6_EIM_DATA10 = 6,
+} IMX_IOMUXC_QSPI1B_SS1_B_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII1_RD0_ALT0_ENET1_RX_DATA0 = 0,
+   IMX_IOMUXC_RGMII1_RD0_ALT5_GPIO5_IO00 = 5,
+   IMX_IOMUXC_RGMII1_RD0_ALT6_CSI2_DATA10 = 6,
+} IMX_IOMUXC_RGMII1_RD0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII1_RD1_ALT0_ENET1_RX_DATA1 = 0,
+   IMX_IOMUXC_RGMII1_RD1_ALT5_GPIO5_IO01 = 5,
+   IMX_IOMUXC_RGMII1_RD1_ALT6_CSI2_DATA11 = 6,
+} IMX_IOMUXC_RGMII1_RD1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII1_RD2_ALT0_ENET1_RX_DATA2 = 0,
+   IMX_IOMUXC_RGMII1_RD2_ALT5_GPIO5_IO02 = 5,
+   IMX_IOMUXC_RGMII1_RD2_ALT6_CSI2_DATA12 = 6,
+} IMX_IOMUXC_RGMII1_RD2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII1_RD3_ALT0_ENET1_RX_DATA3 = 0,
+   IMX_IOMUXC_RGMII1_RD3_ALT5_GPIO5_IO03 = 5,
+   IMX_IOMUXC_RGMII1_RD3_ALT6_CSI2_DATA13 = 6,
+} IMX_IOMUXC_RGMII1_RD3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII1_RX_CTL_ALT0_ENET1_RX_EN = 0,
+   IMX_IOMUXC_RGMII1_RX_CTL_ALT5_GPIO5_IO04 = 5,
+   IMX_IOMUXC_RGMII1_RX_CTL_ALT6_CSI2_DATA14 = 6,
+} IMX_IOMUXC_RGMII1_RX_CTL_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII1_RXC_ALT0_ENET1_RGMII_RXC = 0,
+   IMX_IOMUXC_RGMII1_RXC_ALT1_ENET1_RX_ER = 1,
+   IMX_IOMUXC_RGMII1_RXC_ALT5_GPIO5_IO05 = 5,
+   IMX_IOMUXC_RGMII1_RXC_ALT6_CSI2_DATA15 = 6,
+} IMX_IOMUXC_RGMII1_RXC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII1_TD0_ALT0_ENET1_TX_DATA0 = 0,
+   IMX_IOMUXC_RGMII1_TD0_ALT2_SAI2_RX_SYNC = 2,
+   IMX_IOMUXC_RGMII1_TD0_ALT5_GPIO5_IO06 = 5,
+   IMX_IOMUXC_RGMII1_TD0_ALT6_CSI2_DATA16 = 6,
+} IMX_IOMUXC_RGMII1_TD0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII1_TD1_ALT0_ENET1_TX_DATA1 = 0,
+   IMX_IOMUXC_RGMII1_TD1_ALT2_SAI2_RX_BCLK = 2,
+   IMX_IOMUXC_RGMII1_TD1_ALT5_GPIO5_IO07 = 5,
+   IMX_IOMUXC_RGMII1_TD1_ALT6_CSI2_DATA17 = 6,
+} IMX_IOMUXC_RGMII1_TD1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII1_TD2_ALT0_ENET1_TX_DATA2 = 0,
+   IMX_IOMUXC_RGMII1_TD2_ALT2_SAI2_TX_SYNC = 2,
+   IMX_IOMUXC_RGMII1_TD2_ALT5_GPIO5_IO08 = 5,
+   IMX_IOMUXC_RGMII1_TD2_ALT6_CSI2_DATA18 = 6,
+} IMX_IOMUXC_RGMII1_TD2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII1_TD3_ALT0_ENET1_TX_DATA3 = 0,
+   IMX_IOMUXC_RGMII1_TD3_ALT2_SAI2_TX_BCLK = 2,
+   IMX_IOMUXC_RGMII1_TD3_ALT5_GPIO5_IO09 = 5,
+   IMX_IOMUXC_RGMII1_TD3_ALT6_CSI2_DATA19 = 6,
+} IMX_IOMUXC_RGMII1_TD3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII1_TX_CTL_ALT0_ENET1_TX_EN = 0,
+   IMX_IOMUXC_RGMII1_TX_CTL_ALT2_SAI2_RX_DATA0 = 2,
+   IMX_IOMUXC_RGMII1_TX_CTL_ALT5_GPIO5_IO10 = 5,
+   IMX_IOMUXC_RGMII1_TX_CTL_ALT6_CSI2_DATA00 = 6,
+} IMX_IOMUXC_RGMII1_TX_CTL_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII1_TXC_ALT0_ENET1_RGMII_TXC = 0,
+   IMX_IOMUXC_RGMII1_TXC_ALT1_ENET1_TX_ER = 1,
+   IMX_IOMUXC_RGMII1_TXC_ALT2_SAI2_TX_DATA0 = 2,
+   IMX_IOMUXC_RGMII1_TXC_ALT5_GPIO5_IO11 = 5,
+   IMX_IOMUXC_RGMII1_TXC_ALT6_CSI2_DATA01 = 6,
+} IMX_IOMUXC_RGMII1_TXC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII2_RD0_ALT0_ENET2_RX_DATA0 = 0,
+   IMX_IOMUXC_RGMII2_RD0_ALT2_PWM4_OUT = 2,
+   IMX_IOMUXC_RGMII2_RD0_ALT5_GPIO5_IO12 = 5,
+   IMX_IOMUXC_RGMII2_RD0_ALT6_CSI2_DATA02 = 6,
+} IMX_IOMUXC_RGMII2_RD0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII2_RD1_ALT0_ENET2_RX_DATA1 = 0,
+   IMX_IOMUXC_RGMII2_RD1_ALT2_PWM3_OUT = 2,
+   IMX_IOMUXC_RGMII2_RD1_ALT5_GPIO5_IO13 = 5,
+   IMX_IOMUXC_RGMII2_RD1_ALT6_CSI2_DATA03 = 6,
+} IMX_IOMUXC_RGMII2_RD1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII2_RD2_ALT0_ENET2_RX_DATA2 = 0,
+   IMX_IOMUXC_RGMII2_RD2_ALT2_PWM2_OUT = 2,
+   IMX_IOMUXC_RGMII2_RD2_ALT5_GPIO5_IO14 = 5,
+   IMX_IOMUXC_RGMII2_RD2_ALT6_CSI2_DATA04 = 6,
+} IMX_IOMUXC_RGMII2_RD2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII2_RD3_ALT0_ENET2_RX_DATA3 = 0,
+   IMX_IOMUXC_RGMII2_RD3_ALT2_PWM1_OUT = 2,
+   IMX_IOMUXC_RGMII2_RD3_ALT5_GPIO5_IO15 = 5,
+   IMX_IOMUXC_RGMII2_RD3_ALT6_CSI2_DATA05 = 6,
+} IMX_IOMUXC_RGMII2_RD3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII2_RX_CTL_ALT0_ENET2_RX_EN = 0,
+   IMX_IOMUXC_RGMII2_RX_CTL_ALT5_GPIO5_IO16 = 5,
+   IMX_IOMUXC_RGMII2_RX_CTL_ALT6_CSI2_DATA06 = 6,
+} IMX_IOMUXC_RGMII2_RX_CTL_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII2_RXC_ALT0_ENET2_RGMII_RXC = 0,
+   IMX_IOMUXC_RGMII2_RXC_ALT1_ENET2_RX_ER = 1,
+   IMX_IOMUXC_RGMII2_RXC_ALT5_GPIO5_IO17 = 5,
+   IMX_IOMUXC_RGMII2_RXC_ALT6_CSI2_DATA07 = 6,
+} IMX_IOMUXC_RGMII2_RXC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII2_TD0_ALT0_ENET2_TX_DATA0 = 0,
+   IMX_IOMUXC_RGMII2_TD0_ALT2_SAI1_RX_SYNC = 2,
+   IMX_IOMUXC_RGMII2_TD0_ALT3_PWM8_OUT = 3,
+   IMX_IOMUXC_RGMII2_TD0_ALT5_GPIO5_IO18 = 5,
+   IMX_IOMUXC_RGMII2_TD0_ALT6_CSI2_DATA08 = 6,
+} IMX_IOMUXC_RGMII2_TD0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII2_TD1_ALT0_ENET2_TX_DATA1 = 0,
+   IMX_IOMUXC_RGMII2_TD1_ALT2_SAI1_RX_BCLK = 2,
+   IMX_IOMUXC_RGMII2_TD1_ALT3_PWM7_OUT = 3,
+   IMX_IOMUXC_RGMII2_TD1_ALT5_GPIO5_IO19 = 5,
+   IMX_IOMUXC_RGMII2_TD1_ALT6_CSI2_DATA09 = 6,
+} IMX_IOMUXC_RGMII2_TD1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII2_TD2_ALT0_ENET2_TX_DATA2 = 0,
+   IMX_IOMUXC_RGMII2_TD2_ALT2_SAI1_TX_SYNC = 2,
+   IMX_IOMUXC_RGMII2_TD2_ALT3_PWM6_OUT = 3,
+   IMX_IOMUXC_RGMII2_TD2_ALT5_GPIO5_IO20 = 5,
+   IMX_IOMUXC_RGMII2_TD2_ALT6_CSI2_VSYNC = 6,
+} IMX_IOMUXC_RGMII2_TD2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII2_TD3_ALT0_ENET2_TX_DATA3 = 0,
+   IMX_IOMUXC_RGMII2_TD3_ALT2_SAI1_TX_BCLK = 2,
+   IMX_IOMUXC_RGMII2_TD3_ALT3_PWM5_OUT = 3,
+   IMX_IOMUXC_RGMII2_TD3_ALT5_GPIO5_IO21 = 5,
+   IMX_IOMUXC_RGMII2_TD3_ALT6_CSI2_HSYNC = 6,
+} IMX_IOMUXC_RGMII2_TD3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII2_TX_CTL_ALT0_ENET2_TX_EN = 0,
+   IMX_IOMUXC_RGMII2_TX_CTL_ALT2_SAI1_RX_DATA0 = 2,
+   IMX_IOMUXC_RGMII2_TX_CTL_ALT5_GPIO5_IO22 = 5,
+   IMX_IOMUXC_RGMII2_TX_CTL_ALT6_CSI2_FIELD = 6,
+   IMX_IOMUXC_RGMII2_TX_CTL_ALT7_JTAG_DE_B = 7,
+} IMX_IOMUXC_RGMII2_TX_CTL_ALT;
+
+typedef enum {
+   IMX_IOMUXC_RGMII2_TXC_ALT0_ENET2_RGMII_TXC = 0,
+   IMX_IOMUXC_RGMII2_TXC_ALT1_ENET2_TX_ER = 1,
+   IMX_IOMUXC_RGMII2_TXC_ALT2_SAI1_TX_DATA0 = 2,
+   IMX_IOMUXC_RGMII2_TXC_ALT5_GPIO5_IO23 = 5,
+   IMX_IOMUXC_RGMII2_TXC_ALT6_CSI2_PIXCLK = 6,
+} IMX_IOMUXC_RGMII2_TXC_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_CLK_ALT0_SD1_CLK = 0,
+   IMX_IOMUXC_SD1_CLK_ALT1_AUD5_RXFS = 1,
+   IMX_IOMUXC_SD1_CLK_ALT2_WDOG2_B = 2,
+   IMX_IOMUXC_SD1_CLK_ALT3_GPT_CLK = 3,
+   IMX_IOMUXC_SD1_CLK_ALT4_WDOG2_RST_B_DEB = 4,
+   IMX_IOMUXC_SD1_CLK_ALT5_GPIO6_IO00 = 5,
+   IMX_IOMUXC_SD1_CLK_ALT6_ENET2_1588_EVENT1_OUT = 6,
+} IMX_IOMUXC_SD1_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_CMD_ALT0_SD1_CMD = 0,
+   IMX_IOMUXC_SD1_CMD_ALT1_AUD5_RXC = 1,
+   IMX_IOMUXC_SD1_CMD_ALT2_WDOG1_B = 2,
+   IMX_IOMUXC_SD1_CMD_ALT3_GPT_COMPARE1 = 3,
+   IMX_IOMUXC_SD1_CMD_ALT4_WDOG1_RST_B_DEB = 4,
+   IMX_IOMUXC_SD1_CMD_ALT5_GPIO6_IO01 = 5,
+   IMX_IOMUXC_SD1_CMD_ALT6_ENET2_1588_EVENT1_IN = 6,
+   IMX_IOMUXC_SD1_CMD_ALT7_CCM_CLKO1 = 7,
+} IMX_IOMUXC_SD1_CMD_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_DATA0_ALT0_SD1_DATA0 = 0,
+   IMX_IOMUXC_SD1_DATA0_ALT1_AUD5_RXD = 1,
+   IMX_IOMUXC_SD1_DATA0_ALT3_GPT_CAPTURE1 = 3,
+   IMX_IOMUXC_SD1_DATA0_ALT4_UART2_RX_DATA = 4,
+   IMX_IOMUXC_SD1_DATA0_ALT5_GPIO6_IO02 = 5,
+   IMX_IOMUXC_SD1_DATA0_ALT6_ENET1_1588_EVENT1_IN = 6,
+} IMX_IOMUXC_SD1_DATA0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_DATA1_ALT0_SD1_DATA1 = 0,
+   IMX_IOMUXC_SD1_DATA1_ALT1_AUD5_TXC = 1,
+   IMX_IOMUXC_SD1_DATA1_ALT2_PWM4_OUT = 2,
+   IMX_IOMUXC_SD1_DATA1_ALT3_GPT_CAPTURE2 = 3,
+   IMX_IOMUXC_SD1_DATA1_ALT4_UART2_TX_DATA = 4,
+   IMX_IOMUXC_SD1_DATA1_ALT5_GPIO6_IO03 = 5,
+   IMX_IOMUXC_SD1_DATA1_ALT6_ENET1_1588_EVENT1_OUT = 6,
+   IMX_IOMUXC_SD1_DATA1_ALT7_CCM_CLKO2 = 7,
+} IMX_IOMUXC_SD1_DATA1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_DATA2_ALT0_SD1_DATA2 = 0,
+   IMX_IOMUXC_SD1_DATA2_ALT1_AUD5_TXFS = 1,
+   IMX_IOMUXC_SD1_DATA2_ALT2_PWM3_OUT = 2,
+   IMX_IOMUXC_SD1_DATA2_ALT3_GPT_COMPARE2 = 3,
+   IMX_IOMUXC_SD1_DATA2_ALT4_UART2_CTS_B = 4,
+   IMX_IOMUXC_SD1_DATA2_ALT5_GPIO6_IO04 = 5,
+   IMX_IOMUXC_SD1_DATA2_ALT6_ECSPI4_RDY = 6,
+} IMX_IOMUXC_SD1_DATA2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD1_DATA3_ALT0_SD1_DATA3 = 0,
+   IMX_IOMUXC_SD1_DATA3_ALT1_AUD5_TXD = 1,
+   IMX_IOMUXC_SD1_DATA3_ALT2_AUD5_RXD = 2,
+   IMX_IOMUXC_SD1_DATA3_ALT3_GPT_COMPARE3 = 3,
+   IMX_IOMUXC_SD1_DATA3_ALT4_UART2_RTS_B = 4,
+   IMX_IOMUXC_SD1_DATA3_ALT5_GPIO6_IO05 = 5,
+   IMX_IOMUXC_SD1_DATA3_ALT6_ECSPI4_SS1 = 6,
+   IMX_IOMUXC_SD1_DATA3_ALT7_CCM_PMIC_READY = 7,
+} IMX_IOMUXC_SD1_DATA3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_CLK_ALT0_SD2_CLK = 0,
+   IMX_IOMUXC_SD2_CLK_ALT1_AUD6_RXFS = 1,
+   IMX_IOMUXC_SD2_CLK_ALT2_KPP_COL5 = 2,
+   IMX_IOMUXC_SD2_CLK_ALT3_ECSPI4_SCLK = 3,
+   IMX_IOMUXC_SD2_CLK_ALT4_MLB_SIG = 4,
+   IMX_IOMUXC_SD2_CLK_ALT5_GPIO6_IO06 = 5,
+   IMX_IOMUXC_SD2_CLK_ALT6_MQS_RIGHT = 6,
+   IMX_IOMUXC_SD2_CLK_ALT7_WDOG1_ANY = 7,
+} IMX_IOMUXC_SD2_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_CMD_ALT0_SD2_CMD = 0,
+   IMX_IOMUXC_SD2_CMD_ALT1_AUD6_RXC = 1,
+   IMX_IOMUXC_SD2_CMD_ALT2_KPP_ROW5 = 2,
+   IMX_IOMUXC_SD2_CMD_ALT3_ECSPI4_MOSI = 3,
+   IMX_IOMUXC_SD2_CMD_ALT4_MLB_CLK = 4,
+   IMX_IOMUXC_SD2_CMD_ALT5_GPIO6_IO07 = 5,
+   IMX_IOMUXC_SD2_CMD_ALT6_MQS_LEFT = 6,
+   IMX_IOMUXC_SD2_CMD_ALT7_WDOG3_B = 7,
+} IMX_IOMUXC_SD2_CMD_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_DATA0_ALT0_SD2_DATA0 = 0,
+   IMX_IOMUXC_SD2_DATA0_ALT1_AUD6_RXD = 1,
+   IMX_IOMUXC_SD2_DATA0_ALT2_KPP_ROW7 = 2,
+   IMX_IOMUXC_SD2_DATA0_ALT3_PWM1_OUT = 3,
+   IMX_IOMUXC_SD2_DATA0_ALT4_I2C4_SDA = 4,
+   IMX_IOMUXC_SD2_DATA0_ALT5_GPIO6_IO08 = 5,
+   IMX_IOMUXC_SD2_DATA0_ALT6_ECSPI4_SS3 = 6,
+   IMX_IOMUXC_SD2_DATA0_ALT7_UART4_RX_DATA = 7,
+} IMX_IOMUXC_SD2_DATA0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_DATA1_ALT0_SD2_DATA1 = 0,
+   IMX_IOMUXC_SD2_DATA1_ALT1_AUD6_TXC = 1,
+   IMX_IOMUXC_SD2_DATA1_ALT2_KPP_COL7 = 2,
+   IMX_IOMUXC_SD2_DATA1_ALT3_PWM2_OUT = 3,
+   IMX_IOMUXC_SD2_DATA1_ALT4_I2C4_SCL = 4,
+   IMX_IOMUXC_SD2_DATA1_ALT5_GPIO6_IO09 = 5,
+   IMX_IOMUXC_SD2_DATA1_ALT6_ECSPI4_SS2 = 6,
+   IMX_IOMUXC_SD2_DATA1_ALT7_UART4_TX_DATA = 7,
+} IMX_IOMUXC_SD2_DATA1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_DATA2_ALT0_SD2_DATA2 = 0,
+   IMX_IOMUXC_SD2_DATA2_ALT1_AUD6_TXFS = 1,
+   IMX_IOMUXC_SD2_DATA2_ALT2_KPP_ROW6 = 2,
+   IMX_IOMUXC_SD2_DATA2_ALT3_ECSPI4_SS0 = 3,
+   IMX_IOMUXC_SD2_DATA2_ALT4_SDMA_EXT_EVENT0 = 4,
+   IMX_IOMUXC_SD2_DATA2_ALT5_GPIO6_IO10 = 5,
+   IMX_IOMUXC_SD2_DATA2_ALT6_SPDIF_OUT = 6,
+   IMX_IOMUXC_SD2_DATA2_ALT7_UART6_RX_DATA = 7,
+} IMX_IOMUXC_SD2_DATA2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD2_DATA3_ALT0_SD2_DATA3 = 0,
+   IMX_IOMUXC_SD2_DATA3_ALT1_AUD6_TXD = 1,
+   IMX_IOMUXC_SD2_DATA3_ALT2_KPP_COL6 = 2,
+   IMX_IOMUXC_SD2_DATA3_ALT3_ECSPI4_MISO = 3,
+   IMX_IOMUXC_SD2_DATA3_ALT4_MLB_DATA = 4,
+   IMX_IOMUXC_SD2_DATA3_ALT5_GPIO6_IO11 = 5,
+   IMX_IOMUXC_SD2_DATA3_ALT6_SPDIF_IN = 6,
+   IMX_IOMUXC_SD2_DATA3_ALT7_UART6_TX_DATA = 7,
+} IMX_IOMUXC_SD2_DATA3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_CLK_ALT0_SD4_CLK = 0,
+   IMX_IOMUXC_SD4_CLK_ALT1_NAND_DATA15 = 1,
+   IMX_IOMUXC_SD4_CLK_ALT2_ECSPI2_MISO = 2,
+   IMX_IOMUXC_SD4_CLK_ALT3_AUD3_RXFS = 3,
+   IMX_IOMUXC_SD4_CLK_ALT4_LCD2_DATA13 = 4,
+   IMX_IOMUXC_SD4_CLK_ALT5_GPIO6_IO12 = 5,
+   IMX_IOMUXC_SD4_CLK_ALT6_ECSPI3_SS2 = 6,
+} IMX_IOMUXC_SD4_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_CMD_ALT0_SD4_CMD = 0,
+   IMX_IOMUXC_SD4_CMD_ALT1_NAND_DATA14 = 1,
+   IMX_IOMUXC_SD4_CMD_ALT2_ECSPI2_MOSI = 2,
+   IMX_IOMUXC_SD4_CMD_ALT3_AUD3_RXC = 3,
+   IMX_IOMUXC_SD4_CMD_ALT4_LCD2_DATA14 = 4,
+   IMX_IOMUXC_SD4_CMD_ALT5_GPIO6_IO13 = 5,
+   IMX_IOMUXC_SD4_CMD_ALT6_ECSPI3_SS1 = 6,
+} IMX_IOMUXC_SD4_CMD_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DATA0_ALT0_SD4_DATA0 = 0,
+   IMX_IOMUXC_SD4_DATA0_ALT1_NAND_DATA10 = 1,
+   IMX_IOMUXC_SD4_DATA0_ALT2_ECSPI2_SS0 = 2,
+   IMX_IOMUXC_SD4_DATA0_ALT3_AUD3_RXD = 3,
+   IMX_IOMUXC_SD4_DATA0_ALT4_LCD2_DATA12 = 4,
+   IMX_IOMUXC_SD4_DATA0_ALT5_GPIO6_IO14 = 5,
+   IMX_IOMUXC_SD4_DATA0_ALT6_ECSPI3_SS3 = 6,
+} IMX_IOMUXC_SD4_DATA0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DATA1_ALT0_SD4_DATA1 = 0,
+   IMX_IOMUXC_SD4_DATA1_ALT1_NAND_DATA11 = 1,
+   IMX_IOMUXC_SD4_DATA1_ALT2_ECSPI2_SCLK = 2,
+   IMX_IOMUXC_SD4_DATA1_ALT3_AUD3_TXC = 3,
+   IMX_IOMUXC_SD4_DATA1_ALT4_LCD2_DATA11 = 4,
+   IMX_IOMUXC_SD4_DATA1_ALT5_GPIO6_IO15 = 5,
+   IMX_IOMUXC_SD4_DATA1_ALT6_ECSPI3_RDY = 6,
+} IMX_IOMUXC_SD4_DATA1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DATA2_ALT0_SD4_DATA2 = 0,
+   IMX_IOMUXC_SD4_DATA2_ALT1_NAND_DATA12 = 1,
+   IMX_IOMUXC_SD4_DATA2_ALT2_I2C2_SDA = 2,
+   IMX_IOMUXC_SD4_DATA2_ALT3_AUD3_TXFS = 3,
+   IMX_IOMUXC_SD4_DATA2_ALT4_LCD2_DATA10 = 4,
+   IMX_IOMUXC_SD4_DATA2_ALT5_GPIO6_IO16 = 5,
+   IMX_IOMUXC_SD4_DATA2_ALT6_ECSPI2_SS3 = 6,
+} IMX_IOMUXC_SD4_DATA2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DATA3_ALT0_SD4_DATA3 = 0,
+   IMX_IOMUXC_SD4_DATA3_ALT1_NAND_DATA13 = 1,
+   IMX_IOMUXC_SD4_DATA3_ALT2_I2C2_SCL = 2,
+   IMX_IOMUXC_SD4_DATA3_ALT3_AUD3_TXD = 3,
+   IMX_IOMUXC_SD4_DATA3_ALT4_LCD2_DATA09 = 4,
+   IMX_IOMUXC_SD4_DATA3_ALT5_GPIO6_IO17 = 5,
+   IMX_IOMUXC_SD4_DATA3_ALT6_ECSPI2_RDY = 6,
+} IMX_IOMUXC_SD4_DATA3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DATA4_ALT0_SD4_DATA4 = 0,
+   IMX_IOMUXC_SD4_DATA4_ALT1_NAND_DATA09 = 1,
+   IMX_IOMUXC_SD4_DATA4_ALT2_UART5_RX_DATA = 2,
+   IMX_IOMUXC_SD4_DATA4_ALT3_ECSPI3_SCLK = 3,
+   IMX_IOMUXC_SD4_DATA4_ALT4_LCD2_DATA08 = 4,
+   IMX_IOMUXC_SD4_DATA4_ALT5_GPIO6_IO18 = 5,
+   IMX_IOMUXC_SD4_DATA4_ALT6_SPDIF_OUT = 6,
+} IMX_IOMUXC_SD4_DATA4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DATA5_ALT0_SD4_DATA5 = 0,
+   IMX_IOMUXC_SD4_DATA5_ALT1_NAND_CE2_B = 1,
+   IMX_IOMUXC_SD4_DATA5_ALT2_UART5_TX_DATA = 2,
+   IMX_IOMUXC_SD4_DATA5_ALT3_ECSPI3_MOSI = 3,
+   IMX_IOMUXC_SD4_DATA5_ALT4_LCD2_DATA07 = 4,
+   IMX_IOMUXC_SD4_DATA5_ALT5_GPIO6_IO19 = 5,
+   IMX_IOMUXC_SD4_DATA5_ALT6_SPDIF_IN = 6,
+} IMX_IOMUXC_SD4_DATA5_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DATA6_ALT0_SD4_DATA6 = 0,
+   IMX_IOMUXC_SD4_DATA6_ALT1_NAND_CE3_B = 1,
+   IMX_IOMUXC_SD4_DATA6_ALT2_UART5_RTS_B = 2,
+   IMX_IOMUXC_SD4_DATA6_ALT3_ECSPI3_MISO = 3,
+   IMX_IOMUXC_SD4_DATA6_ALT4_LCD2_DATA06 = 4,
+   IMX_IOMUXC_SD4_DATA6_ALT5_GPIO6_IO20 = 5,
+   IMX_IOMUXC_SD4_DATA6_ALT6_SD4_WP = 6,
+} IMX_IOMUXC_SD4_DATA6_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_DATA7_ALT0_SD4_DATA7 = 0,
+   IMX_IOMUXC_SD4_DATA7_ALT1_NAND_DATA08 = 1,
+   IMX_IOMUXC_SD4_DATA7_ALT2_UART5_CTS_B = 2,
+   IMX_IOMUXC_SD4_DATA7_ALT3_ECSPI3_SS0 = 3,
+   IMX_IOMUXC_SD4_DATA7_ALT4_LCD2_DATA15 = 4,
+   IMX_IOMUXC_SD4_DATA7_ALT5_GPIO6_IO21 = 5,
+   IMX_IOMUXC_SD4_DATA7_ALT6_SD4_CD_B = 6,
+} IMX_IOMUXC_SD4_DATA7_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD4_RESET_B_ALT0_SD4_RESET_B = 0,
+   IMX_IOMUXC_SD4_RESET_B_ALT1_NAND_DQS = 1,
+   IMX_IOMUXC_SD4_RESET_B_ALT2_SD4_RESET = 2,
+   IMX_IOMUXC_SD4_RESET_B_ALT3_AUDIO_CLK_OUT = 3,
+   IMX_IOMUXC_SD4_RESET_B_ALT4_LCD2_RESET = 4,
+   IMX_IOMUXC_SD4_RESET_B_ALT5_GPIO6_IO22 = 5,
+   IMX_IOMUXC_SD4_RESET_B_ALT6_LCD2_CS = 6,
+} IMX_IOMUXC_SD4_RESET_B_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_CLK_ALT0_SD3_CLK = 0,
+   IMX_IOMUXC_SD3_CLK_ALT1_UART4_CTS_B = 1,
+   IMX_IOMUXC_SD3_CLK_ALT2_ECSPI4_SCLK = 2,
+   IMX_IOMUXC_SD3_CLK_ALT3_AUD6_RXFS = 3,
+   IMX_IOMUXC_SD3_CLK_ALT4_LCD2_VSYNC = 4,
+   IMX_IOMUXC_SD3_CLK_ALT5_GPIO7_IO00 = 5,
+   IMX_IOMUXC_SD3_CLK_ALT6_LCD2_BUSY = 6,
+} IMX_IOMUXC_SD3_CLK_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_CMD_ALT0_SD3_CMD = 0,
+   IMX_IOMUXC_SD3_CMD_ALT1_UART4_TX_DATA = 1,
+   IMX_IOMUXC_SD3_CMD_ALT2_ECSPI4_MOSI = 2,
+   IMX_IOMUXC_SD3_CMD_ALT3_AUD6_RXC = 3,
+   IMX_IOMUXC_SD3_CMD_ALT4_LCD2_HSYNC = 4,
+   IMX_IOMUXC_SD3_CMD_ALT5_GPIO7_IO01 = 5,
+   IMX_IOMUXC_SD3_CMD_ALT6_LCD2_RS = 6,
+} IMX_IOMUXC_SD3_CMD_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DATA0_ALT0_SD3_DATA0 = 0,
+   IMX_IOMUXC_SD3_DATA0_ALT1_I2C4_SCL = 1,
+   IMX_IOMUXC_SD3_DATA0_ALT2_ECSPI2_SS1 = 2,
+   IMX_IOMUXC_SD3_DATA0_ALT3_AUD6_RXD = 3,
+   IMX_IOMUXC_SD3_DATA0_ALT4_LCD2_DATA01 = 4,
+   IMX_IOMUXC_SD3_DATA0_ALT5_GPIO7_IO02 = 5,
+   IMX_IOMUXC_SD3_DATA0_ALT6_DCIC1_OUT = 6,
+} IMX_IOMUXC_SD3_DATA0_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DATA1_ALT0_SD3_DATA1 = 0,
+   IMX_IOMUXC_SD3_DATA1_ALT1_I2C4_SDA = 1,
+   IMX_IOMUXC_SD3_DATA1_ALT2_ECSPI2_SS2 = 2,
+   IMX_IOMUXC_SD3_DATA1_ALT3_AUD6_TXC = 3,
+   IMX_IOMUXC_SD3_DATA1_ALT4_LCD2_DATA00 = 4,
+   IMX_IOMUXC_SD3_DATA1_ALT5_GPIO7_IO03 = 5,
+   IMX_IOMUXC_SD3_DATA1_ALT6_DCIC2_OUT = 6,
+} IMX_IOMUXC_SD3_DATA1_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DATA2_ALT0_SD3_DATA2 = 0,
+   IMX_IOMUXC_SD3_DATA2_ALT1_UART4_RTS_B = 1,
+   IMX_IOMUXC_SD3_DATA2_ALT2_ECSPI4_SS0 = 2,
+   IMX_IOMUXC_SD3_DATA2_ALT3_AUD6_TXFS = 3,
+   IMX_IOMUXC_SD3_DATA2_ALT4_LCD2_CLK = 4,
+   IMX_IOMUXC_SD3_DATA2_ALT5_GPIO7_IO04 = 5,
+   IMX_IOMUXC_SD3_DATA2_ALT6_LCD2_WR_RWN = 6,
+} IMX_IOMUXC_SD3_DATA2_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DATA3_ALT0_SD3_DATA3 = 0,
+   IMX_IOMUXC_SD3_DATA3_ALT1_UART4_RX_DATA = 1,
+   IMX_IOMUXC_SD3_DATA3_ALT2_ECSPI4_MISO = 2,
+   IMX_IOMUXC_SD3_DATA3_ALT3_AUD6_TXD = 3,
+   IMX_IOMUXC_SD3_DATA3_ALT4_LCD2_ENABLE = 4,
+   IMX_IOMUXC_SD3_DATA3_ALT5_GPIO7_IO05 = 5,
+   IMX_IOMUXC_SD3_DATA3_ALT6_LCD2_RD_E = 6,
+} IMX_IOMUXC_SD3_DATA3_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DATA4_ALT0_SD3_DATA4 = 0,
+   IMX_IOMUXC_SD3_DATA4_ALT1_CAN2_RX = 1,
+   IMX_IOMUXC_SD3_DATA4_ALT3_UART3_RX_DATA = 3,
+   IMX_IOMUXC_SD3_DATA4_ALT4_LCD2_DATA03 = 4,
+   IMX_IOMUXC_SD3_DATA4_ALT5_GPIO7_IO06 = 5,
+   IMX_IOMUXC_SD3_DATA4_ALT6_ENET2_1588_EVENT0_IN = 6,
+} IMX_IOMUXC_SD3_DATA4_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DATA5_ALT0_SD3_DATA5 = 0,
+   IMX_IOMUXC_SD3_DATA5_ALT1_CAN1_TX = 1,
+   IMX_IOMUXC_SD3_DATA5_ALT3_UART3_TX_DATA = 3,
+   IMX_IOMUXC_SD3_DATA5_ALT4_LCD2_DATA02 = 4,
+   IMX_IOMUXC_SD3_DATA5_ALT5_GPIO7_IO07 = 5,
+   IMX_IOMUXC_SD3_DATA5_ALT6_ENET2_1588_EVENT0_OUT = 6,
+} IMX_IOMUXC_SD3_DATA5_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DATA6_ALT0_SD3_DATA6 = 0,
+   IMX_IOMUXC_SD3_DATA6_ALT1_CAN2_TX = 1,
+   IMX_IOMUXC_SD3_DATA6_ALT3_UART3_RTS_B = 3,
+   IMX_IOMUXC_SD3_DATA6_ALT4_LCD2_DATA04 = 4,
+   IMX_IOMUXC_SD3_DATA6_ALT5_GPIO7_IO08 = 5,
+   IMX_IOMUXC_SD3_DATA6_ALT6_ENET1_1588_EVENT0_OUT = 6,
+} IMX_IOMUXC_SD3_DATA6_ALT;
+
+typedef enum {
+   IMX_IOMUXC_SD3_DATA7_ALT0_SD3_DATA7 = 0,
+   IMX_IOMUXC_SD3_DATA7_ALT1_CAN1_RX = 1,
+   IMX_IOMUXC_SD3_DATA7_ALT3_UART3_CTS_B = 3,
+   IMX_IOMUXC_SD3_DATA7_ALT4_LCD2_DATA05 = 4,
+   IMX_IOMUXC_SD3_DATA7_ALT5_GPIO7_IO09 = 5,
+   IMX_IOMUXC_SD3_DATA7_ALT6_ENET1_1588_EVENT0_IN = 6,
+} IMX_IOMUXC_SD3_DATA7_ALT;
+
+typedef enum {
+   IMX_IOMUXC_USB_H_DATA_ALT0_USB_H_DATA = 0,
+   IMX_IOMUXC_USB_H_DATA_ALT1_PWM2_OUT = 1,
+   IMX_IOMUXC_USB_H_DATA_ALT2_XTALOSC_REF_CLK_24M = 2,
+   IMX_IOMUXC_USB_H_DATA_ALT3_I2C4_SDA = 3,
+   IMX_IOMUXC_USB_H_DATA_ALT4_WDOG3_B = 4,
+   IMX_IOMUXC_USB_H_DATA_ALT5_GPIO7_IO10 = 5,
+} IMX_IOMUXC_USB_H_DATA_ALT;
+
+typedef enum {
+   IMX_IOMUXC_USB_H_STROBE_ALT0_USB_H_STROBE = 0,
+   IMX_IOMUXC_USB_H_STROBE_ALT1_PWM1_OUT = 1,
+   IMX_IOMUXC_USB_H_STROBE_ALT2_XTALOSC_REF_CLK_32K = 2,
+   IMX_IOMUXC_USB_H_STROBE_ALT3_I2C4_SCL = 3,
+   IMX_IOMUXC_USB_H_STROBE_ALT4_WDOG3_RST_B_DEB = 4,
+   IMX_IOMUXC_USB_H_STROBE_ALT5_GPIO7_IO11 = 5,
+} IMX_IOMUXC_USB_H_STROBE_ALT;
+
+#endif // _IMX6_IOMUX_SX_H_
diff --git a/Silicon/NXP/iMX6Pkg/Include/iMX6UsbPhy.h b/Silicon/NXP/iMX6Pkg/Include/iMX6UsbPhy.h
new file mode 100644
index 000000000000..d88108227589
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Include/iMX6UsbPhy.h
@@ -0,0 +1,20 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _IMX6_USB_PHY_H_
+#define _IMX6_USB_PHY_H_
+
+EFI_STATUS ImxUsbPhyInit (IMX_USBPHY_ID ImxUsbPhyId);
+
+#endif // _IMX6_USB_PHY_H_
diff --git a/Silicon/NXP/iMX6Pkg/Include/iMX6_DQ.h b/Silicon/NXP/iMX6Pkg/Include/iMX6_DQ.h
new file mode 100644
index 000000000000..f1c5574f968e
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Include/iMX6_DQ.h
@@ -0,0 +1,1686 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __IMX6_DQ_H__
+#define __IMX6_DQ_H__
+
+#pragma pack(push, 1)
+
+// DDR attributes
+#define DDR_ATTRIBUTES_CACHED               ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
+#define DDR_ATTRIBUTES_UNCACHED             ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
+
+// Boot DRAM region (kernel.img & boot working DRAM)
+#define FRAME_BUFFER_BASE                   0x10000000
+#define FRAME_BUFFER_SIZE                   0x00800000 // 8MB
+
+#define BOOT_IMAGE_PHYSICAL_BASE            0x10800000
+#define BOOT_IMAGE_PHYSICAL_LENGTH          0x001D0000 // 1.8MB
+#define BOOT_IMAGE_ATTRIBUTES               CacheAttributes
+
+// The region of registers from 0x00100000 to 0x00D00000
+#define SOC_REGISTERS_PHYSICAL_BASE1        0x00100000
+#define SOC_REGISTERS_PHYSICAL_LENGTH1      0x00C00000
+#define SOC_REGISTERS_ATTRIBUTES            ARM_MEMORY_REGION_ATTRIBUTE_DEVICE
+
+// PCIE registers and configuration space (0x01000000 - 0x02000000)
+#define PCIE_REGISTERS_PHYSICAL_BASE        0x01000000
+#define PCIE_REGISTERS_PHYSICAL_LENGTH      0x01000000
+
+// The region of registers from 0x02000000 to 0x02A00000
+#define SOC_REGISTERS_PHYSICAL_BASE2        0x02000000
+#define SOC_REGISTERS_PHYSICAL_LENGTH2      0x00A00000
+
+// Main system DRAM as defined by the PCD definitions of system memory.
+
+// MPPP definitions
+#define CPU0_MPPP_PHYSICAL_BASE            0x1080F000
+#define CPU1_MPPP_PHYSICAL_BASE            0x10810000
+#define CPU2_MPPP_PHYSICAL_BASE            0x10811000
+#define CPU3_MPPP_PHYSICAL_BASE            0x10812000
+
+// Interrupt controller
+#define CSP_BASE_REG_PA_IC_IFC              0x00A00100
+#define CSP_BASE_REG_PA_IC_DIST             0x00A01000
+
+// L2 cache controller
+#define CSP_BASE_REG_PA_PL310               0x00A02000
+
+// Timers
+#define CSP_BASE_REG_PA_GPT                 0x02098000
+#define CSP_BASE_REG_PA_EPIT1               0x020D0000
+#define CSP_BASE_REG_PA_EPIT2               0x020D4000
+
+// Timers IRQs
+#define IC_DIST_VECTOR_BASE 0
+#define IRQ_EPIT1           88
+#define IRQ_EPIT2           89
+
+// SDMA (Smart DMA) controller
+#define CSP_BASE_REG_PA_SDMA                0x020EC000
+#define IRQ_SDMA 34
+
+// SOC peripherals
+#define CSP_BASE_REG_PA_UART1               0x02020000
+#define CSP_BASE_REG_PA_UART2               0x021e8000
+#define CSP_BASE_REG_PA_UART3               0x021EC000
+#define CSP_BASE_REG_PA_UART4               0x021F0000
+#define CSP_BASE_REG_PA_UART5               0x021F4000
+#define CSP_BASE_REG_PA_ESDHC2              0x02194000
+#define CSP_BASE_REG_PA_ESDHC3              0x02198000
+
+#define DBG_PORT_SUBTYPE_IMX6   0x000C
+
+// Timers clock sources
+#define SOC_OSC_FREQUENCY_REF_HZ  24000000  // Oscillator frequency 24Mhz
+#define SOC_HIGH_FREQUENCY_REF_HZ 66000000  // High Frequency reference clock 66Mhz
+#define SOC_LOW_FREQ_REF_HZ       32768     // SNVS RTC frequency 32kHz
+
+#define IMX_GPU3D_BASE 0x00130000
+#define IMX_GPU3D_LENGTH 0x4000
+
+#define IMX_GPU2D_BASE 0x00134000
+#define IMX_GPU2D_LENGTH 0x4000
+
+//
+// IOMUX Controller (IOMUXC)
+//
+
+#define IMX_IOMUXC_BASE 0x020E0000
+#define IMX_IOMUXC_LENGTH 0x4000
+
+#define IMX_IOMUXC_TZASC1_BYP   0x1
+#define IMX_IOMUXC_TZASC2_BYP   0x2
+
+//
+// Secure Nonvolatile Storage (SNVS)
+//
+
+#define IMX_SNVS_BASE 0x020CC000
+#define IMX_SNVS_LENGTH 0x4000
+#define IMX_SNVS_IP_ID 0x3E
+#define IMX_SNVS_IRQ 51         // SNVS consolidated interrupt
+
+//
+// IOMUXC Registers
+//
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL0      0x020E01F8
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW0      0x020E01FC
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL1      0x020E0200
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW1      0x020E0204
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL2      0x020E0208
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW2      0x020E020C
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL3      0x020E0210
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW3      0x020E0214
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL4      0x020E0218
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW4      0x020E021C
+
+// define base address of Select Input registers to be one word
+// less than the minimum value so that a valid Select Input value
+// is non-zero.
+#define IOMUXC_SELECT_INPUT_BASE_ADDRESS 0x20E07AC
+
+typedef enum {
+   IOMUXC_ASRC_ASRCK_CLOCK_6_SELECT_INPUT = 0x20E07B0,
+   IOMUXC_AUD4_INPUT_DA_AMX_SELECT_INPUT = 0x20E07B4,
+   IOMUXC_AUD4_INPUT_DB_AMX_SELECT_INPUT = 0x20E07B8,
+   IOMUXC_AUD4_INPUT_RXCLK_AMX_SELECT_INPUT = 0x20E07BC,
+   IOMUXC_AUD4_INPUT_RXFS_AMX_SELECT_INPUT = 0x20E07C0,
+   IOMUXC_AUD4_INPUT_TXCLK_AMX_SELECT_INPUT = 0x20E07C4,
+   IOMUXC_AUD4_INPUT_TXFS_AMX_SELECT_INPUT = 0x20E07C8,
+   IOMUXC_AUD5_INPUT_DA_AMX_SELECT_INPUT = 0x20E07CC,
+   IOMUXC_AUD5_INPUT_DB_AMX_SELECT_INPUT = 0x20E07D0,
+   IOMUXC_AUD5_INPUT_RXCLK_AMX_SELECT_INPUT = 0x20E07D4,
+   IOMUXC_AUD5_INPUT_RXFS_AMX_SELECT_INPUT = 0x20E07D8,
+   IOMUXC_AUD5_INPUT_TXCLK_AMX_SELECT_INPUT = 0x20E07DC,
+   IOMUXC_AUD5_INPUT_TXFS_AMX_SELECT_INPUT = 0x20E07E0,
+   IOMUXC_FLEXCAN1_RX_SELECT_INPUT = 0x20E07E4,
+   IOMUXC_FLEXCAN2_RX_SELECT_INPUT = 0x20E07E8,
+   IOMUXC_CCM_PMIC_READY_SELECT_INPUT = 0x20E07F0,
+   IOMUXC_ECSPI1_CSPI_CLK_IN_SELECT_INPUT = 0x20E07F4,
+   IOMUXC_ECSPI1_MISO_SELECT_INPUT = 0x20E07F8,
+   IOMUXC_ECSPI1_MOSI_SELECT_INPUT = 0x20E07FC,
+   IOMUXC_ECSPI1_SS0_SELECT_INPUT = 0x20E0800,
+   IOMUXC_ECSPI1_SS1_SELECT_INPUT = 0x20E0804,
+   IOMUXC_ECSPI1_SS2_SELECT_INPUT = 0x20E0808,
+   IOMUXC_ECSPI1_SS3_SELECT_INPUT = 0x20E080C,
+   IOMUXC_ECSPI2_CSPI_CLK_IN_SELECT_INPUT = 0x20E0810,
+   IOMUXC_ECSPI2_MISO_SELECT_INPUT = 0x20E0814,
+   IOMUXC_ECSPI2_MOSI_SELECT_INPUT = 0x20E0818,
+   IOMUXC_ECSPI2_SS0_SELECT_INPUT = 0x20E081C,
+   IOMUXC_ECSPI2_SS1_SELECT_INPUT = 0x20E0820,
+   IOMUXC_ECSPI4_SS0_SELECT_INPUT = 0x20E0824,
+   IOMUXC_ECSPI5_CSPI_CLK_IN_SELECT_INPUT = 0x20E0828,
+   IOMUXC_ECSPI5_MISO_SELECT_INPUT = 0x20E082C,
+   IOMUXC_ECSPI5_MOSI_SELECT_INPUT = 0x20E0830,
+   IOMUXC_ECSPI5_SS0_SELECT_INPUT = 0x20E0834,
+   IOMUXC_ECSPI5_SS1_SELECT_INPUT = 0x20E0838,
+   IOMUXC_ENET_REF_CLK_SELECT_INPUT = 0x20E083C,
+   IOMUXC_ENET_MAC0_MDIO_SELECT_INPUT = 0x20E0840,
+   IOMUXC_ENET_MAC0_RX_CLK_SELECT_INPUT = 0x20E0844,
+   IOMUXC_ENET_MAC0_RX_DATA0_SELECT_INPUT = 0x20E0848,
+   IOMUXC_ENET_MAC0_RX_DATA1_SELECT_INPUT = 0x20E084C,
+   IOMUXC_ENET_MAC0_RX_DATA2_SELECT_INPUT = 0x20E0850,
+   IOMUXC_ENET_MAC0_RX_DATA3_SELECT_INPUT = 0x20E0854,
+   IOMUXC_ENET_MAC0_RX_EN_SELECT_INPUT = 0x20E0858,
+   IOMUXC_ESAI_RX_FS_SELECT_INPUT = 0x20E085C,
+   IOMUXC_ESAI_TX_FS_SELECT_INPUT = 0x20E0860,
+   IOMUXC_ESAI_RX_HF_CLK_SELECT_INPUT = 0x20E0864,
+   IOMUXC_ESAI_TX_HF_CLK_SELECT_INPUT = 0x20E0868,
+   IOMUXC_ESAI_RX_CLK_SELECT_INPUT = 0x20E086C,
+   IOMUXC_ESAI_TX_CLK_SELECT_INPUT = 0x20E0870,
+   IOMUXC_ESAI_SDO0_SELECT_INPUT = 0x20E0874,
+   IOMUXC_ESAI_SDO1_SELECT_INPUT = 0x20E0878,
+   IOMUXC_ESAI_SDO2_SDI3_SELECT_INPUT = 0x20E087C,
+   IOMUXC_ESAI_SDO3_SDI2_SELECT_INPUT = 0x20E0880,
+   IOMUXC_ESAI_SDO4_SDI1_SELECT_INPUT = 0x20E0884,
+   IOMUXC_ESAI_SDO5_SDI0_SELECT_INPUT = 0x20E0888,
+   IOMUXC_HDMI_ICECIN_SELECT_INPUT = 0x20E088C,
+   IOMUXC_HDMI_II2C_CLKIN_SELECT_INPUT = 0x20E0890,
+   IOMUXC_HDMI_II2C_DATAIN_SELECT_INPUT = 0x20E0894,
+   IOMUXC_I2C1_SCL_IN_SELECT_INPUT = 0x20E0898,
+   IOMUXC_I2C1_SDA_IN_SELECT_INPUT = 0x20E089C,
+   IOMUXC_I2C2_SCL_IN_SELECT_INPUT = 0x20E08A0,
+   IOMUXC_I2C2_SDA_IN_SELECT_INPUT = 0x20E08A4,
+   IOMUXC_I2C3_SCL_IN_SELECT_INPUT = 0x20E08A8,
+   IOMUXC_I2C3_SDA_IN_SELECT_INPUT = 0x20E08AC,
+   IOMUXC_IPU2_SENS1_DATA10_SELECT_INPUT = 0x20E08B0,
+   IOMUXC_IPU2_SENS1_DATA11_SELECT_INPUT = 0x20E08B4,
+   IOMUXC_IPU2_SENS1_DATA12_SELECT_INPUT = 0x20E08B8,
+   IOMUXC_IPU2_SENS1_DATA13_SELECT_INPUT = 0x20E08BC,
+   IOMUXC_IPU2_SENS1_DATA14_SELECT_INPUT = 0x20E08C0,
+   IOMUXC_IPU2_SENS1_DATA15_SELECT_INPUT = 0x20E08C4,
+   IOMUXC_IPU2_SENS1_DATA16_SELECT_INPUT = 0x20E08C8,
+   IOMUXC_IPU2_SENS1_DATA17_SELECT_INPUT = 0x20E08CC,
+   IOMUXC_IPU2_SENS1_DATA18_SELECT_INPUT = 0x20E08D0,
+   IOMUXC_IPU2_SENS1_DATA19_SELECT_INPUT = 0x20E08D4,
+   IOMUXC_IPU2_SENS1_DATA_EN_SELECT_INPUT = 0x20E08D8,
+   IOMUXC_IPU2_SENS1_HSYNC_SELECT_INPUT = 0x20E08DC,
+   IOMUXC_IPU2_SENS1_PIX_CLK_SELECT_INPUT = 0x20E08E0,
+   IOMUXC_IPU2_SENS1_VSYNC_SELECT_INPUT = 0x20E08E4,
+   IOMUXC_KEY_COL5_SELECT_INPUT = 0x20E08E8,
+   IOMUXC_KEY_COL6_SELECT_INPUT = 0x20E08EC,
+   IOMUXC_KEY_COL7_SELECT_INPUT = 0x20E08F0,
+   IOMUXC_KEY_ROW5_SELECT_INPUT = 0x20E08F4,
+   IOMUXC_KEY_ROW6_SELECT_INPUT = 0x20E08F8,
+   IOMUXC_KEY_ROW7_SELECT_INPUT = 0x20E08FC,
+   IOMUXC_MLB_MLB_CLK_IN_SELECT_INPUT = 0x20E0900,
+   IOMUXC_MLB_MLB_DATA_IN_SELECT_INPUT = 0x20E0904,
+   IOMUXC_MLB_MLB_SIG_IN_SELECT_INPUT = 0x20E0908,
+   IOMUXC_SDMA_EVENTS14_SELECT_INPUT = 0x20E090C,
+   IOMUXC_SDMA_EVENTS47_SELECT_INPUT = 0x20E0910,
+   IOMUXC_SPDIF_SPDIF_IN1_SELECT_INPUT = 0x20E0914,
+   IOMUXC_SPDIF_TX_CLK2_SELECT_INPUT = 0x20E0918,
+   IOMUXC_UART1_UART_RTS_B_SELECT_INPUT = 0x20E091C,
+   IOMUXC_UART1_UART_RX_DATA_SELECT_INPUT = 0x20E0920,
+   IOMUXC_UART2_UART_RTS_B_SELECT_INPUT = 0x20E0924,
+   IOMUXC_UART2_UART_RX_DATA_SELECT_INPUT = 0x20E0928,
+   IOMUXC_UART3_UART_RTS_B_SELECT_INPUT = 0x20E092C,
+   IOMUXC_UART3_UART_RX_DATA_SELECT_INPUT = 0x20E0930,
+   IOMUXC_UART4_UART_RTS_B_SELECT_INPUT = 0x20E0934,
+   IOMUXC_UART4_UART_RX_DATA_SELECT_INPUT = 0x20E0938,
+   IOMUXC_UART5_UART_RTS_B_SELECT_INPUT = 0x20E093C,
+   IOMUXC_UART5_UART_RX_DATA_SELECT_INPUT = 0x20E0940,
+   IOMUXC_USB_OTG_OC_SELECT_INPUT = 0x20E0944,
+   IOMUXC_USB_H1_OC_SELECT_INPUT = 0x20E0948,
+   IOMUXC_USDHC1_WP_ON_SELECT_INPUT = 0x20E094C,
+   IOMUXC_SELECT_INPUT_UPPER_BOUND = IOMUXC_USDHC1_WP_ON_SELECT_INPUT,
+} IMX_INPUT_SELECT;
+
+#define IOMUXC_GPR_BASE_ADDRESS             0x020E0000
+
+typedef struct{
+    UINT32 GPR0;                          // 0x00 IOMUXC_GPR0
+    UINT32 GPR1;                          // 0x04 IOMUXC_GPR1
+    UINT32 GPR2;                          // 0x08 IOMUXC_GPR2
+    UINT32 GPR3;                          // 0x0C IOMUXC_GPR3
+    UINT32 GPR4;                          // 0x10 IOMUXC_GPR4
+    UINT32 GPR5;                          // 0x14 IOMUXC_GPR5
+    UINT32 GPR6;                          // 0x18 IOMUXC_GPR6
+    UINT32 GPR7;                          // 0x1C IOMUXC_GPR7
+    UINT32 GPR8;                          // 0x20 IOMUXC_GPR8
+    UINT32 GPR9;                          // 0x24 IOMUXC_GPR9
+    UINT32 GPR10;                         // 0x28 IOMUXC_GPR10
+    UINT32 GPR11;                         // 0x2c IOMUXC_GPR11
+    UINT32 GPR12;                         // 0x30 IOMUXC_GPR12
+    UINT32 GPR13;                         // 0x34 IOMUXC_GPR13
+    UINT32 Reserved;                      // 0x38 Reserved
+    UINT32 GPR14;                         // 0x3C IOMUXC_GPR14; see ERR006687
+} IMX_IOMUXC_GPR_REGISTERS;
+
+typedef enum {
+    IMX_IOMUXC_GPR1_USB_OTG_ID_SEL_ENET_RX_ER,
+    IMX_IOMUXC_GPR1_USB_OTG_ID_SEL_GPIO_1,
+} IMX_IOMUXC_GPR1_USB_OTG_ID_SEL;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 ACT_CS0 : 1;                 // 0
+        UINT32 ADDRS0_10 : 2;               // 1-2
+        UINT32 ACT_CS1 : 1;                 // 3
+        UINT32 ADDRS1_10 : 2;               // 4-5
+        UINT32 ACT_CS2 : 1;                 // 6
+        UINT32 ADDRS2_10 : 2;               // 7-8
+        UINT32 ACT_CS3 : 1;                 // 9
+        UINT32 ADDRS3_10 : 2;               // 10-11 Active Chip Select and Address Space
+        UINT32 GINT : 1;                    // 12 Global interrupt "0" bit (connected to ARM IRQ#0 and GPC)
+        UINT32 USB_OTG_ID_SEL : 1;          // 13 ''usb_otg_id' pin iomux select control.
+        UINT32 SYS_INT : 1;                 // 14 PCIe_CTL
+        UINT32 USB_EXP_MODE : 1;            // 15 USB Exposure mode
+        UINT32 REF_SSP_EN : 1;              // 16 PCIe_PHY - Reference Clock Enable for SS function.
+        UINT32 PU_VPU_MUX : 1;              // 17 IPU-1/IPU-2 to VPU signals control.
+        UINT32 TEST_POWERDOWN : 1;          // 18 PCIe_PHY - All Circuits Power-Down Control Function.
+        UINT32 MIPI_IPU1_MUX : 1;           // 19 MIPI sensor to IPU-1 mux control.
+        UINT32 MIPI_IPU2_MUX : 1;           // 20 MIPI sensor to IPU-2 mux control
+        UINT32 ENET_CLK_SEL : 1;            // 21 ENET TX reference clock
+        UINT32 EXC_MON : 1;                 // 22 Exclusive monitor response select of illegal command
+        UINT32 reserved1 : 1;               // 23
+        UINT32 MIPI_DPI_OFF : 1;            // 24 MIPI DPI shutdown request
+        UINT32 MIPI_COLOR_SW : 1;           // 25 MIPI color switch control
+        UINT32 APP_REQ_ENTR_L1 : 1;         // 26 PCIe_CTL - Application Request to Enter L1
+        UINT32 APP_READY_ENTR_L23 : 1;      // 27 PCIe_CTL - Application Ready to Enter L23
+        UINT32 APP_REQ_EXIT_L1 : 1;         // 28 PCIe_CTL - Application Request to Exit L1
+        UINT32 reserved2 : 1;               // 29
+        UINT32 APP_CLK_REQ_N : 1;           // 30 PCIe_CTL (CLK LOGIC CONTROLLER GLUE) - Indicates that application logic is ready to have reference clock removed.
+        UINT32 CFG_L1_CLK_REMOVAL_EN : 1;   // 31 PCIe_CTL (CLK LOGIC CONTROLLER GLUE) - Enable the reference clock removal in L1 state.
+        // MSB
+    };
+} IMX_IOMUXC_GPR1_REG;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 PCS_TX_DEEMPH_GEN1 : 6;      // 0-5 PCIe_PHY - This static value sets the launch amplitude of the transmitter when pipe0_tx_swing is set to 1'b0 (default state).
+        UINT32 PCS_TX_DEEMPH_GEN2_3P5DB : 6;// 6-11 PCIe_PHY - This static value sets the Tx driver SWING_FULL value.
+        UINT32 PCS_TX_DEEMPH_GEN2_6DB : 6;  // 12-17 PCIe_PHY - This static value sets the Tx driver de-emphasis value in the case where pipe0_tx_deemph is set to 1'b0 and the PHY is running at the Gen2 (6db) rate.
+        UINT32 PCS_TX_SWING_FULL : 7;       // 18-24 PCIe_PHY - This static value sets the Tx driver de-emphasis value in the case where pipe0_tx_deemph is set to 1'b1 (the default setting) and the PHY is running at the Gen2 (3p5db) rate.
+        UINT32 PCS_TX_SWING_LOW : 7;        // 25-31 PCIe_PHY - This static value sets the Tx driver de-emphasis value in the case where pipe0_tx_deemph is set to 1'b1 (the default setting) and the PHY is running at the Gen1 rate.
+        // MSB
+    };
+} IMX_IOMUXC_GPR8_REG;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 reserved0 : 2;               // 0-1
+        UINT32 uSDHC_DBG_MUX : 2;           // 2-3 uSDHC debug bus IO mux control
+        UINT32 LOS_LEVEL : 5;               // 4-8 PCIe_PHY - Loss-of-Signal Detector Sensitivity Level Control Function: Sets the sensitivity level for the Loss - of - Signal detector.This signal must be set to 0x9
+        UINT32 APPS_PM_XMT_PME : 1;         // 9 PCIe_CTL - Wake Up. Used by application logic to wake up the PMC state machine from a D1, D2 or D3 power state.Upon wake - up, the core sends a PM_PME Message
+        UINT32 APP_LTSSM_ENABLE : 1;        // 10 PCIe_CTL Driven low by the application after reset to hold the LTSSM in the Detect state until the application is ready.When the application has finished initializing the core configuration registers, it asserts app_ltssm_enable to allow the LTSSM to continue Link establishment.
+        UINT32 APP_INIT_RST : 1;            // 11 PCIe_PHY - PCIe_CTL - Request from the application to send a Hot Reset to the downstream device.
+        UINT32 DEVICE_TYPE : 4;             // 12-15 PCIe_CTL - Device/Port Type. 0000 PCIE_EP EP Mode 0010 PCIE_RC RC Mode
+        UINT32 APPS_PM_XMT_TURNOFF : 1;     // 16 PCIe_CTL - Request from the application to generate a PM_Turn_Off Message.
+        UINT32 DIA_STATUS_BUS_SELECT : 4;   // 17-20 PCIe_CTL - used for debug to select what part of diag_status_bus will be reflected on the 32 bits of the iomux
+        UINT32 PCIe_CTL_7 : 3;              // 21-23 PCIe control of diagnostic bus select
+        UINT32 ARMP_APB_CLK_EN : 1;         // 24 ARM platform APB clock enable
+        UINT32 ARMP_ATB_CLK_EN : 1;         // 25 ARM platform ATB clock enable
+        UINT32 ARMP_AHB_CLK_EN : 1;         // 26 ARM platform AHB clock enable
+        UINT32 ARMP_IPG_CLK_EN : 1;         // 27 ARM platform IPG clock enable
+        UINT32 reserved1 : 4;               // 28-31
+        // MSB
+    };
+} IMX_IOMUXC_GPR12_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 reserved1 : 1;               // 0
+    UINT32 reserved2 : 1;               // 1
+    UINT32 MC_ENV : 1;                  // 2 Monotonic Counter Enable and Valid
+    UINT32 reserved3 : 1;               // 3
+    UINT32 reserved4 : 1;               // 4
+    UINT32 DP_EN : 1;                   // 5 Dumb PMIC Enabled
+    UINT32 TOP : 1;                     // 6 Turn off System Power
+    UINT32 PWR_GLITCH_EN : 1;           // 7 Power Glitch Detection Enable
+    UINT32 reserved5 : 1;               // 8
+    UINT32 reserved6 : 1;               // 9
+    UINT32 reserved7 : 5;               // 10-14
+    UINT32 reserved8 : 1;               // 15
+    UINT32 BTN_PRESS_TIME : 2;          // 16-17 Button press time out values for PMIC Logic.
+    UINT32 DEBOUNCE : 2;                // 18-19 debounce time for the BTN input signal
+    UINT32 ON_TIME : 2;                 // 20-21 Time after BTN is asserted before pmic_en_b is asserted
+    UINT32 PK_EN : 1;                   // 22 PMIC On Request Enable
+    UINT32 PK_OVERRIDE : 1;             // 23 PMIC On Request Override
+    UINT32 reserved9 : 8;               // 24-31
+    // MSB
+  };
+} IMX_SNVS_LPCR_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 MINOR_REV : 8;               // 0-7 SNVS block minor version number
+    UINT32 MAJOR_REV : 8;               // 8-15 SNVS block major version number
+    UINT32 IP_ID : 16;                  // 16-31 SNVS block ID (IMX_SNVS_IP_ID)
+    // MSB
+  };
+} IMX_SNVS_HPVIDR1_REG;
+
+typedef struct {
+  UINT32 HPLR;                          // 0x000 SNVS_HP Lock Register (SNVS_HPLR)
+  UINT32 HPCOMR;                        // 0x004 SNVS_HP Command Register (SNVS_HPCOMR)
+  UINT32 HPCR;                          // 0x008 SNVS_HP Control Register (SNVS_HPCR)
+  UINT32 reserved1[2];
+  UINT32 HPSR;                          // 0x014 SNVS_HP Status Register (SNVS_HPSR)
+  UINT32 reserved2[3];
+  UINT32 HPRTCMR;                       // 0x024 SNVS_HP Real Time Counter MSB Register (SNVS_HPRTCMR
+  UINT32 HPRTCLR;                       // 0x028 SNVS_HP Real Time Counter LSB Register (SNVS_HPRTCLR)
+  UINT32 HPTAMR;                        // 0x02C SNVS_HP Time Alarm MSB Register (SNVS_HPTAMR)
+  UINT32 HPTALR;                        // 0x030 SNVS_HP Time Alarm LSB Register (SNVS_HPTALR)
+  UINT32 LPLR;                          // 0x034 SNVS_LP Lock Register (SNVS_LPLR)
+  UINT32 LPCR;                          // 0x038 SNVS_LP Control Register (SNVS_LPCR)
+  UINT32 reserved3[4];
+  UINT32 LPSR;                          // 0x04C SNVS_LP Status Register (SNVS_LPSR)
+  UINT32 reserved4[3];
+  UINT32 LPSMCMR;                       // 0x05C SNVS_LP Secure Monotonic Counter MSB Register (SNVS_LPSMCMR)
+  UINT32 LPSMCLR;                       // 0x060 SNVS_LP Secure Monotonic Counter LSB Register (SNVS_LPSMCLR)
+  UINT32 reserved5[1];
+  UINT32 LPGPR;                         // 0x068 SNVS_LP General Purpose Register (SNVS_LPGPR)
+  UINT32 reserved6[739];
+  UINT32 HPVIDR1;                       // 0xBF8 SNVS_HP Version ID Register 1 (SNVS_HPVIDR1)
+  UINT32 HPVIDR2;                       // 0xBFC SNVS_HP Version ID Register 2 (SNVS_HPVIDR2)
+} IMX_SNVS_REGISTERS;
+
+//
+// System Reset Controller (SRC)
+//
+
+#define IMX_SRC_BASE 0x020D8000
+#define IMX_SRC_LENGTH 0x4000
+
+//
+// SCR Register Definition
+//
+
+typedef enum {
+  IMX_SCR_WARM_RST_BYPASS_COUNT_DISABLED,
+  IMX_SCR_WARM_RST_BYPASS_COUNT_16,
+  IMX_SCR_WARM_RST_BYPASS_COUNT_32,
+  IMX_SCR_WARM_RST_BYPASS_COUNT_64,
+} IMX_SCR_WARM_RST_BYPASS_COUNT;
+
+typedef enum {
+  IMX_SRC_MASK_WDOG_RST_B_MASKED = 0x5,
+  IMX_SRC_MASK_WDOG_RST_B_NOT_MASKED = 0xA,
+} IMX_SRC_MASK_WDOG_RST;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 warm_reset_enable : 1;       // 0 WARM reset enable bit
+    UINT32 sw_gpu_rst : 1;              // 1 Software reset for GPU
+    UINT32 sw_vpu_rst : 1;              // 2 Software reset for VPU
+    UINT32 sw_ipu1_rst : 1;             // 3 Software reset for IPU1
+    UINT32 sw_open_vg_rst : 1;          // 4 Software reset for open_vg
+    UINT32 warm_rst_bypass_count : 2;   // 5-6 Defines the XTALI cycles to count before bypassing the MMDC acknowledge for WARM reset (IMX_SCR_WARM_RST_BYPASS_COUNT)
+    UINT32 mask_wdog_rst : 4;           // 7-10 Mask wdog_rst_b source (IMX_SRC_MASK_WDOG_RST)
+    UINT32 eim_rst : 1;                 // 11 EIM reset is needed in order to reconfigure the eim chip select.
+    UINT32 sw_ipu2_rst : 1;             // 12 Software reset for ipu2
+    UINT32 core0_rst : 1;               // 13 Software reset for core0 only.
+    UINT32 core1_rst : 1;               // 14 Software reset for core1 only.
+    UINT32 core2_rst : 1;               // 15 Software reset for core2 only
+    UINT32 core3_rst : 1;               // 16 Software reset for core3 only.
+    UINT32 core0_dbg_rst : 1;           // 17 Software reset for core0 debug only.
+    UINT32 core1_dbg_rst : 1;           // 18 Software reset for core1 debug only.
+    UINT32 core2_dbg_rst : 1;           // 19 Software reset for core2 debug only.
+    UINT32 core3_dbg_rst : 1;           // 20 Software reset for core3 debug only.
+    UINT32 cores_dbg_rst : 1;           // 21 Software reset for debug of arm platform only.
+    UINT32 core1_enable : 1;            // 22 core1 enable
+    UINT32 core2_enable : 1;            // 23 core2 enable
+    UINT32 core3_enable : 1;            // 24 core3 enable
+    UINT32 dbg_rst_msk_pg : 1;          // 25 Do not assert debug resets after power gating event of core
+    UINT32 reserved : 6;                // 26-31 reserved
+    // MSB
+  };
+} IMX_SRC_SCR_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 BOOT_CFG1 : 8;   // 0-7
+    UINT32 BOOT_CFG2 : 8;   // 8-15
+    UINT32 BOOT_CFG3 : 8;   // 16-23
+    UINT32 BOOT_CFG4 : 8;   // 24-31
+    // MSB
+  };
+} IMX_SRC_SBMR1_REG;
+
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 SEC_COFNIG : 2;    // 0-1
+    UINT32 reserved1 : 1;     // 2
+    UINT32 DIR_BT_DIS : 1;    // 3
+    UINT32 BT_FUSE_SEL : 1;   // 4
+    UINT32 reserved2 : 19;    // 5-23
+    UINT32 BMOD : 2;          // 24-25
+    UINT32 reserved3 : 6;     // 26-31
+    // MSB
+  };
+} IMX_SRC_SBMR2_REG;
+
+typedef struct {
+  UINT32 SCR;                           // 0x00 SRC Control Register (SRC_SCR)
+  UINT32 SBMR1;                         // 0x04 SRC Boot Mode Register 1 (SRC_SBMR1)
+  UINT32 SRSR;                          // 0x08 SRC Reset Status Register (SRC_SRSR)
+  UINT32 reserved1[2];
+  UINT32 SISR;                          // 0x14 SRC Interrupt Status Register (SRC_SISR)
+  UINT32 SIMR;                          // 0x18 SRC Interrupt Mask Register (SRC_SIMR)
+  UINT32 SBMR2;                         // 0x1C SRC Boot Mode Register 2 (SRC_SBMR2)
+  UINT32 GPR1;                          // 0x20 SRC General Purpose Register 1 (SRC_GPR1)
+  UINT32 GPR2;                          // 0x24 SRC General Purpose Register 2 (SRC_GPR2)
+  UINT32 GPR3;                          // 0x28 SRC General Purpose Register 3 (SRC_GPR3)
+  UINT32 GPR4;                          // 0x2C SRC General Purpose Register 4 (SRC_GPR4)
+  UINT32 GPR5;                          // 0x30 SRC General Purpose Register 4 (SRC_GPR5)
+  UINT32 GPR6;                          // 0x34 SRC General Purpose Register 4 (SRC_GPR6)
+  UINT32 GPR7;                          // 0x38 SRC General Purpose Register 4 (SRC_GPR7)
+  UINT32 GPR8;                          // 0x3C SRC General Purpose Register 4 (SRC_GPR8)
+  UINT32 GPR9;                          // 0x40 SRC General Purpose Register 4 (SRC_GPR9)
+  UINT32 GPR10;                         // 0x44 SRC General Purpose Register 4 (SRC_GPR10)
+} IMX_SRC_REGISTERS;
+
+
+//
+// Watchdog (WDOG)
+//
+
+#define IMX_WDOG1_BASE 0x020BC000
+#define IMX_WDOG2_BASE 0x020C0000
+#define IMX_WDOG_LENGTH 0x4000
+
+#define IMX_WDOG_WSR_FEED1 0x5555
+#define IMX_WDOG_WSR_FEED2 0xAAAA
+
+typedef union {
+  UINT16 AsUint16;
+  struct {
+    // LSB
+    UINT16 WDZST : 1;                   // 0 Watchdog Low Power
+    UINT16 WDBG : 1;                    // 1 Watchdog DEBUG Enable
+    UINT16 WDE : 1;                     // 2 Watchdog Enable
+    UINT16 WDT : 1;                     // 3 WDOG_B Time-out assertion.
+    UINT16 SRS : 1;                     // 4 Software Reset Signal
+    UINT16 WDA : 1;                     // 5 WDOG_B assertion
+    UINT16 reserved1 : 1;               // 6
+    UINT16 WDW : 1;                     // 7 Watchdog Disable for Wait
+    UINT16 WT : 8;                      // 8-15 Watchdog Time-out Field
+    // MSB
+  };
+} IMX_WDOG_WCR_REG;
+
+typedef struct {
+  UINT16 WCR;                           // 0x0 Watchdog Control Register (WDOG1_WCR)
+  UINT16 WSR;                           // 0x2 Watchdog Service Register (WDOG1_WSR)
+  UINT16 WRSR;                          // 0x4 Watchdog Reset Status Register (WDOG1_WRSR)
+  UINT16 WICR;                          // 0x6 Watchdog Interrupt Control Register (WDOG1_WICR)
+  UINT16 WMCR;                          // 0x8 Watchdog Miscellaneous Control Register (WDOG1_WMCR)
+} IMX_WDOG_REGISTERS;
+
+//
+// Clock Control Module (CCM)
+//
+
+#define IMX_CCM_BASE 0x020C4000
+#define IMX_CCM_LENGTH 0x4000
+#define IMX_CCM_ANALOG_BASE  0x020C8000
+#define IMX_CCM_ANALOG_LENGTH 0x1000
+
+#define IMX_GPU2D_CORE_CLK_MAX 532000000 // 532Mhz
+#define IMX_GPU3D_CORE_CLK_MAX 540000000 // 540Mhz
+#define IMX_GPU3D_SHADER_CLK_MAX 660000000 // 660Mhz
+
+#define IMX_REF_CLK_24M_FREQ 24000000
+
+typedef enum {
+  IMX_CCM_PLL3_SW_CLK_SEL_PLL3_MAIN_CLK,
+  IMX_CCM_PLL3_SW_CLK_SEL_PLL3_BYPASS_CLK,
+} IMX_CCM_PLL3_SW_CLK_SEL;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 pll3_sw_clk_sel : 1;         // 0 Selects source to generate pll3_sw_clk
+    UINT32 reserved1 : 1;               // 1 reserved
+    UINT32 pll1_sw_clk_sel : 1;         // 2 Selects source to generate pll1_sw_clk.
+    UINT32 reserved2 : 5;               // 3-7
+    UINT32 step_sel : 1;                // 8 Selects the option to be chosen for the step frequency
+    UINT32 pfd_396m_dis_mask : 1;       // 9 Mask of 396M PFD auto-disable
+    UINT32 pfd_352m_dis_mask : 1;       // 10 Mask of 352M PFD auto-disable.
+    UINT32 pfd_594_dis_mask : 1;        // 11 Mask of 594M PFD auto-disable.
+    UINT32 pfd_508m_dis_mask : 1;       // 12 Mask of 508M PFD auto-disable
+    UINT32 pfd_454m_dis_mask : 1;       // 13 Mask of 454M PFD auto-disable.
+    UINT32 pfd_720m_dis_mask : 1;       // 14 Mask of 720M PFD auto-disable.
+    UINT32 pfd_540m_dis_mask : 1;       // 15 Mask of 540M PFD auto-disable.
+    UINT32 reserved3 : 16;              // 16-31
+    // MSB
+  };
+} IMX_CCM_CCSR_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 arm_podf : 3;                // 0-3 Divider for ARM clock root
+    UINT32 reserved : 29;               // 3-31
+    // MSB
+  };
+} IMX_CCM_CACRR_REG;
+
+// CBCMR.gpu2d_axi_clk_sel
+typedef enum {
+  IMX_CCM_GPU2D_AXI_CLK_SEL_AXI,
+  IMX_CCM_GPU2D_AXI_CLK_SEL_AHB,
+} IMX_CCM_GPU2D_AXI_CLK_SEL;
+
+// CBCMR.gpu3d_axi_clk_sel
+typedef enum {
+  IMX_CCM_GPU3D_AXI_CLK_SEL_AXI,
+  IMX_CCM_GPU3D_AXI_CLK_SEL_AHB,
+} IMX_CCM_GPU3D_AXI_CLK_SEL;
+
+// CBCMR.gpu2d_core_clk_sel
+typedef enum {
+  IMX_CCM_GPU2D_CORE_CLK_SEL_AXI,
+  IMX_CCM_GPU2D_CORE_CLK_SEL_PLL3_SW,
+  IMX_CCM_GPU2D_CORE_CLK_SEL_PLL2_PFD0,
+  IMX_CCM_GPU2D_CORE_CLK_SEL_PLL2_PFD2,
+} IMX_CCM_GPU2D_CORE_CLK_SEL;
+
+// CBCMR.pre_periph_clk_sel
+typedef enum {
+  IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2,
+  IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2_PFD2,
+  IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2_PFD0,
+  IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2_PFD2_DIV2,
+} IMX_CCM_PRE_PERIPH_CLK_SEL;
+
+// CBCMR.gpu3d_core_clk_sel
+typedef enum {
+  IMX_CCM_GPU3D_CORE_CLK_SEL_MMDC_CH0_AXI,
+  IMX_CCM_GPU3D_CORE_CLK_SEL_PLL3_SW,
+  IMX_CCM_GPU3D_CORE_CLK_SEL_PLL2_PFD1,
+  IMX_CCM_GPU3D_CORE_CLK_SEL_PLL2_PFD2,
+} IMX_CCM_GPU3D_CORE_CLK_SEL;
+
+// CBCMR.gpu3d_shader_clk_sel
+typedef enum {
+  IMX_CCM_GPU3D_SHADER_CLK_SEL_MMDC_CH0_AXI,
+  IMX_CCM_GPU3D_SHADER_CLK_SEL_PLL3_SW,
+  IMX_CCM_GPU3D_SHADER_CLK_SEL_PLL2_PFD1,
+  IMX_CCM_GPU3D_SHADER_CLK_SEL_PLL3_PFD0,
+} IMX_CCM_GPU3D_SHADER_CLK_SEL;
+
+// CBCMR.periph_clk2_sel
+typedef enum {
+  IMX_CCM_PERIPH_CLK2_SEL_PLL3_SW_CLK,
+  IMX_CCM_PERIPH_CLK2_SEL_OSC_CLK,
+  IMX_CCM_PERIPH_CLK2_SEL_PLL2,
+} IMX_CCM_PERIPH_CLK2_SEL;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 gpu2d_axi_clk_sel : 1;       // 0 Selector for gpu2d_axi clock multiplexer (IMX_CCM_GPU2D_AXI_CLK_SEL)
+    UINT32 gpu3d_axi_clk_sel : 1;       // 1 Selector for gpu3d_axi clock multiplexer (IMX_CCM_GPU3D_AXI_CLK_SEL)
+    UINT32 reserved1 : 2;               // 2-3
+    UINT32 gpu3d_core_clk_sel : 2;      // 4-5 Selector for gpu3d_core clock multiplexer (IMX_CCM_GPU3D_CORE_CLK_SEL)
+    UINT32 reserved2 : 2;               // 6-7
+    UINT32 gpu3d_shader_clk_sel : 2;    // 8-9 Selector for gpu3d_shader clock multiplexer (IMX_CCM_GPU3D_SHADER_CLK_SEL)
+    UINT32 pcie_axi_clk_sel : 1;        // 10 Selector for pcie_axi clock multiplexer
+    UINT32 vdoaxi_clk_sel : 1;          // 11 Selector for vdoaxi clock multiplexer
+    UINT32 periph_clk2_sel : 2;         // 12-13 Selector for peripheral clk2 clock multiplexer
+    UINT32 vpu_axi_clk_sel : 2;         // 14-15 Selector for VPU axi clock multiplexer
+    UINT32 gpu2d_core_clk_sel : 2;      // 16-17 Selector for open vg (GPU2D Core) clock multiplexer (IMX_CCM_GPU2D_CORE_CLK_SEL)
+    UINT32 pre_periph_clk_sel : 2;      // 18-19 Selector for pre_periph clock multiplexer
+    UINT32 periph2_clk2_sel : 1;        // 20 Selector for periph2_clk2 clock multiplexer
+    UINT32 pre_periph2_clk_sel : 2;     // 21-22 Selector for pre_periph2 clock multiplexer
+    UINT32 gpu2d_core_clk_podf : 3;     // 23-25 Divider for gpu2d_core clock.
+    UINT32 gpu3d_core_podf : 3;         // 26-28 Divider for gpu3d_core clock
+    UINT32 gpu3d_shader_podf : 3;       // 29-31 Divider for gpu3d_shader clock.
+    // MSB
+  };
+} IMX_CCM_CBCMR_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 ssi1_clk_podf : 6;           // 0-5 Divider for ssi1 clock podf
+    UINT32 ssi1_clk_pred : 3;           // 6-8 Divider for ssi1 clock pred
+    UINT32 esai_clk_pred : 3;           // 9-11 Divider for esai clock pred
+    UINT32 reserved1 : 4;               // 12-15 Reserved
+    UINT32 ssi3_clk_podf : 6;           // 16-21 Divider for ssi3 clock podf
+    UINT32 ssi3_clk_pred : 3;           // 22-24 Divider for ssi3 clock pred
+    UINT32 esai_clk_podf : 3;           // 25-27 Divider for esai clock podf
+    UINT32 reserved2 : 4;               // 28-31 Reserved
+    // MSB
+  };
+} IMX_CCM_CS1CDR_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 ssi2_clk_podf : 6;           // 0-5 Divider for ssi2 clock podf
+    UINT32 ssi2_clk_pred : 3;           // 6-8 Divider for ssi2 clock pred
+    UINT32 ldb_di0_clk_sel : 3;         // 9-11 Selector for ldb_di0 clock multiplexer
+    UINT32 ldb_di1_clk_sel : 3;         // 12-14 Selector for ldb_di1 clock multiplexer
+    UINT32 reserved1 : 1;               // 15 Reserved
+    UINT32 enfc_clk_sel : 2;            // 16-17 Selector for enfc clock multiplexer
+    UINT32 enfc_clk_pred : 3;           // 18-20 Divider for enfc clock pred divider
+    UINT32 esai_clk_podf : 6;           // 21-26 Divider for enfc clock divider
+    UINT32 reserved2 : 5;               // 27-31 Reserved
+    // MSB
+  };
+} IMX_CCM_CS2CDR_REG;
+
+typedef enum {
+  IMX_CCM_CCGR_OFF = 0x0,               // Clock is off during all modes. Stop enter hardware handshake is disabled.
+  IMX_CCM_CCGR_ON_RUN = 0x1,            // Clock is on in run mode, but off in WAIT and STOP modes
+  IMX_CCM_CCGR_ON = 0x3,                // Clock is on during all modes, except STOP mode.
+} IMX_CCM_CCGR;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 aips_tz1_clk_enable : 2;     // 0-1 aips_tz1 clocks (aips_tz1_clk_enable)
+    UINT32 aips_tz2_clk_enable : 2;     // 2-3 aips_tz2 clocks (aips_tz2_clk_enable)
+    UINT32 apbhdma_hclk_enable : 2;     // 4-5 apbhdma hclk clock (apbhdma_hclk_enable)
+    UINT32 asrc_clk_enable : 2;         // 6-7 asrc clock (asrc_clk_enable)
+    UINT32 caam_secure_mem_clk_enable : 2; // 8-9 caam_secure_mem clock (caam_secure_mem_clk_enable)
+    UINT32 caam_wrapper_aclk_enable : 2; // 10-11 caam_wrapper_aclk clock (caam_wrapper_aclk_enable)
+    UINT32 caam_wrapper_ipg_enable : 2; // 12-13 caam_wrapper_ipg clock (caam_wrapper_ipg_enable)
+    UINT32 can1_clk_enable : 2;         // 14-15 can1 clock (can1_clk_enable)
+    UINT32 can1_serial_clk_enable : 2;  // 16-17 can1_serial clock (can1_serial_clk_enable)
+    UINT32 can2_clk_enable : 2;         // 18-19 can2 clock (can2_clk_enable)
+    UINT32 can2_serial_clk_enable : 2;  // 20-21 can2_serial clock (can2_serial_clk_enable)
+    UINT32 arm_dbg_clk_enable : 2;      // 22-23 CPU debug clocks (arm_dbg_clk_enable)
+    UINT32 dcic1_clk_enable : 2;        // 24-25 dcic 1 clocks (dcic1_clk_enable)
+    UINT32 dcic2_clk_enable : 2;        // 26-27 dcic2 clocks (dcic2_clk_enable)
+    UINT32 dtcp_clk_enable : 2;         // 28-29 dtcp clocks (dtcp_clk_enable)
+    UINT32 reserved : 2;                // 30-31
+    // MSB
+  };
+} IMX_CCM_CCGR0_REG;
+
+// CHSCCDR.ipu1_di0_clk_sel
+typedef enum {
+  IMX_CHSCCDR_IPU1_DI0_CLK_SEL_PREMUX,
+  IMX_CHSCCDR_IPU1_DI0_CLK_SEL_IPP_DI0_CLK,
+  IMX_CHSCCDR_IPU1_DI0_CLK_SEL_IPP_DI1_CLK,
+  IMX_CHSCCDR_IPU1_DI0_CLK_SEL_LDB_DI0_CLK,
+  IMX_CHSCCDR_IPU1_DI0_CLK_SEL_LDB_DI1_CLK,
+} IMX_CHSCCDR_IPU1_DI0_CLK_SEL;
+
+// CHSCCDR.ipu1_di0_podf
+typedef enum {
+  IMX_CHSCCDR_IPU1_DI0_PODF_DIV_1,
+  IMX_CHSCCDR_IPU1_DI0_PODF_DIV_2,
+  IMX_CHSCCDR_IPU1_DI0_PODF_DIV_3,
+  IMX_CHSCCDR_IPU1_DI0_PODF_DIV_4,
+  IMX_CHSCCDR_IPU1_DI0_PODF_DIV_5,
+  IMX_CHSCCDR_IPU1_DI0_PODF_DIV_6,
+  IMX_CHSCCDR_IPU1_DI0_PODF_DIV_7,
+  IMX_CHSCCDR_IPU1_DI0_PODF_DIV_8,
+} IMX_CHSCCDR_IPU1_DI0_PODF;
+
+// CHSCCDR.ipu1_di0_pre_clk_sel
+typedef enum {
+  IMX_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MMDC_CH0,
+  IMX_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL3_SW_CLK,
+  IMX_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL5,
+  IMX_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL2_PFD0,
+  IMX_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL2_PFD2,
+  IMX_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL3_PFD1,
+} IMX_CHSCCDR_IPU1_DI0_PRE_CLK_SEL;
+
+// CHSCCDR.ipu1_di1_clk_sel
+typedef enum {
+  IMX_CHSCCDR_IPU1_DI1_CLK_SEL_PREMUX,
+  IMX_CHSCCDR_IPU1_DI1_CLK_SEL_IPP_DI0_CLK,
+  IMX_CHSCCDR_IPU1_DI1_CLK_SEL_IPP_DI1_CLK,
+  IMX_CHSCCDR_IPU1_DI1_CLK_SEL_LDB_DI0_CLK,
+  IMX_CHSCCDR_IPU1_DI1_CLK_SEL_LDB_DI1_CLK,
+} IMX_CHSCCDR_IPU1_DI1_CLK_SEL;
+
+// CHSCCDR.ipu1_di1_podf
+typedef enum {
+  IMX_CHSCCDR_IPU1_DI1_PODF_DIV_1,
+  IMX_CHSCCDR_IPU1_DI1_PODF_DIV_2,
+  IMX_CHSCCDR_IPU1_DI1_PODF_DIV_3,
+  IMX_CHSCCDR_IPU1_DI1_PODF_DIV_4,
+  IMX_CHSCCDR_IPU1_DI1_PODF_DIV_5,
+  IMX_CHSCCDR_IPU1_DI1_PODF_DIV_6,
+  IMX_CHSCCDR_IPU1_DI1_PODF_DIV_7,
+  IMX_CHSCCDR_IPU1_DI1_PODF_DIV_8,
+} IMX_CHSCCDR_IPU1_DI1_PODF;
+
+// CHSCCDR.ipu1_di1_pre_clk_sel
+typedef enum {
+  IMX_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_MMDC_CH0,
+  IMX_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL3_SW_CLK,
+  IMX_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL5,
+  IMX_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL2_PFD0,
+  IMX_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL2_PFD2,
+  IMX_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL3_PFD1,
+} IMX_CHSCCDR_IPU1_DI1_PRE_CLK_SEL;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 ipu1_di0_clk_sel : 3;        // 0-2 Selector for ipu1 di0 root clock multiplexer
+        UINT32 ipu1_di0_podf : 3;           // 3-5 Divider for ipu1_di0 clock divider
+        UINT32 ipu1_di0_pre_clk_sel : 3;    // 6-8 Selector for ipu1 di0 root clock pre-multiplexer
+        UINT32 ipu1_di1_clk_sel : 3;        // 9-11 Selector for ipu1 di1 root clock multiplexer
+        UINT32 ipu1_di1_podf : 3;           // 12-14 Divider for ipu1_di clock divider
+        UINT32 ipu1_di1_pre_clk_sel : 3;    // 15-17 Selector for ipu1 di1 root clock pre-multiplexer
+        UINT32 reserved : 14;               // 18-31
+        // MSB
+    };
+} IMX_CCM_CHSCCDR_REG;
+
+//
+// NOTE: OPENVG clock cannot be gated without gating GPU2D clock as well.
+//       Configure both CG bits (CCM_ANALOG_CCGR1[CG12] and
+//       CCM_ANALOG_CCGR3[CG15]) to gate OPENVG.
+//
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 ecspi1_clk_enable : 2;       // 0-1 ecspi1 clocks (ecspi1_clk_enable)
+    UINT32 ecspi2_clk_enable : 2;       // 2-3 ecspi2 clocks (ecspi2_clk_enable)
+    UINT32 ecspi3_clk_enable : 2;       // 4-5 ecspi3 clocks (ecspi3_clk_enable)
+    UINT32 ecspi4_clk_enable : 2;       // 6-7 ecspi4 clocks (ecspi4_clk_enable)
+    UINT32 ecspi5_clk_enable : 2;       // 8-9 ecspi5 clocks (ecspi5_clk_enable)
+    UINT32 enet_clk_enable : 2;         // 10-11 enet clock (enet_clk_enable)
+    UINT32 epit1_clk_enable : 2;        // 12-13 epit1 clocks (epit1_clk_enable)
+    UINT32 epit2_clk_enable : 2;        // 14-15 epit2 clocks (epit2_clk_enable)
+    UINT32 esai_clk_enable : 2;         // 16-17 esai clocks (esai_clk_enable)
+    UINT32 reserved1 : 2;               // 18-19
+    UINT32 gpt_clk_enable : 2;          // 20-21 gpt bus clock (gpt_clk_enable)
+    UINT32 gpt_serial_clk_enable : 2;   // 22-23 gpt serial clock (gpt_serial_clk_enable)
+    UINT32 gpu2d_clk_enable : 2;        // 24-25 gpu2d clock (gpu2d_clk_enable)
+    UINT32 gpu3d_clk_enable : 2;        // 26-27 gpu3d clock (gpu3d_clk_enable)
+    UINT32 reserved2 : 4;               // 28-31
+    // MSB
+  };
+} IMX_CCM_CCGR1_REG;
+
+// CBCDR.axi_sel
+typedef enum {
+  IMX_CCM_AXI_SEL_PERIPH_CLK,
+  IMX_CCM_AXI_SEL_AXI_ALT,
+} IMX_CCM_AXI_SEL;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 periph2_clk2_podf : 3;       // 0-2 Divider for periph2_clk2 podf
+    UINT32 mmdc_ch1_axi_podf : 3;       // 3-5 Divider for mmdc_ch1_axi podf
+    UINT32 axi_sel : 1;                 // 6 AXI clock source select (IMX_CCM_AXI_SEL)
+    UINT32 axi_alt_sel : 1;             // 7 AXI alternative clock select
+    UINT32 ipg_podf : 2;                // 8-9 Divider for ipg podf.
+    UINT32 ahb_podf : 3;                // 10-12 Divider for AHB PODF.
+    UINT32 reserved1 : 3;               // 13-15
+    UINT32 axi_podf : 3;                // 16-18 Divider for axi podf
+    UINT32 mmdc_ch0_axi_podf : 3;       // 19-21 Divider for mmdc_ch0_axi podf.
+    UINT32 reserved2 : 3;               // 22-24
+    UINT32 periph_clk_sel : 1;          // 25 Selector for peripheral main clock (source of MMDC_CH0_CLK_ROOT).
+    UINT32 periph2_clk_sel : 1;         // 16 Selector for peripheral2 main clock (source of mmdc_ch1_clk_root
+    UINT32 periph_clk2_podf : 3;        // 27-29 Divider for periph2 clock podf.
+    UINT32 reserved3 : 2;               // 30-31
+    // MSB
+  };
+} IMX_CCM_CBCDR_REG;
+
+// CCOSR.CLKO1_SEL
+typedef enum {
+  IMX_CCM_CLKO1_SEL_PLL3_SW_CLK_2,
+  IMX_CCM_CLKO1_SEL_PLL2_MAIN_CLK_2,
+  IMX_CCM_CLKO1_SEL_PLL1_MAIN_CLK_2,
+  IMX_CCM_CLKO1_SEL_PLL5_MAIN_CLK_2,
+  IMX_CCM_CLKO1_SEL_VIDEO_27M_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_AXI_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_ENFC_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_IPU1_DI0_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_IPU1_DI1_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_IPU2_DI0_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_IPU2_DI1_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_AHB_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_IPG_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_PERCLK_ROOT,
+  IMX_CCM_CLKO1_SEL_CKIL_SYNC_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_PLL4_MAIN_CLK,
+} IMX_CCM_CLKO1_SEL;
+
+// CCOSR.CLK_OUT_SEL
+typedef enum {
+  IMX_CCM_CLK_OUT_SEL_CCM_CLKO1,
+  IMX_CCM_CLK_OUT_SEL_CCM_CLKO2,
+} IMX_CCM_CLK_OUT_SEL;
+
+// CCOSR.CLKO2_SEL
+typedef enum {
+  IMX_CCM_CLKO2_SEL_MMDC_CH0_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_MMDC_CH1_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_USDHC4_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_USDHC1_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_GPU2D_AXI_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_WRCK_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_ECSPI_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_GPU3D_AXI_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_USDHC3_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_125M_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_ARM_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_IPU1_HSP_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_IPU2_HSP_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_VDO_AXI_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_OSC_CLK,
+  IMX_CCM_CLKO2_SEL_GPU2D_CORE_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_GPU3D_CORE_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_USDHC2_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_SSI1_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_SSI2_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_SSI3_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_GPU3D_SHADER_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_VPU_AXI_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_CAN_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_LDB_DI0_SERIAL_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_LDB_DI1_SERIAL_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_ESAI_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_ACLK_EIM_SLOW_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_UART_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_SPDIF0_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_SPDIF1_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_HSI_TX_CLK_ROOT,
+} IMX_CCM_CLKO2_SEL;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 CLKO1_SEL : 4;               // 0-3 Selection of the clock to be generated on CCM_CLKO1 (IMX_CCM_CLKO1_SEL)
+    UINT32 CLKO1_DIV : 3;               // 4-6 Setting the divider of CCM_CLKO1
+    UINT32 CLKO1_EN : 1;                // 7 Enable of CCM_CLKO1 clock
+    UINT32 CLK_OUT_SEL : 1;             // 8 CCM_CLKO1 output to reflect CCM_CLKO1 or CCM_CLKO2 clocks
+    UINT32 reserved1 : 7;               // 9-15
+    UINT32 CLKO2_SEL : 5;               // 16-20 Selection of the clock to be generated on CCM_CLKO2 (IMX_CCM_CLKO2_SEL)
+    UINT32 CLKO2_DIV : 3;               // 21-23 Setting the divider of CCM_CLKO2
+    UINT32 CLKO2_EN : 1;                // 24 Enable of CCM_CLKO2 clock
+    UINT32 reserved2 : 7;               // 25-31
+    // MSB
+  };
+} IMX_CCM_CCOSR_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 ipu1_ipu_clk_enable : 2;     // 0-1 ipu1_ipu clock (ipu1_ipu_clk_enable)
+    UINT32 ipu1_ipu_di0_clk_enable : 2; // 2-3 ipu1_di0 clock and pre-clock (ipu1_ipu_di0_clk_enable)
+    UINT32 ipu1_ipu_di1_clk_enable : 2; // 4-5 ipu1_di1 clock and pre-clock (ipu1_ipu_di1_clk_enable)
+    UINT32 ipu2_ipu_clk_enable : 2;     // 6-7 ipu2_ipu clock (ipu2_ipu_clk_enable)
+    UINT32 ipu2_ipu_di0_clk_enable : 2; // 8-9 ipu2_di0 clock and pre-clock (ipu2_ipu_di0_clk_enable)
+    UINT32 ipu2_ipu_di1_clk_enable : 2; // 10-11 ipu2_di1 clock and pre-clock (ipu2_ipu_di1_clk_enable)
+    UINT32 ldb_di0_clk_enable : 2;      // 12-13 ldb_di0 clock (ldb_di0_clk_enable)
+    UINT32 ldb_di1_clk_enable : 2;      // 14-15 ldb_di1 clock (ldb_di1_clk_enable)
+    UINT32 mipi_core_cfg_clk_enable : 2; // 16-17 mipi_core_cfg clock (mipi_core_cfg_clk_enable)
+    UINT32 mlb_clk_enable : 2;          // 18-19 mlb clock (mlb_clk_enable)
+    UINT32 mmdc_core_aclk_fast_core_p0_enable : 2; // 20-21 mmdc_core_aclk_fast_core_p0 clock (mmdc_core_aclk_fast_core_p0_enable)
+    UINT32 reserved1 : 2;               // 22-23
+    UINT32 mmdc_core_ipg_clk_p0_enable : 2; // 24-25 mmdc_core_ipg_clk_p0 clock (mmdc_core_ipg_clk_p0_enable)
+    UINT32 reserved2 : 2;               // 26-27
+    UINT32 ocram_clk_enable : 2;        // 28-29 ocram clock (ocram_clk_enable)
+    UINT32 openvgaxiclk_clk_root_enable : 2; // 30-31 openvgaxiclk clock (openvgaxiclk_clk_root_enable)
+    // MSB
+  };
+} IMX_CCM_CCGR3_REG;
+
+typedef struct {
+  UINT32 CCR;                           // 0x00 CCM Control Register (CCM_CCR)
+  UINT32 CCDR;                          // 0x04 CCM Control Divider Register (CCM_CCDR)
+  UINT32 CSR;                           // 0x08 CCM Status Register (CCM_CSR)
+  UINT32 CCSR;                          // 0x0C CCM Clock Switcher Register (CCM_CCSR)
+  UINT32 CACRR;                         // 0x10 CCM Arm Clock Root Register (CCM_CACRR)
+  UINT32 CBCDR;                         // 0x14 CCM Bus Clock Divider Register (CCM_CBCDR)
+  UINT32 CBCMR;                         // 0x18 CCM Bus Clock Multiplexer Register (CCM_CBCMR)
+  UINT32 CSCMR1;                        // 0x1C CCM Serial Clock Multiplexer Register 1 (CCM_CSCMR1)
+  UINT32 CSCMR2;                        // 0x20 CCM Serial Clock Multiplexer Register 2 (CCM_CSCMR2)
+  UINT32 CSCDR1;                        // 0x24 CCM Serial Clock Divider Register 1 (CCM_CSCDR1)
+  UINT32 CS1CDR;                        // 0x28 CCM SSI1 Clock Divider Register (CCM_CS1CDR)
+  UINT32 CS2CDR;                        // 0x2C CCM SSI2 Clock Divider Register (CCM_CS2CDR)
+  UINT32 CDCDR;                         // 0x30 CCM D1 Clock Divider Register (CCM_CDCDR)
+  UINT32 CHSCCDR;                       // 0x34 CCM HSC Clock Divider Register (CCM_CHSCCDR)
+  UINT32 CSCDR2;                        // 0x38 CCM Serial Clock Divider Register 2 (CCM_CSCDR2)
+  UINT32 CSCDR3;                        // 0x3C CCM Serial Clock Divider Register 3 (CCM_CSCDR3)
+  UINT32 reserved1[2];
+  UINT32 CDHIPR;                        // 0x48 CCM Divider Handshake In-Process Register (CCM_CDHIPR)
+  UINT32 reserved2[2];
+  UINT32 CLPCR;                         // 0x54 CCM Low Power Control Register (CCM_CLPCR)
+  UINT32 CISR;                          // 0x58 CCM Interrupt Status Register (CCM_CISR)
+  UINT32 CIMR;                          // 0x5C CCM Interrupt Mask Register (CCM_CIMR)
+  UINT32 CCOSR;                         // 0x60 CCM Clock Output Source Register (CCM_CCOSR)
+  UINT32 CGPR;                          // 0x64 CCM General Purpose Register (CCM_CGPR)
+  UINT32 CCGR[7];                       // 0x68-7C CCM Clock Gating Register 0-6 (CCM_CCGR0-CCM_CCGR6)
+  UINT32 reserved3[1];
+  UINT32 CMEOR;                         // 0x88 CCM Module Enable Override Register (CCM_CMEOR)
+} IMX_CCM_REGISTERS;
+
+//
+// CCM Analog
+//
+
+typedef enum {
+  IMX_PLL_BYPASS_CLK_SRC_REF_CLK_24M,
+  IMX_PLL_BYPASS_CLK_SRC_CLK1,
+  IMX_PLL_BYPASS_CLK_SRC_CLK2,
+  IMX_PLL_BYPASS_CLK_SRC_XOR,
+} IMX_PLL_BYPASS_CLK_SRC;
+
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 DIV_SELECT : 7;              // 0-6  Valid range for divider value: 54-108. Fout = Fin * div_select/2.0
+    UINT32 reserved1 : 5;               // 7-11
+    UINT32 POWERDOWN : 1;               // 12 Powers down the PLL.
+    UINT32 ENABLE: 1;                   // 13 Enable the clock output.
+    UINT32 BYPASS_CLK_SRC : 2;          // 14-15 Determines the bypass and PLL reference clock source.
+    UINT32 BYPASS : 1;                  // 16 Bypass the PLL.
+    UINT32 LVDS_SEL : 1;                // 17 Analog Debug Bit
+    UINT32 LVDS_24MHZ_SEL : 1;          // 18 Analog Debug Bit
+    UINT32 reserved2 : 1;               // 19 PLL_SEL (Reserved)
+    UINT32 reserved3 : 11;              // 20-30
+    UINT32 LOCK : 1;                    // 31 1 - PLL is currently locked. 0 - PLL is not currently locked.
+    // MSB
+  };
+} IMX_CCM_ANALOG_PLL_ARM_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 DIV_SELECT : 1;              // 0 0 - Fout=Fref*20; 1 - Fout=Fref*22.
+    UINT32 reserved1 : 11;              // 1-11
+    UINT32 POWERDOWN : 1;               // 12 Powers down the PLL.
+    UINT32 ENABLE : 1;                  // 13 Enable PLL output
+    UINT32 BYPASS_CLK_SRC : 2;          // 14-15 Determines the bypass source.
+    UINT32 BYPASS : 1;                  // 16 Bypass the PLL.
+    UINT32 reserved2 : 1;               // 17
+    UINT32 PFD_OFFSET_EN : 1;           // 18 Enables an offset in the phase frequency detector
+    UINT32 reserved3 : 12;              // 19-30
+    UINT32 LOCK : 1;                    // 31 1 - PLL is currently locked; 0 - PLL is not currently locked.
+    // MSB
+  };
+} IMX_CCM_ANALOG_PLL_SYS_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 DIV_SELECT : 2;              // 0-1 - Fout=Fref*20; 1 - Fout=Fref*22.
+    UINT32 reserved1 : 4;               // 2-5
+    UINT32 EN_USB_CLKS : 1;             // 6 Powers the 9-phase PLL outputs for USBPHYn
+    UINT32 reserved2 : 5;               // 7-11
+    UINT32 POWER : 1;                   // 12 Powers up the PLL.
+    UINT32 ENABLE : 1;                  // 13 Enable the PLL clock output
+    UINT32 BYPASS_CLK_SRC : 2;          // 14-15 Determines the bypass source
+    UINT32 BYPASS : 1;                  // 16 Bypass the PLL.
+    UINT32 reserved3 : 14;              // 17-30
+    UINT32 LOCK : 1;                    // 31 1 - PLL is currently locked
+    // MSB
+  };
+} IMX_CCM_ANALOG_PLL_USB1_REG;
+
+typedef enum {
+    IMX_POST_DIV_SELECT_DIVIDE_4,
+    IMX_POST_DIV_SELECT_DIVIDE_2,
+    IMX_POST_DIV_SELECT_DIVIDE_1,
+} IMX_CCM_PLL_VIDEO_CTRL_POST_DIV_SELECT;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 DIV_SELECT : 7;          // 0-6 This field controls the PLL loop divider. Valid range for DIV_SELECT divider value: 27~54
+        UINT32 Reserved1 : 5;           // 7-11
+        UINT32 POWERDOWN : 1;           // 12 Powers down the PLL
+        UINT32 ENABLE : 1;              // 13 Enalbe PLL output
+        UINT32 BYPASS_CLK_SRC : 2;      // 14-15 Determines the bypass source
+        UINT32 BYPASS : 1;              // 16 Bypass the PLL
+        UINT32 Reserved2 : 1;           // 17
+        UINT32 PFD_OFFSET_EN : 1;       // 18 Enables an offset in the phase frequency detector
+        UINT32 POST_DIV_SELECT : 2;     // 19-20 These bits implement a divider after the PLL, but before the enable and bypass mux.
+        UINT32 Reserved3 : 1;           // 21
+        UINT32 Reserved4 : 9;           // 22-30 Always set to zero
+        UINT32 LOCK : 1;                // 31 PLL is/not currently locked
+        // MSB
+    };
+} IMX_CCM_PLL_VIDEO_CTRL_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 PFD0_FRAC : 6;               // 0-5 fractional divide value. The resulting frequency shall be 528*18/PFD0_FRAC where PFD0_FRAC is in the range 12-35.
+    UINT32 PFD0_STABLE : 1;             // 6
+    UINT32 PFD0_CLKGATE : 1;            // 7 Set to 1 to gate ref_pfd0
+    UINT32 PFD1_FRAC : 6;               // 8-13 fractional divide value
+    UINT32 PFD1_STABLE : 1;             // 14
+    UINT32 PFD1_CLKGATE : 1;            // 15 Set to 1 to gate ref_pfd1
+    UINT32 PFD2_FRAC : 6;               // 16-21 fractional divide value
+    UINT32 PFD2_STABLE : 1;             // 22
+    UINT32 PFD2_CLKGATE : 1;            // 23 Set to 1 to gate ref_pfd2
+    UINT32 PFD3_FRAC : 6;               // 24-29 fractional divide value
+    UINT32 PFD3_STABLE : 1;             // 30
+    UINT32 PFD3_CLKGATE : 1;            // 31 Set to 1 to gate ref_pfd3
+    // MSB
+  };
+} IMX_CCM_PFD_480_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 PFD0_FRAC : 6;               // 0-5 fractional divide value. The resulting frequency shall be 528*18/PFD0_FRAC where PFD0_FRAC is in the range 12-35.
+    UINT32 PFD0_STABLE : 1;             // 6
+    UINT32 PFD0_CLKGATE : 1;            // 7 Set to 1 to gate ref_pfd0
+    UINT32 PFD1_FRAC : 6;               // 8-13 fractional divide value
+    UINT32 PFD1_STABLE : 1;             // 14
+    UINT32 PFD1_CLKGATE : 1;            // 15 Set to 1 to gate ref_pfd1
+    UINT32 PFD2_FRAC : 6;               // 16-21 fractional divide value
+    UINT32 PFD2_STABLE : 1;             // 22
+    UINT32 PFD2_CLKGATE : 1;            // 23 Set to 1 to gate ref_pfd2
+    UINT32 reserved : 8;                // 24-31
+    // MSB
+  };
+} IMX_CCM_PFD_528_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 REG0_TARG : 5;               // 0-4 target voltage for the ARM core power domain
+    UINT32 reserved1 : 4;               // 5-8
+    UINT32 REG1_TARG : 5;               // 9-13 target voltage for the VPU/GPU power domain
+    UINT32 reserved2 : 4;               // 14-17
+    UINT32 REG2_TARG : 5;               // 18-22 target voltage for the SOC power domain
+    UINT32 reserved3 : 6;               // 23-28
+    UINT32 FET_ODRIVE : 1;              // 29 increases the gate drive on power gating FET
+    UINT32 reserved4 : 2;               // 30-31
+    // MSB
+  };
+} IMX_PMU_REG_CORE_REG;
+
+typedef enum {
+    PLL_ENET_DIV_SELECT_25MHZ = 0,
+    PLL_ENET_DIV_SELECT_50MHZ = 1,
+    PLL_ENET_DIV_SELECT_100MHZ = 2,
+    PLL_ENET_DIV_SELECT_125MHZ = 3,
+} CCM_ANALOG_PLL_ENET_DIV_SELECT;
+
+//
+// CCM ANALOG PLL Ethernet(n) register
+//
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        unsigned  DIV_SELECT : 2;       // 0-1
+        unsigned  Zero1 : 5;            // 2-6
+        unsigned  Reserved1 : 5;        // 7-11
+        unsigned  POWERDOWN : 1;        // 12
+        unsigned  ENABLE : 1;           // 13
+        unsigned  BYPASS_CLK_SRC : 2;   // 14-15
+        unsigned  BYPASS : 1;           // 16
+        unsigned  Reserved2 : 1;        // 17
+        unsigned  PFD_OFFSET_EN : 1;    // 18
+        unsigned  ENABLE_125M : 1;      // 19
+        unsigned  ENABLE_100M : 1;      // 20
+        unsigned  Zero2 : 10;           // 21-30
+        unsigned  LOCK : 1;             // 31
+        // MSB
+    };
+} IMX_CCM_ANALOG_PLL_ENET_REG;
+
+//
+// CCM ANALOG PLL Ethernet(n) register
+//
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        unsigned  LVDS1_CLK_SEL : 5;    // 0-4
+        unsigned  LVDS2_CLK_SEL : 5;    // 5-9
+        unsigned  LVDSCLK1_OBEN : 1;    // 10
+        unsigned  LVDSCLK2_OBEN : 1;    // 11
+        unsigned  LVDSCLK1_IBEN : 1;    // 12
+        unsigned  LVDSCLK2_IBEN : 1;    // 13
+        unsigned  Reserved0 : 15;       // 14-28
+        unsigned  IRQ_TEMPSENSE : 1;    // 29
+        unsigned  IRQ_ANA_BO : 1;       // 30
+        unsigned  IRQ_DIG_BO : 1;       // 31
+        // MSB
+    };
+} IMX_CCM_ANALOG_MISC1_REG;
+
+typedef struct {
+  UINT32 PLL_ARM;                       // 0x000 Analog ARM PLL control Register (CCM_ANALOG_PLL_ARM)
+  UINT32 PLL_ARM_SET;                   // 0x004 Analog ARM PLL control Register (CCM_ANALOG_PLL_ARM_SET)
+  UINT32 PLL_ARM_CLR;                   // 0x008 Analog ARM PLL control Register (CCM_ANALOG_PLL_ARM_CLR)
+  UINT32 PLL_ARM_TOG;                   // 0x00C Analog ARM PLL control Register (CCM_ANALOG_PLL_ARM_TOG)
+  UINT32 PLL_USB1;                      // 0x010 Analog USB1 480MHz PLL Control Register (CCM_ANALOG_PLL_USB1)
+  UINT32 PLL_USB1_SET;                  // 0x014 Analog USB1 480MHz PLL Control Register (CCM_ANALOG_PLL_USB1_SET)
+  UINT32 PLL_USB1_CLR;                  // 0x018 Analog USB1 480MHz PLL Control Register (CCM_ANALOG_PLL_USB1_CLR)
+  UINT32 PLL_USB1_TOG;                  // 0x01C Analog USB1 480MHz PLL Control Register (CCM_ANALOG_PLL_USB1_TOG)
+  UINT32 PLL_USB2;                      // 0x020 Analog USB2 480MHz PLL Control Register (CCM_ANALOG_PLL_USB2)
+  UINT32 PLL_USB2_SET;                  // 0x024 Analog USB2 480MHz PLL Control Register (CCM_ANALOG_PLL_USB2_SET)
+  UINT32 PLL_USB2_CLR;                  // 0x028 Analog USB2 480MHz PLL Control Register (CCM_ANALOG_PLL_USB2_CLR)
+  UINT32 PLL_USB2_TOG;                  // 0x02C Analog USB2 480MHz PLL Control Register (CCM_ANALOG_PLL_USB2_TOG)
+  UINT32 PLL_SYS;                       // 0x030 Analog System PLL Control Register (CCM_ANALOG_PLL_SYS)
+  UINT32 PLL_SYS_SET;                   // 0x034 Analog System PLL Control Register (CCM_ANALOG_PLL_SYS_SET)
+  UINT32 PLL_SYS_CLR;                   // 0x038 Analog System PLL Control Register (CCM_ANALOG_PLL_SYS_CLR)
+  UINT32 PLL_SYS_TOG;                   // 0x03C Analog System PLL Control Register (CCM_ANALOG_PLL_SYS_CLR)
+  UINT32 PLL_SYS_SS;                    // 0x040 528MHz System PLL Spread Spectrum Register (CCM_ANALOG_PLL_SYS_SS)
+  UINT32 reserved1[3];
+  UINT32 PLL_SYS_NUM;                   // 0x050 Numerator of 528MHz System PLL Fractional Loop Divider Register (CCM_ANALOG_PLL_SYS_NUM)
+  UINT32 reserved2[3];
+  UINT32 PLL_SYS_DENOM;                 // 0x060 Denominator of 528MHz System PLL Fractional Loop Divider Register (CCM_ANALOG_PLL_SYS_DENOM)
+  UINT32 reserved3[3];
+  UINT32 PLL_AUDIO;                     // 0x070 Analog Audio PLL control Register (CCM_ANALOG_PLL_AUDIO)
+  UINT32 PLL_AUDIO_SET;                 // 0x074 Analog Audio PLL control Register (CCM_ANALOG_PLL_AUDIO_SET)
+  UINT32 PLL_AUDIO_CLR;                 // 0x078 Analog Audio PLL control Register (CCM_ANALOG_PLL_AUDIO_CLR)
+  UINT32 PLL_AUDIO_TOG;                 // 0x07C Analog Audio PLL control Register (CCM_ANALOG_PLL_AUDIO_TOG)
+  UINT32 PLL_AUDIO_NUM;                 // 0x080 Numerator of Audio PLL Fractional Loop Divider Register (CCM_ANALOG_PLL_AUDIO_NUM)
+  UINT32 reserved4[3];
+  UINT32 PLL_AUDIO_DENOM;               // 0x090 Denominator of Audio PLL Fractional Loop Divider Register (CCM_ANALOG_PLL_AUDIO_DENOM)
+  UINT32 reserved5[3];
+  UINT32 PLL_VIDEO;                     // 0x0A0 Analog Video PLL control Register (CCM_ANALOG_PLL_VIDEO)
+  UINT32 PLL_VIDEO_SET;                 // 0x0A4 Analog Video PLL control Register (CCM_ANALOG_PLL_VIDEO_SET)
+  UINT32 PLL_VIDEO_CLR;                 // 0x0A8 Analog Video PLL control Register (CCM_ANALOG_PLL_VIDEO_CLR)
+  UINT32 PLL_VIDEO_TOG;                 // 0x0AC Analog Video PLL control Register (CCM_ANALOG_PLL_VIDEO_TOG)
+  UINT32 PLL_VIDEO_NUM;                 // 0x0B0 Numerator of Video PLL Fractional Loop Divider Register (CCM_ANALOG_PLL_VIDEO_NUM)
+  UINT32 reserved6[3];
+  UINT32 PLL_VIDEO_DENOM;               // 0x0C0 Denominator of Video PLL Fractional Loop Divider Register (CCM_ANALOG_PLL_VIDEO_DENOM)
+  UINT32 reserved7[3];
+  UINT32 PLL_MLB;                       // 0x0D0 MLB PLL Control Register (CCM_ANALOG_PLL_MLB)
+  UINT32 PLL_MLB_SET;                   // 0x0D4 MLB PLL Control Register (CCM_ANALOG_PLL_MLB_SET)
+  UINT32 PLL_MLB_CLR;                   // 0x0D8 MLB PLL Control Register (CCM_ANALOG_PLL_MLB_CLR)
+  UINT32 PLL_MLB_TOG;                   // 0x0DC MLB PLL Control Register (CCM_ANALOG_PLL_MLB_TOG)
+  UINT32 PLL_ENET;                      // 0x0E0 Analog ENET PLL Control Register (CCM_ANALOG_PLL_ENET)
+  UINT32 PLL_ENET_SET;                  // 0x0E4 Analog ENET PLL Control Register (CCM_ANALOG_PLL_ENET_SET)
+  UINT32 PLL_ENET_CLR;                  // 0x0E8 Analog ENET PLL Control Register (CCM_ANALOG_PLL_ENET_CLR)
+  UINT32 PLL_ENET_TOG;                  // 0x0EC Analog ENET PLL Control Register (CCM_ANALOG_PLL_ENET_TOG)
+  UINT32 PFD_480;                       // 0x0F0 480MHz Clock (PLL3) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_480)
+  UINT32 PFD_480_SET;                   // 0x0F4 480MHz Clock (PLL3) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_480_SET)
+  UINT32 PFD_480_CLR;                   // 0x0F8 480MHz Clock (PLL3) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_480_CLR)
+  UINT32 PFD_480_TOG;                   // 0x0FC 480MHz Clock (PLL3) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_480_TOG)
+  UINT32 PFD_528;                       // 0x100 528MHz Clock (PLL2) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_528)
+  UINT32 PFD_528_SET;                   // 0x104 528MHz Clock (PLL2) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_528_SET)
+  UINT32 PFD_528_CLR;                   // 0x108 528MHz Clock (PLL2) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_528_CLR)
+  UINT32 PFD_528_TOG;                   // 0x10C 528MHz Clock (PLL2) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_528_TOG)
+  UINT32 PMU_REG_1P1;                   // 0x110 Regulator 1P1 Register (PMU_REG_1P1)
+  UINT32 PMU_REG_1P1_SET;               // 0x114
+  UINT32 PMU_REG_1P1_CLR;               // 0x118
+  UINT32 PMU_REG_1P1_TOG;               // 0x11C
+  UINT32 PMU_REG_3P0;                   // 0X120 Regulator 3P0 Register (PMU_REG_3P0)
+  UINT32 PMU_REG_3P0_SET;               // 0x124
+  UINT32 PMU_REG_3P0_CLR;               // 0x128
+  UINT32 PMU_REG_3P0_TOG;               // 0x12C
+  UINT32 PMU_REG_2P5;                   // 0x130 Regulator 2P5 Register (PMU_REG_2P5)
+  UINT32 PMU_REG_2P5_SET;               // 0x134
+  UINT32 PMU_REG_2P5_CLR;               // 0x138
+  UINT32 PMU_REG_2P5_TOG;               // 0x13C
+  UINT32 PMU_REG_CORE;                  // 0x140 Digital Regulator Core Register (PMU_REG_CORE)
+  UINT32 PMU_REG_CORE_SET;              // 0x144
+  UINT32 PMU_REG_CORE_CLR;              // 0x148
+  UINT32 PMU_REG_CORE_TOG;              // 0x14C
+  UINT32 MISC0;                         // 0x150 Miscellaneous Register 0 (CCM_ANALOG_MISC0)
+  UINT32 MISC0_SET;                     // 0x154 Miscellaneous Register 0 (CCM_ANALOG_MISC0_SET)
+  UINT32 MISC0_CLR;                     // 0x158 Miscellaneous Register 0 (CCM_ANALOG_MISC0_CLR)
+  UINT32 MISC0_TOG;                     // 0x15C Miscellaneous Register 0 (CCM_ANALOG_MISC0_TOG)
+  UINT32 MISC1;                         // 0x160 Miscellaneous Register 1 (CCM_ANALOG_MISC1)
+  UINT32 MISC1_SET;                     // 0x164 Miscellaneous Register 1 (CCM_ANALOG_MISC1_SET)
+  UINT32 MISC1_CLR;                     // 0x168 Miscellaneous Register 1 (CCM_ANALOG_MISC1_CLR)
+  UINT32 MISC1_TOG;                     // 0x16C Miscellaneous Register 1 (CCM_ANALOG_MISC1_TOG)
+  UINT32 MISC2;                         // 0x170 Miscellaneous Register 2 (CCM_ANALOG_MISC2)
+  UINT32 MISC2_SET;                     // 0x174 Miscellaneous Register 2 (CCM_ANALOG_MISC2_SET)
+  UINT32 MISC2_CLR;                     // 0x178 Miscellaneous Register 2 (CCM_ANALOG_MISC2_CLR)
+  UINT32 MISC2_TOG;                     // 0x17C Miscellaneous Register 2 (CCM_ANALOG_MISC2_TOG)
+} IMX_CCM_ANALOG_REGISTERS;
+
+//
+// General Power Controller (GPC)
+//
+
+#define IMX_GPC_BASE 0x020DC000
+#define IMX_GPC_LENGTH 0x1000
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 PCR : 1;                     // 0 Power Control
+    UINT32 reserved : 31;               // 1-31
+    // MSB
+  };
+} IMX_GPC_PGC_PGCR_REG;
+
+#define IMX_GPC_PGC_PUPSCR_SW_DEFAULT 1
+#define IMX_GPC_PGC_PUPSCR_SW2ISO_DEFAULT 0xf
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 SW : 6;                      // 0-5 number of IPG clock cycles before asserting power toggle on/off signal (switch_b)
+    UINT32 reserved1 : 2;               // 6-7
+    UINT32 SW2ISO : 6;                  // 8-13 IPG clock cycles before negating isolation
+    UINT32 reserved2 : 18;              // 14-31
+    // MSB
+  };
+} IMX_GPC_PGC_PUPSCR_REG;
+
+#define IMX_GPC_PGC_PDNSCR_ISO_DEFAULT 1
+#define IMX_GPC_PGC_PDNSCR_ISO2SW_DEFAULT 1
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 ISO : 6;                     // 0-5 number of IPG clocks before isolation
+    UINT32 reserved1 : 2;               // 6-7
+    UINT32 ISO2SW : 6;                  // 8-13 number of IPG clocks before negating power toggle on/off signal (switch_b)
+    UINT32 reserved2 : 18;              // 14-31
+    // MSB
+  };
+} IMX_GPC_PGC_PDNSCR_REG;
+
+typedef struct {
+  UINT32 CTRL;                          // 0x0 PGC Control Register (PGC_GPU/CPU_CTRL)
+  UINT32 PUPSCR;                        // 0x4 Power Up Sequence Control Register (PGC_GPU/CPU_PUPSCR)
+  UINT32 PDNSCR;                        // 0x8 Pull Down Sequence Control Register (PGC_GPU/CPU_PDNSCR)
+  UINT32 SR;                            // 0xC Power Gating Controller Status Register (PGC_GPU/CPU_SR)
+} IMX_GPC_PGC_REGISTERS;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 gpu_vpu_pdn_req : 1;         // 0 GPU/VPU Power Down request. Self-cleared bit.
+    UINT32 gpu_vpu_pup_req : 1;         // 1 GPU/VPU Power Up request. Self-cleared bit.
+    UINT32 reserved1 : 14;              // 2-15
+    UINT32 DVFS0CR : 1;                 // 16 DVFS0 (ARM) Change request (bit is read-only)
+    UINT32 reserved2 : 4;               // 17-20
+    UINT32 GPCIRQM : 1;                 // 21 GPC interrupt/event masking
+    UINT32 reserved3 : 10;              // 22-31
+    // MSB
+  };
+} IMX_GPC_CNTR_REG;
+
+typedef struct {
+  UINT32 CNTR;                          // 0x000 GPC Interface control register (GPC_CNTR)
+  UINT32 PGR;                           // 0x004 GPC Power Gating Register (GPC_PGR)
+  UINT32 IMR1;                          // 0x008 IRQ masking register 1 (GPC_IMR1)
+  UINT32 IMR2;                          // 0x00C IRQ masking register 2 (GPC_IMR2)
+  UINT32 IMR3;                          // 0x010 IRQ masking register 3 (GPC_IMR3)
+  UINT32 IMR4;                          // 0x014 IRQ masking register 4 (GPC_IMR4)
+  UINT32 ISR1;                          // 0x018 IRQ status resister 1 (GPC_ISR1)
+  UINT32 ISR2;                          // 0x01C IRQ status resister 2 (GPC_ISR2)
+  UINT32 ISR3;                          // 0x020 IRQ status resister 3 (GPC_ISR3)
+  UINT32 ISR4;                          // 0x024 IRQ status resister 4 (GPC_ISR4)
+  UINT32 reserved1[142];
+  IMX_GPC_PGC_REGISTERS PGC_GPU;        // 0x260-0x26C GPU PGC Control
+  UINT32 reserved2[12];
+  IMX_GPC_PGC_REGISTERS PGC_CPU;        // 0x2A0-0x2AC CPU PGC Control
+} IMX_GPC_REGISTERS;
+
+//
+// Ethernet controller (ENET)
+//
+
+#define IMX_ENET_BASE 0x02188000
+#define IMX_ENET_LENGTH 0x4000
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 RESET : 1;                   // 0 Ethernet MAC Reset
+    UINT32 ETHEREN : 1;                 // 1 Ethernet Enable
+    UINT32 MAGICEN : 1;                 // 2 Magic Packet Detection Enable
+    UINT32 SLEEP : 1;                   // 3 Sleep Mode Enable
+    UINT32 EN1588 : 1;                  // 4 EN1588 Enable
+    UINT32 SPEED : 1;                   // 5 Selects between 10/100 and 1000 Mbps modes of operation
+    UINT32 DBGEN : 1;                   // 6 Debug Enable
+    UINT32 STOPEN : 1;                  // 7 STOPEN Signal Control
+    UINT32 DBSWP : 1;                   // 8 Descriptor Byte Swapping Enable
+    UINT32 reserved1 : 3;               // 9-11
+    UINT32 reserved2 : 20;              // 12-31 This field must be set to F_0000h
+    // MSB
+  };
+} IMX_ENET_ECR_REG;
+
+typedef struct {
+  UINT32 reserved0;     // 0
+  UINT32 EIR;           // 4
+  UINT32 EIMR;          // 8
+  UINT32 reserved1;     // Ch
+  UINT32 RDAR;          // 10h
+  UINT32 TDAR;          // 14h
+  UINT32 reserved2[3];  // 18h - 20h
+  UINT32 ECR;           // 24h Ethernet Control Register (ENET_ECR)
+  UINT32 reserved3[6];  // 28h - 3Ch
+  UINT32 MMFR;          // 40h
+  UINT32 MSCR;          // 44h
+  UINT32 reserved4[7];  // 48h - 60h
+  UINT32 MIBC;          // 64h
+  UINT32 reserved5[7];  //
+  UINT32 RCR;           // 84h
+  UINT32 reserved6[15]; //
+  UINT32 TCR;           // C4h
+  UINT32 reserved7[7];
+  UINT32 PALR;          // E4h
+  UINT32 PAUR;          // E8h
+  UINT32 OPD;           // ECh
+  UINT32 reserved8[322];
+} IMX_ENET_REGISTERS;
+
+//
+// GPIO Controller (GPIO)
+//
+
+#define IMX_GPIO_BASE 0x0209C000
+#define IMX_GPIO_LENGTH (7 * 0x4000)
+
+//
+// USB CORE (EHCI)
+//
+
+#define IMX_USBCORE_BASE    0x02184000
+#define IMX_USBCORE_LENGTH  0x200
+#define IMX_USBCMD_OFFSET   0x140
+#define IMX_USBMODE_OFFSET  0x1A8
+
+//
+// To do:
+// - Add the USB Core register file
+//
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 RS : 1;          // 0 Run/Stop (RS) . Read/Write. Default 0b. 1=Run. 0=Stop.
+        UINT32 RST : 1;         // 1 Controller Reset (RESET) - Read/Write.
+        UINT32 FS_1 : 2;        // 2-3 Frame List Size (Read/Write or Read Only). Default 000b.
+        UINT32 PSE : 1;         // 4 Periodic Schedule Enable- Read/Write. Default 0b.
+        UINT32 ASE : 1;         // 5 Asynchronous Schedule Enable Read/Write. Default 0b.
+        UINT32 IAA : 1;         // 6 Interrupt on Async Advance Doorbell Read/Write.
+        UINT32 reserved1 : 1;   // 7
+        UINT32 ASP : 2;         // 8-9 Asynchronous Schedule Park Mode Count (OPTIONAL) . Read/Write.
+        UINT32 reserved2 : 1;   // 10 Reserved. These bits are reserved and should be set to zero.
+        UINT32 ASPE : 1;        // 11 Asynchronous Schedule Park Mode Enable (OPTIONAL) . Read/Write.
+        UINT32 ATDTW : 1;       // 12 Add dTD TripWire C Read/Write. [device mode only]
+        UINT32 SUTW : 1;        // 13 Setup TripWire C Read/Write. [device mode only]
+        UINT32 reserved3 : 1;   // 14
+        UINT32 FS2 : 1;         // 15 Frame List Size - (Read/Write or Read Only). [host mode only]
+        UINT32 ITC : 8;         // 16-23 Interrupt Threshold Control Read/Write. Default 08h.
+        UINT32 reserved : 8;    // 24-31 Reserved. These bits are reserved and should be set to zero.
+        // LSB
+    };
+} USB_USBCMD_REG;
+
+typedef enum {
+    IMX_USBMODE_IDLE = 0,
+    IMX_USBMODE_DEVICE = 2,
+    IMX_USBMODE_HOST = 3,
+} IMX_USBMODE_CM;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 CM : 2;          // 0-1 Controller Mode.
+        UINT32 ES : 1;          // 1 Endian Select (0- Little, 1-Big)
+        UINT32 SLOM : 1;        // 3 Setup Lockout Mode
+        UINT32 SDIS : 1;        // 4 Stream Disable Mode
+        UINT32 reserved : 26;   // 5-31
+        // LSB
+    };
+} USB_USBMODE_REG;
+
+//
+// USB Non-CORE
+//
+
+#define IMX_USBNONCORE_BASE 0x02184800
+#define IMX_USBNONCORE_LENGTH 0x20
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 reserved1 : 7;       // 0-6
+        UINT32 OVER_CUR_DIS : 1;    // 7 Disable Overcurrent Detection
+        UINT32 OVER_CUR_POL : 1;    // 8 Polarity of Overcurrent (1-active low, 0-active high)
+        UINT32 PWR_POL : 1;         // 9 Power Polarity (1-active high, 0-active low)
+        UINT32 WIE : 1;             // 10 Wake-up Interrupt Enable
+        UINT32 RESET : 1;           // 11 Force Host 1 UTMI PHY Reset.
+        UINT32 SUSPENDM : 1;        // 12 Force Host 1 UTMI PHY Suspend.
+        UINT32 UTMI_ON_CLOCK : 1;   // 13 Force UTMI PHY clock output on even if in low-power suspend mode.
+        UINT32 WKUP_SW_EN : 1;      // 14 Software Wake-up Enable
+        UINT32 WKUP_SW : 1;         // 15 Software Wake-up
+        UINT32 WKUP_ID_EN : 1;      // 16 Wake-up on ID change enable
+        UINT32 WKUP_VBUS_EN : 1;    // 17 wake-up on VBUS change enable
+        UINT32 reserved2 : 13;      // 18-30
+        UINT32 WIR : 1;             // 31 Wake-up Interrupt Request
+        // LSB
+    };
+} USBNC_USB_UH_CTRL_REG;
+
+typedef struct {
+    UINT32 USBNC_USB_OTG_CTRL;          // 0x00 USB OTG Control Register (USBNC_USB_OTG_CTRL)
+    UINT32 USBNC_USB_UH1_CTRL;          // 0x04 USB Host1 Control Register (USBNC_USB_UH1_CTRL)
+    UINT32 USBNC_USB_UH2_CTRL;          // 0x08 USB Host2 Control Register (USBNC_USB_UH2_CTRL)
+    UINT32 USBNC_USB_UH3_CTRL;          // 0x0C USB Host3 Control Register (USBNC_USB_UH3_CTRL)
+    UINT32 USBNC_USB_UH2_HSIC_CTRL;     // 0x10 USB Host2 HSIC Control Register (USBNC_USB_UH2_HSIC_CTRL)
+    UINT32 USBNC_USB_UH3_HSIC_CTRL;     // 0x14 USB Host3 HSIC Control Register (USBNC_USB_UH3_HSIC_CTRL)
+    UINT32 USBNC_USB_OTG_PHY_CTRL_0;    // 0x18 OTG UTMI PHY Control 0 Register (USBNC_USB_OTG_PHY_CTRL_0)
+    UINT32 USBNC_USB_UH1_PHY_CTRL_0;    // 0x1C Host1 UTMI PHY Control 0 Register (USBNC_USB_UH1_PHY_CTRL_0)
+} IMX_USBNONCORE_REGISTERS;
+
+
+//
+// USB PHY
+//
+
+#define IMX_USBPHY1_BASE 0x020C9000
+#define IMX_USBPHY2_BASE 0x020CA000
+#define IMX_USBPHY_LENGTH 0x1000
+
+typedef enum {
+    IMX_USBPHY0, // OTG
+    IMX_USBPHY1,
+
+    IMX_USBPHY_COUNT
+} IMX_USBPHY_ID;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 ENOTG_ID_CHG_IRQ : 1;        // 0 Enable OTG_ID_CHG_IRQ.
+        UINT32 ENHOSTDISCONDETECT : 1;      // 1 For host mode, enables high-speed disconnect detector.
+        UINT32 ENIRQHOSTDISCON : 1;         // 2 Enables interrupt for detection of disconnection to Device when in high-speed host mode.
+        UINT32 HOSTDISCONDETECT_IRQ : 1;    // 3 Indicates that the device has disconnected in high-speed mode.
+        UINT32 ENDEVPLUGINDETECT : 1;       // 4 For device mode, enables 200-KOhm pullups for detecting connectivity to the host.
+        UINT32 DEVPLUGIN_POLARITY : 1;      // 5 For device mode interrupt generation polarity
+        UINT32 OTG_ID_CHG_IRQ : 1;          // 6 OTG ID change interrupt. Indicates the value of ID pin changed.
+        UINT32 ENOTGIDDETECT : 1;           // 7 Enables circuit to detect resistance of MiniAB ID pin.
+        UINT32 RESUMEIRQSTICKY : 1;         // 8 1 makes RESUME_IRQ bit a sticky bit.
+        UINT32 ENIRQRESUMEDETECT : 1;       // 9 Enables interrupt for detection of a non-J state on the USB line.
+        UINT32 RESUME_IRQ : 1;              // 10 Indicates that the host is sending a wake-up after suspend
+        UINT32 ENIRQDEVPLUGIN : 1;          // 11 Enables interrupt for the detection of connectivity to the USB line.
+        UINT32 DEVPLUGIN_IRQ : 1;           // 12 Indicates that the device is connected
+        UINT32 DATA_ON_LRADC : 1;           // 13 Enables the LRADC to monitor USB_DP and USB_DM.
+        UINT32 ENUTMILEVEL2 : 1;            // 14 Enables UTMI+ Level2.
+        UINT32 ENUTMILEVEL3 : 1;            // 15 Enables UTMI+ Level3.
+        UINT32 ENIRQWAKEUP : 1;             // 16 Enables interrupt for the wakeup events
+        UINT32 WAKEUP_IRQ : 1;              // 17 Indicates that there is a wakeup event.
+        UINT32 ENAUTO_PWRON_PLL : 1;        // 18
+        UINT32 ENAUTOCLR_CLKGATE : 1;       // 19 Enables the feature to auto-clear the CLKGATE bit if there is wakeup event while USB is suspended.
+        UINT32 ENAUTOCLR_PHY_PWD : 1;       // 20 Enables the feature to auto-clear the PWD register bits in USBPHYx_PWD if there is wakeup event while USB is suspended
+        UINT32 ENDPDMCHG_WKUP : 1;          // 21 Enables the feature to wakeup USB if DP/DM is toggled when USB is suspended
+        UINT32 ENIDCHG_WKUP : 1;            // 22 Enables the feature to wakeup USB if ID is toggled when USB is suspended
+        UINT32 ENVBUSCHG_WKUP : 1;          // 23 Enables the feature to wakeup USB if VBUS is toggled when USB is suspended.
+        UINT32 FSDLL_RST_EN : 1;            // 24 Enables the feature to reset the FSDLL lock detection logic at the end of each TX packet.
+        UINT32 ENAUTOCLR_USBCLKGATE : 1;    // 25
+        UINT32 ENAUTOSET_USBCLKS : 1;       // 26
+        UINT32 OTG_ID_VALUE : 1;            // 27
+        UINT32 HOST_FORCE_LS_SE0 : 1;       // 28 Forces the next FS packet that is transmitted to have a EOP with LS timing.
+        UINT32 UTMI_SUSPENDM : 1;           // 29 Used by the PHY to indicate a powered-down state.
+        UINT32 CLKGATE : 1;                 // 30 Gate UTMI Clocks. Clear to 0 to run clocks.
+        UINT32 SFTRST : 1;                  // 31 Soft-reset the USBPHYx_PWD, USBPHYx_TX, USBPHYx_RX, Set to 0 to release the PHY from reset.
+        // MSB
+    };
+} USBPHYx_CTRL_REG;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 STEP : 16;   // 0-15 Fixed read-only value reflecting the stepping of the RTL version.
+        UINT32 MINOR : 8;   // 16-23 Fixed read-only value reflecting the MINOR field of the RTL version.
+        UINT32 MAJOR : 8;   // 24-31 Fixed read-only value reflecting the MAJOR field of the RTL version
+        // MSB
+    };
+} USBPHYx_VERSION_REG;
+
+typedef struct {
+    UINT32 USBPHY_PWD;             // 0x00 USB PHY Power-Down Register (USBPHY_PWD)
+    UINT32 USBPHY_PWD_SET;         // 0x04 USB PHY Power-Down Register (USBPHY_PWD_SET)
+    UINT32 USBPHY_PWD_CLR;         // 0x08 USB PHY Power-Down Register (USBPHY_PWD_CLR)
+    UINT32 USBPHY_PWD_TOG;         // 0x0C USB PHY Power-Down Register (USBPHY_PWD_TOG)
+    UINT32 USBPHY_TX;              // 0x10 USB PHY Transmitter Control Register (USBPHY_TX)
+    UINT32 USBPHY_TX_SET;          // 0x14 USB PHY Transmitter Control Register (USBPHY_TX_SET)
+    UINT32 USBPHY_TX_CLR;          // 0x18 USB PHY Transmitter Control Register (USBPHY_TX_CLR)
+    UINT32 USBPHY_TX_TOG;          // 0x1C USB PHY Transmitter Control Register (USBPHY_TX_TOG)
+    UINT32 USBPHY_RX;              // 0x20 USB PHY Receiver Control Register (USBPHY_RX)
+    UINT32 USBPHY_RX_SET;          // 0x24 USB PHY Receiver Control Register(USBPHY_RX_SET)
+    UINT32 USBPHY_RX_CLR;          // 0x28 USB PHY Receiver Control Register (USBPHY_RX_CLR)
+    UINT32 USBPHY_RX_TOG;          // 0x2C USB PHY Receiver Control Register (USBPHY_RX_TOG)
+    UINT32 USBPHY_CTRL;            // 0x30 USB PHY General Control Register (USBPHY_CTRL)
+    UINT32 USBPHY_CTRL_SET;        // 0x34 USB PHY General Control Register (USBPHY_CTRL_SET)
+    UINT32 USBPHY_CTRL_CLR;        // 0x38 USB PHY General Control Register (USBPHY_CTRL_CLR)
+    UINT32 USBPHY_CTRL_TOG;        // 0x3C USB PHY General Control Register (USBPHY_CTRL_TOG)
+    UINT32 USBPHY_STATUS;          // 0x40 USB PHY Status Register (USBPHY_STATUS)
+    UINT32 reserved1[3];
+    UINT32 USBPHY_DEBUG;           // 0x50 USB PHY Debug Register (USBPHY_DEBUG)
+    UINT32 USBPHY_DEBUG_SET;       // 0x54 USB PHY Debug Register(USBPHY_DEBUG_SET)
+    UINT32 USBPHY_DEBUG_CLR;       // 0x58 USB PHY Debug Register (USBPHY_DEBUG_CLR)
+    UINT32 USBPHY_DEBUG_TOG;       // 0x5C USB PHY Debug Register(USBPHY_DEBUG_TOG)
+    UINT32 USBPHY_DEBUG0_STATUS;   // 0x60 UTMI Debug Status Register 0 (USBPHY_DEBUG0_STATUS)
+    UINT32 reserved2[3];
+    UINT32 USBPHY_DEBUG1;          // 0x70 UTMI Debug Status Register 1 (USBPHY_DEBUG1)
+    UINT32 USBPHY_DEBUG1_SET;      // 0x74 UTMI Debug Status Register 1 (USBPHY_DEBUG1_SET)
+    UINT32 USBPHY_DEBUG1_CLR;      // 0x78 UTMI Debug Status Register 1 (USBPHY_DEBUG1_CLR)
+    UINT32 USBPHY_DEBUG1_TOG;      // 0x7C UTMI Debug Status Register 1 (USBPHY_DEBUG1_TOG)
+    UINT32 USBPHY_VERSION;         // 0x80 UTMI RTL Version (USBPHYx_VERSION)
+    UINT32 reserved3[3];
+    UINT32 USBPHY_IP;              // 0x90
+    UINT32 USBPHY_IP_SET;          // 0x94
+    UINT32 USBPHY_IP_CLR;          // 0x98
+    UINT32 USBPHY_IP_TOG;          // 0x9C
+} IMX_USBPHY_REGISTERS;
+
+#define IMX_USBPHY_IP_FIX   ((1 << 17) | (1 << 18))
+
+//
+// USB Analog
+//
+
+#define IMX_USBANA_BASE 0x020C81A0
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 reserved1 : 18;  // 0-17
+        UINT32 CHK_CONTACT : 1; // 18
+        UINT32 CHK_CHRG_B : 1;  // 19
+        UINT32 EN_B : 1;        // 20
+        UINT32 reserved2 : 11;  // 21-31
+        // MSB
+    };
+} USB_ANALOG_USB_CHRG_DETECT_REG;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 HS_USE_EXTERNAL_R : 1;  // 0 Use external resistor to generate the current bias for the high speed transmitter.
+        UINT32 EN_DEGLITCH : 1;        // 1 Enable the deglitching circuit of the USB PLL output.
+        UINT32 reserved1 : 28;         // 2-29
+        UINT32 EN_CLK_UTMI : 1;        // Enables the clk to the UTMI block.
+        UINT32 reserved2 : 1;          // 31
+        // MSB
+    };
+} USB_ANALOG_USB_MISC_REG;
+
+typedef struct {
+    UINT32 USB_ANALOG_USB_VBUS_DETECT;       // 0x00 USB VBUS Detect Register (USB_ANALOG_USB_VBUS_DETECT)
+    UINT32 USB_ANALOG_USB_VBUS_DETECT_SET;   // 0x04 USB VBUS Detect Register (USB_ANALOG_USB_VBUS_DETECT_SET)
+    UINT32 USB_ANALOG_USB_VBUS_DETECT_CLR;   // 0x08 USB VBUS Detect Register (USB_ANALOG_USB_VBUS_DETECT_CLR)
+    UINT32 USB_ANALOG_USB_VBUS_DETECT_TOG;   // 0x0C USB VBUS Detect Register (USB_ANALOG_USB_VBUS_DETECT_TOG)
+    UINT32 USB_ANALOG_USB_CHRG_DETECT;       // 0x10 USB Charger Detect Register (USB_ANALOG_USB_CHRG_DETECT)
+    UINT32 USB_ANALOG_USB_CHRG_DETECT_SET;   // 0x14 USB Charger Detect Register (USB_ANALOG_USB_CHRG_DETECT_SET)
+    UINT32 USB_ANALOG_USB_CHRG_DETECT_CLR;   // 0x18 USB Charger Detect Register (USB_ANALOG_USB_CHRG_DETECT_CLR)
+    UINT32 USB_ANALOG_USB_CHRG_DETECT_TOG;   // 0x1C USB Charger Detect Register (USB_ANALOG_USB_CHRG_DETECT_TOG)
+    UINT32 USB_ANALOG_USB_VBUS_DETECT_STAT;  // 0x20 USB VBUS Detect Status Register (USB_ANALOG_USB_VBUS_DETECT_STAT)
+    UINT32 reserved1[3];
+    UINT32 USB_ANALOG_USB_CHRG_DETECT_STAT;  // 0x30 USB Charger Detect Status Register (USB_ANALOG_USB_CHRG_DETECT_STAT)
+    UINT32 reserved2[7];
+    UINT32 USB_ANALOG_USB_MISC;              // 0x50 USB Misc Register (USB_ANALOG_USB_MISC)
+    UINT32 USB_ANALOG_USB_MISC_SET;          // 0x54 USB Misc Register (USB_ANALOG_USB_MISC_SET)
+    UINT32 USB_ANALOG_USB_MISC_CLR;          // 0x58 USB Misc Register (USB_ANALOG_USB_MISC_CLR)
+    UINT32 USB_ANALOG_USB_MISC_TOG;          // 0x5C USB Misc Register (USB_ANALOG_USB_MISC_TOG)
+} IMX_USBANA_USB_REGISTERS;
+
+typedef struct {
+    IMX_USBANA_USB_REGISTERS USBANA[IMX_USBPHY_COUNT];
+    UINT32 USB_ANALOG_DIGPROG;                // 0xC0 Chip Silicon Version (USB_ANALOG_DIGPROG)
+} IMX_USBANA_REGISTERS;
+
+#pragma pack(pop)
+
+#endif // __IMX6_DQ_H__
diff --git a/Silicon/NXP/iMX6Pkg/Include/iMX6_SDL.h b/Silicon/NXP/iMX6Pkg/Include/iMX6_SDL.h
new file mode 100644
index 000000000000..a0e4e79208f9
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Include/iMX6_SDL.h
@@ -0,0 +1,1657 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __IMX6_SDL_H__
+#define __IMX6_SDL_H__
+
+#pragma pack(push, 1)
+
+// DDR attributes
+#define DDR_ATTRIBUTES_CACHED               ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
+#define DDR_ATTRIBUTES_UNCACHED             ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
+
+// Boot DRAM region (kernel.img & boot working DRAM)
+#define FRAME_BUFFER_BASE                   0x10000000
+#define FRAME_BUFFER_SIZE                   0x00800000 // 8MB
+
+#define BOOT_IMAGE_PHYSICAL_BASE            0x10800000
+#define BOOT_IMAGE_PHYSICAL_LENGTH          0x001D0000 // 1.8MB
+#define BOOT_IMAGE_ATTRIBUTES               CacheAttributes
+
+// The region of registers from 0x00100000 to 0x00D00000
+#define SOC_REGISTERS_PHYSICAL_BASE1        0x00100000
+#define SOC_REGISTERS_PHYSICAL_LENGTH1      0x00C00000
+#define SOC_REGISTERS_ATTRIBUTES            ARM_MEMORY_REGION_ATTRIBUTE_DEVICE
+
+// PCIE registers and configuration space (0x01000000 - 0x02000000)
+#define PCIE_REGISTERS_PHYSICAL_BASE        0x01000000
+#define PCIE_REGISTERS_PHYSICAL_LENGTH      0x01000000
+
+// The region of registers from 0x02000000 to 0x02A00000
+#define SOC_REGISTERS_PHYSICAL_BASE2        0x02000000
+#define SOC_REGISTERS_PHYSICAL_LENGTH2      0x00A00000
+
+// Main system DRAM as defined by the PCD definitions of system memory.
+
+// MPPP definitions
+#define CPU0_MPPP_PHYSICAL_BASE            0x1080F000
+#define CPU1_MPPP_PHYSICAL_BASE            0x10810000
+#define CPU2_MPPP_PHYSICAL_BASE            0x10811000
+#define CPU3_MPPP_PHYSICAL_BASE            0x10812000
+
+// Interrupt controller
+#define CSP_BASE_REG_PA_IC_IFC              0x00A00100
+#define CSP_BASE_REG_PA_IC_DIST             0x00A01000
+
+// L2 cache controller
+#define CSP_BASE_REG_PA_PL310               0x00A02000
+
+// Timers
+#define CSP_BASE_REG_PA_GPT                 0x02098000
+#define CSP_BASE_REG_PA_EPIT1               0x020D0000
+#define CSP_BASE_REG_PA_EPIT2               0x020D4000
+
+// Timers IRQs
+#define IC_DIST_VECTOR_BASE 0
+#define IRQ_EPIT1           88
+#define IRQ_EPIT2           89
+
+// SDMA (Smart DMA) controller
+#define CSP_BASE_REG_PA_SDMA                0x020EC000
+#define IRQ_SDMA 34
+
+// SOC peripherals
+#define CSP_BASE_REG_PA_UART1 0x02020000
+#define CSP_BASE_REG_PA_UART2 0x021E8000
+#define CSP_BASE_REG_PA_UART3 0x021EC000
+#define CSP_BASE_REG_PA_UART4 0x021F0000
+#define CSP_BASE_REG_PA_UART5 0x021F4000
+
+#define CSP_BASE_REG_PA_ESDHC1 0x02190000
+#define CSP_BASE_REG_PA_ESDHC2 0x02194000
+#define CSP_BASE_REG_PA_ESDHC3 0x02198000
+#define CSP_BASE_REG_PA_ESDHC4 0x0219C000
+
+#define DBG_PORT_SUBTYPE_IMX6   0x000C
+
+// Timers clock sources
+#define SOC_OSC_FREQUENCY_REF_HZ  24000000  // Oscillator frequency 24Mhz
+#define SOC_HIGH_FREQUENCY_REF_HZ 66000000  // High Frequency reference clock 66Mhz
+#define SOC_LOW_FREQ_REF_HZ       32768     // SNVS RTC frequency 32kHz
+
+#define IMX_GPU3D_BASE 0x00130000
+#define IMX_GPU3D_LENGTH 0x4000
+
+#define IMX_GPU2D_BASE 0x00134000
+#define IMX_GPU2D_LENGTH 0x4000
+
+//
+// IOMUX Controller (IOMUXC)
+//
+
+#define IMX_IOMUXC_BASE 0x020E0000
+#define IMX_IOMUXC_LENGTH 0x4000
+
+//
+// Secure Nonvolatile Storage (SNVS)
+//
+
+#define IMX_SNVS_BASE 0x020CC000
+#define IMX_SNVS_LENGTH 0x4000
+#define IMX_SNVS_IP_ID 0x3E
+#define IMX_SNVS_IRQ 51         // SNVS consolidated interrupt
+
+//
+// IOMUXC Registers
+//
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL0      0x020E0244
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW0      0x020E0258
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL1      0x020E0248
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW1      0x020E025C
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL2      0x020E024C
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW2      0x020E0260
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL3      0x020E0250
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW3      0x020E0264
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL4      0x020E0254
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW4      0x020E0268
+
+// define base address of Select Input registers IMX6SDL to be one word
+// less than the minimum value so that a valid Select Input value
+// is non-zero.
+#define IOMUXC_SELECT_INPUT_BASE_ADDRESS 0x20E0790
+
+typedef enum {
+   IOMUXC_ASRC_ASRCK_CLOCK_6_SELECT_INPUT = 0x20E0794,
+   IOMUXC_AUD4_INPUT_DA_AMX_SELECT_INPUT = 0x20E0798,
+   IOMUXC_AUD4_INPUT_DB_AMX_SELECT_INPUT = 0x20E079C,
+   IOMUXC_AUD4_INPUT_RXCLK_AMX_SELECT_INPUT = 0x20E07A0,
+   IOMUXC_AUD4_INPUT_RXFS_AMX_SELECT_INPUT = 0x20E07C0,
+   IOMUXC_AUD4_INPUT_TXCLK_AMX_SELECT_INPUT = 0x20E07A8,
+   IOMUXC_AUD4_INPUT_TXFS_AMX_SELECT_INPUT = 0x20E07AC,
+   IOMUXC_AUD5_INPUT_DA_AMX_SELECT_INPUT = 0x20E07B0,
+   IOMUXC_AUD5_INPUT_DB_AMX_SELECT_INPUT = 0x20E07B4,
+   IOMUXC_AUD5_INPUT_RXCLK_AMX_SELECT_INPUT = 0x20E07B8,
+   IOMUXC_AUD5_INPUT_RXFS_AMX_SELECT_INPUT = 0x20E07BC,
+   IOMUXC_AUD5_INPUT_TXCLK_AMX_SELECT_INPUT = 0x20E07C0,
+   IOMUXC_AUD5_INPUT_TXFS_AMX_SELECT_INPUT = 0x20E07C4,
+   IOMUXC_FLEXCAN1_RX_SELECT_INPUT = 0x20E07C8,
+   IOMUXC_FLEXCAN2_RX_SELECT_INPUT = 0x20E07CC,
+   IOMUXC_CCM_PMIC_READY_SELECT_INPUT = 0x20E07D4,
+   IOMUXC_ECSPI1_CSPI_CLK_IN_SELECT_INPUT = 0x20E07D8,
+   IOMUXC_ECSPI1_MISO_SELECT_INPUT = 0x20E07DC,
+   IOMUXC_ECSPI1_MOSI_SELECT_INPUT = 0x20E07E0,
+   IOMUXC_ECSPI1_SS0_SELECT_INPUT = 0x20E07E4,
+   IOMUXC_ECSPI1_SS1_SELECT_INPUT = 0x20E07E8,
+   IOMUXC_ECSPI1_SS2_SELECT_INPUT = 0x20E07EC,
+   IOMUXC_ECSPI1_SS3_SELECT_INPUT = 0x20E07F0,
+   IOMUXC_ECSPI2_CSPI_CLK_IN_SELECT_INPUT = 0x20E07F4,
+   IOMUXC_ECSPI2_MISO_SELECT_INPUT = 0x20E07F8,
+   IOMUXC_ECSPI2_MOSI_SELECT_INPUT = 0x20E07FC,
+   IOMUXC_ECSPI2_SS0_SELECT_INPUT = 0x20E0800,
+   IOMUXC_ECSPI2_SS1_SELECT_INPUT = 0x20E0804,
+   IOMUXC_ECSPI4_SS0_SELECT_INPUT = 0x20E0808,
+   IOMUXC_ENET_REF_CLK_SELECT_INPUT = 0x20E080C,
+   IOMUXC_ENET_MAC0_MDIO_SELECT_INPUT = 0x20E0810,
+   IOMUXC_ENET_MAC0_RX_CLK_SELECT_INPUT = 0x20E0814,
+   IOMUXC_ENET_MAC0_RX_DATA0_SELECT_INPUT = 0x20E0818,
+   IOMUXC_ENET_MAC0_RX_DATA1_SELECT_INPUT = 0x20E081C,
+   IOMUXC_ENET_MAC0_RX_DATA2_SELECT_INPUT = 0x20E0820,
+   IOMUXC_ENET_MAC0_RX_DATA3_SELECT_INPUT = 0x20E0824,
+   IOMUXC_ENET_MAC0_RX_EN_SELECT_INPUT = 0x20E0828,
+   IOMUXC_ESAI_RX_FS_SELECT_INPUT = 0x20E082C,
+   IOMUXC_ESAI_TX_FS_SELECT_INPUT = 0x20E0830,
+   IOMUXC_ESAI_RX_HF_CLK_SELECT_INPUT = 0x20E0834,
+   IOMUXC_ESAI_TX_HF_CLK_SELECT_INPUT = 0x20E0838,
+   IOMUXC_ESAI_RX_CLK_SELECT_INPUT = 0x20E083C,
+   IOMUXC_ESAI_TX_CLK_SELECT_INPUT = 0x20E0840,
+   IOMUXC_ESAI_SDO0_SELECT_INPUT = 0x20E0844,
+   IOMUXC_ESAI_SDO1_SELECT_INPUT = 0x20E0848,
+   IOMUXC_ESAI_SDO2_SDI3_SELECT_INPUT = 0x20E084C,
+   IOMUXC_ESAI_SDO3_SDI2_SELECT_INPUT = 0x20E0850,
+   IOMUXC_ESAI_SDO4_SDI1_SELECT_INPUT = 0x20E0854,
+   IOMUXC_ESAI_SDO5_SDI0_SELECT_INPUT = 0x20E0858,
+   IOMUXC_HDMI_ICECIN_SELECT_INPUT = 0x20E085C,
+   IOMUXC_HDMI_II2C_CLKIN_SELECT_INPUT = 0x20E0860,
+   IOMUXC_HDMI_II2C_DATAIN_SELECT_INPUT = 0x20E0864,
+   IOMUXC_I2C1_SCL_IN_SELECT_INPUT = 0x20E0868,
+   IOMUXC_I2C1_SDA_IN_SELECT_INPUT = 0x20E086C,
+   IOMUXC_I2C2_SCL_IN_SELECT_INPUT = 0x20E0870,
+   IOMUXC_I2C2_SDA_IN_SELECT_INPUT = 0x20E0874,
+   IOMUXC_I2C3_SCL_IN_SELECT_INPUT = 0x20E0878,
+   IOMUXC_I2C3_SDA_IN_SELECT_INPUT = 0x20E087C,
+   IOMUXC_I2C4_SCL_IN_SELECT_INPUT = 0x20E0880,
+   IOMUXC_I2C4_SDA_IN_SELECT_INPUT = 0x20E0884,
+   IOMUXC_KEY_COL5_SELECT_INPUT = 0x20E08C0,
+   IOMUXC_KEY_COL6_SELECT_INPUT = 0x20E08C4,
+   IOMUXC_KEY_COL7_SELECT_INPUT = 0x20E08C8,
+   IOMUXC_KEY_ROW5_SELECT_INPUT = 0x20E08CC,
+   IOMUXC_KEY_ROW6_SELECT_INPUT = 0x20E08D0,
+   IOMUXC_KEY_ROW7_SELECT_INPUT = 0x20E08D4,
+   IOMUXC_MLB_MLB_CLK_IN_SELECT_INPUT = 0x20E08DC,
+   IOMUXC_MLB_MLB_DATA_IN_SELECT_INPUT = 0x20E08E0,
+   IOMUXC_MLB_MLB_SIG_IN_SELECT_INPUT = 0x20E08E4,
+   IOMUXC_SDMA_EVENTS14_SELECT_INPUT = 0x20E08E8,
+   IOMUXC_SPDIF_SPDIF_IN1_SELECT_INPUT = 0x20E08F0,
+   IOMUXC_SPDIF_TX_CLK2_SELECT_INPUT = 0x20E08F4,
+   IOMUXC_UART1_UART_RTS_B_SELECT_INPUT = 0x20E08F8,
+   IOMUXC_UART1_UART_RX_DATA_SELECT_INPUT = 0x20E08FC,
+   IOMUXC_UART2_UART_RTS_B_SELECT_INPUT = 0x20E00900,
+   IOMUXC_UART2_UART_RX_DATA_SELECT_INPUT = 0x20E0904,
+   IOMUXC_UART3_UART_RTS_B_SELECT_INPUT = 0x20E908,
+   IOMUXC_UART3_UART_RX_DATA_SELECT_INPUT = 0x20E090C,
+   IOMUXC_UART4_UART_RTS_B_SELECT_INPUT = 0x20E0910,
+   IOMUXC_UART4_UART_RX_DATA_SELECT_INPUT = 0x20E0914,
+   IOMUXC_UART5_UART_RTS_B_SELECT_INPUT = 0x20E0918,
+   IOMUXC_UART5_UART_RX_DATA_SELECT_INPUT = 0x20E091C,
+   IOMUXC_USB_OTG_OC_SELECT_INPUT = 0x20E0920,
+   IOMUXC_USB_H1_OC_SELECT_INPUT = 0x20E0924,
+   IOMUXC_USDHC1_WP_ON_SELECT_INPUT = 0x20E092C,
+   IOMUXC_SELECT_INPUT_UPPER_BOUND = IOMUXC_USDHC1_WP_ON_SELECT_INPUT,
+} IMX_INPUT_SELECT;
+
+#define IOMUXC_GPR_BASE_ADDRESS 0x020E0000
+
+typedef struct{
+    UINT32 GPR0;                          // 0x00 IOMUXC_GPR0
+    UINT32 GPR1;                          // 0x04 IOMUXC_GPR1
+    UINT32 GPR2;                          // 0x08 IOMUXC_GPR2
+    UINT32 GPR3;                          // 0x0C IOMUXC_GPR3
+    UINT32 GPR4;                          // 0x10 IOMUXC_GPR4
+    UINT32 GPR5;                          // 0x14 IOMUXC_GPR5
+    UINT32 GPR6;                          // 0x18 IOMUXC_GPR6
+    UINT32 GPR7;                          // 0x1C IOMUXC_GPR7
+    UINT32 GPR8;                          // 0x20 IOMUXC_GPR8
+    UINT32 GPR9;                          // 0x24 IOMUXC_GPR9
+    UINT32 GPR10;                         // 0x28 IOMUXC_GPR10
+    UINT32 GPR11;                         // 0x2c IOMUXC_GPR11
+    UINT32 GPR12;                         // 0x30 IOMUXC_GPR12
+    UINT32 GPR13;                         // 0x34 IOMUXC_GPR13
+} IMX_IOMUXC_GPR_REGISTERS;
+
+typedef enum {
+    IMX_IOMUXC_GPR1_USB_OTG_ID_SEL_ENET_RX_ER,
+    IMX_IOMUXC_GPR1_USB_OTG_ID_SEL_GPIO_1,
+} IMX_IOMUXC_GPR1_USB_OTG_ID_SEL;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 ACT_CS0 : 1;                 // 0
+        UINT32 ADDRS0_10 : 2;               // 1-2
+        UINT32 ACT_CS1 : 1;                 // 3
+        UINT32 ADDRS1_10 : 2;               // 4-5
+        UINT32 ACT_CS2 : 1;                 // 6
+        UINT32 ADDRS2_10 : 2;               // 7-8
+        UINT32 ACT_CS3 : 1;                 // 9
+        UINT32 ADDRS3_10 : 2;               // 10-11 Active Chip Select and Address Space
+        UINT32 GINT : 1;                    // 12 Global interrupt "0" bit (connected to ARM IRQ#0 and GPC)
+        UINT32 USB_OTG_ID_SEL : 1;          // 13 ''usb_otg_id' pin iomux select control.
+        UINT32 SYS_INT : 1;                 // 14 PCIe_CTL
+        UINT32 USB_EXP_MODE : 1;            // 15 USB Exposure mode
+        UINT32 REF_SSP_EN : 1;              // 16 PCIe_PHY - Reference Clock Enable for SS function.
+        UINT32 PU_VPU_MUX : 1;              // 17 IPU-1/IPU-2 to VPU signals control.
+        UINT32 TEST_POWERDOWN : 1;          // 18 PCIe_PHY - All Circuits Power-Down Control Function.
+        UINT32 MIPI_IPU1_MUX : 1;           // 19 MIPI sensor to IPU-1 mux control.
+        UINT32 MIPI_IPU2_MUX : 1;           // 20 MIPI sensor to IPU-2 mux control
+        UINT32 ENET_CLK_SEL : 1;            // 21 ENET TX reference clock
+        UINT32 EXC_MON : 1;                 // 22 Exclusive monitor response select of illegal command
+        UINT32 reserved1 : 1;               // 23
+        UINT32 MIPI_DPI_OFF : 1;            // 24 MIPI DPI shutdown request
+        UINT32 MIPI_COLOR_SW : 1;           // 25 MIPI color switch control
+        UINT32 APP_REQ_ENTR_L1 : 1;         // 26 PCIe_CTL - Application Request to Enter L1
+        UINT32 APP_READY_ENTR_L23 : 1;      // 27 PCIe_CTL - Application Ready to Enter L23
+        UINT32 APP_REQ_EXIT_L1 : 1;         // 28 PCIe_CTL - Application Request to Exit L1
+        UINT32 reserved2 : 1;               // 29
+        UINT32 APP_CLK_REQ_N : 1;           // 30 PCIe_CTL (CLK LOGIC CONTROLLER GLUE) - Indicates that application logic is ready to have reference clock removed.
+        UINT32 CFG_L1_CLK_REMOVAL_EN : 1;   // 31 PCIe_CTL (CLK LOGIC CONTROLLER GLUE) - Enable the reference clock removal in L1 state.
+        // MSB
+    };
+} IMX_IOMUXC_GPR1_REG;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 PCS_TX_DEEMPH_GEN1 : 6;      // 0-5 PCIe_PHY - This static value sets the launch amplitude of the transmitter when pipe0_tx_swing is set to 1'b0 (default state).
+        UINT32 PCS_TX_DEEMPH_GEN2_3P5DB : 6;// 6-11 PCIe_PHY - This static value sets the Tx driver SWING_FULL value.
+        UINT32 PCS_TX_DEEMPH_GEN2_6DB : 6;  // 12-17 PCIe_PHY - This static value sets the Tx driver de-emphasis value in the case where pipe0_tx_deemph is set to 1'b0 and the PHY is running at the Gen2 (6db) rate.
+        UINT32 PCS_TX_SWING_FULL : 7;       // 18-24 PCIe_PHY - This static value sets the Tx driver de-emphasis value in the case where pipe0_tx_deemph is set to 1'b1 (the default setting) and the PHY is running at the Gen2 (3p5db) rate.
+        UINT32 PCS_TX_SWING_LOW : 7;        // 25-31 PCIe_PHY - This static value sets the Tx driver de-emphasis value in the case where pipe0_tx_deemph is set to 1'b1 (the default setting) and the PHY is running at the Gen1 rate.
+        // MSB
+    };
+} IMX_IOMUXC_GPR8_REG;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 reserved0 : 2;               // 0-1
+        UINT32 uSDHC_DBG_MUX : 2;           // 2-3 uSDHC debug bus IO mux control
+        UINT32 LOS_LEVEL : 5;               // 4-8 PCIe_PHY - Loss-of-Signal Detector Sensitivity Level Control Function: Sets the sensitivity level for the Loss - of - Signal detector.This signal must be set to 0x9
+        UINT32 APPS_PM_XMT_PME : 1;         // 9 PCIe_CTL - Wake Up. Used by application logic to wake up the PMC state machine from a D1, D2 or D3 power state.Upon wake - up, the core sends a PM_PME Message
+        UINT32 APP_LTSSM_ENABLE : 1;        // 10 PCIe_CTL Driven low by the application after reset to hold the LTSSM in the Detect state until the application is ready.When the application has finished initializing the core configuration registers, it asserts app_ltssm_enable to allow the LTSSM to continue Link establishment.
+        UINT32 APP_INIT_RST : 1;            // 11 PCIe_PHY - PCIe_CTL - Request from the application to send a Hot Reset to the downstream device.
+        UINT32 DEVICE_TYPE : 4;             // 12-15 PCIe_CTL - Device/Port Type. 0000 PCIE_EP EP Mode 0010 PCIE_RC RC Mode
+        UINT32 APPS_PM_XMT_TURNOFF : 1;     // 16 PCIe_CTL - Request from the application to generate a PM_Turn_Off Message.
+        UINT32 DIA_STATUS_BUS_SELECT : 4;   // 17-20 PCIe_CTL - used for debug to select what part of diag_status_bus will be reflected on the 32 bits of the iomux
+        UINT32 PCIe_CTL_7 : 3;              // 21-23 PCIe control of diagnostic bus select
+        UINT32 ARMP_APB_CLK_EN : 1;         // 24 ARM platform APB clock enable
+        UINT32 ARMP_ATB_CLK_EN : 1;         // 25 ARM platform ATB clock enable
+        UINT32 ARMP_AHB_CLK_EN : 1;         // 26 ARM platform AHB clock enable
+        UINT32 ARMP_IPG_CLK_EN : 1;         // 27 ARM platform IPG clock enable
+        UINT32 reserved1 : 4;               // 28-31
+        // MSB
+    };
+} IMX_IOMUXC_GPR12_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 reserved1 : 1;               // 0
+    UINT32 reserved2 : 1;               // 1
+    UINT32 MC_ENV : 1;                  // 2 Monotonic Counter Enable and Valid
+    UINT32 reserved3 : 1;               // 3
+    UINT32 reserved4 : 1;               // 4
+    UINT32 DP_EN : 1;                   // 5 Dumb PMIC Enabled
+    UINT32 TOP : 1;                     // 6 Turn off System Power
+    UINT32 PWR_GLITCH_EN : 1;           // 7 Power Glitch Detection Enable
+    UINT32 reserved5 : 1;               // 8
+    UINT32 reserved6 : 1;               // 9
+    UINT32 reserved7 : 5;               // 10-14
+    UINT32 reserved8 : 1;               // 15
+    UINT32 BTN_PRESS_TIME : 2;          // 16-17 Button press time out values for PMIC Logic.
+    UINT32 DEBOUNCE : 2;                // 18-19 debounce time for the BTN input signal
+    UINT32 ON_TIME : 2;                 // 20-21 Time after BTN is asserted before pmic_en_b is asserted
+    UINT32 PK_EN : 1;                   // 22 PMIC On Request Enable
+    UINT32 PK_OVERRIDE : 1;             // 23 PMIC On Request Override
+    UINT32 reserved9 : 8;               // 24-31
+    // MSB
+  };
+} IMX_SNVS_LPCR_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 MINOR_REV : 8;               // 0-7 SNVS block minor version number
+    UINT32 MAJOR_REV : 8;               // 8-15 SNVS block major version number
+    UINT32 IP_ID : 16;                  // 16-31 SNVS block ID (IMX_SNVS_IP_ID)
+    // MSB
+  };
+} IMX_SNVS_HPVIDR1_REG;
+
+typedef struct {
+  UINT32 HPLR;                          // 0x000 SNVS_HP Lock Register (SNVS_HPLR)
+  UINT32 HPCOMR;                        // 0x004 SNVS_HP Command Register (SNVS_HPCOMR)
+  UINT32 HPCR;                          // 0x008 SNVS_HP Control Register (SNVS_HPCR)
+  UINT32 reserved1[2];
+  UINT32 HPSR;                          // 0x014 SNVS_HP Status Register (SNVS_HPSR)
+  UINT32 reserved2[3];
+  UINT32 HPRTCMR;                       // 0x024 SNVS_HP Real Time Counter MSB Register (SNVS_HPRTCMR
+  UINT32 HPRTCLR;                       // 0x028 SNVS_HP Real Time Counter LSB Register (SNVS_HPRTCLR)
+  UINT32 HPTAMR;                        // 0x02C SNVS_HP Time Alarm MSB Register (SNVS_HPTAMR)
+  UINT32 HPTALR;                        // 0x030 SNVS_HP Time Alarm LSB Register (SNVS_HPTALR)
+  UINT32 LPLR;                          // 0x034 SNVS_LP Lock Register (SNVS_LPLR)
+  UINT32 LPCR;                          // 0x038 SNVS_LP Control Register (SNVS_LPCR)
+  UINT32 reserved3[4];
+  UINT32 LPSR;                          // 0x04C SNVS_LP Status Register (SNVS_LPSR)
+  UINT32 reserved4[3];
+  UINT32 LPSMCMR;                       // 0x05C SNVS_LP Secure Monotonic Counter MSB Register (SNVS_LPSMCMR)
+  UINT32 LPSMCLR;                       // 0x060 SNVS_LP Secure Monotonic Counter LSB Register (SNVS_LPSMCLR)
+  UINT32 reserved5[1];
+  UINT32 LPGPR;                         // 0x068 SNVS_LP General Purpose Register (SNVS_LPGPR)
+  UINT32 reserved6[739];
+  UINT32 HPVIDR1;                       // 0xBF8 SNVS_HP Version ID Register 1 (SNVS_HPVIDR1)
+  UINT32 HPVIDR2;                       // 0xBFC SNVS_HP Version ID Register 2 (SNVS_HPVIDR2)
+} IMX_SNVS_REGISTERS;
+
+//
+// System Reset Controller (SRC)
+//
+
+#define IMX_SRC_BASE 0x020D8000
+#define IMX_SRC_LENGTH 0x4000
+
+//
+// SCR Register Definition
+//
+
+typedef enum {
+  IMX_SCR_WARM_RST_BYPASS_COUNT_DISABLED,
+  IMX_SCR_WARM_RST_BYPASS_COUNT_16,
+  IMX_SCR_WARM_RST_BYPASS_COUNT_32,
+  IMX_SCR_WARM_RST_BYPASS_COUNT_64,
+} IMX_SCR_WARM_RST_BYPASS_COUNT;
+
+typedef enum {
+  IMX_SRC_MASK_WDOG_RST_B_MASKED = 0x5,
+  IMX_SRC_MASK_WDOG_RST_B_NOT_MASKED = 0xA,
+} IMX_SRC_MASK_WDOG_RST;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 warm_reset_enable : 1;       // 0 WARM reset enable bit
+    UINT32 sw_gpu_rst : 1;              // 1 Software reset for GPU
+    UINT32 sw_vpu_rst : 1;              // 2 Software reset for VPU
+    UINT32 sw_ipu1_rst : 1;             // 3 Software reset for IPU1
+    UINT32 sw_open_vg_rst : 1;          // 4 Software reset for open_vg
+    UINT32 warm_rst_bypass_count : 2;   // 5-6 Defines the XTALI cycles to count before bypassing the MMDC acknowledge for WARM reset (IMX_SCR_WARM_RST_BYPASS_COUNT)
+    UINT32 mask_wdog_rst : 4;           // 7-10 Mask wdog_rst_b source (IMX_SRC_MASK_WDOG_RST)
+    UINT32 eim_rst : 1;                 // 11 EIM reset is needed in order to reconfigure the eim chip select.
+    UINT32 sw_ipu2_rst : 1;             // 12 Software reset for ipu2
+    UINT32 core0_rst : 1;               // 13 Software reset for core0 only.
+    UINT32 core1_rst : 1;               // 14 Software reset for core1 only.
+    UINT32 core2_rst : 1;               // 15 Software reset for core2 only
+    UINT32 core3_rst : 1;               // 16 Software reset for core3 only.
+    UINT32 core0_dbg_rst : 1;           // 17 Software reset for core0 debug only.
+    UINT32 core1_dbg_rst : 1;           // 18 Software reset for core1 debug only.
+    UINT32 core2_dbg_rst : 1;           // 19 Software reset for core2 debug only.
+    UINT32 core3_dbg_rst : 1;           // 20 Software reset for core3 debug only.
+    UINT32 cores_dbg_rst : 1;           // 21 Software reset for debug of arm platform only.
+    UINT32 core1_enable : 1;            // 22 core1 enable
+    UINT32 core2_enable : 1;            // 23 core2 enable
+    UINT32 core3_enable : 1;            // 24 core3 enable
+    UINT32 dbg_rst_msk_pg : 1;          // 25 Do not assert debug resets after power gating event of core
+    UINT32 reserved : 6;                // 26-31 reserved
+    // MSB
+  };
+} IMX_SRC_SCR_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 BOOT_CFG1 : 8;   // 0-7
+    UINT32 BOOT_CFG2 : 8;   // 8-15
+    UINT32 BOOT_CFG3 : 8;   // 16-23
+    UINT32 BOOT_CFG4 : 8;   // 24-31
+    // MSB
+  };
+} IMX_SRC_SBMR1_REG;
+
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 SEC_COFNIG : 2;    // 0-1
+    UINT32 reserved1 : 1;     // 2
+    UINT32 DIR_BT_DIS : 1;    // 3
+    UINT32 BT_FUSE_SEL : 1;   // 4
+    UINT32 reserved2 : 19;    // 5-23
+    UINT32 BMOD : 2;          // 24-25
+    UINT32 reserved3 : 6;     // 26-31
+    // MSB
+  };
+} IMX_SRC_SBMR2_REG;
+
+typedef struct {
+  UINT32 SCR;                           // 0x00 SRC Control Register (SRC_SCR)
+  UINT32 SBMR1;                         // 0x04 SRC Boot Mode Register 1 (SRC_SBMR1)
+  UINT32 SRSR;                          // 0x08 SRC Reset Status Register (SRC_SRSR)
+  UINT32 reserved1[2];
+  UINT32 SISR;                          // 0x14 SRC Interrupt Status Register (SRC_SISR)
+  UINT32 SIMR;                          // 0x18 SRC Interrupt Mask Register (SRC_SIMR)
+  UINT32 SBMR2;                         // 0x1C SRC Boot Mode Register 2 (SRC_SBMR2)
+  UINT32 GPR1;                          // 0x20 SRC General Purpose Register 1 (SRC_GPR1)
+  UINT32 GPR2;                          // 0x24 SRC General Purpose Register 2 (SRC_GPR2)
+  UINT32 GPR3;                          // 0x28 SRC General Purpose Register 3 (SRC_GPR3)
+  UINT32 GPR4;                          // 0x2C SRC General Purpose Register 4 (SRC_GPR4)
+  UINT32 GPR5;                          // 0x30 SRC General Purpose Register 4 (SRC_GPR5)
+  UINT32 GPR6;                          // 0x34 SRC General Purpose Register 4 (SRC_GPR6)
+  UINT32 GPR7;                          // 0x38 SRC General Purpose Register 4 (SRC_GPR7)
+  UINT32 GPR8;                          // 0x3C SRC General Purpose Register 4 (SRC_GPR8)
+  UINT32 GPR9;                          // 0x40 SRC General Purpose Register 4 (SRC_GPR9)
+  UINT32 GPR10;                         // 0x44 SRC General Purpose Register 4 (SRC_GPR10)
+} IMX_SRC_REGISTERS;
+
+
+//
+// Watchdog (WDOG)
+//
+
+#define IMX_WDOG1_BASE 0x020BC000
+#define IMX_WDOG2_BASE 0x020C0000
+#define IMX_WDOG_LENGTH 0x4000
+
+#define IMX_WDOG_WSR_FEED1 0x5555
+#define IMX_WDOG_WSR_FEED2 0xAAAA
+
+typedef union {
+  UINT16 AsUint16;
+  struct {
+    // LSB
+    UINT16 WDZST : 1;                   // 0 Watchdog Low Power
+    UINT16 WDBG : 1;                    // 1 Watchdog DEBUG Enable
+    UINT16 WDE : 1;                     // 2 Watchdog Enable
+    UINT16 WDT : 1;                     // 3 WDOG_B Time-out assertion.
+    UINT16 SRS : 1;                     // 4 Software Reset Signal
+    UINT16 WDA : 1;                     // 5 WDOG_B assertion
+    UINT16 reserved1 : 1;               // 6
+    UINT16 WDW : 1;                     // 7 Watchdog Disable for Wait
+    UINT16 WT : 8;                      // 8-15 Watchdog Time-out Field
+    // MSB
+  };
+} IMX_WDOG_WCR_REG;
+
+typedef struct {
+  UINT16 WCR;                           // 0x0 Watchdog Control Register (WDOG1_WCR)
+  UINT16 WSR;                           // 0x2 Watchdog Service Register (WDOG1_WSR)
+  UINT16 WRSR;                          // 0x4 Watchdog Reset Status Register (WDOG1_WRSR)
+  UINT16 WICR;                          // 0x6 Watchdog Interrupt Control Register (WDOG1_WICR)
+  UINT16 WMCR;                          // 0x8 Watchdog Miscellaneous Control Register (WDOG1_WMCR)
+} IMX_WDOG_REGISTERS;
+
+//
+// Clock Control Module (CCM)
+//
+
+#define IMX_CCM_BASE 0x020C4000
+#define IMX_CCM_LENGTH 0x4000
+#define IMX_CCM_ANALOG_BASE  0x020C8000
+#define IMX_CCM_ANALOG_LENGTH 0x1000
+
+#define IMX_GPU2D_CORE_CLK_MAX 532000000 // 532Mhz
+#define IMX_GPU3D_CORE_CLK_MAX 540000000 // 540Mhz
+
+#define IMX_REF_CLK_24M_FREQ 24000000
+
+typedef enum {
+  IMX_CCM_PLL3_SW_CLK_SEL_PLL3_MAIN_CLK,
+  IMX_CCM_PLL3_SW_CLK_SEL_PLL3_BYPASS_CLK,
+} IMX_CCM_PLL3_SW_CLK_SEL;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 pll3_sw_clk_sel : 1;         // 0 Selects source to generate pll3_sw_clk
+    UINT32 reserved1 : 1;               // 1 reserved
+    UINT32 pll1_sw_clk_sel : 1;         // 2 Selects source to generate pll1_sw_clk.
+    UINT32 reserved2 : 5;               // 3-7
+    UINT32 step_sel : 1;                // 8 Selects the option to be chosen for the step frequency
+    UINT32 pfd_396m_dis_mask : 1;       // 9 Mask of 396M PFD auto-disable
+    UINT32 pfd_352m_dis_mask : 1;       // 10 Mask of 352M PFD auto-disable.
+    UINT32 pfd_594_dis_mask : 1;        // 11 Mask of 594M PFD auto-disable.
+    UINT32 pfd_508m_dis_mask : 1;       // 12 Mask of 508M PFD auto-disable
+    UINT32 pfd_454m_dis_mask : 1;       // 13 Mask of 454M PFD auto-disable.
+    UINT32 pfd_720m_dis_mask : 1;       // 14 Mask of 720M PFD auto-disable.
+    UINT32 pfd_540m_dis_mask : 1;       // 15 Mask of 540M PFD auto-disable.
+    UINT32 reserved3 : 16;              // 16-31
+    // MSB
+  };
+} IMX_CCM_CCSR_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 arm_podf : 3;                // 0-3 Divider for ARM clock root
+    UINT32 reserved : 29;               // 3-31
+    // MSB
+  };
+} IMX_CCM_CACRR_REG;
+
+// CBCMR.gpu2d_axi_clk_sel
+typedef enum {
+  IMX_CCM_GPU2D_AXI_CLK_SEL_AXI,
+  IMX_CCM_GPU2D_AXI_CLK_SEL_AHB,
+} IMX_CCM_GPU2D_AXI_CLK_SEL;
+
+// CBCMR.gpu3d_axi_clk_sel
+typedef enum {
+  IMX_CCM_GPU3D_AXI_CLK_SEL_AXI,
+  IMX_CCM_GPU3D_AXI_CLK_SEL_AHB,
+} IMX_CCM_GPU3D_AXI_CLK_SEL;
+
+// CBCMR.gpu2d_core_clk_sel
+typedef enum {
+  IMX_CCM_GPU2D_CORE_CLK_SEL_AXI,
+  IMX_CCM_GPU2D_CORE_CLK_SEL_PLL3_SW,
+  IMX_CCM_GPU2D_CORE_CLK_SEL_PLL2_PFD0,
+  IMX_CCM_GPU2D_CORE_CLK_SEL_PLL2_PFD2,
+} IMX_CCM_GPU2D_CORE_CLK_SEL;
+
+// CBCMR.pre_periph_clk_sel
+typedef enum {
+  IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2,
+  IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2_PFD2,
+  IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2_PFD0,
+  IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2_PFD2_DIV2,
+} IMX_CCM_PRE_PERIPH_CLK_SEL;
+
+// CBCMR.gpu3d_core_clk_sel
+typedef enum {
+  IMX_CCM_GPU3D_CORE_CLK_SEL_MMDC_CH0_AXI,
+  IMX_CCM_GPU3D_CORE_CLK_SEL_PLL3_SW,
+  IMX_CCM_GPU3D_CORE_CLK_SEL_PLL2_PFD1,
+  IMX_CCM_GPU3D_CORE_CLK_SEL_PLL2_PFD2,
+} IMX_CCM_GPU3D_CORE_CLK_SEL;
+
+// CBCMR.gpu3d_shader_clk_sel
+typedef enum {
+  IMX_CCM_GPU3D_SHADER_CLK_SEL_MMDC_CH0_AXI,
+  IMX_CCM_GPU3D_SHADER_CLK_SEL_PLL3_SW,
+  IMX_CCM_GPU3D_SHADER_CLK_SEL_PLL2_PFD1,
+  IMX_CCM_GPU3D_SHADER_CLK_SEL_PLL3_PFD0,
+} IMX_CCM_GPU3D_SHADER_CLK_SEL;
+
+// CBCMR.periph_clk2_sel
+typedef enum {
+  IMX_CCM_PERIPH_CLK2_SEL_PLL3_SW_CLK,
+  IMX_CCM_PERIPH_CLK2_SEL_OSC_CLK,
+  IMX_CCM_PERIPH_CLK2_SEL_PLL2,
+} IMX_CCM_PERIPH_CLK2_SEL;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 gpu2d_axi_clk_sel : 1;       // 0 Selector for gpu2d_axi clock multiplexer (IMX_CCM_GPU2D_AXI_CLK_SEL)
+    UINT32 gpu3d_axi_clk_sel : 1;       // 1 Selector for gpu3d_axi clock multiplexer (IMX_CCM_GPU3D_AXI_CLK_SEL)
+    UINT32 reserved1 : 2;               // 2-3
+    UINT32 gpu3d_core_clk_sel : 2;      // 4-5 Selector for gpu3d_core clock multiplexer (IMX_CCM_GPU3D_CORE_CLK_SEL)
+    UINT32 reserved2 : 2;               // 6-7
+    UINT32 gpu3d_shader_clk_sel : 2;    // 8-9 Selector for gpu3d_shader clock multiplexer (IMX_CCM_GPU3D_SHADER_CLK_SEL)
+    UINT32 pcie_axi_clk_sel : 1;        // 10 Selector for pcie_axi clock multiplexer
+    UINT32 vdoaxi_clk_sel : 1;          // 11 Selector for vdoaxi clock multiplexer
+    UINT32 periph_clk2_sel : 2;         // 12-13 Selector for peripheral clk2 clock multiplexer
+    UINT32 vpu_axi_clk_sel : 2;         // 14-15 Selector for VPU axi clock multiplexer
+    UINT32 gpu2d_core_clk_sel : 2;      // 16-17 Selector for open vg (GPU2D Core) clock multiplexer (IMX_CCM_GPU2D_CORE_CLK_SEL)
+    UINT32 pre_periph_clk_sel : 2;      // 18-19 Selector for pre_periph clock multiplexer
+    UINT32 periph2_clk2_sel : 1;        // 20 Selector for periph2_clk2 clock multiplexer
+    UINT32 pre_periph2_clk_sel : 2;     // 21-22 Selector for pre_periph2 clock multiplexer
+    UINT32 gpu2d_core_clk_podf : 3;     // 23-25 Divider for gpu2d_core clock.
+    UINT32 gpu3d_core_podf : 3;         // 26-28 Divider for gpu3d_core clock
+    UINT32 gpu3d_shader_podf : 3;       // 29-31 Divider for gpu3d_shader clock.
+    // MSB
+  };
+} IMX_CCM_CBCMR_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 ssi1_clk_podf : 6;           // 0-5 Divider for ssi1 clock podf
+    UINT32 ssi1_clk_pred : 3;           // 6-8 Divider for ssi1 clock pred
+    UINT32 esai_clk_pred : 3;           // 9-11 Divider for esai clock pred
+    UINT32 reserved1 : 4;               // 12-15 Reserved
+    UINT32 ssi3_clk_podf : 6;           // 16-21 Divider for ssi3 clock podf
+    UINT32 ssi3_clk_pred : 3;           // 22-24 Divider for ssi3 clock pred
+    UINT32 esai_clk_podf : 3;           // 25-27 Divider for esai clock podf
+    UINT32 reserved2 : 4;               // 28-31 Reserved
+    // MSB
+  };
+} IMX_CCM_CS1CDR_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 ssi2_clk_podf : 6;           // 0-5 Divider for ssi2 clock podf
+    UINT32 ssi2_clk_pred : 3;           // 6-8 Divider for ssi2 clock pred
+    UINT32 ldb_di0_clk_sel : 3;         // 9-11 Selector for ldb_di0 clock multiplexer
+    UINT32 ldb_di1_clk_sel : 3;         // 12-14 Selector for ldb_di1 clock multiplexer
+    UINT32 reserved1 : 1;               // 15 Reserved
+    UINT32 enfc_clk_sel : 2;            // 16-17 Selector for enfc clock multiplexer
+    UINT32 enfc_clk_pred : 3;           // 18-20 Divider for enfc clock pred divider
+    UINT32 esai_clk_podf : 6;           // 21-26 Divider for enfc clock divider
+    UINT32 reserved2 : 5;               // 27-31 Reserved
+    // MSB
+  };
+} IMX_CCM_CS2CDR_REG;
+
+typedef enum {
+  IMX_CCM_CCGR_OFF = 0x0,               // Clock is off during all modes. Stop enter hardware handshake is disabled.
+  IMX_CCM_CCGR_ON_RUN = 0x1,            // Clock is on in run mode, but off in WAIT and STOP modes
+  IMX_CCM_CCGR_ON = 0x3,                // Clock is on during all modes, except STOP mode.
+} IMX_CCM_CCGR;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 aips_tz1_clk_enable : 2;     // 0-1 aips_tz1 clocks (aips_tz1_clk_enable)
+    UINT32 aips_tz2_clk_enable : 2;     // 2-3 aips_tz2 clocks (aips_tz2_clk_enable)
+    UINT32 apbhdma_hclk_enable : 2;     // 4-5 apbhdma hclk clock (apbhdma_hclk_enable)
+    UINT32 asrc_clk_enable : 2;         // 6-7 asrc clock (asrc_clk_enable)
+    UINT32 caam_secure_mem_clk_enable : 2; // 8-9 caam_secure_mem clock (caam_secure_mem_clk_enable)
+    UINT32 caam_wrapper_aclk_enable : 2; // 10-11 caam_wrapper_aclk clock (caam_wrapper_aclk_enable)
+    UINT32 caam_wrapper_ipg_enable : 2; // 12-13 caam_wrapper_ipg clock (caam_wrapper_ipg_enable)
+    UINT32 can1_clk_enable : 2;         // 14-15 can1 clock (can1_clk_enable)
+    UINT32 can1_serial_clk_enable : 2;  // 16-17 can1_serial clock (can1_serial_clk_enable)
+    UINT32 can2_clk_enable : 2;         // 18-19 can2 clock (can2_clk_enable)
+    UINT32 can2_serial_clk_enable : 2;  // 20-21 can2_serial clock (can2_serial_clk_enable)
+    UINT32 arm_dbg_clk_enable : 2;      // 22-23 CPU debug clocks (arm_dbg_clk_enable)
+    UINT32 dcic1_clk_enable : 2;        // 24-25 dcic 1 clocks (dcic1_clk_enable)
+    UINT32 dcic2_clk_enable : 2;        // 26-27 dcic2 clocks (dcic2_clk_enable)
+    UINT32 dtcp_clk_enable : 2;         // 28-29 dtcp clocks (dtcp_clk_enable)
+    UINT32 reserved : 2;                // 30-31
+    // MSB
+  };
+} IMX_CCM_CCGR0_REG;
+
+// CHSCCDR.ipu1_di0_clk_sel
+typedef enum {
+  IMX_CHSCCDR_IPU1_DI0_CLK_SEL_PREMUX,      // 0
+  IMX_CHSCCDR_IPU1_DI0_CLK_SEL_IPP_DI0_CLK, // 1
+  IMX_CHSCCDR_IPU1_DI0_CLK_SEL_IPP_DI1_CLK, // 2
+  IMX_CHSCCDR_IPU1_DI0_CLK_SEL_LDB_DI0_CLK, // 3
+  IMX_CHSCCDR_IPU1_DI0_CLK_SEL_LDB_DI1_CLK, // 4
+} IMX_CHSCCDR_IPU1_DI0_CLK_SEL;
+
+// CHSCCDR.ipu1_di0_podf
+typedef enum {
+  IMX_CHSCCDR_IPU1_DI0_PODF_DIV_1,  // 0
+  IMX_CHSCCDR_IPU1_DI0_PODF_DIV_2,  // 1
+  IMX_CHSCCDR_IPU1_DI0_PODF_DIV_3,
+  IMX_CHSCCDR_IPU1_DI0_PODF_DIV_4,
+  IMX_CHSCCDR_IPU1_DI0_PODF_DIV_5,
+  IMX_CHSCCDR_IPU1_DI0_PODF_DIV_6,
+  IMX_CHSCCDR_IPU1_DI0_PODF_DIV_7,
+  IMX_CHSCCDR_IPU1_DI0_PODF_DIV_8,
+} IMX_CHSCCDR_IPU1_DI0_PODF;
+
+// CHSCCDR.ipu1_di0_pre_clk_sel
+typedef enum {
+  IMX_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MMDC_CH0,        // 0
+  IMX_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL3_SW_CLK,     // 1
+  IMX_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL5,            // 2
+  IMX_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL2_PFD0,
+  IMX_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL2_PFD2,
+  IMX_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL3_PFD1,
+} IMX_CHSCCDR_IPU1_DI0_PRE_CLK_SEL;
+
+// CHSCCDR.ipu1_di1_clk_sel
+typedef enum {
+  IMX_CHSCCDR_IPU1_DI1_CLK_SEL_PREMUX,      // 0
+  IMX_CHSCCDR_IPU1_DI1_CLK_SEL_IPP_DI0_CLK, // 1
+  IMX_CHSCCDR_IPU1_DI1_CLK_SEL_IPP_DI1_CLK, // 2
+  IMX_CHSCCDR_IPU1_DI1_CLK_SEL_LDB_DI0_CLK, // 3
+  IMX_CHSCCDR_IPU1_DI1_CLK_SEL_LDB_DI1_CLK, // 4
+} IMX_CHSCCDR_IPU1_DI1_CLK_SEL;
+
+// CHSCCDR.ipu1_di1_podf
+typedef enum {
+  IMX_CHSCCDR_IPU1_DI1_PODF_DIV_1,  // 0
+  IMX_CHSCCDR_IPU1_DI1_PODF_DIV_2,
+  IMX_CHSCCDR_IPU1_DI1_PODF_DIV_3,
+  IMX_CHSCCDR_IPU1_DI1_PODF_DIV_4,
+  IMX_CHSCCDR_IPU1_DI1_PODF_DIV_5,
+  IMX_CHSCCDR_IPU1_DI1_PODF_DIV_6,
+  IMX_CHSCCDR_IPU1_DI1_PODF_DIV_7,
+  IMX_CHSCCDR_IPU1_DI1_PODF_DIV_8,
+} IMX_CHSCCDR_IPU1_DI1_PODF;
+
+// CHSCCDR.ipu1_di1_pre_clk_sel
+typedef enum {
+  IMX_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_MMDC_CH0,    // 0
+  IMX_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL3_SW_CLK, // 1
+  IMX_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL5,        // 2
+  IMX_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL2_PFD0,
+  IMX_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL2_PFD2,
+  IMX_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL3_PFD1,
+} IMX_CHSCCDR_IPU1_DI1_PRE_CLK_SEL;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 ipu1_di0_clk_sel : 3;        // 0-2 Selector for ipu1 di0 root clock multiplexer
+        UINT32 ipu1_di0_podf : 3;           // 3-5 Divider for ipu1_di0 clock divider
+        UINT32 ipu1_di0_pre_clk_sel : 3;    // 6-8 Selector for ipu1 di0 root clock pre-multiplexer
+        UINT32 ipu1_di1_clk_sel : 3;        // 9-11 Selector for ipu1 di1 root clock multiplexer
+        UINT32 ipu1_di1_podf : 3;           // 12-14 Divider for ipu1_di clock divider
+        UINT32 ipu1_di1_pre_clk_sel : 3;    // 15-17 Selector for ipu1 di1 root clock pre-multiplexer
+        UINT32 reserved : 14;               // 18-31
+        // MSB
+    };
+} IMX_CCM_CHSCCDR_REG;
+
+//
+// NOTE: OPENVG clock cannot be gated without gating GPU2D clock as well.
+//       Configure both CG bits (CCM_ANALOG_CCGR1[CG12] and
+//       CCM_ANALOG_CCGR3[CG15]) to gate OPENVG.
+//
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 ecspi1_clk_enable : 2;       // 0-1 ecspi1 clocks (ecspi1_clk_enable)
+    UINT32 ecspi2_clk_enable : 2;       // 2-3 ecspi2 clocks (ecspi2_clk_enable)
+    UINT32 ecspi3_clk_enable : 2;       // 4-5 ecspi3 clocks (ecspi3_clk_enable)
+    UINT32 ecspi4_clk_enable : 2;       // 6-7 ecspi4 clocks (ecspi4_clk_enable)
+    UINT32 ecspi5_clk_enable : 2;       // 8-9 ecspi5 clocks (ecspi5_clk_enable)
+    UINT32 enet_clk_enable : 2;         // 10-11 enet clock (enet_clk_enable)
+    UINT32 epit1_clk_enable : 2;        // 12-13 epit1 clocks (epit1_clk_enable)
+    UINT32 epit2_clk_enable : 2;        // 14-15 epit2 clocks (epit2_clk_enable)
+    UINT32 esai_clk_enable : 2;         // 16-17 esai clocks (esai_clk_enable)
+    UINT32 reserved1 : 2;               // 18-19
+    UINT32 gpt_clk_enable : 2;          // 20-21 gpt bus clock (gpt_clk_enable)
+    UINT32 gpt_serial_clk_enable : 2;   // 22-23 gpt serial clock (gpt_serial_clk_enable)
+    UINT32 gpu2d_clk_enable : 2;        // 24-25 gpu2d clock (gpu2d_clk_enable)
+    UINT32 gpu3d_clk_enable : 2;        // 26-27 gpu3d clock (gpu3d_clk_enable)
+    UINT32 reserved2 : 4;               // 28-31
+    // MSB
+  };
+} IMX_CCM_CCGR1_REG;
+
+// CBCDR.axi_sel
+typedef enum {
+  IMX_CCM_AXI_SEL_PERIPH_CLK,
+  IMX_CCM_AXI_SEL_AXI_ALT,
+} IMX_CCM_AXI_SEL;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 periph2_clk2_podf : 3;       // 0-2 Divider for periph2_clk2 podf
+    UINT32 mmdc_ch1_axi_podf : 3;       // 3-5 Divider for mmdc_ch1_axi podf
+    UINT32 axi_sel : 1;                 // 6 AXI clock source select (IMX_CCM_AXI_SEL)
+    UINT32 axi_alt_sel : 1;             // 7 AXI alternative clock select
+    UINT32 ipg_podf : 2;                // 8-9 Divider for ipg podf.
+    UINT32 ahb_podf : 3;                // 10-12 Divider for AHB PODF.
+    UINT32 reserved1 : 3;               // 13-15
+    UINT32 axi_podf : 3;                // 16-18 Divider for axi podf
+    UINT32 mmdc_ch0_axi_podf : 3;       // 19-21 Divider for mmdc_ch0_axi podf.
+    UINT32 reserved2 : 3;               // 22-24
+    UINT32 periph_clk_sel : 1;          // 25 Selector for peripheral main clock (source of MMDC_CH0_CLK_ROOT).
+    UINT32 periph2_clk_sel : 1;         // 16 Selector for peripheral2 main clock (source of mmdc_ch1_clk_root
+    UINT32 periph_clk2_podf : 3;        // 27-29 Divider for periph2 clock podf.
+    UINT32 reserved3 : 2;               // 30-31
+    // MSB
+  };
+} IMX_CCM_CBCDR_REG;
+
+// CCOSR.CLKO1_SEL
+typedef enum {
+  IMX_CCM_CLKO1_SEL_PLL3_SW_CLK_2,
+  IMX_CCM_CLKO1_SEL_PLL2_MAIN_CLK_2,
+  IMX_CCM_CLKO1_SEL_PLL1_MAIN_CLK_2,
+  IMX_CCM_CLKO1_SEL_PLL5_MAIN_CLK_2,
+  IMX_CCM_CLKO1_SEL_VIDEO_27M_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_AXI_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_ENFC_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_IPU1_DI0_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_IPU1_DI1_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_IPU2_DI0_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_IPU2_DI1_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_AHB_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_IPG_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_PERCLK_ROOT,
+  IMX_CCM_CLKO1_SEL_CKIL_SYNC_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_PLL4_MAIN_CLK,
+} IMX_CCM_CLKO1_SEL;
+
+// CCOSR.CLK_OUT_SEL
+typedef enum {
+  IMX_CCM_CLK_OUT_SEL_CCM_CLKO1,
+  IMX_CCM_CLK_OUT_SEL_CCM_CLKO2,
+} IMX_CCM_CLK_OUT_SEL;
+
+// CCOSR.CLKO2_SEL
+typedef enum {
+  IMX_CCM_CLKO2_SEL_MMDC_CH0_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_MMDC_CH1_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_USDHC4_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_USDHC1_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_GPU2D_AXI_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_WRCK_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_ECSPI_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_GPU3D_AXI_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_USDHC3_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_125M_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_ARM_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_IPU1_HSP_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_IPU2_HSP_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_VDO_AXI_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_OSC_CLK,
+  IMX_CCM_CLKO2_SEL_GPU2D_CORE_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_GPU3D_CORE_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_USDHC2_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_SSI1_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_SSI2_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_SSI3_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_GPU3D_SHADER_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_VPU_AXI_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_CAN_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_LDB_DI0_SERIAL_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_LDB_DI1_SERIAL_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_ESAI_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_ACLK_EIM_SLOW_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_UART_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_SPDIF0_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_SPDIF1_CLK_ROOT,
+  IMX_CCM_CLKO2_SEL_HSI_TX_CLK_ROOT,
+} IMX_CCM_CLKO2_SEL;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 CLKO1_SEL : 4;               // 0-3 Selection of the clock to be generated on CCM_CLKO1 (IMX_CCM_CLKO1_SEL)
+    UINT32 CLKO1_DIV : 3;               // 4-6 Setting the divider of CCM_CLKO1
+    UINT32 CLKO1_EN : 1;                // 7 Enable of CCM_CLKO1 clock
+    UINT32 CLK_OUT_SEL : 1;             // 8 CCM_CLKO1 output to reflect CCM_CLKO1 or CCM_CLKO2 clocks
+    UINT32 reserved1 : 7;               // 9-15
+    UINT32 CLKO2_SEL : 5;               // 16-20 Selection of the clock to be generated on CCM_CLKO2 (IMX_CCM_CLKO2_SEL)
+    UINT32 CLKO2_DIV : 3;               // 21-23 Setting the divider of CCM_CLKO2
+    UINT32 CLKO2_EN : 1;                // 24 Enable of CCM_CLKO2 clock
+    UINT32 reserved2 : 7;               // 25-31
+    // MSB
+  };
+} IMX_CCM_CCOSR_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 ipu1_ipu_clk_enable : 2;     // 0-1 ipu1_ipu clock (ipu1_ipu_clk_enable)
+    UINT32 ipu1_ipu_di0_clk_enable : 2; // 2-3 ipu1_di0 clock and pre-clock (ipu1_ipu_di0_clk_enable)
+    UINT32 ipu1_ipu_di1_clk_enable : 2; // 4-5 ipu1_di1 clock and pre-clock (ipu1_ipu_di1_clk_enable)
+    UINT32 ipu2_ipu_clk_enable : 2;     // 6-7 ipu2_ipu clock (ipu2_ipu_clk_enable)
+    UINT32 ipu2_ipu_di0_clk_enable : 2; // 8-9 ipu2_di0 clock and pre-clock (ipu2_ipu_di0_clk_enable)
+    UINT32 ipu2_ipu_di1_clk_enable : 2; // 10-11 ipu2_di1 clock and pre-clock (ipu2_ipu_di1_clk_enable)
+    UINT32 ldb_di0_clk_enable : 2;      // 12-13 ldb_di0 clock (ldb_di0_clk_enable)
+    UINT32 ldb_di1_clk_enable : 2;      // 14-15 ldb_di1 clock (ldb_di1_clk_enable)
+    UINT32 mipi_core_cfg_clk_enable : 2; // 16-17 mipi_core_cfg clock (mipi_core_cfg_clk_enable)
+    UINT32 mlb_clk_enable : 2;          // 18-19 mlb clock (mlb_clk_enable)
+    UINT32 mmdc_core_aclk_fast_core_p0_enable : 2; // 20-21 mmdc_core_aclk_fast_core_p0 clock (mmdc_core_aclk_fast_core_p0_enable)
+    UINT32 reserved1 : 2;               // 22-23
+    UINT32 mmdc_core_ipg_clk_p0_enable : 2; // 24-25 mmdc_core_ipg_clk_p0 clock (mmdc_core_ipg_clk_p0_enable)
+    UINT32 reserved2 : 2;               // 26-27
+    UINT32 ocram_clk_enable : 2;        // 28-29 ocram clock (ocram_clk_enable)
+    UINT32 openvgaxiclk_clk_root_enable : 2; // 30-31 openvgaxiclk clock (openvgaxiclk_clk_root_enable)
+    // MSB
+  };
+} IMX_CCM_CCGR3_REG;
+
+typedef struct {
+  UINT32 CCR;                           // 0x00 CCM Control Register (CCM_CCR)
+  UINT32 CCDR;                          // 0x04 CCM Control Divider Register (CCM_CCDR)
+  UINT32 CSR;                           // 0x08 CCM Status Register (CCM_CSR)
+  UINT32 CCSR;                          // 0x0C CCM Clock Switcher Register (CCM_CCSR)
+  UINT32 CACRR;                         // 0x10 CCM Arm Clock Root Register (CCM_CACRR)
+  UINT32 CBCDR;                         // 0x14 CCM Bus Clock Divider Register (CCM_CBCDR)
+  UINT32 CBCMR;                         // 0x18 CCM Bus Clock Multiplexer Register (CCM_CBCMR)
+  UINT32 CSCMR1;                        // 0x1C CCM Serial Clock Multiplexer Register 1 (CCM_CSCMR1)
+  UINT32 CSCMR2;                        // 0x20 CCM Serial Clock Multiplexer Register 2 (CCM_CSCMR2)
+  UINT32 CSCDR1;                        // 0x24 CCM Serial Clock Divider Register 1 (CCM_CSCDR1)
+  UINT32 CS1CDR;                        // 0x28 CCM SSI1 Clock Divider Register (CCM_CS1CDR)
+  UINT32 CS2CDR;                        // 0x2C CCM SSI2 Clock Divider Register (CCM_CS2CDR)
+  UINT32 CDCDR;                         // 0x30 CCM D1 Clock Divider Register (CCM_CDCDR)
+  UINT32 CHSCCDR;                       // 0x34 CCM HSC Clock Divider Register (CCM_CHSCCDR)
+  UINT32 CSCDR2;                        // 0x38 CCM Serial Clock Divider Register 2 (CCM_CSCDR2)
+  UINT32 CSCDR3;                        // 0x3C CCM Serial Clock Divider Register 3 (CCM_CSCDR3)
+  UINT32 reserved1[2];
+  UINT32 CDHIPR;                        // 0x48 CCM Divider Handshake In-Process Register (CCM_CDHIPR)
+  UINT32 reserved2[2];
+  UINT32 CLPCR;                         // 0x54 CCM Low Power Control Register (CCM_CLPCR)
+  UINT32 CISR;                          // 0x58 CCM Interrupt Status Register (CCM_CISR)
+  UINT32 CIMR;                          // 0x5C CCM Interrupt Mask Register (CCM_CIMR)
+  UINT32 CCOSR;                         // 0x60 CCM Clock Output Source Register (CCM_CCOSR)
+  UINT32 CGPR;                          // 0x64 CCM General Purpose Register (CCM_CGPR)
+  UINT32 CCGR[7];                       // 0x68-7C CCM Clock Gating Register 0-6 (CCM_CCGR0-CCM_CCGR6)
+  UINT32 reserved3[1];
+  UINT32 CMEOR;                         // 0x88 CCM Module Enable Override Register (CCM_CMEOR)
+} IMX_CCM_REGISTERS;
+
+//
+// CCM Analog
+//
+
+typedef enum {
+  IMX_PLL_BYPASS_CLK_SRC_REF_CLK_24M,
+  IMX_PLL_BYPASS_CLK_SRC_CLK1,
+  IMX_PLL_BYPASS_CLK_SRC_CLK2,
+  IMX_PLL_BYPASS_CLK_SRC_XOR,
+} IMX_PLL_BYPASS_CLK_SRC;
+
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 DIV_SELECT : 7;              // 0-6  Valid range for divider value: 54-108. Fout = Fin * div_select/2.0
+    UINT32 reserved1 : 5;               // 7-11
+    UINT32 POWERDOWN : 1;               // 12 Powers down the PLL.
+    UINT32 ENABLE: 1;                   // 13 Enable the clock output.
+    UINT32 BYPASS_CLK_SRC : 2;          // 14-15 Determines the bypass and PLL reference clock source.
+    UINT32 BYPASS : 1;                  // 16 Bypass the PLL.
+    UINT32 LVDS_SEL : 1;                // 17 Analog Debug Bit
+    UINT32 LVDS_24MHZ_SEL : 1;          // 18 Analog Debug Bit
+    UINT32 reserved2 : 1;               // 19 PLL_SEL (Reserved)
+    UINT32 reserved3 : 11;              // 20-30
+    UINT32 LOCK : 1;                    // 31 1 - PLL is currently locked. 0 - PLL is not currently locked.
+    // MSB
+  };
+} IMX_CCM_ANALOG_PLL_ARM_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 DIV_SELECT : 1;              // 0 0 - Fout=Fref*20; 1 - Fout=Fref*22.
+    UINT32 reserved1 : 11;              // 1-11
+    UINT32 POWERDOWN : 1;               // 12 Powers down the PLL.
+    UINT32 ENABLE : 1;                  // 13 Enable PLL output
+    UINT32 BYPASS_CLK_SRC : 2;          // 14-15 Determines the bypass source.
+    UINT32 BYPASS : 1;                  // 16 Bypass the PLL.
+    UINT32 reserved2 : 1;               // 17
+    UINT32 PFD_OFFSET_EN : 1;           // 18 Enables an offset in the phase frequency detector
+    UINT32 reserved3 : 12;              // 19-30
+    UINT32 LOCK : 1;                    // 31 1 - PLL is currently locked; 0 - PLL is not currently locked.
+    // MSB
+  };
+} IMX_CCM_ANALOG_PLL_SYS_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 DIV_SELECT : 2;              // 0-1 - Fout=Fref*20; 1 - Fout=Fref*22.
+    UINT32 reserved1 : 4;               // 2-5
+    UINT32 EN_USB_CLKS : 1;             // 6 Powers the 9-phase PLL outputs for USBPHYn
+    UINT32 reserved2 : 5;               // 7-11
+    UINT32 POWER : 1;                   // 12 Powers up the PLL.
+    UINT32 ENABLE : 1;                  // 13 Enable the PLL clock output
+    UINT32 BYPASS_CLK_SRC : 2;          // 14-15 Determines the bypass source
+    UINT32 BYPASS : 1;                  // 16 Bypass the PLL.
+    UINT32 reserved3 : 14;              // 17-30
+    UINT32 LOCK : 1;                    // 31 1 - PLL is currently locked
+    // MSB
+  };
+} IMX_CCM_ANALOG_PLL_USB1_REG;
+
+typedef enum {
+    IMX_POST_DIV_SELECT_DIVIDE_4,
+    IMX_POST_DIV_SELECT_DIVIDE_2,
+    IMX_POST_DIV_SELECT_DIVIDE_1,
+} IMX_CCM_PLL_VIDEO_CTRL_POST_DIV_SELECT;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 DIV_SELECT : 7;          // 0-6 This field controls the PLL loop divider. Valid range for DIV_SELECT divider value: 27~54
+        UINT32 Reserved1 : 5;           // 7-11
+        UINT32 POWERDOWN : 1;           // 12 Powers down the PLL
+        UINT32 ENABLE : 1;              // 13 Enalbe PLL output
+        UINT32 BYPASS_CLK_SRC : 2;      // 14-15 Determines the bypass source
+        UINT32 BYPASS : 1;              // 16 Bypass the PLL
+        UINT32 Reserved2 : 1;           // 17
+        UINT32 PFD_OFFSET_EN : 1;       // 18 Enables an offset in the phase frequency detector
+        UINT32 POST_DIV_SELECT : 2;     // 19-20 These bits implement a divider after the PLL, but before the enable and bypass mux.
+        UINT32 Reserved3 : 1;           // 21
+        UINT32 Reserved4 : 9;           // 22-30 Always set to zero
+        UINT32 LOCK : 1;                // 31 PLL is/not currently locked
+        // MSB
+    };
+} IMX_CCM_PLL_VIDEO_CTRL_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 PFD0_FRAC : 6;               // 0-5 fractional divide value. The resulting frequency shall be 528*18/PFD0_FRAC where PFD0_FRAC is in the range 12-35.
+    UINT32 PFD0_STABLE : 1;             // 6
+    UINT32 PFD0_CLKGATE : 1;            // 7 Set to 1 to gate ref_pfd0
+    UINT32 PFD1_FRAC : 6;               // 8-13 fractional divide value
+    UINT32 PFD1_STABLE : 1;             // 14
+    UINT32 PFD1_CLKGATE : 1;            // 15 Set to 1 to gate ref_pfd1
+    UINT32 PFD2_FRAC : 6;               // 16-21 fractional divide value
+    UINT32 PFD2_STABLE : 1;             // 22
+    UINT32 PFD2_CLKGATE : 1;            // 23 Set to 1 to gate ref_pfd2
+    UINT32 PFD3_FRAC : 6;               // 24-29 fractional divide value
+    UINT32 PFD3_STABLE : 1;             // 30
+    UINT32 PFD3_CLKGATE : 1;            // 31 Set to 1 to gate ref_pfd3
+    // MSB
+  };
+} IMX_CCM_PFD_480_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 PFD0_FRAC : 6;               // 0-5 fractional divide value. The resulting frequency shall be 528*18/PFD0_FRAC where PFD0_FRAC is in the range 12-35.
+    UINT32 PFD0_STABLE : 1;             // 6
+    UINT32 PFD0_CLKGATE : 1;            // 7 Set to 1 to gate ref_pfd0
+    UINT32 PFD1_FRAC : 6;               // 8-13 fractional divide value
+    UINT32 PFD1_STABLE : 1;             // 14
+    UINT32 PFD1_CLKGATE : 1;            // 15 Set to 1 to gate ref_pfd1
+    UINT32 PFD2_FRAC : 6;               // 16-21 fractional divide value
+    UINT32 PFD2_STABLE : 1;             // 22
+    UINT32 PFD2_CLKGATE : 1;            // 23 Set to 1 to gate ref_pfd2
+    UINT32 reserved : 8;                // 24-31
+    // MSB
+  };
+} IMX_CCM_PFD_528_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 REG0_TARG : 5;               // 0-4 target voltage for the ARM core power domain
+    UINT32 reserved1 : 4;               // 5-8
+    UINT32 REG1_TARG : 5;               // 9-13 target voltage for the VPU/GPU power domain
+    UINT32 reserved2 : 4;               // 14-17
+    UINT32 REG2_TARG : 5;               // 18-22 target voltage for the SOC power domain
+    UINT32 reserved3 : 6;               // 23-28
+    UINT32 FET_ODRIVE : 1;              // 29 increases the gate drive on power gating FET
+    UINT32 reserved4 : 2;               // 30-31
+    // MSB
+  };
+} IMX_PMU_REG_CORE_REG;
+
+typedef enum {
+    PLL_ENET_DIV_SELECT_25MHZ = 0,
+    PLL_ENET_DIV_SELECT_50MHZ = 1,
+    PLL_ENET_DIV_SELECT_100MHZ = 2,
+    PLL_ENET_DIV_SELECT_125MHZ = 3,
+} CCM_ANALOG_PLL_ENET_DIV_SELECT;
+
+//
+// CCM ANALOG PLL Ethernet(n) register
+//
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        unsigned  DIV_SELECT : 2;       // 0-1
+        unsigned  Zero1 : 5;            // 2-6
+        unsigned  Reserved1 : 5;        // 7-11
+        unsigned  POWERDOWN : 1;        // 12
+        unsigned  ENABLE : 1;           // 13
+        unsigned  BYPASS_CLK_SRC : 2;   // 14-15
+        unsigned  BYPASS : 1;           // 16
+        unsigned  Reserved2 : 1;        // 17
+        unsigned  PFD_OFFSET_EN : 1;    // 18
+        unsigned  ENABLE_125M : 1;      // 19
+        unsigned  ENABLE_100M : 1;      // 20
+        unsigned  Zero2 : 10;           // 21-30
+        unsigned  LOCK : 1;             // 31
+        // MSB
+    };
+} IMX_CCM_ANALOG_PLL_ENET_REG;
+
+//
+// CCM ANALOG PLL Ethernet(n) register
+//
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        unsigned  LVDS1_CLK_SEL : 5;    // 0-4
+        unsigned  LVDS2_CLK_SEL : 5;    // 5-9
+        unsigned  LVDSCLK1_OBEN : 1;    // 10
+        unsigned  LVDSCLK2_OBEN : 1;    // 11
+        unsigned  LVDSCLK1_IBEN : 1;    // 12
+        unsigned  LVDSCLK2_IBEN : 1;    // 13
+        unsigned  Reserved0 : 15;       // 14-28
+        unsigned  IRQ_TEMPSENSE : 1;    // 29
+        unsigned  IRQ_ANA_BO : 1;       // 30
+        unsigned  IRQ_DIG_BO : 1;       // 31
+        // MSB
+    };
+} IMX_CCM_ANALOG_MISC1_REG;
+
+typedef struct {
+  UINT32 PLL_ARM;                       // 0x000 Analog ARM PLL control Register (CCM_ANALOG_PLL_ARM)
+  UINT32 PLL_ARM_SET;                   // 0x004 Analog ARM PLL control Register (CCM_ANALOG_PLL_ARM_SET)
+  UINT32 PLL_ARM_CLR;                   // 0x008 Analog ARM PLL control Register (CCM_ANALOG_PLL_ARM_CLR)
+  UINT32 PLL_ARM_TOG;                   // 0x00C Analog ARM PLL control Register (CCM_ANALOG_PLL_ARM_TOG)
+  UINT32 PLL_USB1;                      // 0x010 Analog USB1 480MHz PLL Control Register (CCM_ANALOG_PLL_USB1)
+  UINT32 PLL_USB1_SET;                  // 0x014 Analog USB1 480MHz PLL Control Register (CCM_ANALOG_PLL_USB1_SET)
+  UINT32 PLL_USB1_CLR;                  // 0x018 Analog USB1 480MHz PLL Control Register (CCM_ANALOG_PLL_USB1_CLR)
+  UINT32 PLL_USB1_TOG;                  // 0x01C Analog USB1 480MHz PLL Control Register (CCM_ANALOG_PLL_USB1_TOG)
+  UINT32 PLL_USB2;                      // 0x020 Analog USB2 480MHz PLL Control Register (CCM_ANALOG_PLL_USB2)
+  UINT32 PLL_USB2_SET;                  // 0x024 Analog USB2 480MHz PLL Control Register (CCM_ANALOG_PLL_USB2_SET)
+  UINT32 PLL_USB2_CLR;                  // 0x028 Analog USB2 480MHz PLL Control Register (CCM_ANALOG_PLL_USB2_CLR)
+  UINT32 PLL_USB2_TOG;                  // 0x02C Analog USB2 480MHz PLL Control Register (CCM_ANALOG_PLL_USB2_TOG)
+  UINT32 PLL_SYS;                       // 0x030 Analog System PLL Control Register (CCM_ANALOG_PLL_SYS)
+  UINT32 PLL_SYS_SET;                   // 0x034 Analog System PLL Control Register (CCM_ANALOG_PLL_SYS_SET)
+  UINT32 PLL_SYS_CLR;                   // 0x038 Analog System PLL Control Register (CCM_ANALOG_PLL_SYS_CLR)
+  UINT32 PLL_SYS_TOG;                   // 0x03C Analog System PLL Control Register (CCM_ANALOG_PLL_SYS_CLR)
+  UINT32 PLL_SYS_SS;                    // 0x040 528MHz System PLL Spread Spectrum Register (CCM_ANALOG_PLL_SYS_SS)
+  UINT32 reserved1[3];
+  UINT32 PLL_SYS_NUM;                   // 0x050 Numerator of 528MHz System PLL Fractional Loop Divider Register (CCM_ANALOG_PLL_SYS_NUM)
+  UINT32 reserved2[3];
+  UINT32 PLL_SYS_DENOM;                 // 0x060 Denominator of 528MHz System PLL Fractional Loop Divider Register (CCM_ANALOG_PLL_SYS_DENOM)
+  UINT32 reserved3[3];
+  UINT32 PLL_AUDIO;                     // 0x070 Analog Audio PLL control Register (CCM_ANALOG_PLL_AUDIO)
+  UINT32 PLL_AUDIO_SET;                 // 0x074 Analog Audio PLL control Register (CCM_ANALOG_PLL_AUDIO_SET)
+  UINT32 PLL_AUDIO_CLR;                 // 0x078 Analog Audio PLL control Register (CCM_ANALOG_PLL_AUDIO_CLR)
+  UINT32 PLL_AUDIO_TOG;                 // 0x07C Analog Audio PLL control Register (CCM_ANALOG_PLL_AUDIO_TOG)
+  UINT32 PLL_AUDIO_NUM;                 // 0x080 Numerator of Audio PLL Fractional Loop Divider Register (CCM_ANALOG_PLL_AUDIO_NUM)
+  UINT32 reserved4[3];
+  UINT32 PLL_AUDIO_DENOM;               // 0x090 Denominator of Audio PLL Fractional Loop Divider Register (CCM_ANALOG_PLL_AUDIO_DENOM)
+  UINT32 reserved5[3];
+  UINT32 PLL_VIDEO;                     // 0x0A0 Analog Video PLL control Register (CCM_ANALOG_PLL_VIDEO)
+  UINT32 PLL_VIDEO_SET;                 // 0x0A4 Analog Video PLL control Register (CCM_ANALOG_PLL_VIDEO_SET)
+  UINT32 PLL_VIDEO_CLR;                 // 0x0A8 Analog Video PLL control Register (CCM_ANALOG_PLL_VIDEO_CLR)
+  UINT32 PLL_VIDEO_TOG;                 // 0x0AC Analog Video PLL control Register (CCM_ANALOG_PLL_VIDEO_TOG)
+  UINT32 PLL_VIDEO_NUM;                 // 0x0B0 Numerator of Video PLL Fractional Loop Divider Register (CCM_ANALOG_PLL_VIDEO_NUM)
+  UINT32 reserved6[3];
+  UINT32 PLL_VIDEO_DENOM;               // 0x0C0 Denominator of Video PLL Fractional Loop Divider Register (CCM_ANALOG_PLL_VIDEO_DENOM)
+  UINT32 reserved7[3];
+  UINT32 PLL_MLB;                       // 0x0D0 MLB PLL Control Register (CCM_ANALOG_PLL_MLB)
+  UINT32 PLL_MLB_SET;                   // 0x0D4 MLB PLL Control Register (CCM_ANALOG_PLL_MLB_SET)
+  UINT32 PLL_MLB_CLR;                   // 0x0D8 MLB PLL Control Register (CCM_ANALOG_PLL_MLB_CLR)
+  UINT32 PLL_MLB_TOG;                   // 0x0DC MLB PLL Control Register (CCM_ANALOG_PLL_MLB_TOG)
+  UINT32 PLL_ENET;                      // 0x0E0 Analog ENET PLL Control Register (CCM_ANALOG_PLL_ENET)
+  UINT32 PLL_ENET_SET;                  // 0x0E4 Analog ENET PLL Control Register (CCM_ANALOG_PLL_ENET_SET)
+  UINT32 PLL_ENET_CLR;                  // 0x0E8 Analog ENET PLL Control Register (CCM_ANALOG_PLL_ENET_CLR)
+  UINT32 PLL_ENET_TOG;                  // 0x0EC Analog ENET PLL Control Register (CCM_ANALOG_PLL_ENET_TOG)
+  UINT32 PFD_480;                       // 0x0F0 480MHz Clock (PLL3) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_480)
+  UINT32 PFD_480_SET;                   // 0x0F4 480MHz Clock (PLL3) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_480_SET)
+  UINT32 PFD_480_CLR;                   // 0x0F8 480MHz Clock (PLL3) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_480_CLR)
+  UINT32 PFD_480_TOG;                   // 0x0FC 480MHz Clock (PLL3) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_480_TOG)
+  UINT32 PFD_528;                       // 0x100 528MHz Clock (PLL2) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_528)
+  UINT32 PFD_528_SET;                   // 0x104 528MHz Clock (PLL2) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_528_SET)
+  UINT32 PFD_528_CLR;                   // 0x108 528MHz Clock (PLL2) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_528_CLR)
+  UINT32 PFD_528_TOG;                   // 0x10C 528MHz Clock (PLL2) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_528_TOG)
+  UINT32 PMU_REG_1P1;                   // 0x110 Regulator 1P1 Register (PMU_REG_1P1)
+  UINT32 PMU_REG_1P1_SET;               // 0x114
+  UINT32 PMU_REG_1P1_CLR;               // 0x118
+  UINT32 PMU_REG_1P1_TOG;               // 0x11C
+  UINT32 PMU_REG_3P0;                   // 0X120 Regulator 3P0 Register (PMU_REG_3P0)
+  UINT32 PMU_REG_3P0_SET;               // 0x124
+  UINT32 PMU_REG_3P0_CLR;               // 0x128
+  UINT32 PMU_REG_3P0_TOG;               // 0x12C
+  UINT32 PMU_REG_2P5;                   // 0x130 Regulator 2P5 Register (PMU_REG_2P5)
+  UINT32 PMU_REG_2P5_SET;               // 0x134
+  UINT32 PMU_REG_2P5_CLR;               // 0x138
+  UINT32 PMU_REG_2P5_TOG;               // 0x13C
+  UINT32 PMU_REG_CORE;                  // 0x140 Digital Regulator Core Register (PMU_REG_CORE)
+  UINT32 PMU_REG_CORE_SET;              // 0x144
+  UINT32 PMU_REG_CORE_CLR;              // 0x148
+  UINT32 PMU_REG_CORE_TOG;              // 0x14C
+  UINT32 MISC0;                         // 0x150 Miscellaneous Register 0 (CCM_ANALOG_MISC0)
+  UINT32 MISC0_SET;                     // 0x154 Miscellaneous Register 0 (CCM_ANALOG_MISC0_SET)
+  UINT32 MISC0_CLR;                     // 0x158 Miscellaneous Register 0 (CCM_ANALOG_MISC0_CLR)
+  UINT32 MISC0_TOG;                     // 0x15C Miscellaneous Register 0 (CCM_ANALOG_MISC0_TOG)
+  UINT32 MISC1;                         // 0x160 Miscellaneous Register 1 (CCM_ANALOG_MISC1)
+  UINT32 MISC1_SET;                     // 0x164 Miscellaneous Register 1 (CCM_ANALOG_MISC1_SET)
+  UINT32 MISC1_CLR;                     // 0x168 Miscellaneous Register 1 (CCM_ANALOG_MISC1_CLR)
+  UINT32 MISC1_TOG;                     // 0x16C Miscellaneous Register 1 (CCM_ANALOG_MISC1_TOG)
+  UINT32 MISC2;                         // 0x170 Miscellaneous Register 2 (CCM_ANALOG_MISC2)
+  UINT32 MISC2_SET;                     // 0x174 Miscellaneous Register 2 (CCM_ANALOG_MISC2_SET)
+  UINT32 MISC2_CLR;                     // 0x178 Miscellaneous Register 2 (CCM_ANALOG_MISC2_CLR)
+  UINT32 MISC2_TOG;                     // 0x17C Miscellaneous Register 2 (CCM_ANALOG_MISC2_TOG)
+} IMX_CCM_ANALOG_REGISTERS;
+
+//
+// General Power Controller (GPC)
+//
+
+#define IMX_GPC_BASE 0x020DC000
+#define IMX_GPC_LENGTH 0x1000
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 PCR : 1;                     // 0 Power Control
+    UINT32 reserved : 31;               // 1-31
+    // MSB
+  };
+} IMX_GPC_PGC_PGCR_REG;
+
+#define IMX_GPC_PGC_PUPSCR_SW_DEFAULT 1
+#define IMX_GPC_PGC_PUPSCR_SW2ISO_DEFAULT 0xf
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 SW : 6;                      // 0-5 number of IPG clock cycles before asserting power toggle on/off signal (switch_b)
+    UINT32 reserved1 : 2;               // 6-7
+    UINT32 SW2ISO : 6;                  // 8-13 IPG clock cycles before negating isolation
+    UINT32 reserved2 : 18;              // 14-31
+    // MSB
+  };
+} IMX_GPC_PGC_PUPSCR_REG;
+
+#define IMX_GPC_PGC_PDNSCR_ISO_DEFAULT 1
+#define IMX_GPC_PGC_PDNSCR_ISO2SW_DEFAULT 1
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 ISO : 6;                     // 0-5 number of IPG clocks before isolation
+    UINT32 reserved1 : 2;               // 6-7
+    UINT32 ISO2SW : 6;                  // 8-13 number of IPG clocks before negating power toggle on/off signal (switch_b)
+    UINT32 reserved2 : 18;              // 14-31
+    // MSB
+  };
+} IMX_GPC_PGC_PDNSCR_REG;
+
+typedef struct {
+  UINT32 CTRL;                          // 0x0 PGC Control Register (PGC_GPU/CPU_CTRL)
+  UINT32 PUPSCR;                        // 0x4 Power Up Sequence Control Register (PGC_GPU/CPU_PUPSCR)
+  UINT32 PDNSCR;                        // 0x8 Pull Down Sequence Control Register (PGC_GPU/CPU_PDNSCR)
+  UINT32 SR;                            // 0xC Power Gating Controller Status Register (PGC_GPU/CPU_SR)
+} IMX_GPC_PGC_REGISTERS;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 gpu_vpu_pdn_req : 1;         // 0 GPU/VPU Power Down request. Self-cleared bit.
+    UINT32 gpu_vpu_pup_req : 1;         // 1 GPU/VPU Power Up request. Self-cleared bit.
+    UINT32 reserved1 : 14;              // 2-15
+    UINT32 DVFS0CR : 1;                 // 16 DVFS0 (ARM) Change request (bit is read-only)
+    UINT32 reserved2 : 4;               // 17-20
+    UINT32 GPCIRQM : 1;                 // 21 GPC interrupt/event masking
+    UINT32 reserved3 : 10;              // 22-31
+    // MSB
+  };
+} IMX_GPC_CNTR_REG;
+
+typedef struct {
+  UINT32 CNTR;                          // 0x000 GPC Interface control register (GPC_CNTR)
+  UINT32 PGR;                           // 0x004 GPC Power Gating Register (GPC_PGR)
+  UINT32 IMR1;                          // 0x008 IRQ masking register 1 (GPC_IMR1)
+  UINT32 IMR2;                          // 0x00C IRQ masking register 2 (GPC_IMR2)
+  UINT32 IMR3;                          // 0x010 IRQ masking register 3 (GPC_IMR3)
+  UINT32 IMR4;                          // 0x014 IRQ masking register 4 (GPC_IMR4)
+  UINT32 ISR1;                          // 0x018 IRQ status resister 1 (GPC_ISR1)
+  UINT32 ISR2;                          // 0x01C IRQ status resister 2 (GPC_ISR2)
+  UINT32 ISR3;                          // 0x020 IRQ status resister 3 (GPC_ISR3)
+  UINT32 ISR4;                          // 0x024 IRQ status resister 4 (GPC_ISR4)
+  UINT32 reserved1[142];
+  IMX_GPC_PGC_REGISTERS PGC_GPU;        // 0x260-0x26C GPU PGC Control
+  UINT32 reserved2[12];
+  IMX_GPC_PGC_REGISTERS PGC_CPU;        // 0x2A0-0x2AC CPU PGC Control
+} IMX_GPC_REGISTERS;
+
+//
+// Ethernet controller (ENET)
+//
+
+#define IMX_ENET_BASE 0x02188000
+#define IMX_ENET_LENGTH 0x4000
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 RESET : 1;                   // 0 Ethernet MAC Reset
+    UINT32 ETHEREN : 1;                 // 1 Ethernet Enable
+    UINT32 MAGICEN : 1;                 // 2 Magic Packet Detection Enable
+    UINT32 SLEEP : 1;                   // 3 Sleep Mode Enable
+    UINT32 EN1588 : 1;                  // 4 EN1588 Enable
+    UINT32 SPEED : 1;                   // 5 Selects between 10/100 and 1000 Mbps modes of operation
+    UINT32 DBGEN : 1;                   // 6 Debug Enable
+    UINT32 STOPEN : 1;                  // 7 STOPEN Signal Control
+    UINT32 DBSWP : 1;                   // 8 Descriptor Byte Swapping Enable
+    UINT32 reserved1 : 3;               // 9-11
+    UINT32 reserved2 : 20;              // 12-31 This field must be set to F_0000h
+    // MSB
+  };
+} IMX_ENET_ECR_REG;
+
+typedef struct {
+  UINT32 reserved0;     // 0
+  UINT32 EIR;           // 4
+  UINT32 EIMR;          // 8
+  UINT32 reserved1;     // Ch
+  UINT32 RDAR;          // 10h
+  UINT32 TDAR;          // 14h
+  UINT32 reserved2[3];  // 18h - 20h
+  UINT32 ECR;           // 24h Ethernet Control Register (ENET_ECR)
+  UINT32 reserved3[6];  // 28h - 3Ch
+  UINT32 MMFR;          // 40h
+  UINT32 MSCR;          // 44h
+  UINT32 reserved4[7];  // 48h - 60h
+  UINT32 MIBC;          // 64h
+  UINT32 reserved5[7];  //
+  UINT32 RCR;           // 84h
+  UINT32 reserved6[15]; //
+  UINT32 TCR;           // C4h
+  UINT32 reserved7[7];
+  UINT32 PALR;          // E4h
+  UINT32 PAUR;          // E8h
+  UINT32 OPD;           // ECh
+  UINT32 reserved8[322];
+} IMX_ENET_REGISTERS;
+
+//
+// GPIO Controller (GPIO)
+//
+
+#define IMX_GPIO_BASE 0x0209C000
+#define IMX_GPIO_LENGTH (7 * 0x4000)
+
+//
+// USB CORE (EHCI)
+//
+
+#define IMX_USBCORE_BASE    0x02184000
+#define IMX_USBCORE_LENGTH  0x200
+#define IMX_USBCMD_OFFSET   0x140
+#define IMX_USBMODE_OFFSET  0x1A8
+
+//
+// To do:
+// - Add the USB Core register file
+//
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 RS : 1;          // 0 Run/Stop (RS) . Read/Write. Default 0b. 1=Run. 0=Stop.
+        UINT32 RST : 1;         // 1 Controller Reset (RESET) - Read/Write.
+        UINT32 FS_1 : 2;        // 2-3 Frame List Size (Read/Write or Read Only). Default 000b.
+        UINT32 PSE : 1;         // 4 Periodic Schedule Enable- Read/Write. Default 0b.
+        UINT32 ASE : 1;         // 5 Asynchronous Schedule Enable Read/Write. Default 0b.
+        UINT32 IAA : 1;         // 6 Interrupt on Async Advance Doorbell Read/Write.
+        UINT32 reserved1 : 1;   // 7
+        UINT32 ASP : 2;         // 8-9 Asynchronous Schedule Park Mode Count (OPTIONAL) . Read/Write.
+        UINT32 reserved2 : 1;   // 10 Reserved. These bits are reserved and should be set to zero.
+        UINT32 ASPE : 1;        // 11 Asynchronous Schedule Park Mode Enable (OPTIONAL) . Read/Write.
+        UINT32 ATDTW : 1;       // 12 Add dTD TripWire C Read/Write. [device mode only]
+        UINT32 SUTW : 1;        // 13 Setup TripWire C Read/Write. [device mode only]
+        UINT32 reserved3 : 1;   // 14
+        UINT32 FS2 : 1;         // 15 Frame List Size - (Read/Write or Read Only). [host mode only]
+        UINT32 ITC : 8;         // 16-23 Interrupt Threshold Control Read/Write. Default 08h.
+        UINT32 reserved : 8;    // 24-31 Reserved. These bits are reserved and should be set to zero.
+        // LSB
+    };
+} USB_USBCMD_REG;
+
+typedef enum {
+    IMX_USBMODE_IDLE = 0,
+    IMX_USBMODE_DEVICE = 2,
+    IMX_USBMODE_HOST = 3,
+} IMX_USBMODE_CM;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 CM : 2;          // 0-1 Controller Mode.
+        UINT32 ES : 1;          // 1 Endian Select (0- Little, 1-Big)
+        UINT32 SLOM : 1;        // 3 Setup Lockout Mode
+        UINT32 SDIS : 1;        // 4 Stream Disable Mode
+        UINT32 reserved : 26;   // 5-31
+        // LSB
+    };
+} USB_USBMODE_REG;
+
+//
+// USB Non-CORE
+//
+
+#define IMX_USBNONCORE_BASE 0x02184800
+#define IMX_USBNONCORE_LENGTH 0x20
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 reserved1 : 7;       // 0-6
+        UINT32 OVER_CUR_DIS : 1;    // 7 Disable Overcurrent Detection
+        UINT32 OVER_CUR_POL : 1;    // 8 Polarity of Overcurrent (1-active low, 0-active high)
+        UINT32 PWR_POL : 1;         // 9 Power Polarity (1-active high, 0-active low)
+        UINT32 WIE : 1;             // 10 Wake-up Interrupt Enable
+        UINT32 RESET : 1;           // 11 Force Host 1 UTMI PHY Reset.
+        UINT32 SUSPENDM : 1;        // 12 Force Host 1 UTMI PHY Suspend.
+        UINT32 UTMI_ON_CLOCK : 1;   // 13 Force UTMI PHY clock output on even if in low-power suspend mode.
+        UINT32 WKUP_SW_EN : 1;      // 14 Software Wake-up Enable
+        UINT32 WKUP_SW : 1;         // 15 Software Wake-up
+        UINT32 WKUP_ID_EN : 1;      // 16 Wake-up on ID change enable
+        UINT32 WKUP_VBUS_EN : 1;    // 17 wake-up on VBUS change enable
+        UINT32 reserved2 : 13;      // 18-30
+        UINT32 WIR : 1;             // 31 Wake-up Interrupt Request
+        // LSB
+    };
+} USBNC_USB_UH_CTRL_REG;
+
+typedef struct {
+    UINT32 USBNC_USB_OTG_CTRL;          // 0x00 USB OTG Control Register (USBNC_USB_OTG_CTRL)
+    UINT32 USBNC_USB_UH1_CTRL;          // 0x04 USB Host1 Control Register (USBNC_USB_UH1_CTRL)
+    UINT32 USBNC_USB_UH2_CTRL;          // 0x08 USB Host2 Control Register (USBNC_USB_UH2_CTRL)
+    UINT32 USBNC_USB_UH3_CTRL;          // 0x0C USB Host3 Control Register (USBNC_USB_UH3_CTRL)
+    UINT32 USBNC_USB_UH2_HSIC_CTRL;     // 0x10 USB Host2 HSIC Control Register (USBNC_USB_UH2_HSIC_CTRL)
+    UINT32 USBNC_USB_UH3_HSIC_CTRL;     // 0x14 USB Host3 HSIC Control Register (USBNC_USB_UH3_HSIC_CTRL)
+    UINT32 USBNC_USB_OTG_PHY_CTRL_0;    // 0x18 OTG UTMI PHY Control 0 Register (USBNC_USB_OTG_PHY_CTRL_0)
+    UINT32 USBNC_USB_UH1_PHY_CTRL_0;    // 0x1C Host1 UTMI PHY Control 0 Register (USBNC_USB_UH1_PHY_CTRL_0)
+} IMX_USBNONCORE_REGISTERS;
+
+
+//
+// USB PHY
+//
+
+#define IMX_USBPHY1_BASE 0x020C9000
+#define IMX_USBPHY2_BASE 0x020CA000
+#define IMX_USBPHY_LENGTH 0x1000
+
+typedef enum {
+    IMX_USBPHY0, // OTG
+    IMX_USBPHY1,
+
+    IMX_USBPHY_COUNT
+} IMX_USBPHY_ID;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 ENOTG_ID_CHG_IRQ : 1;        // 0 Enable OTG_ID_CHG_IRQ.
+        UINT32 ENHOSTDISCONDETECT : 1;      // 1 For host mode, enables high-speed disconnect detector.
+        UINT32 ENIRQHOSTDISCON : 1;         // 2 Enables interrupt for detection of disconnection to Device when in high-speed host mode.
+        UINT32 HOSTDISCONDETECT_IRQ : 1;    // 3 Indicates that the device has disconnected in high-speed mode.
+        UINT32 ENDEVPLUGINDETECT : 1;       // 4 For device mode, enables 200-KOhm pullups for detecting connectivity to the host.
+        UINT32 DEVPLUGIN_POLARITY : 1;      // 5 For device mode interrupt generation polarity
+        UINT32 OTG_ID_CHG_IRQ : 1;          // 6 OTG ID change interrupt. Indicates the value of ID pin changed.
+        UINT32 ENOTGIDDETECT : 1;           // 7 Enables circuit to detect resistance of MiniAB ID pin.
+        UINT32 RESUMEIRQSTICKY : 1;         // 8 1 makes RESUME_IRQ bit a sticky bit.
+        UINT32 ENIRQRESUMEDETECT : 1;       // 9 Enables interrupt for detection of a non-J state on the USB line.
+        UINT32 RESUME_IRQ : 1;              // 10 Indicates that the host is sending a wake-up after suspend
+        UINT32 ENIRQDEVPLUGIN : 1;          // 11 Enables interrupt for the detection of connectivity to the USB line.
+        UINT32 DEVPLUGIN_IRQ : 1;           // 12 Indicates that the device is connected
+        UINT32 DATA_ON_LRADC : 1;           // 13 Enables the LRADC to monitor USB_DP and USB_DM.
+        UINT32 ENUTMILEVEL2 : 1;            // 14 Enables UTMI+ Level2.
+        UINT32 ENUTMILEVEL3 : 1;            // 15 Enables UTMI+ Level3.
+        UINT32 ENIRQWAKEUP : 1;             // 16 Enables interrupt for the wakeup events
+        UINT32 WAKEUP_IRQ : 1;              // 17 Indicates that there is a wakeup event.
+        UINT32 reserved1 : 1;               // 18 reserved
+        UINT32 ENAUTOCLR_CLKGATE : 1;       // 19 Enables the feature to auto-clear the CLKGATE bit if there is wakeup event while USB is suspended.
+        UINT32 ENAUTOCLR_PHY_PWD : 1;       // 20 Enables the feature to auto-clear the PWD register bits in USBPHYx_PWD if there is wakeup event while USB is suspended
+        UINT32 ENDPDMCHG_WKUP : 1;          // 21 Enables the feature to wakeup USB if DP/DM is toggled when USB is suspended
+        UINT32 ENIDCHG_WKUP : 1;            // 22 Enables the feature to wakeup USB if ID is toggled when USB is suspended
+        UINT32 ENVBUSCHG_WKUP : 1;          // 23 Enables the feature to wakeup USB if VBUS is toggled when USB is suspended.
+        UINT32 FSDLL_RST_EN : 1;            // 24 Enables the feature to reset the FSDLL lock detection logic at the end of each TX packet.
+        UINT32 reserved2 : 2;               // 25-26
+        UINT32 OTG_ID_VALUE : 1;            // 27
+        UINT32 HOST_FORCE_LS_SE0 : 1;       // 28 Forces the next FS packet that is transmitted to have a EOP with LS timing.
+        UINT32 UTMI_SUSPENDM : 1;           // 29 Used by the PHY to indicate a powered-down state.
+        UINT32 CLKGATE : 1;                 // 30 Gate UTMI Clocks. Clear to 0 to run clocks.
+        UINT32 SFTRST : 1;                  // 31 Soft-reset the USBPHYx_PWD, USBPHYx_TX, USBPHYx_RX, Set to 0 to release the PHY from reset.
+        // MSB
+    };
+} USBPHYx_CTRL_REG;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 STEP : 16;   // 0-15 Fixed read-only value reflecting the stepping of the RTL version.
+        UINT32 MINOR : 8;   // 16-23 Fixed read-only value reflecting the MINOR field of the RTL version.
+        UINT32 MAJOR : 8;   // 24-31 Fixed read-only value reflecting the MAJOR field of the RTL version
+        // MSB
+    };
+} USBPHYx_VERSION_REG;
+
+typedef struct {
+    UINT32 USBPHY_PWD;             // 0x00 USB PHY Power-Down Register (USBPHY_PWD)
+    UINT32 USBPHY_PWD_SET;         // 0x04 USB PHY Power-Down Register (USBPHY_PWD_SET)
+    UINT32 USBPHY_PWD_CLR;         // 0x08 USB PHY Power-Down Register (USBPHY_PWD_CLR)
+    UINT32 USBPHY_PWD_TOG;         // 0x0C USB PHY Power-Down Register (USBPHY_PWD_TOG)
+    UINT32 USBPHY_TX;              // 0x10 USB PHY Transmitter Control Register (USBPHY_TX)
+    UINT32 USBPHY_TX_SET;          // 0x14 USB PHY Transmitter Control Register (USBPHY_TX_SET)
+    UINT32 USBPHY_TX_CLR;          // 0x18 USB PHY Transmitter Control Register (USBPHY_TX_CLR)
+    UINT32 USBPHY_TX_TOG;          // 0x1C USB PHY Transmitter Control Register (USBPHY_TX_TOG)
+    UINT32 USBPHY_RX;              // 0x20 USB PHY Receiver Control Register (USBPHY_RX)
+    UINT32 USBPHY_RX_SET;          // 0x24 USB PHY Receiver Control Register(USBPHY_RX_SET)
+    UINT32 USBPHY_RX_CLR;          // 0x28 USB PHY Receiver Control Register (USBPHY_RX_CLR)
+    UINT32 USBPHY_RX_TOG;          // 0x2C USB PHY Receiver Control Register (USBPHY_RX_TOG)
+    UINT32 USBPHY_CTRL;            // 0x30 USB PHY General Control Register (USBPHY_CTRL)
+    UINT32 USBPHY_CTRL_SET;        // 0x34 USB PHY General Control Register (USBPHY_CTRL_SET)
+    UINT32 USBPHY_CTRL_CLR;        // 0x38 USB PHY General Control Register (USBPHY_CTRL_CLR)
+    UINT32 USBPHY_CTRL_TOG;        // 0x3C USB PHY General Control Register (USBPHY_CTRL_TOG)
+    UINT32 USBPHY_STATUS;          // 0x40 USB PHY Status Register (USBPHY_STATUS)
+    UINT32 reserved1[3];
+    UINT32 USBPHY_DEBUG;           // 0x50 USB PHY Debug Register (USBPHY_DEBUG)
+    UINT32 USBPHY_DEBUG_SET;       // 0x54 USB PHY Debug Register(USBPHY_DEBUG_SET)
+    UINT32 USBPHY_DEBUG_CLR;       // 0x58 USB PHY Debug Register (USBPHY_DEBUG_CLR)
+    UINT32 USBPHY_DEBUG_TOG;       // 0x5C USB PHY Debug Register(USBPHY_DEBUG_TOG)
+    UINT32 USBPHY_DEBUG0_STATUS;   // 0x60 UTMI Debug Status Register 0 (USBPHY_DEBUG0_STATUS)
+    UINT32 reserved2[3];
+    UINT32 USBPHY_DEBUG1;          // 0x70 UTMI Debug Status Register 1 (USBPHY_DEBUG1)
+    UINT32 USBPHY_DEBUG1_SET;      // 0x74 UTMI Debug Status Register 1 (USBPHY_DEBUG1_SET)
+    UINT32 USBPHY_DEBUG1_CLR;      // 0x78 UTMI Debug Status Register 1 (USBPHY_DEBUG1_CLR)
+    UINT32 USBPHY_DEBUG1_TOG;      // 0x7C UTMI Debug Status Register 1 (USBPHY_DEBUG1_TOG)
+    UINT32 USBPHY_VERSION;         // 0x80 UTMI RTL Version (USBPHYx_VERSION)
+} IMX_USBPHY_REGISTERS;
+
+//
+// USB Analog
+//
+
+#define IMX_USBANA_BASE 0x020C81A0
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 reserved1 : 18;  // 0-17
+        UINT32 CHK_CONTACT : 1; // 18
+        UINT32 CHK_CHRG_B : 1;  // 19
+        UINT32 EN_B : 1;        // 20
+        UINT32 reserved2 : 11;  // 21-31
+        // MSB
+    };
+} USB_ANALOG_USB_CHRG_DETECT_REG;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 HS_USE_EXTERNAL_R : 1;  // 0 Use external resistor to generate the current bias for the high speed transmitter.
+        UINT32 EN_DEGLITCH : 1;        // 1 Enable the deglitching circuit of the USB PLL output.
+        UINT32 reserved1 : 28;         // 2-29
+        UINT32 EN_CLK_UTMI : 1;        // Enables the clk to the UTMI block.
+        UINT32 reserved2 : 1;          // 31
+        // MSB
+    };
+} USB_ANALOG_USB_MISC_REG;
+
+typedef struct {
+    UINT32 USB_ANALOG_USB_VBUS_DETECT;       // 0x00 USB VBUS Detect Register (USB_ANALOG_USB_VBUS_DETECT)
+    UINT32 USB_ANALOG_USB_VBUS_DETECT_SET;   // 0x04 USB VBUS Detect Register (USB_ANALOG_USB_VBUS_DETECT_SET)
+    UINT32 USB_ANALOG_USB_VBUS_DETECT_CLR;   // 0x08 USB VBUS Detect Register (USB_ANALOG_USB_VBUS_DETECT_CLR)
+    UINT32 USB_ANALOG_USB_VBUS_DETECT_TOG;   // 0x0C USB VBUS Detect Register (USB_ANALOG_USB_VBUS_DETECT_TOG)
+    UINT32 USB_ANALOG_USB_CHRG_DETECT;       // 0x10 USB Charger Detect Register (USB_ANALOG_USB_CHRG_DETECT)
+    UINT32 USB_ANALOG_USB_CHRG_DETECT_SET;   // 0x14 USB Charger Detect Register (USB_ANALOG_USB_CHRG_DETECT_SET)
+    UINT32 USB_ANALOG_USB_CHRG_DETECT_CLR;   // 0x18 USB Charger Detect Register (USB_ANALOG_USB_CHRG_DETECT_CLR)
+    UINT32 USB_ANALOG_USB_CHRG_DETECT_TOG;   // 0x1C USB Charger Detect Register (USB_ANALOG_USB_CHRG_DETECT_TOG)
+    UINT32 USB_ANALOG_USB_VBUS_DETECT_STAT;  // 0x20 USB VBUS Detect Status Register (USB_ANALOG_USB_VBUS_DETECT_STAT)
+    UINT32 reserved1[3];
+    UINT32 USB_ANALOG_USB_CHRG_DETECT_STAT;  // 0x30 USB Charger Detect Status Register (USB_ANALOG_USB_CHRG_DETECT_STAT)
+    UINT32 reserved2[7];
+    UINT32 USB_ANALOG_USB_MISC;              // 0x50 USB Misc Register (USB_ANALOG_USB_MISC)
+    UINT32 USB_ANALOG_USB_MISC_SET;          // 0x54 USB Misc Register (USB_ANALOG_USB_MISC_SET)
+    UINT32 USB_ANALOG_USB_MISC_CLR;          // 0x58 USB Misc Register (USB_ANALOG_USB_MISC_CLR)
+    UINT32 USB_ANALOG_USB_MISC_TOG;          // 0x5C USB Misc Register (USB_ANALOG_USB_MISC_TOG)
+} IMX_USBANA_USB_REGISTERS;
+
+typedef struct {
+    IMX_USBANA_USB_REGISTERS USBANA[IMX_USBPHY_COUNT];
+    UINT32 USB_ANALOG_DIGPROG;                // 0xC0 Chip Silicon Version (USB_ANALOG_DIGPROG)
+} IMX_USBANA_REGISTERS;
+
+#pragma pack(pop)
+
+#endif // __IMX6_SDL_H__
diff --git a/Silicon/NXP/iMX6Pkg/Include/iMX6_SX.h b/Silicon/NXP/iMX6Pkg/Include/iMX6_SX.h
new file mode 100644
index 000000000000..5438e9915344
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Include/iMX6_SX.h
@@ -0,0 +1,1762 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __IMX6_SX_H__
+#define __IMX6_SX_H__
+
+#pragma pack(push, 1)
+
+// DDR attributes
+#define DDR_ATTRIBUTES_CACHED               ARM_MEMORY_REGION_ATTRIBUTE_WRITE_BACK
+#define DDR_ATTRIBUTES_UNCACHED             ARM_MEMORY_REGION_ATTRIBUTE_UNCACHED_UNBUFFERED
+
+// Boot DRAM region (kernel.img & boot working DRAM)
+#define FRAME_BUFFER_BASE                   0x821D4000
+#define FRAME_BUFFER_SIZE                   0x00800000 // 8MB
+
+#define BOOT_IMAGE_PHYSICAL_BASE            0x82004000
+#define BOOT_IMAGE_PHYSICAL_LENGTH          0x001D0000 // 1MB
+#define BOOT_IMAGE_ATTRIBUTES               CacheAttributes
+
+// The region of registers from 0x00100000 to 0x02300000
+#define SOC_REGISTERS_PHYSICAL_BASE1        0x00100000
+#define SOC_REGISTERS_PHYSICAL_LENGTH1      0x02200000
+#define SOC_REGISTERS_ATTRIBUTES            ARM_MEMORY_REGION_ATTRIBUTE_DEVICE
+
+// PCIE registers and configuration space (0x08000000 - 0x09000000)
+#define PCIE_REGISTERS_PHYSICAL_BASE        0x08000000
+#define PCIE_REGISTERS_PHYSICAL_LENGTH      0x01000000
+
+// The region of registers from 0x0C000000 to 0x80000000
+#define SOC_REGISTERS_PHYSICAL_BASE2        0x0C000000
+#define SOC_REGISTERS_PHYSICAL_LENGTH2      0x74000000
+
+// Main system DRAM as defined by the PCD definitions of system memory.
+
+// MPPP definitions
+#define CPU0_MPPP_PHYSICAL_BASE            0x8080F000
+
+// Interrupt controller
+#define CSP_BASE_REG_PA_IC_IFC              0x00A00100
+#define CSP_BASE_REG_PA_IC_DIST             0x00A01000
+
+// L2 cache controller
+#define CSP_BASE_REG_PA_PL310               0x00A02000
+
+// Timers
+#define CSP_BASE_REG_PA_GPT                 0x02098000
+#define CSP_BASE_REG_PA_EPIT1               0x020D0000
+#define CSP_BASE_REG_PA_EPIT2               0x020D4000
+
+// Timers IRQs
+#define IC_DIST_VECTOR_BASE 0
+#define IRQ_EPIT1           88
+#define IRQ_EPIT2           89
+
+// SDMA (Smart DMA) controller
+#define CSP_BASE_REG_PA_SDMA                0x020EC000
+#define IRQ_SDMA 34
+
+// SOC peripherals
+#define CSP_BASE_REG_PA_UART1               0x02020000
+#define CSP_BASE_REG_PA_UART2               0x021e8000
+#define CSP_BASE_REG_PA_UART3               0x021EC000
+#define CSP_BASE_REG_PA_UART4               0x021F0000
+#define CSP_BASE_REG_PA_UART5               0x021F4000
+#define CSP_BASE_REG_PA_ESDHC2              0x02194000
+#define CSP_BASE_REG_PA_ESDHC3              0x02198000
+
+#define DBG_PORT_SUBTYPE_IMX6   0x000C
+
+// Timers clock sources
+#define SOC_OSC_FREQUENCY_REF_HZ  24000000  // Oscillator frequency 24Mhz
+#define SOC_HIGH_FREQUENCY_REF_HZ 66000000  // High Frequency reference clock 66Mhz
+#define SOC_LOW_FREQ_REF_HZ       32768     // SNVS RTC frequency 32kHz
+
+// GPU Definitions
+#define IMX_GPU_CORE_CLK_MAX 540000000 // 540 Mhz NEW UNUSED SX RM.p790, Mirroring GPU Constants for DQ
+
+//
+// IOMUX Controller (IOMUXC)
+//
+
+#define IMX_IOMUXC_BASE 0x020E0000
+#define IMX_IOMUXC_LENGTH 0x4000
+
+//
+// Secure Nonvolatile Storage (SNVS)
+//
+
+#define IMX_SNVS_BASE 0x020CC000
+#define IMX_SNVS_LENGTH 0x4000
+#define IMX_SNVS_IP_ID 0x3E
+#define IMX_SNVS_IRQ 51         // SNVS consolidated interrupt
+
+//
+// IOMUXC Registers
+//
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL0      0x020E00A4
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL1      0x020E00A8
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL2      0x020E00AC
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL3      0x020E00B0
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_COL4      0x020E00B4
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW0      0x020E00B8
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW1      0x020E00BC
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW2      0x020E00C0
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW3      0x020E00C4
+#define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW4      0x020E00C8
+
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_COL0      0x020E03EC
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_COL1      0x020E03F0
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_COL2      0x020E03F4
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_COL3      0x020E03F8
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_COL4      0x020E03FC
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_ROW0      0x020E0400
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_ROW1      0x020E0404
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_ROW2      0x020E0408
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_ROW3      0x020E040C
+#define IOMUXC_SW_PAD_CTL_PAD_KEY_ROW4      0x020E0410
+
+// define base address of Select Input registers to be one word
+// less than the minimum value so that a valid Select Input value
+// is non-zero. (IOMUXC_SW_PAD_CTL_GRP_B3DS)
+#define IOMUXC_SELECT_INPUT_BASE_ADDRESS 0x20E0620
+
+typedef enum {
+   IOMUXC_ANATOP_USB_OTG_ID_SELECT_INPUT = 0x20E0624,
+   IOMUXC_ANATOP_USB_UH1_ID_SELECT_INPUT = 0x20E0628,
+   IOMUXC_AUDMUX_P3_INPUT_DA_AMX_SELECT_INPUT = 0x20E062C,
+   IOMUXC_AUDMUX_P3_INPUT_DB_AMX_SELECT_INPUT = 0x20E0630,
+   IOMUXC_AUDMUX_P3_INPUT_RXCLK_AMX_SELECT_INPUT = 0x20E0634,
+   IOMUXC_AUDMUX_P3_INPUT_RXFS_AMX_SELECT_INPUT = 0x20E0638,
+   IOMUXC_AUDMUX_P3_INPUT_TXCLK_AMX_SELECT_INPUT = 0x20E063C,
+   IOMUXC_AUDMUX_P3_INPUT_TXFS_AMX_SELECT_INPUT = 0x20E0640,
+   IOMUXC_AUDMUX_P4_INPUT_DA_AMX_SELECT_INPUT = 0x20E0644,
+   IOMUXC_AUDMUX_P4_INPUT_DB_AMX_SELECT_INPUT = 0x20E0648,
+   IOMUXC_AUDMUX_P4_INPUT_RXCLK_AMX_SELECT_INPUT = 0x20E064C,
+   IOMUXC_AUDMUX_P4_INPUT_RXFS_AMX_SELECT_INPUT = 0x20E0650,
+   IOMUXC_AUDMUX_P4_INPUT_TXCLK_AMX_SELECT_INPUT = 0x20E0654,
+   IOMUXC_AUDMUX_P4_INPUT_TXFS_AMX_SELECT_INPUT = 0x20E0658,
+   IOMUXC_AUDMUX_P5_INPUT_DA_AMX_SELECT_INPUT = 0x20E065C,
+   IOMUXC_AUDMUX_P5_INPUT_DB_AMX_SELECT_INPUT = 0x20E0660,
+   IOMUXC_AUDMUX_P5_INPUT_RXCLK_AMX_SELECT_INPUT = 0x20E0664,
+   IOMUXC_AUDMUX_P5_INPUT_RXFS_AMX_SELECT_INPUT = 0x20E0668,
+   IOMUXC_AUDMUX_P5_INPUT_TXCLK_AMX_SELECT_INPUT = 0x20E066C,
+   IOMUXC_AUDMUX_P5_INPUT_TXFS_AMX_SELECT_INPUT = 0x20E0670,
+   IOMUXC_AUDMUX_P6_INPUT_DA_AMX_SELECT_INPUT = 0x20E0674,
+   IOMUXC_AUDMUX_P6_INPUT_DB_AMX_SELECT_INPUT = 0x20E0678,
+   IOMUXC_AUDMUX_P6_INPUT_RXCLK_AMX_SELECT_INPUT = 0x20E067C,
+   IOMUXC_AUDMUX_P6_INPUT_RXFS_AMX_SELECT_INPUT = 0x20E0680,
+   IOMUXC_AUDMUX_P6_INPUT_TXCLK_AMX_SELECT_INPUT = 0x20E0684,
+   IOMUXC_AUDMUX_P6_INPUT_TXFS_AMX_SELECT_INPUT = 0x20E0688,
+   IOMUXC_CAN1_IPP_IND_CANRX_SELECT_INPUT = 0x20E068C,
+   IOMUXC_CAN2_IPP_IND_CANRX_SELECT_INPUT = 0x20E0690,
+   IOMUXC_CCM_PMIC_VFUNCIONAL_READY_SELECT_INPUT = 0x20E069C,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_0 = 0x20E06A0,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_1 = 0x20E06A4,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_2 = 0x20E06A8,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_3 = 0x20E06AC,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_4 = 0x20E06B0,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_5 = 0x20E06B4,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_6 = 0x20E06B8,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_7 = 0x20E06BC,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_8 = 0x20E06C0,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_9 = 0x20E06C4,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_11 = 0x20E06C8,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_12 = 0x20E06CC,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_13 = 0x20E06D0,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_14 = 0x20E06D4,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_15 = 0x20E06D8,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_16 = 0x20E06DC,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_17 = 0x20E06E0,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_18 = 0x20E06E4,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_19 = 0x20E06E8,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_20 = 0x20E06EC,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_21 = 0x20E06F0,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_22 = 0x20E06F4,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_23 = 0x20E06F8,
+   IOMUXC_CSI1_IPP_CSI_D_SELECT_INPUT_10 = 0x20E06FC,
+   IOMUXC_CSI1_IPP_CSI_HSYNC_SELECT_INPUT = 0x20E0700,
+   IOMUXC_CSI1_IPP_CSI_PIXCLK_SELECT_INPUT = 0x20E0704,
+   IOMUXC_CSI1_IPP_CSI_VSYNC_SELECT_INPUT = 0x20E0708,
+   IOMUXC_CSI1_TVDECODER_IN_FIELD_SELECT_INPUT = 0x20E070C,
+   IOMUXC_ECSPI1_IPP_CSPI_CLK_IN_SELECT_INPUT = 0x20E0710,
+   IOMUXC_ECSPI1_IPP_IND_MISO_SELECT_INPUT = 0x20E0714,
+   IOMUXC_ECSPI1_IPP_IND_MOSI_SELECT_INPUT = 0x20E0718,
+   IOMUXC_ECSPI1_IPP_IND_SS_B_SELECT_INPUT_0 = 0x20E071C,
+   IOMUXC_ECSPI2_IPP_CSPI_CLK_IN_SELECT_INPUT = 0x20E0720,
+   IOMUXC_ECSPI2_IPP_IND_MISO_SELECT_INPUT = 0x20E0724,
+   IOMUXC_ECSPI2_IPP_IND_MOSI_SELECT_INPUT = 0x20E0728,
+   IOMUXC_ECSPI2_IPP_IND_SS_B_SELECT_INPUT_0 = 0x20E072C,
+   IOMUXC_ECSPI3_IPP_CSPI_CLK_IN_SELECT_INPUT = 0x20E0730,
+   IOMUXC_ECSPI3_IPP_IND_MISO_SELECT_INPUT = 0x20E0734,
+   IOMUXC_ECSPI3_IPP_IND_MOSI_SELECT_INPUT = 0x20E0738,
+   IOMUXC_ECSPI3_IPP_IND_SS_B_SELECT_INPUT_0 = 0x20E073C,
+   IOMUXC_ECSPI4_IPP_CSPI_CLK_IN_SELECT_INPUT = 0x20E0740,
+   IOMUXC_ECSPI4_IPP_IND_MISO_SELECT_INPUT = 0x20E0744,
+   IOMUXC_ECSPI4_IPP_IND_MOSI_SELECT_INPUT = 0x20E0748,
+   IOMUXC_ECSPI4_IPP_IND_SS_B_SELECT_INPUT_0 = 0x20E074C,
+   IOMUXC_ECSPI5_IPP_CSPI_CLK_IN_SELECT_INPUT = 0x20E0750,
+   IOMUXC_ECSPI5_IPP_IND_MISO_SELECT_INPUT = 0x20E0754,
+   IOMUXC_ECSPI5_IPP_IND_MOSI_SELECT_INPUT = 0x20E0758,
+   IOMUXC_ECSPI5_IPP_IND_SS_B_SELECT_INPUT_0 = 0x20E075C,
+   IOMUXC_ENET1_IPG_CLK_RMII_SELECT_INPUT = 0x20E0760,
+   IOMUXC_ENET1_IPP_IND_MAC0_MDIO_SELECT_INPUT = 0x20E0764,
+   IOMUXC_ENET1_IPP_IND_MAC0_RXCLK_SELECT_INPUT = 0x20E0768,
+   IOMUXC_ENET2_IPG_CLK_RMII_SELECT_INPUT = 0x20E076C,
+   IOMUXC_ENET2_IPP_IND_MAC0_MDIO_SELECT_INPUT = 0x20E0770,
+   IOMUXC_ENET2_IPP_IND_MAC0_RXCLK_SELECT_INPUT = 0x20E0774,
+   IOMUXC_ESAI_IPP_IND_FSR_SELECT_INPUT = 0x20E0778,
+   IOMUXC_ESAI_IPP_IND_FST_SELECT_INPUT = 0x20E077C,
+   IOMUXC_ESAI_IPP_IND_HCKR_SELECT_INPUT = 0x20E0780,
+   IOMUXC_ESAI_IPP_IND_HCKT_SELECT_INPUT = 0x20E0784,
+   IOMUXC_ESAI_IPP_IND_SCKR_SELECT_INPUT = 0x20E0788,
+   IOMUXC_ESAI_IPP_IND_SCKT_SELECT_INPUT = 0x20E078C,
+   IOMUXC_ESAI_IPP_IND_SDO0_SELECT_INPUT = 0x20E0790,
+   IOMUXC_ESAI_IPP_IND_SDO1_SELECT_INPUT = 0x20E0794,
+   IOMUXC_ESAI_IPP_IND_SDO2_SDI3_SELECT_INPUT = 0x20E0798,
+   IOMUXC_ESAI_IPP_IND_SDO3_SDI2_SELECT_INPUT = 0x20E079C,
+   IOMUXC_ESAI_IPP_IND_SDO4_SDI1_SELECT_INPUT = 0x20E07A0,
+   IOMUXC_ESAI_IPP_IND_SDO5_SDI0_SELECT_INPUT = 0x20E07A4,
+   IOMUXC_I2C1_IPP_SCL_IN_SELECT_INPUT = 0x20E07A8,
+   IOMUXC_I2C1_IPP_SDA_IN_SELECT_INPUT = 0x20E07AC,
+   IOMUXC_I2C2_IPP_SCL_IN_SELECT_INPUT = 0x20E07B0,
+   IOMUXC_I2C2_IPP_SDA_IN_SELECT_INPUT = 0x20E07B4,
+   IOMUXC_I2C3_IPP_SCL_IN_SELECT_INPUT = 0x20E07B8,
+   IOMUXC_I2C3_IPP_SDA_IN_SELECT_INPUT = 0x20E07BC,
+   IOMUXC_I2C4_IPP_SCL_IN_SELECT_INPUT = 0x20E07C0,
+   IOMUXC_I2C4_IPP_SDA_IN_SELECT_INPUT = 0x20E07C4,
+   IOMUXC_KPP_IPP_IND_COL_SELECT_INPUT_5 = 0x20E07C8,
+   IOMUXC_KPP_IPP_IND_COL_SELECT_INPUT_6 = 0x20E07CC,
+   IOMUXC_KPP_IPP_IND_COL_SELECT_INPUT_7 = 0x20E07D0,
+   IOMUXC_KPP_IPP_IND_ROW_SELECT_INPUT_5 = 0x20E07D4,
+   IOMUXC_KPP_IPP_IND_ROW_SELECT_INPUT_6 = 0x20E07D8,
+   IOMUXC_KPP_IPP_IND_ROW_SELECT_INPUT_7 = 0x20E07DC,
+   IOMUXC_LCD1_BUSY_SELECT_INPUT = 0x20E07E0,
+   IOMUXC_LCD2_BUSY_SELECT_INPUT = 0x20E07E4,
+   IOMUXC_MLB_MLB_CLK_IN_SELECT_INPUT = 0x20E07E8,
+   IOMUXC_MLB_MLB_DATA_IN_SELECT_INPUT = 0x20E07EC,
+   IOMUXC_MLB_MLB_SIG_IN_SELECT_INPUT = 0x20E07F0,
+   IOMUXC_SAI1_IPP_IND_SAI_RXBCLK_SELECT_INPUT = 0x20E07F4,
+   IOMUXC_SAI1_IPP_IND_SAI_RXDATA_SELECT_INPUT_0 = 0x20E07F8,
+   IOMUXC_SAI1_IPP_IND_SAI_RXSYNC_SELECT_INPUT = 0x20E07FC,
+   IOMUXC_SAI1_IPP_IND_SAI_TXBCLK_SELECT_INPUT = 0x20E0800,
+   IOMUXC_SAI1_IPP_IND_SAI_TXSYNC_SELECT_INPUT = 0x20E0804,
+   IOMUXC_SAI2_IPP_IND_SAI_RXBCLK_SELECT_INPUT = 0x20E0808,
+   IOMUXC_SAI2_IPP_IND_SAI_RXDATA_SELECT_INPUT_0 = 0x20E080C,
+   IOMUXC_SAI2_IPP_IND_SAI_RXSYNC_SELECT_INPUT = 0x20E0810,
+   IOMUXC_SAI2_IPP_IND_SAI_TXBCLK_SELECT_INPUT = 0x20E0814,
+   IOMUXC_SAI2_IPP_IND_SAI_TXSYNC_SELECT_INPUT = 0x20E0818,
+   IOMUXC_SDMA_EVENTS_SELECT_INPUT_14 = 0x20E081C,
+   IOMUXC_SDMA_EVENTS_SELECT_INPUT_15 = 0x20E0820,
+   IOMUXC_SPDIF_SPDIF_IN1_SELECT_INPUT = 0x20E0824,
+   IOMUXC_SPDIF_TX_CLK2_SELECT_INPUT = 0x20E0828,
+   IOMUXC_UART1_IPP_UART_RTS_B_SELECT_INPUT = 0x20E082C,
+   IOMUXC_UART1_IPP_UART_RXD_MUX_SELECT_INPUT = 0x20E0830,
+   IOMUXC_UART2_IPP_UART_RTS_B_SELECT_INPUT = 0x20E0834,
+   IOMUXC_UART2_IPP_UART_RXD_MUX_SELECT_INPUT = 0x20E0838,
+   IOMUXC_UART3_IPP_UART_RTS_B_SELECT_INPUT = 0x20E083C,
+   IOMUXC_UART3_IPP_UART_RXD_MUX_SELECT_INPUT = 0x20E0840,
+   IOMUXC_UART4_IPP_UART_RTS_B_SELECT_INPUT = 0x20E0844,
+   IOMUXC_UART4_IPP_UART_RXD_MUX_SELECT_INPUT = 0x20E0848,
+   IOMUXC_UART5_IPP_UART_RTS_B_SELECT_INPUT = 0x20E084C,
+   IOMUXC_UART5_IPP_UART_RXD_MUX_SELECT_INPUT = 0x20E0850,
+   IOMUXC_UART6_IPP_UART_RTS_B_SELECT_INPUT = 0x20E0854,
+   IOMUXC_UART6_IPP_UART_RXD_MUX_SELECT_INPUT = 0x20E0858,
+   IOMUXC_USB_IPP_IND_OTG2_OC_SELECT_INPUT = 0x20E085C,
+   IOMUXC_USB_IPP_IND_OTG_OC_SELECT_INPUT = 0x20E0860,
+   IOMUXC_USDHC1_IPP_CARD_DET_SELECT_INPUT = 0x20E0864,
+   IOMUXC_USDHC1_IPP_WP_ON_SELECT_INPUT = 0x20E0868,
+   IOMUXC_USDHC2_IPP_CARD_DET_SELECT_INPUT = 0x20E086C,
+   IOMUXC_USDHC2_IPP_WP_ON_SELECT_INPUT = 0x20E0870,
+   IOMUXC_USDHC4_IPP_CARD_DET_SELECT_INPUT = 0x20E0874,
+   IOMUXC_USDHC4_IPP_WP_ON_SELECT_INPUT = 0x20E0878,
+   IOMUXC_SELECT_INPUT_UPPER_BOUND = IOMUXC_USDHC4_IPP_WP_ON_SELECT_INPUT,
+} IMX_INPUT_SELECT;
+
+#define IOMUXC_GPR_BASE_ADDRESS             0x020E4000
+
+typedef struct{
+    UINT32 GPR0;                          // 0x00 IOMUXC_GPR0
+    UINT32 GPR1;                          // 0x04 IOMUXC_GPR1
+    UINT32 GPR2;                          // 0x08 IOMUXC_GPR2
+    UINT32 GPR3;                          // 0x0C IOMUXC_GPR3
+    UINT32 GPR4;                          // 0x10 IOMUXC_GPR4
+    UINT32 GPR5;                          // 0x14 IOMUXC_GPR5
+    UINT32 GPR6;                          // 0x18 IOMUXC_GPR6
+    UINT32 GPR7;                          // 0x1C IOMUXC_GPR7
+    UINT32 GPR8;                          // 0x20 IOMUXC_GPR8
+    UINT32 GPR9;                          // 0x24 IOMUXC_GPR9
+    UINT32 GPR10;                         // 0x28 IOMUXC_GPR10
+    UINT32 GPR11;                         // 0x2c IOMUXC_GPR11
+    UINT32 GPR12;                         // 0x30 IOMUXC_GPR12
+    UINT32 GPR13;                         // 0x34 IOMUXC_GPR13
+} IMX_IOMUXC_GPR_REGISTERS;
+
+typedef enum {
+    IMX_IOMUXC_GPR1_USB_OTG_ID_SEL_ENET_RX_ER,
+    IMX_IOMUXC_GPR1_USB_OTG_ID_SEL_GPIO_1,
+} IMX_IOMUXC_GPR1_USB_OTG_ID_SEL;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 ACT_CS0 : 1;                 // 0
+        UINT32 ADDRS0_10 : 2;               // 1-2
+        UINT32 ACT_CS1 : 1;                 // 3
+        UINT32 ADDRS1_10 : 2;               // 4-5
+        UINT32 ACT_CS2 : 1;                 // 6
+        UINT32 ADDRS2_10 : 2;               // 7-8
+        UINT32 ACT_CS3 : 1;                 // 9
+        UINT32 ADDRS3_10 : 2;               // 10-11 Active Chip Select and Address Space
+        UINT32 GINT : 1;                    // 12 Global interrupt "0" bit (connected to ARM IRQ#0 and GPC)
+        UINT32 USB_OTG_ID_SEL : 1;          // 13 ''usb_otg_id' pin iomux select control.
+        UINT32 SYS_INT : 1;                 // 14 PCIe_CTL
+        UINT32 USB_EXP_MODE : 1;            // 15 USB Exposure mode
+        UINT32 REF_SSP_EN : 1;              // 16 PCIe_PHY - Reference Clock Enable for SS function.
+        UINT32 PU_VPU_MUX : 1;              // 17 IPU-1/IPU-2 to VPU signals control.
+        UINT32 TEST_POWERDOWN : 1;          // 18 PCIe_PHY - All Circuits Power-Down Control Function.
+        UINT32 MIPI_IPU1_MUX : 1;           // 19 MIPI sensor to IPU-1 mux control.
+        UINT32 MIPI_IPU2_MUX : 1;           // 20 MIPI sensor to IPU-2 mux control
+        UINT32 ENET_CLK_SEL : 1;            // 21 ENET TX reference clock
+        UINT32 EXC_MON : 1;                 // 22 Exclusive monitor response select of illegal command
+        UINT32 reserved1 : 1;               // 23
+        UINT32 MIPI_DPI_OFF : 1;            // 24 MIPI DPI shutdown request
+        UINT32 MIPI_COLOR_SW : 1;           // 25 MIPI color switch control
+        UINT32 APP_REQ_ENTR_L1 : 1;         // 26 PCIe_CTL - Application Request to Enter L1
+        UINT32 APP_READY_ENTR_L23 : 1;      // 27 PCIe_CTL - Application Ready to Enter L23
+        UINT32 APP_REQ_EXIT_L1 : 1;         // 28 PCIe_CTL - Application Request to Exit L1
+        UINT32 reserved2 : 1;               // 29
+        UINT32 APP_CLK_REQ_N : 1;           // 30 PCIe_CTL (CLK LOGIC CONTROLLER GLUE) - Indicates that application logic is ready to have reference clock removed.
+        UINT32 CFG_L1_CLK_REMOVAL_EN : 1;   // 31 PCIe_CTL (CLK LOGIC CONTROLLER GLUE) - Enable the reference clock removal in L1 state.
+        // MSB
+    };
+} IMX_IOMUXC_GPR1_REG;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 PCS_TX_DEEMPH_GEN1 : 6;      // 0-5 PCIe_PHY - This static value sets the launch amplitude of the transmitter when pipe0_tx_swing is set to 1'b0 (default state).
+        UINT32 PCS_TX_DEEMPH_GEN2_3P5DB : 6;// 6-11 PCIe_PHY - This static value sets the Tx driver SWING_FULL value.
+        UINT32 PCS_TX_DEEMPH_GEN2_6DB : 6;  // 12-17 PCIe_PHY - This static value sets the Tx driver de-emphasis value in the case where pipe0_tx_deemph is set to 1'b0 and the PHY is running at the Gen2 (6db) rate.
+        UINT32 PCS_TX_SWING_FULL : 7;       // 18-24 PCIe_PHY - This static value sets the Tx driver de-emphasis value in the case where pipe0_tx_deemph is set to 1'b1 (the default setting) and the PHY is running at the Gen2 (3p5db) rate.
+        UINT32 PCS_TX_SWING_LOW : 7;        // 25-31 PCIe_PHY - This static value sets the Tx driver de-emphasis value in the case where pipe0_tx_deemph is set to 1'b1 (the default setting) and the PHY is running at the Gen1 rate.
+        // MSB
+    };
+} IMX_IOMUXC_GPR8_REG;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 reserved0 : 2;               // 0-1
+        UINT32 uSDHC_DBG_MUX : 2;           // 2-3 uSDHC debug bus IO mux control
+        UINT32 LOS_LEVEL : 5;               // 4-8 PCIe_PHY - Loss-of-Signal Detector Sensitivity Level Control Function: Sets the sensitivity level for the Loss - of - Signal detector.This signal must be set to 0x9
+        UINT32 APPS_PM_XMT_PME : 1;         // 9 PCIe_CTL - Wake Up. Used by application logic to wake up the PMC state machine from a D1, D2 or D3 power state.Upon wake - up, the core sends a PM_PME Message
+        UINT32 APP_LTSSM_ENABLE : 1;        // 10 PCIe_CTL Driven low by the application after reset to hold the LTSSM in the Detect state until the application is ready.When the application has finished initializing the core configuration registers, it asserts app_ltssm_enable to allow the LTSSM to continue Link establishment.
+        UINT32 APP_INIT_RST : 1;            // 11 PCIe_PHY - PCIe_CTL - Request from the application to send a Hot Reset to the downstream device.
+        UINT32 DEVICE_TYPE : 4;             // 12-15 PCIe_CTL - Device/Port Type. 0000 PCIE_EP - EP Mode 0010 PCIE_RC - RC Mode
+        UINT32 APPS_PM_XMT_TURNOFF : 1;     // 16 PCIe_CTL - Request from the application to generate a PM_Turn_Off Message.
+        UINT32 DIA_STATUS_BUS_SELECT : 4;   // 17-20 PCIe_CTL - used for debug to select what part of diag_status_bus will be reflected on the 32 bits of the iomux
+        UINT32 PCIe_CTL_7 : 3;              // 21-23 PCIe control of diagnostic bus select
+        UINT32 ARMP_APB_CLK_EN : 1;         // 24 ARM platform APB clock enable
+        UINT32 ARMP_ATB_CLK_EN : 1;         // 25 ARM platform ATB clock enable
+        UINT32 ARMP_AHB_CLK_EN : 1;         // 26 ARM platform AHB clock enable
+        UINT32 ARMP_IPG_CLK_EN : 1;         // 27 ARM platform IPG clock enable
+        UINT32 reserved1 : 4;               // 28-31
+        // MSB
+    };
+} IMX_IOMUXC_GPR12_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 reserved1 : 1;               // 0
+    UINT32 reserved2 : 1;               // 1
+    UINT32 MC_ENV : 1;                  // 2 Monotonic Counter Enable and Valid
+    UINT32 reserved3 : 1;               // 3
+    UINT32 reserved4 : 1;               // 4
+    UINT32 DP_EN : 1;                   // 5 Dumb PMIC Enabled
+    UINT32 TOP : 1;                     // 6 Turn off System Power
+    UINT32 PWR_GLITCH_EN : 1;           // 7 Power Glitch Detection Enable
+    UINT32 reserved5 : 1;               // 8
+    UINT32 reserved6 : 1;               // 9
+    UINT32 reserved7 : 5;               // 10-14
+    UINT32 reserved8 : 1;               // 15
+    UINT32 BTN_PRESS_TIME : 2;          // 16-17 Button press time out values for PMIC Logic.
+    UINT32 DEBOUNCE : 2;                // 18-19 debounce time for the BTN input signal
+    UINT32 ON_TIME : 2;                 // 20-21 Time after BTN is asserted before pmic_en_b is asserted
+    UINT32 PK_EN : 1;                   // 22 PMIC On Request Enable
+    UINT32 PK_OVERRIDE : 1;             // 23 PMIC On Request Override
+    UINT32 reserved9 : 8;               // 24-31
+    // MSB
+  };
+} IMX_SNVS_LPCR_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 MINOR_REV : 8;               // 0-7 SNVS block minor version number
+    UINT32 MAJOR_REV : 8;               // 8-15 SNVS block major version number
+    UINT32 IP_ID : 16;                  // 16-31 SNVS block ID (IMX_SNVS_IP_ID)
+    // MSB
+  };
+} IMX_SNVS_HPVIDR1_REG;
+
+typedef struct {
+  UINT32 HPLR;                          // 0x000 SNVS_HP Lock Register (SNVS_HPLR)
+  UINT32 HPCOMR;                        // 0x004 SNVS_HP Command Register (SNVS_HPCOMR)
+  UINT32 HPCR;                          // 0x008 SNVS_HP Control Register (SNVS_HPCR)
+  UINT32 reserved1[2];
+  UINT32 HPSR;                          // 0x014 SNVS_HP Status Register (SNVS_HPSR)
+  UINT32 reserved2[3];
+  UINT32 HPRTCMR;                       // 0x024 SNVS_HP Real Time Counter MSB Register (SNVS_HPRTCMR
+  UINT32 HPRTCLR;                       // 0x028 SNVS_HP Real Time Counter LSB Register (SNVS_HPRTCLR)
+  UINT32 HPTAMR;                        // 0x02C SNVS_HP Time Alarm MSB Register (SNVS_HPTAMR)
+  UINT32 HPTALR;                        // 0x030 SNVS_HP Time Alarm LSB Register (SNVS_HPTALR)
+  UINT32 LPLR;                          // 0x034 SNVS_LP Lock Register (SNVS_LPLR)
+  UINT32 LPCR;                          // 0x038 SNVS_LP Control Register (SNVS_LPCR)
+  UINT32 reserved3[4];
+  UINT32 LPSR;                          // 0x04C SNVS_LP Status Register (SNVS_LPSR)
+  UINT32 reserved4[3];
+  UINT32 LPSMCMR;                       // 0x05C SNVS_LP Secure Monotonic Counter MSB Register (SNVS_LPSMCMR)
+  UINT32 LPSMCLR;                       // 0x060 SNVS_LP Secure Monotonic Counter LSB Register (SNVS_LPSMCLR)
+  UINT32 reserved5[1];
+  UINT32 LPGPR;                         // 0x068 SNVS_LP General Purpose Register (SNVS_LPGPR)
+  UINT32 reserved6[739];
+  UINT32 HPVIDR1;                       // 0xBF8 SNVS_HP Version ID Register 1 (SNVS_HPVIDR1)
+  UINT32 HPVIDR2;                       // 0xBFC SNVS_HP Version ID Register 2 (SNVS_HPVIDR2)
+} IMX_SNVS_REGISTERS;
+
+//
+// System Reset Controller (SRC)
+//
+
+#define IMX_SRC_BASE 0x020D8000
+#define IMX_SRC_LENGTH 0x4000
+
+//
+// SCR Register Definition
+//
+
+// SRC_SCR_REG.warm_rst_bypass_count
+typedef enum {
+  IMX_SCR_WARM_RST_BYPASS_COUNT_DISABLED,
+  IMX_SCR_WARM_RST_BYPASS_COUNT_16,
+  IMX_SCR_WARM_RST_BYPASS_COUNT_32,
+  IMX_SCR_WARM_RST_BYPASS_COUNT_64,
+} IMX_SCR_WARM_RST_BYPASS_COUNT;
+
+// SRC_SCR_REG.mask_wdog_rst
+typedef enum {
+  IMX_SRC_MASK_WDOG_RST_B_MASKED = 0x5,
+  IMX_SRC_MASK_WDOG_RST_B_NOT_MASKED = 0xA,
+} IMX_SRC_MASK_WDOG_RST;
+
+// SRC_SCR_REG.mask_tempsense_reset
+typedef enum {
+  IMX_SRC_MASK_TEMPSENSE_RESET_NOT_MASKED = 0x2,
+  IMX_SRC_MASK_TEMPSENSE_RESET_MASKED = 0x5,
+} IMX_SRC_MASK_TEMPSENSE_RESET;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 warm_reset_enable : 1;       // 0 WARM reset enable bit
+    UINT32 sw_gpu_rst : 1;              // 1 Software reset for GPU
+    UINT32 reserved1 : 1;               // 2
+    UINT32 m4c_rst : 1;                 // 3 Self-clearing SW reset for M4 core
+    UINT32 m4c_non_sclr_rst : 1;        // 4 Non-self-clearing SW reset for M4 core
+    UINT32 warm_rst_bypass_count : 2;   // 5-6 Defines the XTALI cycles to count before bypassing the MMDC acknowledge for WARM reset. (IMX_SCR_WARM_RST_BYPASS_COUNT)
+    UINT32 mask_wdog_rst : 4;           // 7-10 Mask wdog_rst_b source (IMX_SRC_MASK_WDOG_RST)
+    UINT32 eim_rst : 1;                 // 11 EIM reset is needed in order to reconfigure the eim chip select.
+    UINT32 m4p_rst : 1;                 // 12 Self-clearing SW reset for M4 platform
+    UINT32 core0_rst : 1;               // 13 Software reset for core0 only
+    UINT32 reserved2 : 3;               // 14-16
+    UINT32 core0_dbg_rst : 1;           // 17 Software reset for core0 debug only.
+    UINT32 mask_tempsense_reset : 3;    // 18-20 Mask tempsense_reset source (IMX_SRC_MASK_TEMPSENSE_RESET)
+    UINT32 cores_dbg_rst : 1;           // 21 Software reset for debug of arm platform only
+    UINT32 m4_enable : 1;               // 22 Enable M4 core
+    UINT32 wdog3_rst_optn_m4 : 1;       // 23 wdog3_rst_b option for M4. This bit is only effective when wdog3_rst_option is set to 1.
+    UINT32 wdog3_rst_optn : 1;          // 24 Wdog3_rst_b option
+    UINT32 dbg_rst_msk_pg : 1;          // 25 Do not assert debug resets after power gating event of core
+    UINT32 mix_rst_strch : 2;           // 26-27 SoC mix (Audio, ENET, uSDHC, EIM, QSPI, OCRAM, MMDC, etc) power up reset stretch mix reset width = (mix_rst_strtch +1)* 88 ipg_clk cycles
+    UINT32 mask_wdog3_rst : 4;          // 28-31 Mask wdog3_rst_b source (IMX_SRC_MASK_WDOG_RST)
+    // MSB
+  };
+} IMX_SRC_SCR_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 BOOT_CFG1 : 8;   // 0-7
+    UINT32 BOOT_CFG2 : 8;   // 8-15
+    UINT32 BOOT_CFG3 : 8;   // 16-23
+    UINT32 BOOT_CFG4 : 8;   // 24-31
+    // MSB
+  };
+} IMX_SRC_SBMR1_REG;
+
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 SEC_COFNIG : 2;    // 0-1
+    UINT32 reserved1 : 1;     // 2
+    UINT32 DIR_BT_DIS : 1;    // 3
+    UINT32 BT_FUSE_SEL : 1;   // 4
+    UINT32 reserved2 : 19;    // 5-23
+    UINT32 BMOD : 2;          // 24-25
+    UINT32 reserved3 : 6;     // 26-31
+    // MSB
+  };
+} IMX_SRC_SBMR2_REG;
+
+typedef struct {
+  UINT32 SCR;                           // 0x00 SRC Control Register (SRC_SCR)
+  UINT32 SBMR1;                         // 0x04 SRC Boot Mode Register 1 (SRC_SBMR1)
+  UINT32 SRSR;                          // 0x08 SRC Reset Status Register (SRC_SRSR)
+  UINT32 reserved1[2];
+  UINT32 SISR;                          // 0x14 SRC Interrupt Status Register (SRC_SISR)
+  UINT32 SIMR;                          // 0x18 SRC Interrupt Mask Register (SRC_SIMR)
+  UINT32 SBMR2;                         // 0x1C SRC Boot Mode Register 2 (SRC_SBMR2)
+  UINT32 GPR1;                          // 0x20 SRC General Purpose Register 1 (SRC_GPR1)
+  UINT32 GPR2;                          // 0x24 SRC General Purpose Register 2 (SRC_GPR2)
+  UINT32 GPR3;                          // 0x28 SRC General Purpose Register 3 (SRC_GPR3)
+  UINT32 GPR4;                          // 0x2C SRC General Purpose Register 4 (SRC_GPR4)
+  UINT32 GPR5;                          // 0x30 SRC General Purpose Register 4 (SRC_GPR5)
+  UINT32 GPR6;                          // 0x34 SRC General Purpose Register 4 (SRC_GPR6)
+  UINT32 GPR7;                          // 0x38 SRC General Purpose Register 4 (SRC_GPR7)
+  UINT32 GPR8;                          // 0x3C SRC General Purpose Register 4 (SRC_GPR8)
+  UINT32 GPR9;                          // 0x40 SRC General Purpose Register 4 (SRC_GPR9)
+  UINT32 GPR10;                         // 0x44 SRC General Purpose Register 4 (SRC_GPR10)
+} IMX_SRC_REGISTERS;
+
+
+//
+// Watchdog (WDOG)
+//
+
+#define IMX_WDOG1_BASE 0x020BC000
+#define IMX_WDOG2_BASE 0x020C0000
+#define IMX_WDOG3_BASE 0x02288000 // SX RM.p4734
+
+#define IMX_WDOG_LENGTH 0x4000
+
+#define IMX_WDOG_WSR_FEED1 0x5555
+#define IMX_WDOG_WSR_FEED2 0xAAAA
+
+typedef union {
+  UINT16 AsUint16;
+  struct {
+    // LSB
+    UINT16 WDZST : 1;                   // 0 Watchdog Low Power
+    UINT16 WDBG : 1;                    // 1 Watchdog DEBUG Enable
+    UINT16 WDE : 1;                     // 2 Watchdog Enable
+    UINT16 WDT : 1;                     // 3 WDOG_B Time-out assertion.
+    UINT16 SRS : 1;                     // 4 Software Reset Signal
+    UINT16 WDA : 1;                     // 5 WDOG_B assertion
+    UINT16 reserved1 : 1;               // 6
+    UINT16 WDW : 1;                     // 7 Watchdog Disable for Wait
+    UINT16 WT : 8;                      // 8-15 Watchdog Time-out Field
+    // MSB
+  };
+} IMX_WDOG_WCR_REG;
+
+typedef struct {
+  UINT16 WCR;                           // 0x0 Watchdog Control Register (WDOG1_WCR)
+  UINT16 WSR;                           // 0x2 Watchdog Service Register (WDOG1_WSR)
+  UINT16 WRSR;                          // 0x4 Watchdog Reset Status Register (WDOG1_WRSR)
+  UINT16 WICR;                          // 0x6 Watchdog Interrupt Control Register (WDOG1_WICR)
+  UINT16 WMCR;                          // 0x8 Watchdog Miscellaneous Control Register (WDOG1_WMCR)
+} IMX_WDOG_REGISTERS;
+
+//
+// Clock Control Module (CCM)
+//
+
+#define IMX6SX_CCM_CLOCK_OFF    0
+#define IMX6SX_RUN_ONLY         1
+#define IMX6SX_RUN_AND_WAIT     3
+
+#define IMX_CCM_BASE 0x020C4000
+#define IMX_CCM_LENGTH 0x4000
+#define IMX_CCM_ANALOG_BASE  0x020C8000
+#define IMX_CCM_ANALOG_LENGTH 0x1000
+
+#define IMX_REF_CLK_24M_FREQ 24000000
+
+typedef enum {
+  IMX_CCM_PLL3_SW_CLK_SEL_PLL3_MAIN_CLK,
+  IMX_CCM_PLL3_SW_CLK_SEL_PLL3_BYPASS_CLK,
+} IMX_CCM_PLL3_SW_CLK_SEL;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 pll3_sw_clk_sel : 1;         // 0 Selects source to generate pll3_sw_clk (IMX_CCM_PLL3_SW_CLK_SEL)
+    UINT32 reserved1 : 1;               // 1
+    UINT32 pll1_sw_clk_sel : 1;         // 2 Selects source to generate pll1_sw_clk.
+    UINT32 reserved2 : 5;               // 3-7
+    UINT32 step_sel : 1;                // 8 Selects the option to be chosen for the step frequency
+    UINT32 reserved3 : 23;              // 9-31
+    // MSB
+  };
+} IMX_CCM_CCSR_REG; // SX RM.p812
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 arm_podf : 3;                // 0-3 Divider for ARM clock root
+    UINT32 reserved : 29;               // 3-31
+    // MSB
+  };
+} IMX_CCM_CACRR_REG;
+
+// CBCMR.gpu_core_sel
+typedef enum {
+  IMX_CCM_GPU_CLK_SEL_PLL3_PFD1,
+  IMX_CCM_GPU_CLK_SEL_PLL3_PFD0,
+  IMX_CCM_GPU_CLK_SEL_PLL2,
+  IMX_CCM_GPU_CLK_SEL_PLL2_PFD2
+} IMX_CCM_GPU_CLK_SEL;
+
+// CBCMR.gpu_axi_sel
+typedef enum {
+  IMX_CCM_GPU_AXI_SEL_PLL2_PFD2,
+  IMX_CCM_GPU_AXI_SEL_PLL3_PFD0,
+  IMX_CCM_GPU_AXI_SEL_PLL3_PFD1,
+  IMX_CCM_GPU_AXI_SEL_PLL2
+} IMX_CCM_GPU_AXI_SEL;
+
+// CBCMR.pcie_axi_clock_sel
+typedef enum {
+  IMX_CCM_PCIE_AXI_CLOCK_SEL_AXI,
+  IMX_CCM_PCIE_AXI_CLOCK_SEL_AHB,
+} IMX_CCM_PCIE_AXI_CLOCK_SEL;
+
+// CBCMR.periph_clk2_sel
+typedef enum {
+  IMX_CCM_PERIPH_CLK2_SEL_PLL3_SW_CLK,
+  IMX_CCM_PERIPH_CLK2_SEL_OSC_CLK,
+  IMX_CCM_PERIPH_CLK2_SEL_PLL2_BYPASS_CLK
+} IMX_CCM_PERIPH_CLK2_SEL;
+
+// CBCMR.pre_periph_clk_sel
+typedef enum {
+  IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2,
+  IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2_PFD2,
+  IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2_PFD0,
+  IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2_PFD2_DIV2,
+} IMX_CCM_PRE_PERIPH_CLK_SEL;
+
+// CBCMR.periph2_clk2_sel
+typedef enum {
+  IMX_CCM_PERIPH2_CLK2_SEL_PLL3_SW_CLK,
+  IMX_CCM_PERIPH2_CLK2_SEL_OSC
+} IMX_CCM_PERIPH2_CLK2_SEL;
+
+// CBCMR.pre_periph2_clk_sel
+typedef enum {
+  IMX_CCM_PRE_PERIPH2_CLK_SEL_PLL2,
+  IMX_CCM_PRE_PERIPH2_CLK_SEL_PLL2_PFD2,
+  IMX_CCM_PRE_PERIPH2_CLK_SEL_PLL2_PFD0,
+  IMX_CCM_PRE_PERIPH2_CLK_SEL_PLL4
+} IMX_CCM_PRE_PERIPH2_CLK_SEL;
+
+// CBCMR.podf (divider for lcdif1_podf, gpu_axi_podf, gpu_core_podf)
+typedef enum {
+  IMX_CCM_PODF_DIV1,
+  IMX_CCM_PODF_DIV2,
+  IMX_CCM_PODF_DIV3,
+  IMX_CCM_PODF_DIV4,
+  IMX_CCM_PODF_DIV5,
+  IMX_CCM_PODF_DIV6,
+  IMX_CCM_PODF_DIV7,
+  IMX_CCM_PODF_DIV8
+} IMX_CCM_PODF;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 reserved1 : 4;               // 0-3
+    UINT32 gpu_core_sel : 2;            // 4-5 Selector for gpu_core clock multiplexer (IMX_CCM_GPU_CLK_SEL)
+    UINT32 reserved2 : 2;               // 6-7
+    UINT32 gpu_axi_sel : 2;             // 8-9 Selector for gpu_axi clock multiplexer (IMX_CCM_GPU_AXI_SEL)
+    UINT32 pcie_axi_clock_sel : 1;          // 10 Selector for pcie_axi_clock multiplexier (IMX_CCM_PCIE_AXI_CLOCK_SEL)
+    UINT32 reserved3 : 1;               // 11
+    UINT32 periph_clk2_sel : 2;         // 12-13 Selector for peripheral clk2 clock multiplexer (IMX_CCM_PERIPH_CLK2_SEL)
+    UINT32 reserved4 : 4;               // 14-17
+    UINT32 pre_periph_clk_sel : 2;      // 18-19 Selector for pre_periph clock multiplexer (IMX_CCM_PRE_PERIPH_CLK_SEL)
+    UINT32 periph2_clk2_sel : 1;        // 20 Selector for periph2_clk2 clock multiplexer (IMX_CCM_PERIPH2_CLK2_SEL)
+    UINT32 pre_periph2_clk_sel : 2;     // 21-22 Selector for pre_periph2 clock multiplexer (IMX_CCM_PRE_PERIPH2_CLK_SEL)
+    UINT32 lcdif1_podf : 3;             // 23-25 Post-divider for lcdif1 clock (IMX_CCM_PODF)
+    UINT32 gpu_axi_podf : 3;            // 26-28 Divider for gpu_axi_podf (IMX_CCM_PODF)
+    UINT32 gpu_core_podf : 3;           // 29-31 Post divider for gpu_core clock (IMX_CCM_PODF)
+    // MSB
+  };
+} IMX_CCM_CBCMR_REG; // SX RM.p816
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 ssi1_clk_podf : 6;           // 0-5 Divider for ssi1 clock podf
+    UINT32 ssi1_clk_pred : 3;           // 6-8 Divider for ssi1 clock pred
+    UINT32 esai_clk_pred : 3;           // 9-11 Divider for esai clock pred
+    UINT32 reserved1 : 4;               // 12-15 Reserved
+    UINT32 ssi3_clk_podf : 6;           // 16-21 Divider for ssi3 clock podf
+    UINT32 ssi3_clk_pred : 3;           // 22-24 Divider for ssi3 clock pred
+    UINT32 esai_clk_podf : 3;           // 25-27 Divider for esai clock podf
+    UINT32 reserved2 : 4;               // 28-31 Reserved
+    // MSB
+  };
+} IMX_CCM_CS1CDR_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 ssi2_clk_podf : 6;           // 0-5 Divider for ssi2 clock podf
+    UINT32 ssi2_clk_pred : 3;           // 6-8 Divider for ssi2 clock pred
+    UINT32 ldb_di0_clk_sel : 3;         // 9-11 Selector for ldb_di0 clock multiplexer
+    UINT32 ldb_di1_clk_sel : 3;         // 12-14 Selector for ldb_di1 clock multiplexer
+    UINT32 qspi2_clk_sel : 3;           // 15-17 Selector for QSPI2 clock multiplexer
+    UINT32 qspi2_clk_pred : 3;          // 18-20 Divider for QSPI1 clock pred divider
+    UINT32 qspi2_clk_podf : 6;          // 21-26 Divider for QSPI2 clock divider
+    UINT32 reserved : 5;                // 27-31
+    // MSB
+  };
+} IMX_CCM_CS2CDR_REG; // SX RM.p827
+
+typedef enum {
+  IMX_CCM_CCGR_OFF = 0x0,               // Clock is off during all modes. Stop enter hardware handshake is disabled.
+  IMX_CCM_CCGR_ON_RUN = 0x1,            // Clock is on in run mode, but off in WAIT and STOP modes
+  IMX_CCM_CCGR_ON = 0x3,                // Clock is on during all modes, except STOP mode.
+} IMX_CCM_CCGR;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 aips_tz1_clk_enable : 2;     // 0-1 aips_tz1 clocks (aips_tz1_clk_enable)
+    UINT32 aips_tz2_clk_enable : 2;     // 2-3 aips_tz2 clocks (aips_tz2_clk_enable)
+    UINT32 apbhdma_hclk_enable : 2;     // 4-5 apbhdma hclk clock (apbhdma_hclk_enable)
+    UINT32 asrc_clk_enable : 2;         // 6-7 asrc clock (asrc_clk_enable)
+    UINT32 caam_secure_mem_clk_enable : 2; // 8-9 caam_secure_mem clock (caam_secure_mem_clk_enable)
+    UINT32 caam_wrapper_aclk_enable : 2; // 10-11 caam_wrapper_aclk clock (caam_wrapper_aclk_enable)
+    UINT32 caam_wrapper_ipg_enable : 2; // 12-13 caam_wrapper_ipg clock (caam_wrapper_ipg_enable)
+    UINT32 can1_clk_enable : 2;         // 14-15 can1 clock (can1_clk_enable)
+    UINT32 can1_serial_clk_enable : 2;  // 16-17 can1_serial clock (can1_serial_clk_enable)
+    UINT32 can2_clk_enable : 2;         // 18-19 can2 clock (can2_clk_enable)
+    UINT32 can2_serial_clk_enable : 2;  // 20-21 can2_serial clock (can2_serial_clk_enable)
+    UINT32 arm_dbg_clk_enable : 2;      // 22-23 CPU debug clocks (arm_dbg_clk_enable)
+    UINT32 dcic1_clk_enable : 2;        // 24-25 dcic 1 clocks (dcic1_clk_enable)
+    UINT32 dcic2_clk_enable : 2;        // 26-27 dcic2 clocks (dcic2_clk_enable)
+    UINT32 reserved : 2;                // 28-29
+    UINT32 aips_tz3_clk_enable : 2;     // 30-31 aips_tz3 clocks (aips_tz3_clk_enable)
+    // MSB
+  };
+} IMX_CCM_CCGR0_REG; // SX RM.p851
+
+// CHSCCDR.m4_clk_sel
+typedef enum {
+  IMX_CHSCCDR_M4_CLK_SEL_DIVIDED_PRE_MUXED_M4_CLOCK,
+  IMX_CHSCCDR_M4_CLK_SEL_IPP_DI0_CLK,
+  IMX_CHSCCDR_M4_CLK_SEL_IPP_DI1_CLK,
+  IMX_CHSCCDR_M4_CLK_SEL_LDB_DI0_CLK,
+  IMX_CHSCCDR_M4_CLK_SEL_LDB_DI1_CLK
+} IMX_CHSCCDR_M4_CLK_SEL;
+
+// CHSCCDR.m4_pre_clk_sel
+typedef enum {
+  IMX_M4_PRE_CLK_SEL_PLL2,
+  IMX_M4_PRE_CLK_SEL_PLL3_SW_CLK,
+  IMX_M4_PRE_CLK_SEL_OSC_CLK_24M,
+  IMX_M4_PRE_CLK_SEL_PLL2_PFD0,
+  IMX_M4_PRE_CLK_SEL_PLL2_PFD2,
+  IMX_M4_PRE_CLK_SEL_PLL3_PFD3
+} IMX_M4_PRE_CLK_SEL;
+
+// CHSCCDR.enet_clk_sel
+typedef enum {
+  IMX_ENET_CLK_SEL_DIVIDED_PREMUXED_ENET_CLK,
+  IMX_ENET_CLK_SEL_IPP_DI0_CLK,
+  IMX_ENET_CLK_SEL_IPP_DI1_CLK,
+  IMX_ENET_CLK_SEL_LDB_DI0_CLK,
+  IMX_ENET_CLK_SEL_LDB_DI1_CLK
+} IMX_ENET_CLK_SEL;
+
+// CHSCCDR.enet_pre_clk_sel
+typedef enum {
+  IMX_ENET_PRE_CLK_SEL_PLL2,
+  IMX_ENET_PRE_CLK_SEL_PLL3_SW_CLK,
+  IMX_ENET_PRE_CLK_SEL_PLL5,
+  IMX_ENET_PRE_CLK_SEL_PLL2_PFD0,
+  IMX_ENET_PRE_CLK_SEL_PLL2_PFD2,
+  IMX_ENET_PRE_CLK_SEL_PLL3_PFD2
+} IMX_ENET_PRE_CLK_SEL;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 m4_clk_sel : 3;              // 0-2 Selector for M4 root clock multiplexer (IMX_CHSCCDR_M4_CLK_SEL)
+        UINT32 m4_podf : 3;                 // 3-5 Divider for M4 clock divider
+        UINT32 m4_pre_clk_sel : 3;          // 6-8 Selector for M4 root clock pre-multiplexer (IMX_M4_PRE_CLK_SEL)
+        UINT32 enet_clk_sel : 3;            // 9-11 Selector for ENET root clock multiplexer (IMX_ENET_CLK_SEL)
+        UINT32 enet_podf : 3;               // 12-14 Divider for ENET clock divider
+        UINT32 enet_pre_clk_sel : 3;        // 15-17 Selector for ENET root clock pre-multiplexer (IMX_ENET_PRE_CLK_SEL)
+        UINT32 reserved : 14;               // 18-31
+        // MSB
+    };
+} IMX_CCM_CHSCCDR_REG; // SX RM.p830
+
+//
+// NOTE: OPENVG clock cannot be gated without gating GPU2D clock as well.
+//       Configure both CG bits (CCM_ANALOG_CCGR1[CG12] and
+//       CCM_ANALOG_CCGR3[CG15]) to gate OPENVG.
+//
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 ecspi1_clk_enable : 2;       // 0-1 ecspi1 clocks (ecspi1_clk_enable)
+    UINT32 ecspi2_clk_enable : 2;       // 2-3 ecspi2 clocks (ecspi2_clk_enable)
+    UINT32 ecspi3_clk_enable : 2;       // 4-5 ecspi3 clocks (ecspi3_clk_enable)
+    UINT32 ecspi4_clk_enable : 2;       // 6-7 ecspi4 clocks (ecspi4_clk_enable)
+    UINT32 ecspi5_clk_enable : 2;       // 8-9 ecspi5 clocks (ecspi5_clk_enable)
+    UINT32 reserved1 : 2;               // 10-11
+    UINT32 epit1_clk_enable : 2;        // 12-13 epit1 clocks (epit1_clk_enable)
+    UINT32 epit2_clk_enable : 2;        // 14-15 epit2 clocks (epit2_clk_enable)
+    UINT32 esai_clk_enable : 2;         // 16-17 esai clocks (esai_clk_enable)
+    UINT32 wakeup_clk_enable : 2;       // 18-19 wakeup clock (wakeup_clk_enable)
+    UINT32 gpt_clk_enable : 2;          // 20-21 gpt bus clock (gpt_clk_enable)
+    UINT32 gpt_serial_clk_enable : 2;   // 22-23 gpt serial clock (gpt_serial_clk_enable)
+    UINT32 reserved2 : 2;               // 24-25
+    UINT32 gpu_clk_enable : 2;          // 26-27 gpu clock (gpu_clk_enable)
+    UINT32 ocram_s_clk_enable : 2;      // 28-29 ocram_s clock (ocram_s_clk_enable)
+    UINT32 canfd_clk_enable : 2;        // 30-31 canfd clock (canfd_clk_enable)
+    // MSB
+  };
+} IMX_CCM_CCGR1_REG;
+
+// CBCDR.ocram_clk_sel
+typedef enum {
+  IMX_CCM_OCRAM_CLK_SEL_PERIPH_CLK,
+  IMX_CCM_OCRAM_CLK_SEL_AXI_ALT_CLK
+} IMX_CCM_OCRAM_CLK_SEL;
+
+// CBCDR.ocram_alt_clk_sel
+typedef enum {
+  IMX_CCM_OCRAM_ALT_CLK_SEL_PLL2_PFD2,
+  IMX_CCM_OCRAM_ALT_CLK_SEL_PLL3_PFD1
+} IMX_CCM_OCRAM_ALT_CLK_SEL;
+
+// CBCDR.periph_clk_sel
+typedef enum {
+  IMX_CCM_PERIPH_CLK_SEL_PRE_PERIPH_CLK_SEL,
+  IMX_CCM_PERIPH_CLK_SEL_PERIPH_CLK2_CLK_DIVIDED
+} IMX_CCM_PERIPH_CLK_SEL;
+
+// CBCDR.periph2_clk_sel
+typedef enum {
+  IMX_CCM_PERIPH2_CLK_SEL_PRE_PERIPH2_CLK,
+  IMX_CCM_PERIPH2_CLK_SEL_PERIPH2_CLK2_CLK_DIVIDED
+} IMX_CCM_PERIPH2_CLK_SEL;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 periph2_clk2_podf : 3;       // 0-2 Divider for periph2_clk2 podf
+    UINT32 fabric_mmdc_podf : 3;        // 3-5 Post divider for fabric / mmdc clock
+    UINT32 ocram_clk_sel : 1;           // 6 OCRAM clock source select (IMX_CCM_OCRAM_CLK_SEL)
+    UINT32 ocram_alt_clk_sel : 1;       // 7 OCRAM alternative clock select (IMX_CCM_OCRAM_ALT_CLK_SEL)
+    UINT32 ipg_podf : 2;                // 8-9 Divider for ipg podf
+    UINT32 ahb_podf : 3;                // 10-12 Divider for AHB PODF
+    UINT32 reserved1 : 3;               // 13-15
+    UINT32 ocram_podf : 3;              // 16-18 Post divider for ocram clock
+    UINT32 reserved2 : 6;               // 19-24
+    UINT32 periph_clk_sel : 1;          // 25 Selector for peripheral main clock (IMX_CCM_PERIPH_CLK_SEL)
+    UINT32 periph2_clk_sel : 1;         // 26 Selector for peripheral2 main clock (source of mmdc_clk_root ) (IMX_CCM_PERIPH2_CLK_SEL)
+    UINT32 periph_clk2_podf : 3;        // 27-29 Divider for periph_clk2_podf
+    UINT32 reserved3 : 2;               // 30-31
+    // MSB
+  };
+} IMX_CCM_CBCDR_REG; // SX RM.p813
+
+// CCOSR.CLKO1_SEL
+typedef enum {
+  IMX_CCM_CLKO1_SEL_VID_CLK_ROOT = 4,
+  IMX_CCM_CLKO1_SEL_OCRAM_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_QSPI2_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_M4_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_ENET_AXI_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_LCDIF2_PIX_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_LCDIF1_PIX_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_AHB_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_IPG_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_PERCLK_ROOT,
+  IMX_CCM_CLKO1_SEL_CKIL_SYNC_CLK_ROOT,
+  IMX_CCM_CLKO1_SEL_PLL4_MAIN_CLK
+} IMX_CCM_CLKO1_SEL;
+
+// CCOSR.CLKO2_SEL
+typedef enum {
+  IMX_CCM_CLKO2_SEL_MMDC_CLK_ROOT = 1,
+  IMX_CCM_CLKO2_SEL_USDHC4_CLK_ROOT = 2,
+  IMX_CCM_CLKO2_SEL_USDHC1_CLK_ROOT = 3,
+  IMX_CCM_CLKO2_SEL_WRCK_CLK_ROOT = 5,
+  IMX_CCM_CLKO2_SEL_ECSPI_CLK_ROOT = 6,
+  IMX_CCM_CLKO2_SEL_USDHC3_CLK_ROOT = 8,
+  IMX_CCM_CLKO2_SEL_PCIE_CLK_ROOT = 9,
+  IMX_CCM_CLKO2_SEL_ARM_CLK_ROOT = 10,
+  IMX_CCM_CLKO2_SEL_CSI_CORE = 11,
+  IMX_CCM_CLKO2_SEL_DISPLAY_AXI_CLK_ROOT = 12,
+  IMX_CCM_CLKO2_SEL_OSC_CLK = 14,
+  IMX_CCM_CLKO2_SEL_USDHC2_CLK_ROOT = 17,
+  IMX_CCM_CLKO2_SEL_SSI1_CLK_ROOT = 18,
+  IMX_CCM_CLKO2_SEL_SSI2_CLK_ROOT = 19,
+  IMX_CCM_CLKO2_SEL_SSI3_CLK_ROOT = 20,
+  IMX_CCM_CLKO2_SEL_GPU_AXI_CLK_ROOT = 21,
+  IMX_CCM_CLKO2_SEL_CAN_CLK_ROOT = 23,
+  IMX_CCM_CLKO2_SEL_LVDS_CLK_ROOT = 24,
+  IMX_CCM_CLKO2_SEL_QSPI1_CLK_ROOT = 25,
+  IMX_CCM_CLKO2_SEL_ESAI_CLK_ROOT = 26,
+  IMX_CCM_CLKO2_SEL_ACLK_EIM_SLOW_CLK_ROOT = 27,
+  IMX_CCM_CLKO2_SEL_UART_CLK_ROOT = 28,
+  IMX_CCM_CLKO2_SEL_SPDIF0_CLK_ROOT = 29,
+  IMX_CCM_CLKO2_SEL_AUDIO_CLK_ROOT = 36
+} IMX_CCM_CLKO2_SEL;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 CLKO1_SEL : 4;               // 0-3 Selection of the clock to be generated on CCM_CLKO1 (IMX_CCM_CLKO1_SEL)
+    UINT32 CLKO1_DIV : 3;               // 4-6 Setting the divider of CCM_CLKO1
+    UINT32 CLKO1_EN : 1;                // 7 Enable of CCM_CLKO1 clock
+    UINT32 CLK_OUT_SEL : 1;             // 8 CCM_CLKO1 output to reflect CCM_CLKO1 or CCM_CLKO2 clocks
+    UINT32 reserved1 : 7;               // 9-15
+    UINT32 CLKO2_SEL : 5;               // 16-20 Selection of the clock to be generated on CCM_CLKO2 (IMX_CCM_CLKO2_SEL)
+    UINT32 CLKO2_DIV : 3;               // 21-23 Setting the divider of CCM_CLKO2
+    UINT32 CLKO2_EN : 1;                // 24 Enable of CCM_CLKO2 clock
+    UINT32 reserved2 : 7;               // 25-31
+    // MSB
+  };
+} IMX_CCM_CCOSR_REG; // SX RM.p847
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 reserved1 : 2;                                   // 0-1
+    UINT32 csi_clk_enable : 2;                              // 2-3 csi clock (csi_clk_enable)
+    UINT32 reserved2 : 2;                                   // 4-5
+    UINT32 i2c1_serial_clk_enable : 2;                      // 6-7 i2c1_serial clock (i2c1_serial_clk_enable)
+    UINT32 i2c2_serial_clk_enable : 2;                      // 8-9 i2c2_serial clock (i2c2_serial_clk_enable)
+    UINT32 i2c3_serial_clk_enable : 2;                      // 10-11 i2c3_serial clock (i2c3_serial_clk_enable)
+    UINT32 iim_clk_enable : 2;                              // 12-13 OCOTP_CTRL clock (iim_clk_enable)
+    UINT32 iomux_ipt_clk_io_enable : 2;                     // 14-15 iomux_ipt_clk_io clock (iomux_ipt_clk_io_enable)
+    UINT32 ipmux1_clk_enable : 2;                           // 16-17 ipmux1 clock (ipmux1_clk_enable)
+    UINT32 ipmux2_clk_enable : 2;                           // 18-19 ipmux2 clock (ipmux2_clk_enable)
+    UINT32 ipmux3_clk_enable : 2;                           // 20-21 ipmux3 clock (ipmux3_clk_enable)
+    UINT32 ipsync_ip2apb_tzasc1_ipg_master_clk_enable : 2;  // 22-23 ipsync_ip2apb_tzasc1_ipg clocks (ipsync_ip2apb_tzasc1_ipg_master_clk_enable)
+    UINT32 reserved3 : 2;                                   // 24-25
+    UINT32 reserved4 : 2;                                   // 26-27
+    UINT32 lcd_clk_enable : 2;                              // 28-29 lcd clocks (lcd_clk_enable)
+    UINT32 pxp_clk_enable : 2;                              // 30-31 pxp clocks (pxp_clk_enable)
+    // MSB
+  };
+} IMX_CCM_CCGR2_REG; // SX RM.p853
+// Check(IMX_CCM_CCGR2_REG, sizeof(UINT32));
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 reserved1 : 2;                          // 0-1
+    UINT32 m4_clk_enable : 2;                      // 2-3 m4 clock (m4_clk_enable)
+    UINT32 enet_clk_enable : 2;                    // 4-5 enet clock (enet_clk_enable)
+    UINT32 disp_axi_clk_enable : 2;                // 6-7 display axi clock (disp_axi_clk_enable)
+    UINT32 lcdif2_pix_clk_enable : 2;              // 8-9 lcdif2 pix clock (lcdif2_pix_clk_enable)
+    UINT32 lcdif1_pix_clk_enable : 2;              // 10-11 lcdif1 pix clock (lcdif1_pix_clk_enable)
+    UINT32 ldb_di0_clk_enable : 2;                 // 12-13 ldb_di0 clock (ldb_di0_clk_enable)
+    UINT32 qspi1_clk_enable : 2;                   // 14-15 qspi1 clock (qspi1_clk_enable)
+    UINT32 reserved2 : 2;                          // 16-17
+    UINT32 mlb_clk_enable : 2;                     // 18-19 mlb clock (mlb_clk_enable)
+    UINT32 mmdc_core_aclk_fast_core_p0_enable : 2; // 20-21 mmdc_core_aclk_fast_core_p0 clock (mmdc_core_aclk_fast_core_p0_enable)
+    UINT32 reserved3 : 2;                          // 22-23
+    UINT32 mmdc_core_ipg_clk_p0_enable : 2;        // 24-25 mmdc_core_ipg_clk_p0 clock (mmdc_core_ipg_clk_p0_enable)
+    UINT32 mmdc_core_ipg_clk_p1_enable : 2;        // 26-27 mmdc_core_ipg_clk_p1 clock (mmdc_core_ipg_clk_p1_enable)
+    UINT32 ocram_clk_enable : 2;                   // 28-29 ocram clock (ocram_clk_enable)
+    UINT32 reserved4 : 2;                          // 30-31
+    // MSB
+  };
+} IMX_CCM_CCGR3_REG;
+
+typedef enum {
+  IMX_CCM_PERCLK_CLK_SEL_IPG_CLK_ROOT = 0,
+  IMX_CCM_PERCLK_CLK_SEL_OSC_CLK = 1
+} IMX_CCM_PERCLK_CLK_SEL;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    UINT32  perclk_podf         : 6; // 0-5 Divider for perclk podf.
+    UINT32  perclk_clk_sel      : 1; // 6 Selector for the perclk clock multiplexor (IMX_CCM_PERCLK_CLK_SEL);
+    UINT32  qspi1_sel           : 3; // 7-9 QSPI1 clock select
+    UINT32  ssi1_clk_sel        : 2; // 10-11 Selector for ssi1 clock multiplexer
+    UINT32  ssi2_clk_sel        : 2; // 12-13 Selector for ssi2 clock multiplexer
+    UINT32  ssi3_clk_sel        : 2; // 14-15 Selector for ssi3 clock multiplexer
+    UINT32  usdhc1_clk_sel      : 1; // 16 Selector for usdhc1 clock multiplexer
+    UINT32  usdhc2_clk_sel      : 1; // 17 Selector for usdhc2 clock multiplexer
+    UINT32  usdhc3_clk_sel      : 1; // 18 Selector for usdhc3 clock multiplexe
+    UINT32  usdhc4_clk_sel      : 1; // 19 Selector for usdhc4 clock multiplexer
+    UINT32  lcdif2_podf         : 3; // 20-22 Post-divider for lcdif2 clock.
+    UINT32  aclk_eim_slow_podf  : 3; // 23-25 Divider for aclk_eim_slow clock root.
+    UINT32  qspi1_podf          : 3; // 26-28 Divider for QSPI1 clock root
+    UINT32  aclk_eim_slow_sel   : 2; // 29-30 Selector for aclk_eim_slow root clock multiplexer
+    UINT32  reserved1           : 1; // 31
+  };
+} IMX_CCM_CSCMR1_REG; // SX RM.p818
+
+typedef struct {
+  UINT32 CCR;                           // 0x00 CCM Control Register (CCM_CCR)
+  UINT32 CCDR;                          // 0x04 CCM Control Divider Register (CCM_CCDR)
+  UINT32 CSR;                           // 0x08 CCM Status Register (CCM_CSR)
+  UINT32 CCSR;                          // 0x0C CCM Clock Switcher Register (CCM_CCSR)
+  UINT32 CACRR;                         // 0x10 CCM Arm Clock Root Register (CCM_CACRR)
+  UINT32 CBCDR;                         // 0x14 CCM Bus Clock Divider Register (CCM_CBCDR)
+  UINT32 CBCMR;                         // 0x18 CCM Bus Clock Multiplexer Register (CCM_CBCMR)
+  UINT32 CSCMR1;                        // 0x1C CCM Serial Clock Multiplexer Register 1 (CCM_CSCMR1)
+  UINT32 CSCMR2;                        // 0x20 CCM Serial Clock Multiplexer Register 2 (CCM_CSCMR2)
+  UINT32 CSCDR1;                        // 0x24 CCM Serial Clock Divider Register 1 (CCM_CSCDR1)
+  UINT32 CS1CDR;                        // 0x28 CCM SSI1 Clock Divider Register (CCM_CS1CDR)
+  UINT32 CS2CDR;                        // 0x2C CCM SSI2 Clock Divider Register (CCM_CS2CDR)
+  UINT32 CDCDR;                         // 0x30 CCM D1 Clock Divider Register (CCM_CDCDR)
+  UINT32 CHSCCDR;                       // 0x34 CCM HSC Clock Divider Register (CCM_CHSCCDR)
+  UINT32 CSCDR2;                        // 0x38 CCM Serial Clock Divider Register 2 (CCM_CSCDR2)
+  UINT32 CSCDR3;                        // 0x3C CCM Serial Clock Divider Register 3 (CCM_CSCDR3)
+  UINT32 reserved1;
+  UINT32 CWDR;                          // 0x44 CCM Wakeup Detector Register (CCM_CWDR)
+  UINT32 CDHIPR;                        // 0x48 CCM Divider Handshake In-Process Register (CCM_CDHIPR)
+  UINT32 reserved2[2];
+  UINT32 CLPCR;                         // 0x54 CCM Low Power Control Register (CCM_CLPCR)
+  UINT32 CISR;                          // 0x58 CCM Interrupt Status Register (CCM_CISR)
+  UINT32 CIMR;                          // 0x5C CCM Interrupt Mask Register (CCM_CIMR)
+  UINT32 CCOSR;                         // 0x60 CCM Clock Output Source Register (CCM_CCOSR)
+  UINT32 CGPR;                          // 0x64 CCM General Purpose Register (CCM_CGPR)
+  UINT32 CCGR[7];                       // 0x68-80 CCM Clock Gating Register 0-6 (CCM_CCGR0-CCM_CCGR6)
+  UINT32 reserved3;
+  UINT32 CMEOR;                         // 0x88 CCM Module Enable Override Register (CCM_CMEOR)
+} IMX_CCM_REGISTERS;
+
+//
+// CCM Analog
+//
+
+typedef enum {
+  IMX_PLL_BYPASS_CLK_SRC_REF_CLK_24M,
+  IMX_PLL_BYPASS_CLK_SRC_CLK1,
+  IMX_PLL_BYPASS_CLK_SRC_GPANAIO, // Only for CCM_ANALOG_PLL_SYS and CCM_ANALOG_PLL_USB1n (SX RM.p868)
+  IMX_PLL_BYPASS_CLK_SRC_CHRG_DET_B // Only for CCM_ANALOG_PLL_SYS and CCM_ANALOG_PLL_USB1n (SX RM.p868)
+} IMX_PLL_BYPASS_CLK_SRC;  // SX RM.p866
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 PFD0_FRAC : 6;               // 0-5 fractional divide value. The resulting frequency shall be 528*18/PFD0_FRAC where PFD0_FRAC is in the range 12-35.
+    UINT32 PFD0_STABLE : 1;             // 6
+    UINT32 PFD0_CLKGATE : 1;            // 7 Set to 1 to gate ref_pfd0
+    UINT32 PFD1_FRAC : 6;               // 8-13 fractional divide value
+    UINT32 PFD1_STABLE : 1;             // 14
+    UINT32 PFD1_CLKGATE : 1;            // 15 Set to 1 to gate ref_pfd1
+    UINT32 PFD2_FRAC : 6;               // 16-21 fractional divide value
+    UINT32 PFD2_STABLE : 1;             // 22
+    UINT32 PFD2_CLKGATE : 1;            // 23 Set to 1 to gate ref_pfd2
+    UINT32 PFD3_FRAC : 6;               // 24-29 fractional divide value
+    UINT32 PFD3_STABLE : 1;             // 30
+    UINT32 PFD3_CLKGATE : 1;            // 31 Set to 1 to gate ref_pfd3
+    // MSB
+  };
+} IMX_CCM_PFD_480_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 PFD0_FRAC : 6;               // 0-5 fractional divide value. The resulting frequency shall be 528*18/PFD0_FRAC where PFD0_FRAC is in the range 12-35.
+    UINT32 PFD0_STABLE : 1;             // 6
+    UINT32 PFD0_CLKGATE : 1;            // 7 Set to 1 to gate ref_pfd0
+    UINT32 PFD1_FRAC : 6;               // 8-13 fractional divide value
+    UINT32 PFD1_STABLE : 1;             // 14
+    UINT32 PFD1_CLKGATE : 1;            // 15 Set to 1 to gate ref_pfd1
+    UINT32 PFD2_FRAC : 6;               // 16-21 fractional divide value
+    UINT32 PFD2_STABLE : 1;             // 22
+    UINT32 PFD2_CLKGATE : 1;            // 23 Set to 1 to gate ref_pfd2
+    UINT32 PFD3_FRAC : 6;               // 24-29 fractional divide value. The resulting frequency shall be 528*18/PFD3_FRAC where PFD3_FRAC is in the range 12-35
+    UINT32 PFD3_STABLE : 1;             // 30
+    UINT32 PFD3_CLKGATE : 1;            // 31 Set to 1 to gate ref_pfd3
+    // MSB
+  };
+} IMX_CCM_PFD_528_REG; // SX RM.p888
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 DIV_SELECT : 7;              // 0-6  Valid range for divider value: 54-108. Fout = Fin * div_select/2.0
+    UINT32 reserved1 : 5;               // 7-11
+    UINT32 POWERDOWN : 1;               // 12 Powers down the PLL.
+    UINT32 ENABLE: 1;                   // 13 Enable the clock output.
+    UINT32 BYPASS_CLK_SRC : 2;          // 14-15 Determines the bypass and PLL reference clock source.
+    UINT32 BYPASS : 1;                  // 16 Bypass the PLL.
+    UINT32 LVDS_SEL : 1;                // 17 Analog Debug Bit
+    UINT32 LVDS_24MHZ_SEL : 1;          // 18 Analog Debug Bit
+    UINT32 reserved2 : 1;               // 19 PLL_SEL (Reserved)
+    UINT32 reserved3 : 11;              // 20-30
+    UINT32 LOCK : 1;                    // 31 1 - PLL is currently locked. 0 - PLL is not currently locked.
+    // MSB
+  };
+} IMX_CCM_ANALOG_PLL_ARM_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 DIV_SELECT : 1;              // 0 0 - Fout=Fref*20; 1 - Fout=Fref*22.
+    UINT32 reserved1 : 11;              // 1-11
+    UINT32 POWERDOWN : 1;               // 12 Powers down the PLL.
+    UINT32 ENABLE : 1;                  // 13 Enable PLL output
+    UINT32 BYPASS_CLK_SRC : 2;          // 14-15 Determines the bypass source.
+    UINT32 BYPASS : 1;                  // 16 Bypass the PLL.
+    UINT32 reserved2 : 1;               // 17
+    UINT32 PFD_OFFSET_EN : 1;           // 18 Enables an offset in the phase frequency detector
+    UINT32 reserved3 : 12;              // 19-30
+    UINT32 LOCK : 1;                    // 31 1 - PLL is currently locked; 0 - PLL is not currently locked.
+    // MSB
+  };
+} IMX_CCM_ANALOG_PLL_SYS_REG;
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 DIV_SELECT : 2;              // 0-1 - Fout=Fref*20; 1 - Fout=Fref*22.
+    UINT32 reserved1 : 4;               // 2-5
+    UINT32 EN_USB_CLKS : 1;             // 6 Powers the 9-phase PLL outputs for USBPHYn
+    UINT32 reserved2 : 5;               // 7-11
+    UINT32 POWER : 1;                   // 12 Powers up the PLL.
+    UINT32 ENABLE : 1;                  // 13 Enable the PLL clock output
+    UINT32 BYPASS_CLK_SRC : 2;          // 14-15 Determines the bypass source
+    UINT32 BYPASS : 1;                  // 16 Bypass the PLL.
+    UINT32 reserved3 : 14;              // 17-30
+    UINT32 LOCK : 1;                    // 31 1 - PLL is currently locked
+    // MSB
+  };
+} IMX_CCM_ANALOG_PLL_USB1_REG;
+
+typedef enum {
+    IMX_POST_DIV_SELECT_DIVIDE_4,
+    IMX_POST_DIV_SELECT_DIVIDE_2,
+    IMX_POST_DIV_SELECT_DIVIDE_1,
+} IMX_CCM_PLL_VIDEO_CTRL_POST_DIV_SELECT;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 DIV_SELECT : 7;          // 0-6 This field controls the PLL loop divider. Valid range for DIV_SELECT divider value: 27~54
+        UINT32 Reserved1 : 5;           // 7-11
+        UINT32 POWERDOWN : 1;           // 12 Powers down the PLL
+        UINT32 ENABLE : 1;              // 13 Enalbe PLL output
+        UINT32 BYPASS_CLK_SRC : 2;      // 14-15 Determines the bypass source
+        UINT32 BYPASS : 1;              // 16 Bypass the PLL
+        UINT32 Reserved2 : 1;           // 17
+        UINT32 PFD_OFFSET_EN : 1;       // 18 Enables an offset in the phase frequency detector
+        UINT32 POST_DIV_SELECT : 2;     // 19-20 These bits implement a divider after the PLL, but before the enable and bypass mux.
+        UINT32 Reserved3 : 1;           // 21
+        UINT32 Reserved4 : 9;           // 22-30 Always set to zero
+        UINT32 LOCK : 1;                // 31 PLL is/not currently locked
+        // MSB
+    };
+} IMX_CCM_PLL_VIDEO_CTRL_REG;
+
+//
+// Power Management Unit
+//
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 REG0_TARG : 5;               // 0-4 target voltage for the ARM core power domain
+    UINT32 reserved1 : 4;               // 5-8
+    UINT32 REG1_TARG : 5;               // 9-13 target voltage for the VPU/GPU power domain
+    UINT32 reserved2 : 4;               // 14-17
+    UINT32 REG2_TARG : 5;               // 18-22 target voltage for the SOC power domain
+    UINT32 reserved3 : 4;               // 23-26
+    UINT32 RAMP_RATE : 2;               // 27-28 Regulator voltage ramp rate
+    UINT32 FET_ODRIVE : 1;              // 29 increases the gate drive on power gating FET
+    UINT32 reserved4 : 2;               // 30-31
+    // MSB
+  };
+} IMX_PMU_REG_CORE_REG;
+
+typedef enum {
+    PLL_ENET_DIV_SELECT_25MHZ = 0,
+    PLL_ENET_DIV_SELECT_50MHZ = 1,
+    PLL_ENET_DIV_SELECT_100MHZ = 2,
+    PLL_ENET_DIV_SELECT_125MHZ = 3,
+} CCM_ANALOG_PLL_ENET_DIV_SELECT;
+
+//
+// CCM ANALOG PLL Ethernet(n) register
+//
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        unsigned  DIV_SELECT : 2;       // 0-1
+        unsigned  Zero1 : 5;            // 2-6
+        unsigned  Reserved1 : 5;        // 7-11
+        unsigned  POWERDOWN : 1;        // 12
+        unsigned  ENABLE : 1;           // 13
+        unsigned  BYPASS_CLK_SRC : 2;   // 14-15
+        unsigned  BYPASS : 1;           // 16
+        unsigned  Reserved2 : 1;        // 17
+        unsigned  PFD_OFFSET_EN : 1;    // 18
+        unsigned  ENABLE_125M : 1;      // 19
+        unsigned  ENABLE_100M : 1;      // 20
+        unsigned  Zero2 : 10;           // 21-30
+        unsigned  LOCK : 1;             // 31
+        // MSB
+    };
+} IMX_CCM_ANALOG_PLL_ENET_REG;
+
+//
+// CCM ANALOG PLL Ethernet(n) register
+//
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        unsigned  LVDS1_CLK_SEL : 5;    // 0-4
+        unsigned  LVDS2_CLK_SEL : 5;    // 5-9
+        unsigned  LVDSCLK1_OBEN : 1;    // 10
+        unsigned  LVDSCLK2_OBEN : 1;    // 11
+        unsigned  LVDSCLK1_IBEN : 1;    // 12
+        unsigned  LVDSCLK2_IBEN : 1;    // 13
+        unsigned  Reserved0 : 15;       // 14-28
+        unsigned  IRQ_TEMPSENSE : 1;    // 29
+        unsigned  IRQ_ANA_BO : 1;       // 30
+        unsigned  IRQ_DIG_BO : 1;       // 31
+        // MSB
+    };
+} IMX_CCM_ANALOG_MISC1_REG;
+
+typedef struct {
+  UINT32 PLL_ARM;                       // 0x000 Analog ARM PLL control Register (CCM_ANALOG_PLL_ARM)
+  UINT32 PLL_ARM_SET;                   // 0x004 Analog ARM PLL control Register (CCM_ANALOG_PLL_ARM_SET)
+  UINT32 PLL_ARM_CLR;                   // 0x008 Analog ARM PLL control Register (CCM_ANALOG_PLL_ARM_CLR)
+  UINT32 PLL_ARM_TOG;                   // 0x00C Analog ARM PLL control Register (CCM_ANALOG_PLL_ARM_TOG)
+  UINT32 PLL_USB1;                      // 0x010 Analog USB1 480MHz PLL Control Register (CCM_ANALOG_PLL_USB1)
+  UINT32 PLL_USB1_SET;                  // 0x014 Analog USB1 480MHz PLL Control Register (CCM_ANALOG_PLL_USB1_SET)
+  UINT32 PLL_USB1_CLR;                  // 0x018 Analog USB1 480MHz PLL Control Register (CCM_ANALOG_PLL_USB1_CLR)
+  UINT32 PLL_USB1_TOG;                  // 0x01C Analog USB1 480MHz PLL Control Register (CCM_ANALOG_PLL_USB1_TOG)
+  UINT32 PLL_USB2;                      // 0x020 Analog USB2 480MHz PLL Control Register (CCM_ANALOG_PLL_USB2)
+  UINT32 PLL_USB2_SET;                  // 0x024 Analog USB2 480MHz PLL Control Register (CCM_ANALOG_PLL_USB2_SET)
+  UINT32 PLL_USB2_CLR;                  // 0x028 Analog USB2 480MHz PLL Control Register (CCM_ANALOG_PLL_USB2_CLR)
+  UINT32 PLL_USB2_TOG;                  // 0x02C Analog USB2 480MHz PLL Control Register (CCM_ANALOG_PLL_USB2_TOG)
+  UINT32 PLL_SYS;                       // 0x030 Analog System PLL Control Register (CCM_ANALOG_PLL_SYS)
+  UINT32 PLL_SYS_SET;                   // 0x034 Analog System PLL Control Register (CCM_ANALOG_PLL_SYS_SET)
+  UINT32 PLL_SYS_CLR;                   // 0x038 Analog System PLL Control Register (CCM_ANALOG_PLL_SYS_CLR)
+  UINT32 PLL_SYS_TOG;                   // 0x03C Analog System PLL Control Register (CCM_ANALOG_PLL_SYS_CLR)
+  UINT32 PLL_SYS_SS;                    // 0x040 528MHz System PLL Spread Spectrum Register (CCM_ANALOG_PLL_SYS_SS)
+  UINT32 reserved1[11];
+  UINT32 PLL_AUDIO;                     // 0x070 Analog Audio PLL control Register (CCM_ANALOG_PLL_AUDIO)
+  UINT32 PLL_AUDIO_SET;                 // 0x074 Analog Audio PLL control Register (CCM_ANALOG_PLL_AUDIO_SET)
+  UINT32 PLL_AUDIO_CLR;                 // 0x078 Analog Audio PLL control Register (CCM_ANALOG_PLL_AUDIO_CLR)
+  UINT32 PLL_AUDIO_TOG;                 // 0x07C Analog Audio PLL control Register (CCM_ANALOG_PLL_AUDIO_TOG)
+  UINT32 PLL_AUDIO_NUM;                 // 0x080 Numerator of Audio PLL Fractional Loop Divider Register (CCM_ANALOG_PLL_AUDIO_NUM)
+  UINT32 reserved2[3];
+  UINT32 PLL_AUDIO_DENOM;               // 0x090 Denominator of Audio PLL Fractional Loop Divider Register (CCM_ANALOG_PLL_AUDIO_DENOM)
+  UINT32 reserved3[3];
+  UINT32 PLL_VIDEO;                     // 0x0A0 Analog Video PLL control Register (CCM_ANALOG_PLL_VIDEO)
+  UINT32 PLL_VIDEO_SET;                 // 0x0A4 Analog Video PLL control Register (CCM_ANALOG_PLL_VIDEO_SET)
+  UINT32 PLL_VIDEO_CLR;                 // 0x0A8 Analog Video PLL control Register (CCM_ANALOG_PLL_VIDEO_CLR)
+  UINT32 PLL_VIDEO_TOG;                 // 0x0AC Analog Video PLL control Register (CCM_ANALOG_PLL_VIDEO_TOG)
+  UINT32 PLL_VIDEO_NUM;                 // 0x0B0 Numerator of Video PLL Fractional Loop Divider Register (CCM_ANALOG_PLL_VIDEO_NUM)
+  UINT32 reserved4[3];
+  UINT32 PLL_VIDEO_DENOM;               // 0x0C0 Denominator of Video PLL Fractional Loop Divider Register (CCM_ANALOG_PLL_VIDEO_DENOM)
+  UINT32 reserved5[7];
+  UINT32 PLL_ENET;                      // 0x0E0 Analog ENET PLL Control Register (CCM_ANALOG_PLL_ENET)
+  UINT32 PLL_ENET_SET;                  // 0x0E4 Analog ENET PLL Control Register (CCM_ANALOG_PLL_ENET_SET)
+  UINT32 PLL_ENET_CLR;                  // 0x0E8 Analog ENET PLL Control Register (CCM_ANALOG_PLL_ENET_CLR)
+  UINT32 PLL_ENET_TOG;                  // 0x0EC Analog ENET PLL Control Register (CCM_ANALOG_PLL_ENET_TOG)
+  UINT32 PFD_480;                       // 0x0F0 480MHz Clock (PLL3) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_480)
+  UINT32 PFD_480_SET;                   // 0x0F4 480MHz Clock (PLL3) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_480_SET)
+  UINT32 PFD_480_CLR;                   // 0x0F8 480MHz Clock (PLL3) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_480_CLR)
+  UINT32 PFD_480_TOG;                   // 0x0FC 480MHz Clock (PLL3) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_480_TOG)
+  UINT32 PFD_528;                       // 0x100 528MHz Clock (PLL2) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_528)
+  UINT32 PFD_528_SET;                   // 0x104 528MHz Clock (PLL2) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_528_SET)
+  UINT32 PFD_528_CLR;                   // 0x108 528MHz Clock (PLL2) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_528_CLR)
+  UINT32 PFD_528_TOG;                   // 0x10C 528MHz Clock (PLL2) Phase Fractional Divider Control Register (CCM_ANALOG_PFD_528_TOG)
+  UINT32 reserved6[16];
+  UINT32 MISC0;                         // 0x150 Miscellaneous Register 0 (CCM_ANALOG_MISC0)
+  UINT32 MISC0_SET;                     // 0x154 Miscellaneous Register 0 (CCM_ANALOG_MISC0_SET)
+  UINT32 MISC0_CLR;                     // 0x158 Miscellaneous Register 0 (CCM_ANALOG_MISC0_CLR)
+  UINT32 MISC0_TOG;                     // 0x15C Miscellaneous Register 0 (CCM_ANALOG_MISC0_TOG)
+  UINT32 MISC1;                         // 0x160 Miscellaneous Register 1 (CCM_ANALOG_MISC1)
+  UINT32 MISC1_SET;                     // 0x164 Miscellaneous Register 1 (CCM_ANALOG_MISC1_SET)
+  UINT32 MISC1_CLR;                     // 0x168 Miscellaneous Register 1 (CCM_ANALOG_MISC1_CLR)
+  UINT32 MISC1_TOG;                     // 0x16C Miscellaneous Register 1 (CCM_ANALOG_MISC1_TOG)
+  UINT32 MISC2;                         // 0x170 Miscellaneous Register 2 (CCM_ANALOG_MISC2)
+  UINT32 MISC2_SET;                     // 0x174 Miscellaneous Register 2 (CCM_ANALOG_MISC2_SET)
+  UINT32 MISC2_CLR;                     // 0x178 Miscellaneous Register 2 (CCM_ANALOG_MISC2_CLR)
+  UINT32 MISC2_TOG;                     // 0x17C Miscellaneous Register 2 (CCM_ANALOG_MISC2_TOG)
+} IMX_CCM_ANALOG_REGISTERS; // SX RM.p864
+
+//
+// General Power Controller (GPC)
+//
+
+#define IMX_GPC_BASE 0x020DC000
+#define IMX_GPC_LENGTH 0x1000
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 PCR : 1;                     // 0 Power Control
+    UINT32 reserved : 31;               // 1-31
+    // MSB
+  };
+} IMX_GPC_PGC_PGCR_REG;
+
+#define IMX_GPC_PGC_PUPSCR_SW_DEFAULT 1
+#define IMX_GPC_PGC_PUPSCR_SW2ISO_DEFAULT 0xf
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 SW : 6;                      // 0-5 number of IPG clock cycles before asserting power toggle on/off signal (switch_b)
+    UINT32 reserved1 : 2;               // 6-7
+    UINT32 SW2ISO : 6;                  // 8-13 IPG clock cycles before negating isolation
+    UINT32 reserved2 : 18;              // 14-31
+    // MSB
+  };
+} IMX_GPC_PGC_PUPSCR_REG;
+
+#define IMX_GPC_PGC_PDNSCR_ISO_DEFAULT 1
+#define IMX_GPC_PGC_PDNSCR_ISO2SW_DEFAULT 1
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 ISO : 6;                     // 0-5 number of IPG clocks before isolation
+    UINT32 reserved1 : 2;               // 6-7
+    UINT32 ISO2SW : 6;                  // 8-13 number of IPG clocks before negating power toggle on/off signal (switch_b)
+    UINT32 reserved2 : 18;              // 14-31
+    // MSB
+  };
+} IMX_GPC_PGC_PDNSCR_REG;
+
+typedef struct {
+  UINT32 CTRL;                          // 0x0 PGC Control Register (PGC_GPU/CPU_CTRL)
+  UINT32 PUPSCR;                        // 0x4 Power Up Sequence Control Register (PGC_GPU/CPU_PUPSCR)
+  UINT32 PDNSCR;                        // 0x8 Pull Down Sequence Control Register (PGC_GPU/CPU_PDNSCR)
+  UINT32 SR;                            // 0xC Power Gating Controller Status Register (PGC_GPU/CPU_SR)
+} IMX_GPC_PGC_REGISTERS;
+
+//
+// General Power Controller (GPC)
+//
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 gpu_vpu_pdn_req : 1;         // 0 GPU/VPU Power Down request. Self-cleared bit.
+    UINT32 gpu_vpu_pup_req : 1;         // 1 GPU/VPU Power Up request. Self-cleared bit.
+    UINT32 MEGA_PDN_REQ : 1;            // 2 MEGA domain power down request. Self-clear bit.
+    UINT32 MEGA_PUP_REQ : 1;            // 3 MEGA domain power up request. Self-clear bit.
+    UINT32 DISPLAY_PDN_REQ : 1;         // 4 Display Power Down request. Self-cleared bit.
+    UINT32 DISPLAY_PUP_REQ : 1;         // 5 Display Power Up request. Self-cleared bit.
+    UINT32 PCIE_PHY_PDN_REQ : 1;        // 6 PCIE PHY power down request. Self-clear bit.
+    UINT32 PCIE_PHY_PUP_REQ : 1;        // 7 PCIE PHY power up request. Self-clear bit.
+    UINT32 reserved1 : 8;               // 8-15
+    UINT32 DVFS0CR : 1;                 // 16 DVFS0 (ARM) Change request (bit is read-only)
+    UINT32 VADC_ANALOG_OFF : 1;         // 17 Indication to VADC whether the analog power to VADC is available or not
+    UINT32 VADC_EXT_PWD_N : 1;          // 18 VADC power down bit
+    UINT32 reserved2 : 2;               // 19-20
+    UINT32 GPCIRQM : 1;                 // 21 GPC interrupt/event masking
+    UINT32 L2_PGE : 1;                  // 22 L2 Cache Power Gate Enable
+    UINT32 reserved3 : 9;              // 23-31
+    // MSB
+  };
+} IMX_GPC_CNTR_REG; //SX RM.p1466
+
+typedef struct {
+  UINT32 CNTR;                          // 0x000 GPC Interface control register (GPC_CNTR)
+  UINT32 PGR;                           // 0x004 GPC Power Gating Register (GPC_PGR)
+  UINT32 IMR1;                          // 0x008 IRQ masking register 1 (GPC_IMR1)
+  UINT32 IMR2;                          // 0x00C IRQ masking register 2 (GPC_IMR2)
+  UINT32 IMR3;                          // 0x010 IRQ masking register 3 (GPC_IMR3)
+  UINT32 IMR4;                          // 0x014 IRQ masking register 4 (GPC_IMR4)
+  UINT32 ISR1;                          // 0x018 IRQ status resister 1 (GPC_ISR1)
+  UINT32 ISR2;                          // 0x01C IRQ status resister 2 (GPC_ISR2)
+  UINT32 ISR3;                          // 0x020 IRQ status resister 3 (GPC_ISR3)
+  UINT32 ISR4;                          // 0x024 IRQ status resister 4 (GPC_ISR4)
+  UINT32 reserved1[142];
+  IMX_GPC_PGC_REGISTERS PGC_GPU;        // 0x260-0x26C GPU PGC Control
+  UINT32 reserved2[12];
+  IMX_GPC_PGC_REGISTERS PGC_CPU;        // 0x2A0-0x2AC CPU PGC Control
+} IMX_GPC_REGISTERS;
+
+//
+// Ethernet controller (ENET)
+//
+
+#define IMX_ENET_BASE 0x02188000
+#define IMX_ENET_LENGTH 0x4000
+
+typedef union {
+  UINT32 AsUint32;
+  struct {
+    // LSB
+    UINT32 RESET : 1;                   // 0 Ethernet MAC Reset
+    UINT32 ETHEREN : 1;                 // 1 Ethernet Enable
+    UINT32 MAGICEN : 1;                 // 2 Magic Packet Detection Enable
+    UINT32 SLEEP : 1;                   // 3 Sleep Mode Enable
+    UINT32 EN1588 : 1;                  // 4 EN1588 Enable
+    UINT32 SPEED : 1;                   // 5 Selects between 10/100 and 1000 Mbps modes of operation
+    UINT32 DBGEN : 1;                   // 6 Debug Enable
+    UINT32 reserved1 : 1;               // 7
+    UINT32 DBSWP : 1;                   // 8 Descriptor Byte Swapping Enable
+    UINT32 SVLANEN : 1;                 // 9 Enable additional detection of S-VLAN tag according to IEEE802.1Q
+    UINT32 VLANUSE2ND : 1;              // 10 VLAN use second tag
+    UINT32 SVLANDBL : 1;                // 11 S-VLAN double tag
+    UINT32 reserved2 : 4;               // 12-15 This field must be set to 0
+    UINT32 TXC_DLY : 1;                 // 16 Transmit clock delay
+    UINT32 RXC_DLY : 1;                 // 17 Receive clock delay
+    UINT32 reserved3 : 14;              // 18-31 This field must be set to 01110000000000b = 0x1C00
+    // MSB
+  };
+} IMX_ENET_ECR_REG;
+
+#define IMX_ENET_ECR_REG_SET_RESERVED(ecrReg) (ecrReg)->reserved3 = 0x1C00
+
+typedef struct {
+  UINT32 reserved0;     // 0
+  UINT32 EIR;           // 4
+  UINT32 EIMR;          // 8
+  UINT32 reserved1;     // Ch
+  UINT32 RDAR;          // 10h
+  UINT32 TDAR;          // 14h
+  UINT32 reserved2[3];  // 18h - 20h
+  UINT32 ECR;           // 24h Ethernet Control Register (ENET_ECR)
+  UINT32 reserved3[6];  // 28h - 3Ch
+  UINT32 MMFR;          // 40h
+  UINT32 MSCR;          // 44h
+  UINT32 reserved4[7];  // 48h - 60h
+  UINT32 MIBC;          // 64h
+  UINT32 reserved5[7];  //
+  UINT32 RCR;           // 84h
+  UINT32 reserved6[15]; //
+  UINT32 TCR;           // C4h
+  UINT32 reserved7[7];
+  UINT32 PALR;          // E4h
+  UINT32 PAUR;          // E8h
+  UINT32 OPD;           // ECh
+  UINT32 reserved8[322];
+} IMX_ENET_REGISTERS;
+
+//
+// GPIO Controller (GPIO)
+//
+
+#define IMX_GPIO_BASE 0x0209C000
+#define IMX_GPIO_LENGTH (7 * 0x4000)
+
+//
+// USB CORE (EHCI)
+//
+
+#define IMX_USBCORE_BASE 0x02184000
+#define IMX_USBCORE_LENGTH 0x200
+    #define IMX_USBCMD_OFFSET 0x140
+    #define IMX_USBMODE_OFFSET 0x1A8
+
+//
+// To do:
+// - Add the USB Core register file
+//
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 RS : 1;          // 0 Run/Stop (RS) . Read/Write. Default 0b. 1=Run. 0=Stop.
+        UINT32 RST : 1;         // 1 Controller Reset (RESET) - Read/Write.
+        UINT32 FS_1 : 2;        // 2-3 Frame List Size (Read/Write or Read Only). Default 000b.
+        UINT32 PSE : 1;         // 4 Periodic Schedule Enable- Read/Write. Default 0b.
+        UINT32 ASE : 1;         // 5 Asynchronous Schedule Enable Read/Write. Default 0b.
+        UINT32 IAA : 1;         // 6 Interrupt on Async Advance Doorbell Read/Write.
+        UINT32 reserved1 : 1;   // 7
+        UINT32 ASP : 2;         // 8-9 Asynchronous Schedule Park Mode Count (OPTIONAL) . Read/Write.
+        UINT32 reserved2 : 1;   // 10 Reserved. These bits are reserved and should be set to zero.
+        UINT32 ASPE : 1;        // 11 Asynchronous Schedule Park Mode Enable (OPTIONAL) . Read/Write.
+        UINT32 ATDTW : 1;       // 12 Add dTD TripWire - Read/Write. [device mode only]
+        UINT32 SUTW : 1;        // 13 Setup TripWire - Read/Write. [device mode only]
+        UINT32 reserved3 : 1;   // 14
+        UINT32 FS2 : 1;         // 15 Frame List Size - (Read/Write or Read Only). [host mode only]
+        UINT32 ITC : 8;         // 16-23 Interrupt Threshold Control Read/Write. Default 08h.
+        UINT32 reserved : 8;    // 24-31 Reserved. These bits are reserved and should be set to zero.
+        // LSB
+    };
+} USB_USBCMD_REG;
+
+typedef enum {
+    IMX_USBMODE_IDLE = 0,
+    IMX_USBMODE_DEVICE = 2,
+    IMX_USBMODE_HOST = 3,
+} IMX_USBMODE_CM;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 CM : 2;          // 0-1 Controller Mode.
+        UINT32 ES : 1;          // 1 Endian Select (0- Little, 1-Big)
+        UINT32 SLOM : 1;        // 3 Setup Lockout Mode
+        UINT32 SDIS : 1;        // 4 Stream Disable Mode
+        UINT32 reserved : 26;   // 5-31
+        // LSB
+    };
+} USB_USBMODE_REG;
+
+//
+// USB Non-CORE
+//
+
+#define IMX_USBNONCORE_BASE 0x02184800
+#define IMX_USBNONCORE_LENGTH 0x20
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 reserved1 : 7;       // 0-6
+        UINT32 OVER_CUR_DIS : 1;    // 7 Disable Overcurrent Detection
+        UINT32 OVER_CUR_POL : 1;    // 8 Polarity of Overcurrent (1-active low, 0-active high)
+        UINT32 PWR_POL : 1;         // 9 Power Polarity (1-active high, 0-active low)
+        UINT32 WIE : 1;             // 10 Wake-up Interrupt Enable
+        UINT32 RESET : 1;           // 11 Force Host 1 UTMI PHY Reset.
+        UINT32 SUSPENDM : 1;        // 12 Force Host 1 UTMI PHY Suspend.
+        UINT32 UTMI_ON_CLOCK : 1;   // 13 Force UTMI PHY clock output on even if in low-power suspend mode.
+        UINT32 WKUP_SW_EN : 1;      // 14 Software Wake-up Enable
+        UINT32 WKUP_SW : 1;         // 15 Software Wake-up
+        UINT32 WKUP_ID_EN : 1;      // 16 Wake-up on ID change enable
+        UINT32 WKUP_VBUS_EN : 1;    // 17 wake-up on VBUS change enable
+        UINT32 reserved2 : 13;      // 18-30
+        UINT32 WIR : 1;             // 31 Wake-up Interrupt Request
+        // LSB
+    };
+} USBNC_USB_UH_CTRL_REG;
+
+typedef struct {
+    UINT32 USBNC_USB_OTG_CTRL;          // 0x00 USB OTG Control Register (USBNC_USB_OTG_CTRL)
+    UINT32 USBNC_USB_UH1_CTRL;          // 0x04 USB Host1 Control Register (USBNC_USB_UH1_CTRL)
+    UINT32 USBNC_USB_UH2_CTRL;          // 0x08 USB Host2 Control Register (USBNC_USB_UH2_CTRL)
+    UINT32 USBNC_USB_UH3_CTRL;          // 0x0C USB Host3 Control Register (USBNC_USB_UH3_CTRL)
+    UINT32 USBNC_USB_UH2_HSIC_CTRL;     // 0x10 USB Host2 HSIC Control Register (USBNC_USB_UH2_HSIC_CTRL)
+    UINT32 USBNC_USB_UH3_HSIC_CTRL;     // 0x14 USB Host3 HSIC Control Register (USBNC_USB_UH3_HSIC_CTRL)
+    UINT32 USBNC_USB_OTG_PHY_CTRL_0;    // 0x18 OTG UTMI PHY Control 0 Register (USBNC_USB_OTG_PHY_CTRL_0)
+    UINT32 USBNC_USB_UH1_PHY_CTRL_0;    // 0x1C Host1 UTMI PHY Control 0 Register (USBNC_USB_UH1_PHY_CTRL_0)
+} IMX_USBNONCORE_REGISTERS;
+
+
+//
+// USB PHY
+//
+
+#define IMX_USBPHY1_BASE 0x020C9000
+#define IMX_USBPHY2_BASE 0x020CA000
+#define IMX_USBPHY_LENGTH 0x1000
+
+typedef enum {
+    IMX_USBPHY0, // OTG
+    IMX_USBPHY1,
+
+    IMX_USBPHY_COUNT
+} IMX_USBPHY_ID;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 ENOTG_ID_CHG_IRQ : 1;        // 0 Enable OTG_ID_CHG_IRQ.
+        UINT32 ENHOSTDISCONDETECT : 1;      // 1 For host mode, enables high-speed disconnect detector.
+        UINT32 ENIRQHOSTDISCON : 1;         // 2 Enables interrupt for detection of disconnection to Device when in high-speed host mode.
+        UINT32 HOSTDISCONDETECT_IRQ : 1;    // 3 Indicates that the device has disconnected in high-speed mode.
+        UINT32 ENDEVPLUGINDETECT : 1;       // 4 For device mode, enables 200-KOhm pullups for detecting connectivity to the host.
+        UINT32 DEVPLUGIN_POLARITY : 1;      // 5 For device mode interrupt generation polarity
+        UINT32 OTG_ID_CHG_IRQ : 1;          // 6 OTG ID change interrupt. Indicates the value of ID pin changed.
+        UINT32 ENOTGIDDETECT : 1;           // 7 Enables circuit to detect resistance of MiniAB ID pin.
+        UINT32 RESUMEIRQSTICKY : 1;         // 8 1 makes RESUME_IRQ bit a sticky bit.
+        UINT32 ENIRQRESUMEDETECT : 1;       // 9 Enables interrupt for detection of a non-J state on the USB line.
+        UINT32 RESUME_IRQ : 1;              // 10 Indicates that the host is sending a wake-up after suspend
+        UINT32 ENIRQDEVPLUGIN : 1;          // 11 Enables interrupt for the detection of connectivity to the USB line.
+        UINT32 DEVPLUGIN_IRQ : 1;           // 12 Indicates that the device is connected
+        UINT32 DATA_ON_LRADC : 1;           // 13 Enables the LRADC to monitor USB_DP and USB_DM.
+        UINT32 ENUTMILEVEL2 : 1;            // 14 Enables UTMI+ Level2.
+        UINT32 ENUTMILEVEL3 : 1;            // 15 Enables UTMI+ Level3.
+        UINT32 ENIRQWAKEUP : 1;             // 16 Enables interrupt for the wakeup events
+        UINT32 WAKEUP_IRQ : 1;              // 17 Indicates that there is a wakeup event.
+        UINT32 reserved1 : 1;               // 18 reserved
+        UINT32 ENAUTOCLR_CLKGATE : 1;       // 19 Enables the feature to auto-clear the CLKGATE bit if there is wakeup event while USB is suspended.
+        UINT32 ENAUTOCLR_PHY_PWD : 1;       // 20 Enables the feature to auto-clear the PWD register bits in USBPHYx_PWD if there is wakeup event while USB is suspended
+        UINT32 ENDPDMCHG_WKUP : 1;          // 21 Enables the feature to wakeup USB if DP/DM is toggled when USB is suspended
+        UINT32 ENIDCHG_WKUP : 1;            // 22 Enables the feature to wakeup USB if ID is toggled when USB is suspended
+        UINT32 ENVBUSCHG_WKUP : 1;          // 23 Enables the feature to wakeup USB if VBUS is toggled when USB is suspended.
+        UINT32 FSDLL_RST_EN : 1;            // 24 Enables the feature to reset the FSDLL lock detection logic at the end of each TX packet.
+        UINT32 reserved2 : 2;               // 25-26
+        UINT32 OTG_ID_VALUE : 1;            // 27
+        UINT32 HOST_FORCE_LS_SE0 : 1;       // 28 Forces the next FS packet that is transmitted to have a EOP with LS timing.
+        UINT32 UTMI_SUSPENDM : 1;           // 29 Used by the PHY to indicate a powered-down state.
+        UINT32 CLKGATE : 1;                 // 30 Gate UTMI Clocks. Clear to 0 to run clocks.
+        UINT32 SFTRST : 1;                  // 31 Soft-reset the USBPHYx_PWD, USBPHYx_TX, USBPHYx_RX, Set to 0 to release the PHY from reset.
+        // MSB
+    };
+} USBPHYx_CTRL_REG;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 STEP : 16;   // 0-15 Fixed read-only value reflecting the stepping of the RTL version.
+        UINT32 MINOR : 8;   // 16-23 Fixed read-only value reflecting the MINOR field of the RTL version.
+        UINT32 MAJOR : 8;   // 24-31 Fixed read-only value reflecting the MAJOR field of the RTL version
+        // MSB
+    };
+} USBPHYx_VERSION_REG;
+
+typedef struct {
+    UINT32 USBPHY_PWD;             // 0x00 USB PHY Power-Down Register (USBPHY_PWD)
+    UINT32 USBPHY_PWD_SET;         // 0x04 USB PHY Power-Down Register (USBPHY_PWD_SET)
+    UINT32 USBPHY_PWD_CLR;         // 0x08 USB PHY Power-Down Register (USBPHY_PWD_CLR)
+    UINT32 USBPHY_PWD_TOG;         // 0x0C USB PHY Power-Down Register (USBPHY_PWD_TOG)
+    UINT32 USBPHY_TX;              // 0x10 USB PHY Transmitter Control Register (USBPHY_TX)
+    UINT32 USBPHY_TX_SET;          // 0x14 USB PHY Transmitter Control Register (USBPHY_TX_SET)
+    UINT32 USBPHY_TX_CLR;          // 0x18 USB PHY Transmitter Control Register (USBPHY_TX_CLR)
+    UINT32 USBPHY_TX_TOG;          // 0x1C USB PHY Transmitter Control Register (USBPHY_TX_TOG)
+    UINT32 USBPHY_RX;              // 0x20 USB PHY Receiver Control Register (USBPHY_RX)
+    UINT32 USBPHY_RX_SET;          // 0x24 USB PHY Receiver Control Register(USBPHY_RX_SET)
+    UINT32 USBPHY_RX_CLR;          // 0x28 USB PHY Receiver Control Register (USBPHY_RX_CLR)
+    UINT32 USBPHY_RX_TOG;          // 0x2C USB PHY Receiver Control Register (USBPHY_RX_TOG)
+    UINT32 USBPHY_CTRL;            // 0x30 USB PHY General Control Register (USBPHY_CTRL)
+    UINT32 USBPHY_CTRL_SET;        // 0x34 USB PHY General Control Register (USBPHY_CTRL_SET)
+    UINT32 USBPHY_CTRL_CLR;        // 0x38 USB PHY General Control Register (USBPHY_CTRL_CLR)
+    UINT32 USBPHY_CTRL_TOG;        // 0x3C USB PHY General Control Register (USBPHY_CTRL_TOG)
+    UINT32 USBPHY_STATUS;          // 0x40 USB PHY Status Register (USBPHY_STATUS)
+    UINT32 reserved1[3];
+    UINT32 USBPHY_DEBUG;           // 0x50 USB PHY Debug Register (USBPHY_DEBUG)
+    UINT32 USBPHY_DEBUG_SET;       // 0x54 USB PHY Debug Register(USBPHY_DEBUG_SET)
+    UINT32 USBPHY_DEBUG_CLR;       // 0x58 USB PHY Debug Register (USBPHY_DEBUG_CLR)
+    UINT32 USBPHY_DEBUG_TOG;       // 0x5C USB PHY Debug Register(USBPHY_DEBUG_TOG)
+    UINT32 USBPHY_DEBUG0_STATUS;   // 0x60 UTMI Debug Status Register 0 (USBPHY_DEBUG0_STATUS)
+    UINT32 reserved2[3];
+    UINT32 USBPHY_DEBUG1;          // 0x70 UTMI Debug Status Register 1 (USBPHY_DEBUG1)
+    UINT32 USBPHY_DEBUG1_SET;      // 0x74 UTMI Debug Status Register 1 (USBPHY_DEBUG1_SET)
+    UINT32 USBPHY_DEBUG1_CLR;      // 0x78 UTMI Debug Status Register 1 (USBPHY_DEBUG1_CLR)
+    UINT32 USBPHY_DEBUG1_TOG;      // 0x7C UTMI Debug Status Register 1 (USBPHY_DEBUG1_TOG)
+    UINT32 USBPHY_VERSION;         // 0x80 UTMI RTL Version (USBPHYx_VERSION)
+} IMX_USBPHY_REGISTERS;
+
+//
+// USB Analog
+//
+
+#define IMX_USBANA_BASE 0x020C81A0
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 reserved1 : 18;  // 0-17
+        UINT32 CHK_CONTACT : 1; // 18
+        UINT32 CHK_CHRG_B : 1;  // 19
+        UINT32 EN_B : 1;        // 20
+        UINT32 reserved2 : 11;  // 21-31
+        // MSB
+    };
+} USB_ANALOG_USB_CHRG_DETECT_REG;
+
+typedef union {
+    UINT32 AsUint32;
+    struct {
+        // LSB
+        UINT32 HS_USE_EXTERNAL_R : 1;  // 0 Use external resistor to generate the current bias for the high speed transmitter.
+        UINT32 EN_DEGLITCH : 1;        // 1 Enable the deglitching circuit of the USB PLL output.
+        UINT32 reserved1 : 28;         // 2-29
+        UINT32 EN_CLK_UTMI : 1;        // Enables the clk to the UTMI block.
+        UINT32 reserved2 : 1;          // 31
+        // MSB
+    };
+} USB_ANALOG_USB_MISC_REG;
+
+typedef struct {
+    UINT32 USB_ANALOG_USB_VBUS_DETECT;       // 0x00 USB VBUS Detect Register (USB_ANALOG_USB_VBUS_DETECT)
+    UINT32 USB_ANALOG_USB_VBUS_DETECT_SET;   // 0x04 USB VBUS Detect Register (USB_ANALOG_USB_VBUS_DETECT_SET)
+    UINT32 USB_ANALOG_USB_VBUS_DETECT_CLR;   // 0x08 USB VBUS Detect Register (USB_ANALOG_USB_VBUS_DETECT_CLR)
+    UINT32 USB_ANALOG_USB_VBUS_DETECT_TOG;   // 0x0C USB VBUS Detect Register (USB_ANALOG_USB_VBUS_DETECT_TOG)
+    UINT32 USB_ANALOG_USB_CHRG_DETECT;       // 0x10 USB Charger Detect Register (USB_ANALOG_USB_CHRG_DETECT)
+    UINT32 USB_ANALOG_USB_CHRG_DETECT_SET;   // 0x14 USB Charger Detect Register (USB_ANALOG_USB_CHRG_DETECT_SET)
+    UINT32 USB_ANALOG_USB_CHRG_DETECT_CLR;   // 0x18 USB Charger Detect Register (USB_ANALOG_USB_CHRG_DETECT_CLR)
+    UINT32 USB_ANALOG_USB_CHRG_DETECT_TOG;   // 0x1C USB Charger Detect Register (USB_ANALOG_USB_CHRG_DETECT_TOG)
+    UINT32 USB_ANALOG_USB_VBUS_DETECT_STAT;  // 0x20 USB VBUS Detect Status Register (USB_ANALOG_USB_VBUS_DETECT_STAT)
+    UINT32 reserved1[3];
+    UINT32 USB_ANALOG_USB_CHRG_DETECT_STAT;  // 0x30 USB Charger Detect Status Register (USB_ANALOG_USB_CHRG_DETECT_STAT)
+    UINT32 reserved2[7];
+    UINT32 USB_ANALOG_USB_MISC;              // 0x50 USB Misc Register (USB_ANALOG_USB_MISC)
+    UINT32 USB_ANALOG_USB_MISC_SET;          // 0x54 USB Misc Register (USB_ANALOG_USB_MISC_SET)
+    UINT32 USB_ANALOG_USB_MISC_CLR;          // 0x58 USB Misc Register (USB_ANALOG_USB_MISC_CLR)
+    UINT32 USB_ANALOG_USB_MISC_TOG;          // 0x5C USB Misc Register (USB_ANALOG_USB_MISC_TOG)
+} IMX_USBANA_USB_REGISTERS;
+
+typedef struct {
+    IMX_USBANA_USB_REGISTERS USBANA[IMX_USBPHY_COUNT];
+    UINT32 USB_ANALOG_DIGPROG;                // 0xC0 Chip Silicon Version (USB_ANALOG_DIGPROG)
+} IMX_USBANA_REGISTERS;
+
+#pragma pack(pop)
+
+#endif // __IMX6_SX_H__
-- 
2.16.2.gvfs.1.33.gf5370f1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH edk2-platforms 02/13] Silicon/NXP: Add i.MX6 GPT and EPIT timer headers
  2018-07-20  6:33 [PATCH edk2-platforms 00/13] Silicon/NXP: Import NXP i.MX6 Package Chris Co
  2018-07-20  6:33 ` [PATCH edk2-platforms 01/13] Silicon/NXP: Add i.MX6 SoC header files Chris Co
@ 2018-07-20  6:33 ` Chris Co
  2018-07-20  6:33 ` [PATCH edk2-platforms 03/13] Silicon/NXP: Add iMX6Pkg dec Chris Co
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chris Co @ 2018-07-20  6:33 UTC (permalink / raw)
  To: edk2-devel@lists.01.org; +Cc: Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This adds the definitions for the NXP i.MX6 General Purpose Timer
and the Enhanced Periodic Interrupt Timer modules.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Christopher Co <christopher.co@microsoft.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/NXP/iMX6Pkg/Include/common_epit.h | 158 ++++++++++
 Silicon/NXP/iMX6Pkg/Include/common_gpt.h  | 314 ++++++++++++++++++++
 2 files changed, 472 insertions(+)

diff --git a/Silicon/NXP/iMX6Pkg/Include/common_epit.h b/Silicon/NXP/iMX6Pkg/Include/common_epit.h
new file mode 100644
index 000000000000..a0be49f59da0
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Include/common_epit.h
@@ -0,0 +1,158 @@
+/** @file
+*
+*  Provides definitions for the EPIT (Enhanced Periodic Interrupt Timer)
+*  module that are common to Freescale SoCs.
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Copyright (c) 2004-2010, Freescale Semiconductor, Inc. All Rights Reserved.
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __COMMON_EPIT_H
+#define __COMMON_EPIT_H
+
+#if __cplusplus
+extern "C" {
+#endif
+
+
+//------------------------------------------------------------------------------
+// GENERAL MODULE CONSTANTS
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+// REGISTER LAYOUT
+//------------------------------------------------------------------------------
+typedef struct
+{
+     UINT32 CR;
+     UINT32 SR;
+     UINT32 LR;
+     UINT32 CMPR;
+     UINT32 CNT;
+} CSP_EPIT_REG, *PCSP_EPIT_REG;
+
+
+//------------------------------------------------------------------------------
+// REGISTER OFFSETS
+//------------------------------------------------------------------------------
+#define EPIT_CR_OFFSET          0x0000
+#define EPIT_SR_OFFSET          0x0004
+#define EPIT_LR_OFFSET          0x0008
+#define EPIT_CMPR_OFFSET        0x000C
+#define EPIT_CNR_OFFSET         0x0010
+
+
+//------------------------------------------------------------------------------
+// REGISTER BIT FIELD POSITIONS (LEFT SHIFT)
+//------------------------------------------------------------------------------
+#define EPIT_CR_EN_LSH          0
+#define EPIT_CR_ENMOD_LSH       1
+#define EPIT_CR_OCIEN_LSH       2
+#define EPIT_CR_RLD_LSH         3
+#define EPIT_CR_PRESCALAR_LSH   4
+#define EPIT_CR_SWR_LSH         16
+#define EPIT_CR_IOVW_LSH        17
+#define EPIT_CR_DBGEN_LSH       18
+#define EPIT_CR_WAITEN_LSH      19
+#define EPIT_CR_DOZEN_LSH       20
+#define EPIT_CR_STOPEN_LSH      21
+#define EPIT_CR_OM_LSH          22
+#define EPIT_CR_CLKSRC_LSH      24
+
+#define EPIT_SR_OCIF_LSH        0
+
+#define EPIT_LR_LOAD_LSH        0
+
+#define EPIT_CMPR_COMPARE_LSH   0
+
+#define EPIT_CNT_COUNT_LSH      0
+
+
+//------------------------------------------------------------------------------
+// REGISTER BIT FIELD WIDTHS
+//------------------------------------------------------------------------------
+#define EPIT_CR_EN_WID          1
+#define EPIT_CR_ENMOD_WID       1
+#define EPIT_CR_OCIEN_WID       2
+#define EPIT_CR_RLD_WID         1
+#define EPIT_CR_PRESCALAR_WID   12
+#define EPIT_CR_SWR_WID         1
+#define EPIT_CR_IOVW_WID        1
+#define EPIT_CR_DBGEN_WID       1
+#define EPIT_CR_WAITEN_WID      1
+#define EPIT_CR_DOZEN_WID       1
+#define EPIT_CR_STOPEN_WID      1
+#define EPIT_CR_OM_WID          2
+#define EPIT_CR_CLKSRC_WID      2
+
+#define EPIT_SR_OCIF_WID        1
+
+#define EPIT_LR_LOAD_WID        32
+
+#define EPIT_CMPR_COMPARE_WID   32
+
+#define EPIT_CNT_COUNT_WID      32
+
+
+//------------------------------------------------------------------------------
+// REGISTER BIT WRITE VALUES
+//------------------------------------------------------------------------------
+
+// CR
+#define EPIT_CR_EN_DISABLE          0
+#define EPIT_CR_EN_ENABLE           1
+
+#define EPIT_CR_ENMOD_RESUME        0
+#define EPIT_CR_ENMOD_LOAD          1
+
+#define EPIT_CR_OCIEN_DISABLE       0
+#define EPIT_CR_OCIEN_ENABLE        1
+
+#define EPIT_CR_RLD_ROLLOVER        0
+#define EPIT_CR_RLD_RELOAD          1
+
+#define EPIT_CR_SWR_NORESET         0
+#define EPIT_CR_SWR_RESET           1
+
+#define EPIT_CR_IOVW_NOOVR          0
+#define EPIT_CR_IOVW_OVR            1
+
+#define EPIT_CR_DBGEN_INACTIVE      0
+#define EPIT_CR_DBGEN_ACTIVE        1
+
+#define EPIT_CR_WAITEN_DISABLE      0
+#define EPIT_CR_WAITEN_ENABLE       1
+
+#define EPIT_CR_DOZEN_DISABLE       0
+#define EPIT_CR_DOZEN_ENABLE        1
+
+#define EPIT_CR_STOPEN_DISABLE      0
+#define EPIT_CR_STOPEN_ENABLE       1
+
+#define EPIT_CR_OM_DICONNECT        0
+#define EPIT_CR_OM_TOGGLE           1
+#define EPIT_CR_OM_CLEAR            2
+#define EPIT_CR_OM_SET              3
+
+#define EPIT_CR_CLKSRC_OFF          0
+#define EPIT_CR_CLKSRC_IPGCLK       1
+#define EPIT_CR_CLKSRC_HIGHFREQ     2   // High freq is sourcing from PERCLK
+#define EPIT_CR_CLKSRC_CKIL         3
+
+// CNT
+#define EPIT_CNT_COUNT_MAX          0xFFFFFFFF
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __COMMON_EPIT_H
diff --git a/Silicon/NXP/iMX6Pkg/Include/common_gpt.h b/Silicon/NXP/iMX6Pkg/Include/common_gpt.h
new file mode 100644
index 000000000000..3c92023a60fe
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Include/common_gpt.h
@@ -0,0 +1,314 @@
+/** @file
+*
+*  Provides definitions for the GPT (General Purpose Timer) module
+*  that are common to Freescale SoCs.
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Copyright (c) 2004-2010, Freescale Semiconductor, Inc. All Rights Reserved.
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef __COMMON_GPT_H
+#define __COMMON_GPT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+//------------------------------------------------------------------------------
+// GENERAL MODULE CONSTANTS
+//------------------------------------------------------------------------------
+
+
+//------------------------------------------------------------------------------
+// REGISTER LAYOUT
+//------------------------------------------------------------------------------
+typedef struct
+{
+     UINT32 CR;
+     UINT32 PR;
+     UINT32 SR;
+     UINT32 IR;
+     UINT32 OCR1;
+     UINT32 OCR2;
+     UINT32 OCR3;
+     UINT32 ICR1;
+     UINT32 ICR2;
+     UINT32 CNT;
+} CSP_GPT_REGS, *PCSP_GPT_REGS;
+
+
+//------------------------------------------------------------------------------
+// REGISTER OFFSETS
+//------------------------------------------------------------------------------
+#define GPT_CR_OFFSET          0x0000
+#define GPT_PR_OFFSET          0x0004
+#define GPT_SR_OFFSET          0x0008
+#define GPT_IR_OFFSET          0x000C
+#define GPT_OCR1_OFFSET        0x0010
+#define GPT_OCR2_OFFSET        0x0014
+#define GPT_OCR3_OFFSET        0x0018
+#define GPT_ICR1_OFFSET        0x001C
+#define GPT_ICR2_OFFSET        0x0020
+#define GPT_CNT_OFFSET         0x0024
+
+
+//------------------------------------------------------------------------------
+// REGISTER BIT FIELD POSITIONS (LEFT SHIFT)
+//------------------------------------------------------------------------------
+#define GPT_CR_EN_LSH          0
+#define GPT_CR_ENMOD_LSH       1
+#define GPT_CR_DBGEN_LSH       2
+#define GPT_CR_WAITEN_LSH      3
+#define GPT_CR_STOPEN_LSH      5
+#define GPT_CR_CLKSRC_LSH      6
+#define GPT_CR_FRR_LSH         9
+#ifdef CPU_IMX6SX
+#define GPT_CR_EN_24M_LSH      10
+#elif defined(CPU_IMX6SDL)
+#define GPT_CR_EN_24M_LSH      10
+#endif
+#define GPT_CR_SWR_LSH         15
+#define GPT_CR_IM1_LSH         16
+#define GPT_CR_IM2_LSH         18
+#define GPT_CR_OM1_LSH         20
+#define GPT_CR_OM2_LSH         23
+#define GPT_CR_OM3_LSH         26
+#define GPT_CR_FO1_LSH         29
+#define GPT_CR_FO2_LSH         30
+#define GPT_CR_FO3_LSH         31
+
+#define GPT_PR_PRESCALER_LSH   0
+
+#define GPT_SR_OF1_LSH         0
+#define GPT_SR_OF2_LSH         1
+#define GPT_SR_OF3_LSH         2
+#define GPT_SR_IF1_LSH         3
+#define GPT_SR_IF2_LSH         4
+#define GPT_SR_ROV_LSH         5
+
+#define GPT_IR_OF1IE_LSH       0
+#define GPT_IR_OF2IE_LSH       1
+#define GPT_IR_OF3IE_LSH       2
+#define GPT_IR_IF1IE_LSH       3
+#define GPT_IR_IF2IE_LSH       4
+#define GPT_IR_ROVIE_LSH       5
+
+#define GPT_OCR1_COMP_LSH      0
+
+#define GPT_OCR2_COMP_LSH      0
+
+#define GPT_OCR3_COMP_LSH      0
+
+#define GPT_ICR1_CAPT_LSH      0
+
+#define GPT_ICR2_CAPT_LSH      0
+
+#define GPT_CNT_COUNT_LSH      0
+
+
+//------------------------------------------------------------------------------
+// REGISTER BIT FIELD WIDTHS
+//------------------------------------------------------------------------------
+#define GPT_CR_EN_WID          1
+#define GPT_CR_ENMOD_WID       1
+#define GPT_CR_DBGEN_WID       1
+#define GPT_CR_WAITEN_WID      1
+#define GPT_CR_STOPEN_WID      1
+#define GPT_CR_CLKSRC_WID      3
+#define GPT_CR_FRR_WID         1
+#ifdef CPU_IMX6SX
+#define GPT_CR_EN_24M_WID      1
+#elif defined(CPU_IMX6SDL)
+#define GPT_CR_EN_24M_WID      1
+#endif
+#define GPT_CR_SWR_WID         1
+#define GPT_CR_IM1_WID         2
+#define GPT_CR_IM2_WID         2
+#define GPT_CR_OM1_WID         3
+#define GPT_CR_OM2_WID         3
+#define GPT_CR_OM3_WID         3
+#define GPT_CR_FO1_WID         1
+#define GPT_CR_FO2_WID         1
+#define GPT_CR_FO3_WID         1
+
+#define GPT_PR_PRESCALER_WID   12
+
+#define GPT_SR_OF1_WID         1
+#define GPT_SR_OF2_WID         1
+#define GPT_SR_OF3_WID         1
+#define GPT_SR_IF1_WID         1
+#define GPT_SR_IF2_WID         1
+#define GPT_SR_ROV_WID         1
+
+#define GPT_IR_OF1IE_WID       1
+#define GPT_IR_OF2IE_WID       1
+#define GPT_IR_OF3IE_WID       1
+#define GPT_IR_IF1IE_WID       1
+#define GPT_IR_IF2IE_WID       1
+#define GPT_IR_ROVIE_WID       1
+
+#define GPT_OCR1_COMP_WID      32
+
+#define GPT_OCR2_COMP_WID      32
+
+#define GPT_OCR3_COMP_WID      32
+
+#define GPT_ICR1_CAPT_WID      32
+
+#define GPT_ICR2_CAPT_WID      32
+
+#define GPT_CNT_COUNT_WID      32
+
+
+//------------------------------------------------------------------------------
+// REGISTER BIT WRITE VALUES
+//------------------------------------------------------------------------------
+
+// GPTCR
+#define GPT_CR_EN_ENABLE                1 // GPT enabled
+#define GPT_CR_EN_DISABLE               0 // GPT disabled
+
+#define GPT_CR_ENMOD_RESET              1 // GPT counter reset to
+                                          // 0 when disabled
+#define GPT_CR_ENMOD_RETAIN             0 // GPT counter retains
+                                          // value when disabled
+
+#define GPT_CR_DBGEN_ENABLE             1 // GPT enabled in debug mode
+#define GPT_CR_DBGEN_DISABLE            0 // GPT disabled in debug mode
+
+#define GPT_CR_WAITEN_ENABLE            1 // GPT enabled in wait mode
+#define GPT_CR_WAITEN_DISABLE           0 // GPT disabled in wait mode
+
+#define GPT_CR_STOPEN_ENABLE            1 // GPT enabled in stopdoze mode
+#define GPT_CR_STOPEN_DISABLE           0 // GPT disabled in stopoze mode
+
+#if defined(CPU_IMX6DQ)
+#define GPT_CR_CLKSRC_NOCLK             0 // No clock to GPT
+#define GPT_CR_CLKSRC_IPGCLK            1 // ipg_clk is the clock source
+#define GPT_CR_CLKSRC_HIGHFREQ          2 // ipg_clk_highfreq
+#define GPT_CR_CLKSRC_EXTCLK            3 // ipp_gpt_clkin (external clock
+                                          // from pad) is the clock source
+#define GPT_CR_CLKSRC_CLK32K            4 // ipg_clk_32k is clock source
+#define GPT_CR_CLKSRC_CLK8M             5 // crystal oscillator divided by 8 is clock source
+#define GPT_CR_CLKSRC_CLK24M            7 // crystal oscillator (24 Mhz) is clock source
+#elif defined(CPU_IMX6SDL)
+#define GPT_CR_CLKSRC_NOCLK             0 // No clock to GPT
+#define GPT_CR_CLKSRC_IPGCLK            1 // Peripheral Clock
+#define GPT_CR_CLKSRC_HIGHFREQ          2 // High Frequency Reference Clock
+#define GPT_CR_CLKSRC_EXTCLK            3 // External Clock (CLKIN)
+#define GPT_CR_CLKSRC_LOWFREQ           4 // Low Frequency Reference Clock
+#define GPT_CR_CLKSRC_CLK24M            5 // Crystal oscillator as Reference Clock
+#elif defined(CPU_IMX6SX)
+#define GPT_CR_CLKSRC_NOCLK             0 // No clock to GPT
+#define GPT_CR_CLKSRC_PERIPHCLK         1 // Peripheral Clock
+#define GPT_CR_CLKSRC_HIGHFREQ          2 // High Frequency Reference Clock
+#define GPT_CR_CLKSRC_EXTCLK            3 // External Clock (CLKIN)
+#define GPT_CR_CLKSRC_LOWFREQ           4 // Low Frequency Reference Clock
+#define GPT_CR_CLKSRC_CLK24M            5 // Crystal oscillator as Reference Clock
+#else
+#error CPU Preprocessor Flag Not Defined
+#endif
+
+#define GPT_CR_FRR_FREERUN              1 // Freerun mode (counter
+                                          // continues after compare)
+#define GPT_CR_FRR_RESTART              0 // Restart mode (counter set
+                                          // to zero after compare)
+#if defined(CPU_IMX6SX) || defined(CPU_IMX6SDL)
+#define GPT_CR_EN_24M_DISABLE           0  // 24M clock disabled
+#define GPT_CR_EN_24M_ENABLE            1  // 24M clock enabled
+#endif
+
+#define GPT_CR_SWR_RESET                1 // Self-clearing software reset
+#define GPT_CR_SWR_NORESET              0 // Do not activate software reset
+
+#define GPT_CR_IM1_DISABLE              0 // Capture Disabled
+#define GPT_CR_IM1_EDGE_RISE            1 // Capture on rising edge
+#define GPT_CR_IM1_EDGE_FALL            2 // Capture on falling edge
+#define GPT_CR_IM1_EDGE_BOTH            3 // Capture on both edges
+
+#define GPT_CR_IM2_DISABLE              0 // Capture Disabled
+#define GPT_CR_IM2_EDGE_RISE            1 // Capture on rising edge
+#define GPT_CR_IM2_EDGE_FALL            2 // Capture on falling edge
+#define GPT_CR_IM2_EDGE_BOTH            3 // Capture on both edges
+
+#define GPT_CR_OM1_DISABLE              0 // Compare generates no response
+#define GPT_CR_OM1_TOGGLE               1 // Compare toggles output pin
+#define GPT_CR_OM1_CLEAR                2 // Compare clears output pin
+#define GPT_CR_OM1_SET                  3 // Compare sets output pin
+#define GPT_CR_OM1_PULSE                4 // Compare event generates a
+                                          // single count duration pulse
+                                          // on output pin
+
+#define GPT_CR_OM2_DISABLE              0 // Compare generates no response
+#define GPT_CR_OM2_TOGGLE               1 // Compare toggles output pin
+#define GPT_CR_OM2_CLEAR                2 // Compare clears output pin
+#define GPT_CR_OM2_SET                  3 // Compare sets output pin
+#define GPT_CR_OM2_PULSE                4 // Compare event generates a
+                                          // single count duration pulse
+                                          // on output pin
+
+#define GPT_CR_OM3_DISABLE              0 // Compare generates no response
+#define GPT_CR_OM3_TOGGLE               1 // Compare toggles output pin
+#define GPT_CR_OM3_CLEAR                2 // Compare clears output pin
+#define GPT_CR_OM3_SET                  3 // Compare sets output pin
+#define GPT_CR_OM3_PULSE                4 // Compare event generates a
+                                          // single count duration pulse
+                                          // on output pin
+
+#define GPT_CR_FO1_FORCE                1 // Force pin action programmed
+                                          // for output compare 1 pin.
+                                          // Pin is self-negating.
+#define GPT_CR_FO1_NOFORCE              0 // Do not force pin
+
+#define GPT_CR_FO2_FORCE                1 // Force pin action programmed
+                                          // for output compare 1 pin
+                                          // Pin is self-negating.
+#define GPT_CR_FO2_NOFORCE              0 // Do not force pin
+
+#define GPT_CR_FO3_FORCE                1 // Force pin action programmed
+                                          // for output compare 1 pin
+                                          // Pin is self-negating.
+#define GPT_CR_FO3_NOFORCE              0 // Do not force pin
+
+// GPTSR
+#define GPT_SR_OF1_STATUS_CLEAR         1 // Output compare 1 status clear
+#define GPT_SR_OF2_STATUS_CLEAR         1 // Output compare 2 status clear
+#define GPT_SR_OF3_STATUS_CLEAR         1 // Output compare 3 status clear
+#define GPT_SR_IF1_STATUS_CLEAR         1 // Input capture 1 status clear
+#define GPT_SR_IF2_STATUS_CLEAR         1 // Input capture 2 status clear
+#define GPT_SR_ROV_STATUS_CLEAR         1 // Rollover status clear
+
+// GPTIR
+#define GPT_IR_OF1IE_INT_ENABLE         1 // Output compare 1 int enabled
+#define GPT_IR_OF1IE_INT_DISABLE        0 // Output compare 1 int disabled
+
+#define GPT_IR_OF2IE_INT_ENABLE         1 // Output compare 2 int enabled
+#define GPT_IR_OF2IE_INT_DISABLE        0 // Output compare 2 int disabled
+
+#define GPT_IR_OF3IE_INT_ENABLE         1 // Output compare 3 int enabled
+#define GPT_IR_OF3IE_INT_DISABLE        0 // Output compare 3 int disabled
+
+#define GPT_IR_IF1IE_INT_ENABLE         1 // Input capture 1 int enabled
+#define GPT_IR_IF1IE_INT_DISABLE        0 // Input capture 1 int disabled
+
+#define GPT_IR_IF2IE_INT_ENABLE         1 // Input capture 2 int enabled
+#define GPT_IR_IF2IE_INT_DISABLE        0 // Input capture 2 int disabled
+
+#define GPT_IR_ROVIE_INT_ENABLE         1 // Rollover int enabled
+#define GPT_IR_ROVIE_INT_DISABLE        0 // Rollover int disabled
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __COMMON_GPT_H
-- 
2.16.2.gvfs.1.33.gf5370f1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH edk2-platforms 03/13] Silicon/NXP: Add iMX6Pkg dec
  2018-07-20  6:33 [PATCH edk2-platforms 00/13] Silicon/NXP: Import NXP i.MX6 Package Chris Co
  2018-07-20  6:33 ` [PATCH edk2-platforms 01/13] Silicon/NXP: Add i.MX6 SoC header files Chris Co
  2018-07-20  6:33 ` [PATCH edk2-platforms 02/13] Silicon/NXP: Add i.MX6 GPT and EPIT timer headers Chris Co
@ 2018-07-20  6:33 ` Chris Co
  2018-07-20  6:33 ` [PATCH edk2-platforms 04/13] Silicon/NXP: Add i.MX6 Timer DXE driver Chris Co
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chris Co @ 2018-07-20  6:33 UTC (permalink / raw)
  To: edk2-devel@lists.01.org; +Cc: Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This adds PCD declarations common across NXP i.MX6 SoCs

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Christopher Co <christopher.co@microsoft.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/NXP/iMX6Pkg/iMX6Pkg.dec | 100 ++++++++++++++++++++
 1 file changed, 100 insertions(+)

diff --git a/Silicon/NXP/iMX6Pkg/iMX6Pkg.dec b/Silicon/NXP/iMX6Pkg/iMX6Pkg.dec
new file mode 100644
index 000000000000..6fa09090772e
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/iMX6Pkg.dec
@@ -0,0 +1,100 @@
+## @file
+#
+#  Copyright (c) Microsoft Corporation. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = iMX6Pkg
+  PACKAGE_GUID                   = 6eba6648-d853-4eb3-9761-528b82d5ab04
+  PACKAGE_VERSION                = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+#                   Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+#  BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+  Include                        # Root include for the package
+  Silicon/NXP/iMXPlatformPkg/Include      # Root include for the iMXPlatform package
+
+[LibraryClasses]
+  iMXIoMuxLib|Silicon/NXP/iMX6Pkg/Include/iMXIoMux.h
+  iMX6ClkPwrLib|Silicon/NXP/iMX6Pkg/Include/iMX6ClkPwr.h
+  iMX6UsbPhyLib|Silicon/NXP/iMX6Pkg/Include/iMX6UsbPhy.h
+
+[Protocols.common]
+  gEfiSdhcProtocolGuid = { 0x46055b0f, 0x992a, 0x4ad7, { 0x8f, 0x81, 0x14, 0x81, 0x86, 0xff, 0xdf, 0x72 } }
+
+[Guids.common]
+  giMX6TokenSpaceGuid    =  { 0x24b09abe, 0x4e47, 0x481c, { 0xa9, 0xad, 0xce, 0xf1, 0x2c, 0x39, 0x23, 0x27} }
+
+[PcdsFixedAtBuild.common]
+  #
+  # Frame buffer is set to the first addressable memory on the i.MX6
+  # Sabre board for convenience.
+  # Keep in mind that this chunk of memory is the only one that remains fixed
+  # through the various boot stages (primary boot->UEFI->Windows.
+  #
+  giMX6TokenSpaceGuid.PcdFrameBufferBase|0x10000000|UINT32|0x0000000A
+  giMX6TokenSpaceGuid.PcdFrameBufferSize|0x00800000|UINT32|0x0000000B
+
+  #
+  # Performance counter
+  #
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedFdPerformanceCounterFrequencyInHz|1000000|UINT32 |0xC
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedFdPerformanceCounterPeriodInNanoseconds|1000|UINT32 |0xD
+
+  #
+  # USB EHCI Controller
+  #
+  giMX6TokenSpaceGuid.PcdEHCIBase|0x02184000|UINT32|0xE
+  giMX6TokenSpaceGuid.PcdEHCILength|0x4000|UINT32|0xF
+  giMX6TokenSpaceGuid.PcdIsUsbPortOTG|TRUE|BOOLEAN|0x10
+  giMX6TokenSpaceGuid.PcdUSBOTGBase|0x02184000|UINT32|0x11
+
+  #
+  # ARM System Reset Controller (SRC)
+  #
+  giMX6TokenSpaceGuid.PcdSrcBase|0x020D8000|UINT32|0x2B
+
+  #
+  # PCIE
+  #
+  # PCI Host config space is fixed at 0x01FFC000. The memory range from
+  # 0x01000000 - 0x01FFBFFF is assigned for PCIe. The memory layout defined
+  # by the boot loader is as below
+  #
+  # PCIe Device Config Space : 0x01F00000 - 0x01F80000
+  # PCIe IO (unsupported) : 0x01100000 - 0x011FFFFF
+  # PCIe Memory : 0x01200000 - 0x012FFFFF
+  #
+  giMX6TokenSpaceGuid.PcdPcieHostConfigBase|0x01FFC000|UINT32|0x2C
+  giMX6TokenSpaceGuid.PcdPcieDeviceConfigBase|0x01F00000|UINT32|0x2D
+  giMX6TokenSpaceGuid.PcdPcieDeviceConfigSize|0x00080000|UINT32|0x2E
+  giMX6TokenSpaceGuid.PcdPcieIOBase|0x00000000|UINT32|0x2F
+  giMX6TokenSpaceGuid.PcdPcieIOSize|0x00000000|UINT32|0x30
+  giMX6TokenSpaceGuid.PcdPciMemoryBase|0x01100000|UINT32|0x31
+  giMX6TokenSpaceGuid.PcdPciMemorySize|0x00D00000|UINT32|0x32
+  giMX6TokenSpaceGuid.PcdPciPrefetchMemoryBase|0x00000000|UINT32|0x33
+  giMX6TokenSpaceGuid.PcdPciPrefetchMemorySize|0x00000000|UINT32|0x34
+  giMX6TokenSpaceGuid.PcdPcieResetGpio|FALSE|BOOLEAN|0x35
+  giMX6TokenSpaceGuid.PcdPcieResetGpioBankNumber|0|UINT32|0x36
+  giMX6TokenSpaceGuid.PcdPcieResetGpioIoNumber|0|UINT32|0x37
+
+[PcdsFeatureFlag.common]
+  giMX6TokenSpaceGuid.PcdGpuEnable|FALSE|BOOLEAN|0x00001000
+  giMX6TokenSpaceGuid.PcdLvdsEnable|FALSE|BOOLEAN|0x00001001
-- 
2.16.2.gvfs.1.33.gf5370f1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH edk2-platforms 04/13] Silicon/NXP: Add i.MX6 Timer DXE driver
  2018-07-20  6:33 [PATCH edk2-platforms 00/13] Silicon/NXP: Import NXP i.MX6 Package Chris Co
                   ` (2 preceding siblings ...)
  2018-07-20  6:33 ` [PATCH edk2-platforms 03/13] Silicon/NXP: Add iMX6Pkg dec Chris Co
@ 2018-07-20  6:33 ` Chris Co
  2018-07-20  6:33 ` [PATCH edk2-platforms 05/13] Silicon/NXP: Add i.MX6 GPT Timer library Chris Co
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chris Co @ 2018-07-20  6:33 UTC (permalink / raw)
  To: edk2-devel@lists.01.org; +Cc: Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This adds DXE support for EPIT timer on NXP i.MX6 SoCs.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Christopher Co <christopher.co@microsoft.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/Timer.c      | 268 ++++++++++++++++++++
 Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/TimerDxe.inf |  55 ++++
 2 files changed, 323 insertions(+)

diff --git a/Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/Timer.c b/Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/Timer.c
new file mode 100644
index 000000000000..75c98dcff9ea
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/Timer.c
@@ -0,0 +1,268 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <iMX6.h>
+#include <common_macros.h>
+#include <common_epit.h>
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+
+#include <Protocol/Timer.h>
+#include <Protocol/HardwareInterrupt.h>
+
+// The notification function to call on every timer interrupt.
+volatile EFI_TIMER_NOTIFY mTimerNotifyFunction = (EFI_TIMER_NOTIFY) NULL;
+EFI_EVENT EfiExitBootServicesEvent = (EFI_EVENT) NULL;
+
+// Cached copy of the Hardware Interrupt protocol instance
+EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;
+
+// Cached interrupt vector
+volatile UINTN  mVector;
+UINT64 mCurrentTimerPeriod;
+
+EFI_STATUS
+EFIAPI
+TimerDriverRegisterHandler (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN EFI_TIMER_NOTIFY         NotifyFunction
+  )
+{
+  DEBUG ((DEBUG_VERBOSE, "++TimerDriverRegisterHandler()\n"));
+  if ((NotifyFunction == NULL) && (mTimerNotifyFunction == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((NotifyFunction != NULL) && (mTimerNotifyFunction != NULL)) {
+    return EFI_ALREADY_STARTED;
+  }
+
+  mTimerNotifyFunction = NotifyFunction;
+  DEBUG ((DEBUG_VERBOSE, "--TimerDriverRegisterHandler()=ok\n"));
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+TimerDriverSetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN UINT64                   TimerPeriod
+  )
+{
+  EFI_STATUS  Status;
+  UINT32      TimerCount;
+  UINT16      epitPreScalar;
+
+  DEBUG ((DEBUG_VERBOSE, "++TimerDriverSetTimerPeriod(%d)\n", TimerPeriod));
+
+  PCSP_EPIT_REG g_pEPIT = (PCSP_EPIT_REG) CSP_BASE_REG_PA_EPIT1;
+
+  DEBUG ((DEBUG_VERBOSE, "TimerDriverSetTimerPeriod() disable timer. EPIT_REG adr=%p\n", g_pEPIT));
+
+  // First stop the timer.
+  INSREG32BF(&g_pEPIT->CR,EPIT_CR_EN,EPIT_CR_EN_DISABLE);
+
+  if (TimerPeriod == 0) {
+    Status = gInterrupt->DisableInterruptSource(gInterrupt, mVector);
+    mCurrentTimerPeriod = 0;
+    DEBUG ((DEBUG_VERBOSE, "--TimerDriverSetTimerPeriod() Timer Disabled\n"));
+    return Status;
+  }
+
+  // configure EPIT to be sourced from iMX6 24 MHz crystal oscialltor per
+  // i.MX 6Dual/6Quad Applications Processor Reference Manual, Rev. 3, 07/2015
+  // aim to have UEFI tick counting at 1 MHz clock or another frequency as set in pcd value
+  epitPreScalar = 68;
+  DEBUG((DEBUG_VERBOSE, "TimerDriverSetTimerPeriod() using corrected EPIT prescalar=%d\n", epitPreScalar));
+
+  OUTREG32(&g_pEPIT->CR,
+      CSP_BITFVAL(EPIT_CR_ENMOD, EPIT_CR_ENMOD_LOAD) |
+      CSP_BITFVAL(EPIT_CR_OCIEN, EPIT_CR_OCIEN_ENABLE) |
+      CSP_BITFVAL(EPIT_CR_RLD, EPIT_CR_RLD_RELOAD) |
+      CSP_BITFVAL(EPIT_CR_PRESCALAR, (epitPreScalar-1)) |  // bits 4-15, 000 to FFF.
+      CSP_BITFVAL(EPIT_CR_SWR, EPIT_CR_SWR_NORESET) |
+      CSP_BITFVAL(EPIT_CR_IOVW, EPIT_CR_IOVW_OVR) |
+      CSP_BITFVAL(EPIT_CR_DBGEN, EPIT_CR_DBGEN_ACTIVE) |
+      CSP_BITFVAL(EPIT_CR_WAITEN, EPIT_CR_WAITEN_ENABLE) |
+      CSP_BITFVAL(EPIT_CR_DOZEN, EPIT_CR_DOZEN_ENABLE) |
+      CSP_BITFVAL(EPIT_CR_STOPEN, EPIT_CR_STOPEN_ENABLE) |
+      CSP_BITFVAL(EPIT_CR_OM, EPIT_CR_OM_DICONNECT) |
+      CSP_BITFVAL(EPIT_CR_CLKSRC, EPIT_CR_CLKSRC_IPGCLK)); // source is crystal clock source (24 MHz)
+
+  // Clear timer compare interrupt flag (write-1-clear)
+  OUTREG32(&g_pEPIT->SR, CSP_BITFMASK(EPIT_SR_OCIF));
+    // Set the new compare value
+  TimerCount = (UINT32)(TimerPeriod / 10);
+
+  if((UINT64)TimerCount > (UINT64)0xffffffff)
+    TimerCount = 0xffffffff;
+
+  mCurrentTimerPeriod = TimerPeriod;
+
+  OUTREG32(&g_pEPIT->CMPR, TimerCount);
+  OUTREG32(&g_pEPIT->LR, TimerCount);
+  Status = gInterrupt->EnableInterruptSource(gInterrupt, mVector);
+  // turn the timer on
+  INSREG32BF(&g_pEPIT->CR,EPIT_CR_EN,EPIT_CR_EN_ENABLE);
+
+  DEBUG ((DEBUG_VERBOSE, "--TimerDriverSetTimerPeriod(%d)=%Xh\n", TimerPeriod,Status));
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+TimerDriverGetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL   *This,
+  OUT UINT64                   *TimerPeriod
+  )
+{
+  *TimerPeriod = mCurrentTimerPeriod;
+  DEBUG ((DEBUG_VERBOSE, "+-TimerDriverGetTimerPeriod(%d)=ok\n", mCurrentTimerPeriod));
+  return EFI_SUCCESS;
+}
+
+VOID
+EFIAPI
+TimerInterruptHandler (
+  IN  HARDWARE_INTERRUPT_SOURCE   Source,
+  IN  EFI_SYSTEM_CONTEXT          SystemContext
+  )
+{
+  EFI_TPL OriginalTPL;
+  PCSP_EPIT_REG g_pEPIT = (PCSP_EPIT_REG) CSP_BASE_REG_PA_EPIT1;
+
+  //
+  // DXE core uses this callback for the EFI timer tick. The DXE core uses locks
+  // that raise to TPL_HIGH and then restore back to current level. Thus we need
+  // to make sure TPL level is set to TPL_HIGH while we are handling the timer tick.
+  //
+  OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+
+  // Check if the timer interrupt is active
+  if (INREG32 (&g_pEPIT->SR) != 0) {
+    // Acknowledge the EPIT interrupt
+    OUTREG32 (&g_pEPIT->SR, 0x1);
+
+    // Signal end of interrupt early to help avoid losing subsequent ticks from long duration handlers
+    gInterrupt->EndOfInterrupt (gInterrupt, Source);
+
+    if (mTimerNotifyFunction) {
+      mTimerNotifyFunction (mCurrentTimerPeriod);
+    }
+  }
+
+  gBS->RestoreTPL (OriginalTPL);
+}
+
+EFI_STATUS
+EFIAPI
+TimerDriverGenerateSoftInterrupt (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+EFI_TIMER_ARCH_PROTOCOL   gTimer = {
+  TimerDriverRegisterHandler,
+  TimerDriverSetTimerPeriod,
+  TimerDriverGetTimerPeriod,
+  TimerDriverGenerateSoftInterrupt
+};
+
+VOID
+EFIAPI
+ExitBootServicesEvent (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  EFI_STATUS  Status;
+
+  DEBUG ((DEBUG_INFO, "Disabling EPIT timer on ExitBootServicesEvent"));
+
+  // Disable the timer
+  Status = TimerDriverSetTimerPeriod(&gTimer, 0);
+  ASSERT_EFI_ERROR (Status);
+}
+
+EFI_STATUS
+EFIAPI
+TimerInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_HANDLE  Handle = NULL;
+  EFI_STATUS  Status;
+  DEBUG ((DEBUG_VERBOSE, "++TimerInitialize()\n"));
+
+  mVector = IRQ_EPIT1;
+
+  // Find the interrupt controller protocol.  ASSERT if not found.
+  Status = gBS->LocateProtocol (
+                  &gHardwareInterruptProtocolGuid,
+                  NULL,
+                  (VOID **) &gInterrupt);
+
+  ASSERT_EFI_ERROR (Status);
+
+  // Disable the timer
+  Status = TimerDriverSetTimerPeriod (&gTimer, 0);
+  ASSERT_EFI_ERROR (Status);
+
+  // Install interrupt handler
+  Status = gInterrupt->RegisterInterruptSource (gInterrupt, mVector, TimerInterruptHandler);
+  ASSERT_EFI_ERROR (Status);
+
+  // Set up default timer
+  Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32 (PcdTimerPeriod));
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((
+    DEBUG_VERBOSE,
+    "EPIT Timer initialized to default period %d x 100ns ~ %dms\n",
+    FixedPcdGet32(PcdTimerPeriod),
+    FixedPcdGet32(PcdTimerPeriod) / 10000));
+
+  // Install the Timer Architectural Protocol onto a new handle
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gEfiTimerArchProtocolGuid,
+                  &gTimer,
+                  NULL);
+
+  ASSERT_EFI_ERROR(Status);
+
+  // Register for an ExitBootServicesEvent
+  Status = gBS->CreateEvent (
+                  EVT_SIGNAL_EXIT_BOOT_SERVICES,
+                  TPL_NOTIFY,
+                  ExitBootServicesEvent,
+                  NULL,
+                  &EfiExitBootServicesEvent);
+
+  ASSERT_EFI_ERROR (Status);
+
+  DEBUG ((DEBUG_VERBOSE, "--TimerInitialize()\n"));
+  return Status;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/TimerDxe.inf b/Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/TimerDxe.inf
new file mode 100644
index 000000000000..d574b99533ca
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/TimerDxe.inf
@@ -0,0 +1,55 @@
+#/** @file
+#
+#  Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
+#  Copyright (c) Microsoft Corporation. All rights reserved.
+#
+#  All rights reserved. This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = iMX6TimerDxe
+  FILE_GUID                      = 7CAF576F-F1D9-4104-A922-CB64537FD7AE
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = TimerInitialize
+
+[Sources.common]
+  Timer.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  Silicon/NXP/iMX6Pkg/iMX6Pkg.dec
+
+[LibraryClasses]
+  BaseLib
+  UefiRuntimeServicesTableLib
+  PerformanceLib
+  UefiLib
+  UefiBootServicesTableLib
+  BaseMemoryLib
+  DebugLib
+  UefiDriverEntryPoint
+  IoLib
+
+[Guids]
+
+[Protocols]
+  gEfiTimerArchProtocolGuid
+  gHardwareInterruptProtocolGuid
+
+[Pcd.common]
+  gEmbeddedTokenSpaceGuid.PcdTimerPeriod
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedFdPerformanceCounterPeriodInNanoseconds
+
+[Depex]
+  gHardwareInterruptProtocolGuid
-- 
2.16.2.gvfs.1.33.gf5370f1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH edk2-platforms 05/13] Silicon/NXP: Add i.MX6 GPT Timer library
  2018-07-20  6:33 [PATCH edk2-platforms 00/13] Silicon/NXP: Import NXP i.MX6 Package Chris Co
                   ` (3 preceding siblings ...)
  2018-07-20  6:33 ` [PATCH edk2-platforms 04/13] Silicon/NXP: Add i.MX6 Timer DXE driver Chris Co
@ 2018-07-20  6:33 ` Chris Co
  2018-07-20  6:33 ` [PATCH edk2-platforms 06/13] Silicon/NXP: Add i.MX6 USB Phy Library Chris Co
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chris Co @ 2018-07-20  6:33 UTC (permalink / raw)
  To: edk2-devel@lists.01.org; +Cc: Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This adds support for GPT Timer on NXP i.MX6 SoCs.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Christopher Co <christopher.co@microsoft.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/NXP/iMX6Pkg/Library/TimerLib/TimerLib.c   | 257 ++++++++++++++++++++
 Silicon/NXP/iMX6Pkg/Library/TimerLib/TimerLib.inf |  37 +++
 2 files changed, 294 insertions(+)

diff --git a/Silicon/NXP/iMX6Pkg/Library/TimerLib/TimerLib.c b/Silicon/NXP/iMX6Pkg/Library/TimerLib/TimerLib.c
new file mode 100644
index 000000000000..54dd3b5f7004
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Library/TimerLib/TimerLib.c
@@ -0,0 +1,257 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Uefi.h>
+#include <Base.h>
+
+#include <common_macros.h>
+#include <iMX6.h>
+#include <common_gpt.h>
+
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseLib.h>
+#include <Library/ArmLib.h>
+
+// Select appropriate multiply function for platform architecture.
+#ifdef MDE_CPU_ARM
+#define MultU64xN MultU64x32
+#else
+#define MultU64xN MultU64x64
+#endif
+
+RETURN_STATUS
+EFIAPI
+TimerConstructor (
+  VOID
+  )
+{
+  PCSP_GPT_REGS pGPT;
+  UINT32 FreqPreScale;
+
+  pGPT = (PCSP_GPT_REGS)CSP_BASE_REG_PA_GPT;
+
+  ASSERT(SOC_OSC_FREQUENCY_REF_HZ >= PcdGet32 (PcdArmArchTimerFreqInHz));
+
+  // Calculate the scale factor since we are using the 24Mhz oscillator
+  // as reference.
+  FreqPreScale = SOC_OSC_FREQUENCY_REF_HZ / PcdGet32 (PcdArmArchTimerFreqInHz);
+  ASSERT(FreqPreScale <= (1<<GPT_PR_PRESCALER_WID));
+
+  // Set the frequency scale
+  OUTREG32(&pGPT->PR,FreqPreScale - 1);
+
+#if defined(CPU_IMX6DQ)
+  // Set GPT configuration:
+  // - GPT Enabled
+  // - Use the 24Mhz oscillator source
+  OUTREG32(&pGPT->CR,
+    CSP_BITFVAL(GPT_CR_EN, GPT_CR_EN_ENABLE) |
+    CSP_BITFVAL(GPT_CR_CLKSRC, GPT_CR_CLKSRC_CLK24M));
+#elif defined(CPU_IMX6SDL) || defined(CPU_IMX6SX)
+  // Set GPT configuration:
+  // - GPT Enabled
+  // - Enable 24 Mhz Oscillator
+  // - Use the 24Mhz oscillator source
+  OUTREG32(&pGPT->CR,
+    CSP_BITFVAL(GPT_CR_EN, GPT_CR_EN_ENABLE) |
+    CSP_BITFVAL(GPT_CR_EN_24M, GPT_CR_EN_24M_ENABLE) |
+    CSP_BITFVAL(GPT_CR_CLKSRC, GPT_CR_CLKSRC_CLK24M));
+#else
+#error CPU Preprocessor Flag Not Defined
+#endif
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Stalls the CPU for at least the given number of microseconds.
+
+  Stalls the CPU for the number of microseconds specified by MicroSeconds.
+
+  @param  MicroSeconds  The minimum number of microseconds to delay.
+
+  @return The value of MicroSeconds inputted.
+
+**/
+UINTN
+EFIAPI
+MicroSecondDelay (
+  IN      UINTN                     MicroSeconds
+  )
+{
+  UINT64 TimerTicks64;
+  UINT32 CurCounterRead;
+  UINT32 PrevCounterRead;
+  UINT64 CountOffset;
+
+  // Convert uSec delay to counter ticks:
+  TimerTicks64      = ((UINT64)MicroSeconds * PcdGet32 (PcdArmArchTimerFreqInHz)) / 1000000U;
+  CurCounterRead    = (UINT32)GetPerformanceCounter();
+  PrevCounterRead   = CurCounterRead;
+  TimerTicks64      += (UINT64)CurCounterRead;
+  CountOffset       = 0;
+
+  // GPT is a 32bit counter, thus we need to handle rollover cases.
+  while(((UINT64)CurCounterRead + CountOffset) < TimerTicks64) {
+
+    CurCounterRead = (UINT32)GetPerformanceCounter();
+    if (CurCounterRead < PrevCounterRead) {
+        CountOffset += 0x100000000;
+    }
+
+    PrevCounterRead = CurCounterRead;
+  }
+
+  return MicroSeconds;
+}
+
+/**
+  Stalls the CPU for at least the given number of nanoseconds.
+
+  Stalls the CPU for the number of nanoseconds specified by NanoSeconds.
+
+  @param  NanoSeconds The minimum number of nanoseconds to delay.
+
+  @return The value of NanoSeconds inputted.
+
+**/
+UINTN
+EFIAPI
+NanoSecondDelay (
+  IN      UINTN                     NanoSeconds
+  )
+{
+  if (NanoSeconds < (0xffffffff - 999)) {
+    NanoSeconds += 999;
+  }
+  MicroSecondDelay(NanoSeconds / 1000);
+
+  return 0;
+}
+
+/**
+  Retrieves the current value of a 64-bit free running performance counter.
+
+  The counter can either count up by 1 or count down by 1. If the physical
+  performance counter counts by a larger increment, then the counter values
+  must be translated. The properties of the counter can be retrieved from
+  GetPerformanceCounterProperties().
+
+  @return The current value of the free running performance counter.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounter (
+  VOID
+  )
+{
+  PCSP_GPT_REGS pGPT = (PCSP_GPT_REGS)CSP_BASE_REG_PA_GPT;
+
+  return INREG32 (&pGPT->CNT);
+}
+
+/**
+  Retrieves the 64-bit frequency in Hz and the range of performance counter
+  values.
+
+  If StartValue is not NULL, then the value that the performance counter starts
+  with immediately after is it rolls over is returned in StartValue. If
+  EndValue is not NULL, then the value that the performance counter end with
+  immediately before it rolls over is returned in EndValue. The 64-bit
+  frequency of the performance counter in Hz is always returned. If StartValue
+  is less than EndValue, then the performance counter counts up. If StartValue
+  is greater than EndValue, then the performance counter counts down. For
+  example, a 64-bit free running counter that counts up would have a StartValue
+  of 0 and an EndValue of 0xFFFFFFFFFFFFFFFF. A 24-bit free running counter
+  that counts down would have a StartValue of 0xFFFFFF and an EndValue of 0.
+
+  @param  StartValue  The value the performance counter starts with when it
+                      rolls over.
+  @param  EndValue    The value that the performance counter ends with before
+                      it rolls over.
+
+  @return The frequency in Hz.
+
+**/
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+  OUT      UINT64                    *StartValue,  OPTIONAL
+  OUT      UINT64                    *EndValue     OPTIONAL
+  )
+{
+  if (StartValue != NULL) {
+    *StartValue = 0x0;
+  }
+
+  if (EndValue != NULL) {
+    *EndValue = 0xFFFFFFFF;
+  }
+
+  return PcdGet32 (PcdArmArchTimerFreqInHz);
+}
+
+/**
+  Converts elapsed ticks of performance counter to time in nanoseconds.
+
+  This function converts the elapsed ticks of running performance counter to
+  time value in unit of nanoseconds.
+
+  @param  Ticks     The number of elapsed ticks of running performance counter.
+
+  @return The elapsed time in nanoseconds.
+
+**/
+UINT64
+EFIAPI
+GetTimeInNanoSecond (
+  IN      UINT64                     Ticks
+  )
+{
+  UINT64  NanoSeconds;
+  UINT32  Remainder;
+  UINT32  TimerFreq;
+
+  TimerFreq = PcdGet32 (PcdArmArchTimerFreqInHz);
+
+  //
+  //          Ticks
+  // Time = --------- x 1,000,000,000
+  //        Frequency
+  //
+  NanoSeconds = MultU64xN (
+                  DivU64x32Remainder (
+                    Ticks,
+                    TimerFreq,
+                    &Remainder),
+                  1000000000U
+                  );
+
+  //
+  // Frequency < 0x100000000, so Remainder < 0x100000000, then (Remainder * 1,000,000,000)
+  // will not overflow 64-bit.
+  //
+  NanoSeconds += DivU64x32 (
+                   MultU64xN (
+                     (UINT64) Remainder,
+                     1000000000U),
+                   TimerFreq
+                   );
+
+  return NanoSeconds;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Library/TimerLib/TimerLib.inf b/Silicon/NXP/iMX6Pkg/Library/TimerLib/TimerLib.inf
new file mode 100644
index 000000000000..4715b90db153
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Library/TimerLib/TimerLib.inf
@@ -0,0 +1,37 @@
+## @file
+#
+#  Copyright (c) Microsoft Corporation. All rights reserved.
+#  Copyright (c) 2007 - 2008, Intel Corporation.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = iMX6TimerLib
+  FILE_GUID                      = 2956C1A6-6FF8-4763-9FD8-D45892E025E3
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TimerLib
+
+[Sources.common]
+  TimerLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  ArmPkg/ArmPkg.dec
+  Silicon/NXP/iMX6Pkg/iMX6Pkg.dec
+
+[LibraryClasses]
+  DebugLib
+  IoLib
+
+[Pcd]
+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz
-- 
2.16.2.gvfs.1.33.gf5370f1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH edk2-platforms 06/13] Silicon/NXP: Add i.MX6 USB Phy Library
  2018-07-20  6:33 [PATCH edk2-platforms 00/13] Silicon/NXP: Import NXP i.MX6 Package Chris Co
                   ` (4 preceding siblings ...)
  2018-07-20  6:33 ` [PATCH edk2-platforms 05/13] Silicon/NXP: Add i.MX6 GPT Timer library Chris Co
@ 2018-07-20  6:33 ` Chris Co
  2018-07-20  6:33 ` [PATCH edk2-platforms 07/13] Silicon/NXP: Add i.MX6 I/O MUX library Chris Co
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chris Co @ 2018-07-20  6:33 UTC (permalink / raw)
  To: edk2-devel@lists.01.org; +Cc: Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This adds support for configuring the USB EHCI PHY on NXP i.MX6 SoCs.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Christopher Co <christopher.co@microsoft.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhy.c      | 364 ++++++++++++++++++++
 Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhyLib.inf |  43 +++
 2 files changed, 407 insertions(+)

diff --git a/Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhy.c b/Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhy.c
new file mode 100644
index 000000000000..967fa0620242
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhy.c
@@ -0,0 +1,364 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <PiDxe.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <iMX6.h>
+#include <iMX6IoMux.h>
+#include <iMX6UsbPhy.h>
+
+/**
+  Timeout constants
+**/
+
+#define USB_PHY_PLL_LOCK_TIMEOUT_USEC (UINT32)(1000*1000)
+#define USB_EHCI_STOP_RESET_TIMEOUT_USEC (UINT32)(1000*1000)
+
+/**
+  Required register bit masks
+**/
+
+#define IMX_CCM_ANALOG_PLL_USB1_REG_LOCK 0x80000000
+
+#define IMX_USB_CMD_REG_RUN 0x00000001
+#define IMX_USB_CMD_REG_RESET 0x00000002
+
+/**
+  Wait for a register bit to be on/off
+**/
+EFI_STATUS RegisterWaitBit (
+    volatile VOID* RegisterAddr,
+    UINT32 Mask,
+    BOOLEAN IsWaitOn,
+    UINT32 TimeOutUsec)
+{
+    UINT32 TimeUsec = 0;
+    do {
+        UINT32 RegisterValue = MmioRead32((UINTN)RegisterAddr) & Mask;
+        if (((RegisterValue == Mask) && IsWaitOn) || ((RegisterValue == 0) && !IsWaitOn)) {
+            return EFI_SUCCESS;
+        }
+
+        MicroSecondDelay(10);
+        TimeUsec += 10;
+    } while (TimeUsec < TimeOutUsec);
+
+    return EFI_TIMEOUT;
+}
+
+/**
+  Turn on the 480Mhz PLL
+**/
+EFI_STATUS ImxUsbPhyEnablePll (IMX_USBPHY_ID ImxUsbPhyId)
+{
+    volatile IMX_CCM_ANALOG_REGISTERS* CcmAnaRegsPtr = (IMX_CCM_ANALOG_REGISTERS*)IMX_CCM_ANALOG_BASE;
+    volatile IMX_CCM_ANALOG_PLL_USB1_REG* PllUsbClrRegPtr;
+    volatile IMX_CCM_ANALOG_PLL_USB1_REG* PllUsbSetRegPtr;
+    EFI_STATUS Status;
+
+    switch (ImxUsbPhyId) {
+    case IMX_USBPHY0:
+        PllUsbClrRegPtr = (IMX_CCM_ANALOG_PLL_USB1_REG*)&CcmAnaRegsPtr->PLL_USB1_CLR;
+        PllUsbSetRegPtr = (IMX_CCM_ANALOG_PLL_USB1_REG*)&CcmAnaRegsPtr->PLL_USB1_SET;
+        break;
+
+    case IMX_USBPHY1:
+        PllUsbClrRegPtr = (IMX_CCM_ANALOG_PLL_USB1_REG*)&CcmAnaRegsPtr->PLL_USB2_CLR;
+        PllUsbSetRegPtr = (IMX_CCM_ANALOG_PLL_USB1_REG*)&CcmAnaRegsPtr->PLL_USB2_SET;
+        break;
+
+    default:
+        return EFI_INVALID_PARAMETER;
+    }
+
+    IMX_CCM_ANALOG_PLL_USB1_REG PllUsbClrReg = { 0 };
+    PllUsbClrReg.BYPASS = 1;
+    MmioWrite32((UINTN)PllUsbClrRegPtr, PllUsbClrReg.AsUint32);
+
+    IMX_CCM_ANALOG_PLL_USB1_REG PllUsbSetReg = { 0 };
+    PllUsbSetReg.EN_USB_CLKS = 1;
+    PllUsbSetReg.POWER = 1;
+    PllUsbSetReg.ENABLE = 1;
+    MmioWrite32((UINTN)PllUsbSetRegPtr, PllUsbSetReg.AsUint32);
+
+    //
+    // Wait for PLL to lock
+    //
+    Status = RegisterWaitBit(
+        PllUsbSetRegPtr,
+        IMX_CCM_ANALOG_PLL_USB1_REG_LOCK,
+        TRUE, // On
+        USB_PHY_PLL_LOCK_TIMEOUT_USEC);
+
+    if (Status != EFI_SUCCESS) {
+        DEBUG((DEBUG_ERROR, "PLL 480Mhz failed to lock for PHY %d\n", (UINT32)ImxUsbPhyId));
+
+        //
+        // On failure disable the PHY
+        //
+        PllUsbClrReg.AsUint32 = 0;
+        PllUsbSetReg.EN_USB_CLKS = 1;
+        PllUsbSetReg.POWER = 1;
+        PllUsbSetReg.ENABLE = 1;
+        MmioWrite32((UINTN)PllUsbClrRegPtr, PllUsbSetReg.AsUint32);
+        return Status;
+    }
+
+    return EFI_SUCCESS;
+}
+
+/**
+  Reset the EHCI controller associated with the given PHY.
+**/
+EFI_STATUS ImxUsbEhciResetController (IMX_USBPHY_ID ImxUsbPhyId)
+{
+    volatile USB_USBCMD_REG* UsbCmdRegPtr;
+    EFI_STATUS Status;
+
+    switch (ImxUsbPhyId) {
+    case IMX_USBPHY0:
+        UsbCmdRegPtr = (USB_USBCMD_REG*)(IMX_USBCORE_BASE + IMX_USBCORE_LENGTH * 0 + IMX_USBCMD_OFFSET);
+        break;
+
+    case IMX_USBPHY1:
+        UsbCmdRegPtr = (USB_USBCMD_REG*)(IMX_USBCORE_BASE + IMX_USBCORE_LENGTH * 1 + IMX_USBCMD_OFFSET);
+        break;
+
+    default:
+        return EFI_INVALID_PARAMETER;
+    }
+
+    //
+    // The host controller can only be reset when it is stopped.
+    //
+    USB_USBCMD_REG UsbCmdReg = { MmioRead32((UINTN)UsbCmdRegPtr) };
+    UsbCmdReg.RS = 0;
+    MmioWrite32((UINTN)UsbCmdRegPtr, UsbCmdReg.AsUint32);
+
+    //
+    // Wait for controller to stop
+    //
+    Status = RegisterWaitBit(
+        UsbCmdRegPtr,
+        IMX_USB_CMD_REG_RUN,
+        FALSE, // Off
+        USB_EHCI_STOP_RESET_TIMEOUT_USEC);
+
+    if (Status != EFI_SUCCESS) {
+        ASSERT_EFI_ERROR(Status);
+        DEBUG((DEBUG_ERROR, "Failed to stop EHCI controller (PHY %d)\n", (UINT32)ImxUsbPhyId));
+        return Status;
+    }
+
+    //
+    // Reset the controller
+    //
+    UsbCmdReg.AsUint32 = MmioRead32((UINTN)UsbCmdRegPtr);
+    UsbCmdReg.RST = 1;
+    MmioWrite32((UINTN)UsbCmdRegPtr, UsbCmdReg.AsUint32);
+
+    //
+    // Wait for controller reset to complete
+    //
+    Status = RegisterWaitBit(
+        UsbCmdRegPtr,
+        IMX_USB_CMD_REG_RESET,
+        FALSE, // Off
+        USB_EHCI_STOP_RESET_TIMEOUT_USEC);
+
+    if (Status != EFI_SUCCESS) {
+        ASSERT_EFI_ERROR(Status);
+        DEBUG((DEBUG_ERROR, "Failed to reset EHCI controller (PHY %d)\n", (UINT32)ImxUsbPhyId));
+        return Status;
+    }
+
+    //
+    // Force OTG port into Host mode. Depending on the ID_PIN tends to be
+    // unreliable in some board designs such as SABRESED.
+    // If the OTG port is not forced into Host mode, the USB stack fails to
+    // start.
+    //
+    if (ImxUsbPhyId == IMX_USBPHY0) {
+        volatile USB_USBMODE_REG* UsbModeRegPtr;
+        USB_USBMODE_REG UsbModeReg;
+
+        DEBUG((DEBUG_INFO, "Switching USB OTG Port to Host\n"));
+
+        UsbModeRegPtr = (USB_USBMODE_REG*)(IMX_USBCORE_BASE + IMX_USBMODE_OFFSET);
+        UsbModeReg.AsUint32 = MmioRead32((UINTN)UsbModeRegPtr);
+        UsbModeReg.CM = IMX_USBMODE_HOST;
+        MmioWrite32((UINTN)UsbModeRegPtr, UsbModeReg.AsUint32);
+
+        DEBUG_CODE_BEGIN();
+        UsbModeReg.AsUint32 = MmioRead32((UINTN)UsbModeRegPtr);
+        ASSERT(UsbModeReg.CM == IMX_USBMODE_HOST);
+        DEBUG_CODE_END();
+    }
+
+    return EFI_SUCCESS;
+}
+
+/**
+  Initialize a USB PHY
+**/
+EFI_STATUS ImxUsbPhyInit (IMX_USBPHY_ID ImxUsbPhyId)
+{
+    volatile IMX_USBNONCORE_REGISTERS* UsbNonCoreRegPtr = (IMX_USBNONCORE_REGISTERS*)IMX_USBNONCORE_BASE;
+    volatile IMX_USBANA_REGISTERS* UsbAnaRegsPtr = (IMX_USBANA_REGISTERS*)IMX_USBANA_BASE;
+    volatile IMX_USBPHY_REGISTERS* UsbPhyRegsPtr;
+    volatile IMX_USBANA_USB_REGISTERS* UsbAnaUsbRegsPtr;
+    volatile USBNC_USB_UH_CTRL_REG* UsbNcUhCtrlRegPtr;
+    EFI_STATUS Status;
+
+    switch (ImxUsbPhyId) {
+    case IMX_USBPHY0:
+        UsbPhyRegsPtr = (IMX_USBPHY_REGISTERS*)IMX_USBPHY1_BASE;
+        UsbAnaUsbRegsPtr = &UsbAnaRegsPtr->USBANA[0];
+        UsbNcUhCtrlRegPtr = (USBNC_USB_UH_CTRL_REG*)&UsbNonCoreRegPtr->USBNC_USB_OTG_CTRL;
+        break;
+
+    case IMX_USBPHY1:
+        UsbPhyRegsPtr = (IMX_USBPHY_REGISTERS*)IMX_USBPHY2_BASE;
+        UsbAnaUsbRegsPtr = &UsbAnaRegsPtr->USBANA[1];
+        UsbNcUhCtrlRegPtr = (USBNC_USB_UH_CTRL_REG*)&UsbNonCoreRegPtr->USBNC_USB_UH1_CTRL;
+        break;
+
+    default:
+        return EFI_INVALID_PARAMETER;
+    }
+
+    //
+    // USB power configuration:
+    //
+    {
+        //
+        // Set power polarity
+        //
+        USBNC_USB_UH_CTRL_REG UsbNcHcCtrlReg = { MmioRead32((UINTN)UsbNcUhCtrlRegPtr) };
+        UsbNcHcCtrlReg.PWR_POL = 1;
+        UsbNcHcCtrlReg.AsUint32 |= 0x2;     // Reserved bit
+        MmioWrite32((UINTN)UsbNcUhCtrlRegPtr, UsbNcHcCtrlReg.AsUint32);
+
+        //
+        // Disable external USB charger detector
+        //
+        USB_ANALOG_USB_CHRG_DETECT_REG UsbAnaChrgDetReg = { 0 };
+        UsbAnaChrgDetReg.EN_B = 1;
+        UsbAnaChrgDetReg.CHK_CHRG_B = 1;
+        MmioWrite32((UINTN)&UsbAnaUsbRegsPtr->USB_ANALOG_USB_CHRG_DETECT_SET, UsbAnaChrgDetReg.AsUint32);
+
+        //
+        // Enable the 480Mhz PLL
+        //
+        Status = ImxUsbPhyEnablePll(ImxUsbPhyId);
+        if (Status != EFI_SUCCESS) {
+            ASSERT_EFI_ERROR(Status);
+            DEBUG((DEBUG_ERROR, "Failed to enable PLL 480Mhz failed for PHY %d\n", (UINT32)ImxUsbPhyId));
+            return Status;
+        }
+    }
+
+    //
+    // Configure Over Current
+    //
+    {
+        USBNC_USB_UH_CTRL_REG UsbNcHcCtrlReg = { MmioRead32((UINTN)UsbNcUhCtrlRegPtr) };
+        UsbNcHcCtrlReg.OVER_CUR_POL = 0;
+        UsbNcHcCtrlReg.OVER_CUR_DIS = 1;
+        MmioWrite32((UINTN)UsbNcUhCtrlRegPtr, UsbNcHcCtrlReg.AsUint32);
+    }
+
+    //
+    // Enable USBH PHY clock
+    //
+    {
+        USBPHYx_CTRL_REG UsbPhyCtrlReg = { 0 };
+        UsbPhyCtrlReg.CLKGATE = 1;
+        MmioWrite32((UINTN)&UsbPhyRegsPtr->USBPHY_CTRL_CLR, UsbPhyCtrlReg.AsUint32);
+        MicroSecondDelay(10);
+    }
+
+    //
+    // Enable clock to UTMI block
+    //
+    {
+        USB_ANALOG_USB_MISC_REG UsbAnaMicReg = { 0 };
+        UsbAnaMicReg.EN_CLK_UTMI = 1;
+        MmioWrite32((UINTN)&UsbAnaUsbRegsPtr->USB_ANALOG_USB_MISC_SET, UsbAnaMicReg.AsUint32);
+        MicroSecondDelay(10);
+    }
+
+    //
+    // Enable USBH PHY
+    //
+    {
+        //
+        // Reset the associated EHCI controller
+        //
+        Status = ImxUsbEhciResetController(ImxUsbPhyId);
+        if (Status != EFI_SUCCESS) {
+            return Status;
+        }
+
+        //
+        // Reset the PHY
+        //
+        USBPHYx_CTRL_REG UsbPhyCtrl;
+        {
+            UsbPhyCtrl.AsUint32 = 0;
+            UsbPhyCtrl.SFTRST = 1;
+            MmioWrite32((UINTN)&UsbPhyRegsPtr->USBPHY_CTRL_SET, UsbPhyCtrl.AsUint32);
+            MicroSecondDelay(10);
+
+            UsbPhyCtrl.AsUint32 = 0;
+            UsbPhyCtrl.SFTRST = 1;
+            UsbPhyCtrl.CLKGATE = 1;
+            MmioWrite32((UINTN)&UsbPhyRegsPtr->USBPHY_CTRL_CLR, UsbPhyCtrl.AsUint32);
+            MicroSecondDelay(10);
+        }
+
+        //
+        // Power UP the PHY
+        //
+        MmioWrite32((UINTN)&UsbPhyRegsPtr->USBPHY_PWD, 0);
+
+        //
+        // Apply PHY configuration:
+        // - Enable low/full speed devices.
+        //
+        UsbPhyCtrl.AsUint32 = 0;
+        // iMX6 Solo and DualLite - 66.3.4 USB PHY General Control Register (USBPHYx_CTRLn)
+#if !(defined(CPU_IMX6SX) || defined(CPU_IMX6SDL))
+        UsbPhyCtrl.ENAUTOSET_USBCLKS = 1;
+        UsbPhyCtrl.ENAUTOCLR_USBCLKGATE = 1;
+#endif
+        UsbPhyCtrl.ENAUTOCLR_PHY_PWD = 1;
+        UsbPhyCtrl.ENAUTOCLR_CLKGATE = 1;
+#if !(defined(CPU_IMX6SX) || defined(CPU_IMX6SDL))
+        UsbPhyCtrl.ENAUTO_PWRON_PLL = 1;
+#endif
+        UsbPhyCtrl.ENUTMILEVEL2 = 1;
+        UsbPhyCtrl.ENUTMILEVEL3 = 1;
+        MmioWrite32((UINTN)&UsbPhyRegsPtr->USBPHY_CTRL_SET, UsbPhyCtrl.AsUint32);
+#if !(defined(CPU_IMX6SX) || defined(CPU_IMX6SDL))
+        MmioWrite32 ((UINTN)&UsbPhyRegsPtr->USBPHY_IP_SET, IMX_USBPHY_IP_FIX);
+#endif
+    }
+
+    return EFI_SUCCESS;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhyLib.inf b/Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhyLib.inf
new file mode 100644
index 000000000000..35b31adf7989
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhyLib.inf
@@ -0,0 +1,43 @@
+## @file
+#
+#  Copyright (c) Microsoft Corporation. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = iMX6UsbPhyLib
+  FILE_GUID                      = 463989D1-27DC-4AE7-92AE-C7E28C1C605D
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = iMX6UsbPhyLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  Silicon/NXP/iMXPlatformPkg/iMXPlatformPkg.dec
+  Silicon/NXP/iMX6Pkg/iMX6Pkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  IoLib
+  TimerLib
+  iMXIoMuxLib
+
+[Sources.common]
+  iMX6UsbPhy.c
+
+[FixedPcd]
+  giMXPlatformTokenSpaceGuid.PcdGpioBankMemoryRange
-- 
2.16.2.gvfs.1.33.gf5370f1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH edk2-platforms 07/13] Silicon/NXP: Add i.MX6 I/O MUX library
  2018-07-20  6:33 [PATCH edk2-platforms 00/13] Silicon/NXP: Import NXP i.MX6 Package Chris Co
                   ` (5 preceding siblings ...)
  2018-07-20  6:33 ` [PATCH edk2-platforms 06/13] Silicon/NXP: Add i.MX6 USB Phy Library Chris Co
@ 2018-07-20  6:33 ` Chris Co
  2018-07-20  6:33 ` [PATCH edk2-platforms 08/13] Silicon/NXP: Add i.MX6 Clock Library Chris Co
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chris Co @ 2018-07-20  6:33 UTC (permalink / raw)
  To: edk2-devel@lists.01.org; +Cc: Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This adds support for initializing and manipulating the I/O Pads
on NXP i.MX6 SoCs.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Christopher Co <christopher.co@microsoft.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/NXP/iMX6Pkg/Library/iMX6IoMuxLib/iMX6IoMux.c      | 163 ++++++++++++++++++++
 Silicon/NXP/iMX6Pkg/Library/iMX6IoMuxLib/iMX6IoMuxLib.inf |  41 +++++
 2 files changed, 204 insertions(+)

diff --git a/Silicon/NXP/iMX6Pkg/Library/iMX6IoMuxLib/iMX6IoMux.c b/Silicon/NXP/iMX6Pkg/Library/iMX6IoMuxLib/iMX6IoMux.c
new file mode 100644
index 000000000000..573f6c581a63
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Library/iMX6IoMuxLib/iMX6IoMux.c
@@ -0,0 +1,163 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <PiDxe.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+
+#include <iMX6.h>
+#include <iMX6IoMux.h>
+
+//
+// Muxing functions
+//
+
+VOID
+ImxPadConfig (
+  IMX_PAD Pad,
+  IMX_PADCFG PadConfig
+  )
+{
+  _Static_assert(
+    (IOMUXC_SELECT_INPUT_UPPER_BOUND - IOMUXC_SELECT_INPUT_BASE_ADDRESS) < (0xff * 4),
+    "Too many SELECT_INPUT registers values to encode in IMX_PADCFG");
+
+  //
+  // Configure Mux Control
+  //
+  MmioWrite32 (
+    IMX_IOMUXC_BASE + _IMX_PAD_MUX_OFFSET(Pad),
+    _IMX_PADCFG_MUX_CTL(PadConfig));
+
+  //
+  // Configure Select Input Control
+  //
+  if (_IMX_PADCFG_SEL_INP(PadConfig) != 0) {
+    DEBUG ((DEBUG_INFO, "Setting INPUT_SELECT %x value %x\n",
+      _IMX_SEL_INP_REGISTER(_IMX_PADCFG_SEL_INP(PadConfig)),
+      _IMX_SEL_INP_VALUE(_IMX_PADCFG_SEL_INP(PadConfig))));
+
+    MmioWrite32 (
+      _IMX_SEL_INP_REGISTER(_IMX_PADCFG_SEL_INP(PadConfig)),
+      _IMX_SEL_INP_VALUE(_IMX_PADCFG_SEL_INP(PadConfig)));
+  }
+
+  //
+  // Configure Pad Control
+  //
+  MmioWrite32 (
+    IMX_IOMUXC_BASE + _IMX_PAD_CTL_OFFSET(Pad),
+    _IMX_PADCFG_PAD_CTL(PadConfig));
+}
+
+VOID
+ImxPadDumpConfig (
+  char *SignalFriendlyName,
+  IMX_PAD Pad
+  )
+{
+  IMX_IOMUXC_MUX_CTL muxCtl;
+  muxCtl.AsUint32 = MmioRead32 (
+    IMX_IOMUXC_BASE + _IMX_PAD_MUX_OFFSET(Pad));
+
+  DEBUG ((
+    DEBUG_INIT,
+    "- %a MUX_CTL(0x%p)=0x%08x: MUX_MODE:%d SION:%d | ",
+    SignalFriendlyName,
+    IMX_IOMUXC_BASE + _IMX_PAD_MUX_OFFSET(Pad),
+    muxCtl.AsUint32,
+    muxCtl.Fields.MUX_MODE,
+    muxCtl.Fields.SION));
+
+  IMX_IOMUXC_PAD_CTL padCtl;
+  padCtl.AsUint32 = MmioRead32 (
+    IMX_IOMUXC_BASE + _IMX_PAD_CTL_OFFSET(Pad));
+
+  DEBUG ((
+    DEBUG_INIT,
+    "PAD_CTL(0x%p)=0x%08x: SRE:%d DSE:%d SPEED:%d ODE:%d PKE:%d PUE:%d PUS:%d HYS:%d\n",
+    IMX_IOMUXC_BASE + _IMX_PAD_CTL_OFFSET(Pad),
+    padCtl.AsUint32,
+    padCtl.Fields.SRE,
+    padCtl.Fields.DSE,
+    padCtl.Fields.SPEED,
+    padCtl.Fields.ODE,
+    padCtl.Fields.PKE,
+    padCtl.Fields.PUE,
+    padCtl.Fields.PUS,
+    padCtl.Fields.HYS));
+}
+
+//
+// GPIO functions
+//
+
+VOID
+ImxGpioDirection (
+  IMX_GPIO_BANK Bank,
+  UINT32 IoNumber,
+  IMX_GPIO_DIR Direction
+  )
+{
+  volatile IMX_GPIO_REGISTERS *gpioRegisters =
+      (IMX_GPIO_REGISTERS *) IMX_GPIO_BASE;
+
+  ASSERT (IoNumber < 32);
+
+  if (Direction == IMX_GPIO_DIR_INPUT) {
+    MmioAnd32 ((UINTN) &gpioRegisters->Banks[Bank - 1].GDIR, ~(1 << IoNumber));
+  } else {
+    MmioOr32 ((UINTN) &gpioRegisters->Banks[Bank - 1].GDIR, 1 << IoNumber);
+  }
+}
+
+VOID
+ImxGpioWrite (
+  IMX_GPIO_BANK Bank,
+  UINT32 IoNumber,
+  IMX_GPIO_VALUE Value
+  )
+{
+  volatile IMX_GPIO_REGISTERS *gpioRegisters =
+      (IMX_GPIO_REGISTERS *) IMX_GPIO_BASE;
+
+  ASSERT (IoNumber < 32);
+
+  if (Value == IMX_GPIO_LOW) {
+    MmioAnd32 ((UINTN) &gpioRegisters->Banks[Bank - 1].DR, ~(1 << IoNumber));
+  } else {
+    MmioOr32 ((UINTN) &gpioRegisters->Banks[Bank - 1].DR, 1 << IoNumber);
+  }
+}
+
+IMX_GPIO_VALUE
+ImxGpioRead (
+  IMX_GPIO_BANK Bank,
+  UINT32 IoNumber
+  )
+{
+  volatile IMX_GPIO_REGISTERS *gpioRegisters =
+      (IMX_GPIO_REGISTERS *) IMX_GPIO_BASE;
+
+  ASSERT (IoNumber < 32);
+
+  UINT32 Mask = (1 << IoNumber);
+  UINT32 Psr = MmioRead32 ((UINTN) &gpioRegisters->Banks[Bank - 1].PSR);
+
+  if (Psr & Mask) {
+    return IMX_GPIO_HIGH;
+  } else {
+    return IMX_GPIO_LOW;
+  }
+}
diff --git a/Silicon/NXP/iMX6Pkg/Library/iMX6IoMuxLib/iMX6IoMuxLib.inf b/Silicon/NXP/iMX6Pkg/Library/iMX6IoMuxLib/iMX6IoMuxLib.inf
new file mode 100644
index 000000000000..8af5502be4d8
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Library/iMX6IoMuxLib/iMX6IoMuxLib.inf
@@ -0,0 +1,41 @@
+## @file
+#
+#  Copyright (c) Microsoft Corporation. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = iMX6IoMuxLib
+  FILE_GUID                      = FA41BEF0-0666-4C07-9EC3-47F61C36EDBE
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = iMX6IoMuxLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  Silicon/NXP/iMXPlatformPkg/iMXPlatformPkg.dec
+  Silicon/NXP/iMX6Pkg/iMX6Pkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  IoLib
+  TimerLib
+
+[Sources.common]
+  iMX6IoMux.c
+
+ [FixedPcd]
+  giMXPlatformTokenSpaceGuid.PcdGpioBankMemoryRange
-- 
2.16.2.gvfs.1.33.gf5370f1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH edk2-platforms 08/13] Silicon/NXP: Add i.MX6 Clock Library
  2018-07-20  6:33 [PATCH edk2-platforms 00/13] Silicon/NXP: Import NXP i.MX6 Package Chris Co
                   ` (6 preceding siblings ...)
  2018-07-20  6:33 ` [PATCH edk2-platforms 07/13] Silicon/NXP: Add i.MX6 I/O MUX library Chris Co
@ 2018-07-20  6:33 ` Chris Co
  2018-07-20  6:33 ` [PATCH edk2-platforms 09/13] Silicon/NXP: Add i.MX6 ACPI tables Chris Co
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chris Co @ 2018-07-20  6:33 UTC (permalink / raw)
  To: edk2-devel@lists.01.org; +Cc: Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This adds support for managing clocks on NXP i.MX6 SoC. It will
manipulate the Clock Gating registers (CCGR).

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Christopher Co <christopher.co@microsoft.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwr.c         |  501 ++++++++
 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwrLib.inf    |   46 +
 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwr_private.h |  203 ++++
 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6DQClkPwr.inc     | 1278 ++++++++++++++++++++
 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6SDLClkPwr.inc    | 1231 +++++++++++++++++++
 Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6SXClkPwr.inc     |  665 ++++++++++
 6 files changed, 3924 insertions(+)

diff --git a/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwr.c b/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwr.c
new file mode 100644
index 000000000000..91811ae44cdc
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwr.c
@@ -0,0 +1,501 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <PiDxe.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/TimerLib.h>
+#include <Library/BaseMemoryLib.h>
+
+#include <iMX6.h>
+#include <iMX6ClkPwr.h>
+#include "iMX6ClkPwr_private.h"
+
+// Let GCC know it's OK to compare enum values
+#if defined (__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wenum-compare"
+#endif
+
+C_ASSERT(IMX_CLOCK_GATE_STATE_OFF == IMX_CCM_CCGR_OFF);
+C_ASSERT(IMX_CLOCK_GATE_STATE_ON_RUN == IMX_CCM_CCGR_ON_RUN);
+C_ASSERT(IMX_CLOCK_GATE_STATE_ON == IMX_CCM_CCGR_ON);
+
+#if defined (__GNUC__)
+#pragma GCC diagnostic pop // -Wenum-compare
+#endif
+
+/**
+  Caches clock values, since clocks towards the root of the tree are
+  requested frequently.
+**/
+static IMX_CLOCK_TREE_CACHE ImxpClockPwrCache;
+
+#if defined(CPU_IMX6DQ)
+#include "iMX6DQClkPwr.inc"
+#elif defined(CPU_IMX6SX)
+#include "iMX6SXClkPwr.inc"
+#elif defined(CPU_IMX6SDL)
+#include "iMX6SDLClkPwr.inc"
+#else
+#error CPU Preprocessor Flag Not Defined
+#endif
+
+//
+// Common private functions
+//
+
+/**
+  Reset (invalidate) the clock tree cache. The clock tree cache must be
+  invalidated whenever the clock tree is modified, e.g. when changing
+  PLL configuration, clock mux, or divider.
+**/
+VOID ImxpClkPwrCacheReset ()
+{
+  SetMem (&ImxpClockPwrCache.Valid, sizeof(ImxpClockPwrCache.Valid), 0);
+}
+
+/**
+  Configure clock gating for the specified clock signal.
+**/
+VOID ImxClkPwrSetClockGate (IMX_CLK_GATE ClockGate, IMX_CLOCK_GATE_STATE State)
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  // Extract register index
+  const IMX_CCGR_INDEX index = ImxpCcgrIndexFromClkGate(ClockGate);
+  const UINTN startBit = index.GateNumber * 2;
+  const UINTN endBit = startBit + 1;
+
+  MmioBitFieldWrite32 (
+    (UINTN) &ccmRegisters->CCGR[index.RegisterIndex],
+    startBit,
+    endBit,
+    State);
+}
+
+/**
+  Determine if gating TZASC1_IPG_MASTER_CLK should be skipped.
+ **/
+BOOLEAN ImxClkPwrShouldSkipTZASC1 ()
+{
+    BOOLEAN Skip = FALSE;
+
+#if defined(CPU_IMX6DQ)
+    IMX_IOMUXC_GPR_REGISTERS *IoMuxMmioBasePtr =
+        (IMX_IOMUXC_GPR_REGISTERS *)IOMUXC_GPR_BASE_ADDRESS;
+
+    UINTN IomuxGPR9 = MmioRead32 ((UINTN) &IoMuxMmioBasePtr->GPR9);
+    if (IomuxGPR9 & IMX_IOMUXC_TZASC1_BYP) {
+        // TZASC-1 is active.
+        Skip = TRUE;
+    }
+#endif
+
+    return Skip;
+}
+
+/**
+  Determine if a clock gate should be skipped
+ **/
+BOOLEAN ImxClkPwrShouldSkipGate (IMX_CLK_GATE ClockGate)
+{
+    switch(ClockGate) {
+    case IMX_IPSYNC_IP2APB_TZASC1_IPG_MASTER_CLK_ENABLE:
+        return ImxClkPwrShouldSkipTZASC1 ();
+
+    default:
+        return FALSE;
+    }
+}
+
+/**
+  Set multiple clock gates to a given state efficiently.
+**/
+VOID ImxClkPwrSetClockGates (
+  const IMX_CLK_GATE *ClockGateList,
+  UINTN ClockGateCount,
+  IMX_CLOCK_GATE_STATE State
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  UINTN i;
+
+  // Read all CCGR registers to local copy
+  UINT32 ccgrRegisters[ARRAYSIZE (ccmRegisters->CCGR)];
+  for (i = 0; i < ARRAYSIZE (ccgrRegisters); ++i) {
+    ccgrRegisters[i] = MmioRead32 ((UINTN) &ccmRegisters->CCGR[i]);
+  }
+
+  // Compute new CCGR register values
+  for (i = 0; i < ClockGateCount; ++i) {
+    if (ImxClkPwrShouldSkipGate(ClockGateList[i])) {
+        continue;
+    }
+
+    IMX_CCGR_INDEX index = ImxpCcgrIndexFromClkGate (ClockGateList[i]);
+    ccgrRegisters[index.RegisterIndex] =
+      (ccgrRegisters[index.RegisterIndex] & ~(0x3 << (2 * index.GateNumber))) |
+      (State << (2 * index.GateNumber));
+  }
+
+  // Write back to registers
+  for (i = 0; i < ARRAYSIZE (ccgrRegisters); ++i) {
+    MmioWrite32 ((UINTN) &ccmRegisters->CCGR[i], ccgrRegisters[i]);
+  }
+}
+
+/**
+  Get the current clock gating setting for the specified clock gate.
+**/
+IMX_CLOCK_GATE_STATE ImxClkPwrGetClockGate (IMX_CLK_GATE ClockGate)
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  const IMX_CCGR_INDEX index = ImxpCcgrIndexFromClkGate(ClockGate);
+  const UINTN startBit = index.GateNumber * 2;
+  const UINTN endBit = startBit + 1;
+
+  UINT32 value = MmioBitFieldRead32 (
+                    (UINTN) &ccmRegisters->CCGR[index.RegisterIndex],
+                    startBit,
+                    endBit);
+
+  if ((value != IMX_CCM_CCGR_OFF) && (value != IMX_CCM_CCGR_ON_RUN) &&
+      (value != IMX_CCM_CCGR_ON)) {
+      ASSERT (FALSE);
+  }
+
+  return (IMX_CLOCK_GATE_STATE) value;
+}
+
+EFI_STATUS
+ImxpGetPll3MainClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_ANALOG_REGISTERS *ccmAnalogRegisters =
+      (IMX_CCM_ANALOG_REGISTERS *) IMX_CCM_ANALOG_BASE;
+
+  IMX_CCM_ANALOG_PLL_USB1_REG pllUsb1Reg; pllUsb1Reg.AsUint32 =
+      MmioRead32((UINTN)&ccmAnalogRegisters->PLL_USB1);
+
+  const IMX_CLK parent = ImxpClkFromBypassClkSource (pllUsb1Reg.BYPASS_CLK_SRC);
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  if (pllUsb1Reg.DIV_SELECT == 0) {
+    ClockInfo->Frequency = parentInfo.Frequency * 20;
+  } else {
+    ClockInfo->Frequency = parentInfo.Frequency * 22;
+  }
+
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetPll3PfdClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  IMX_PLL_PFD PfdIndex,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_ANALOG_REGISTERS *ccmAnalogRegisters =
+      (IMX_CCM_ANALOG_REGISTERS *) IMX_CCM_ANALOG_BASE;
+
+  IMX_CCM_PFD_480_REG pfd480Reg;pfd480Reg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmAnalogRegisters->PFD_480);
+
+  UINT32 pfdFrac;
+  switch (PfdIndex) {
+  case IMX_PLL_PFD0:
+    pfdFrac = pfd480Reg.PFD0_FRAC;
+    break;
+  case IMX_PLL_PFD1:
+    pfdFrac = pfd480Reg.PFD1_FRAC;
+    break;
+  case IMX_PLL_PFD2:
+    pfdFrac = pfd480Reg.PFD2_FRAC;
+    break;
+  case IMX_PLL_PFD3:
+    pfdFrac = pfd480Reg.PFD3_FRAC;
+    break;
+  default:
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, IMX_PLL3_MAIN_CLK, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  // The resulting frequency shall be 480*18/PFDn_FRAC
+  // where PFD0_FRAC is in the range 12-35.
+  ASSERT ((pfdFrac >= 12) && (pfdFrac <= 35));
+  ClockInfo->Frequency = (UINT32) ((UINT64) parentInfo.Frequency * 18 / pfdFrac);
+  ClockInfo->Parent = IMX_PLL3_MAIN_CLK;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetPll3SwClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CCSR_REG ccsrReg; ccsrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CCSR);
+
+  IMX_CLK parent;
+  if (ccsrReg.pll3_sw_clk_sel == IMX_CCM_PLL3_SW_CLK_SEL_PLL3_MAIN_CLK) {
+    parent = IMX_PLL3_MAIN_CLK;
+  } else {
+    ASSERT (ccsrReg.pll3_sw_clk_sel == IMX_CCM_PLL3_SW_CLK_SEL_PLL3_BYPASS_CLK);
+
+    ASSERT (!"Not implemented");
+    return EFI_UNSUPPORTED;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency = parentInfo.Frequency;
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+ImxpGetPll1MainClkInfo  (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_ANALOG_REGISTERS *ccmAnalogRegisters =
+      (IMX_CCM_ANALOG_REGISTERS *) IMX_CCM_ANALOG_BASE;
+
+  IMX_CCM_ANALOG_PLL_ARM_REG pllArmReg;pllArmReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmAnalogRegisters->PLL_ARM);
+
+  const IMX_CLK parent = ImxpClkFromBypassClkSource (pllArmReg.BYPASS_CLK_SRC);
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  if (pllArmReg.BYPASS != 0) {
+    ClockInfo->Frequency = parentInfo.Frequency;
+    ClockInfo->Parent = parent;
+    return EFI_SUCCESS;
+  }
+
+  ClockInfo->Frequency =
+    (UINT32) ((UINT64) parentInfo.Frequency * pllArmReg.DIV_SELECT / 2);
+
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetPll2MainClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_ANALOG_REGISTERS *ccmAnalogRegisters =
+      (IMX_CCM_ANALOG_REGISTERS *) IMX_CCM_ANALOG_BASE;
+
+  IMX_CCM_ANALOG_PLL_SYS_REG pllSysReg; pllSysReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmAnalogRegisters->PLL_SYS);
+
+  // Determine the reference clock source
+  const IMX_CLK parent = ImxpClkFromBypassClkSource (pllSysReg.BYPASS_CLK_SRC);
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  if (pllSysReg.BYPASS != 0) {
+    ClockInfo->Frequency = parentInfo.Frequency;
+    ClockInfo->Parent = parent;
+    return EFI_SUCCESS;
+  }
+
+  if (pllSysReg.DIV_SELECT == 0) {
+    ClockInfo->Frequency = parentInfo.Frequency * 20;
+  } else {
+    ASSERT (pllSysReg.DIV_SELECT == 1);
+    ClockInfo->Frequency = parentInfo.Frequency * 22;
+  }
+
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetArmClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CLOCK_INFO pll1Info;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, IMX_PLL1_MAIN_CLK, &pll1Info);
+  if (EFI_ERROR(status)) {
+    return status;
+  }
+
+  IMX_CCM_CACRR_REG cacrrReg;cacrrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CACRR);
+
+  ClockInfo->Frequency = pll1Info.Frequency / (1 + cacrrReg.arm_podf);
+  ClockInfo->Parent = IMX_PLL1_MAIN_CLK;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetPrePeriphClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCMR_REG cbcmrReg ; cbcmrReg.AsUint32 = MmioRead32 ((UINTN) &ccmRegisters->CBCMR);
+
+  IMX_CLK parent;
+  switch (cbcmrReg.pre_periph_clk_sel) {
+  case IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2:
+    parent = IMX_PLL2_MAIN_CLK;
+    break;
+  case IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2_PFD2:
+    parent = IMX_PLL2_PFD2;
+    break;
+  case IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2_PFD0:
+    parent = IMX_PLL2_PFD0;
+    break;
+  case IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2_PFD2_DIV2:
+    parent = IMX_PLL2_PFD2;
+    break;
+  default:
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  if (cbcmrReg.pre_periph_clk_sel == IMX_CCM_PRE_PERIPH_CLK_SEL_PLL2_PFD2_DIV2) {
+    ClockInfo->Frequency = parentInfo.Frequency / 2;
+  } else {
+    ClockInfo->Frequency = parentInfo.Frequency;
+  }
+
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+VOID ImxpGetOsc24ClkInfo (OUT IMX_CLOCK_INFO *ClockInfo)
+{
+  ClockInfo->Frequency = IMX_REF_CLK_24M_FREQ;
+  ClockInfo->Parent = IMX_CLK_NONE;
+}
+
+EFI_STATUS
+ImxpGetAhbClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+   volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, IMX_PERIPH_CLK, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  IMX_CCM_CBCDR_REG cbcdrReg; cbcdrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CBCDR);
+
+  ClockInfo->Frequency = parentInfo.Frequency / (1 + cbcdrReg.ahb_podf);
+  ClockInfo->Parent = IMX_PERIPH_CLK;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetIpgClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, IMX_AHB_CLK_ROOT, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  IMX_CCM_CBCDR_REG cbcdrReg; cbcdrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CBCDR);
+
+  ClockInfo->Frequency = parentInfo.Frequency / (1 + cbcdrReg.ipg_podf);
+  ClockInfo->Parent = IMX_AHB_CLK_ROOT;
+
+  return EFI_SUCCESS;
+}
+
+//
+// Public functions
+//
+
+EFI_STATUS
+ImxClkPwrGetClockInfo (
+  IMX_CLK ClockId,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  return ImxpGetClockInfo (&ImxpClockPwrCache, ClockId, ClockInfo);
+}
diff --git a/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwrLib.inf b/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwrLib.inf
new file mode 100644
index 000000000000..39ae4dfc2e38
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwrLib.inf
@@ -0,0 +1,46 @@
+## @file
+#
+#  Copyright (c) Microsoft Corporation. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = iMX6ClkPwrLib
+  FILE_GUID                      = 8DB4B460-9201-435A-B86A-24B58CED9A9E
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = iMX6ClkPwrLib
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  Silicon/NXP/iMXPlatformPkg/iMXPlatformPkg.dec
+  Silicon/NXP/iMX6Pkg/iMX6Pkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  DebugLib
+  IoLib
+  TimerLib
+  iMXIoMuxLib
+
+[Sources.common]
+  iMX6ClkPwr.c
+
+[FeaturePcd]
+  giMX6TokenSpaceGuid.PcdLvdsEnable
+
+[FixedPcd]
+  giMXPlatformTokenSpaceGuid.PcdGpioBankMemoryRange
diff --git a/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwr_private.h b/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwr_private.h
new file mode 100644
index 000000000000..8cb6c6062148
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwr_private.h
@@ -0,0 +1,203 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Copyright 2018 NXP
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _IMX6_CLK_PWR_PRIVATE_H_
+#define _IMX6_CLK_PWR_PRIVATE_H_
+
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
+#endif // ARRAYSIZE
+
+#ifndef C_ASSERT
+#define C_ASSERT(e) typedef char __C_ASSERT__[(e)?1:-1]
+#endif // C_ASSERT
+
+typedef enum {
+  IMX_PLL_PFD0,
+  IMX_PLL_PFD1,
+  IMX_PLL_PFD2,
+  IMX_PLL_PFD3,
+} IMX_PLL_PFD;
+
+typedef struct {
+  UINT16 RegisterIndex;   // Register index (0-6)
+  UINT16 GateNumber;      // Gate number within register (0-15)
+} IMX_CCGR_INDEX;
+
+IMX_CCGR_INDEX ImxpCcgrIndexFromClkGate (IMX_CLK_GATE ClockGate);
+
+#define _BITS_PER_UINTN (8 * sizeof(UINTN))
+
+typedef struct {
+  UINTN Valid[(IMX_CLK_MAX + _BITS_PER_UINTN) / _BITS_PER_UINTN];
+  IMX_CLOCK_INFO Table[IMX_CLK_MAX];
+} IMX_CLOCK_TREE_CACHE;
+
+VOID ImxpClkPwrCacheReset ();
+
+IMX_CLK ImxpClkFromBypassClkSource (IMX_PLL_BYPASS_CLK_SRC BypassClockSource);
+
+VOID ImxCcmConfigureGpuClockTree ();
+
+VOID ImxCcmConfigureIPUDIxClockTree ();
+
+VOID ImxCcmConfigureIPULDBxClockTree ();
+
+#if (defined(CPU_IMX6DQ) || defined(CPU_IMX6SDL))
+VOID ImxSetClockRatePLL5 (UINT32 ClockRate, IMX_CCM_PLL_VIDEO_CTRL_POST_DIV_SELECT PostDivSelect);
+#elif defined(CPU_IMX6SX)
+VOID ImxSetClockRatePLL5 (UINT32 TargetClockRate, UINT32 PreDividerLcdif1Val, UINT32 PostDividerLcdif1Val);
+#else
+#error iMX6 CPU Type Not Defined!
+#endif
+
+//
+// Clock Info functions
+//
+
+EFI_STATUS
+ImxpGetClockInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  IN IMX_CLK ClockId,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+VOID ImxpGetOsc24ClkInfo (OUT IMX_CLOCK_INFO *ClockInfo);
+
+EFI_STATUS
+ImxpGetPll1MainClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetPll2MainClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetPll2PfdClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  IMX_PLL_PFD PfdIndex,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetPll3MainClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetPll3PfdClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  IMX_PLL_PFD PfdIndex,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetPll3SwClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetAxiClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetPeriphClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetPrePeriphClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetPeriphClk2Info (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetArmClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetMmdcCh0ClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetAhbClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetIpgClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetGpu2dAxiClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetGpu3dAxiClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetGpu2dCoreClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetGpu3dCoreClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+EFI_STATUS
+ImxpGetGpu3dShaderClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  );
+
+//
+// Power functions
+//
+
+VOID ImxEnableGpuVpuPowerDomain ();
+
+VOID ImxDisableGpuVpuPowerDomain ();
+
+#endif // _IMX6_CLK_PWR_PRIVATE_H_
diff --git a/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6DQClkPwr.inc b/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6DQClkPwr.inc
new file mode 100644
index 000000000000..e01e663775c6
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6DQClkPwr.inc
@@ -0,0 +1,1278 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Copyright 2018 NXP
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#if !defined(CPU_IMX6DQ)
+#error iMX6DQClkPwr.inc should not be compiled for non iMX6DQ platform.
+#endif
+
+/**
+  Get the CCGR register index and gate number for a clock gate.
+**/
+
+IMX_CCGR_INDEX ImxpCcgrIndexFromClkGate (IMX_CLK_GATE ClockGate)
+{
+  static const IMX_CCGR_INDEX ImxpCcgrIndexMap[] = {
+    {0, 0},  // MX6_AIPS_TZ1_CLK_ENABLE
+    {0, 1},  // MX6_AIPS_TZ2_CLK_ENABLE
+    {0, 2},  // MX6_APBHDMA_HCLK_ENABLE
+    {0, 3},  // MX6_ASRC_CLK_ENABLE
+    {0, 4},  // MX6_CAAM_SECURE_MEM_CLK_ENABLE
+    {0, 5},  // MX6_CAAM_WRAPPER_ACLK_ENABLE
+    {0, 6},  // MX6_CAAM_WRAPPER_IPG_ENABLE
+    {0, 7},  // MX6_CAN1_CLK_ENABLE
+    {0, 8},  // MX6_CAN1_SERIAL_CLK_ENABLE
+    {0, 9},  // MX6_CAN2_CLK_ENABLE
+    {0, 10}, // MX6_CAN2_SERIAL_CLK_ENABLE
+    {0, 11}, // MX6_ARM_DBG_CLK_ENABLE
+    {0, 12}, // MX6_DCIC1_CLK_ENABLE
+    {0, 13}, // MX6_DCIC2_CLK_ENABLE
+    {0, 14}, // MX6_DTCP_CLK_ENABLE
+    {1, 0},  // MX6_ECSPI1_CLK_ENABLE
+    {1, 1},  // MX6_ECSPI2_CLK_ENABLE
+    {1, 2},  // MX6_ECSPI3_CLK_ENABLE
+    {1, 3},  // MX6_ECSPI4_CLK_ENABLE
+    {1, 4},  // MX6_ECSPI5_CLK_ENABLE
+    {1, 5},  // MX6_ENET_CLK_ENABLE
+    {1, 6},  // MX6_EPIT1_CLK_ENABLE
+    {1, 7},  // MX6_EPIT2_CLK_ENABLE
+    {1, 8},  // MX6_ESAI_CLK_ENABLE
+    {1, 10}, // MX6_GPT_CLK_ENABLE
+    {1, 11}, // MX6_GPT_SERIAL_CLK_ENABLE
+    {1, 12}, // MX6_GPU2D_CLK_ENABLE
+    {1, 13}, // MX6_GPU3D_CLK_ENABLE
+    {2, 0},  // MX6_HDMI_TX_ENABLE
+    {2, 2},  // MX6_HDMI_TX_ISFRCLK_ENABLE
+    {2, 3},  // MX6_I2C1_SERIAL_CLK_ENABLE
+    {2, 4},  // MX6_I2C2_SERIAL_CLK_ENABLE
+    {2, 5},  // MX6_I2C3_SERIAL_CLK_ENABLE
+    {2, 6},  // MX6_IIM_CLK_ENABLE
+    {2, 7},  // MX6_IOMUX_IPT_CLK_IO_ENABLE
+    {2, 8},  // MX6_IPMUX1_CLK_ENABLE
+    {2, 9},  // MX6_IPMUX2_CLK_ENABLE
+    {2, 10}, // MX6_IPMUX3_CLK_ENABLE
+    {2, 11}, // MX6_IPSYNC_IP2APB_TZASC1_IPG_MASTER_CLK_ENABLE
+    {2, 12}, // MX6_IPSYNC_IP2APB_TZASC2_IPG_MASTER_CLK_ENABLE
+    {2, 13}, // MX6_IPSYNC_VDOA_IPG_MASTER_CLK_ENABLE
+    {3, 0},  // MX6_IPU1_IPU_CLK_ENABLE
+    {3, 1},  // MX6_IPU1_IPU_DI0_CLK_ENABLE
+    {3, 2},  // MX6_IPU1_IPU_DI1_CLK_ENABLE
+    {3, 3},  // MX6_IPU2_IPU_CLK_ENABLE
+    {3, 4},  // MX6_IPU2_IPU_DI0_CLK_ENABLE
+    {3, 5},  // MX6_IPU2_IPU_DI1_CLK_ENABLE
+    {3, 6},  // MX6_LDB_DI0_CLK_ENABLE
+    {3, 7},  // MX6_LDB_DI1_CLK_ENABLE
+    {3, 8},  // MX6_MIPI_CORE_CFG_CLK_ENABLE
+    {3, 9},  // MX6_MLB_CLK_ENABLE
+    {3, 10}, // MX6_MMDC_CORE_ACLK_FAST_CORE_P0_ENABLE
+    {3, 12}, // MX6_MMDC_CORE_IPG_CLK_P0_ENABLE
+    {3, 14}, // MX6_OCRAM_CLK_ENABLE
+    {3, 15}, // MX6_OPENVGAXICLK_CLK_ROOT_ENABLE
+    {4, 0},  // MX6_PCIE_ROOT_ENABLE
+    {4, 4},  // MX6_PL301_MX6QFAST1_S133CLK_ENABLE
+    {4, 6},  // MX6_PL301_MX6QPER1_BCHCLK_ENABLE
+    {4, 7},  // MX6_PL301_MX6QPER2_MAINCLK_ENABLE
+    {4, 8},  // MX6_PWM1_CLK_ENABLE
+    {4, 9},  // MX6_PWM2_CLK_ENABLE
+    {4, 10}, // MX6_PWM3_CLK_ENABLE
+    {4, 11}, // MX6_PWM4_CLK_ENABLE
+    {4, 12}, // MX6_RAWNAND_U_BCH_INPUT_APB_CLK_ENABLE
+    {4, 13}, // MX6_RAWNAND_U_GPMI_BCH_INPUT_BCH_CLK_ENABLE
+    {4, 14}, // MX6_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_CLK_ENABLE
+    {4, 15}, // MX6_RAWNAND_U_GPMI_INPUT_APB_CLK_ENABLE
+    {5, 0},  // MX6_ROM_CLK_ENABLE
+    {5, 2},  // MX6_SATA_CLK_ENABLE
+    {5, 3},  // MX6_SDMA_CLK_ENABLE
+    {5, 6},  // MX6_SPBA_CLK_ENABLE
+    {5, 7},  // MX6_SPDIF_CLK_ENABLE
+    {5, 9},  // MX6_SSI1_CLK_ENABLE
+    {5, 10}, // MX6_SSI2_CLK_ENABLE
+    {5, 11}, // MX6_SSI3_CLK_ENABLE
+    {5, 12}, // MX6_UART_CLK_ENABLE
+    {5, 13}, // MX6_UART_SERIAL_CLK_ENABLE
+    {6, 0},  // MX6_USBOH3_CLK_ENABLE
+    {6, 1},  // MX6_USDHC1_CLK_ENABLE
+    {6, 2},  // MX6_USDHC2_CLK_ENABLE
+    {6, 3},  // MX6_USDHC3_CLK_ENABLE
+    {6, 4},  // MX6_USDHC4_CLK_ENABLE
+    {6, 5},  // MX6_EIM_SLOW_CLK_ENABLE
+    {6, 6},  // MX6_VDOAXICLK_CLK_ENABLE
+    {6, 7},  // MX6_VPU_CLK_ENABLE
+  };
+
+  return ImxpCcgrIndexMap[ClockGate];
+}
+
+CONST CHAR16 *StringFromImxClk (IMX_CLK Value)
+{
+  switch (Value) {
+  case IMX_CLK_NONE: return L"(none)";
+  case IMX_OSC_CLK: return L"OSC_CLK";
+  case IMX_PLL1_MAIN_CLK: return L"PLL1_MAIN_CLK";
+  case IMX_PLL2_MAIN_CLK: return L"PLL2_MAIN_CLK";
+  case IMX_PLL2_PFD0: return L"PLL2_PFD0";
+  case IMX_PLL2_PFD1: return L"PLL2_PFD1";
+  case IMX_PLL2_PFD2: return L"PLL2_PFD2";
+  case IMX_PLL3_MAIN_CLK: return L"PLL3_MAIN_CLK";
+  case IMX_PLL3_PFD0: return L"PLL3_PFD0";
+  case IMX_PLL3_PFD1: return L"PLL3_PFD1";
+  case IMX_PLL3_PFD2: return L"PLL3_PFD2";
+  case IMX_PLL3_PFD3: return L"PLL3_PFD3";
+  case IMX_PLL4_MAIN_CLK: return L"PLL4_MAIN_CLK";
+  case IMX_PLL5_MAIN_CLK: return L"PLL5_MAIN_CLK";
+  case IMX_CLK1: return L"CLK1";
+  case IMX_CLK2: return L"CLK2";
+  case IMX_PLL1_SW_CLK: return L"PLL1_SW_CLK";
+  case IMX_STEP_CLK: return L"STEP_CLK";
+  case IMX_PLL3_SW_CLK: return L"PLL3_SW_CLK";
+  case IMX_AXI_ALT: return L"AXI_ALT";
+  case IMX_AXI_CLK_ROOT: return L"AXI_CLK_ROOT";
+  case IMX_PERIPH_CLK2: return L"PERIPH_CLK2";
+  case IMX_PERIPH_CLK: return L"PERIPH_CLK";
+  case IMX_PRE_PERIPH_CLK: return L"PRE_PERIPH_CLK";
+  case IMX_PRE_PERIPH2_CLK: return L"PRE_PERIPH2_CLK";
+  case IMX_PERIPH2_CLK: return L"PERIPH2_CLK";
+  case IMX_ARM_CLK_ROOT: return L"ARM_CLK_ROOT";
+  case IMX_MMDC_CH0_CLK_ROOT: return L"MMDC_CH0_CLK_ROOT";
+  case IMX_MMDC_CH1_CLK_ROOT: return L"MMDC_CH1_CLK_ROOT";
+  case IMX_AHB_CLK_ROOT: return L"AHB_CLK_ROOT";
+  case IMX_IPG_CLK_ROOT: return L"IPG_CLK_ROOT";
+  case IMX_PERCLK_CLK_ROOT: return L"PERCLK_CLK_ROOT";
+  case IMX_USDHC1_CLK_ROOT: return L"USDHC1_CLK_ROOT";
+  case IMX_USDHC2_CLK_ROOT: return L"USDHC2_CLK_ROOT";
+  case IMX_USDHC3_CLK_ROOT: return L"USDHC3_CLK_ROOT";
+  case IMX_USDHC4_CLK_ROOT: return L"USDHC4_CLK_ROOT";
+  case IMX_SSI1_CLK_ROOT: return L"SSI1_CLK_ROOT";
+  case IMX_SSI2_CLK_ROOT: return L"SSI2_CLK_ROOT";
+  case IMX_SSI3_CLK_ROOT: return L"SSI3_CLK_ROOT";
+  case IMX_GPU2D_AXI_CLK_ROOT: return L"GPU2D_AXI_CLK_ROOT";
+  case IMX_GPU3D_AXI_CLK_ROOT: return L"GPU3D_AXI_CLK_ROOT";
+  case IMX_PCIE_AXI_CLK_ROOT: return L"PCIE_AXI_CLK_ROOT";
+  case IMX_VDO_AXI_CLK_ROOT: return L"VDO_AXI_CLK_ROOT";
+  case IMX_IPU1_HSP_CLK_ROOT: return L"IPU1_HSP_CLK_ROOT";
+  case IMX_IPU2_HSP_CLK_ROOT: return L"IPU2_HSP_CLK_ROOT";
+  case IMX_GPU2D_CORE_CLK_ROOT: return L"GPU2D_CORE_CLK_ROOT";
+  case IMX_ACLK_EIM_SLOW_CLK_ROOT: return L"ACLK_EIM_SLOW_CLK_ROOT";
+  case IMX_ACLK_CLK_ROOT: return L"ACLK_CLK_ROOT";
+  case IMX_ENFC_CLK_ROOT: return L"ENFC_CLK_ROOT";
+  case IMX_GPU3D_CORE_CLK_ROOT: return L"GPU3D_CORE_CLK_ROOT";
+  case IMX_GPU3D_SHADER_CLK_ROOT: return L"GPU3D_SHADER_CLK_ROOT";
+  case IMX_VPU_AXI_CLK_ROOT: return L"VPU_AXI_CLK_ROOT";
+  case IMX_IPU1_DI0_CLK_ROOT: return L"IPU1_DI0_CLK_ROOT";
+  case IMX_IPU1_DI1_CLK_ROOT: return L"IPU1_DI1_CLK_ROOT";
+  case IMX_IPU2_DI0_CLK_ROOT: return L"IPU2_DI0_CLK_ROOT";
+  case IMX_IPU2_DI1_CLK_ROOT: return L"IPU2_DI1_CLK_ROOT";
+  case IMX_LDB_DI0_SERIAL_CLK_ROOT: return L"LDB_DI0_SERIAL_CLK_ROOT";
+  case IMX_LDB_DI0_IPU: return L"LDB_DI0_IPU";
+  case IMX_LDB_DI1_SERIAL_CLK_ROOT: return L"LDB_DI1_SERIAL_CLK_ROOT";
+  case IMX_LDB_DI1_IPU: return L"LDB_DI1_IPU";
+  case IMX_SPDIF0_CLK_ROOT: return L"SPDIF0_CLK_ROOT";
+  case IMX_SPDIF1_CLK_ROOT: return L"SPDIF1_CLK_ROOT";
+  case IMX_ESAI_CLK_ROOT: return L"ESAI_CLK_ROOT";
+  case IMX_HSI_TX_CLK_ROOT: return L"HSI_TX_CLK_ROOT";
+  case IMX_CAN_CLK_ROOT: return L"CAN_CLK_ROOT";
+  case IMX_ECSPI_CLK_ROOT: return L"ECSPI_CLK_ROOT";
+  case IMX_UART_CLK_ROOT: return L"UART_CLK_ROOT";
+  case IMX_VIDEO_27M_CLK_ROOT: return L"VIDEO_27M_CLK_ROOT";
+  default:
+    ASSERT (FALSE);
+    return L"[invalid IMX_CLK value]";
+  }
+}
+
+IMX_CLK ImxpClkFromBypassClkSource (IMX_PLL_BYPASS_CLK_SRC BypassClockSource)
+{
+  switch (BypassClockSource) {
+  case IMX_PLL_BYPASS_CLK_SRC_REF_CLK_24M:
+    return IMX_OSC_CLK;
+  case IMX_PLL_BYPASS_CLK_SRC_CLK1:
+    return IMX_CLK1;
+  case IMX_PLL_BYPASS_CLK_SRC_CLK2:
+    return IMX_CLK2;
+  case IMX_PLL_BYPASS_CLK_SRC_XOR:
+  default:
+    ASSERT (FALSE);
+    return IMX_CLK_NONE;
+  }
+}
+
+/**
+  Configure the GPU clock tree so that GPU2D and GPU3D are clocked from
+  the AXI clock root and are within the allowed frequency range.
+
+  The GPU must be powered down, and GPU clocks must be gated when this
+  function is called.
+**/
+VOID ImxCcmConfigureGpuClockTree ()
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCMR_REG cbcmrReg ; cbcmrReg.AsUint32 = MmioRead32 ((UINTN) &ccmRegisters->CBCMR);
+
+  cbcmrReg.gpu2d_axi_clk_sel = IMX_CCM_GPU2D_AXI_CLK_SEL_AXI;
+  cbcmrReg.gpu3d_axi_clk_sel = IMX_CCM_GPU3D_AXI_CLK_SEL_AXI;
+
+  cbcmrReg.gpu2d_core_clk_sel = IMX_CCM_GPU2D_CORE_CLK_SEL_PLL2_PFD0;
+  cbcmrReg.gpu3d_core_clk_sel = IMX_CCM_GPU3D_CORE_CLK_SEL_MMDC_CH0_AXI;
+  cbcmrReg.gpu3d_shader_clk_sel = IMX_CCM_GPU3D_SHADER_CLK_SEL_MMDC_CH0_AXI;
+
+  cbcmrReg.gpu2d_core_clk_podf = 0;
+  cbcmrReg.gpu3d_core_podf = 0;
+  cbcmrReg.gpu3d_shader_podf = 0;
+
+  ImxpClkPwrCacheReset ();
+  MmioWrite32 ((UINTN) &ccmRegisters->CBCMR, cbcmrReg.AsUint32);
+}
+
+/**
+    Configure all of DIx clock tree for both IPU1 and IPU2. For flexibility
+    purpose use PLL5 (PLL Video) as main reference clock. PLL 5 has flexible
+    divider making it easily configurable. Muxing and clock programming needs
+    when to be updated when supporting multiple display.
+**/
+VOID ImxCcmConfigureIPUDIxClockTree ()
+{
+    volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+    IMX_CCM_CHSCCDR_REG chscddrReg; chscddrReg.AsUint32 = MmioRead32((UINTN)&ccmRegisters->CHSCCDR);
+
+    // Setup muxing to pre-mux
+  if (FeaturePcdGet(PcdLvdsEnable)) {
+    chscddrReg.ipu1_di0_clk_sel     = IMX_CHSCCDR_IPU1_DI0_CLK_SEL_LDB_DI0_CLK;
+    chscddrReg.ipu1_di1_clk_sel     = IMX_CHSCCDR_IPU1_DI0_CLK_SEL_LDB_DI0_CLK;
+  } else {
+    chscddrReg.ipu1_di0_clk_sel     = IMX_CHSCCDR_IPU1_DI0_CLK_SEL_PREMUX;
+    chscddrReg.ipu1_di1_clk_sel     = IMX_CHSCCDR_IPU1_DI0_CLK_SEL_PREMUX;
+  }
+
+    chscddrReg.ipu1_di0_podf        = IMX_CHSCCDR_IPU1_DI0_PODF_DIV_1;
+    chscddrReg.ipu1_di1_podf        = IMX_CHSCCDR_IPU1_DI1_PODF_DIV_1;
+    chscddrReg.ipu1_di0_pre_clk_sel = IMX_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL5;
+    chscddrReg.ipu1_di1_pre_clk_sel = IMX_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL5;
+
+    MmioWrite32 ((UINTN)&ccmRegisters->CHSCCDR, chscddrReg.AsUint32);
+}
+
+/**
+    Configure both LDB0/1 to use PLL5 clock
+**/
+VOID ImxCcmConfigureIPULDBxClockTree ()
+{
+    volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+    IMX_CCM_CS2CDR_REG cs2cdrReg; cs2cdrReg.AsUint32 = MmioRead32((UINTN)&ccmRegisters->CS2CDR);
+
+    cs2cdrReg.ldb_di0_clk_sel = 0x0;
+    cs2cdrReg.ldb_di1_clk_sel = 0x0;
+
+    MmioWrite32 ((UINTN)&ccmRegisters->CS2CDR, cs2cdrReg.AsUint32);
+}
+
+/**
+    Configure PLL 5 clock rate to the desired clock rate
+**/
+VOID ImxSetClockRatePLL5 (
+    UINT32 ClockRate,
+    IMX_CCM_PLL_VIDEO_CTRL_POST_DIV_SELECT PostDivSelect
+    )
+{
+    // Use clock rate as denom for simple fractional calculation
+    UINT32 denom = IMX_REF_CLK_24M_FREQ;
+    UINT32 divSelect = ClockRate / IMX_REF_CLK_24M_FREQ; // Signed value
+    UINT32 numerator = ClockRate % IMX_REF_CLK_24M_FREQ;
+    volatile IMX_CCM_ANALOG_REGISTERS *ccmAnalogRegisters =
+        (IMX_CCM_ANALOG_REGISTERS *)IMX_CCM_ANALOG_BASE;
+    IMX_CCM_PLL_VIDEO_CTRL_REG pllVideoCtrlReg; pllVideoCtrlReg.AsUint32 =
+        MmioRead32 ((UINTN)&ccmAnalogRegisters->PLL_VIDEO);
+
+    ASSERT (numerator < denom);
+    ASSERT ((divSelect >= 27) && (divSelect <= 54));
+
+    // PLL output frequency = Fref * (DIV_SELECT + NUM / DENOM)
+    // Use the clock rate as denomitor to make fractional calulation simple
+    pllVideoCtrlReg.DIV_SELECT = divSelect;
+    pllVideoCtrlReg.POST_DIV_SELECT = PostDivSelect;
+
+    MmioWrite32(
+        (UINTN)&ccmAnalogRegisters->PLL_VIDEO, pllVideoCtrlReg.AsUint32);
+    MmioWrite32(
+        (UINTN)&ccmAnalogRegisters->PLL_VIDEO_NUM, numerator);
+    MmioWrite32(
+        (UINTN)&ccmAnalogRegisters->PLL_VIDEO_DENOM, denom);
+
+    pllVideoCtrlReg.AsUint32 = MmioRead32(
+        (UINTN)&ccmAnalogRegisters->PLL_VIDEO);
+
+    // Check to see if pll is locked, if not attempt to enable it
+    if (pllVideoCtrlReg.LOCK == 0) {
+        UINT32 counter = 10000;
+        {
+            IMX_CCM_PLL_VIDEO_CTRL_REG pllVideoCtrlClearReg = { 0 };
+            pllVideoCtrlClearReg.POWERDOWN = 1;
+            MmioWrite32(
+                (UINTN)&ccmAnalogRegisters->PLL_VIDEO_CLR,
+                pllVideoCtrlClearReg.AsUint32);
+        }
+        pllVideoCtrlReg.AsUint32 = MmioRead32(
+            (UINTN)&ccmAnalogRegisters->PLL_VIDEO);
+        {
+            IMX_CCM_PLL_VIDEO_CTRL_REG pllVideoCtrlSetReg = { 0 };
+            pllVideoCtrlSetReg.ENABLE = 1;
+            MmioWrite32(
+                (UINTN)&ccmAnalogRegisters->PLL_VIDEO_SET,
+                pllVideoCtrlSetReg.AsUint32);
+        }
+        pllVideoCtrlReg.AsUint32 = MmioRead32(
+            (UINTN)&ccmAnalogRegisters->PLL_VIDEO);
+        {
+            IMX_CCM_PLL_VIDEO_CTRL_REG pllVideoCtrlClearReg = { 0 };
+            pllVideoCtrlClearReg.BYPASS = 1;
+            MmioWrite32(
+                (UINTN)&ccmAnalogRegisters->PLL_VIDEO_CLR,
+                pllVideoCtrlClearReg.AsUint32);
+        }
+        pllVideoCtrlReg.AsUint32 = MmioRead32(
+            (UINTN)&ccmAnalogRegisters->PLL_VIDEO);
+        do {
+            pllVideoCtrlReg.AsUint32 = MmioRead32(
+                (UINTN)&ccmAnalogRegisters->PLL_VIDEO);
+            --counter;
+        } while ((pllVideoCtrlReg.LOCK == 0) && (counter > 0));
+        ASSERT (counter > 0);
+    }
+}
+
+EFI_STATUS
+ImxpGetPll2PfdClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  IMX_PLL_PFD PfdIndex,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_ANALOG_REGISTERS *ccmAnalogRegisters =
+      (IMX_CCM_ANALOG_REGISTERS *) IMX_CCM_ANALOG_BASE;
+
+  IMX_CCM_PFD_528_REG pfd528Reg; pfd528Reg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmAnalogRegisters->PFD_528);
+
+  UINT32 pfdFrac;
+  switch (PfdIndex) {
+  case IMX_PLL_PFD0:
+    pfdFrac = pfd528Reg.PFD0_FRAC;
+    break;
+  case IMX_PLL_PFD1:
+    pfdFrac = pfd528Reg.PFD1_FRAC;
+    break;
+  case IMX_PLL_PFD2:
+    pfdFrac = pfd528Reg.PFD2_FRAC;
+    break;
+  default:
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, IMX_PLL2_MAIN_CLK, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  // The resulting frequency shall be 528*18/PFDn_FRAC
+  // where PFD0_FRAC is in the range 12-35.
+  ASSERT ((pfdFrac >= 12) && (pfdFrac <= 35));
+  ClockInfo->Frequency = (UINT32) ((UINT64) parentInfo.Frequency * 18 / pfdFrac);
+  ClockInfo->Parent = IMX_PLL2_MAIN_CLK;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetAxiClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCDR_REG cbcdrReg; cbcdrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CBCDR);
+
+  IMX_CLK parent;
+  if (cbcdrReg.axi_sel == IMX_CCM_AXI_SEL_PERIPH_CLK) {
+    parent = IMX_PERIPH_CLK;
+  } else {
+    ASSERT (cbcdrReg.axi_sel == IMX_CCM_AXI_SEL_AXI_ALT);
+    parent = IMX_AXI_ALT;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency = parentInfo.Frequency / (1 + cbcdrReg.axi_podf);
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetGpu2dCoreClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCMR_REG cbcmrReg ; cbcmrReg.AsUint32 = MmioRead32 ((UINTN) &ccmRegisters->CBCMR);
+
+  IMX_CLK parent;
+  switch (cbcmrReg.gpu2d_core_clk_sel) {
+  case IMX_CCM_GPU2D_CORE_CLK_SEL_AXI:
+    parent = IMX_AXI_CLK_ROOT;
+    break;
+  case IMX_CCM_GPU2D_CORE_CLK_SEL_PLL3_SW:
+    parent = IMX_PLL3_SW_CLK;
+    break;
+  case IMX_CCM_GPU2D_CORE_CLK_SEL_PLL2_PFD0:
+    parent = IMX_PLL2_PFD0;
+    break;
+  case IMX_CCM_GPU2D_CORE_CLK_SEL_PLL2_PFD2:
+    parent = IMX_PLL2_PFD2;
+    break;
+  default:
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency =
+      parentInfo.Frequency / (1 + cbcmrReg.gpu2d_core_clk_podf);
+  ClockInfo->Parent = parent;
+
+  if (ClockInfo->Frequency > IMX_GPU2D_CORE_CLK_MAX) {
+    DEBUG ((
+      DEBUG_WARN,
+      "GPU2D_CORE_CLK exceeds maximum. (Value = %d, Max = %d)\r\n",
+      ClockInfo->Frequency,
+      IMX_GPU2D_CORE_CLK_MAX));
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetGpu3dCoreClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCMR_REG cbcmrReg ; cbcmrReg.AsUint32 = MmioRead32 ((UINTN) &ccmRegisters->CBCMR);
+
+  IMX_CLK parent;
+  switch (cbcmrReg.gpu3d_core_clk_sel) {
+  case IMX_CCM_GPU3D_CORE_CLK_SEL_MMDC_CH0_AXI:
+    parent = IMX_MMDC_CH0_CLK_ROOT;
+    break;
+  case IMX_CCM_GPU3D_CORE_CLK_SEL_PLL3_SW:
+    parent = IMX_PLL3_SW_CLK;
+    break;
+  case IMX_CCM_GPU3D_CORE_CLK_SEL_PLL2_PFD1:
+    parent = IMX_PLL2_PFD1;
+    break;
+  case IMX_CCM_GPU3D_CORE_CLK_SEL_PLL2_PFD2:
+    parent = IMX_PLL2_PFD2;
+    break;
+  default:
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency = parentInfo.Frequency / (1 + cbcmrReg.gpu3d_core_podf);
+  ClockInfo->Parent = parent;
+
+  if (ClockInfo->Frequency > IMX_GPU3D_CORE_CLK_MAX) {
+    DEBUG ((
+      DEBUG_WARN,
+      "GPU3D_CORE_CLK exceeds maximum. (Value = %d, Max = %d)\r\n",
+      ClockInfo->Frequency,
+      IMX_GPU3D_CORE_CLK_MAX));
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetGpu3dShaderClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCMR_REG cbcmrReg ; cbcmrReg.AsUint32 = MmioRead32 ((UINTN) &ccmRegisters->CBCMR);
+
+  IMX_CLK parent;
+  switch (cbcmrReg.gpu3d_shader_clk_sel) {
+  case IMX_CCM_GPU3D_SHADER_CLK_SEL_MMDC_CH0_AXI:
+    parent = IMX_MMDC_CH0_CLK_ROOT;
+    break;
+  case IMX_CCM_GPU3D_SHADER_CLK_SEL_PLL3_SW:
+    parent = IMX_PLL3_SW_CLK;
+    break;
+  case IMX_CCM_GPU3D_SHADER_CLK_SEL_PLL2_PFD1:
+    parent = IMX_PLL2_PFD1;
+    break;
+  case IMX_CCM_GPU3D_SHADER_CLK_SEL_PLL3_PFD0:
+    parent = IMX_PLL3_PFD0;
+    break;
+  default:
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency =
+      parentInfo.Frequency / (1 + cbcmrReg.gpu3d_shader_podf);
+
+  ClockInfo->Parent = parent;
+
+  if (ClockInfo->Frequency > IMX_GPU3D_SHADER_CLK_MAX) {
+    DEBUG ((
+      DEBUG_WARN,
+      "GPU3D_SHADER_CLK exceeds maximum. (Value = %d, Max = %d)",
+      ClockInfo->Frequency,
+      IMX_GPU3D_SHADER_CLK_MAX));
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetPeriphClk2Info (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCMR_REG cbcmrReg; cbcmrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CBCMR);
+
+  IMX_CLK parent;
+  switch (cbcmrReg.periph_clk2_sel) {
+  case IMX_CCM_PERIPH_CLK2_SEL_PLL3_SW_CLK:
+    parent = IMX_PLL3_SW_CLK;
+    break;
+  case IMX_CCM_PERIPH_CLK2_SEL_OSC_CLK:
+    parent = IMX_OSC_CLK;
+    break;
+  case IMX_CCM_PERIPH_CLK2_SEL_PLL2:
+    parent = IMX_PLL2_MAIN_CLK;
+    break;
+  default:
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  IMX_CCM_CBCDR_REG cbcdrReg; cbcdrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CBCDR);
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency = parentInfo.Frequency / (1 + cbcdrReg.periph_clk2_podf);
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetPeriphClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCDR_REG cbcdrReg; cbcdrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CBCDR);
+
+  IMX_CLK parent;
+
+  // NOTE: periph_clk_sel is OR'd with PLL_bypass_en2 (from jtag) to
+  //       produce the input value to the MUX. We assume PLL_bypass_en2 is 0.
+  if (cbcdrReg.periph_clk_sel == 0) {
+    parent = IMX_PRE_PERIPH_CLK;
+  } else {
+    ASSERT (cbcdrReg.periph_clk_sel == 1);
+    parent = IMX_PERIPH_CLK2;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency = parentInfo.Frequency / (1 + cbcdrReg.mmdc_ch0_axi_podf);
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetMmdcCh0ClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, IMX_PERIPH_CLK, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  IMX_CCM_CBCDR_REG cbcdrReg; cbcdrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CBCDR);
+
+  ClockInfo->Frequency =
+      parentInfo.Frequency / (1 + cbcdrReg.mmdc_ch0_axi_podf);
+  ClockInfo->Parent = IMX_PERIPH_CLK;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetGpu2dAxiClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCMR_REG cbcmrReg ; cbcmrReg.AsUint32 = MmioRead32 ((UINTN) &ccmRegisters->CBCMR);
+
+  IMX_CLK parent;
+  if (cbcmrReg.gpu2d_axi_clk_sel == IMX_CCM_GPU2D_AXI_CLK_SEL_AXI) {
+    parent = IMX_AXI_CLK_ROOT;
+  } else {
+    ASSERT (cbcmrReg.gpu2d_axi_clk_sel == IMX_CCM_GPU2D_AXI_CLK_SEL_AHB);
+    parent = IMX_AHB_CLK_ROOT;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency = parentInfo.Frequency;
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetGpu3dAxiClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCMR_REG cbcmrReg ; cbcmrReg.AsUint32 = MmioRead32 ((UINTN) &ccmRegisters->CBCMR);
+
+  IMX_CLK parent;
+  if (cbcmrReg.gpu3d_axi_clk_sel == IMX_CCM_GPU3D_AXI_CLK_SEL_AXI) {
+    parent = IMX_AXI_CLK_ROOT;
+  } else {
+    ASSERT (cbcmrReg.gpu3d_axi_clk_sel == IMX_CCM_GPU3D_AXI_CLK_SEL_AHB);
+    parent = IMX_AHB_CLK_ROOT;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency = parentInfo.Frequency;
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+VOID ImxEnableGpuVpuPowerDomain ()
+{
+  volatile IMX_CCM_ANALOG_REGISTERS *analogRegisters =
+    (IMX_CCM_ANALOG_REGISTERS *) IMX_CCM_ANALOG_BASE;
+
+  volatile IMX_GPC_REGISTERS *gpcRegisters = (IMX_GPC_REGISTERS *) IMX_GPC_BASE;
+  volatile IMX_GPC_PGC_REGISTERS *gpuPgcRegisters = &gpcRegisters->PGC_GPU;
+
+  // Configure GPC/PGC PUPSCR Register SW2ISO bits
+  {
+      IMX_GPC_PGC_PUPSCR_REG pupscrReg; pupscrReg.AsUint32 =
+        MmioRead32 ((UINTN) &gpuPgcRegisters->PUPSCR);
+
+    pupscrReg.SW = IMX_GPC_PGC_PUPSCR_SW_DEFAULT;
+    pupscrReg.SW2ISO = IMX_GPC_PGC_PUPSCR_SW2ISO_DEFAULT;
+
+    MmioWrite32 ((UINTN) &gpuPgcRegisters->PUPSCR, pupscrReg.AsUint32);
+  }
+
+  // Turn on LDO_PU to 1.250V
+  {
+    IMX_PMU_REG_CORE_REG pmuCoreReg = {0};
+    pmuCoreReg.REG1_TARG = 0x1f;
+
+    MmioWrite32 ((UINTN) &analogRegisters->PMU_REG_CORE_CLR, pmuCoreReg.AsUint32);
+
+    pmuCoreReg.REG1_TARG = 22;
+    MmioWrite32 ((UINTN) &analogRegisters->PMU_REG_CORE_SET, pmuCoreReg.AsUint32);
+
+    MicroSecondDelay (100);
+  }
+
+  // Assert power up request
+  IMX_GPC_CNTR_REG gpcCntrReg; gpcCntrReg.AsUint32 =
+      MmioRead32 ((UINTN) &gpcRegisters->CNTR);
+
+  gpcCntrReg.gpu_vpu_pdn_req = 0;
+  gpcCntrReg.gpu_vpu_pup_req = 1;
+
+  MmioWrite32 ((UINTN) &gpcRegisters->CNTR, gpcCntrReg.AsUint32);
+
+  // Wait for power up request to complete
+  do {
+    gpcCntrReg.AsUint32 = MmioRead32 ((UINTN) &gpcRegisters->CNTR);
+  } while (gpcCntrReg.gpu_vpu_pup_req != 0);
+}
+
+VOID ImxDisableGpuVpuPowerDomain ()
+{
+  volatile IMX_GPC_REGISTERS *gpcRegisters = (IMX_GPC_REGISTERS *) IMX_GPC_BASE;
+  volatile IMX_GPC_PGC_REGISTERS *gpuPgcRegisters = &gpcRegisters->PGC_GPU;
+
+  // Configure GPC/PGC PDNSCR Register ISO bits
+  {
+      IMX_GPC_PGC_PDNSCR_REG pdnscrReg; pdnscrReg.AsUint32 =
+        MmioRead32 ((UINTN) &gpuPgcRegisters->PDNSCR);
+
+    pdnscrReg.ISO = IMX_GPC_PGC_PDNSCR_ISO_DEFAULT;
+    pdnscrReg.ISO2SW = IMX_GPC_PGC_PDNSCR_ISO2SW_DEFAULT;
+
+    MmioWrite32 ((UINTN) &gpuPgcRegisters->PDNSCR, pdnscrReg.AsUint32);
+  }
+
+  // Configure GPC/PGC CTRL[PCR] bit to allow power down of the blocks
+  {
+      IMX_GPC_PGC_PGCR_REG ctrlReg; ctrlReg.AsUint32 =
+        MmioRead32 ((UINTN) &gpuPgcRegisters->CTRL);
+
+    ctrlReg.PCR = 1;    // enable powering down of the blocks
+
+    MmioWrite32 ((UINTN) &gpuPgcRegisters->CTRL, ctrlReg.AsUint32);
+  }
+
+  // Assert power down request
+  {
+      IMX_GPC_CNTR_REG gpcCntrReg; gpcCntrReg.AsUint32 =
+        MmioRead32 ((UINTN) &gpcRegisters->CNTR);
+
+    gpcCntrReg.gpu_vpu_pdn_req = 1;
+    gpcCntrReg.gpu_vpu_pup_req = 0;
+
+    MmioWrite32 ((UINTN) &gpcRegisters->CNTR, gpcCntrReg.AsUint32);
+
+    // Wait for power down request to complete
+    do {
+      gpcCntrReg.AsUint32 = MmioRead32 ((UINTN) &gpcRegisters->CNTR);
+    } while (gpcCntrReg.gpu_vpu_pdn_req != 0);
+  }
+}
+
+EFI_STATUS
+ImxpGetClockInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  IN IMX_CLK ClockId,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  ASSERT (ClockId < ARRAYSIZE(Cache->Table));
+
+  // First try to satisfy from cache
+  {
+    UINTN cacheValidBits = Cache->Valid[ClockId / _BITS_PER_UINTN];
+    if (cacheValidBits & (1 << (ClockId % _BITS_PER_UINTN))) {
+      *ClockInfo = Cache->Table[ClockId];
+      return EFI_SUCCESS;
+    }
+  }
+
+  EFI_STATUS status;
+  switch (ClockId) {
+  case IMX_OSC_CLK:
+    ImxpGetOsc24ClkInfo (ClockInfo);
+    status = EFI_SUCCESS;
+    break;
+  case IMX_PLL1_MAIN_CLK:
+    status = ImxpGetPll1MainClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_PLL2_MAIN_CLK:
+    status = ImxpGetPll2MainClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_PLL2_PFD0:
+    status = ImxpGetPll2PfdClkInfo (Cache, IMX_PLL_PFD0, ClockInfo);
+    break;
+  case IMX_PLL2_PFD1:
+    status = ImxpGetPll2PfdClkInfo (Cache, IMX_PLL_PFD1, ClockInfo);
+    break;
+  case IMX_PLL2_PFD2:
+    status = ImxpGetPll2PfdClkInfo (Cache, IMX_PLL_PFD2, ClockInfo);
+    break;
+  case IMX_PLL3_MAIN_CLK:
+    status = ImxpGetPll3MainClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_PLL3_PFD0:
+    status = ImxpGetPll3PfdClkInfo (Cache, IMX_PLL_PFD0, ClockInfo);
+    break;
+  case IMX_PLL3_PFD1:
+    status = ImxpGetPll3PfdClkInfo (Cache, IMX_PLL_PFD1, ClockInfo);
+    break;
+  case IMX_PLL3_PFD2:
+    status = ImxpGetPll3PfdClkInfo (Cache, IMX_PLL_PFD2, ClockInfo);
+    break;
+  case IMX_PLL3_PFD3:
+    status = ImxpGetPll3PfdClkInfo (Cache, IMX_PLL_PFD3, ClockInfo);
+    break;
+  case IMX_PLL3_SW_CLK:
+    status = ImxpGetPll3SwClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_AXI_CLK_ROOT:
+    status = ImxpGetAxiClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_PERIPH_CLK2:
+    status = ImxpGetPeriphClk2Info (Cache, ClockInfo);
+    break;
+  case IMX_PERIPH_CLK:
+    status = ImxpGetPeriphClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_PRE_PERIPH_CLK:
+    status = ImxpGetPrePeriphClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_ARM_CLK_ROOT:
+    status = ImxpGetArmClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_MMDC_CH0_CLK_ROOT:
+    status = ImxpGetMmdcCh0ClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_AHB_CLK_ROOT:
+    status = ImxpGetAhbClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_IPG_CLK_ROOT:
+    status = ImxpGetIpgClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_GPU2D_AXI_CLK_ROOT:
+    status = ImxpGetGpu2dAxiClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_GPU3D_AXI_CLK_ROOT:
+    status = ImxpGetGpu3dAxiClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_GPU2D_CORE_CLK_ROOT:
+    status = ImxpGetGpu2dCoreClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_GPU3D_CORE_CLK_ROOT:
+    status = ImxpGetGpu3dCoreClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_GPU3D_SHADER_CLK_ROOT:
+    status = ImxpGetGpu3dShaderClkInfo (Cache, ClockInfo);
+    break;
+  default:
+    return EFI_UNSUPPORTED;
+  }
+
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  // Update the cache
+  Cache->Table[ClockId] = *ClockInfo;
+  Cache->Valid[ClockId / _BITS_PER_UINTN] |= (1 << (ClockId % _BITS_PER_UINTN));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Power on and clock the GPU2D/GPU3D blocks.
+
+  Follow the datasheet recommended sequence for clocking and powering:
+    Gate clocks -> unpower module ->
+    configure muxes/dividers -> power module -> Ungate clocks
+**/
+EFI_STATUS ImxClkPwrGpuEnable ()
+{
+#if !defined(MDEPKG_NDEBUG)
+
+  //
+  // Precondition: clock and power should be disabled
+  //
+  {
+    ASSERT (ImxClkPwrGetClockGate (IMX_GPU3D_CLK_ENABLE) == IMX_CLOCK_GATE_STATE_OFF);
+    ASSERT (ImxClkPwrGetClockGate (IMX_GPU2D_CLK_ENABLE) == IMX_CLOCK_GATE_STATE_OFF);
+    ASSERT (ImxClkPwrGetClockGate (IMX_OPENVGAXICLK_CLK_ROOT_ENABLE) == IMX_CLOCK_GATE_STATE_OFF);
+  }
+
+#endif
+
+  // Ensure clocks are gated
+  ImxClkPwrSetClockGate (IMX_GPU3D_CLK_ENABLE, IMX_CLOCK_GATE_STATE_OFF);
+  ImxClkPwrSetClockGate (IMX_GPU2D_CLK_ENABLE, IMX_CLOCK_GATE_STATE_OFF);
+  ImxClkPwrSetClockGate (IMX_OPENVGAXICLK_CLK_ROOT_ENABLE, IMX_CLOCK_GATE_STATE_OFF);
+
+  // Ensure GPU powered down (GPU should be powered down anyway)
+  ImxDisableGpuVpuPowerDomain ();
+
+  // Configure clock muxes and dividers for GPU3D, GPU2D, and OpenVG
+  ImxCcmConfigureGpuClockTree ();
+
+  // Power on the GPU
+  ImxEnableGpuVpuPowerDomain ();
+
+  // Ungate the GPU clocks
+  ImxClkPwrSetClockGate (IMX_GPU3D_CLK_ENABLE, IMX_CLOCK_GATE_STATE_ON);
+  ImxClkPwrSetClockGate (IMX_GPU2D_CLK_ENABLE, IMX_CLOCK_GATE_STATE_ON);
+  ImxClkPwrSetClockGate (IMX_OPENVGAXICLK_CLK_ROOT_ENABLE, IMX_CLOCK_GATE_STATE_ON);
+
+  return EFI_SUCCESS;
+}
+
+/**
+    Setup the clock tree for Display Interface (DI)
+        Gate clocks -> Configure mux/div -> Ungate clocks -> Setup PLL
+**/
+EFI_STATUS ImxClkPwrIpuDIxEnable ()
+{
+    ImxClkPwrSetClockGate(IMX_IPU1_DI0_CLK_ENABLE, IMX_CCM_CCGR_OFF);
+    ImxClkPwrSetClockGate(IMX_IPU2_DI0_CLK_ENABLE, IMX_CCM_CCGR_OFF);
+    ImxClkPwrSetClockGate(IMX_IPU1_DI1_CLK_ENABLE, IMX_CCM_CCGR_OFF);
+    ImxClkPwrSetClockGate(IMX_IPU2_DI1_CLK_ENABLE, IMX_CCM_CCGR_OFF);
+
+    ImxCcmConfigureIPUDIxClockTree();
+
+    ImxClkPwrSetClockGate(IMX_IPU1_DI0_CLK_ENABLE, IMX_CCM_CCGR_ON);
+
+    // Setup PLL to 65MHz as expected from UBOOT although transition
+    // might be so fast that UBOOT screen would not be displayed
+    ImxSetPll5ReferenceRate(65000000);
+
+    return EFI_SUCCESS;
+}
+
+/**
+    Setup the clock tree for LDB0/1
+**/
+EFI_STATUS ImxClkPwrIpuLDBxEnable ()
+{
+    ImxClkPwrSetClockGate(IMX_LDB_DI0_CLK_ENABLE, IMX_CCM_CCGR_OFF);
+    ImxClkPwrSetClockGate(IMX_LDB_DI1_CLK_ENABLE, IMX_CCM_CCGR_OFF);
+
+    ImxCcmConfigureIPULDBxClockTree();
+
+    ImxClkPwrSetClockGate(IMX_LDB_DI0_CLK_ENABLE, IMX_CCM_CCGR_ON);
+    ImxClkPwrSetClockGate(IMX_LDB_DI1_CLK_ENABLE, IMX_CCM_CCGR_ON);
+
+    return EFI_SUCCESS;
+}
+
+/**
+    Configure PLL5 to the desired clock rate for all Display Interface (DI).
+    Currently only support one display to IPU1 DI0.
+**/
+EFI_STATUS ImxSetPll5ReferenceRate (
+    UINT32 ClockRate
+    )
+{
+    BOOLEAN foundConfig = FALSE;
+    UINT32 dxPodfDivider;
+    UINT32 targetFreq;
+    UINT32 postDivSelectCount;
+    UINT32 postDivSelectValue[3] = { 1, 2, 4 };
+    IMX_CCM_PLL_VIDEO_CTRL_POST_DIV_SELECT postDivSelect[3] = {
+        IMX_POST_DIV_SELECT_DIVIDE_1,
+        IMX_POST_DIV_SELECT_DIVIDE_2,
+        IMX_POST_DIV_SELECT_DIVIDE_4};
+
+    for (postDivSelectCount = 0;
+        postDivSelectCount < ARRAYSIZE (postDivSelectValue);
+        ++postDivSelectCount) {
+
+        for (dxPodfDivider = 1; dxPodfDivider < 9; ++dxPodfDivider) {
+
+            targetFreq =
+                dxPodfDivider *
+                ClockRate *
+                postDivSelectValue[postDivSelectCount];
+
+            // The valid range for PPL loop divider is 27-54 so we
+            // need to target freq need to fit within the valid range.
+            if ((targetFreq >= PLL5_MIN_FREQ) &&
+                (targetFreq <= PLL5_MAX_FREQ)) {
+                foundConfig = TRUE;
+                break;
+            }
+        }
+
+        if (foundConfig == TRUE) {
+            break;
+        }
+    }
+
+    if (foundConfig == FALSE) {
+        DEBUG((DEBUG_ERROR, "ClockRate %d\n", ClockRate));
+        ASSERT(FALSE);
+        return EFI_INVALID_PARAMETER;
+    }
+
+    DEBUG ((
+        DEBUG_INFO,
+        "PLL 5 setting (%d) Target Freq %d Divider %d PostDiv %d\n",
+        ClockRate,
+        targetFreq,
+        dxPodfDivider,
+        postDivSelectValue[postDivSelectCount]
+        ));
+
+    {
+        volatile IMX_CCM_REGISTERS *ccmRegisters =
+            (IMX_CCM_REGISTERS *)IMX_CCM_BASE;
+        IMX_CCM_CHSCCDR_REG chscddrReg; chscddrReg.AsUint32 =
+             MmioRead32 ((UINTN)&ccmRegisters->CHSCCDR) ;
+
+        ImxClkPwrSetClockGate(IMX_IPU1_DI0_CLK_ENABLE, IMX_CCM_CCGR_OFF);
+        ImxClkPwrSetClockGate(IMX_IPU2_DI0_CLK_ENABLE, IMX_CCM_CCGR_OFF);
+        ImxClkPwrSetClockGate(IMX_IPU1_DI1_CLK_ENABLE, IMX_CCM_CCGR_OFF);
+        ImxClkPwrSetClockGate(IMX_IPU2_DI1_CLK_ENABLE, IMX_CCM_CCGR_OFF);
+
+        chscddrReg.ipu1_di0_podf = dxPodfDivider - 1;
+        chscddrReg.ipu1_di1_podf = dxPodfDivider - 1;
+
+        MmioWrite32 ((UINTN)&ccmRegisters->CHSCCDR, chscddrReg.AsUint32);
+
+        ImxClkPwrSetClockGate(IMX_IPU1_DI0_CLK_ENABLE, IMX_CCM_CCGR_ON);
+    }
+
+    ImxSetClockRatePLL5(targetFreq, postDivSelect[postDivSelectCount]);
+
+    return EFI_SUCCESS;
+}
+
+EFI_STATUS ImxClkPwrClkOut1Enable (IMX_CLK Clock, UINT32 Divider)
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  if ((Divider < 1) || (Divider > 8)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  IMX_CCM_CCOSR_REG ccosrReg; ccosrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CCOSR);
+
+  switch (Clock) {
+  case IMX_OSC_CLK:
+    ccosrReg.CLKO2_SEL = IMX_CCM_CLKO2_SEL_OSC_CLK;
+    ccosrReg.CLKO2_DIV = Divider - 1;
+    ccosrReg.CLKO2_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO2;
+    break;
+
+  case IMX_PLL2_MAIN_CLK:
+    ccosrReg.CLKO1_SEL = IMX_CCM_CLKO1_SEL_PLL2_MAIN_CLK_2;
+    ccosrReg.CLKO1_DIV = Divider - 1;
+    ccosrReg.CLKO1_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO1;
+    break;
+
+  case IMX_AXI_CLK_ROOT:
+    ccosrReg.CLKO1_SEL = IMX_CCM_CLKO1_SEL_AXI_CLK_ROOT;
+    ccosrReg.CLKO1_DIV = Divider - 1;
+    ccosrReg.CLKO1_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO1;
+    break;
+
+  case IMX_IPG_CLK_ROOT:
+    ccosrReg.CLKO1_SEL = IMX_CCM_CLKO1_SEL_IPG_CLK_ROOT;
+    ccosrReg.CLKO1_DIV = Divider - 1;
+    ccosrReg.CLKO1_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO1;
+    break;
+
+  case IMX_GPU2D_AXI_CLK_ROOT:
+    ccosrReg.CLKO2_SEL = IMX_CCM_CLKO2_SEL_GPU2D_AXI_CLK_ROOT;
+    ccosrReg.CLKO2_DIV = Divider - 1;
+    ccosrReg.CLKO2_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO2;
+    break;
+
+  case IMX_GPU3D_AXI_CLK_ROOT:
+    ccosrReg.CLKO2_SEL = IMX_CCM_CLKO2_SEL_GPU3D_AXI_CLK_ROOT;
+    ccosrReg.CLKO2_DIV = Divider - 1;
+    ccosrReg.CLKO2_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO2;
+    break;
+
+  case IMX_GPU2D_CORE_CLK_ROOT:
+    ccosrReg.CLKO2_SEL = IMX_CCM_CLKO2_SEL_GPU2D_CORE_CLK_ROOT;
+    ccosrReg.CLKO2_DIV = Divider - 1;
+    ccosrReg.CLKO2_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO2;
+    break;
+
+  case IMX_GPU3D_CORE_CLK_ROOT:
+    ccosrReg.CLKO2_SEL = IMX_CCM_CLKO2_SEL_GPU3D_CORE_CLK_ROOT;
+    ccosrReg.CLKO2_DIV = Divider - 1;
+    ccosrReg.CLKO2_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO2;
+    break;
+
+  case IMX_GPU3D_SHADER_CLK_ROOT:
+    ccosrReg.CLKO2_SEL = IMX_CCM_CLKO2_SEL_GPU3D_SHADER_CLK_ROOT;
+    ccosrReg.CLKO2_DIV = Divider - 1;
+    ccosrReg.CLKO2_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO2;
+    break;
+
+  case IMX_UART_CLK_ROOT:
+    ccosrReg.CLKO2_SEL = IMX_CCM_CLKO2_SEL_UART_CLK_ROOT;
+    ccosrReg.CLKO2_DIV = Divider - 1;
+    ccosrReg.CLKO2_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO2;
+    break;
+
+  default:
+    return EFI_UNSUPPORTED;
+  }
+
+  MmioWrite32 ((UINTN) &ccmRegisters->CCOSR, ccosrReg.AsUint32);
+
+  return EFI_SUCCESS;
+}
+
+VOID ImxClkPwrClkOut1Disable ()
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CCOSR_REG ccosrReg; ccosrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CCOSR);
+
+  ccosrReg.CLKO1_EN = 0;
+  ccosrReg.CLKO2_EN = 0;
+
+  MmioWrite32 ((UINTN) &ccmRegisters->CCOSR, ccosrReg.AsUint32);
+}
+
+EFI_STATUS ImxClkPwrValidateClocks ()
+{
+  struct {
+    IMX_CLK Clock;
+    IMX_CLOCK_INFO Info;
+  } expectedClocks[] = {
+    // Clock, Frequency, Parent
+    {IMX_OSC_CLK, {24000000, IMX_CLK_NONE}},
+    {IMX_PLL1_MAIN_CLK, {792000000, IMX_OSC_CLK}},
+    {IMX_PLL2_MAIN_CLK, {528000000, IMX_OSC_CLK}},
+    {IMX_PLL2_PFD0, {352000000, IMX_PLL2_MAIN_CLK}},
+    {IMX_PLL2_PFD1,{594000000, IMX_PLL2_MAIN_CLK}},
+    {IMX_PLL2_PFD2, {396000000, IMX_PLL2_MAIN_CLK}},
+    {IMX_PLL3_MAIN_CLK, {480000000, IMX_OSC_CLK}},
+    {IMX_PLL3_PFD0, {720000000, IMX_PLL3_MAIN_CLK}},
+    {IMX_PLL3_PFD1, {540000000, IMX_PLL3_MAIN_CLK}},
+    {IMX_PLL3_PFD2, {508235294, IMX_PLL3_MAIN_CLK}},
+    {IMX_PLL3_PFD3, {454736842, IMX_PLL3_MAIN_CLK}},
+    {IMX_AXI_CLK_ROOT, {264000000, IMX_PERIPH_CLK}},
+    {IMX_MMDC_CH0_CLK_ROOT, {528000000, IMX_PERIPH_CLK}},
+  };
+
+  BOOLEAN invalid = FALSE;
+
+  int i;
+  for (i = 0; i < ARRAYSIZE (expectedClocks); ++i) {
+    DEBUG ((
+      DEBUG_INFO,
+      "Validating clock %s. Expecting: Frequency = %d (%d Mhz), Parent = %s\r\n",
+      StringFromImxClk (expectedClocks[i].Clock),
+      expectedClocks[i].Info.Frequency,
+      expectedClocks[i].Info.Frequency / 1000000,
+      StringFromImxClk (expectedClocks[i].Info.Parent)
+      ));
+
+    IMX_CLOCK_INFO actualInfo;
+    EFI_STATUS status = ImxClkPwrGetClockInfo (
+        expectedClocks[i].Clock,
+        &actualInfo);
+
+    if (EFI_ERROR (status)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "Failed to get clock info. (Clock = %s, status = 0x%x)\r\n",
+        StringFromImxClk (expectedClocks[i].Clock),
+        status
+        ));
+
+      return status;
+    }
+
+    if ((actualInfo.Frequency != expectedClocks[i].Info.Frequency) ||
+        (actualInfo.Parent != expectedClocks[i].Info.Parent)) {
+
+        DEBUG ((
+          DEBUG_ERROR,
+          "Clock settings do not match expected! Clock = %s (Expected, Actual) "
+          "Frequency: %d, %d. Parent: %s, %s\r\n",
+          StringFromImxClk (expectedClocks[i].Clock),
+          expectedClocks[i].Info.Frequency,
+          actualInfo.Frequency,
+          StringFromImxClk (expectedClocks[i].Info.Parent),
+          StringFromImxClk (actualInfo.Parent)
+          ));
+
+        invalid = TRUE;
+    }
+  }
+
+  return invalid ? EFI_DEVICE_ERROR : EFI_SUCCESS;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6SDLClkPwr.inc b/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6SDLClkPwr.inc
new file mode 100644
index 000000000000..0d8df235e89e
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6SDLClkPwr.inc
@@ -0,0 +1,1231 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef CPU_IMX6SDL
+#error iMX6SDLClkPwr.inc should not be compiled for non iMX6 SDL platform.
+#endif
+
+/**
+  Get the CCGR register index and gate number for a clock gate.
+**/
+
+IMX_CCGR_INDEX ImxpCcgrIndexFromClkGate (IMX_CLK_GATE ClockGate)
+{
+  static const IMX_CCGR_INDEX ImxpCcgrIndexMap[] = {
+    {0, 0},  // MX6_AIPS_TZ1_CLK_ENABLE
+    {0, 1},  // MX6_AIPS_TZ2_CLK_ENABLE
+    {0, 2},  // MX6_APBHDMA_HCLK_ENABLE
+    {0, 3},  // MX6_ASRC_CLK_ENABLE
+    {0, 4},  // MX6_CAAM_SECURE_MEM_CLK_ENABLE
+    {0, 5},  // MX6_CAAM_WRAPPER_ACLK_ENABLE
+    {0, 6},  // MX6_CAAM_WRAPPER_IPG_ENABLE
+    {0, 7},  // MX6_CAN1_CLK_ENABLE
+    {0, 8},  // MX6_CAN1_SERIAL_CLK_ENABLE
+    {0, 9},  // MX6_CAN2_CLK_ENABLE
+    {0, 10}, // MX6_CAN2_SERIAL_CLK_ENABLE
+    {0, 11}, // MX6_ARM_DBG_CLK_ENABLE
+    {0, 12}, // MX6_DCIC1_CLK_ENABLE
+    {0, 13}, // MX6_DCIC2_CLK_ENABLE
+    {0, 14}, // MX6_DTCP_CLK_ENABLE
+    {1, 0},  // MX6_ECSPI1_CLK_ENABLE
+    {1, 1},  // MX6_ECSPI2_CLK_ENABLE
+    {1, 2},  // MX6_ECSPI3_CLK_ENABLE
+    {1, 3},  // MX6_ECSPI4_CLK_ENABLE
+    {1, 4},  // MX6_ECSPI5_CLK_ENABLE
+    {1, 5},  // MX6_ENET_CLK_ENABLE
+    {1, 6},  // MX6_EPIT1_CLK_ENABLE
+    {1, 7},  // MX6_EPIT2_CLK_ENABLE
+    {1, 8},  // MX6_ESAI_CLK_ENABLE
+    {1, 10}, // MX6_GPT_CLK_ENABLE
+    {1, 11}, // MX6_GPT_SERIAL_CLK_ENABLE
+    {1, 12}, // MX6_GPU2D_CLK_ENABLE
+    {1, 13}, // MX6_GPU3D_CLK_ENABLE
+    {2, 0},  // MX6_HDMI_TX_ENABLE
+    {2, 2},  // MX6_HDMI_TX_ISFRCLK_ENABLE
+    {2, 3},  // MX6_I2C1_SERIAL_CLK_ENABLE
+    {2, 4},  // MX6_I2C2_SERIAL_CLK_ENABLE
+    {2, 5},  // MX6_I2C3_SERIAL_CLK_ENABLE
+    {2, 6},  // MX6_IIM_CLK_ENABLE
+    {2, 7},  // MX6_IOMUX_IPT_CLK_IO_ENABLE
+    {2, 8},  // MX6_IPMUX1_CLK_ENABLE
+    {2, 9},  // MX6_IPMUX2_CLK_ENABLE
+    {2, 10}, // MX6_IPMUX3_CLK_ENABLE
+    {2, 11}, // MX6_IPSYNC_IP2APB_TZASC1_IPG_MASTER_CLK_ENABLE
+    {2, 12}, // MX6_IPSYNC_IP2APB_TZASC2_IPG_MASTER_CLK_ENABLE
+    {2, 13}, // MX6_IPSYNC_VDOA_IPG_MASTER_CLK_ENABLE
+    {3, 0},  // MX6_IPU1_IPU_CLK_ENABLE
+    {3, 1},  // MX6_IPU1_IPU_DI0_CLK_ENABLE
+    {3, 2},  // MX6_IPU1_IPU_DI1_CLK_ENABLE
+    {3, 3},  // MX6_IPU2_IPU_CLK_ENABLE
+    {3, 4},  // MX6_IPU2_IPU_DI0_CLK_ENABLE
+    {3, 5},  // MX6_IPU2_IPU_DI1_CLK_ENABLE
+    {3, 6},  // MX6_LDB_DI0_CLK_ENABLE
+    {3, 7},  // MX6_LDB_DI1_CLK_ENABLE
+    {3, 8},  // MX6_MIPI_CORE_CFG_CLK_ENABLE
+    {3, 9},  // MX6_MLB_CLK_ENABLE
+    {3, 10}, // MX6_MMDC_CORE_ACLK_FAST_CORE_P0_ENABLE
+    {3, 12}, // MX6_MMDC_CORE_IPG_CLK_P0_ENABLE
+    {3, 14}, // MX6_OCRAM_CLK_ENABLE
+    {3, 15}, // MX6_OPENVGAXICLK_CLK_ROOT_ENABLE
+    {4, 0},  // MX6_PCIE_ROOT_ENABLE
+    {4, 4},  // MX6_PL301_MX6QFAST1_S133CLK_ENABLE
+    {4, 6},  // MX6_PL301_MX6QPER1_BCHCLK_ENABLE
+    {4, 7},  // MX6_PL301_MX6QPER2_MAINCLK_ENABLE
+    {4, 8},  // MX6_PWM1_CLK_ENABLE
+    {4, 9},  // MX6_PWM2_CLK_ENABLE
+    {4, 10}, // MX6_PWM3_CLK_ENABLE
+    {4, 11}, // MX6_PWM4_CLK_ENABLE
+    {4, 12}, // MX6_RAWNAND_U_BCH_INPUT_APB_CLK_ENABLE
+    {4, 13}, // MX6_RAWNAND_U_GPMI_BCH_INPUT_BCH_CLK_ENABLE
+    {4, 14}, // MX6_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_CLK_ENABLE
+    {4, 15}, // MX6_RAWNAND_U_GPMI_INPUT_APB_CLK_ENABLE
+    {5, 0},  // MX6_ROM_CLK_ENABLE
+    {5, 2},  // MX6_SATA_CLK_ENABLE
+    {5, 3},  // MX6_SDMA_CLK_ENABLE
+    {5, 6},  // MX6_SPBA_CLK_ENABLE
+    {5, 7},  // MX6_SPDIF_CLK_ENABLE
+    {5, 9},  // MX6_SSI1_CLK_ENABLE
+    {5, 10}, // MX6_SSI2_CLK_ENABLE
+    {5, 11}, // MX6_SSI3_CLK_ENABLE
+    {5, 12}, // MX6_UART_CLK_ENABLE
+    {5, 13}, // MX6_UART_SERIAL_CLK_ENABLE
+    {6, 0},  // MX6_USBOH3_CLK_ENABLE
+    {6, 1},  // MX6_USDHC1_CLK_ENABLE
+    {6, 2},  // MX6_USDHC2_CLK_ENABLE
+    {6, 3},  // MX6_USDHC3_CLK_ENABLE
+    {6, 4},  // MX6_USDHC4_CLK_ENABLE
+    {6, 5},  // MX6_EIM_SLOW_CLK_ENABLE
+    {6, 6},  // MX6_VDOAXICLK_CLK_ENABLE
+    {6, 7},  // MX6_VPU_CLK_ENABLE
+  };
+
+  return ImxpCcgrIndexMap[ClockGate];
+}
+
+CONST CHAR16 *StringFromImxClk (IMX_CLK Value)
+{
+  switch (Value) {
+  case IMX_CLK_NONE: return L"(none)";
+  case IMX_OSC_CLK: return L"OSC_CLK";
+  case IMX_PLL1_MAIN_CLK: return L"PLL1_MAIN_CLK";
+  case IMX_PLL2_MAIN_CLK: return L"PLL2_MAIN_CLK";
+  case IMX_PLL2_PFD0: return L"PLL2_PFD0";
+  case IMX_PLL2_PFD1: return L"PLL2_PFD1";
+  case IMX_PLL2_PFD2: return L"PLL2_PFD2";
+  case IMX_PLL3_MAIN_CLK: return L"PLL3_MAIN_CLK";
+  case IMX_PLL3_PFD0: return L"PLL3_PFD0";
+  case IMX_PLL3_PFD1: return L"PLL3_PFD1";
+  case IMX_PLL3_PFD2: return L"PLL3_PFD2";
+  case IMX_PLL3_PFD3: return L"PLL3_PFD3";
+  case IMX_PLL4_MAIN_CLK: return L"PLL4_MAIN_CLK";
+  case IMX_PLL5_MAIN_CLK: return L"PLL5_MAIN_CLK";
+  case IMX_CLK1: return L"CLK1";
+  case IMX_CLK2: return L"CLK2";
+  case IMX_PLL1_SW_CLK: return L"PLL1_SW_CLK";
+  case IMX_STEP_CLK: return L"STEP_CLK";
+  case IMX_PLL3_SW_CLK: return L"PLL3_SW_CLK";
+  case IMX_AXI_ALT: return L"AXI_ALT";
+  case IMX_AXI_CLK_ROOT: return L"AXI_CLK_ROOT";
+  case IMX_PERIPH_CLK2: return L"PERIPH_CLK2";
+  case IMX_PERIPH_CLK: return L"PERIPH_CLK";
+  case IMX_PRE_PERIPH_CLK: return L"PRE_PERIPH_CLK";
+  case IMX_PRE_PERIPH2_CLK: return L"PRE_PERIPH2_CLK";
+  case IMX_PERIPH2_CLK: return L"PERIPH2_CLK";
+  case IMX_ARM_CLK_ROOT: return L"ARM_CLK_ROOT";
+  case IMX_MMDC_CH0_CLK_ROOT: return L"MMDC_CH0_CLK_ROOT";
+  case IMX_MMDC_CH1_CLK_ROOT: return L"MMDC_CH1_CLK_ROOT";
+  case IMX_AHB_CLK_ROOT: return L"AHB_CLK_ROOT";
+  case IMX_IPG_CLK_ROOT: return L"IPG_CLK_ROOT";
+  case IMX_PERCLK_CLK_ROOT: return L"PERCLK_CLK_ROOT";
+  case IMX_USDHC1_CLK_ROOT: return L"USDHC1_CLK_ROOT";
+  case IMX_USDHC2_CLK_ROOT: return L"USDHC2_CLK_ROOT";
+  case IMX_USDHC3_CLK_ROOT: return L"USDHC3_CLK_ROOT";
+  case IMX_USDHC4_CLK_ROOT: return L"USDHC4_CLK_ROOT";
+  case IMX_SSI1_CLK_ROOT: return L"SSI1_CLK_ROOT";
+  case IMX_SSI2_CLK_ROOT: return L"SSI2_CLK_ROOT";
+  case IMX_SSI3_CLK_ROOT: return L"SSI3_CLK_ROOT";
+  case IMX_GPU2D_AXI_CLK_ROOT: return L"GPU2D_AXI_CLK_ROOT";
+  case IMX_GPU3D_AXI_CLK_ROOT: return L"GPU3D_AXI_CLK_ROOT";
+  case IMX_PCIE_AXI_CLK_ROOT: return L"PCIE_AXI_CLK_ROOT";
+  case IMX_VDO_AXI_CLK_ROOT: return L"VDO_AXI_CLK_ROOT";
+  case IMX_IPU1_HSP_CLK_ROOT: return L"IPU1_HSP_CLK_ROOT";
+  case IMX_GPU2D_CORE_CLK_ROOT: return L"GPU2D_CORE_CLK_ROOT";
+  case IMX_ACLK_EIM_SLOW_CLK_ROOT: return L"ACLK_EIM_SLOW_CLK_ROOT";
+  case IMX_ACLK_CLK_ROOT: return L"ACLK_CLK_ROOT";
+  case IMX_ENFC_CLK_ROOT: return L"ENFC_CLK_ROOT";
+  case IMX_GPU3D_CORE_CLK_ROOT: return L"GPU3D_CORE_CLK_ROOT";
+  case IMX_GPU3D_SHADER_CLK_ROOT: return L"GPU3D_SHADER_CLK_ROOT";
+  case IMX_VPU_AXI_CLK_ROOT: return L"VPU_AXI_CLK_ROOT";
+  case IMX_IPU1_DI0_CLK_ROOT: return L"IPU1_DI0_CLK_ROOT";
+  case IMX_IPU1_DI1_CLK_ROOT: return L"IPU1_DI1_CLK_ROOT";
+  case IMX_LDB_DI0_SERIAL_CLK_ROOT: return L"LDB_DI0_SERIAL_CLK_ROOT";
+  case IMX_LDB_DI0_IPU: return L"LDB_DI0_IPU";
+  case IMX_LDB_DI1_SERIAL_CLK_ROOT: return L"LDB_DI1_SERIAL_CLK_ROOT";
+  case IMX_LDB_DI1_IPU: return L"LDB_DI1_IPU";
+  case IMX_SPDIF0_CLK_ROOT: return L"SPDIF0_CLK_ROOT";
+  case IMX_SPDIF1_CLK_ROOT: return L"SPDIF1_CLK_ROOT";
+  case IMX_ESAI_CLK_ROOT: return L"ESAI_CLK_ROOT";
+  case IMX_HSI_TX_CLK_ROOT: return L"HSI_TX_CLK_ROOT";
+  case IMX_CAN_CLK_ROOT: return L"CAN_CLK_ROOT";
+  case IMX_ECSPI_CLK_ROOT: return L"ECSPI_CLK_ROOT";
+  case IMX_UART_CLK_ROOT: return L"UART_CLK_ROOT";
+  case IMX_VIDEO_27M_CLK_ROOT: return L"VIDEO_27M_CLK_ROOT";
+  default:
+    ASSERT (FALSE);
+    return L"[invalid IMX_CLK value]";
+  }
+}
+
+IMX_CLK ImxpClkFromBypassClkSource (IMX_PLL_BYPASS_CLK_SRC BypassClockSource)
+{
+  switch (BypassClockSource) {
+  case IMX_PLL_BYPASS_CLK_SRC_REF_CLK_24M:
+    return IMX_OSC_CLK;
+  case IMX_PLL_BYPASS_CLK_SRC_CLK1:
+    return IMX_CLK1;
+  case IMX_PLL_BYPASS_CLK_SRC_CLK2:
+    return IMX_CLK2;
+  case IMX_PLL_BYPASS_CLK_SRC_XOR:
+  default:
+    ASSERT (FALSE);
+    return IMX_CLK_NONE;
+  }
+}
+
+/**
+  Configure the GPU clock tree so that GPU2D and GPU3D are clocked from
+  the AXI clock root and are within the allowed frequency range.
+
+  The GPU must be powered down, and GPU clocks must be gated when this
+  function is called.
+**/
+VOID ImxCcmConfigureGpuClockTree ()
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCMR_REG cbcmrReg ; cbcmrReg.AsUint32 = MmioRead32 ((UINTN) &ccmRegisters->CBCMR);
+
+  cbcmrReg.gpu2d_axi_clk_sel = IMX_CCM_GPU2D_AXI_CLK_SEL_AXI;
+  cbcmrReg.gpu3d_axi_clk_sel = IMX_CCM_GPU3D_AXI_CLK_SEL_AXI;
+
+  cbcmrReg.gpu2d_core_clk_sel = IMX_CCM_GPU2D_CORE_CLK_SEL_PLL2_PFD0;
+  cbcmrReg.gpu3d_core_clk_sel = IMX_CCM_GPU3D_CORE_CLK_SEL_MMDC_CH0_AXI;
+  cbcmrReg.gpu3d_shader_clk_sel = IMX_CCM_GPU3D_SHADER_CLK_SEL_MMDC_CH0_AXI;
+
+  cbcmrReg.gpu2d_core_clk_podf = 0;
+  cbcmrReg.gpu3d_core_podf = 0;
+  cbcmrReg.gpu3d_shader_podf = 0;
+
+  ImxpClkPwrCacheReset ();
+  MmioWrite32 ((UINTN) &ccmRegisters->CBCMR, cbcmrReg.AsUint32);
+}
+
+/**
+    Configure all of DIx clock tree for IPU1. For flexibility
+    purpose use PLL5 (PLL Video) as main reference clock. PLL 5 has flexible
+    divider making it easily configurable. Muxing and clock programming needs
+    when to be updated when supporting multiple display.
+**/
+VOID ImxCcmConfigureIPUDIxClockTree ()
+{
+    volatile IMX_CCM_REGISTERS* ccmRegisters = (IMX_CCM_REGISTERS*) IMX_CCM_BASE;
+    IMX_CCM_CHSCCDR_REG chscddrReg;
+
+    chscddrReg.AsUint32 = MmioRead32((UINTN)&ccmRegisters->CHSCCDR);    // CCM HSC Clock Divider Register
+
+    // Setup muxing to pre-mux
+    chscddrReg.ipu1_di0_clk_sel = IMX_CHSCCDR_IPU1_DI0_CLK_SEL_PREMUX;          // 0 - derive clock from mmdc_ch0 clock
+    chscddrReg.ipu1_di1_clk_sel = IMX_CHSCCDR_IPU1_DI1_CLK_SEL_PREMUX;          // 0 - derive clock from divided pre-muxed ipu1 di1 clock
+    chscddrReg.ipu1_di0_podf = IMX_CHSCCDR_IPU1_DI0_PODF_DIV_1;                 // 0 - divide by 1
+    chscddrReg.ipu1_di1_podf = IMX_CHSCCDR_IPU1_DI1_PODF_DIV_1;                 // 0 - divide by 1
+    chscddrReg.ipu1_di0_pre_clk_sel = IMX_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_PLL5;    // 2 - derive clock from pll5
+    chscddrReg.ipu1_di1_pre_clk_sel = IMX_CHSCCDR_IPU1_DI1_PRE_CLK_SEL_PLL5;    // 2 - derive clock from pll5
+
+    MmioWrite32 ((UINTN)&ccmRegisters->CHSCCDR, chscddrReg.AsUint32);
+}
+
+/**
+    Configure PLL 5 clock rate to the desired clock rate
+**/
+VOID ImxSetClockRatePLL5 (
+    UINT32 ClockRate,
+    IMX_CCM_PLL_VIDEO_CTRL_POST_DIV_SELECT PostDivSelect
+    )
+{
+    // Use clock rate as denom for simple fractional calculation
+    UINT32 denom = IMX_REF_CLK_24M_FREQ;
+    UINT32 divSelect = ClockRate / IMX_REF_CLK_24M_FREQ; // Signed value
+    UINT32 numerator = ClockRate % IMX_REF_CLK_24M_FREQ;
+    volatile IMX_CCM_ANALOG_REGISTERS *ccmAnalogRegisters =
+        (IMX_CCM_ANALOG_REGISTERS *)IMX_CCM_ANALOG_BASE;
+    IMX_CCM_PLL_VIDEO_CTRL_REG pllVideoCtrlReg; pllVideoCtrlReg.AsUint32 =
+        MmioRead32 ((UINTN)&ccmAnalogRegisters->PLL_VIDEO);
+
+    ASSERT (numerator < denom);
+    ASSERT ((divSelect >= 27) && (divSelect <= 54));
+
+    // PLL output frequency = Fref * (DIV_SELECT + NUM / DENOM)
+    // Use the clock rate as denomitor to make fractional calulation simple
+    pllVideoCtrlReg.DIV_SELECT = divSelect;
+    pllVideoCtrlReg.POST_DIV_SELECT = PostDivSelect;
+
+    MmioWrite32(
+        (UINTN)&ccmAnalogRegisters->PLL_VIDEO, pllVideoCtrlReg.AsUint32);
+    MmioWrite32(
+        (UINTN)&ccmAnalogRegisters->PLL_VIDEO_NUM, numerator);
+    MmioWrite32(
+        (UINTN)&ccmAnalogRegisters->PLL_VIDEO_DENOM, denom);
+
+    pllVideoCtrlReg.AsUint32 = MmioRead32(
+        (UINTN)&ccmAnalogRegisters->PLL_VIDEO);
+
+    // Check to see if pll is locked, if not attempt to enable it
+    if (pllVideoCtrlReg.LOCK == 0) {
+        UINT32 counter = 10000;
+        {
+            IMX_CCM_PLL_VIDEO_CTRL_REG pllVideoCtrlClearReg = { 0 };
+            pllVideoCtrlClearReg.POWERDOWN = 1;
+            MmioWrite32(
+                (UINTN)&ccmAnalogRegisters->PLL_VIDEO_CLR,
+                pllVideoCtrlClearReg.AsUint32);
+        }
+        pllVideoCtrlReg.AsUint32 = MmioRead32(
+            (UINTN)&ccmAnalogRegisters->PLL_VIDEO);
+        {
+            IMX_CCM_PLL_VIDEO_CTRL_REG pllVideoCtrlSetReg = { 0 };
+            pllVideoCtrlSetReg.ENABLE = 1;
+            MmioWrite32(
+                (UINTN)&ccmAnalogRegisters->PLL_VIDEO_SET,
+                pllVideoCtrlSetReg.AsUint32);
+        }
+        pllVideoCtrlReg.AsUint32 = MmioRead32(
+            (UINTN)&ccmAnalogRegisters->PLL_VIDEO);
+        {
+            IMX_CCM_PLL_VIDEO_CTRL_REG pllVideoCtrlClearReg = { 0 };
+            pllVideoCtrlClearReg.BYPASS = 1;
+            MmioWrite32(
+                (UINTN)&ccmAnalogRegisters->PLL_VIDEO_CLR,
+                pllVideoCtrlClearReg.AsUint32);
+        }
+        pllVideoCtrlReg.AsUint32 = MmioRead32(
+            (UINTN)&ccmAnalogRegisters->PLL_VIDEO);
+        do {
+            pllVideoCtrlReg.AsUint32 = MmioRead32(
+                (UINTN)&ccmAnalogRegisters->PLL_VIDEO);
+            --counter;
+        } while ((pllVideoCtrlReg.LOCK == 0) && (counter > 0));
+        ASSERT (counter > 0);
+    }
+}
+
+EFI_STATUS
+ImxpGetPll2PfdClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  IMX_PLL_PFD PfdIndex,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_ANALOG_REGISTERS *ccmAnalogRegisters =
+      (IMX_CCM_ANALOG_REGISTERS *) IMX_CCM_ANALOG_BASE;
+
+  IMX_CCM_PFD_528_REG pfd528Reg; pfd528Reg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmAnalogRegisters->PFD_528);
+
+  UINT32 pfdFrac;
+  switch (PfdIndex) {
+  case IMX_PLL_PFD0:
+    pfdFrac = pfd528Reg.PFD0_FRAC;
+    break;
+  case IMX_PLL_PFD1:
+    pfdFrac = pfd528Reg.PFD1_FRAC;
+    break;
+  case IMX_PLL_PFD2:
+    pfdFrac = pfd528Reg.PFD2_FRAC;
+    break;
+  default:
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, IMX_PLL2_MAIN_CLK, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  // The resulting frequency shall be 528*18/PFDn_FRAC
+  // where PFD0_FRAC is in the range 12-35.
+  ASSERT ((pfdFrac >= 12) && (pfdFrac <= 35));
+  ClockInfo->Frequency = (UINT32) ((UINT64) parentInfo.Frequency * 18 / pfdFrac);
+  ClockInfo->Parent = IMX_PLL2_MAIN_CLK;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetAxiClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCDR_REG cbcdrReg; cbcdrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CBCDR);
+
+  IMX_CLK parent;
+  if (cbcdrReg.axi_sel == IMX_CCM_AXI_SEL_PERIPH_CLK) {
+    parent = IMX_PERIPH_CLK;
+  } else {
+    ASSERT (cbcdrReg.axi_sel == IMX_CCM_AXI_SEL_AXI_ALT);
+    parent = IMX_AXI_ALT;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency = parentInfo.Frequency / (1 + cbcdrReg.axi_podf);
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetGpu2dCoreClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCMR_REG cbcmrReg ; cbcmrReg.AsUint32 = MmioRead32 ((UINTN) &ccmRegisters->CBCMR);
+
+  IMX_CLK parent;
+  switch (cbcmrReg.gpu2d_core_clk_sel) {
+  case IMX_CCM_GPU2D_CORE_CLK_SEL_AXI:
+    parent = IMX_AXI_CLK_ROOT;
+    break;
+  case IMX_CCM_GPU2D_CORE_CLK_SEL_PLL3_SW:
+    parent = IMX_PLL3_SW_CLK;
+    break;
+  case IMX_CCM_GPU2D_CORE_CLK_SEL_PLL2_PFD0:
+    parent = IMX_PLL2_PFD0;
+    break;
+  case IMX_CCM_GPU2D_CORE_CLK_SEL_PLL2_PFD2:
+    parent = IMX_PLL2_PFD2;
+    break;
+  default:
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency =
+      parentInfo.Frequency / (1 + cbcmrReg.gpu2d_core_clk_podf);
+  ClockInfo->Parent = parent;
+
+  if (ClockInfo->Frequency > IMX_GPU2D_CORE_CLK_MAX) {
+    DEBUG ((
+      DEBUG_WARN,
+      "GPU2D_CORE_CLK exceeds maximum. (Value = %d, Max = %d)\r\n",
+      ClockInfo->Frequency,
+      IMX_GPU2D_CORE_CLK_MAX));
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetGpu3dCoreClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCMR_REG cbcmrReg ; cbcmrReg.AsUint32 = MmioRead32 ((UINTN) &ccmRegisters->CBCMR);
+
+  IMX_CLK parent;
+  switch (cbcmrReg.gpu3d_core_clk_sel) {
+  case IMX_CCM_GPU3D_CORE_CLK_SEL_MMDC_CH0_AXI:
+    parent = IMX_MMDC_CH0_CLK_ROOT;
+    break;
+  case IMX_CCM_GPU3D_CORE_CLK_SEL_PLL3_SW:
+    parent = IMX_PLL3_SW_CLK;
+    break;
+  case IMX_CCM_GPU3D_CORE_CLK_SEL_PLL2_PFD1:
+    parent = IMX_PLL2_PFD1;
+    break;
+  case IMX_CCM_GPU3D_CORE_CLK_SEL_PLL2_PFD2:
+    parent = IMX_PLL2_PFD2;
+    break;
+  default:
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency = parentInfo.Frequency / (1 + cbcmrReg.gpu3d_core_podf);
+  ClockInfo->Parent = parent;
+
+  if (ClockInfo->Frequency > IMX_GPU3D_CORE_CLK_MAX) {
+    DEBUG ((
+      DEBUG_WARN,
+      "GPU3D_CORE_CLK exceeds maximum. (Value = %d, Max = %d)\r\n",
+      ClockInfo->Frequency,
+      IMX_GPU3D_CORE_CLK_MAX));
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetGpu3dShaderClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCMR_REG cbcmrReg ; cbcmrReg.AsUint32 = MmioRead32 ((UINTN) &ccmRegisters->CBCMR);
+
+  IMX_CLK parent;
+  switch (cbcmrReg.gpu3d_shader_clk_sel) {
+  case IMX_CCM_GPU3D_SHADER_CLK_SEL_MMDC_CH0_AXI:
+    parent = IMX_MMDC_CH0_CLK_ROOT;
+    break;
+  case IMX_CCM_GPU3D_SHADER_CLK_SEL_PLL3_SW:
+    parent = IMX_PLL3_SW_CLK;
+    break;
+  case IMX_CCM_GPU3D_SHADER_CLK_SEL_PLL2_PFD1:
+    parent = IMX_PLL2_PFD1;
+    break;
+  case IMX_CCM_GPU3D_SHADER_CLK_SEL_PLL3_PFD0:
+    parent = IMX_PLL3_PFD0;
+    break;
+  default:
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency =
+      parentInfo.Frequency / (1 + cbcmrReg.gpu3d_shader_podf);
+
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetPeriphClk2Info (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCMR_REG cbcmrReg; cbcmrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CBCMR);
+
+  IMX_CLK parent;
+  switch (cbcmrReg.periph_clk2_sel) {
+  case IMX_CCM_PERIPH_CLK2_SEL_PLL3_SW_CLK:
+    parent = IMX_PLL3_SW_CLK;
+    break;
+  case IMX_CCM_PERIPH_CLK2_SEL_OSC_CLK:
+    parent = IMX_OSC_CLK;
+    break;
+  case IMX_CCM_PERIPH_CLK2_SEL_PLL2:
+    parent = IMX_PLL2_MAIN_CLK;
+    break;
+  default:
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  IMX_CCM_CBCDR_REG cbcdrReg; cbcdrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CBCDR);
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency = parentInfo.Frequency / (1 + cbcdrReg.periph_clk2_podf);
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetPeriphClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCDR_REG cbcdrReg; cbcdrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CBCDR);
+
+  IMX_CLK parent;
+
+  // NOTE: periph_clk_sel is OR'd with PLL_bypass_en2 (from jtag) to
+  //       produce the input value to the MUX. We assume PLL_bypass_en2 is 0.
+  if (cbcdrReg.periph_clk_sel == 0) {
+    parent = IMX_PRE_PERIPH_CLK;
+  } else {
+    ASSERT (cbcdrReg.periph_clk_sel == 1);
+    parent = IMX_PERIPH_CLK2;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency = parentInfo.Frequency / (1 + cbcdrReg.mmdc_ch0_axi_podf);
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetMmdcCh0ClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, IMX_PERIPH_CLK, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  IMX_CCM_CBCDR_REG cbcdrReg; cbcdrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CBCDR);
+
+  ClockInfo->Frequency =
+      parentInfo.Frequency / (1 + cbcdrReg.mmdc_ch0_axi_podf);
+  ClockInfo->Parent = IMX_PERIPH_CLK;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetGpu2dAxiClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCMR_REG cbcmrReg ; cbcmrReg.AsUint32 = MmioRead32 ((UINTN) &ccmRegisters->CBCMR);
+
+  IMX_CLK parent;
+  if (cbcmrReg.gpu2d_axi_clk_sel == IMX_CCM_GPU2D_AXI_CLK_SEL_AXI) {
+    parent = IMX_AXI_CLK_ROOT;
+  } else {
+    ASSERT (cbcmrReg.gpu2d_axi_clk_sel == IMX_CCM_GPU2D_AXI_CLK_SEL_AHB);
+    parent = IMX_AHB_CLK_ROOT;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency = parentInfo.Frequency;
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetGpu3dAxiClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCMR_REG cbcmrReg ; cbcmrReg.AsUint32 = MmioRead32 ((UINTN) &ccmRegisters->CBCMR);
+
+  IMX_CLK parent;
+  if (cbcmrReg.gpu3d_axi_clk_sel == IMX_CCM_GPU3D_AXI_CLK_SEL_AXI) {
+    parent = IMX_AXI_CLK_ROOT;
+  } else {
+    ASSERT (cbcmrReg.gpu3d_axi_clk_sel == IMX_CCM_GPU3D_AXI_CLK_SEL_AHB);
+    parent = IMX_AHB_CLK_ROOT;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency = parentInfo.Frequency;
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+VOID ImxEnableGpuVpuPowerDomain ()
+{
+  volatile IMX_CCM_ANALOG_REGISTERS *analogRegisters =
+    (IMX_CCM_ANALOG_REGISTERS *) IMX_CCM_ANALOG_BASE;
+
+  volatile IMX_GPC_REGISTERS *gpcRegisters = (IMX_GPC_REGISTERS *) IMX_GPC_BASE;
+  volatile IMX_GPC_PGC_REGISTERS *gpuPgcRegisters = &gpcRegisters->PGC_GPU;
+
+  // Configure GPC/PGC PUPSCR Register SW2ISO bits
+  {
+      IMX_GPC_PGC_PUPSCR_REG pupscrReg; pupscrReg.AsUint32 =
+        MmioRead32 ((UINTN) &gpuPgcRegisters->PUPSCR);
+
+    pupscrReg.SW = IMX_GPC_PGC_PUPSCR_SW_DEFAULT;
+    pupscrReg.SW2ISO = IMX_GPC_PGC_PUPSCR_SW2ISO_DEFAULT;
+
+    MmioWrite32 ((UINTN) &gpuPgcRegisters->PUPSCR, pupscrReg.AsUint32);
+  }
+
+  // Turn on LDO_PU to 1.250V
+  {
+    IMX_PMU_REG_CORE_REG pmuCoreReg = {0};
+    pmuCoreReg.REG1_TARG = 0x1f;
+
+    MmioWrite32 ((UINTN) &analogRegisters->PMU_REG_CORE_CLR, pmuCoreReg.AsUint32);
+
+    pmuCoreReg.REG1_TARG = 22;
+    MmioWrite32 ((UINTN) &analogRegisters->PMU_REG_CORE_SET, pmuCoreReg.AsUint32);
+
+    MicroSecondDelay (100);
+  }
+
+  // Assert power up request
+  IMX_GPC_CNTR_REG gpcCntrReg; gpcCntrReg.AsUint32 =
+      MmioRead32 ((UINTN) &gpcRegisters->CNTR);
+
+  gpcCntrReg.gpu_vpu_pdn_req = 0;
+  gpcCntrReg.gpu_vpu_pup_req = 1;
+
+  MmioWrite32 ((UINTN) &gpcRegisters->CNTR, gpcCntrReg.AsUint32);
+
+  // Wait for power up request to complete
+  do {
+    gpcCntrReg.AsUint32 = MmioRead32 ((UINTN) &gpcRegisters->CNTR);
+  } while (gpcCntrReg.gpu_vpu_pup_req != 0);
+}
+
+VOID ImxDisableGpuVpuPowerDomain ()
+{
+  volatile IMX_GPC_REGISTERS *gpcRegisters = (IMX_GPC_REGISTERS *) IMX_GPC_BASE;
+  volatile IMX_GPC_PGC_REGISTERS *gpuPgcRegisters = &gpcRegisters->PGC_GPU;
+
+  // Configure GPC/PGC PDNSCR Register ISO bits
+  {
+      IMX_GPC_PGC_PDNSCR_REG pdnscrReg; pdnscrReg.AsUint32 =
+        MmioRead32 ((UINTN) &gpuPgcRegisters->PDNSCR);
+
+    pdnscrReg.ISO = IMX_GPC_PGC_PDNSCR_ISO_DEFAULT;
+    pdnscrReg.ISO2SW = IMX_GPC_PGC_PDNSCR_ISO2SW_DEFAULT;
+
+    MmioWrite32 ((UINTN) &gpuPgcRegisters->PDNSCR, pdnscrReg.AsUint32);
+  }
+
+  // Configure GPC/PGC CTRL[PCR] bit to allow power down of the blocks
+  {
+      IMX_GPC_PGC_PGCR_REG ctrlReg; ctrlReg.AsUint32 =
+        MmioRead32 ((UINTN) &gpuPgcRegisters->CTRL);
+
+    ctrlReg.PCR = 1;    // enable powering down of the blocks
+
+    MmioWrite32 ((UINTN) &gpuPgcRegisters->CTRL, ctrlReg.AsUint32);
+  }
+
+  // Assert power down request
+  {
+      IMX_GPC_CNTR_REG gpcCntrReg; gpcCntrReg.AsUint32 =
+        MmioRead32 ((UINTN) &gpcRegisters->CNTR);
+
+    gpcCntrReg.gpu_vpu_pdn_req = 1;
+    gpcCntrReg.gpu_vpu_pup_req = 0;
+
+    MmioWrite32 ((UINTN) &gpcRegisters->CNTR, gpcCntrReg.AsUint32);
+
+    // Wait for power down request to complete
+    do {
+      gpcCntrReg.AsUint32 = MmioRead32 ((UINTN) &gpcRegisters->CNTR);
+    } while (gpcCntrReg.gpu_vpu_pdn_req != 0);
+  }
+}
+
+EFI_STATUS
+ImxpGetClockInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  IN IMX_CLK ClockId,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  ASSERT (ClockId < ARRAYSIZE(Cache->Table));
+
+  // First try to satisfy from cache
+  {
+    UINTN cacheValidBits = Cache->Valid[ClockId / _BITS_PER_UINTN];
+    if (cacheValidBits & (1 << (ClockId % _BITS_PER_UINTN))) {
+      *ClockInfo = Cache->Table[ClockId];
+      return EFI_SUCCESS;
+    }
+  }
+
+  EFI_STATUS status;
+  switch (ClockId) {
+  case IMX_OSC_CLK:
+    ImxpGetOsc24ClkInfo (ClockInfo);
+    status = EFI_SUCCESS;
+    break;
+  case IMX_PLL1_MAIN_CLK:
+    status = ImxpGetPll1MainClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_PLL2_MAIN_CLK:
+    status = ImxpGetPll2MainClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_PLL2_PFD0:
+    status = ImxpGetPll2PfdClkInfo (Cache, IMX_PLL_PFD0, ClockInfo);
+    break;
+  case IMX_PLL2_PFD1:
+    status = ImxpGetPll2PfdClkInfo (Cache, IMX_PLL_PFD1, ClockInfo);
+    break;
+  case IMX_PLL2_PFD2:
+    status = ImxpGetPll2PfdClkInfo (Cache, IMX_PLL_PFD2, ClockInfo);
+    break;
+  case IMX_PLL3_MAIN_CLK:
+    status = ImxpGetPll3MainClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_PLL3_PFD0:
+    status = ImxpGetPll3PfdClkInfo (Cache, IMX_PLL_PFD0, ClockInfo);
+    break;
+  case IMX_PLL3_PFD1:
+    status = ImxpGetPll3PfdClkInfo (Cache, IMX_PLL_PFD1, ClockInfo);
+    break;
+  case IMX_PLL3_PFD2:
+    status = ImxpGetPll3PfdClkInfo (Cache, IMX_PLL_PFD2, ClockInfo);
+    break;
+  case IMX_PLL3_PFD3:
+    status = ImxpGetPll3PfdClkInfo (Cache, IMX_PLL_PFD3, ClockInfo);
+    break;
+  case IMX_PLL3_SW_CLK:
+    status = ImxpGetPll3SwClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_AXI_CLK_ROOT:
+    status = ImxpGetAxiClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_PERIPH_CLK2:
+    status = ImxpGetPeriphClk2Info (Cache, ClockInfo);
+    break;
+  case IMX_PERIPH_CLK:
+    status = ImxpGetPeriphClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_PRE_PERIPH_CLK:
+    status = ImxpGetPrePeriphClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_ARM_CLK_ROOT:
+    status = ImxpGetArmClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_MMDC_CH0_CLK_ROOT:
+    status = ImxpGetMmdcCh0ClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_AHB_CLK_ROOT:
+    status = ImxpGetAhbClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_IPG_CLK_ROOT:
+    status = ImxpGetIpgClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_GPU2D_AXI_CLK_ROOT:
+    status = ImxpGetGpu2dAxiClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_GPU3D_AXI_CLK_ROOT:
+    status = ImxpGetGpu3dAxiClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_GPU2D_CORE_CLK_ROOT:
+    status = ImxpGetGpu2dCoreClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_GPU3D_CORE_CLK_ROOT:
+    status = ImxpGetGpu3dCoreClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_GPU3D_SHADER_CLK_ROOT:
+    status = ImxpGetGpu3dShaderClkInfo (Cache, ClockInfo);
+    break;
+  default:
+    return EFI_UNSUPPORTED;
+  }
+
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  // Update the cache
+  Cache->Table[ClockId] = *ClockInfo;
+  Cache->Valid[ClockId / _BITS_PER_UINTN] |= (1 << (ClockId % _BITS_PER_UINTN));
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Power on and clock the GPU2D/GPU3D blocks.
+
+  Follow the datasheet recommended sequence for clocking and powering:
+    Gate clocks -> unpower module ->
+    configure muxes/dividers -> power module -> Ungate clocks
+**/
+EFI_STATUS ImxClkPwrGpuEnable ()
+{
+    //EFI_STATUS status;
+
+#if !defined(MDEPKG_NDEBUG)
+
+  //
+  // Precondition: clock and power should be disabled
+  //
+  {
+    ASSERT (ImxClkPwrGetClockGate (IMX_GPU3D_CLK_ENABLE) == IMX_CLOCK_GATE_STATE_OFF);
+    ASSERT (ImxClkPwrGetClockGate (IMX_GPU2D_CLK_ENABLE) == IMX_CLOCK_GATE_STATE_OFF);
+    ASSERT (ImxClkPwrGetClockGate (IMX_OPENVGAXICLK_CLK_ROOT_ENABLE) == IMX_CLOCK_GATE_STATE_OFF);
+  }
+
+#endif
+
+  // Ensure clocks are gated
+  ImxClkPwrSetClockGate (IMX_GPU3D_CLK_ENABLE, IMX_CLOCK_GATE_STATE_OFF);
+  ImxClkPwrSetClockGate (IMX_GPU2D_CLK_ENABLE, IMX_CLOCK_GATE_STATE_OFF);
+  ImxClkPwrSetClockGate (IMX_OPENVGAXICLK_CLK_ROOT_ENABLE, IMX_CLOCK_GATE_STATE_OFF);
+
+  // Ensure GPU powered down (GPU should be powered down anyway)
+  ImxDisableGpuVpuPowerDomain ();
+
+  // Configure clock muxes and dividers for GPU3D, GPU2D, and OpenVG
+  ImxCcmConfigureGpuClockTree ();
+
+  // Power on the GPU
+  ImxEnableGpuVpuPowerDomain ();
+
+  // Ungate the GPU clocks
+  ImxClkPwrSetClockGate (IMX_GPU3D_CLK_ENABLE, IMX_CLOCK_GATE_STATE_ON);
+  ImxClkPwrSetClockGate (IMX_GPU2D_CLK_ENABLE, IMX_CLOCK_GATE_STATE_ON);
+  ImxClkPwrSetClockGate (IMX_OPENVGAXICLK_CLK_ROOT_ENABLE, IMX_CLOCK_GATE_STATE_ON);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+    Setup the clock tree for Display Interface (DI) for DuaLite and Solo
+        Gate clocks -> Configure mux/div -> Ungate clocks -> Setup PLL
+**/
+EFI_STATUS ImxClkPwrIpuDIxEnable ()
+{
+    ImxClkPwrSetClockGate(IMX_IPU1_DI0_CLK_ENABLE, IMX_CCM_CCGR_OFF);
+    ImxClkPwrSetClockGate(IMX_IPU1_DI1_CLK_ENABLE, IMX_CCM_CCGR_OFF);
+
+    ImxCcmConfigureIPUDIxClockTree();
+
+    ImxClkPwrSetClockGate(IMX_IPU1_DI0_CLK_ENABLE, IMX_CCM_CCGR_ON);
+
+    // Setup PLL to 65MHz as expected from UBOOT although transition
+    // might be so fast that UBOOT screen would not be displayed
+    ImxSetPll5ReferenceRate(65000000);
+
+    return EFI_SUCCESS;
+}
+
+/**
+    Configure PLL5 to the desired clock rate for all Display Interface (DI).
+    Currently only support one display to IPU1 DI0.
+**/
+EFI_STATUS ImxSetPll5ReferenceRate (
+    UINT32 ClockRate
+    )
+{
+    BOOLEAN foundConfig = FALSE;
+    UINT32 dxPodfDivider;
+    UINT32 targetFreq;
+    UINT32 postDivSelectCount;
+    UINT32 postDivSelectValue[3] = { 1, 2, 4 };
+    IMX_CCM_PLL_VIDEO_CTRL_POST_DIV_SELECT postDivSelect[3] = {
+        IMX_POST_DIV_SELECT_DIVIDE_1,
+        IMX_POST_DIV_SELECT_DIVIDE_2,
+        IMX_POST_DIV_SELECT_DIVIDE_4 };
+
+    for (postDivSelectCount = 0;
+        postDivSelectCount < ARRAYSIZE (postDivSelectValue);
+        ++postDivSelectCount) {
+
+        for (dxPodfDivider = 1; dxPodfDivider < 9; ++dxPodfDivider) {
+
+            targetFreq =
+                dxPodfDivider *
+                ClockRate *
+                postDivSelectValue[postDivSelectCount];
+
+            // The valid range for PPL loop divider is 27-54 so we
+            // need to target freq need to fit within the valid range.
+            if ((targetFreq >= PLL5_MIN_FREQ) &&
+                (targetFreq <= PLL5_MAX_FREQ)) {
+                foundConfig = TRUE;
+                break;
+            }
+        }
+
+        if (foundConfig == TRUE) {
+            break;
+        }
+    }
+
+    if (foundConfig == FALSE) {
+        DEBUG((DEBUG_ERROR, "ClockRate %d\n", ClockRate));
+        ASSERT(FALSE);
+        return EFI_INVALID_PARAMETER;
+    }
+
+    DEBUG ((
+        DEBUG_INFO,
+        "PLL 5 setting (%d) Target Freq %d Divider %d PostDiv %d\n",
+        ClockRate,
+        targetFreq,
+        dxPodfDivider,
+        postDivSelectValue[postDivSelectCount]
+        ));
+
+    {
+        volatile IMX_CCM_REGISTERS *ccmRegisters =
+            (IMX_CCM_REGISTERS *)IMX_CCM_BASE;
+        IMX_CCM_CHSCCDR_REG chscddrReg; chscddrReg.AsUint32 =
+             MmioRead32 ((UINTN)&ccmRegisters->CHSCCDR) ;
+
+        ImxClkPwrSetClockGate(IMX_IPU1_DI0_CLK_ENABLE, IMX_CCM_CCGR_OFF);
+        ImxClkPwrSetClockGate(IMX_IPU1_DI1_CLK_ENABLE, IMX_CCM_CCGR_OFF);
+
+        chscddrReg.ipu1_di0_podf = dxPodfDivider - 1;
+        chscddrReg.ipu1_di1_podf = dxPodfDivider - 1;
+
+        MmioWrite32 ((UINTN)&ccmRegisters->CHSCCDR, chscddrReg.AsUint32);
+
+        ImxClkPwrSetClockGate(IMX_IPU1_DI0_CLK_ENABLE, IMX_CCM_CCGR_ON);
+    }
+
+    ImxSetClockRatePLL5(targetFreq, postDivSelect[postDivSelectCount]);
+
+    return EFI_SUCCESS;
+}
+
+EFI_STATUS ImxClkPwrClkOut1Enable (IMX_CLK Clock, UINT32 Divider)
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  if ((Divider < 1) || (Divider > 8)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  IMX_CCM_CCOSR_REG ccosrReg; ccosrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CCOSR);
+
+  switch (Clock) {
+  case IMX_OSC_CLK:
+    ccosrReg.CLKO2_SEL = IMX_CCM_CLKO2_SEL_OSC_CLK;
+    ccosrReg.CLKO2_DIV = Divider - 1;
+    ccosrReg.CLKO2_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO2;
+    break;
+
+  case IMX_PLL2_MAIN_CLK:
+    ccosrReg.CLKO1_SEL = IMX_CCM_CLKO1_SEL_PLL2_MAIN_CLK_2;
+    ccosrReg.CLKO1_DIV = Divider - 1;
+    ccosrReg.CLKO1_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO1;
+    break;
+
+  case IMX_AXI_CLK_ROOT:
+    ccosrReg.CLKO1_SEL = IMX_CCM_CLKO1_SEL_AXI_CLK_ROOT;
+    ccosrReg.CLKO1_DIV = Divider - 1;
+    ccosrReg.CLKO1_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO1;
+    break;
+
+  case IMX_IPG_CLK_ROOT:
+    ccosrReg.CLKO1_SEL = IMX_CCM_CLKO1_SEL_IPG_CLK_ROOT;
+    ccosrReg.CLKO1_DIV = Divider - 1;
+    ccosrReg.CLKO1_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO1;
+    break;
+
+  case IMX_GPU2D_AXI_CLK_ROOT:
+    ccosrReg.CLKO2_SEL = IMX_CCM_CLKO2_SEL_GPU2D_AXI_CLK_ROOT;
+    ccosrReg.CLKO2_DIV = Divider - 1;
+    ccosrReg.CLKO2_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO2;
+    break;
+
+  case IMX_GPU3D_AXI_CLK_ROOT:
+    ccosrReg.CLKO2_SEL = IMX_CCM_CLKO2_SEL_GPU3D_AXI_CLK_ROOT;
+    ccosrReg.CLKO2_DIV = Divider - 1;
+    ccosrReg.CLKO2_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO2;
+    break;
+
+  case IMX_GPU2D_CORE_CLK_ROOT:
+    ccosrReg.CLKO2_SEL = IMX_CCM_CLKO2_SEL_GPU2D_CORE_CLK_ROOT;
+    ccosrReg.CLKO2_DIV = Divider - 1;
+    ccosrReg.CLKO2_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO2;
+    break;
+
+  case IMX_GPU3D_CORE_CLK_ROOT:
+    ccosrReg.CLKO2_SEL = IMX_CCM_CLKO2_SEL_GPU3D_CORE_CLK_ROOT;
+    ccosrReg.CLKO2_DIV = Divider - 1;
+    ccosrReg.CLKO2_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO2;
+    break;
+
+  case IMX_GPU3D_SHADER_CLK_ROOT:
+    ccosrReg.CLKO2_SEL = IMX_CCM_CLKO2_SEL_GPU3D_SHADER_CLK_ROOT;
+    ccosrReg.CLKO2_DIV = Divider - 1;
+    ccosrReg.CLKO2_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO2;
+    break;
+
+  case IMX_UART_CLK_ROOT:
+    ccosrReg.CLKO2_SEL = IMX_CCM_CLKO2_SEL_UART_CLK_ROOT;
+    ccosrReg.CLKO2_DIV = Divider - 1;
+    ccosrReg.CLKO2_EN = 1;
+    ccosrReg.CLK_OUT_SEL = IMX_CCM_CLK_OUT_SEL_CCM_CLKO2;
+    break;
+
+  default:
+    return EFI_UNSUPPORTED;
+  }
+
+  MmioWrite32 ((UINTN) &ccmRegisters->CCOSR, ccosrReg.AsUint32);
+
+  return EFI_SUCCESS;
+}
+
+VOID ImxClkPwrClkOut1Disable ()
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CCOSR_REG ccosrReg; ccosrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CCOSR);
+
+  ccosrReg.CLKO1_EN = 0;
+  ccosrReg.CLKO2_EN = 0;
+
+  MmioWrite32 ((UINTN) &ccmRegisters->CCOSR, ccosrReg.AsUint32);
+}
+
+EFI_STATUS ImxClkPwrValidateClocks ()
+{
+  struct {
+    IMX_CLK Clock;
+    IMX_CLOCK_INFO Info;
+  } expectedClocks[] = {
+    // Clock, Frequency, Parent
+    {IMX_OSC_CLK, {24000000, IMX_CLK_NONE}},
+    {IMX_PLL1_MAIN_CLK, {792000000, IMX_OSC_CLK}},
+    {IMX_PLL2_MAIN_CLK, {528000000, IMX_OSC_CLK}},
+    {IMX_PLL2_PFD0, {306580645, IMX_PLL2_MAIN_CLK}},
+    {IMX_PLL2_PFD1,{528000000, IMX_PLL2_MAIN_CLK}},
+    {IMX_PLL2_PFD2, {396000000, IMX_PLL2_MAIN_CLK}},
+    {IMX_PLL3_MAIN_CLK, {480000000, IMX_OSC_CLK}},
+    {IMX_PLL3_PFD0, {720000000, IMX_PLL3_MAIN_CLK}},
+    {IMX_PLL3_PFD1, {540000000, IMX_PLL3_MAIN_CLK}},
+    {IMX_PLL3_PFD2, {508235294, IMX_PLL3_MAIN_CLK}},
+    {IMX_PLL3_PFD3, {454736842, IMX_PLL3_MAIN_CLK}},
+    {IMX_AXI_CLK_ROOT, {198000000, IMX_PERIPH_CLK}},
+    {IMX_MMDC_CH0_CLK_ROOT, {396000000, IMX_PERIPH_CLK}},
+  };
+
+  BOOLEAN invalid = FALSE;
+
+  int i;
+  for (i = 0; i < ARRAYSIZE (expectedClocks); ++i) {
+    DEBUG ((
+      DEBUG_INFO,
+      "Validating clock %s. Expecting: Frequency = %d (%d Mhz), Parent = %s\r\n",
+      StringFromImxClk (expectedClocks[i].Clock),
+      expectedClocks[i].Info.Frequency,
+      expectedClocks[i].Info.Frequency / 1000000,
+      StringFromImxClk (expectedClocks[i].Info.Parent)
+      ));
+
+    IMX_CLOCK_INFO actualInfo;
+    EFI_STATUS status = ImxClkPwrGetClockInfo (
+        expectedClocks[i].Clock,
+        &actualInfo);
+
+    if (EFI_ERROR (status)) {
+      DEBUG ((
+        DEBUG_ERROR,
+        "Failed to get clock info. (Clock = %s, status = 0x%x)\r\n",
+        StringFromImxClk (expectedClocks[i].Clock),
+        status
+        ));
+
+      return status;
+    }
+
+    if ((actualInfo.Frequency != expectedClocks[i].Info.Frequency) ||
+        (actualInfo.Parent != expectedClocks[i].Info.Parent)) {
+
+        DEBUG ((
+          DEBUG_ERROR,
+          "SDL Clock settings do not match expected! Clock = %s (Expected, Actual) "
+          "Frequency: %d, %d. Parent: %s, %s\r\n",
+          StringFromImxClk (expectedClocks[i].Clock),
+          expectedClocks[i].Info.Frequency,
+          actualInfo.Frequency,
+          StringFromImxClk (expectedClocks[i].Info.Parent),
+          StringFromImxClk (actualInfo.Parent)
+          ));
+
+        invalid = TRUE;
+    }
+  }
+
+  return invalid ? EFI_DEVICE_ERROR : EFI_SUCCESS;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6SXClkPwr.inc b/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6SXClkPwr.inc
new file mode 100644
index 000000000000..c6c6251ebccf
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6SXClkPwr.inc
@@ -0,0 +1,665 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#if !defined(CPU_IMX6SX)
+#error iMX6SXClkPwr.inc should not be compiled for non iMX6 SX platform.
+#endif
+
+/**
+  Get the CCGR register index and gate number for a clock gate.
+**/
+IMX_CCGR_INDEX ImxpCcgrIndexFromClkGate (IMX_CLK_GATE ClockGate)
+{
+  static const IMX_CCGR_INDEX ImxpCcgrIndexMap[] = {
+    {0, 0},  // IMX_AIPS_TZ1_CLK_ENABLE
+    {0, 1},  // IMX_AIPS_TZ2_CLK_ENABLE
+    {0, 2},  // IMX_APBHDMA_HCLK_ENABLE
+    {0, 3},  // IMX_ASRC_CLK_ENABLE
+    {0, 4},  // IMX_CAAM_SECURE_MEM_CLK_ENABLE
+    {0, 5},  // IMX_CAAM_WRAPPER_ACLK_ENABLE
+    {0, 6},  // IMX_CAAM_WRAPPER_IPG_ENABLE
+    {0, 7},  // IMX_CAN1_CLK_ENABLE
+    {0, 8},  // IMX_CAN1_SERIAL_CLK_ENABLE
+    {0, 9},  // IMX_CAN2_CLK_ENABLE
+    {0, 10}, // IMX_CAN2_SERIAL_CLK_ENABLE
+    {0, 11}, // IMX_ARM_DBG_CLK_ENABLE
+    {0, 12}, // IMX_DCIC1_CLK_ENABLE
+    {0, 13}, // IMX_DCIC2_CLK_ENABLE
+    {0, 15}, // IMX_AIPS_TZ3_CLK_ENABLE
+    {1, 0},  // IMX_ECSPI1_CLK_ENABLE
+    {1, 1},  // IMX_ECSPI2_CLK_ENABLE
+    {1, 2},  // IMX_ECSPI3_CLK_ENABLE
+    {1, 3},  // IMX_ECSPI4_CLK_ENABLE
+    {1, 4},  // IMX_ECSPI5_CLK_ENABLE
+    {1, 6},  // IMX_EPIT1_CLK_ENABLE
+    {1, 7},  // IMX_EPIT2_CLK_ENABLE
+    {1, 8},  // IMX_ESAI_CLK_ENABLE
+    {1, 9},  // IMX_WAKEUP_CLK_ENABLE
+    {1, 10}, // IMX_GPT_CLK_ENABLE
+    {1, 11}, // IMX_GPT_SERIAL_CLK_ENABLE
+    {1, 13}, // IMX_GPU_CLK_ENABLE
+    {1, 14}, // IMX_OCRAM_S_CLK_ENABLE
+    {1, 15}, // IMX_CANFD_CLK_ENABLE
+    {2, 1},  // IMX_CSI_CLK_ENABLE
+    {2, 3},  // IMX_I2C1_SERIAL_CLK_ENABLE
+    {2, 4},  // IMX_I2C2_SERIAL_CLK_ENABLE
+    {2, 5},  // IMX_I2C3_SERIAL_CLK_ENABLE
+    {2, 6},  // IMX_IIM_CLK_ENABLE
+    {2, 7},  // IMX_IOMUX_IPT_CLK_IO_ENABLE
+    {2, 8},  // IMX_IPMUX1_CLK_ENABLE
+    {2, 9},  // IMX_IPMUX2_CLK_ENABLE
+    {2, 10}, // IMX_IPMUX3_CLK_ENABLE
+    {2, 11}, // IMX_IPSYNC_IP2APB_TZASC1_IPG_MASTER_CLK_ENABLE
+    {2, 14}, // IMX_LCD_CLK_ENABLE
+    {2, 15}, // IMX_PXP_CLK_ENABLE
+    {3, 1},  // IMX_M4_CLK_ENABLE
+    {3, 2},  // IMX_ENET_CLK_ENABLE
+    {3, 3},  // IMX_DISP_AXI_CLK_ENABLE
+    {3, 4},  // IMX_LCDIF2_PIX_CLK_ENABLE
+    {3, 5},  // IMX_LCDIF1_PIX_CLK_ENABLE
+    {3, 6},  // IMX_LDB_DI0_CLK_ENABLE
+    {3, 7},  // IMX_QSPI1_CLK_ENABLE
+    {3, 9},  // IMX_MLB_CLK_ENABLE
+    {3, 10}, // IMX_MMDC_CORE_ACLK_FAST_CORE_P0_ENABLE
+    {3, 12}, // IMX_MMDC_CORE_IPG_CLK_P0_ENABLE
+    {3, 13}, // IMX_MMDC_CORE_IPG_CLK_P1_ENABLE
+    {3, 14}, // IMX_OCRAM_CLK_ENABLE
+    {4, 0},  // IMX_PCIE_ROOT_ENABLE
+    {4, 5},  // IMX_QSPI2_CLK_ENABLE
+    {4, 6},  // IMX_PL301_MX6QPER1_BCHCLK_ENABLE
+    {4, 7},  // IMX_PL301_MX6QPER2_MAINCLK_ENABLE
+    {4, 8},  // IMX_PWM1_CLK_ENABLE
+    {4, 9},  // IMX_PWM2_CLK_ENABLE
+    {4, 10}, // IMX_PWM3_CLK_ENABLE
+    {4, 11}, // IMX_PWM4_CLK_ENABLE
+    {4, 12}, // IMX_RAWNAND_U_BCH_INPUT_APB_CLK_ENABLE
+    {4, 13}, // IMX_RAWNAND_U_GPMI_BCH_INPUT_BCH_CLK_ENABLE
+    {4, 14}, // IMX_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_CLK_ENABLE
+    {4, 15}, // IMX_RAWNAND_U_GPMI_INPUT_APB_CLK_ENABLE
+    {5, 0},  // IMX_ROM_CLK_ENABLE
+    {5, 3},  // IMX_SDMA_CLK_ENABLE
+    {5, 6},  // IMX_SPBA_CLK_ENABLE
+    {5, 7},  // IMX_SPDIF_AND_AUDIO_CLK_ENABLE
+    {5, 9},  // IMX_SSI1_CLK_ENABLE
+    {5, 10}, // IMX_SSI2_CLK_ENABLE
+    {5, 11}, // IMX_SSI3_CLK_ENABLE
+    {5, 12}, // IMX_UART_CLK_ENABLE
+    {5, 13}, // IMX_UART_SERIAL_CLK_ENABLE
+    {5, 14}, // IMX_SAI1_CLK_ENABLE
+    {5, 15}, // IMX_SAI2_CLK_ENABLE
+    {6, 0},  // IMX_USBOH3_CLK_ENABLE
+    {6, 1},  // IMX_USDHC1_CLK_ENABLE
+    {6, 2},  // IMX_USDHC2_CLK_ENABLE
+    {6, 3},  // IMX_USDHC3_CLK_ENABLE
+    {6, 4},  // IMX_USDHC4_CLK_ENABLE
+    {6, 5},  // IMX_EIM_SLOW_CLK_ENABLE
+    {6, 8},  // IMX_PWM8_CLK_ENABLE
+    {6, 10}, // IMX_VADC_CLK_ENABLE
+    {6, 11}, // IMX_GIS_CLK_ENABLE
+    {6, 12}, // IMX_I2C4_SERIAL_CLK_ENABLE
+    {6, 13}, // IMX_PWM5_CLK_ENABLE
+    {6, 14}, // IMX_PWM6_CLK_ENABLE
+    {6, 15}, // IMX_PWM7_CLK_ENABLE
+  };
+
+  return ImxpCcgrIndexMap[ClockGate];
+}
+
+CONST CHAR16 *StringFromImxClk (IMX_CLK Value)
+{
+  switch (Value) {
+  case IMX_CLK_NONE: return L"(none)";
+  case IMX_OSC_CLK: return L"OSC_CLK";
+  case IMX_PLL1_MAIN_CLK: return L"PLL1_MAIN_CLK";
+  case IMX_PLL2_MAIN_CLK: return L"PLL2_MAIN_CLK";
+  case IMX_PLL2_PFD0: return L"PLL2_PFD0";
+  case IMX_PLL2_PFD1: return L"PLL2_PFD1";
+  case IMX_PLL2_PFD2: return L"PLL2_PFD2";
+  case IMX_PLL2_PFD3: return L"PLL2_PFD3";
+  case IMX_PLL3_MAIN_CLK: return L"PLL3_MAIN_CLK";
+  case IMX_PLL3_PFD0: return L"PLL3_PFD0";
+  case IMX_PLL3_PFD1: return L"PLL3_PFD1";
+  case IMX_PLL3_PFD2: return L"PLL3_PFD2";
+  case IMX_PLL3_PFD3: return L"PLL3_PFD3";
+  case IMX_PLL4_MAIN_CLK: return L"PLL4_MAIN_CLK";
+  case IMX_PLL5_MAIN_CLK: return L"PLL5_MAIN_CLK";
+  case IMX_CLK1: return L"CLK1";
+  case IMX_CLK2: return L"CLK2";
+
+  case IMX_PLL1_SW_CLK: return L"PLL1_SW_CLK";
+  case IMX_STEP_CLK: return L"STEP_CLK";
+  case IMX_PLL3_SW_CLK: return L"PLL3_SW_CLK";
+
+  case IMX_PERIPH_CLK2: return L"PERIPH_CLK2";
+  case IMX_PERIPH_CLK: return L"_PERIPH_CLK";
+  case IMX_PRE_PERIPH_CLK: return L"PRE_PERIPH_CLK";
+
+  case IMX_ARM_CLK_ROOT: return L"ARM_CLK_ROOT";
+  case IMX_MMDC_CLK_ROOT: return L"MMDC_CLK_ROOT";
+  case IMX_FABRIC_CLK_ROOT: return L"FABRIC_CLK_ROOT";
+  case IMX_OCRAM_CLK_ROOT: return L"OCRAM_CLK_ROOT";
+  case IMX_PCIE_CLK_ROOT: return L"PCIE_CLK_ROOT";
+  case IMX_AHB_CLK_ROOT: return L"AHB_CLK_ROOT";
+  case IMX_PERCLK_CLK_ROOT: return L"PERCLK_CLK_ROOT";
+  case IMX_IPG_CLK_ROOT: return L"IPG_CLK_ROOT";
+  case IMX_USDHC1_CLK_ROOT: return L"USDHC1_CLK_ROOT";
+  case IMX_USDHC2_CLK_ROOT: return L"USDHC2_CLK_ROOT";
+  case IMX_USDHC3_CLK_ROOT: return L"USDHC3_CLK_ROOT";
+  case IMX_USDHC4_CLK_ROOT: return L"USDHC4_CLK_ROOT";
+  case IMX_ACLK_EIM_SLOW_CLK_ROOT: return L"ACLK_EIM_SLOW_CLK_ROOT";
+  case IMX_GPU_AXI_CLK_ROOT: return L"GPU_AXI_CLK_ROOT";
+  case IMX_GPU_CORE_CLK_ROOT: return L"GPU_CORE_CLK_ROOT";
+  case IMX_VID_CLK_ROOT: return L"VID_CLK_ROOT";
+  case IMX_ESAI_CLK_ROOT: return L"ESAI_CLK_ROOT";
+  case IMX_AUDIO_CLK_ROOT: return L"AUDIO_CLK_ROOT";
+  case IMX_SPDIF0_CLK_ROOT: return L"SPDIF0_CLK_ROOT";
+  case IMX_SSI1_CLK_ROOT: return L"SSI1_CLK_ROOT";
+  case IMX_SSI2_CLK_ROOT: return L"SSI2_CLK_ROOT";
+  case IMX_SSI3_CLK_ROOT: return L"SSI3_CLK_ROOT";
+  case IMX_LCDIF2_PIX_CLK_ROOT: return L"LCDIF2_PIX_CLK_ROOT";
+  case IMX_LCDIF1_PIX_CLK_ROOT: return L"LCDIF1_PIX_CLK_ROOT";
+  case IMX_LVDS_CLK_ROOT: return L"LVDS_CLK_ROOT";
+  case IMX_M4_CLK_ROOT: return L"M4_CLK_ROOT";
+  case IMX_ENET_CLK_ROOT: return L"ENET_CLK_ROOT";
+  case IMX_QSPI1_CLK_ROOT: return L"QSPI1_CLK_ROOT";
+  case IMX_QSPI2_CLK_ROOT: return L"QSPI2_CLK_ROOT";
+  case IMX_DISPLAY_CLK_ROOT: return L"DISPLAY_CLK_ROOT";
+  case IMX_CSI_CLK_ROOT: return L"CSI_CLK_ROOT";
+  case IMX_CAN_CLK_ROOT: return L"CAN_CLK_ROOT";
+  case IMX_ECSPI_CLK_ROOT: return L"ECSPI_CLK_ROOT";
+  case IMX_UART_CLK_ROOT: return L"UART_CLK_ROOT";
+  default:
+    ASSERT (FALSE);
+    return L"[invalid IMX_CLK value]";
+  }
+}
+
+IMX_CLK ImxpClkFromBypassClkSource (IMX_PLL_BYPASS_CLK_SRC BypassClockSource)
+{
+  switch (BypassClockSource) {
+  case IMX_PLL_BYPASS_CLK_SRC_REF_CLK_24M:
+    return IMX_OSC_CLK;
+  case IMX_PLL_BYPASS_CLK_SRC_CLK1:
+    return IMX_CLK1;
+  case IMX_PLL_BYPASS_CLK_SRC_GPANAIO:
+  case IMX_PLL_BYPASS_CLK_SRC_CHRG_DET_B:
+  default:
+    ASSERT (FALSE);
+    return IMX_CLK_NONE;
+  }
+}
+
+
+EFI_STATUS
+ImxpGetPll2PfdClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  IMX_PLL_PFD PfdIndex,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_ANALOG_REGISTERS *ccmAnalogRegisters =
+      (IMX_CCM_ANALOG_REGISTERS *) IMX_CCM_ANALOG_BASE;
+
+  IMX_CCM_PFD_528_REG pfd528Reg; pfd528Reg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmAnalogRegisters->PFD_528);
+
+  UINT32 pfdFrac;
+  switch (PfdIndex) {
+  case IMX_PLL_PFD0:
+    pfdFrac = pfd528Reg.PFD0_FRAC;
+    break;
+  case IMX_PLL_PFD1:
+    pfdFrac = pfd528Reg.PFD1_FRAC;
+    break;
+  case IMX_PLL_PFD2:
+    pfdFrac = pfd528Reg.PFD2_FRAC;
+    break;
+  case IMX_PLL_PFD3:
+    pfdFrac = pfd528Reg.PFD3_FRAC;
+    break;
+  default:
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, IMX_PLL2_MAIN_CLK, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  // The resulting frequency shall be 528*18/PFDn_FRAC
+  // where PFD0_FRAC is in the range 12-35.
+  ASSERT ((pfdFrac >= 12) && (pfdFrac <= 35));
+  ClockInfo->Frequency = (UINT32) ((UINT64) parentInfo.Frequency * 18 / pfdFrac);
+  ClockInfo->Parent = IMX_PLL2_MAIN_CLK;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetPerclkClkRootInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CSCMR1_REG    cscmr1;  cscmr1.AsUint32 =
+    MmioRead32 ((UINTN) &ccmRegisters->CSCMR1);
+
+  IMX_CLK parent;
+  switch(cscmr1.perclk_clk_sel) {
+   case IMX_CCM_PERCLK_CLK_SEL_IPG_CLK_ROOT:
+    parent = IMX_IPG_CLK_ROOT;
+    break;
+   case IMX_CCM_PERCLK_CLK_SEL_OSC_CLK:
+    parent = IMX_OSC_CLK;
+    break;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR(status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency = parentInfo.Frequency / (1 + cscmr1.perclk_podf);
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetPeriphClk2Info (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCMR_REG cbcmrReg; cbcmrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CBCMR);
+
+  IMX_CLK parent;
+  switch (cbcmrReg.periph_clk2_sel) {
+  case IMX_CCM_PERIPH_CLK2_SEL_PLL3_SW_CLK:
+    parent = IMX_PLL3_SW_CLK;
+    break;
+  case IMX_CCM_PERIPH_CLK2_SEL_OSC_CLK:
+    parent = IMX_OSC_CLK;
+    break;
+  case IMX_CCM_PERIPH_CLK2_SEL_PLL2_BYPASS_CLK:
+    parent = IMX_PLL2_MAIN_CLK;
+    break;
+  default:
+    ASSERT (FALSE);
+    return EFI_INVALID_PARAMETER;
+  }
+
+  IMX_CCM_CBCDR_REG cbcdrReg; cbcdrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CBCDR);
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency = parentInfo.Frequency / (1 + cbcdrReg.periph_clk2_podf);
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetPeriphClkInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+  IMX_CCM_CBCDR_REG cbcdrReg; cbcdrReg.AsUint32 =
+      MmioRead32 ((UINTN) &ccmRegisters->CBCDR);
+
+  IMX_CLK parent;
+
+  // NOTE: periph_clk_sel is OR'd with PLL_bypass_en2 (from jtag) to
+  //       produce the input value to the MUX. We assume PLL_bypass_en2 is 0.
+  if (cbcdrReg.periph_clk_sel == 0) {
+    parent = IMX_PRE_PERIPH_CLK;
+  } else {
+    ASSERT (cbcdrReg.periph_clk_sel == 1);
+    parent = IMX_PERIPH_CLK2;
+  }
+
+  IMX_CLOCK_INFO parentInfo;
+  EFI_STATUS status = ImxpGetClockInfo (Cache, parent, &parentInfo);
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  ClockInfo->Frequency = parentInfo.Frequency;
+  ClockInfo->Parent = parent;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+ImxpGetClockInfo (
+  IN OUT IMX_CLOCK_TREE_CACHE *Cache,
+  IN IMX_CLK ClockId,
+  OUT IMX_CLOCK_INFO *ClockInfo
+  )
+{
+  ASSERT (ClockId < ARRAYSIZE(Cache->Table));
+
+  // First try to satisfy from cache
+  {
+    UINTN cacheValidBits = Cache->Valid[ClockId / _BITS_PER_UINTN];
+    if (cacheValidBits & (1 << (ClockId % _BITS_PER_UINTN))) {
+      *ClockInfo = Cache->Table[ClockId];
+      return EFI_SUCCESS;
+    }
+  }
+
+  EFI_STATUS status;
+  switch (ClockId) {
+  case IMX_OSC_CLK:
+    ImxpGetOsc24ClkInfo (ClockInfo);
+    status = EFI_SUCCESS;
+    break;
+  case IMX_PLL1_MAIN_CLK:
+    status = ImxpGetPll1MainClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_PLL2_MAIN_CLK:
+    status = ImxpGetPll2MainClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_PLL2_PFD0:
+    status = ImxpGetPll2PfdClkInfo (Cache, IMX_PLL_PFD0, ClockInfo);
+    break;
+  case IMX_PLL2_PFD1:
+    status = ImxpGetPll2PfdClkInfo (Cache, IMX_PLL_PFD1, ClockInfo);
+    break;
+  case IMX_PLL2_PFD2:
+    status = ImxpGetPll2PfdClkInfo (Cache, IMX_PLL_PFD2, ClockInfo);
+    break;
+  case IMX_PLL3_MAIN_CLK:
+    status = ImxpGetPll3MainClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_PLL3_PFD0:
+    status = ImxpGetPll3PfdClkInfo (Cache, IMX_PLL_PFD0, ClockInfo);
+    break;
+  case IMX_PLL3_PFD1:
+    status = ImxpGetPll3PfdClkInfo (Cache, IMX_PLL_PFD1, ClockInfo);
+    break;
+  case IMX_PLL3_PFD2:
+    status = ImxpGetPll3PfdClkInfo (Cache, IMX_PLL_PFD2, ClockInfo);
+    break;
+  case IMX_PLL3_PFD3:
+    status = ImxpGetPll3PfdClkInfo (Cache, IMX_PLL_PFD3, ClockInfo);
+    break;
+  case IMX_PLL3_SW_CLK:
+    status = ImxpGetPll3SwClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_PERIPH_CLK2:
+    status = ImxpGetPeriphClk2Info (Cache, ClockInfo);
+    break;
+  case IMX_PERIPH_CLK:
+    status = ImxpGetPeriphClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_PRE_PERIPH_CLK:
+    status = ImxpGetPrePeriphClkInfo (Cache, ClockInfo);
+    break;
+  case IMX_ARM_CLK_ROOT:
+    status = ImxpGetArmClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_AHB_CLK_ROOT:
+    status = ImxpGetAhbClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_IPG_CLK_ROOT:
+    status = ImxpGetIpgClkRootInfo (Cache, ClockInfo);
+    break;
+  case IMX_PERCLK_CLK_ROOT:
+    status = ImxpGetPerclkClkRootInfo (Cache, ClockInfo);
+    break;
+
+  default:
+    return EFI_UNSUPPORTED;
+  }
+
+  if (EFI_ERROR (status)) {
+    return status;
+  }
+
+  // Update the cache
+  Cache->Table[ClockId] = *ClockInfo;
+  Cache->Valid[ClockId / _BITS_PER_UINTN] |= (1 << (ClockId % _BITS_PER_UINTN));
+
+  return EFI_SUCCESS;
+}
+
+//
+// Public functions
+//
+
+EFI_STATUS ImxClkPwrClkOut1Enable (IMX_CLK Clock, UINT32 Divider)
+{
+  return EFI_UNSUPPORTED;
+}
+
+VOID ImxClkPwrClkOut1Disable ()
+{
+}
+
+EFI_STATUS ImxClkPwrValidateClocks ()
+{
+  return EFI_UNSUPPORTED;
+}
+
+VOID ImxClkPwrLcdClockDisable ()
+{
+    IMX_CCM_CCGR2_REG value32;
+    volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+    value32.AsUint32 = MmioRead32((UINTN) &ccmRegisters->CCGR[2]);
+    value32.lcd_clk_enable = IMX6SX_CCM_CLOCK_OFF;
+    MmioWrite32((UINTN) &ccmRegisters->CCGR[2], value32.AsUint32);
+}
+
+VOID ImxClkPwrLcdClockEnable ()
+{
+    IMX_CCM_CCGR2_REG value32;
+    volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+
+    value32.AsUint32 = MmioRead32((UINTN) &ccmRegisters->CCGR[2]);
+    value32.lcd_clk_enable = IMX6SX_RUN_ONLY;
+    MmioWrite32((UINTN) &ccmRegisters->CCGR[2], value32.AsUint32);
+}
+
+VOID ImxSetClockRatePLL5 (
+  UINT32 TargetClockRate,
+  UINT32 PreDividerLcdif1Val,
+  UINT32 PostDividerLcdif1Val
+  )
+{
+    IMX_CCM_CCGR3_REG ccgr3;
+    UINT32 value32;
+    IMX_CCM_PLL_VIDEO_CTRL_REG videoControl;
+    volatile IMX_CCM_REGISTERS *ccmRegisters = (IMX_CCM_REGISTERS *) IMX_CCM_BASE;
+    volatile IMX_CCM_ANALOG_REGISTERS *analogRegisters = (IMX_CCM_ANALOG_REGISTERS *) IMX_CCM_ANALOG_BASE;
+
+    // turn off LCD clocks
+    ImxClkPwrLcdClockDisable();
+
+    // gate the LCD pixel and AXI clocks CCGR3.CG5
+    ccgr3.AsUint32 = MmioRead32((UINTN) &ccmRegisters->CCGR[3]);
+    ccgr3.lcdif1_pix_clk_enable = IMX6SX_CCM_CLOCK_OFF;
+    ccgr3.disp_axi_clk_enable = IMX6SX_CCM_CLOCK_OFF;
+    MmioWrite32((UINTN) &ccmRegisters->CCGR[3], ccgr3.AsUint32);
+
+    //
+    // set the divider for the source clock to the video PLL to divide by 1
+    //
+    MmioWrite32((UINTN) &analogRegisters->MISC0_CLR, 0x80000000);
+
+    //
+    // fire up the video PLL to the correct frequency
+    // before division
+    //
+    videoControl.AsUint32 = 0;
+    videoControl.POST_DIV_SELECT = 0x03;
+    videoControl.BYPASS = 0x01;
+    videoControl.POWERDOWN = 0x01;
+    videoControl.DIV_SELECT = 0x7f;
+    MmioWrite32((UINTN) &analogRegisters->PLL_VIDEO_CLR, videoControl.AsUint32);
+
+    //
+    // PLL output frequency = (Reference Freq) * (DIV_SELECT + NUM / DENOM)
+    //
+    // Use clock rate as denominator for simple fractional calculation.
+    // This way we just need to figure out the target clock rate ratio
+    // to the 24MHz reference.
+    //
+    {
+        IMX_CCM_PLL_VIDEO_CTRL_REG pllVideoCtrlReg;
+        UINT32 denom = IMX_REF_CLK_24M_FREQ;
+        UINT32 divSelect = TargetClockRate / IMX_REF_CLK_24M_FREQ;
+        UINT32 numerator = TargetClockRate % IMX_REF_CLK_24M_FREQ;
+        pllVideoCtrlReg.AsUint32 = MmioRead32((UINTN) &analogRegisters->PLL_VIDEO);
+
+        ASSERT (numerator < denom);
+        ASSERT ((divSelect >= 27) && (divSelect <= 54));
+
+        pllVideoCtrlReg.DIV_SELECT = divSelect;
+        pllVideoCtrlReg.POST_DIV_SELECT = IMX_POST_DIV_SELECT_DIVIDE_1;
+
+        DEBUG ((
+            DEBUG_INFO,
+            "PLL 5 divSelect (%d) numerator (%d) denom %d\n",
+            divSelect,
+            numerator,
+            denom
+            ));
+
+        MmioWrite32((UINTN) &analogRegisters->PLL_VIDEO, pllVideoCtrlReg.AsUint32);
+        MmioWrite32((UINTN) &analogRegisters->PLL_VIDEO_NUM, numerator);
+        MmioWrite32((UINTN) &analogRegisters->PLL_VIDEO_DENOM, denom);
+    }
+
+    // wait for PLL to lock
+    do {
+        videoControl.AsUint32 = MmioRead32((UINTN) &analogRegisters->PLL_VIDEO);
+    } while (!(videoControl.LOCK));
+
+    //
+    // select the video PLL in the LCDIF clock selector
+    // and set the CDIF1_PRED value
+    //
+    value32 = MmioRead32((UINTN) &ccmRegisters->CSCDR2);
+    // Clear LCDIF1_CLK_SEL, LCDIF1_PRED and LCDIF1_PRE_CLK_SEL
+    value32 &= ~0x0003FE00;
+    // Set the predivider value and derive clock from PLL5
+    value32 |= ((PreDividerLcdif1Val - 1) << 12) | (2 << 15);
+    MmioWrite32((UINTN) &ccmRegisters->CSCDR2, value32);
+
+    //
+    // set the post divider in CBCMR
+    //
+    value32 = MmioRead32((UINTN) &ccmRegisters->CBCMR);
+    // Clear LCDIF1_PODF
+    value32 &= ~0x03800000;
+    value32 |= ((PostDividerLcdif1Val - 1) << 23);
+    MmioWrite32((UINTN) &ccmRegisters->CBCMR, value32);
+
+    // enable the PLL output
+    videoControl.AsUint32 = 0;
+    videoControl.ENABLE = 1;
+    MmioWrite32((UINTN) &analogRegisters->PLL_VIDEO_SET, videoControl.AsUint32);
+
+    // Ungate the LCD pixel clock
+    ccgr3.AsUint32 = MmioRead32((UINTN) &ccmRegisters->CCGR[3]);
+    ccgr3.lcdif1_pix_clk_enable = IMX6SX_RUN_ONLY;
+    ccgr3.disp_axi_clk_enable = IMX6SX_RUN_ONLY;
+    MmioWrite32((UINTN) &ccmRegisters->CCGR[3], ccgr3.AsUint32);
+
+    // turn on LCD clocks
+    ImxClkPwrLcdClockEnable();
+}
+
+EFI_STATUS
+ImxSetLcdIfClockRate (
+    UINT32 ClockRate
+    )
+{
+    BOOLEAN foundConfig = FALSE;
+    UINT32 targetFreq;
+    UINT32 preDivSelectCount;
+    UINT32 postDivSelectCount;
+    UINT32 preDividerLcdif1[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+    UINT32 postDividerLcdif1[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };
+
+    for (preDivSelectCount = 0;
+        preDivSelectCount < ARRAYSIZE (preDividerLcdif1);
+        ++preDivSelectCount) {
+
+        for (postDivSelectCount = 0;
+            postDivSelectCount < ARRAYSIZE (postDividerLcdif1);
+            ++postDivSelectCount) {
+
+            targetFreq =
+                ClockRate *
+                preDividerLcdif1[preDivSelectCount] *
+                postDividerLcdif1[postDivSelectCount] *
+                1;
+
+            //
+            // The valid range for PLL loop divider is 27-54 so we
+            // need to target freq need to fit within the valid range.
+            //
+            if ((targetFreq >= PLL5_MIN_FREQ) &&
+                (targetFreq <= PLL5_MAX_FREQ)) {
+                foundConfig = TRUE;
+                break;
+            }
+        }
+
+        if (foundConfig == TRUE) {
+            break;
+        }
+    }
+
+    if (foundConfig == FALSE) {
+        DEBUG((DEBUG_ERROR, "No valid configuration found for clock rate %d\n", ClockRate));
+        ASSERT(FALSE);
+        return EFI_INVALID_PARAMETER;
+    }
+
+    DEBUG ((
+        DEBUG_INFO,
+        "PLL 5 setting (%d) Target Freq (%d) PreDiv %d PostDiv %d\n",
+        ClockRate,
+        targetFreq,
+        preDividerLcdif1[preDivSelectCount],
+        postDividerLcdif1[postDivSelectCount]
+        ));
+
+    ImxSetClockRatePLL5(
+        targetFreq,
+        preDividerLcdif1[preDivSelectCount],
+        postDividerLcdif1[postDivSelectCount]);
+
+    return EFI_SUCCESS;
+}
-- 
2.16.2.gvfs.1.33.gf5370f1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH edk2-platforms 09/13] Silicon/NXP: Add i.MX6 ACPI tables
  2018-07-20  6:33 [PATCH edk2-platforms 00/13] Silicon/NXP: Import NXP i.MX6 Package Chris Co
                   ` (7 preceding siblings ...)
  2018-07-20  6:33 ` [PATCH edk2-platforms 08/13] Silicon/NXP: Add i.MX6 Clock Library Chris Co
@ 2018-07-20  6:33 ` Chris Co
  2018-07-20  6:33 ` [PATCH edk2-platforms 10/13] Silicon/NXP: Add i.MX6 Board init library Chris Co
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chris Co @ 2018-07-20  6:33 UTC (permalink / raw)
  To: edk2-devel@lists.01.org; +Cc: Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This adds baseline ACPI table support for booting Windows on
NXP i.MX6 SoCs.  Platforms may override these tables as necessary.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Christopher Co <christopher.co@microsoft.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/NXP/iMX6Pkg/AcpiTables/Csrt.aslc         | 470 +++++++++++++++++++
 Silicon/NXP/iMX6Pkg/AcpiTables/Dbg2.aslc         | 148 ++++++
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Common.inc   | 112 +++++
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Enet.inc     | 111 +++++
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Gfx.inc      |  58 +++
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Gpio.inc     |  47 ++
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-I2c.inc      |  64 +++
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-PCIe.inc     | 483 ++++++++++++++++++++
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Platform.inc | 121 +++++
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Pwm.inc      |  80 ++++
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Sdhc.inc     | 225 +++++++++
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Spi.inc      |  98 ++++
 Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-TrEE.inc     |  36 ++
 Silicon/NXP/iMX6Pkg/AcpiTables/Fadt.aslc         |  56 +++
 Silicon/NXP/iMX6Pkg/AcpiTables/Madt.aslc         | 124 +++++
 Silicon/NXP/iMX6Pkg/AcpiTables/Mcfg.aslc         | 148 ++++++
 Silicon/NXP/iMX6Pkg/AcpiTables/Spcr.aslc         |  92 ++++
 Silicon/NXP/iMX6Pkg/AcpiTables/Tpm2.aslc         |  69 +++
 18 files changed, 2542 insertions(+)

diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Csrt.aslc b/Silicon/NXP/iMX6Pkg/AcpiTables/Csrt.aslc
new file mode 100644
index 000000000000..bedd28dfc486
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Csrt.aslc
@@ -0,0 +1,470 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "../Include/Platform.h"
+#include "../Include/iMX6.h"
+
+#pragma pack(push, iMX6Csrt, 1)
+
+//------------------------------------------------------------------------
+// Timer Resource Group
+//------------------------------------------------------------------------
+
+//
+// Each timer consumes 4K of address space.
+//
+#define TIMER_ADDRES_SIZE 0x1000
+
+#define TIMER_CAP_ALWAYS_ON     0x00000001 // Timer is always ON.
+#define TIMER_CAP_UP_COUNTER    0x00000002 // Up counter vs. down counter (0)
+#define TIMER_CAP_READABLE      0x00000004 // Counter has a software interface.
+#define TIMER_CAP_PERIODIC      0x00000008 // Can generate periodic interrupts.
+#define TIMER_CAP_DRIVES_IRQ    0x00000010 // Timer interrupt drives a physical IRQ.
+#define TIMER_CAP_ONE_SHOT      0x00000020 // Counter is capable of generating one-shot interrupts
+
+//
+// Timer source clock codes
+//
+typedef enum
+{
+    GPT_CLOCK_NONE        = 0,
+    GPT_CLOCK_PERIPHERAL  = 1,
+    GPT_CLOCK_HI_FREQ     = 2,
+    GPT_CLOCK_EXT         = 3,
+    GPT_CLOCK_LOW_FREQ    = 4,
+#if defined(CPU_IMX6DQ)
+    GPT_CLOCK_OSC_DIV_8   = 5,
+    GPT_CLOCK_OSC         = 7,
+#elif (defined(CPU_IMX6SDL) || defined(CPU_IMX6SX))
+    GPT_CLOCK_OSC         = 5,
+#else
+#error iMX6 CPU Type Not Defined (Preprocessor Flag)
+#endif
+} GPT_SOURCE_CLOCK;
+
+//
+// EPIT timer source clock codes
+//
+typedef enum
+{
+    EPIT_CLOCK_NONE        = 0,
+    EPIT_CLOCK_PERIPHERAL  = 1,
+    EPIT_CLOCK_HI_FREQ     = 2,
+    EPIT_CLOCK_LOW_FREQ    = 3,
+
+} EPIT_SOURCE_CLOCK;
+
+// Timer descriptor
+typedef struct
+{
+    EFI_ACPI_5_0_CSRT_RESOURCE_DESCRIPTOR_HEADER Header;
+
+    UINT32 Capabilities;
+    UINT32 Width;
+    UINT32 Source;
+    UINT32 Frequency;
+    UINT32 FrequencyScale;
+    UINT32 BaseAddress;
+    UINT32 Size;
+    UINT32 Interrupt;
+    UINT32 ChipType;
+} RD_TIMER;
+
+// Resource Group Shared Info
+typedef struct
+{
+    UINT16 RevMajor;
+    UINT16 RevMinor;
+
+    UINT32 ChipType;
+} RG_PLATFORM_INFORMATION;
+
+// Timer group descriptor
+typedef struct
+{
+    EFI_ACPI_5_0_CSRT_RESOURCE_GROUP_HEADER Header;
+
+    RG_PLATFORM_INFORMATION PlatformInfo;
+#if defined(CPU_IMX6SDL)
+    RD_TIMER Timers[3];
+#else
+    RD_TIMER Timers[4];
+#endif
+} RG_TIMER;
+
+
+//------------------------------------------------------------------------
+// PL310 L2 Cache Controller Resource Group
+//------------------------------------------------------------------------
+
+#define CSRT_PL310_MINIMUM_VERSION   1
+#define CSRT_PL310_VERSION_2         2
+#define CSRT_PL310_RAW_PROTOCOL      0
+#define CSRT_PL310_SMC_PROTOCOL      1
+
+//
+// We use PSCI_CPU_ON to turn on the L2 cache, with special value
+// 0x00100000 for the Core ID. PSCI sees this core ID and knows
+// this is an L2 cache operation, then looks at R2 for the
+// operation to perform.
+//
+#define PSCI_FID_CPU_ON                        0x84000003
+#define L2CACHE_SMC_R1                         0x00100000
+#define L2CACHE_OP_ENABLE                      1
+#define L2CACHE_OP_DISABLE                     2
+#define L2CACHE_OP_ENABLE_WRITEBACK            3
+#define L2CACHE_OP_DISABLE_WRITEBACK           4
+#define L2CACHE_OP_ENABLE_WFLZ                 5
+
+typedef struct {
+    UINT32 Immediate;
+    UINT32 R0;
+    UINT32 R1;
+    UINT32 R2;
+    UINT32 R3;
+    UINT32 R12;
+} CSRT_SMC_INVOCATION_BLOCK;
+
+// L2 cache descriptor
+typedef struct
+{
+    EFI_ACPI_5_0_CSRT_RESOURCE_DESCRIPTOR_HEADER Header;
+
+    UINT32 Version;
+    UINT32 ManagementProtocol;
+    UINT64 Address;
+
+    CSRT_SMC_INVOCATION_BLOCK InvokeEnable;
+    CSRT_SMC_INVOCATION_BLOCK InvokeDisable;
+    CSRT_SMC_INVOCATION_BLOCK InvokeEnableWriteback;
+    CSRT_SMC_INVOCATION_BLOCK InvokeDisableWriteback;
+    CSRT_SMC_INVOCATION_BLOCK InvokeEnableWFLZ;
+} RD_L2_CACHE;
+
+// PL310 L2 cache controller descriptor
+typedef struct
+{
+    EFI_ACPI_5_0_CSRT_RESOURCE_GROUP_HEADER Header;
+
+    RD_L2_CACHE L2Cache;
+} RG_L2_CACHE;
+
+//------------------------------------------------------------------------
+// SmartDMA (SDMA) Controller Resource Group
+//------------------------------------------------------------------------
+
+enum IMX_SDMA_CORE_CLOCK_RATIO {
+    IMX_SDMA_CORE_CLOCK_TWICE_CORE_FREQ = 0,
+    IMX_SDMA_CORE_CLOCK_EQUALS_CORE_FREQ = 1
+};
+
+// SDMA controller descriptor
+typedef struct
+{
+    EFI_ACPI_5_0_CSRT_RESOURCE_DESCRIPTOR_HEADER Header;
+
+    UINT32 ChipType; // IMX_CHIP_TYPE
+    UINT64 RegistersBaseAddress;
+    UINT64 IoMuxGPR0Address;
+    UINT32 Interrupt;
+    UINT32 SdmaCoreClockRatio; // IMX_SDMA_CORE_CLOCK_RATIO
+} RD_SDMA;
+
+// SDMA controller group descriptor
+typedef struct
+{
+    EFI_ACPI_5_0_CSRT_RESOURCE_GROUP_HEADER Header;
+
+    RD_SDMA Sdma;
+} RG_SDMA;
+
+//------------------------------------------------------------------------
+// CSRT structure for this platform
+//------------------------------------------------------------------------
+typedef struct
+{
+    EFI_ACPI_DESCRIPTION_HEADER CsrtHeader; // Standard ACPI Header
+    RG_TIMER TimerResourceGroup;            // Timer Resource Group
+#ifndef CONFIG_L2CACHE_OFF
+    RG_L2_CACHE L2CacheResourceGroup;       // PL310 L2 Cache Resource Group
+#endif
+    RG_SDMA SdmaResourceGroup;              // SDMA Resource Group
+} EFI_ACPI_CSRT_TABLE;
+
+#pragma pack (pop, iMX6Csrt)
+
+EFI_ACPI_CSRT_TABLE Csrt =
+{
+    //------------------------------------------------------------------------
+    // CSRT Header
+    //------------------------------------------------------------------------
+    {
+        EFI_ACPI_5_0_CORE_SYSTEM_RESOURCE_TABLE_SIGNATURE,  // Signature "CSRT"
+        sizeof(EFI_ACPI_DESCRIPTION_HEADER) +               // Length
+            sizeof(RG_TIMER)
+#ifndef CONFIG_L2CACHE_OFF
+                + sizeof(RG_L2_CACHE)
+#endif
+                + sizeof(RG_SDMA)
+            ,
+        EFI_ACPI_5_0_CSRT_REVISION,                         // Revision
+        0x00,                                               // Checksum calculated at runtime.
+        EFI_ACPI_OEM_ID,                                    // OEMID is a 6 bytes long field.
+        EFI_ACPI_OEM_TABLE_ID,                              // OEM table identification(8 bytes long).
+        EFI_ACPI_OEM_REVISION,                              // OEM revision number.
+        EFI_ACPI_CREATOR_ID,                                // ASL compiler vendor ID.
+        EFI_ACPI_CREATOR_REVISION,                          // ASL compiler revision number.
+    },
+
+    //------------------------------------------------------------------------
+    // TimerResourceGroup
+    //------------------------------------------------------------------------
+    {
+        // Timer group header
+        {
+            sizeof(RG_TIMER),               // Resource Group Length
+            SIGNATURE_32('F','S','C','L'),  // VendorId
+            0,                              // SubvendorId
+            0x0001,                         // DeviceId
+            0,                              // SubdeviceId
+            0,                              // Revision
+            0,                              // Reserved
+            sizeof(RG_PLATFORM_INFORMATION) // Platform Information shared info
+
+        }, // Timer group header
+
+        // Platform Information
+        {
+            0x0001,                        // RevMajor
+            0x0000,                        // RevMinor
+            0,                             // IMX_CHIP_TYPE (not used)
+        },
+
+        //------------------------------------------------------------------------
+        // Timers
+        //------------------------------------------------------------------------
+        {
+            // Counter (GPT)
+            {
+                {
+                    sizeof(RD_TIMER),               // Resource Descriptor Length
+                    EFI_ACPI_CSRT_RD_TYPE_TIMER,    // Resource Type
+                    EFI_ACPI_CSRT_RD_SUBTYPE_TIMER, // Resource Subtype
+                    3,                              // ResourceId
+                },
+                TIMER_CAP_READABLE      |           // Capabilities
+                    TIMER_CAP_UP_COUNTER,
+                32,                                 // Timer width (bits)
+                GPT_CLOCK_OSC,                      // Source is 111b for QD, 101b for SDL
+                SOC_OSC_FREQUENCY_REF_HZ,           // Frequency 24 MHz
+                24,                                 // divider to make 1 MHz
+                CSP_BASE_REG_PA_GPT,                // 32 bit Physical address
+                TIMER_ADDRES_SIZE,                  // Size of timer address space
+                0,                                  // N.B. No interrupt on this counter
+
+            }, // Counter (GPT)
+
+            // Timer0 (EPIT1)
+            {
+                {
+                    sizeof(RD_TIMER),               // Resource Descriptor Length
+                    EFI_ACPI_CSRT_RD_TYPE_TIMER,    // Resource Type
+                    EFI_ACPI_CSRT_RD_SUBTYPE_TIMER, // Resource Subtype
+                    4,                              // ResourceId
+                },
+                TIMER_CAP_ONE_SHOT      |           // Capabilities
+                TIMER_CAP_PERIODIC      |
+                TIMER_CAP_ALWAYS_ON |
+                TIMER_CAP_DRIVES_IRQ,
+                32,                                 // Timer width (bits)
+                EPIT_CLOCK_LOW_FREQ,                // Source
+                SOC_LOW_FREQ_REF_HZ,                // Frequency
+                1,                                  // Frequency scale
+                CSP_BASE_REG_PA_EPIT1,              // 32 bit Physical address
+                TIMER_ADDRES_SIZE,                  // Size of timer address space
+                IRQ_EPIT1,                          // Interrupt
+
+            }, // Timer0 (EPIT1)
+
+            // Timer1 (EPIT2)
+            {
+                {
+                    sizeof(RD_TIMER),               // Resource Descriptor Length
+                    EFI_ACPI_CSRT_RD_TYPE_TIMER,    // Resource Type
+                    EFI_ACPI_CSRT_RD_SUBTYPE_TIMER, // Resource Subtype
+                    5,                              // ResourceId
+                },
+                TIMER_CAP_ONE_SHOT      |           // Capabilities
+                TIMER_CAP_PERIODIC      |
+                    TIMER_CAP_ALWAYS_ON |
+                    TIMER_CAP_DRIVES_IRQ,
+                32,                                 // Timer width (bits)
+                EPIT_CLOCK_LOW_FREQ,                // Source
+                SOC_LOW_FREQ_REF_HZ,                // Frequency
+                1,                                  // Frequency scale
+                CSP_BASE_REG_PA_EPIT2,              // 32 bit Physical address
+                TIMER_ADDRES_SIZE,                  // Size of timer address space
+                IRQ_EPIT2,                          // Interrupt
+
+            }, // Timer1 (EPIT2)
+
+#if !defined(CPU_IMX6SDL)
+
+            // SNVS LP Real Time Counter
+            {
+                {
+                    sizeof(RD_TIMER),               // Resource Descriptor Length
+                    EFI_ACPI_CSRT_RD_TYPE_TIMER,    // Resource Type
+                    EFI_ACPI_CSRT_RD_SUBTYPE_TIMER, // Resource Subtype
+                    6,                              // ResourceId
+                },
+                TIMER_CAP_UP_COUNTER |              // Capabilities
+                    TIMER_CAP_READABLE |
+                    TIMER_CAP_ALWAYS_ON,
+                47,                                 // Timer width (bits)
+                0,                                  // Source (NA)
+                SOC_LOW_FREQ_REF_HZ,                // Frequency
+                1,                                  // Frequency scale
+                IMX_SNVS_BASE,                      // 32 bit Physical address
+                TIMER_ADDRES_SIZE,                  // Size of timer address space
+                IMX_SNVS_IRQ,                       // Interrupt
+
+            }, // SNVS LPRTC
+#endif
+        } // Timers
+
+    }, // TimerResourceGroup
+
+#ifndef CONFIG_L2CACHE_OFF
+    //------------------------------------------------------------------------
+    // L2CacheResourceGroup
+    //------------------------------------------------------------------------
+    {
+        // L2 cache group header
+        {
+            sizeof(RG_L2_CACHE),            // Resource Group Length
+            SIGNATURE_32('A','R','M','H'),  // VendorId
+            SIGNATURE_32('A','R','M','H'),  // SubvendorId
+            0x0310,                         // DeviceId
+            0,                              // SubdeviceId
+            0,                              // Revision
+            0,                              // Reserved
+            0                               // No shared info
+
+        }, // L2 cache group header
+
+        //------------------------------------------------------------------------
+        // PL310 L2 cache controller
+        //------------------------------------------------------------------------
+        {
+            {
+                sizeof(RD_L2_CACHE),            // Resource Descriptor Length
+                EFI_ACPI_CSRT_RD_TYPE_CACHE,    // Resource Type
+                EFI_ACPI_CSRT_RD_SUBTYPE_CACHE, // Resource Subtype
+                0,                              // UID
+            },
+            CSRT_PL310_VERSION_2,               // Version
+            CSRT_PL310_SMC_PROTOCOL,            // Management Protocol
+            CSP_BASE_REG_PA_PL310,              // 64 bit Physical address
+            {                                   // InvokeEnable
+                0,                              // Immediate
+                PSCI_FID_CPU_ON,                // R0
+                L2CACHE_SMC_R1,                 // R1
+                L2CACHE_OP_ENABLE,              // R2
+                0,                              // R3
+                0,                              // R12
+            },
+            {                                   // InvokeDisable
+                0,                              // Immediate
+                PSCI_FID_CPU_ON,                // R0
+                L2CACHE_SMC_R1,                 // R1
+                L2CACHE_OP_DISABLE,             // R2
+                0,                              // R3
+                0,                              // R12
+            },
+            {                                   // InvokeEnableWriteback
+                0,                              // Immediate
+                PSCI_FID_CPU_ON,                // R0
+                L2CACHE_SMC_R1,                 // R1
+                L2CACHE_OP_ENABLE_WRITEBACK,    // R2
+                0,                              // R3
+                0,                              // R12
+            },
+            {                                   // InvokeDisableWriteback
+                0,                              // Immediate
+                PSCI_FID_CPU_ON,                // R0
+                L2CACHE_SMC_R1,                 // R1
+                L2CACHE_OP_DISABLE_WRITEBACK,   // R2
+                0,                              // R3
+                0,                              // R12
+            },
+            {                                   // InvokeEnableWFLZ
+                0,                              // Immediate
+                PSCI_FID_CPU_ON,                // R0
+                L2CACHE_SMC_R1,                 // R1
+                L2CACHE_OP_ENABLE_WFLZ,         // R2
+                0,                              // R3
+                0,                              // R12
+            },
+        }, // L2 cache controller (PL310)
+    },
+#endif
+
+    //------------------------------------------------------------------------
+    // SdmaResourceGroup
+    //------------------------------------------------------------------------
+    {
+        // SDMA group header
+        {
+            sizeof(RG_SDMA),                // Resource Group Length
+            EFI_ACPI_VENDOR_ID,             // VendorId
+            0,                              // SubvendorId
+            EFI_ACPI_CSRT_DEVICE_ID_DMA,    // DeviceId
+            0,                              // SubdeviceId
+            0,                              // Revision
+            0,                              // Reserved
+            0                               // No shared info
+
+        }, // SDMA group header
+
+        //------------------------------------------------------------------------
+        // SDMA controller resource
+        //------------------------------------------------------------------------
+        {
+            {
+                sizeof(RD_SDMA),                            // Resource Descriptor Length
+                EFI_ACPI_CSRT_RD_TYPE_DMA,                  // Resource Type
+                EFI_ACPI_CSRT_RD_SUBTYPE_DMA_CONTROLLER,    // Resource Subtype
+                0,                                          // UID
+            },
+            0,                                    // IMX_CHIP_TYPE (not used)
+            CSP_BASE_REG_PA_SDMA,                 // SDMA registers base physical address
+            IOMUXC_GPR_BASE_ADDRESS,              // IoMuxGPR0 physical address
+            IRQ_SDMA,                             // IRQ number
+            IMX_SDMA_CORE_CLOCK_TWICE_CORE_FREQ,  // DMA/SDMA Core Clock Ratio:
+        }, // SDMA controller
+    }
+}; // CSRT
+
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+{
+  //
+  // Reference the table being generated to prevent the optimizer from removing the
+  // data structure from the executable
+  //
+  return (VOID*)&Csrt;
+}
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Dbg2.aslc b/Silicon/NXP/iMX6Pkg/AcpiTables/Dbg2.aslc
new file mode 100644
index 000000000000..4655bb099ec1
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Dbg2.aslc
@@ -0,0 +1,148 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Platform.h>
+#include "iMX6.h"
+
+//
+// DBG2 Definitions
+//
+
+// Ensure proper structure formats
+#pragma pack (1)
+
+typedef enum
+{
+    DBG2_TYPE_SERIAL = 0x8000,
+    DBG2_TYPE_1394,
+    DBG2_TYPE_USB,
+    DBG2_TYPE_NET
+} DBG2_PORT_TYPE;
+
+#define EFI_ACPI_DEBUG_PORT_2_TABLE_REVISION 0x00000000
+
+#define UART_NAME_SPACE_STRING_LENGTH               sizeof("\\_SB.UAR1")
+
+#define UART_IMX6_UART_ADDRESS_SIZE       0x000000BC
+
+#if FixedPcdGet32(PcdKdUartInstance) == 1
+#define KD_UART_BASE_ADDR CSP_BASE_REG_PA_UART1
+#define KD_UART_ACPI_PATH "\\_SB.UAR1"
+#elif FixedPcdGet32(PcdKdUartInstance) == 2
+#define KD_UART_BASE_ADDR CSP_BASE_REG_PA_UART2
+#define KD_UART_ACPI_PATH "\\_SB.UAR2"
+#elif FixedPcdGet32(PcdKdUartInstance) == 3
+#define KD_UART_BASE_ADDR CSP_BASE_REG_PA_UART3
+#define KD_UART_ACPI_PATH "\\_SB.UAR3"
+#elif FixedPcdGet32(PcdKdUartInstance) == 4
+#define KD_UART_BASE_ADDR CSP_BASE_REG_PA_UART4
+#define KD_UART_ACPI_PATH "\\_SB.UAR4"
+#elif FixedPcdGet32(PcdKdUartInstance) == 5
+#define KD_UART_BASE_ADDR CSP_BASE_REG_PA_UART5
+#define KD_UART_ACPI_PATH "\\_SB.UAR5"
+#else
+#error "Invalid PcdKdUartInstance. Must be 1, 2, 3, 4, or 5"
+#endif
+
+//
+// ACPI 5.0 DBG2 structure
+//
+
+typedef struct
+{
+    EFI_ACPI_DESCRIPTION_HEADER   Header;
+    UINT32                        OffsetDbgDeviceInfo;
+    UINT32                        NumberDbgdeviceInfo;
+} EFI_ACPI_5_0_DEBUG_PORT_2_TABLE_HEADER;
+
+typedef struct {
+    UINT8 Revision;
+    UINT16 Length;
+    UINT8 NumberofGenericAddressRegisters;
+    UINT16 NameSpaceStringLength;
+    UINT16 NameSpaceStringOffset;
+    UINT16 OemDataLength;
+    UINT16 OemDataOffset;
+    UINT16 PortType;
+    UINT16 PortSubtype;
+    UINT16 Reserved;
+    UINT16 BaseAddressRegisterOffset;
+    UINT16 AddressSizeOffset;
+} DEBUG_DEVICE_INFO;
+
+typedef struct {
+    DEBUG_DEVICE_INFO DeviceInfo;
+    EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister;
+    UINT32 AddressSize;
+    char NameSpaceString[UART_NAME_SPACE_STRING_LENGTH];
+} DEBUG_DEVICE_INFO_UART;
+
+typedef struct {
+    EFI_ACPI_5_0_DEBUG_PORT_2_TABLE_HEADER Header;
+    DEBUG_DEVICE_INFO_UART Uart;
+} EFI_ACPI_5_0_DEBUG_PORT_2_TABLE;
+
+#pragma pack ()
+
+//
+// Debug Port 2 table
+//
+
+EFI_ACPI_5_0_DEBUG_PORT_2_TABLE Dbg2 =
+{
+    {                                                               // Header
+        {                                                           // Header
+            EFI_ACPI_5_0_DEBUG_PORT_2_TABLE_SIGNATURE,              // Signature "DBG2"
+            sizeof (EFI_ACPI_5_0_DEBUG_PORT_2_TABLE),               // Length
+            EFI_ACPI_DEBUG_PORT_2_TABLE_REVISION,                   // Revision
+            EFI_ACPI_5_0_UNDEFINED,                                 // Checksum - will be updated at runtime
+            EFI_ACPI_OEM_ID,                                        // OEM ID[6]
+            EFI_ACPI_OEM_TABLE_ID,                                  // OEM Table ID
+            EFI_ACPI_OEM_REVISION,                                  // OEM Revision
+            EFI_ACPI_CREATOR_ID,                                    // Creator ID
+            EFI_ACPI_CREATOR_REVISION                               // Creator Revision
+      },
+      sizeof(EFI_ACPI_5_0_DEBUG_PORT_2_TABLE_HEADER),               // OffsetDbgDeviceinfo
+      1,                                                            // NumberDbgDeviceInfo
+    },
+    {                                                               // Uart
+        {                                                           // DeviceInfo
+            EFI_ACPI_RESERVED_BYTE,                                 // Revision
+            sizeof(DEBUG_DEVICE_INFO_UART),                         // Length
+            1,                                                      // NumberofGenericAddressRegisters
+            UART_NAME_SPACE_STRING_LENGTH,                          // NameSpaceStringLength
+            OFFSET_OF(DEBUG_DEVICE_INFO_UART, NameSpaceString),     // NameSpaceStringOffset
+            0,                                                      // OemDataLength
+            EFI_ACPI_RESERVED_WORD,                                 // OemDataOffset
+            DBG2_TYPE_SERIAL,                                       // PortType
+            DBG_PORT_SUBTYPE_IMX6,                                  // PortSubtype 000Ch
+            EFI_ACPI_RESERVED_WORD,                                 // Reserved
+            OFFSET_OF(DEBUG_DEVICE_INFO_UART, BaseAddressRegister), // BaseAddressRegisterOffset
+            OFFSET_OF(DEBUG_DEVICE_INFO_UART, AddressSize),         // AddressSizeOffset
+        },
+        {                                                           // BaseAddressRegister
+            EFI_ACPI_5_0_SYSTEM_MEMORY,                             // AddressSpaceId
+            0x20,                                                   // RegisterBitWidth = 32
+            0,                                                      // RegisterBitOffset = 0
+            0x20,                                                   // AccessSize = 32
+            KD_UART_BASE_ADDR,                                      // Address
+        },
+        UART_IMX6_UART_ADDRESS_SIZE,                                // AddressSize
+        KD_UART_ACPI_PATH,                                          // NameSpaceString
+    },
+};
+
+void * ReferenceAcpiTable(void) {
+    return (void *) &Dbg2;
+}
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Common.inc b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Common.inc
new file mode 100644
index 000000000000..909b08475f6b
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Common.inc
@@ -0,0 +1,112 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+//
+// IMX alternate settings codes
+//
+
+#define IMX_ALT0 0x0
+#define IMX_ALT1 0x1
+#define IMX_ALT2 0x2
+#define IMX_ALT3 0x3
+#define IMX_ALT4 0x4
+#define IMX_ALT5 0x5
+#define IMX_ALT6 0x6
+#define IMX_ALT7 0x7
+
+//
+// IMX SDMA request lines.
+// These are logical values, the mapping to the SOC
+// actual DMA request lines are done in the HAL extension.
+//
+
+#define SDMA_REQ_VPU 0
+#define SDMA_REQ_IPU2 1
+#define SDMA_REQ_IPU1 2
+#define SDMA_REQ_HDMI_AUDIO 3
+#define SDMA_REQ_ECSPI1_RX 4
+#define SDMA_REQ_ECSPI1_TX 5
+#define SDMA_REQ_ECSPI2_RX 6
+#define SDMA_REQ_ECSPI2_TX 7
+#define SDMA_REQ_ECSPI3_RX 8
+#define SDMA_REQ_ECSPI3_TX 9
+#define SDMA_REQ_ECSPI4_RX 10
+#define SDMA_REQ_ECSPI4_TX 11
+#define SDMA_REQ_ECSPI5_RX 12
+#define SDMA_REQ_ECSPI5_TX 13
+#define SDMA_REQ_I2C1_RX 14
+#define SDMA_REQ_I2C1_TX 15
+#define SDMA_REQ_I2C2_RX 16
+#define SDMA_REQ_I2C2_TX 17
+#define SDMA_REQ_I2C3_RX 18
+#define SDMA_REQ_I2C3_TX 19
+#define SDMA_REQ_UART1_RX 20
+#define SDMA_REQ_UART1_TX 21
+#define SDMA_REQ_UART2_RX 22
+#define SDMA_REQ_UART2_TX 23
+#define SDMA_REQ_UART3_RX 24
+#define SDMA_REQ_UART3_TX 25
+#define SDMA_REQ_UART4_RX 26
+#define SDMA_REQ_UART4_TX 27
+#define SDMA_REQ_UART5_RX 28
+#define SDMA_REQ_UART5_TX 29
+#define SDMA_REQ_SPDIF_RX 30
+#define SDMA_REQ_SPDIF_TX 31
+#define SDMA_REQ_EPIT1 32
+#define SDMA_REQ_EPIT2 33
+#define SDMA_REQ_GPT 34
+#define SDMA_REQ_ASRC_RXA 35
+#define SDMA_REQ_ASRC_RXB 36
+#define SDMA_REQ_ASRC_RXC 37
+#define SDMA_REQ_ASRC_TXA 38
+#define SDMA_REQ_ASRC_TXB 39
+#define SDMA_REQ_ASRC_TXC 40
+#define SDMA_REQ_ESAI_RX 41
+#define SDMA_REQ_ESAI_TX 42
+#define SDMA_REQ_ASRC_TXA_2_ESAI_TX 43
+#define SDMA_REQ_ASRC_TXB_2_ESAI_TX 44
+#define SDMA_REQ_ASRC_TXC_2_ESAI_TX 45
+#define SDMA_REQ_SSI1_RX1 46
+#define SDMA_REQ_SSI1_TX1 47
+#define SDMA_REQ_SSI1_RX0 48
+#define SDMA_REQ_SSI1_TX0 49
+#define SDMA_REQ_SSI2_RX1 50
+#define SDMA_REQ_SSI2_TX1 51
+#define SDMA_REQ_SSI2_RX0 52
+#define SDMA_REQ_SSI2_TX0 53
+#define SDMA_REQ_SSI3_RX1 54
+#define SDMA_REQ_SSI3_TX1 55
+#define SDMA_REQ_SSI3_RX0 56
+#define SDMA_REQ_SSI3_TX0 57
+#define SDMA_REQ_EXT1 58
+#define SDMA_REQ_EXT2 59
+#define SDMA_REQ_UART6_RX 60
+#define SDMA_REQ_UART6_TX 61
+#define SDMA_REQ_ADC1 62
+#define SDMA_REQ_ADC2 63
+#define SDMA_REQ_I2C4_RX 64
+#define SDMA_REQ_I2C4_TX 65
+#define SDMA_REQ_CSI1 66
+#define SDMA_REQ_CSI2 67
+#define SDMA_REQ_PXP 68
+#define SDMA_REQ_LCDIF1 69
+#define SDMA_REQ_LCDIF2 70
+#define SDMA_REQ_QSPI1_RX 71
+#define SDMA_REQ_QSPI1_TX 72
+#define SDMA_REQ_QSPI2_RX 73
+#define SDMA_REQ_QSPI2_TX 74
+#define SDMA_REQ_SAI1_TX 75
+#define SDMA_REQ_SAI1_RX 76
+#define SDMA_REQ_SAI2_TX 77
+#define SDMA_REQ_SAI2_RX 78
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Enet.inc b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Enet.inc
new file mode 100644
index 000000000000..08f9c6b1b3a2
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Enet.inc
@@ -0,0 +1,111 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+Device (ENET)
+{
+    Name (_HID, "FSCL000D")
+    Name (_UID, 0x0)
+    Method (_STA)
+    {
+        Return(0xF)
+    }
+    Method (_CRS, 0x0, NotSerialized) {
+        Name (RBUF, ResourceTemplate () {
+            MEMORY32FIXED(ReadWrite, 0x02188000, 0x4000, )                      // ENET MAC Core Base address
+            Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 150 }   // ENET MAC 0 Core IRQ
+            Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 151 }   // ENET MAC 0 1588 Timer interrupt
+            GpioInt (Level, ActiveHigh, Shared, PullDefault, 0, "\\_SB.GPIO",) { 6 }  // Errata ERR006687: workaround for GPIO interrupt to connect Enet interrupt to the GPC
+        })
+        Return(RBUF)
+    }
+    Name (MAC, Buffer (6) {})
+    CreateDWordField(MAC, 0x00, MACL)
+    CreateWordField(MAC, 0x04, MACH)
+
+    //
+    // Device Specific Method takes 4 args:
+    //  Arg0 : Buffer containing a UUID [16 bytes]
+    //  Arg1 : Integer containing the Revision ID
+    //  Arg2 : Integer containing the Function Index
+    //  Arg3 : Package that contains function-specific arguments
+    //
+    Method (_DSM, 0x4, NotSerialized) {
+        switch(ToBuffer(Arg0))
+        {
+            // iMX Enet interface identifier
+            case(ToUUID("4EBBCB9D-4087-4791-80BD-8F8C08024206"))
+            {
+                // Function selector
+                switch(Arg2)
+                {
+                    //
+                    // Function 0: Query support
+                    //   Bit  Description
+                    //   ---  -------------------------------
+                    //     0  Get property (Function 0)
+                    //     1  Enet PHY address on MDIO bus (Function 1)
+                    //     2  Get Mac Address (Function 2)
+                    //     3  Get MDIO BAse Address (Function 3)
+                    //
+                    case(0)
+                    {
+                        switch(Arg1)
+                        {
+                            // Revision 0:
+                            case(0)
+                            {
+                                // Functions {0,1,2} supported
+                                Return(Buffer(){0x07});
+                            }
+                            default
+                            {
+                                Return(Buffer(){0x00});
+                            }
+                        }
+                    }
+
+                    //
+                    // Function 1: Return Enet PHY address on MDIO bus.
+                    //
+                    case(1)
+                    {
+                        Return(0x00);
+                    }
+
+                    //
+                    // Function 2: Return Mac Address
+                    //
+                    case(2)
+                    {
+                        if (LEqual(SIGN, 0x474C424C)) {
+                            if (LEqual(REVN, 1)) {
+                                if (Lequal(MC0V, 1)) {
+                                    Store(MC0L, MACL);
+                                    Store(MC0H, MACH);
+                                    Return (MAC)
+                                }
+                            }
+                        }
+                        Return(Buffer(){0x00, 0x00, 0x00, 0x00, 0x00, 0x00});
+                    }
+
+                    default
+                    {
+                        Return(Buffer(){0x00});
+                    }
+                }
+            }
+        }
+    }
+}
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Gfx.inc b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Gfx.inc
new file mode 100644
index 000000000000..75aca8f033d0
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Gfx.inc
@@ -0,0 +1,58 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+Device (VPU0)
+{
+   Name (_HID, "FSCL0009")
+   Name (_UID, 0x0)
+   Method (_STA)
+   {
+       Return(0x0)
+   }
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x02040000, 0x3C000, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 35 }    // JPEG codec interrupt request
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 44 }    // VPU interrupt request
+       })
+       Return(RBUF)
+   }
+}
+
+//
+// Description: Graphics Processing Unit (GPU)
+//
+
+Device(GPU0)
+{
+   Name (_HID, "VERI2000")
+   Name (_CID, "VERI2000")
+   Name (_UID, 0)
+   Method (_STA)
+   {
+      Return(0xf)
+   }
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x00130000, 0x4000, )                      //GPU 3D (GC2000)
+           MEMORY32FIXED(ReadWrite, 0x00134000, 0x4000, )                      //GPU 2D (GC320)
+           MEMORY32FIXED(ReadWrite, 0x02600000, 0x400000, )                    //IPU Base
+           MEMORY32FIXED(ReadWrite, 0x00120000, 0x9000, )                      //HDMI PHY
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 41 }    //GC2000
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 42 }    //GC320
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 38 }    //IPU1 sync interrupt request
+       })
+       Return(RBUF)
+   }
+}
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Gpio.inc b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Gpio.inc
new file mode 100644
index 000000000000..c316b0aef2b1
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Gpio.inc
@@ -0,0 +1,47 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+Device (GPIO)
+{
+   Name (_HID, "FSCL0003")
+   Name (_UID, 0x0)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x0209C000, 0x1C000, ) // GPIO1-7
+           MEMORY32FIXED(ReadWrite, 0x020E0000, 0x4000, )  // IOMUXC
+
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 98, 99 }     // GPIO1 0-15, 16-31
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 100, 101 }   // GPIO2 0-15, 16-31
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 102, 103 }   // GPIO3 0-15, 16-31
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 104, 105 }   // GPIO4 0-15, 16-31
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 106, 107 }   // GPIO5 0-15, 16-31
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 108, 109 }   // GPIO6 0-15, 16-31
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 110, 111 }   // GPIO7 0-15, 16-31
+       })
+       Return(RBUF)
+   }
+
+   Name (_DSD, Package()
+   {
+       ToUUID ("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301"),
+       Package ()
+       {
+           Package (2) { "SocType", SOC_TYPE },
+       }
+   })
+}
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-I2c.inc b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-I2c.inc
new file mode 100644
index 000000000000..42c69a6d3c97
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-I2c.inc
@@ -0,0 +1,64 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+Device (I2C1)
+{
+   Name (_HID, "FSCL0004")
+   Name (_UID, 0x1)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x021A0000, 0x14, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 68 }
+       })
+       Return(RBUF)
+   }
+}
+
+Device (I2C2)
+{
+   Name (_HID, "FSCL0004")
+   Name (_UID, 0x2)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x021A4000, 0x14, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 69 }
+       })
+       Return(RBUF)
+   }
+}
+
+Device (I2C3)
+{
+   Name (_HID, "FSCL0004")
+   Name (_UID, 0x3)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x021A8000, 0x14, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 70 }
+       })
+       Return(RBUF)
+   }
+}
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-PCIe.inc b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-PCIe.inc
new file mode 100644
index 000000000000..9f7354a7cf6f
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-PCIe.inc
@@ -0,0 +1,483 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+Device(PCI0)
+{
+   //
+   // PCIe root complex must be enumerated by PnP ID PNP0A08
+   // as a PCIe requirement for ARM.
+   // ACPI spec section 6.1.5.
+   //
+
+   Name(_HID,"PNP0A08")
+
+   //
+   // The _UID value provides a way of uniquely identifying a device
+   // in the case where more than one instance of a specific device
+   // is implemented with the same _HID/_CID. For systems with a
+   // single root complex, this is usually just 0. For systems with
+   // multiple root complexes, this should be different for each
+   // root complex.
+   // ACPI spec section 6.1.12
+   //
+
+   Name(_UID, 0)
+   Name(_STR, Unicode("PCIe 0 Device"))
+
+   //
+   // Declare the base bus number, which is the bus number of the root
+   // bus in this root complex. This is usually 0, but need not be.
+   // For root complexes supporting multiple root busses, this should
+   // be the lowest numbered root bus.
+   // ACPI spec section 6.5.5
+   //
+
+   Name(_BBN, 0)
+
+   //
+   // Declare the segment number of this root complex. Most systems only
+   // have one segment, which is numbered 0.
+   // ACPI spec section 6.5.6.
+   //
+
+   Name(_SEG, 0)
+
+   //
+   // PCIE_PL memory map, refer to chapter 48.12
+   //
+   OperationRegion (PLGC, SystemMemory, 0x01FFC700, 0x220)
+   Field (PLGC, DWordAcc, NoLock, Preserve)
+   {
+       Offset(0x2C),   // skip to register 0x01FFC72C
+       DBG1, 32,       // PCIE_PL_DEBUG1
+   }
+
+   //
+   // IOMUXC memory map, refer to chapter 36.4.2
+   //
+   OperationRegion (IMXC, SystemMemory, 0x020E0000, 0x4000)
+   Field (IMXC, DWordAcc, NoLock, Preserve)
+   {
+       Offset(0x04),   // skip to register 0x020E0004
+       GPR1, 32,       // IOMUXC_GPR1
+   }
+
+   //
+   // PCIe is only available if PCIe PHY reference clock is enabled and link is up
+   //
+   Method (_STA)
+   {
+       Name (LNK, 0x0);    // Declare read variable
+       Name (GPR, 0x0);    // Declare read variable
+
+       Store(GPR1, GPR);   // read IOMUXC_GPR1 register
+
+       //
+       // Check if the PCIe PHY reference clock is enabled
+       //
+       If(LNotEqual(And(GPR, 0x00010000), 0x00010000))
+       {
+           Return(0x0)
+       }
+
+       Store(DBG1, LNK);   // read PCIE_PL_DEBUG1 register
+
+       //
+       // Check if link is already up and is not in training - 48.12.12
+       //  Bit4  : [36]: xmlh_link_up LTSSM reports PHY link up
+       //  Bit29  : [61]: xmlh_link_in_training LTSSM performing link training
+       //
+       If(LAnd(And(DBG1, 0x00000010), Lequal(And(DBG1, 0x20000000), 0x00)))
+       {
+           Return(0xF)
+       }
+       else
+       {
+           Return(0x0)
+       }
+   }
+
+   //
+   // Declare the resources assigned to this root complex.
+   //
+   Method (_CRS, 0, Serialized)
+   {
+
+       //
+       // Declare a ResourceTemplate buffer to return the resource
+       // requirements from _CRS.
+       // ACPI spec section 19.5.109
+       //
+
+       Name (RBUF, ResourceTemplate ()
+       {
+           //
+           // Declare the range of bus numbers assigned to this root
+           // complex. There would be 2 busses the PCI-PCI bridge would
+           // be bus 0 and the attached PCI device is bus 1. So set the
+           // minimum bus as 0 and the maximum bus number will be 1
+           // with a total of 2 busses.
+           // ACPI spec section 19.5.141
+           //
+
+           WordBusNumber (
+               ResourceProducer, // Specify bus ranged is passed to child devices
+               MinFixed,         // Specify min address is fixed
+               MaxFixed,         // Specify max address is fixed
+               PosDecode,        // Positive decode of bus number
+               0,                // AddressGranularity 2 power of 0
+               0,                // AddressMinimum - Minimum Bus Number
+               1,                // AddressMaximum - Maximum Bus Number
+               0,                // AddressTranslation - Set to 0
+               2)                // RangeLength - Number of Busses
+
+
+           //
+           // PCI memory space
+           //
+           Memory32Fixed(ReadWrite, 0x01100000, 0x00E00000, )
+       })
+
+       Return(RBUF)
+   }
+
+   //
+   // Declare the PCI Routing Table.
+   // This defines SPI mappings of the four line-based interrupts
+   // associated with the root complex and hierarchy below it.
+   // ACPI spec section 6.2.12
+   //
+   Name(_PRT, Package()
+   {
+
+       //
+       // Routing for device 0, all functions.
+       // Note: ARM doesn't support LNK nodes, so the third param
+       // is 0 and the fourth param is the SPI number of the interrupt
+       // line.
+       //
+
+       Package() {0x0000FFFF, 0, 0, 155}, // INTA
+       Package() {0x0000FFFF, 1, 0, 154}, // INTB
+       Package() {0x0000FFFF, 2, 0, 153}, // INTC
+       Package() {0x0000FFFF, 3, 0, 152}, // INTD/MSI
+   })
+
+   //
+   // Declare an _OSC (OS Control Hand-off) method which takes 4 arguments.
+   //
+   // Arguments:
+   //   Arg0  A Buffer containing a UUID
+   //   Arg1  An Integer containing a Revision ID of the buffer format
+   //   Arg2  An Integer containing a count of entries in Arg3
+   //   Arg3  A Buffer containing a list of DWORD capabilities
+   // Return Value:
+   //   A Buffer containing a list of capabilities
+   // ACPI spec Section 6.2.10,
+   // PCI FW spec, Section 4.5.
+   //
+
+   Name(SUPP,0) // PCI _OSC Support Field value
+   Name(CTRL,0) // PCI _OSC Control Field value
+   Method(_OSC, 4)
+   {
+
+       //
+       // Look for the PCI Host Bridge Interface UUID.
+       // Section 6.2.10.3
+       //
+
+       //
+       // Create DWord-addressable fields from the Capabilities Buffer
+       // Create CDW1 outside the test as it's used in the else clause.
+       // The first DWORD in the _OSC Capabilities Buffer contains bits
+       // that are generic to _OSC
+       // PCI Firmware Specification - 4.5.1.
+       //
+       // ACPI - 6.2.10
+       // CDW return value information
+       // Bit 0 - Reserved (not used)
+       // Bit 1 - _OSC failure. Platform Firmware was unable to process the request or query
+       // Bit 2 - Unrecognized UUID
+       // Bit 3 - Unrecognized Revision
+       // Bit 4 - Capabilities Masked
+       // All others reserved
+       //
+
+       CreateDWordField(Arg3,0,CDW1)
+       If(LEqual(Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")))
+       {
+           CreateDWordField(Arg3,4,CDW2)
+           CreateDWordField(Arg3,8,CDW3)
+
+           //
+           // Save Capabilities DWord 2 & 3
+           // The second DWORD in the _OSC Capabilities Buffer is the Support Field
+           // The third DWORD in the _OSC Capabilities Buffer is the Control Field
+           // PCI Firmware Specification - 4.5.1.
+           // Supported feature should be set in the control field
+           //
+           // Support field
+           // Bit 0 - Extended PCI Config operation regions supported
+           // Bit 1 - Active State Power Management supported
+           // Bit 2 - Clock Power Management Capability supported
+           // Bit 3 - PCI Segment Groups supported
+           // Bit 4 - MSI supported
+           // Bit 5 - Optimized Buffer Flush and Fill supported
+           // Bit 6 - ASPM Optionality supported
+           //
+           // Control field
+           // Bit 0 - PCI Express Native Hot Plug control
+           // Bit 1 - SHPC Native Hot Plug control
+           // Bit 2 - PCI Express Native Power Management Events control
+           // Bit 3 - PCI Express Advanced Error Reporting control
+           // Bit 4 - PCI Express Capability Structure control
+           // Bit 5 - Latency Tolerance Reporting control
+           //
+
+           Store(CDW2,SUPP)
+           Store(CDW3,CTRL)
+
+           //
+           // Only allow native hot plug control if OS supports:
+           //  ASPM
+           //  Clock PM
+           //  MSI/MSI-X
+           //
+           If(LNotEqual(And(SUPP, 0x16), 0x16))
+           {
+
+               //
+               // Mask bit 0 (and undefined bits)
+               //
+
+               And(CTRL,0x1E,CTRL)
+           }
+
+           //
+           // Spec does not mention if standard hot plug is supported
+           // so unmask the bit
+           //
+
+           And(CTRL,0x1D,CTRL)
+
+           //
+           // Check for unknown revision.
+           //
+
+           If(LNotEqual(Arg1,One))
+           {
+               Or(CDW1,0x08,CDW1)
+           }
+
+           //
+           // Check if capabilities bits were masked.
+           //
+
+           If(LNotEqual(CDW3,CTRL))
+           {
+               Or(CDW1,0x10,CDW1)
+           }
+
+           //
+           // Update DWORD3 in the buffer.
+           //
+
+           Store(CTRL,CDW3)
+           Return(Arg3)
+       }
+       else
+       {
+           //
+           // Unrecognized UUID
+           //
+           Or(CDW1,4,CDW1)
+           Return(Arg3)
+       }
+
+   } // End _OSC
+
+   //
+   // Declare a _DSM method for various functions called by the OS.
+   // See the APCI spec, Section 9.14.1,
+   // and the PCI FW spec, Section 4.6.
+   // See also:
+   // http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/PCI-rsc.doc
+   //
+
+   Method(_DSM, 0x4, Serialized)
+   {
+
+       //
+       // Match against the _DSM PCI UUID. PCI firmware spec - 4.6.1
+       //     Arg0 - UUID
+       //     Arg1 - Revision ID
+       //     Arg2 - Function Index
+       //     Arg3 - Empty Package
+       //
+       // Revision 1 & 2
+       //     Function 1 - PCI Express Slot Information
+       //     Function 2 - PCI Express Slot Number
+       //     Function 3 - Vendor-specific Token ID
+       //     Function 4 - PCI Bus Capabilities
+       //     Function 5 - Ignore PCI Boot Configuration
+       // Revision 2 only
+       //     Function 6 - LTR Maximum Latency
+       //     Function 7 - Express device under OS
+       //
+       If(LEqual(Arg0,ToUUID("E5C937D0-3553-4d7a-9117-EA4D19C3434D")))
+       {
+
+           switch(ToInteger(Arg2))
+           {
+               //
+               // Function 0: Return supported functions as a bit-field
+               // with one bit for each supported function.
+               // Bit 0 must always be set, as that represents
+               // function 0 (which is what is being called here).
+               // Support for different functions may depend on
+               // the revision ID of the interface, passed as Arg1.
+               //
+
+               //
+               // Function 0: Get supported functions
+               //
+               case(0)
+               {
+                   //
+                   // Functions 0,1,5 are supported.
+                   //
+                   if (LEqual(Arg1, 1))
+                   {
+                       return (Buffer() {0x23})
+                   }
+
+                   //
+                   // Functions 0,1,5,7 are supported.
+                   //
+                   if (LEqual(Arg1, 2))
+                   {
+                       return (Buffer() {0xA3})
+                   }
+
+                   //
+                   // Functions 0,1,5,7 are supported for
+                   // future revision. Expect backward compatibility
+                   //
+                   return (Buffer() {0xA3})
+               }
+
+               //
+               // Function 1: PCI Express Slot Information
+               // PCI firmware spec - 4.6.1
+               //
+               case(1)
+               {
+                   //
+                   // Package item 1:
+                   //    0: Failure
+                   //    1: Success
+                   // Package item 2:
+                   //  Integer 1:Bit Position
+                   //        0 Supports x1
+                   //        1 Supports x2
+                   //        2 Supports x4
+                   //        3 Supports x8
+                   //        4 Supports x12
+                   //        5 Supports x16
+                   //  Integer 2:
+                   //        0h Unknown
+                   //        1h PCI Express Card Slot
+                   //        2h PCI Express Server I/O Module Slot
+                   //        3h PCI Express ExpressCard* Slot
+                   //        4h PCI Express Mini Card Slot
+                   //        5h PCI Express Wireless Form Factor Slot
+                   //        Others Reserved
+                   //  Integer 3:
+                   //        0 SMBus signal
+                   //        1 WAKE# signal
+                   //
+                   return ( Package(2) {
+                       // Status success (1)
+                       0x01,
+                       // Slot information
+                       Package() {
+                           0, // Supports x1
+                           4, // PCI Express Mini Card Slot
+                           1  // Supported signals (no SMBus, WAKE#)
+                           }
+                       })
+               }
+
+               //
+               // Function 5: Ignore PCI Boot Configurations
+               // PCI firmware spec - 4.6.5
+               //
+               case(5)
+               {
+                   //
+                   // Always allow OS to rebalance
+                   //
+                   return (0x01)
+               }
+
+               //
+               // Function 7: Naming a PCI or PCI Express Device Under
+               //             Operating Systems
+               // PCI firmware spec - 4.6.7
+               //
+               case(7)
+               {
+                   // Verify revision 2
+                   if (LEqual(Arg1, 2))
+                   {
+                       // PCI Express Slot Parsing
+                       Return ( Package(2) {
+                           1,            // Instance of the enumeration
+                           "PCIe Slot 1" // String name which matches the label on the chassis
+                           })
+                   }
+               }
+
+           } // switch Arg2
+       }
+
+       //
+       // If not one of the function identifiers we recognize, then return a buffer
+       // with bit 0 set to 0 indicating no functions supported.
+       //
+
+       return(Buffer(){0})
+   }
+
+   //
+   // Root Port 0 Device within the Root Complex.
+   //
+
+   Device(RP0) {
+
+       //
+       // Device 0, Function 0.
+       //
+
+       Name(_ADR, 0)
+
+       //
+       // Supports wake
+       //
+       Name(_S0W, 4)
+
+   }
+
+} // PCI0
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Platform.inc b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Platform.inc
new file mode 100644
index 000000000000..b0afab2d0090
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Platform.inc
@@ -0,0 +1,121 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+OperationRegion(GLBL,SystemMemory,0x10817000,0x10)
+Field(GLBL, AnyAcc, Nolock, Preserve)
+{
+  Offset(0),        // Miscellaneous Dynamic Registers:
+  SIGN, 32,         // Global Page Signature 'GLBL'
+  REVN, 8,          // Revision
+      , 8,          // Reserved
+      , 8,          // Reserved
+      , 8,          // Reserved
+  M0ID, 8,          // MAC 0 ID
+  MC0V, 8,          // MAC 0 Valid
+  MC0L, 32,         // MAC Address 0 Low
+  MC0H, 16,         // MAC Address 0 High
+}
+
+//
+// Description: This is a Processor #0 Device
+//
+
+Device (CPU0)
+{
+   Name (_HID, "ACPI0007")
+   Name (_UID, 0x0)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+}
+
+//
+// Description: This is a Processor #1 Device
+//
+
+Device (CPU1)
+{
+   Name (_HID, "ACPI0007")
+   Name (_UID, 0x1)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+}
+
+//
+// Description: This is a Processor #2 Device
+//
+
+Device (CPU2)
+{
+   Name (_HID, "ACPI0007")
+   Name (_UID, 0x2)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+}
+
+//
+// Description: This is a Processor #3 Device
+//
+
+Device (CPU3)
+{
+   Name (_HID, "ACPI0007")
+   Name (_UID, 0x3)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+}
+
+//
+// Description: Timers HAL extension
+//
+
+Device (EPIT)
+{
+   Name (_HID, "FSCL0001")
+   Name (_UID, 0x0)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+}
+
+//
+// Description: Platform Extension Plugin
+//
+
+Device (PEP0)
+{
+   Name (_HID, "FSCL0002")
+   Name (_UID, 0x0)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 119 } // CCM request 1
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 120 } // CCM request 2
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 121 } // GPC request 1
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) { 58 }  // UART1
+       })
+       Return(RBUF)
+   }
+}
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Pwm.inc b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Pwm.inc
new file mode 100644
index 000000000000..87d602315c2c
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Pwm.inc
@@ -0,0 +1,80 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+Device (PWM1)
+{
+   Name (_HID, "FSCL000E")
+   Name (_UID, 0x1)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x02080000, 0x4000, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 115 }
+       })
+       Return(RBUF)
+   }
+}
+
+Device (PWM2)
+{
+   Name (_HID, "FSCL000E")
+   Name (_UID, 0x2)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x02084000, 0x4000, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 116 }
+       })
+       Return(RBUF)
+   }
+}
+
+Device (PWM3)
+{
+   Name (_HID, "FSCL000E")
+   Name (_UID, 0x3)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x02088000, 0x4000, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 117 }
+       })
+       Return(RBUF)
+   }
+}
+
+Device (PWM4)
+{
+   Name (_HID, "FSCL000E")
+   Name (_UID, 0x4)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x0208C000, 0x4000, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 118 }
+       })
+       Return(RBUF)
+}
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Sdhc.inc b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Sdhc.inc
new file mode 100644
index 000000000000..273e8ea7a8d7
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Sdhc.inc
@@ -0,0 +1,225 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+//
+// uSDHC1
+//
+Device (SDH1)
+{
+   Name (_HID, "FSCL0008")
+   Name (_UID, 0x1)
+
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x02190000, 0x4000, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 54 }
+       })
+       Return(RBUF)
+   }
+
+   Name (_DSD, Package()
+   {
+       ToUUID ("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301"),
+       Package ()
+       {
+           Package (2) { "BaseClockFrequencyHz", 198000000 },  // SDHC Base/Input Clock: 198MHz
+           Package (2) { "Regulator1V8Exist", 0 },             // 1.8V Switching External Circuitry: Not-Implemented
+           Package (2) { "SlotCount", 1 },                     // Number of SD/MMC slots connected on the bus: 1
+           Package (2) { "RegisterBasePA", 0x02190000 }        // Register base physical address
+       }
+   })
+
+   //
+   // Child node to represent the only SD/MMC slot on this SD/MMC bus
+   // In theory an SDHC can be connected to multiple SD/MMC slots at
+   // the same time, but only 1 device will be selected and active at
+   // a time
+   //
+   Device (SD0)
+   {
+       Method (_ADR)
+       {
+         Return (0)
+       }
+
+       Method (_RMV)
+       {
+         Return (0)
+       }
+   }
+}
+
+//
+// uSDHC2
+//
+Device (SDH2)
+{
+   Name (_HID, "FSCL0008")
+   Name (_UID, 0x2)
+
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x02194000, 0x4000, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 55 }
+       })
+       Return(RBUF)
+   }
+
+   Name (_DSD, Package()
+   {
+       ToUUID ("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301"),
+       Package ()
+       {
+           Package (2) { "BaseClockFrequencyHz", 198000000 },  // SDHC Base/Input Clock: 198MHz
+           Package (2) { "Regulator1V8Exist", 0 },             // 1.8V Switching External Circuitry: Not-Implemented
+           Package (2) { "SlotCount", 1 },                     // Number of SD/MMC slots connected on the bus: 1
+           Package (2) { "RegisterBasePA", 0x02194000 }        // Register base physical address
+       }
+   })
+
+   //
+   // Child node to represent the only SD/MMC slot on this SD/MMC bus
+   // In theory an SDHC can be connected to multiple SD/MMC slots at
+   // the same time, but only 1 device will be selected and active at
+   // a time
+   //
+   Device (SD0)
+   {
+       Method (_ADR)
+       {
+         Return (0)
+       }
+
+       Method (_RMV)
+       {
+         Return (0)
+       }
+   }
+}
+
+//
+// uSDHC3
+//
+Device (SDH3)
+{
+   Name (_HID, "FSCL0008")
+   Name (_UID, 0x3)
+
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x02198000, 0x4000, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 56 }
+       })
+       Return(RBUF)
+   }
+
+   Name (_DSD, Package()
+   {
+       ToUUID ("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301"),
+       Package ()
+       {
+           Package (2) { "BaseClockFrequencyHz", 198000000 },  // SDHC Base/Input Clock: 198MHz
+           Package (2) { "Regulator1V8Exist", 0 },             // 1.8V Switching External Circuitry: Not-Implemented
+           Package (2) { "SlotCount", 1 },                     // Number of SD/MMC slots connected on the bus: 1
+           Package (2) { "RegisterBasePA", 0x02198000 }        // Register base physical address
+       }
+   })
+
+   //
+   // Child node to represent the only SD/MMC slot on this SD/MMC bus
+   // In theory an SDHC can be connected to multiple SD/MMC slots at
+   // the same time, but only 1 device will be selected and active at
+   // a time
+   //
+   Device (SD0)
+   {
+       Method (_ADR)
+       {
+         Return (0)
+       }
+
+       Method (_RMV)
+       {
+         Return (0)
+       }
+   }
+}
+
+//
+// uSDHC4
+//
+Device (SDH4)
+{
+   Name (_HID, "FSCL0008")
+   Name (_UID, 0x4)
+
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x0219C000, 0x4000, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 57 }
+       })
+       Return(RBUF)
+   }
+
+   Name (_DSD, Package()
+   {
+       ToUUID ("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301"),
+       Package ()
+       {
+           Package (2) { "BaseClockFrequencyHz", 198000000 },  // SDHC Base/Input Clock: 198MHz
+           Package (2) { "Regulator1V8Exist", 0 },             // 1.8V Switching External Circuitry: Not-Implemented
+           Package (2) { "SlotCount", 1 },                     // Number of SD/MMC slots connected on the bus: 1
+           Package (2) { "RegisterBasePA", 0x0219C000 }        // Register base physical address
+       }
+   })
+
+   //
+   // Child node to represent the only SD/MMC slot on this SD/MMC bus
+   // In theory an SDHC can be connected to multiple SD/MMC slots at
+   // the same time, but only 1 device will be selected and active at
+   // a time
+   //
+   Device (SD0)
+   {
+       Method (_ADR)
+       {
+         Return (0)
+       }
+
+       Method (_RMV)
+       {
+         Return (0)
+       }
+   }
+}
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Spi.inc b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Spi.inc
new file mode 100644
index 000000000000..f80a2e4bcc22
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-Spi.inc
@@ -0,0 +1,98 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+Device (SPI1)
+{
+   Name (_HID, "FSCL0005")
+   Name (_UID, 0x1)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x02008000, 0x4000, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 63 }
+       })
+       Return(RBUF)
+   }
+}
+
+Device (SPI2)
+{
+   Name (_HID, "FSCL0005")
+   Name (_UID, 0x2)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x0200C000, 0x4000, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 64 }
+       })
+       Return(RBUF)
+   }
+}
+
+Device (SPI3)
+{
+   Name (_HID, "FSCL0005")
+   Name (_UID, 0x3)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x02010000, 0x4000, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 65}
+       })
+       Return(RBUF)
+   }
+}
+
+Device (SPI4)
+{
+   Name (_HID, "FSCL0005")
+   Name (_UID, 0x4)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x02014000, 0x4000, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 66 }
+       })
+       Return(RBUF)
+   }
+}
+
+Device (SPI5)
+{
+   Name (_HID, "FSCL0005")
+   Name (_UID, 0x5)
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           MEMORY32FIXED(ReadWrite, 0x02018000, 0x4000, )
+           Interrupt(ResourceConsumer, Level, ActiveHigh, Exclusive) { 67 }
+       })
+       Return(RBUF)
+   }
+}
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-TrEE.inc b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-TrEE.inc
new file mode 100644
index 000000000000..1fea90934949
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Dsdt-TrEE.inc
@@ -0,0 +1,36 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+Device (TREE)
+{
+   Name (_HID, "FSCL000F")
+   Name (_CID, "TrEECSMP")
+   Name (_UID, 0)
+
+   Method (_STA)
+   {
+       Return(0xf)
+   }
+
+   Method (_CRS, 0x0, NotSerialized) {
+       Name (RBUF, ResourceTemplate () {
+           //
+           // OP-TEE Shared memory area.
+           // Needs to match:
+           // PcdTrustZoneSharedMemoryBase and PcdTrustZoneSharedMemorySize
+           MEMORY32FIXED (ReadWrite, 0x12800000, 0x00200000, )
+       })
+       Return (RBUF)
+   }
+}
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Fadt.aslc b/Silicon/NXP/iMX6Pkg/AcpiTables/Fadt.aslc
new file mode 100644
index 000000000000..b90e0efbdcf7
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Fadt.aslc
@@ -0,0 +1,56 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+// Advertise support for PSCI
+#define FADT_ARM_BOOT_ARCH       0x01
+
+char FACP[268] = {
+    0x46, 0x41, 0x43, 0x50, // Signature : 'FACP'
+    0x0C, 0x01, 0x00, 0x00, // Length
+    0x05,  // Revision
+    0x00,  // Checksum
+    0x4E, 0x58, 0x50, 0x4D, 0x58, 0x36, // OEMID : 'NXPMX6'
+    0x45, 0x44, 0x4B, 0x32, 0x20, 0x20, 0x20, 0x20, // OEMTABLE : 'EDK2'
+    0x01, 0x00, 0x00, 0x00, // OEM Revision
+    0x4D, 0x53, 0x46, 0x54, // CreatorID : 'MSFT'
+    0x01, 0x00, 0x00, 0x00, // Creator revision
+                                        0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x04, 0x00, 0x00, 0x00, 0xE3, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C,
+    0x00, 0x00, 0x21, 0x00, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, FADT_ARM_BOOT_ARCH,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+void * ReferenceAcpiTable(void) {
+    return (void *) &FACP;
+}
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Madt.aslc b/Silicon/NXP/iMX6Pkg/AcpiTables/Madt.aslc
new file mode 100644
index 000000000000..9f6518cdabac
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Madt.aslc
@@ -0,0 +1,124 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/AcpiLib.h>
+#include <Platform.h>
+#include <iMX6.h>
+
+#define GICC_BASE                 FixedPcdGet64 (PcdGicInterruptInterfaceBase)
+#define GICD_BASE                 FixedPcdGet64 (PcdGicDistributorBase)
+
+// Virtualization related fields. Not supported on IMX6
+#define GICH_BASE                 0
+#define GICV_BASE                 0
+#define VGIC_MAINT_INT            0
+
+#define PMU_INTERRUPT             0
+
+#pragma pack(push, 1)
+typedef struct {
+  EFI_ACPI_6_0_MULTIPLE_APIC_DESCRIPTION_TABLE_HEADER Header;
+  EFI_ACPI_6_0_GIC_STRUCTURE                          GicC[FixedPcdGet32(PcdCoreCount)];
+  EFI_ACPI_6_0_GIC_DISTRIBUTOR_STRUCTURE              GicD;
+} ACPI_6_0_MADT_STRUCTURE;
+#pragma pack(pop)
+
+ACPI_6_0_MADT_STRUCTURE Madt = {
+  {
+    {
+      EFI_ACPI_6_0_MULTIPLE_APIC_DESCRIPTION_TABLE_SIGNATURE,       // UINT32  Signature
+      sizeof (ACPI_6_0_MADT_STRUCTURE),                             // UINT32  Length
+      EFI_ACPI_6_0_MULTIPLE_APIC_DESCRIPTION_TABLE_REVISION,        // UINT8   Revision
+      0,                                                            // UINT8   Checksum
+      EFI_ACPI_OEM_ID,                                              // UINT8   OemId[6]
+      EFI_ACPI_OEM_TABLE_ID,                                        // UINT64  OemTableId
+      EFI_ACPI_OEM_REVISION,                                        // UINT32  OemRevision
+      EFI_ACPI_CREATOR_ID,                                          // UINT32  CreatorId
+      EFI_ACPI_CREATOR_REVISION                                     // UINT32  CreatorRevision
+    },
+    0,      // UINT32  LocalApicAddress
+    0       // UINT32  Flags
+  },
+  {
+    EFI_ACPI_6_0_GICC_STRUCTURE_INIT(0,                         // GicId
+                                     0x000,                     // AcpiCpuUid
+                                     0x000,                     // Mpidr
+                                     EFI_ACPI_6_0_GIC_ENABLED,  // Flags
+                                     PMU_INTERRUPT,             // PmuIrq
+                                     GICC_BASE,                 // GicBase
+                                     GICV_BASE,                 // GicVBase
+                                     GICH_BASE,                 // GicHBase
+                                     VGIC_MAINT_INT,            // GsivId
+                                     0,                         // GicRBase
+                                     0                          // Efficiency
+                                     ),
+#if FixedPcdGet32(PcdCoreCount) > 1
+    EFI_ACPI_6_0_GICC_STRUCTURE_INIT(1,                         // GicId
+                                     0x001,                     // AcpiCpuUid
+                                     0x001,                     // Mpidr
+                                     EFI_ACPI_6_0_GIC_ENABLED,  // Flags
+                                     PMU_INTERRUPT,             // PmuIrq
+                                     GICC_BASE,                 // GicBase
+                                     GICV_BASE,                 // GicVBase
+                                     GICH_BASE,                 // GicHBase
+                                     VGIC_MAINT_INT,            // GsivId
+                                     0,                         // GicRBase
+                                     0                          // Efficiency
+                                     ),
+#if FixedPcdGet32(PcdCoreCount) > 2
+    EFI_ACPI_6_0_GICC_STRUCTURE_INIT(2,                         // GicId
+                                     0x002,                     // AcpiCpuUid
+                                     0x002,                     // Mpidr
+                                     EFI_ACPI_6_0_GIC_ENABLED,  // Flags
+                                     PMU_INTERRUPT,             // PmuIrq
+                                     GICC_BASE,                 // GicBase
+                                     GICV_BASE,                 // GicVBase
+                                     GICH_BASE,                 // GicHBase
+                                     VGIC_MAINT_INT,            // GsivId
+                                     0,                         // GicRBase
+                                     0                          // Efficiency
+                                     ),
+    EFI_ACPI_6_0_GICC_STRUCTURE_INIT(3,                         // GicId
+                                     0x003,                     // AcpiCpuUid
+                                     0x003,                     // Mpidr
+                                     EFI_ACPI_6_0_GIC_ENABLED,  // Flags
+                                     PMU_INTERRUPT,             // PmuIrq
+                                     GICC_BASE,                 // GicBase
+                                     GICV_BASE,                 // GicVBase
+                                     GICH_BASE,                 // GicHBase
+                                     VGIC_MAINT_INT,            // GsivId
+                                     0,                         // GicRBase
+                                     0                          // Efficiency
+                                     ),
+#endif
+#endif
+  },
+  EFI_ACPI_6_0_GIC_DISTRIBUTOR_INIT(0x0,                        // GicDistHwId
+                                    GICD_BASE,                  // GicDistBase
+                                    IC_DIST_VECTOR_BASE,        // GicDistVector
+                                    EFI_ACPI_6_0_GIC_V1         // GicVersion
+                                    )
+};
+
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+{
+  //
+  // Reference the table being generated to prevent the optimizer from removing the
+  // data structure from the executable
+  //
+  return (VOID*)&Madt;
+}
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Mcfg.aslc b/Silicon/NXP/iMX6Pkg/AcpiTables/Mcfg.aslc
new file mode 100644
index 000000000000..158c2d757b43
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Mcfg.aslc
@@ -0,0 +1,148 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Platform.h>
+#include <IndustryStandard/MemoryMappedConfigurationSpaceAccessTable.h>
+
+#include "iMX6.h"
+#include "../Drivers/PciExpress/iMX6PciExpress.h"
+
+#define EFI_ACPI_OEM_MCFG_REVISION 0x00000001
+
+//
+// Size in bytes a single bus consumes in ECAM space
+// Configuration size = 4K
+// Max device = 32
+// Max function = 8
+// Max bus size = 4K * 32 * 8
+//
+#define ECAM_BUS_ADDR_SIZE  (1 << 20)
+
+//
+// Provide 2 differenct base PCI space address. The first list would represent
+// the host config space and the second list would be the device config space.
+// Windows is expected to be able to parse the information.
+//
+#define TOTAL_PCI_BASE_ADDRESS 2
+
+//
+// MCFG structure
+// PCI Firmware specification Table 4-2
+//
+#pragma pack(push, 1)
+
+typedef struct
+{
+    EFI_ACPI_DESCRIPTION_HEADER Header;
+    UINT64                      Reserved;
+    EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE   AllocationStructure[TOTAL_PCI_BASE_ADDRESS];
+} EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_DESCRIPTION_TABLE;
+
+#pragma pack(pop)
+
+//
+// Multiple APIC Description Table
+//
+EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_DESCRIPTION_TABLE Mcfg =
+{
+    {
+        //
+        // Signature
+        //
+        EFI_ACPI_5_0_PCI_EXPRESS_MEMORY_MAPPED_CONFIGURATION_SPACE_BASE_ADDRESS_DESCRIPTION_TABLE_SIGNATURE,
+
+        //
+        // Length
+        //
+        sizeof (EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_DESCRIPTION_TABLE),
+
+        //
+        // Revision
+        //
+        EFI_ACPI_MEMORY_MAPPED_CONFIGURATION_SPACE_ACCESS_TABLE_REVISION,
+
+        //
+        // Checksum will be updated at runtime
+        //
+        0x00,
+
+        //
+        // OEMID
+        //
+        EFI_ACPI_OEM_ID,
+
+        //
+        // OEM Table ID
+        //
+        EFI_ACPI_OEM_TABLE_ID,
+
+        //
+        // OEM Revision
+        //
+        EFI_ACPI_OEM_MCFG_REVISION,
+
+        //
+        // Creator ID
+        //
+        EFI_ACPI_CREATOR_ID,
+
+        //
+        // Creator revision
+        //
+        EFI_ACPI_CREATOR_REVISION,
+    },
+
+    //
+    // Reserved
+    //
+    0x00,
+
+    //
+    // EFI_ACPI_MEMORY_MAPPED_ENHANCED_CONFIGURATION_SPACE_BASE_ADDRESS_ALLOCATION_STRUCTURE
+    // Configuration space base address allocation
+    // structure [EFI_ACPI_ALLOCATION_STRUCTURE_COUNT]
+    //
+
+    {
+        // PCIe Host
+        {
+            PCIE_HOST_CONFIG_BASE_REG,        // PCIE Host Config Base Address
+            0x00,                             // PciSegmentGroupNumber (_SEG)
+            0x00,                             // StartBusNumber
+            0x00,                             // EndBusNumber
+            0x00000000                        // Reserved
+        },
+
+        // PCIe Device
+        {
+            PCIE_DEVICE_CONFIG_BASE_REG - ECAM_BUS_ADDR_SIZE,  // BaseAddress
+            0x00,                              // PciSegmentGroupNumber (_SEG)
+            0x01,                              // StartBusNumber
+            0x01,                              // EndBusNumber
+            0x00000000                         // Reserved
+        }
+    }
+};
+
+//
+// Reference the table being generated to prevent the optimizer from removing
+// the data structure from the executable.
+//
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+{
+    return (VOID*)&Mcfg;
+}
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Spcr.aslc b/Silicon/NXP/iMX6Pkg/AcpiTables/Spcr.aslc
new file mode 100644
index 000000000000..04bc125c6d9e
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Spcr.aslc
@@ -0,0 +1,92 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "Platform.h"
+#include "iMX6.h"
+
+// Ensure proper structure formats
+#pragma pack (1)
+
+typedef struct
+{
+    EFI_ACPI_DESCRIPTION_HEADER Header;
+    UINT8 Interface_Type;
+    UINT8 Reserved1[3];
+    EFI_ACPI_5_0_GENERIC_ADDRESS_STRUCTURE BaseAddressRegister;
+    UINT8 Interrupt_Type;
+    UINT8 PCAT_compatible_IRQ;
+    UINT32 Interrupt;
+    UINT8 Baud_Rate;
+    UINT8 Parity;
+    UINT8 Stop_Bits;
+    UINT8 Flow_Control;
+    UINT8 Terminal_Type;
+    UINT8 Reserved2;
+    UINT16 PCI_Device_ID;
+    UINT16 PCI_Vender_ID;
+    UINT8 PCI_Bus;
+    UINT8 PCI_Device;
+    UINT8 PCI_Function;
+    UINT32 PCI_Flags;
+    UINT8 PCI_Segment;
+    UINT32 Reserved3;
+} EFI_ACPI_5_0_SPCR_DESCRIPTION_TABLE;
+
+#pragma pack ()
+
+EFI_ACPI_5_0_SPCR_DESCRIPTION_TABLE SPCR =
+{
+    {
+        EFI_ACPI_5_0_SERIAL_PORT_CONSOLE_REDIRECTION_TABLE_SIGNATURE,
+        sizeof (EFI_ACPI_5_0_SPCR_DESCRIPTION_TABLE),
+        0x02,
+        0x00,                           // Checksum will be updated at runtime
+        EFI_ACPI_OEM_ID,
+        EFI_ACPI_OEM_TABLE_ID,
+        EFI_ACPI_OEM_REVISION,
+        EFI_ACPI_CREATOR_ID,
+        EFI_ACPI_CREATOR_REVISION,
+    },
+    DBG_PORT_SUBTYPE_IMX6,                  // Serial Interface type = Serial Port Subtypes of the DBG2
+    {0x00, 0x00, 0x00},                     // Reserved
+    {                                       // ACPI Generic Address Structure. Set to all zeroes to disable console redirection
+        EFI_ACPI_5_0_SYSTEM_MEMORY,         // AddressSpaceId: SystemMemory
+        0x20,                               // RegisterBitWidth
+        0,                                  // RegisterBitOffset
+        EFI_ACPI_5_0_DWORD,                 // AccessSize
+        (UINT64)CSP_BASE_REG_PA_UART3       // Address uart3 0x00000000021EC000
+    },
+    0x08,               // Interrupt Type = Bit[3] ARMH GIC interrupt. 0 means not supported.
+    0x00,               // IRQ. Not used since Bit[0] of the Interrupt Type field is not set
+    0x3c,               // Global System Interrupt used by the UART (UART3 interrupt 60)
+    0x07,               // Baud Rate
+    0x00,               // No Parity
+    0x01,               // One Stop Bit
+    0x00,               // Flow Control: None
+    0x03,               // Terminal Type: ANSI
+    0X00,               // Reserved
+    0xffff,             // 0xFFFF - not a PCI device
+    0xffff,             // 0xFFFF - not a PCI device
+    0x00,               // Bus Number. 0 - not a PCI device
+    0x00,               // Device Number. 0 - not a PCI device
+    0x00,               // Function. 0 - not a PCI device
+    0x00000000,         // PCI Flags
+    0x00,               // PCI Segment
+    0x00000000,         //Reserved
+};
+
+VOID* ReferenceAcpiTable(VOID)
+{
+  return (VOID*)&SPCR;
+}
diff --git a/Silicon/NXP/iMX6Pkg/AcpiTables/Tpm2.aslc b/Silicon/NXP/iMX6Pkg/AcpiTables/Tpm2.aslc
new file mode 100644
index 000000000000..8acc9d84a724
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/AcpiTables/Tpm2.aslc
@@ -0,0 +1,69 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/PcdLib.h>
+#include <IndustryStandard/Tpm2Acpi.h>
+#include <Platform.h>
+
+#include "iMX6.h"
+
+//
+// Definition is missing from MdePkg/Include/IndustryStandard/Tpm2Acpi.h
+//
+#ifdef EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE_WITH_TREE
+#error "EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE_WITH_TREE is defined elsewhere."
+#else
+#define EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE_WITH_TREE  9
+#endif
+
+EFI_TPM2_ACPI_TABLE Tpm2Table = {
+  {
+    EFI_ACPI_5_0_TRUSTED_COMPUTING_PLATFORM_2_TABLE_SIGNATURE,
+    sizeof (EFI_TPM2_ACPI_TABLE),
+    EFI_TPM2_ACPI_TABLE_REVISION,
+    0,                          // Checksum will be updated at runtime
+    EFI_ACPI_OEM_ID,            // OEMID is a 6 bytes long field
+    EFI_ACPI_OEM_TABLE_ID,      // OEM table identification(8 bytes long)
+    EFI_ACPI_OEM_REVISION,      // OEM revision number
+    EFI_ACPI_CREATOR_ID,        // Creator vendor ID
+    EFI_ACPI_CREATOR_REVISION,  // Creator revision number
+  },
+
+  //
+  // Flags
+  //
+  0,
+
+  //
+  // Control Area
+  //
+  FixedPcdGet64(PcdTpm2AcpiBufferBase),
+
+  //
+  // StartMethod
+  //
+  EFI_TPM2_ACPI_TABLE_START_METHOD_COMMAND_RESPONSE_BUFFER_INTERFACE_WITH_TREE,
+};
+
+VOID*
+ReferenceAcpiTable (
+  VOID
+  )
+{
+  //
+  // Reference the table being generated to prevent the optimizer from removing the
+  // data structure from the executable
+  //
+  return (VOID*)&Tpm2Table;
+}
-- 
2.16.2.gvfs.1.33.gf5370f1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH edk2-platforms 10/13] Silicon/NXP: Add i.MX6 Board init library
  2018-07-20  6:33 [PATCH edk2-platforms 00/13] Silicon/NXP: Import NXP i.MX6 Package Chris Co
                   ` (8 preceding siblings ...)
  2018-07-20  6:33 ` [PATCH edk2-platforms 09/13] Silicon/NXP: Add i.MX6 ACPI tables Chris Co
@ 2018-07-20  6:33 ` Chris Co
  2018-07-20  6:34 ` [PATCH edk2-platforms 11/13] Silicon/NXP: Add i.MX6 PCIe DXE driver Chris Co
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chris Co @ 2018-07-20  6:33 UTC (permalink / raw)
  To: edk2-devel@lists.01.org; +Cc: Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This adds support for board initialization which is common to
NXP i.MX6-based platforms.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Christopher Co <christopher.co@microsoft.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6BoardHelper.S   |  94 +++++++++++++++++
 Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6BoardMem.c      | 106 +++++++++++++++++++
 Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6Common.c        |  92 +++++++++++++++++
 Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6QBoardCoreDef.c | 107 ++++++++++++++++++++
 4 files changed, 399 insertions(+)

diff --git a/Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6BoardHelper.S b/Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6BoardHelper.S
new file mode 100644
index 000000000000..18e58b07e3d4
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6BoardHelper.S
@@ -0,0 +1,94 @@
+## @file
+#
+#  Copyright (c) Microsoft Corporation. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+#include <AsmMacroIoLib.h>
+#include <Library/ArmLib.h>
+#include <Base.h>
+#include <Library/PcdLib.h>
+#include <AutoGen.h>
+#include <AcpiTables/Dsdt-Common.inc>
+
+.text
+.align 2
+
+//
+// GIC Cpu interface
+//
+#define ARM_GIC_ICCICR  0x00  // CPU Interface Control Register
+#define ARM_GIC_ICCPMR  0x04  // Interrupt Priority Mask Register
+#define ARM_GIC_ICCBPR  0x08  // Binary Point Register
+#define ARM_GIC_ICCIAR  0x0C  // Interrupt Acknowledge Register
+#define ARM_GIC_ICCEIOR 0x10  // End Of Interrupt Register
+#define ARM_GIC_ICCRPR  0x14  // Running Priority Register
+#define ARM_GIC_ICCPIR  0x18  // Highest Pending Interrupt Register
+#define ARM_GIC_ICCABPR 0x1C  // Aliased Binary Point Register
+#define ARM_GIC_ICCIDR  0xFC  // Identification Register
+
+//
+// SRC (System Reset Controller) register offsets & masks
+//
+#define IMX6_SRC_SCR     0x0
+#define IMX6_SRC_GPR1    0x20
+#define IMX6_SRC_GPR2    0x24
+#define IMX6_SRC_GPR3    0x28
+#define IMX6_SRC_GPR4    0x2C
+#define IMX6_SRC_GPR5    0x30
+#define IMX6_SRC_GPR6    0x34
+#define IMX6_SRC_GPR7    0x38
+#define IMX6_SRC_GPR8    0x3C
+#define IMX6_SRC_GPR9    0x40
+#define IMX6_SRC_GPR10   0x44
+
+GCC_ASM_EXPORT(ArmPlatformPeiBootAction)
+GCC_ASM_EXPORT(ArmPlatformIsPrimaryCore)
+GCC_ASM_EXPORT(ArmPlatformGetPrimaryCoreMpId)
+GCC_ASM_EXPORT(ArmPlatformGetCorePosition)
+
+//UINTN
+//ArmPlatformGetPrimaryCoreMpId (
+//  VOID
+//  );
+ASM_PFX(ArmPlatformGetPrimaryCoreMpId):
+  MOV32 (r0, FixedPcdGet32 (PcdArmPrimaryCore))
+  ldr   r0, [r0]
+  bx    lr
+
+//UINTN
+//ArmPlatformIsPrimaryCore (
+//  IN UINTN MpId
+//  );
+ASM_PFX(ArmPlatformIsPrimaryCore):
+  mrc   p15,0,r0,c0,c0,5
+  ands  r0,r0,#3
+  moveq r0,#1
+  movne r0,#0
+  bx    lr
+
+//UINTN
+//ArmPlatformGetCorePosition (
+//  IN UINTN MpId
+//  );
+ASM_PFX(ArmPlatformGetCorePosition):
+  and   r0, r0, #ARM_CORE_MASK
+  bx    lr
+
+ASM_PFX(ArmPlatformPeiBootAction):
+  // enable unaligned access
+  mrc   p15, 0, r1, c1, c0, 0
+  bic   r1, r1, #0x2
+  mcr   p15, 0, r1, c1, c0, 0
+  isb
+  bx r14
+
+ASM_FUNCTION_REMOVE_IF_UNREFERENCED
diff --git a/Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6BoardMem.c b/Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6BoardMem.c
new file mode 100644
index 000000000000..7d034f813de7
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6BoardMem.c
@@ -0,0 +1,106 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/ArmPlatformLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+#include "iMX6.h"
+
+#define MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS  8
+
+/**
+  Return the Virtual Memory Map of your platform
+
+  This Virtual Memory Map is used by MemoryInitPei Module to initialize the MMU on your platform.
+
+  @param[out]   VirtualMemoryMap    Array of ARM_MEMORY_REGION_DESCRIPTOR describing a Physical-to-
+                                    Virtual Memory mapping. This array must be ended by a zero-filled
+                                    entry
+
+**/
+VOID
+ArmPlatformGetVirtualMemoryMap (
+  IN ARM_MEMORY_REGION_DESCRIPTOR** VirtualMemoryMap
+  )
+{
+  ARM_MEMORY_REGION_ATTRIBUTES  CacheAttributes;
+  UINTN                         Index = 0;
+  ARM_MEMORY_REGION_DESCRIPTOR  *VirtualMemoryTable;
+
+  ASSERT(VirtualMemoryMap != NULL);
+
+  DEBUG((DEBUG_VERBOSE, "Enter: ArmPlatformGetVirtualMemoryMap\n"));
+
+  VirtualMemoryTable = (ARM_MEMORY_REGION_DESCRIPTOR*)AllocatePages(EFI_SIZE_TO_PAGES (sizeof(ARM_MEMORY_REGION_DESCRIPTOR) * MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS));
+  if (VirtualMemoryTable == NULL) {
+    return;
+  }
+
+  CacheAttributes = DDR_ATTRIBUTES_CACHED;
+  DEBUG((DEBUG_VERBOSE, "CacheAttributes=0x%d\n", CacheAttributes));
+
+  // SOC registers region 1 (0x00100000 size 0x00C00000)
+  VirtualMemoryTable[Index].PhysicalBase   = SOC_REGISTERS_PHYSICAL_BASE1;
+  VirtualMemoryTable[Index].VirtualBase    = SOC_REGISTERS_PHYSICAL_BASE1;
+  VirtualMemoryTable[Index].Length         = SOC_REGISTERS_PHYSICAL_LENGTH1;
+  VirtualMemoryTable[Index].Attributes     = SOC_REGISTERS_ATTRIBUTES;
+
+  // PCIE Registers (0x01000000 size 0x01000000)
+  VirtualMemoryTable[++Index].PhysicalBase = PCIE_REGISTERS_PHYSICAL_BASE;
+  VirtualMemoryTable[Index].VirtualBase    = PCIE_REGISTERS_PHYSICAL_BASE;
+  VirtualMemoryTable[Index].Length         = PCIE_REGISTERS_PHYSICAL_LENGTH;
+  VirtualMemoryTable[Index].Attributes     = SOC_REGISTERS_ATTRIBUTES;
+
+  // SOC registers region 2 (excluding EIM) (0x02000000 size 0x00A00000)
+  VirtualMemoryTable[++Index].PhysicalBase = SOC_REGISTERS_PHYSICAL_BASE2;
+  VirtualMemoryTable[Index].VirtualBase    = SOC_REGISTERS_PHYSICAL_BASE2;
+  VirtualMemoryTable[Index].Length         = SOC_REGISTERS_PHYSICAL_LENGTH2;
+  VirtualMemoryTable[Index].Attributes     = SOC_REGISTERS_ATTRIBUTES;
+
+  // Framebuffer
+  VirtualMemoryTable[++Index].PhysicalBase = FixedPcdGet32 (PcdFrameBufferBase);
+  VirtualMemoryTable[Index].VirtualBase    = FixedPcdGet32 (PcdFrameBufferBase);
+  VirtualMemoryTable[Index].Length         = FixedPcdGet32 (PcdFrameBufferSize);
+  VirtualMemoryTable[Index].Attributes     = DDR_ATTRIBUTES_UNCACHED;
+
+  // Boot (UEFI) DRAM region (kernel.img & boot working DRAM) (0x10800000 size 0x001D0000)
+  VirtualMemoryTable[++Index].PhysicalBase   = BOOT_IMAGE_PHYSICAL_BASE;
+  VirtualMemoryTable[Index].VirtualBase      = BOOT_IMAGE_PHYSICAL_BASE;
+  VirtualMemoryTable[Index].Length           = BOOT_IMAGE_PHYSICAL_LENGTH;
+  VirtualMemoryTable[Index].Attributes       = BOOT_IMAGE_ATTRIBUTES;
+
+  // TrustZone Shared Memory
+  VirtualMemoryTable[++Index].PhysicalBase  = FixedPcdGet64(PcdTrustZoneSharedMemoryBase);
+  VirtualMemoryTable[Index].VirtualBase     = FixedPcdGet64(PcdTrustZoneSharedMemoryBase);
+  VirtualMemoryTable[Index].Length          = FixedPcdGet64(PcdTrustZoneSharedMemorySize);
+  VirtualMemoryTable[Index].Attributes      = CacheAttributes;
+
+  // Base SDRAM
+  VirtualMemoryTable[++Index].PhysicalBase = PcdGet64 (PcdSystemMemoryBase);
+  VirtualMemoryTable[Index].VirtualBase    = PcdGet64 (PcdSystemMemoryBase);
+  VirtualMemoryTable[Index].Length         = PcdGet64 (PcdSystemMemorySize);
+  VirtualMemoryTable[Index].Attributes     = CacheAttributes;
+
+  // End of Table
+  VirtualMemoryTable[++Index].PhysicalBase = 0;
+  VirtualMemoryTable[Index].VirtualBase    = 0;
+  VirtualMemoryTable[Index].Length         = 0;
+  VirtualMemoryTable[Index].Attributes     = (ARM_MEMORY_REGION_ATTRIBUTES)0;
+
+  ASSERT((Index + 1) <= MAX_VIRTUAL_MEMORY_MAP_DESCRIPTORS);
+
+  *VirtualMemoryMap = VirtualMemoryTable;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6Common.c b/Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6Common.c
new file mode 100644
index 000000000000..339f9b243f4a
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6Common.c
@@ -0,0 +1,92 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/IoLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PrintLib.h>
+#include <Library/PcdLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/TimerLib.h>
+#include <Library/PcdLib.h>
+#include <IndustryStandard/Tpm20.h>
+#include <IndustryStandard/Tpm2Acpi.h>
+#include <iMX6.h>
+#include <iMX6BoardLib.h>
+
+void __DoNothing() {}
+VOID SdhcInit () __attribute__ ((weak, alias ("__DoNothing")));
+VOID EhciInit () __attribute__ ((weak, alias ("__DoNothing")));
+VOID EnetInit () __attribute__ ((weak, alias ("__DoNothing")));
+VOID I2cInit () __attribute__ ((weak, alias ("__DoNothing")));
+VOID SpiInit () __attribute__ ((weak, alias ("__DoNothing")));
+VOID PcieInit () __attribute__ ((weak, alias ("__DoNothing")));
+VOID SetupAudio () __attribute__ ((weak, alias ("__DoNothing")));
+
+RETURN_STATUS
+EFIAPI
+TimerConstructor (
+  VOID
+  );
+
+/**
+  Initialize controllers that must setup at the early stage
+**/
+RETURN_STATUS
+ArmPlatformInitialize (
+  IN  UINTN                     MpId
+  )
+{
+  if (!ArmPlatformIsPrimaryCore (MpId)) {
+    return RETURN_SUCCESS;
+  }
+
+  ImxClkPwrInit ();
+
+  // Initialize default UEFI debug port early so we can use its debug output
+  SerialPortInitialize ();
+  SerialPortWrite (
+   (UINT8 *)SERIAL_DEBUG_PORT_INIT_MSG,
+   (UINTN)sizeof(SERIAL_DEBUG_PORT_INIT_MSG));
+
+  // Initialize timer early on because the following init path will be calling
+  // delay functions. PrePi.c calls ArmPlatformInitialize before it calls
+  // TimerConstructor to initialize the timer.
+  TimerConstructor ();
+
+  SdhcInit ();
+  EhciInit ();
+  EnetInit ();
+  I2cInit ();
+  SpiInit ();
+  PcieInit ();
+  SetupAudio ();
+
+  return RETURN_SUCCESS;
+}
+
+/**
+  Return the current Boot Mode
+
+  This function returns the boot reason on the platform
+
+**/
+EFI_BOOT_MODE
+ArmPlatformGetBootMode (
+  VOID
+  )
+{
+  return BOOT_WITH_FULL_CONFIGURATION;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6QBoardCoreDef.c b/Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6QBoardCoreDef.c
new file mode 100644
index 000000000000..5e136af212a0
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Library/iMX6BoardLib/iMX6QBoardCoreDef.c
@@ -0,0 +1,107 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/IoLib.h>
+#include <Library/ArmPlatformLib.h>
+#include <Library/PcdLib.h>
+#include <Library/DebugLib.h>
+#include <Ppi/ArmMpCoreInfo.h>
+
+ARM_CORE_INFO iMX6Ppi[] =
+{
+  {
+    // Cluster 0, Core 0
+    0x0, 0x0,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value.
+    // Not used with i.MX6, set to 0
+    (EFI_PHYSICAL_ADDRESS)0x00000000,
+    (EFI_PHYSICAL_ADDRESS)0x00000000,
+    (EFI_PHYSICAL_ADDRESS)0x00000000,
+    (UINT64)0
+  },
+
+#if FixedPcdGet32(PcdCoreCount) > 1
+  {
+    // Cluster 0, Core 1
+    0x0, 0x1,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    // Not used with i.MX6, set to 0
+    (EFI_PHYSICAL_ADDRESS)0x00000000,
+    (EFI_PHYSICAL_ADDRESS)0x00000000,
+    (EFI_PHYSICAL_ADDRESS)0x00000000,
+    (UINT64)0
+  },
+#endif // FixedPcdGet32(PcdCoreCount) > 1
+
+#if FixedPcdGet32(PcdCoreCount) > 2
+  {
+    // Cluster 0, Core 2
+    0x0, 0x2,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    // Not used with i.MX6, set to 0
+    (EFI_PHYSICAL_ADDRESS)0x00000000,
+    (EFI_PHYSICAL_ADDRESS)0x00000000,
+    (EFI_PHYSICAL_ADDRESS)0x00000000,
+    (UINT64)0
+  },
+
+  {
+    // Cluster 0, Core 3
+    0x0, 0x3,
+
+    // MP Core MailBox Set/Get/Clear Addresses and Clear Value
+    // Not used with i.MX6, set to 0
+    (EFI_PHYSICAL_ADDRESS)0x00000000,
+    (EFI_PHYSICAL_ADDRESS)0x00000000,
+    (EFI_PHYSICAL_ADDRESS)0x00000000,
+    (UINT64)0
+  }
+#endif // FixedPcdGet32(PcdCoreCount) > 2
+};
+
+EFI_STATUS
+PrePeiCoreGetMpCoreInfo (
+  OUT UINTN                   *CoreCount,
+  OUT ARM_CORE_INFO           **ArmCoreTable
+  )
+{
+    // Only support one cluster
+    *CoreCount    = sizeof(iMX6Ppi) / sizeof(ARM_CORE_INFO);
+    ASSERT(*CoreCount == FixedPcdGet32(PcdCoreCount));
+    *ArmCoreTable = iMX6Ppi;
+    return EFI_SUCCESS;
+}
+
+EFI_GUID mArmMpCoreInfoPpiGuid = ARM_MP_CORE_INFO_PPI_GUID;
+ARM_MP_CORE_INFO_PPI mMpCoreInfoPpi = { PrePeiCoreGetMpCoreInfo };
+EFI_PEI_PPI_DESCRIPTOR      gPlatformPpiTable[] = {
+  {
+    EFI_PEI_PPI_DESCRIPTOR_PPI,
+    &mArmMpCoreInfoPpiGuid,
+    &mMpCoreInfoPpi
+  }
+};
+
+VOID
+ArmPlatformGetPlatformPpiList (
+  OUT UINTN                   *PpiListSize,
+  OUT EFI_PEI_PPI_DESCRIPTOR  **PpiList
+  )
+{
+    *PpiListSize = sizeof(gPlatformPpiTable);
+    *PpiList = gPlatformPpiTable;
+}
-- 
2.16.2.gvfs.1.33.gf5370f1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH edk2-platforms 11/13] Silicon/NXP: Add i.MX6 PCIe DXE driver
  2018-07-20  6:33 [PATCH edk2-platforms 00/13] Silicon/NXP: Import NXP i.MX6 Package Chris Co
                   ` (9 preceding siblings ...)
  2018-07-20  6:33 ` [PATCH edk2-platforms 10/13] Silicon/NXP: Add i.MX6 Board init library Chris Co
@ 2018-07-20  6:34 ` Chris Co
  2018-07-20  6:34 ` [PATCH edk2-platforms 12/13] Silicon/NXP: Add i.MX6 GOP driver Chris Co
  2018-07-20  6:34 ` [PATCH edk2-platforms 13/13] Silicon/NXP: Add i.MX6 common dsc and fdf files Chris Co
  12 siblings, 0 replies; 14+ messages in thread
From: Chris Co @ 2018-07-20  6:34 UTC (permalink / raw)
  To: edk2-devel@lists.01.org; +Cc: Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This adds DXE driver support for PCIe on NXP i.MX6 SoCs.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Christopher Co <christopher.co@microsoft.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.c   | 1219 ++++++++++++++++++++
 Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.h   |  163 +++
 Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.inf |   66 ++
 3 files changed, 1448 insertions(+)

diff --git a/Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.c b/Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.c
new file mode 100644
index 000000000000..98f9cc034981
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.c
@@ -0,0 +1,1219 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
+*  (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <IndustryStandard/Pci.h>
+
+#include <Protocol/PciIo.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+#include <iMX6.h>
+#include <iMX6ClkPwr.h>
+#include <iMX6IoMux.h>
+
+#include "iMX6PciExpress.h"
+
+PCI_RESOURCE PCIeResource[] =
+{
+    //
+    // Memory resource
+    //
+    {
+        PCIE_MEMORY_SPACE_BASE,
+        PCIE_MEMORY_SPACE_SIZE,
+        PCIE_MEMORY_SPACE_BASE
+    },
+};
+
+//
+// PCIe read and write function
+//
+EFI_STATUS PCIePciWrite (
+    IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+    IN UINTN Address,
+    IN UINTN Count,
+    IN VOID *Buffer
+    );
+
+EFI_STATUS PCIePciRead (
+    IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+    IN UINTN Address,
+    IN UINTN Count,
+    IN VOID *Buffer
+    );
+
+//
+// Internal address translation unit configuration table. Map the PCIe device
+// configuration baesd on configuration. PCI IO space is not supported on
+// Windows. Memory space segment is just mapped back to the same address.
+//
+// The following table is used to setup basic translation setting on various
+// ATU (Address Translation Unit). The ATU is responsible to retranslate
+// address for inbound and outbound message.
+//
+// Address match mode address translation is based on the following formula :
+//     Address = Address - Base Address + Target Address
+//
+// There really isnt a need to retranslate the address for iMX6 however proceed
+// the program the ATU to for configuration and memory message.
+//
+
+IATU_SETTINGS iMX6iATUSettings[] =
+{
+    //
+    // Configuration message
+    //
+    {
+        OUTBOUND,
+        0,
+        CFG0_TYPE,
+        PCIE_DEVICE_CONFIG_BASE_REG,
+        0,
+        PCIE_DEVICE_CONFIG_BASE_REG + PCIE_DEVICE_CONFIG_SIZE - 1,
+        PCIE_DEVICE_CONFIG_BASE_REG,
+        0,
+        REGION_ENABLE,
+    },
+
+    //
+    // Memory message
+    //
+    {
+        OUTBOUND,
+        2,
+        MEMORY_TYPE,
+        PCIE_MEMORY_SPACE_BASE,
+        0,
+        PCIE_MEMORY_SPACE_BASE + PCIE_MEMORY_SPACE_SIZE - 1,
+        PCIE_MEMORY_SPACE_BASE,
+        0,
+        REGION_ENABLE,
+    },
+};
+
+VOID PCIeSetupiATU (
+    IN IATU_SETTINGS* SettingsPtr
+    )
+{
+    volatile CSP_PCIE_PL_REGS* portLogicRegsPtr =
+        (CSP_PCIE_PL_REGS*)PCIE_CTRL_PORT_LOGIG_BASE_REG;
+
+    ASSERT(SettingsPtr->RegionIndex < MAX_iATU_REGION);
+
+    //
+    // Programs specific ATU region. Refer to the comment above
+    // iMX6iATUSettings table for more detail.
+    //
+    MmioWrite32(
+        (UINTN)&portLogicRegsPtr->PCIE_PL_iATUVR,
+        (SettingsPtr->RegionDirection << 31 | SettingsPtr->RegionIndex));
+
+    MmioWrite32(
+        (UINTN)&portLogicRegsPtr->PCIE_PL_iATURC2,
+        REGION_DISABLE);
+
+    MmioWrite32(
+        (UINTN)&portLogicRegsPtr->PCIE_PL_iATURLBA,
+        SettingsPtr->LowerBaseAddr);
+
+    MmioWrite32(
+        (UINTN)&portLogicRegsPtr->PCIE_PL_iATURUBA,
+        SettingsPtr->UpperBaseAddr);
+
+    MmioWrite32(
+        (UINTN)&portLogicRegsPtr->PCIE_PL_iATURLA,
+        SettingsPtr->LimitAddr);
+
+    MmioWrite32(
+        (UINTN)&portLogicRegsPtr->PCIE_PL_iATURLTA,
+        SettingsPtr->LowerTargetAddr);
+
+    MmioWrite32(
+        (UINTN)&portLogicRegsPtr->PCIE_PL_iATURUTA,
+        SettingsPtr->UpperTargetAddr);
+
+    MmioWrite32(
+        (UINTN)&portLogicRegsPtr->PCIE_PL_iATURC1,
+        SettingsPtr->Type);
+
+    MmioWrite32(
+        (UINTN)&portLogicRegsPtr->PCIE_PL_iATURC2,
+        SettingsPtr->State);
+}
+
+VOID PCIeSetupiATUSettings (
+    VOID
+    )
+{
+    UINT32 i;
+
+    //
+    // Initialize internal address translation unit based on settings specify
+    // in iMX6iATUSettings table.
+    //
+    for (i = 0; i < ARRAYSIZE (iMX6iATUSettings); ++i) {
+        PCIeSetupiATU(&iMX6iATUSettings[i]);
+    }
+
+    return;
+}
+
+EFI_STATUS PCIeSetPhyState (
+    IN BOOLEAN State
+    )
+{
+    IMX_IOMUXC_GPR1_REG gpr1Reg;
+    volatile IMX_IOMUXC_GPR_REGISTERS* ioMuxcGprRegisters =
+        (IMX_IOMUXC_GPR_REGISTERS*)IOMUXC_GPR_BASE_ADDRESS;
+
+    gpr1Reg.AsUint32 = MmioRead32((UINTN)&ioMuxcGprRegisters->GPR1);
+
+    if (State == TRUE) {
+        gpr1Reg.REF_SSP_EN = 1;     // Enable PCIe PHY
+        gpr1Reg.TEST_POWERDOWN = 0; // Power down is not requested
+    } else {
+        gpr1Reg.REF_SSP_EN = 0;     // Disable PCIe PHY
+        gpr1Reg.TEST_POWERDOWN = 1; // Power down is requested
+    }
+
+    MmioWrite32((UINTN)&ioMuxcGprRegisters->GPR1, gpr1Reg.AsUint32);
+
+    return EFI_SUCCESS;
+}
+
+EFI_STATUS PCIeSetupInitSetting (
+    VOID
+    )
+{
+    EFI_STATUS status;
+    IMX_IOMUXC_GPR1_REG gpr1Reg;
+    volatile IMX_IOMUXC_GPR_REGISTERS* ioMuxcGprRegisters =
+        (IMX_IOMUXC_GPR_REGISTERS*)IOMUXC_GPR_BASE_ADDRESS;
+
+    //
+    // If PCIe PHY is already enabled we are in an unexpected state, just exit
+    // and assume a bootloader has already setup PCIe and assigned resources.
+    //
+    gpr1Reg.AsUint32 = MmioRead32((UINTN)&ioMuxcGprRegisters->GPR1);
+
+    if (gpr1Reg.REF_SSP_EN == 1) {
+        status = EFI_DEVICE_ERROR;
+        goto Exit;
+    }
+
+    //
+    // Disable the PHY first, without this PCI link randomly does not come up
+    //
+    status = PCIeSetPhyState(FALSE);
+    if (EFI_ERROR(status)) {
+        PCIE_ERROR("Failed to disable PCIe PHY\n");
+        goto Exit;
+    }
+
+    //
+    // First configure PCIe and PCIe PHY default setting
+    //
+    {
+        IMX_IOMUXC_GPR12_REG gpr12Reg;
+        IMX_IOMUXC_GPR8_REG gpr8Reg;
+        volatile IMX_IOMUXC_GPR_REGISTERS* ioMuxcGprRegisters =
+            (IMX_IOMUXC_GPR_REGISTERS*)IOMUXC_GPR_BASE_ADDRESS;
+
+        gpr12Reg.AsUint32 = MmioRead32((UINTN)&ioMuxcGprRegisters->GPR12);
+
+        gpr12Reg.APP_LTSSM_ENABLE = 0;          // Set application not ready
+        gpr12Reg.DIA_STATUS_BUS_SELECT = 0xB;   // Debug functionality
+        gpr12Reg.DEVICE_TYPE = 0x4;             // Set to RC mode
+        gpr12Reg.LOS_LEVEL = 0x9;               // Set to 0x9 per reference manual
+
+        MmioWrite32((UINTN)&ioMuxcGprRegisters->GPR12, gpr12Reg.AsUint32);
+
+        // Gen1 | Gen2 3p5 | Gen2 6 | Swing full 127 | Swing low 127
+        gpr8Reg.PCS_TX_DEEMPH_GEN1 = 0;
+        gpr8Reg.PCS_TX_DEEMPH_GEN2_3P5DB = 0;
+        gpr8Reg.PCS_TX_DEEMPH_GEN2_6DB = 20;
+        gpr8Reg.PCS_TX_SWING_FULL = 127;
+        gpr8Reg.PCS_TX_SWING_LOW = 127;
+
+        MmioWrite32((UINTN)&ioMuxcGprRegisters->GPR8, gpr8Reg.AsUint32);
+    }
+
+    status = EFI_SUCCESS;
+
+Exit:
+    return status;
+}
+
+EFI_STATUS PCIeSetClockGate (
+    IN IMX_CLOCK_GATE_STATE State
+    )
+{
+    ImxClkPwrSetClockGate(IMX_PCIE_ROOT_ENABLE, State);
+    return EFI_SUCCESS;
+}
+
+EFI_STATUS PCIeVerifyClocks (
+    VOID
+    )
+{
+    IMX_CCM_ANALOG_PLL_ENET_REG ccmAnalogPllReg;
+    volatile IMX_CCM_ANALOG_REGISTERS *ccmAnalogRegisters =
+        (IMX_CCM_ANALOG_REGISTERS *)IMX_CCM_ANALOG_BASE;
+
+    ccmAnalogPllReg.AsUint32 = MmioRead32((UINTN)&ccmAnalogRegisters->PLL_ENET);
+
+    if ((ccmAnalogPllReg.POWERDOWN == 0) &&
+        (ccmAnalogPllReg.BYPASS == 0) &&
+        (ccmAnalogPllReg.ENABLE_125M == 1) &&
+        (ccmAnalogPllReg.LOCK == 1)) {
+        return EFI_SUCCESS;
+    }
+
+    return EFI_DEVICE_ERROR;
+}
+
+VOID PCIeEnablePerstLine (
+    VOID
+    )
+{
+    //
+    // Enable board specific PERST line if one is defined
+    //
+    if (FixedPcdGet32(PcdPcieResetGpio)) {
+        ImxGpioWrite(
+            FixedPcdGet32(PcdPcieResetGpioBankNumber),
+            FixedPcdGet32(PcdPcieResetGpioIoNumber),
+            IMX_GPIO_HIGH);
+        gBS->Stall(20000);
+    }
+}
+
+EFI_STATUS PCIeSetupPCIBridge (
+    VOID
+    )
+{
+    UINT8 classCode[0];
+
+    //
+    // Setup the bridge class
+    //
+    classCode[0] = PCI_IF_BRIDGE_P2P;
+    classCode[1] = PCI_CLASS_BRIDGE_P2P;
+    classCode[2] = PCI_CLASS_BRIDGE;
+
+    return PCIePciWrite(
+        EfiPciIoWidthUint8,
+        PCIE_HOST_CONFIG_BASE_REG + PCI_CLASSCODE_OFFSET,
+        3,
+        classCode);
+}
+
+EFI_STATUS PCIeSetLinkStatus (
+    IN BOOLEAN State
+    )
+{
+    IMX_IOMUXC_GPR12_REG gpr12Reg;
+    volatile IMX_IOMUXC_GPR_REGISTERS* ioMuxcGprRegisters =
+        (IMX_IOMUXC_GPR_REGISTERS*)IOMUXC_GPR_BASE_ADDRESS;
+
+    gpr12Reg.AsUint32 = MmioRead32((UINTN)&ioMuxcGprRegisters->GPR12);
+
+    if (State == TRUE) {
+        gpr12Reg.APP_LTSSM_ENABLE = 1; // Enable link
+    } else {
+        gpr12Reg.APP_LTSSM_ENABLE = 0; // Disable link
+    }
+
+    MmioWrite32((UINTN)&ioMuxcGprRegisters->GPR12, gpr12Reg.AsUint32);
+
+    return EFI_SUCCESS;
+}
+
+BOOLEAN PCIeIsLinkUp (
+    VOID
+    )
+{
+    UINT32 debug1Reg;
+    volatile CSP_PCIE_PL_REGS* portLogicRegsPtr =
+        (CSP_PCIE_PL_REGS*)PCIE_CTRL_PORT_LOGIG_BASE_REG;
+
+    debug1Reg = MmioRead32((UINTN)&portLogicRegsPtr->PCIE_PL_DEBUG1);
+
+    return (debug1Reg & PCIE_PL_DEBUG1_PHY_LINK_UP) ? TRUE : FALSE;
+}
+
+EFI_STATUS PCIeWaitForLink (
+    VOID
+    )
+{
+    UINT32 counter = 200;
+    BOOLEAN linkStatus;
+
+    linkStatus = PCIeIsLinkUp();
+
+    //
+    // To optimize boot time, consider lowering timeout value
+    //
+    while (linkStatus == FALSE && counter > 0) {
+        --counter;
+        gBS->Stall(1000);
+        linkStatus = PCIeIsLinkUp();
+    }
+
+    return (linkStatus) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+}
+
+EFI_STATUS PCIeGetAlignAddress (
+    IN UINTN Address,
+    IN UINTN AlignmentSize,
+    OUT UINTN *AlignAddress
+    )
+{
+    EFI_STATUS status;
+
+    *AlignAddress = 0;
+
+    if ((AlignmentSize & (AlignmentSize - 1)) != 0) {
+        status = EFI_INVALID_PARAMETER;
+        goto Exit;
+    }
+
+    //
+    // Even though we do not add a (AlignmentSize + 1) to the incoming address
+    // we would still align to the upper boundary as bit [19:00] is assumed to
+    // be 0x000FFFFF per PCIe spec.
+    //
+    *AlignAddress = (Address) & ~(AlignmentSize - 1);
+
+    status = EFI_SUCCESS;
+Exit:
+    return status;
+}
+
+EFI_STATUS PCIeGetPCIConfigAddress (
+    IN UINTN BusNumber,
+    IN UINTN DevNumber,
+    IN UINTN FuncNumber,
+    IN UINTN Register,
+    OUT UINTN* Address
+    )
+{
+    UINT64 offset;
+    EFI_STATUS status;
+
+    //
+    // For now only support bus 0 and bus 1 with one device in each bus
+    //
+    if (BusNumber == 0 && DevNumber == 0) {
+
+        offset = EFI_PCI_ADDRESS (BusNumber, DevNumber, FuncNumber, Register);
+        *Address = PCIE_HOST_CONFIG_BASE_REG + offset;
+
+        status = EFI_SUCCESS;
+
+    } else if (BusNumber == 1 && DevNumber == 0) {
+
+        offset = EFI_PCI_ADDRESS (BusNumber, DevNumber, FuncNumber, Register);
+        offset -= EFI_PCI_ADDRESS (1, 0, FuncNumber, 0);
+        *Address = PCIE_DEVICE_CONFIG_BASE_REG + offset;
+
+        status = EFI_SUCCESS;
+
+    } else {
+        *Address = 0;
+        status = EFI_INVALID_PARAMETER;
+    }
+
+    return status;
+}
+
+EFI_STATUS PCIePciRead (
+    IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+    IN UINTN Address,
+    IN UINTN Count,
+    OUT VOID *Buffer
+    )
+{
+    PTR dest;
+    UINTN stride;
+    EFI_STATUS status;
+
+    dest.ui = (UINTN)Buffer;
+    Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);
+    stride = (UINTN)1 << Width;
+
+    //
+    // Adopted from PciRootBridgeIoMemRW
+    //
+    switch (Width) {
+    case EfiPciWidthUint8:
+        for (; Count > 0; --Count, dest.buf += stride, Address += stride) {
+            *dest.ui8 = MmioRead8(Address);
+        }
+        status = EFI_SUCCESS;
+        break;
+    case EfiPciWidthUint16:
+        for (; Count > 0; --Count, dest.buf += stride, Address += stride) {
+            *dest.ui16 = MmioRead16(Address);
+        }
+        status = EFI_SUCCESS;
+        break;
+    case EfiPciWidthUint32:
+        for (; Count > 0; --Count, dest.buf += stride, Address += stride) {
+            *dest.ui32 = MmioRead32(Address);
+        }
+        status = EFI_SUCCESS;
+        break;
+    default:
+        status = EFI_INVALID_PARAMETER;
+        goto Exit;
+    }
+
+Exit:
+    return status;
+}
+
+EFI_STATUS PCIePciWrite (
+    IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+    IN UINTN Address,
+    IN UINTN Count,
+    IN VOID *Buffer
+    )
+{
+    PTR src;
+    UINTN stride;
+    EFI_STATUS status;
+
+    src.ui = (UINTN)Buffer;
+    Width = (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)(Width & 0x03);
+    stride = (UINTN)1 << Width;
+
+    //
+    // Adopted from PciRootBridgeIoMemRW
+    //
+    switch (Width) {
+    case EfiPciWidthUint8:
+        for (; Count > 0; --Count, src.buf += stride, Address += stride) {
+            MmioWrite8(Address, *src.ui8);
+        }
+        status = EFI_SUCCESS;
+        break;
+    case EfiPciWidthUint16:
+        for (; Count > 0; --Count, src.buf += stride, Address += stride) {
+            MmioWrite16(Address, *src.ui16);
+        }
+        status = EFI_SUCCESS;
+        break;
+    case EfiPciWidthUint32:
+        for (; Count > 0; --Count, src.buf += stride, Address += stride) {
+            MmioWrite32(Address, *src.ui32);
+        }
+        status = EFI_SUCCESS;
+        break;
+    default:
+        status = EFI_INVALID_PARAMETER;
+        goto Exit;
+    }
+
+Exit:
+    return status;
+}
+
+EFI_STATUS PCIeDevicePresent (
+    OUT PCI_TYPE00* PciDevice,
+    IN UINTN Bus,
+    IN UINTN Device,
+    IN UINTN Func
+    )
+{
+    UINTN address;
+    EFI_STATUS status;
+
+    //
+    // Create PCI address map in terms of Bus, Device, and Func
+    //
+    status = PCIeGetPCIConfigAddress(Bus, Device, Func, 0, &address);
+    if (EFI_ERROR(status)) {
+        status = EFI_NOT_FOUND;
+        goto Exit;
+    }
+
+    //
+    // Read the Vendor ID register
+    //
+    status = PCIePciRead(
+        EfiPciWidthUint32,
+        address,
+        1,
+        PciDevice);
+    if (!EFI_ERROR(status) && (PciDevice->Hdr).VendorId != 0xffff) {
+        //
+        // Read the entire config header for the device
+        //
+        status = PCIePciRead(
+            EfiPciWidthUint32,
+            address,
+            sizeof (PCI_TYPE00) / sizeof (UINT32),
+            PciDevice);
+        if (EFI_ERROR(status)) {
+            PCIE_ERROR("Failed to read PCI config space\n");
+        }
+    } else {
+        PCIE_INFO("No PCIe device found\n");
+        status = EFI_NOT_FOUND;
+    }
+
+Exit:
+    return status;
+}
+
+EFI_STATUS PCIeGetMemoryBarResource (
+    IN UINTN BarSize,
+    IN UINTN* BarAddress,
+    IN BOOLEAN IsBridgeDevice
+    )
+{
+    EFI_STATUS status;
+
+    if (BarSize > PCIeResource->Size) {
+        PCIE_ERROR("Insufficient PCIe memory for 0x%08x (Current size 0x%08x)\n",
+            BarSize,
+            PCIeResource->Size);
+        status = EFI_OUT_OF_RESOURCES;
+        goto Exit;
+    }
+
+    *BarAddress = PCIeResource->Curr;
+
+    if (IsBridgeDevice == FALSE) {
+        PCIeResource->Curr += BarSize;
+        PCIeResource->Size -= BarSize;
+
+        PCIE_INFO("Allocating memory resource 0x%08x size 0x%08x\n",
+            *BarAddress,
+            BarSize);
+    }
+
+    PCIE_INFO("Current memory resource 0x%08x Size 0x%08x\n",
+        PCIeResource->Curr,
+        PCIeResource->Size);
+
+    status = EFI_SUCCESS;
+
+Exit:
+    return status;
+}
+
+EFI_STATUS PCIeParseAssignBar (
+    IN UINTN BaseAddress,
+    IN UINTN MaxBarIndex,
+    IN BOOLEAN IsBridgeDevice
+    )
+{
+    EFI_STATUS status;
+    UINTN barIndex, barOffset;
+    UINT32 allOne32 = 0xFFFFFFFF;
+
+    for (barOffset = 0x10, barIndex = 0;
+         barOffset <= 0x24 && barIndex < MaxBarIndex;
+         barOffset += sizeof (UINT32), ++barIndex) {
+
+        UINTN originalvalue, responseValue, barSize, resourceAddress;
+
+        status = PCIePciRead(
+            EfiPciWidthUint32,
+            BaseAddress + barOffset,
+            1,
+            &originalvalue);
+        ASSERT_EFI_ERROR(status);
+
+        status = PCIePciWrite(
+            EfiPciIoWidthUint32,
+            BaseAddress + barOffset,
+            1,
+            &allOne32);
+        ASSERT_EFI_ERROR(status);
+
+        status = PCIePciRead(
+            EfiPciWidthUint32,
+            BaseAddress + barOffset,
+            1,
+            &responseValue);
+        ASSERT_EFI_ERROR(status);
+
+        //
+        // No support for IO memory
+        // Refer : PCI Local Bus Specification (6.2.5.1)
+        //
+        if ((responseValue & 0x01) == 0x01) {
+            status = PCIePciWrite(
+                EfiPciIoWidthUint32,
+                BaseAddress + barOffset,
+                1,
+                &originalvalue);
+            ASSERT_EFI_ERROR(status);
+            continue;
+        }
+
+        //
+        // No support for prefetch memory
+        //
+        if (((responseValue & 0x01) == 0x00) &&
+            ((responseValue & 0x08) == 0x08)) {
+            status = PCIePciWrite(
+                EfiPciIoWidthUint32,
+                BaseAddress + barOffset,
+                1,
+                &originalvalue);
+            ASSERT_EFI_ERROR(status);
+            continue;
+        }
+
+        barSize = (~(responseValue & 0xFFFFFFF0)) + 1;
+
+        status = PCIeGetMemoryBarResource(
+            barSize,
+            &resourceAddress,
+            IsBridgeDevice);
+        if (EFI_ERROR(status)) {
+            PCIE_ERROR("Failed to acquire BAR resource\n");
+            goto Exit;
+        }
+
+        status = PCIePciWrite(
+            EfiPciIoWidthUint32,
+            BaseAddress + barOffset,
+            1,
+            &resourceAddress);
+        ASSERT_EFI_ERROR(status);
+
+        //
+        // The subsequent BAR is the upper 32 bit address
+        //
+        if (((responseValue & 0x04) == 0x04) &&
+            (barIndex + 1) < MaxBarIndex) {
+
+            UINT32 allZero = 0;
+            barOffset += sizeof (UINT32);
+            ++barIndex;
+
+            status = PCIePciWrite(
+                EfiPciIoWidthUint32,
+                BaseAddress + barOffset,
+                1,
+                &allZero);
+            ASSERT_EFI_ERROR(status);
+
+            continue;
+        }
+    }
+
+    status = EFI_SUCCESS;
+
+Exit:
+    return status;
+}
+
+EFI_STATUS PCIeConfigureDevice (
+    IN PCI_TYPE00 pciDevice,
+    IN UINTN BusNumber,
+    IN UINTN DevNumber,
+    IN UINTN FuncNumber
+    )
+{
+    EFI_STATUS status;
+    UINTN baseAddress;
+
+    PCIE_INFO(
+        "Configuring B:%02d D:%02d F:%02d\n",
+        BusNumber,
+        DevNumber,
+        FuncNumber);
+
+    status = PCIeGetPCIConfigAddress(
+        BusNumber,
+        DevNumber,
+        FuncNumber,
+        0,
+        &baseAddress);
+    ASSERT_EFI_ERROR(status);
+
+    //
+    // Use a fixed cacheline size
+    //
+    {
+        UINT8 fixedCacheLineSize = 0x10;
+
+        status = PCIePciWrite(
+            EfiPciIoWidthUint8,
+            baseAddress + PCI_CACHELINE_SIZE_OFFSET,
+            1,
+            &fixedCacheLineSize);
+        ASSERT_EFI_ERROR(status);
+    }
+
+    if (IS_PCI_BRIDGE (&pciDevice)) {
+        UINT32 allZero = 0;
+
+        PCIE_INFO("PCI Bridge\n");
+
+        //
+        // PCIe initialization sequence, referenced from
+        // InitializePpb in MdeModulePkg/Bus/Pci/PciBusDxe
+        // No support for IO and prefetch memory
+        //
+
+        status = PCIePciWrite(
+            EfiPciIoWidthUint8,
+            baseAddress + 0x1C,
+            1,
+            &allZero);
+        ASSERT_EFI_ERROR(status);
+
+        status = PCIePciWrite(
+            EfiPciIoWidthUint8,
+            baseAddress + 0x1D,
+            1,
+            &allZero);
+
+        status = PCIePciWrite(
+            EfiPciIoWidthUint16,
+            baseAddress + 0x24,
+            1,
+            &allZero);
+        ASSERT_EFI_ERROR(status);
+
+        status = PCIePciWrite(
+            EfiPciIoWidthUint16,
+            baseAddress + 0x26,
+            1,
+            &allZero);
+        ASSERT_EFI_ERROR(status);
+
+        status = PCIePciWrite(
+            EfiPciIoWidthUint32,
+            baseAddress + 0x28,
+            1,
+            &allZero);
+        ASSERT_EFI_ERROR(status);
+
+        status = PCIePciWrite(
+            EfiPciIoWidthUint32,
+            baseAddress + 0x2C,
+            1,
+            &allZero);
+        ASSERT_EFI_ERROR(status);
+
+        status = PCIePciWrite(
+            EfiPciIoWidthUint16,
+            baseAddress + 0x30,
+            1,
+            &allZero);
+        ASSERT_EFI_ERROR(status);
+
+        status = PCIePciWrite(
+            EfiPciIoWidthUint16,
+            baseAddress + 0x32,
+            1,
+            &allZero);
+        ASSERT_EFI_ERROR(status);
+
+        //
+        // Type 1 bridge only has 2 BAR register
+        //
+        status = PCIeParseAssignBar(
+            baseAddress,
+            2,
+            TRUE);
+        if (EFI_ERROR(status)) {
+            PCIE_ERROR("Failed to assign resource to PCI bridge\n");
+            goto Exit;
+        }
+
+    } else {
+
+        //
+        // Device specific configuration should be implemented here
+        //
+        PCIE_INFO("PCI device\n");
+
+        status = PCIeParseAssignBar(
+            baseAddress,
+            PCI_MAX_BAR,
+            FALSE);
+        if (EFI_ERROR(status)) {
+            PCIE_ERROR("Failed to assign resource to PCI device\n");
+            goto Exit;
+        }
+    }
+
+    {
+        UINT16 pciCommand;
+
+        status = PCIePciRead(
+            EfiPciIoWidthUint16,
+            baseAddress + PCI_COMMAND_OFFSET,
+            1,
+            &pciCommand);
+        ASSERT_EFI_ERROR(status);
+
+        pciCommand |=
+            (EFI_PCI_COMMAND_MEMORY_SPACE | EFI_PCI_COMMAND_BUS_MASTER);
+
+        status = PCIePciWrite(
+            EfiPciIoWidthUint16,
+            baseAddress + PCI_COMMAND_OFFSET,
+            1,
+            &pciCommand);
+        ASSERT_EFI_ERROR(status);
+    }
+
+    status = EFI_SUCCESS;
+
+Exit:
+    return status;
+}
+
+EFI_STATUS PCIeSimpleScanBusAndAssignResource (
+    IN UINTN BusNumber
+    )
+{
+    EFI_STATUS status;
+    UINTN devNumber;
+    UINTN functionNumber;
+    PCI_TYPE00 pciDevice;
+
+    for (devNumber = 0; devNumber <= PCI_MAX_DEVICE; ++devNumber) {
+        for (functionNumber = 0; functionNumber <= PCI_MAX_FUNC; ++functionNumber) {
+
+            PCIE_INFO("Scanning device B: %02d D: %02d F: %02d\n",
+                BusNumber,
+                devNumber,
+                functionNumber);
+
+            status = PCIeDevicePresent(
+                &pciDevice,
+                BusNumber,
+                devNumber,
+                functionNumber);
+            if (status == EFI_NOT_FOUND) {
+                PCIE_INFO("No PCI device found\n");
+                status = EFI_SUCCESS;
+                goto Exit;
+            } else if (EFI_ERROR(status)) {
+                PCIE_ERROR("Error detecting PCI device\n");
+                goto Exit;
+            }
+
+            status = PCIeConfigureDevice(
+                pciDevice,
+                BusNumber,
+                devNumber,
+                functionNumber);
+            if (EFI_ERROR(status)) {
+                PCIE_ERROR(
+                    "Failed to configure device B:%02d D:%02d F:%02d\n",
+                    BusNumber,
+                    devNumber,
+                    functionNumber);
+                continue;
+            }
+
+            if (IS_PCI_BRIDGE (&pciDevice)) {
+                UINTN busBaseRegisterAddress;
+                UINTN resourceAddress, bridgeMemory;
+                UINTN bridgeMemoryBase, bridgeMemoryLimit;
+                UINT16 busRegister;
+                UINT8 subBus;
+
+                busRegister = (UINT16)(((BusNumber + 1) << 8) | (UINT16)BusNumber);
+                status = PCIeGetPCIConfigAddress(
+                    BusNumber,
+                    devNumber,
+                    functionNumber,
+                    0,
+                    &busBaseRegisterAddress);
+
+                ASSERT_EFI_ERROR(status);
+
+                status = PCIePciWrite(
+                    EfiPciWidthUint16,
+                    busBaseRegisterAddress + PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET,
+                    1,
+                    &busRegister);
+                if (EFI_ERROR(status)) {
+                    PCIE_ERROR("Failed to update bridge bus number %d\n", BusNumber);
+                    continue;
+                }
+
+                //
+                // Temporarily set maximum subordinate bus number, although for now
+                // only support 2 buses.
+                //
+                subBus = 0XFF;
+                status = PCIePciWrite(
+                    EfiPciWidthUint8,
+                    busBaseRegisterAddress + PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET,
+                    1,
+                    &subBus);
+                if (EFI_ERROR(status)) {
+                    PCIE_ERROR("Failed to update bridge bus number %d\n", BusNumber);
+                    continue;
+                }
+
+                //
+                // Setup the memory base.
+                //
+                status = PCIeGetMemoryBarResource(
+                    0,
+                    &bridgeMemoryBase,
+                    TRUE);
+                if (EFI_ERROR(status)) {
+                    PCIE_ERROR("Failed to acquire BAR resource\n");
+                    goto Exit;
+                }
+
+                bridgeMemory = (bridgeMemoryBase >> 16) & 0xFFF0;
+
+                status = PCIePciWrite(
+                    EfiPciIoWidthUint32,
+                    busBaseRegisterAddress + 0x20,
+                    1,
+                    &bridgeMemory);
+                ASSERT_EFI_ERROR(status);
+
+                status = PCIeSimpleScanBusAndAssignResource(
+                    BusNumber + 1);
+                if (EFI_ERROR(status)) {
+                    PCIE_ERROR("Failed to scan new bus %d\n", BusNumber + 1);
+                    continue;
+                }
+
+                //
+                // Setup the memory limit.
+                //
+                status = PCIeGetMemoryBarResource(
+                    0,
+                    &resourceAddress,
+                    TRUE);
+                if (EFI_ERROR(status)) {
+                    PCIE_ERROR("Failed to acquire BAR resource\n");
+                    goto Exit;
+                }
+
+                ASSERT(bridgeMemoryBase != resourceAddress);
+
+                //
+                // Per spec align address has to be 1MB boundary
+                //
+                PCIeGetAlignAddress(
+                    resourceAddress,
+                    0x00100000,
+                    &bridgeMemoryLimit);
+                ASSERT_EFI_ERROR(status);
+
+                bridgeMemory |= bridgeMemoryLimit;
+
+                status = PCIePciWrite(
+                    EfiPciIoWidthUint32,
+                    busBaseRegisterAddress + 0x20,
+                    1,
+                    &bridgeMemory);
+                ASSERT_EFI_ERROR(status);
+
+                subBus = (BusNumber + 1);
+                status = PCIePciWrite(
+                    EfiPciWidthUint8,
+                    busBaseRegisterAddress +
+                        PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET,
+                    1,
+                    &subBus);
+                if (EFI_ERROR(status)) {
+                    PCIE_ERROR(
+                        "Failed to update subordinate bus number %d\n",
+                        BusNumber);
+                    continue;
+                }
+
+                //
+                // Claim any memory that is used for padding
+                //
+                status = PCIeGetMemoryBarResource(
+                    (bridgeMemoryLimit + 0x00100000) - resourceAddress,
+                    &resourceAddress,
+                    FALSE);
+                if (EFI_ERROR(status)) {
+                    PCIE_ERROR("Failed to realign resource\n");
+                    goto Exit;
+                }
+            }
+
+            //
+            // Skip sub functions, this is not a multi function device
+            //
+            if (functionNumber == 0 && !IS_PCI_MULTI_FUNC (&pciDevice)) {
+
+                functionNumber = PCI_MAX_FUNC;
+            }
+        }
+    }
+
+Exit:
+    return status;
+}
+
+EFI_STATUS PCIeInitialize (
+    IN EFI_HANDLE ImageHandle,
+    IN EFI_SYSTEM_TABLE* SystemTablePtr
+    )
+{
+    EFI_STATUS status;
+
+    status = PCIeSetupInitSetting();
+    if (EFI_ERROR(status)) {
+
+        //
+        // EFI_DEVICE_ERROR indicate that a bootloader has already setup the
+        // PCIe controller. In this case just return success immediately
+        //
+        if (status == EFI_DEVICE_ERROR) {
+            status = EFI_SUCCESS;
+            PCIE_WARNING("PCIe already initialized\n");
+            goto Exit;
+        }
+
+        PCIE_ERROR("Failed to enable PCIe gates\n");
+        goto Exit;
+    }
+
+    status = PCIeSetClockGate(IMX_CLOCK_GATE_STATE_ON);
+    if (EFI_ERROR(status)) {
+        PCIE_ERROR("Failed to enable PCIe gates\n");
+        goto Exit;
+    }
+
+    status = PCIeVerifyClocks();
+    if (EFI_ERROR(status)) {
+        PCIE_ERROR("Failed to verify PCIe clocks, not configured!\n");
+        goto Exit;
+    }
+
+    status = PCIeSetPhyState(TRUE);
+    if (EFI_ERROR(status)) {
+        PCIE_ERROR("Failed to enable PCIe PHY\n");
+        goto Exit;
+    }
+
+    //
+    // Very important to wait for PCIe PHY to settle here or the controller
+    // behaviour becomes unpredictable.
+    //
+    gBS->Stall(50000);
+
+    PCIeEnablePerstLine();
+
+    status = PCIeSetupPCIBridge();
+    if (EFI_ERROR(status)) {
+        PCIE_ERROR("Failed to setup PCI bridge\n");
+        goto Exit;
+    }
+
+    status = PCIeSetLinkStatus(TRUE);
+    if (EFI_ERROR(status)) {
+        PCIE_ERROR("Failed to enable PCIe link\n");
+        goto Exit;
+    }
+
+    status = PCIeWaitForLink();
+    if (EFI_ERROR(status)) {
+        PCIE_ERROR("PCI link never came up\n");
+        goto Exit;
+    }
+
+    PCIeSetupiATUSettings();
+
+    //
+    // Start scanning from bus 0 onward
+    //
+    status = PCIeSimpleScanBusAndAssignResource(0);
+    if (EFI_ERROR(status)) {
+        PCIE_ERROR("PCIeSimpleScanBusAndAssignResource failed %r\n", status);
+        goto Exit;
+    }
+
+#ifdef DEBUG
+    {
+        UINT32 printIndex = 0;
+        volatile UINT32* printAddr = (UINT32*)PCIE_HOST_CONFIG_BASE_REG;
+
+        PCIE_INFO("===============================\n");
+        PCIE_INFO("Host Device Configuration space\n");
+        PCIE_INFO("===============================\n");
+        for (; printIndex < 16; ++printIndex) {
+            PCIE_INFO("PCI [%02x] 0x%08x 0x%08x 0x%08x 0x%08x\n", \
+                printIndex * 16, \
+                printAddr[0], \
+                printAddr[1], \
+                printAddr[2], \
+                printAddr[3]);
+
+            printAddr += 4;
+        }
+
+        PCIE_INFO("===============================\n");
+        PCIE_INFO("Device Configuration space 0x%08x\n", printAddr);
+        PCIE_INFO("===============================\n");
+        for (printIndex = 0; printIndex < 16; ++printIndex) {
+            PCIE_INFO("PCI [%02x] 0x%08x 0x%08x 0x%08x 0x%08x\n", \
+                printIndex * 16, \
+                printAddr[0], \
+                printAddr[1], \
+                printAddr[2], \
+                printAddr[3]);
+
+            printAddr += 4;
+        }
+        PCIE_INFO("===============================\n");
+    }
+#endif
+
+Exit:
+
+    if (EFI_ERROR(status)) {
+        PCIE_ERROR("Failed to initialize PCIe, disabling controller\n");
+    PCIeSetLinkStatus(FALSE);
+        PCIeSetPhyState(FALSE);
+        PCIeSetClockGate(IMX_CLOCK_GATE_STATE_OFF);
+    }
+
+  //
+  // For debug printout the state of the PLL/PHY
+  //
+#ifdef DEBUG
+  {
+    volatile IMX_CCM_ANALOG_REGISTERS* ccmAnalogRegsPtr = (IMX_CCM_ANALOG_REGISTERS*)IMX_CCM_ANALOG_BASE;
+    volatile IMX_IOMUXC_GPR_REGISTERS* ioMuxcRegsPtr = (IMX_IOMUXC_GPR_REGISTERS*)IMX_IOMUXC_BASE;
+
+    PCIE_INFO( "IMX_CCM_PLL_ENET 0x%08X\n", MmioRead32((UINTN) &ccmAnalogRegsPtr->PLL_ENET));
+    PCIE_INFO( "IOMUXC_GPR1 0x%08X\n", MmioRead32((UINTN) &ioMuxcRegsPtr->GPR1));
+  }
+#endif
+    return status;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.h b/Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.h
new file mode 100644
index 000000000000..fa7d275b4fbd
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.h
@@ -0,0 +1,163 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#pragma once
+
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(__array__) (sizeof((__array__))/sizeof((__array__[0])))
+#endif
+
+//
+// Print macro
+//
+#define PCIE_INIT(PRINT_OUT, ...) \
+    DEBUG((DEBUG_INIT, "iMX6PCIe:" PRINT_OUT, ##__VA_ARGS__))
+#define PCIE_INFO(PRINT_OUT, ...) \
+    DEBUG((DEBUG_INFO, "iMX6PCIe:" PRINT_OUT, ##__VA_ARGS__))
+#define PCIE_WARNING(PRINT_OUT, ...) \
+    DEBUG((DEBUG_WARN, "iMX6PCIe:" PRINT_OUT, ##__VA_ARGS__))
+#define PCIE_ERROR(PRINT_OUT, ...) \
+    DEBUG((DEBUG_ERROR, "iMX6PCIe:" PRINT_OUT, ##__VA_ARGS__))
+
+//
+// PCIe related base address
+//
+#define PCIE_HOST_CONFIG_BASE_REG       FixedPcdGet32(PcdPcieHostConfigBase)
+#define PCIE_CTRL_PORT_LOGIG_BASE_REG   0x01FFC700
+#define PCIE_DEVICE_CONFIG_BASE_REG     FixedPcdGet32(PcdPcieDeviceConfigBase)
+#define PCIE_DEVICE_CONFIG_SIZE         FixedPcdGet32(PcdPcieDeviceConfigSize)
+#define PCIE_IO_SPACE_BASE              FixedPcdGet32(PcdPcieIOBase)
+#define PCIE_IO_SPACE_SIZE              FixedPcdGet32(PcdPcieIOSize)
+#define PCIE_MEMORY_SPACE_BASE          FixedPcdGet32(PcdPciMemoryBase)
+#define PCIE_MEMORY_SPACE_SIZE          FixedPcdGet32(PcdPciMemorySize)
+#define PCIE_PREFETCH_MEMORY_SPACE_BASE FixedPcdGet32(PcdPciPrefetchMemoryBase)
+#define PCIE_PREFETCH_MEMORY_SPACE_SIZE FixedPcdGet32(PcdPciPrefetchMemorySize)
+
+#pragma pack(push, 1)
+
+typedef union {
+    UINT8   volatile  *buf;
+    UINT8   volatile  *ui8;
+    UINT16  volatile  *ui16;
+    UINT32  volatile  *ui32;
+    UINT64  volatile  *ui64;
+    UINTN   volatile  ui;
+} PTR;
+
+typedef struct {
+    UINT64 Base;
+    UINT64 Size;
+    UINT64 Curr;
+} PCI_RESOURCE;
+
+//
+// Debug register related bits
+//
+#define PCIE_PL_DEBUG1_PHY_LINK_UP          (1 << 4)
+#define PCIE_PL_DEBUG1_LINK_IN_TRAINING     (1 << 29)
+
+//
+// Address Translation Unit related definition
+//
+
+#define MAX_iATU_REGION          4
+
+typedef enum _REGION_DIRECTION {
+    OUTBOUND,
+    INBOUND,
+} REGION_DIRECTION;
+
+typedef enum _TLP_TYPE {
+    MEMORY_TYPE,
+    MEMORY_LOCK_TYPE,
+    IO_TYPE,
+    CFG0_TYPE = 4,
+    CFG1_TYPE = 5,
+} TLP_TYPE;
+
+typedef enum _REGION_STATE {
+    REGION_DISABLE = 0,
+    REGION_ENABLE = 0x80000000,
+} REGION_STATE;
+
+typedef struct {
+
+    UINT32 PCIE_PL_ALTRTR;          // ACK latency timer and replay timer
+    UINT32 PCIE_PL_VSDR;            // Vendor specific DLLP
+    UINT32 PCIE_PL_PFLR;            // Port force link
+    UINT32 PCIE_PL_AFLACR;          // ACK frequency and L0-L1 ASPM control
+    UINT32 PCIE_PL_PLCR;            // Port link control
+    UINT32 PCIE_PL_LSR;             // Lane skew
+    UINT32 PCIE_PL_SNR;             // Symbol number
+    UINT32 PCIE_PL_STRFM1;          // Symbol timer and filter mask 1
+    UINT32 PCIE_PL_STRFM2;          // Filter mask 2
+    UINT32 PCIE_PL_AMODNPSR;        // AMBA Multiple Outbound Decomposed NP Sub-Requests Control
+    UINT32 PCIE_PL_DEBUG0;          // Debug 0
+    UINT32 PCIE_PL_DEBUG1;          // Debug 1
+    UINT32 PCIE_PL_TPFCSR;          // Transmit Posted FC Credit Status
+    UINT32 PCIE_PL_TNFCSR;          // Transmit Non-Posted FC Credit Status
+    UINT32 PCIE_PL_TCFCSR;          // Transmit Completion FC Credit Status
+    UINT32 PCIE_PL_QSR;             // Queue status
+    UINT32 PCIE_PL_VCTAR1;          // Transmit Completion FC Status 1
+    UINT32 PCIE_PL_VCTAR2;          // Transmit Completion FC Status 1
+    UINT32 PCIE_PL_VC0PRQC;         // VC0 Posted Receive Queue Control
+    UINT32 PCIE_PL_VC0NRQC;         // VC0 Non-Posted Receive Queue Control
+    UINT32 PCIE_PL_VC0CRQC;         // VC0 Completion Receive Queue Control
+    UINT32 PCIE_PL_VCnPRQC;         // VCn Posted Receive Queue Control
+    UINT32 PCIE_PL_VCnNRQC;         // VCn Non-Posted Receive Queue Control
+    UINT32 PCIE_PL_VCnCRQC;         // VCn Completion Receive Queue Control
+    UINT32 PCIE_PL_RESERVED_0[18];
+    UINT32 PCIE_PL_VC0PBD;          // VC0 Posted Buffer Depth
+    UINT32 PCIE_PL_VC0NPBD;         // VC0 Non-Posted Buffer Depth
+    UINT32 PCIE_PL_VC0CBD;          // VC0 Completion Buffer Depth
+    UINT32 PCIE_PL_VC1PBD;          // VCn Posted Buffer Depth
+    UINT32 PCIE_PL_VC1NPBD;         // VCn Non-Posted Buffer Depth
+    UINT32 PCIE_PL_VC1CBD;          // VCn Completion Buffer Depth
+    UINT32 PCIE_PL_RESERVED_1[19];
+    UINT32 PCIE_PL_G2CR;            // Gen2 Control
+    UINT32 PCIE_PL_PHY_STATUS;      // PHY status
+    UINT32 PCIE_PL_PHY_CTRL;        // PHY control
+    UINT32 PCIE_PL_MRCCR0;          // Master Response Composer Control 0
+    UINT32 PCIE_PL_MRCCR1;          // Master Response Composer Control 1
+    UINT32 PCIE_PL_MSICA;           // MSI Controller Address
+    UINT32 PCIE_PL_MSICUA;          // MSI Controller Upper Address
+    UINT32 PCIE_PL_MSICIn_ENB;      // MSI Controller Interrupt n Enable
+    UINT32 PCIE_PL_MSICIn_MASK;     // MSI Controller Interrupt n Mask
+    UINT32 PCIE_PL_MSICIn_STATUS;   // MSI Controller Interrupt n Status
+    UINT32 PCIE_PL_RESERVED_2[21];
+    UINT32 PCIE_PL_MSICGPIO;        // MSI Controller General Purpose IO
+    UINT32 PCIE_PL_RESERVED_3[29];
+    UINT32 PCIE_PL_iATUVR;          // iATU Viewport
+    UINT32 PCIE_PL_iATURC1;         // iATU Control 1
+    UINT32 PCIE_PL_iATURC2;         // iATU Control 2
+    UINT32 PCIE_PL_iATURLBA;        // iATU Region Lower Base Address
+    UINT32 PCIE_PL_iATURUBA;        // iATU Region Upper Base Address
+    UINT32 PCIE_PL_iATURLA;         // iATU Region Limit Address
+    UINT32 PCIE_PL_iATURLTA;        // iATU Region Lower Target Address
+    UINT32 PCIE_PL_iATURUTA;        // iATU Region Upper Target Address
+} CSP_PCIE_PL_REGS, *PCSP_PCIE_PL_REGS;
+
+typedef struct _IATU_SETTINGS {
+    UINT32 RegionDirection;
+    UINT32 RegionIndex;
+    TLP_TYPE Type;
+    UINT32 LowerBaseAddr;
+    UINT32 UpperBaseAddr;
+    UINT32 LimitAddr;
+    UINT32 LowerTargetAddr;
+    UINT32 UpperTargetAddr;
+    UINT32 State;
+} IATU_SETTINGS, *PIATU_SETTINGS;
+
+#pragma pack(pop)
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.inf b/Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.inf
new file mode 100644
index 000000000000..e41c71b939cc
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.inf
@@ -0,0 +1,66 @@
+## @file
+#
+#  Copyright (c) Microsoft Corporation. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+  INF_VERSION       = 0x00010005
+  BASE_NAME         = iMX6PciExpress
+  FILE_GUID         = 5A7FB871-8A19-48D5-A268-441E79AAFD9E
+  MODULE_TYPE       = DXE_DRIVER
+  VERSION_STRING    = 1.0
+  ENTRY_POINT       = PCIeInitialize
+
+[Sources.common]
+  iMX6PciExpress.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  IntelFrameworkPkg/IntelFrameworkPkg.dec
+  ArmPkg/ArmPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Silicon/NXP/iMXPlatformPkg/iMXPlatformPkg.dec
+  Silicon/NXP/iMX6Pkg/iMX6Pkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DxeServicesTableLib
+  UefiLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+  UefiRuntimeServicesTableLib
+  IoLib
+  iMX6ClkPwrLib
+
+[Protocols]
+
+[Pcd]
+  giMX6TokenSpaceGuid.PcdPcieHostConfigBase
+  giMX6TokenSpaceGuid.PcdPcieDeviceConfigBase
+  giMX6TokenSpaceGuid.PcdPcieDeviceConfigSize
+  giMX6TokenSpaceGuid.PcdPcieIOBase
+  giMX6TokenSpaceGuid.PcdPcieIOSize
+  giMX6TokenSpaceGuid.PcdPciMemoryBase
+  giMX6TokenSpaceGuid.PcdPciMemorySize
+  giMX6TokenSpaceGuid.PcdPciPrefetchMemoryBase
+  giMX6TokenSpaceGuid.PcdPciPrefetchMemorySize
+  giMX6TokenSpaceGuid.PcdPcieResetGpio
+  giMX6TokenSpaceGuid.PcdPcieResetGpioBankNumber
+  giMX6TokenSpaceGuid.PcdPcieResetGpioIoNumber
+
+[FixedPcd]
+  giMXPlatformTokenSpaceGuid.PcdGpioBankMemoryRange
+
+[Depex]
+  gEfiMetronomeArchProtocolGuid AND
+  gEfiCpuArchProtocolGuid
-- 
2.16.2.gvfs.1.33.gf5370f1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH edk2-platforms 12/13] Silicon/NXP: Add i.MX6 GOP driver
  2018-07-20  6:33 [PATCH edk2-platforms 00/13] Silicon/NXP: Import NXP i.MX6 Package Chris Co
                   ` (10 preceding siblings ...)
  2018-07-20  6:34 ` [PATCH edk2-platforms 11/13] Silicon/NXP: Add i.MX6 PCIe DXE driver Chris Co
@ 2018-07-20  6:34 ` Chris Co
  2018-07-20  6:34 ` [PATCH edk2-platforms 13/13] Silicon/NXP: Add i.MX6 common dsc and fdf files Chris Co
  12 siblings, 0 replies; 14+ messages in thread
From: Chris Co @ 2018-07-20  6:34 UTC (permalink / raw)
  To: edk2-devel@lists.01.org; +Cc: Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This adds GOP display support for NXP i.MX6 SoCs.  It has support for
HDMI, LVDS, IPU, and parses EDID using I2C.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Christopher Co <christopher.co@microsoft.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/NXP/iMX6Pkg/Drivers/GOP/CPMem.c             | 327 +++++++++++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/CPMem.h             | 276 +++++++++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Ddc.c               |  58 ++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Ddc.h               |  27 +
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Display.c           | 442 ++++++++++++++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Display.h           | 171 ++++++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayController.c | 388 +++++++++++++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayController.h | 312 ++++++++++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayInterface.c  | 444 ++++++++++++++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayInterface.h  | 182 ++++++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Edid.c              |  82 +++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Edid.h              |  31 +
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Hdmi.c              | 608 ++++++++++++++++++++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Hdmi.h              | 537 +++++++++++++++++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/IoMux.c             |  83 +++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/IoMux.h             |  31 +
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Ipu.h               | 236 ++++++++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Lvds.c              |  81 +++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Lvds.h              |  72 +++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Osal.c              |  38 ++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/Osal.h              |  74 +++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/iMX6GOP.inf         |  71 +++
 Silicon/NXP/iMX6Pkg/Drivers/GOP/iMXVideoDxe.c       | 488 ++++++++++++++++
 23 files changed, 5059 insertions(+)

diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/CPMem.c b/Silicon/NXP/iMX6Pkg/Drivers/GOP/CPMem.c
new file mode 100644
index 000000000000..cf05a13d95e5
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/CPMem.c
@@ -0,0 +1,327 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "Osal.h"
+
+#include "Display.h"
+#include "CPMem.h"
+#include "Ipu.h"
+
+CPMEM_PARAM* CpMemParamBasePtr = (CPMEM_PARAM*)(IPU1_BASE + CSP_IPUV3_CPMEM_REGS_OFFSET);
+
+VOID DumpCPMEMParamPack (CPMEM_PARAM* ParamPtr)
+{
+    OS_INFO("--WORD0--\n");
+    OS_INFO("XVVirtualCoordinate 0x%08x\n", ParamPtr->Word0Pack.XVVirtualCoordinate);
+    OS_INFO("YVVirtualCoordinate 0x%08x\n", ParamPtr->Word0Pack.YVVirtualCoordinate);
+    OS_INFO("XBinnerBlockCoordinate 0x%08x\n", ParamPtr->Word0Pack.XBinnerBlockCoordinate);
+    OS_INFO("YBinnerBlockCoordinate 0x%08x\n", ParamPtr->Word0Pack.YBinnerBlockCoordinate);
+    OS_INFO("NewSubBlock 0x%08x\n", ParamPtr->Word0Pack.NewSubBlock);
+    OS_INFO("CurrentField 0x%08x\n", ParamPtr->Word0Pack.CurrentField);
+    OS_INFO("ScrollXCounter 0x%08x\n", ParamPtr->Word0Pack.ScrollXCounter);
+    OS_INFO("ScrollYCounter 0x%08x\n", ParamPtr->Word0Pack.ScrollYCounter);
+    OS_INFO("NumberOfScroll 0x%08x\n", ParamPtr->Word0Pack.NumberOfScroll);
+    OS_INFO("ScrollDeltaX 0x%08x\n", ParamPtr->Word0Pack.ScrollDeltaX);
+    OS_INFO("ScrollMax 0x%08x\n", ParamPtr->Word0Pack.ScrollMax);
+    OS_INFO("ScrollingConfiguration 0x%08x\n", ParamPtr->Word0Pack.ScrollingConfiguration);
+    OS_INFO("ScrollingEnable 0x%08x\n", ParamPtr->Word0Pack.ScrollingEnable);
+    OS_INFO("ScrollDeltaY 0x%08x\n", ParamPtr->Word0Pack.ScrollDeltaY);
+    OS_INFO("ScrollHorizontalDirection 0x%08x\n", ParamPtr->Word0Pack.ScrollHorizontalDirection);
+    OS_INFO("ScrollVerticalDirection 0x%08x\n", ParamPtr->Word0Pack.ScrollVerticalDirection);
+    OS_INFO("BitsPerPixel 0x%08x\n", ParamPtr->Word0Pack.BitsPerPixel);
+    OS_INFO("DecodeAddressSelect 0x%08x\n", ParamPtr->Word0Pack.DecodeAddressSelect);
+    OS_INFO("AccessDimension 0x%08x\n", ParamPtr->Word0Pack.AccessDimension);
+    OS_INFO("ScanOrder 0x%08x\n", ParamPtr->Word0Pack.ScanOrder);
+    OS_INFO("BandMode 0x%08x\n", ParamPtr->Word0Pack.BandMode);
+    OS_INFO("BlockMode 0x%08x\n", ParamPtr->Word0Pack.BlockMode);
+    OS_INFO("Rotation 0x%08x\n", ParamPtr->Word0Pack.Rotation);
+    OS_INFO("HorizontalFlip 0x%08x\n", ParamPtr->Word0Pack.HorizontalFlip);
+    OS_INFO("VerticalFlip 0x%08x\n", ParamPtr->Word0Pack.VerticalFlip);
+    OS_INFO("ThresholdEnable 0x%08x\n", ParamPtr->Word0Pack.ThresholdEnable);
+    OS_INFO("ConditionalAccessPolarity 0x%08x\n", ParamPtr->Word0Pack.ConditionalAccessPolarity);
+    OS_INFO("ConditionalAccessEnable 0x%08x\n", ParamPtr->Word0Pack.ConditionalAccessEnable);
+    OS_INFO("FrameWidth 0x%08x\n", ParamPtr->Word0Pack.FrameWidth);
+    OS_INFO("FrameHeight 0x%08x\n", ParamPtr->Word0Pack.FrameHeight);
+    OS_INFO("EndOfLineInterrupt 0x%08x\n", ParamPtr->Word0Pack.EndOfLineInterrupt);
+
+    OS_INFO("--WORD1--\n");
+    OS_INFO("ExtMemBuffer0Address 0x%08x\n", ParamPtr->Word1Pack.ExtMemBuffer0Address);
+    OS_INFO("ExtMemBuffer1Address 0x%08x\n", ParamPtr->Word1Pack.ExtMemBuffer1Address);
+    OS_INFO("InterlaceOffset 0x%08x\n", ParamPtr->Word1Pack.InterlaceOffset);
+    OS_INFO("NumberOfPixelsInWholeBurstAccess 0x%08x\n", ParamPtr->Word1Pack.NumberOfPixelsInWholeBurstAccess);
+    OS_INFO("PixelFormatSelect 0x%08x\n", ParamPtr->Word1Pack.PixelFormatSelect);
+    OS_INFO("AlphaUsed 0x%08x\n", ParamPtr->Word1Pack.AlphaUsed);
+    OS_INFO("AlphaChannelMapping 0x%08x\n", ParamPtr->Word1Pack.AlphaChannelMapping);
+    OS_INFO("AxiId 0x%08x\n", ParamPtr->Word1Pack.AxiId);
+    OS_INFO("Threshold 0x%08x\n", ParamPtr->Word1Pack.Threshold);
+    OS_INFO("StrideLine 0x%08x\n", ParamPtr->Word1Pack.StrideLine);
+    OS_INFO("Width0 0x%08x\n", ParamPtr->Word1Pack.Width0);
+    OS_INFO("Width1 0x%08x\n", ParamPtr->Word1Pack.Width1);
+    OS_INFO("Width2 0x%08x\n", ParamPtr->Word1Pack.Width2);
+    OS_INFO("Width3 0x%08x\n", ParamPtr->Word1Pack.Width3);
+    OS_INFO("Offset0 0x%08x\n", ParamPtr->Word1Pack.Offset0);
+    OS_INFO("Offset1 0x%08x\n", ParamPtr->Word1Pack.Offset1);
+    OS_INFO("Offset2 0x%08x\n", ParamPtr->Word1Pack.Offset2);
+    OS_INFO("Offset3 0x%08x\n", ParamPtr->Word1Pack.Offset3);
+    OS_INFO("SelectSXSYSet 0x%08x\n", ParamPtr->Word1Pack.SelectSXSYSet);
+    OS_INFO("ConditionalReadEnable 0x%08x\n", ParamPtr->Word1Pack.ConditionalReadEnable);
+}
+
+VOID DumpBasicCPMEMReg (
+    CPMEM_PARAM* CpmemChannel)
+{
+    OS_INFO("---------- CPMEM Register Dump ----------\n");
+    OS_INFO("CPMEM\n");
+    OS_INFO("IDMAC_CHANNEL_DP_PRIMARY_FLOW_MAIN_PLANE\n");
+    DumpCPMEMParamPack(CpmemChannel);
+    OS_INFO("------------------------------------\n");
+}
+
+//
+// Enable IDMAC lock setting, which optimises memory accesses and reduces
+// power consumption
+//
+VOID SetIdmacLockEn(
+    DISPLAY_INTERFACE_CONTEXT* DIContextPtr,
+    UINT32 Channel,
+    UINT32 Setting
+    )
+{
+    static const UINT8 channelMap[] = {
+        5, 0,
+        11, 2,
+        12, 4,
+        14, 6,
+        15, 8,
+        20, 10,
+        21, 12,
+        22, 14,
+        23, 16,
+        27, 18,
+        28, 20,
+        45, 0,
+        46, 2,
+        47, 4,
+        48, 6,
+        49, 8,
+        50, 10,
+    };
+
+    UINTN lockReg;
+    UINT32 value;
+    int shift = -1;
+    int i;
+
+    for (i = 0; i < (sizeof(channelMap) / sizeof(channelMap[0])); i += 2) {
+        if (channelMap[i] == Channel) {
+            shift = channelMap[i + 1];
+            break;
+        }
+    }
+
+    if (shift == -1) {
+        OS_WARNING("Channel %d does not have lock bits", Channel);
+        return;
+    }
+
+    if (Channel < 29) {
+        lockReg = (UINTN)DIContextPtr->IpuMmioBasePtr + IPU_IDMAC_LOCK_EN_1;
+    } else {
+        lockReg = (UINTN)DIContextPtr->IpuMmioBasePtr + IPU_IDMAC_LOCK_EN_2;
+    }
+
+    value = OS_READ32(lockReg);
+    value &= ~(0x3 << shift);
+    value |= (Setting & 0x3) << shift;
+    OS_WRITE32(lockReg, value);
+}
+
+OS_STATUS ConfigureCPMEMFrameBuffer (
+    DISPLAY_INTERFACE_CONTEXT* DIContextPtr,
+    UINT32 Channel,
+    SURFACE_INFO* FrameBufferPtr)
+{
+    OS_STATUS status;
+    CPMEM_WORD0_PACKED_REG cpmemWord0PackedReg;
+    CPMEM_WORD1_PACKED_REG cpmemWord1PackedReg;
+    CPMEM_DEC_SEL decodeAddressSelect = CPMEM_DEC_SEL_0_15; // Only applicable for 4 bpp
+    UINT32 pixelBurst = 1;
+    CPMEM_PFS_PACKED pixelFormatSelector;
+    UINT32 width0, width1, width2, width3;
+    UINT32 offset0, offset1, offset2, offset3;
+    UINT32 bytesPerPixel;
+    CPMEM_PARAM* cpmemChannel = DIContextPtr->CpMemParamBasePtr;
+
+    OS_ZERO_MEM(&cpmemWord0PackedReg, sizeof(cpmemWord0PackedReg));
+    OS_ZERO_MEM(&cpmemWord1PackedReg, sizeof(cpmemWord1PackedReg));
+
+    switch (FrameBufferPtr->PixelFormat)
+    {
+    case PIXEL_FORMAT_BGRA32:
+        pixelBurst = 15; // 16 Pixel. Valid range is 1 - 64 pixel
+        pixelFormatSelector = CPMEM_PFS_RGB;
+        offset0 = 8;
+        offset1 = 16;
+        offset2 = 24;
+        offset3 = 0;
+        bytesPerPixel = 4;
+        break;
+    default:
+        ASSERT(FALSE);
+        status = OS_STATUS_UNSUPPORTED;
+        goto Exit;
+    }
+
+    switch (FrameBufferPtr->Bpp)
+    {
+    case 8:
+        width0 = width1 = width2 = width3 = 0;
+        break;
+    case 32:
+        if (pixelFormatSelector == CPMEM_PFS_RGB) {
+            width0 = width1 = width2 = width3 = 7;
+        } else {
+            width0 = width1 = width2 = width3 = 0;
+        }
+        break;
+    default:
+        ASSERT(FALSE);
+        status = OS_STATUS_UNSUPPORTED;
+        goto Exit;
+    }
+
+    // Setting up CPMEM word 0
+    cpmemWord0PackedReg.XVVirtualCoordinate = 0;
+    cpmemWord0PackedReg.YVVirtualCoordinate = 0;
+
+    // Subblock is unused although expect to have some value after write
+    cpmemWord0PackedReg.XBinnerBlockCoordinate = 0;
+    cpmemWord0PackedReg.YBinnerBlockCoordinate = 0;
+    cpmemWord0PackedReg.NewSubBlock = 0;
+
+    // Verify "current field" definition
+    cpmemWord0PackedReg.CurrentField = 0;
+
+    // Disable scrolling
+    cpmemWord0PackedReg.ScrollXCounter= 0;
+    cpmemWord0PackedReg.ScrollYCounter = 0;
+    cpmemWord0PackedReg.NumberOfScroll = 0;
+    cpmemWord0PackedReg.ScrollDeltaX = 0;
+    cpmemWord0PackedReg.ScrollMax = 0;
+    cpmemWord0PackedReg.ScrollingConfiguration = 0;
+    cpmemWord0PackedReg.ScrollingEnable = 0;
+    cpmemWord0PackedReg.ScrollDeltaY = 0;
+    cpmemWord0PackedReg.ScrollHorizontalDirection = 0;
+    cpmemWord0PackedReg.ScrollVerticalDirection = 0;
+
+    // Bits per pixel
+    cpmemWord0PackedReg.BitsPerPixel = FrameBufferPtr->Bpp;
+
+    // Decode Address Select
+    cpmemWord0PackedReg.DecodeAddressSelect = decodeAddressSelect;
+
+    // Scan order is progressive no support for interlace mode
+    cpmemWord0PackedReg.ScanOrder = CPMEM_SO_PROGRESSIVE;
+
+    // Band mode is sub frame double buffering
+    cpmemWord0PackedReg.BandMode = CPMEM_BNDM_DISABLE;
+
+    // Block mode used for post filtering and rotation
+    cpmemWord0PackedReg.BlockMode = CPMEM_BM_DISABLE;
+
+    // No support for rotation and flipping for now
+    cpmemWord0PackedReg.Rotation = CPMEM_ROT_NO_ROTATION;
+    cpmemWord0PackedReg.HorizontalFlip = CPMEM_HF_NO_HFLIP;
+    cpmemWord0PackedReg.VerticalFlip = CPMEM_HF_NO_VFLIP;
+    cpmemWord0PackedReg.ThresholdEnable = CPMEM_THE_DISABLE;
+
+    // Disable conditional access
+    cpmemWord0PackedReg.ConditionalAccessEnable = CPMEM_CAP_SKIP_LOW;
+    cpmemWord0PackedReg.ConditionalAccessPolarity = CPMEM_CAE_DISABLE;
+
+    // Frame width and height, minus one as 0 == 1 pixel
+    cpmemWord0PackedReg.FrameWidth = FrameBufferPtr->Width - 1;
+    cpmemWord0PackedReg.FrameHeight = FrameBufferPtr->Height - 1;
+
+    // No interrupt required at the end of line
+    cpmemWord0PackedReg.EndOfLineInterrupt = CPMEM_EOLI_DISABLE;
+
+    // Setting up CPMEM word 1
+    // Buffer 0, use the [31:3] bit address
+    cpmemWord1PackedReg.ExtMemBuffer0Address = FrameBufferPtr->PhyAddr >> 3;
+
+    // Buffer 1, use the same buffer for now
+    cpmemWord1PackedReg.ExtMemBuffer1Address = FrameBufferPtr->PhyAddr >> 3;
+
+    // Currently do not support interlace mode
+    cpmemWord1PackedReg.InterlaceOffset = 0;
+
+    // Pixel format and burst
+    cpmemWord1PackedReg.NumberOfPixelsInWholeBurstAccess = pixelBurst;
+    cpmemWord1PackedReg.PixelFormatSelect = pixelFormatSelector;
+
+    // Alpha config
+    cpmemWord1PackedReg.AlphaUsed = CPMEM_ALU_SAME_BUFFER;
+
+    // AXI ID 0 should be okay, we don't have anything else contending for it
+    cpmemWord1PackedReg.AxiId = CPMEM_ID_ID_0;
+
+    cpmemWord1PackedReg.Threshold = CPMEM_THE_DISABLE;
+
+    // Stride, width and offset
+    cpmemWord1PackedReg.StrideLine =
+        (FrameBufferPtr->Pitch * bytesPerPixel) - 1;
+    cpmemWord1PackedReg.Width0 = width0;
+    cpmemWord1PackedReg.Width1 = width1;
+    cpmemWord1PackedReg.Width2 = width2;
+    cpmemWord1PackedReg.Width3 = width3;
+    cpmemWord1PackedReg.Offset0 = offset0;
+    cpmemWord1PackedReg.Offset1 = offset1;
+    cpmemWord1PackedReg.Offset2 = offset2;
+    cpmemWord1PackedReg.Offset3 = offset3;
+
+    // SX SY is ignored since scrolling is disabled
+    cpmemWord1PackedReg.SelectSXSYSet = 0;
+
+    // Conditional read is always enabled so fully transperant pixel are
+    // not read.
+    cpmemWord1PackedReg.ConditionalReadEnable = CPMEM_CRE_ENABLE;
+
+    // Finallu write into cpmem IDMAC channel
+    cpmemChannel = (cpmemChannel + Channel);
+
+    OS_MEM_COPY(
+        &cpmemChannel->Word0Pack,
+        &cpmemWord0PackedReg,
+        sizeof(cpmemChannel->Word0Pack));
+
+    OS_MEM_COPY(
+        &cpmemChannel->Word1Pack,
+        &cpmemWord1PackedReg,
+        sizeof(cpmemChannel->Word1Pack));
+
+    // IDMAC will generate 8 AXI bursts upon assertion of the DMA request
+    // This significantly reduces memory activity and power consumption
+    SetIdmacLockEn(DIContextPtr, Channel, 0x3);
+
+    // Register dump, commented out by default
+#ifdef REGISTER_DUMP
+    DumpBasicCPMEMReg(cpmemChannel);
+#endif
+
+    status = OS_STATUS_SUCCESS;
+
+Exit:
+    return status;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/CPMem.h b/Silicon/NXP/iMX6Pkg/Drivers/GOP/CPMem.h
new file mode 100644
index 000000000000..27bf75decbb2
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/CPMem.h
@@ -0,0 +1,276 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _CPMEM_H_
+#define _CPMEM_H_
+
+// IDMAC channel definition
+#define IDMAC_CHANNEL_CSI_0                                 0
+#define IDMAC_CHANNEL_CSI_1                                 1
+#define IDMAC_CHANNEL_CSI_2                                 2
+#define IDMAC_CHANNEL_CSI_3                                 3
+#define IDMAC_CHANNEL_VDIC_VF1_VF2                          5
+#define IDMAC_CHANNEL_VDIC_PREVIOUS_FIELD                   8
+#define IDMAC_CHANNEL_VDIC_CURRENT_FIELD                    9
+#define IDMAC_CHANNEL_VDIC_NEXT_FIELD                       10
+#define IDMAC_CHANNEL_IC_VIDEO_POST_PROCESSSING             11
+#define IDMAC_CHANNEL_IC_VIDEO_PRP_TASK                     12
+
+#define IDMAC_CHANNEL_DP_PRIMARY_FLOW_MAIN_PLANE            23
+
+typedef enum {
+    CPMEM_SO_PROGRESSIVE,
+    CPMEM_SO_INTERLACE,
+} CPMEM_SO;
+
+typedef enum {
+    CPMEM_BNDM_DISABLE,
+    CPMEM_BNDM_BAND_HEIGHT_4,
+    CPMEM_BNDM_BAND_HEIGHT_8,
+    CPMEM_BNDM_BAND_HEIGHT_16,
+    CPMEM_BNDM_BAND_HEIGHT_32,
+    CPMEM_BNDM_BAND_HEIGHT_64,
+    CPMEM_BNDM_BAND_HEIGHT_128,
+    CPMEM_BNDM_BAND_HEIGHT_256,
+} CPMEM_BNDM;
+
+typedef enum {
+    CPMEM_BM_DISABLE,
+    CPMEM_BM_BW_BH_8,
+    CPMEM_BM_BW_BH_16,
+    CPMEM_BM_UNUSED,
+} CPMEM_BM;
+
+typedef enum {
+    CPMEM_ROT_NO_ROTATION,
+    CPMEM_ROT_90_ROTATION,
+} CPMEM_ROT;
+
+typedef enum {
+    CPMEM_HF_NO_HFLIP,
+    CPMEM_HF_HFLIP_ENABLE,
+} CPMEM_HF;
+
+typedef enum {
+    CPMEM_HF_NO_VFLIP,
+    CPMEM_HF_VFLIP_ENABLE,
+} CPMEM_VF;
+
+typedef enum {
+    CPMEM_THE_DISABLE,
+    CPMEM_THE_ENABLE,
+} CPMEM_THE;
+
+typedef enum {
+    CPMEM_CAP_SKIP_LOW,
+    CPMEM_CAP_SKIP_HIGH,
+} CPMEM_CAP;
+
+typedef enum {
+    CPMEM_CAE_DISABLE,
+    CPMEM_CAE_ENABLE,
+} CPMEM_CAE;
+
+typedef enum {
+    CPMEM_EOLI_DISABLE,
+    CPMEM_EOLI_ENABLE,
+} CPMEM_EOLI;
+
+typedef enum {
+    CPMEM_PFS_NON_INT_444,
+    CPMEM_PFS_NON_INT_422,
+    CPMEM_PFS_NON_INT_420,
+    CPMEM_PFS_PAR_INT_422,
+    CPMEM_PFS_PAR_INT_420,
+} CPMEM_PFS_PLANAR;
+
+typedef enum {
+    CPMEM_DEC_SEL_0_15,
+    CPMEM_DEC_SEL_64_79,
+    CPMEM_DEC_SEL_128_143,
+    CPMEM_DEC_SEL_192_207,
+} CPMEM_DEC_SEL;
+
+typedef enum {
+    CPMEM_PFS_CODE = 5,
+    CPMEM_PFS_GENERIC_DATA,
+    CPMEM_PFS_RGB,
+    CPMEM_PFS_INT_422_Y1U1Y2V1,
+    CPMEM_PFS_INT_422_Y2U1Y1V1,
+    CPMEM_PFS_INT_422_U1Y1V1Y2,
+    CPMEM_PFS_INT_422_U1Y2V1Y1,
+} CPMEM_PFS_PACKED;
+
+typedef enum {
+    CPMEM_ALU_SAME_BUFFER,
+    CPMEM_ALU_SEPERATE_BUFFER,
+} CPMEM_ALU;
+
+typedef enum {
+    CPMEM_ID_ID_0,
+    CPMEM_ID_ID_1,
+    CPMEM_ID_ID_2,
+    CPMEM_ID_ID_3,
+} CPMEM_ID;
+
+typedef enum {
+    CPMEM_CRE_DISABLE,
+    CPMEM_CRE_ENABLE,
+} CPMEM_CRE;
+
+#pragma pack(push, 1)
+
+// CPMEM_WORD0_PLANAR - Non interlaved
+typedef union {
+    struct {
+        UINT32 XVVirtualCoordinate : 10;
+        UINT32 YVVirtualCoordinate : 9;
+        UINT32 XBinnerBlockCoordinate : 13;
+        UINT32 YBinnerBlockCoordinate : 12;
+        UINT32 NewSubBlock : 1;
+        UINT32 CurrentField : 1;
+        UINT32 MemUBufferOffset : 22;
+        UINT32 MemVBufferOffset : 22;
+        UINT32 InitialOffsetX : 4;
+        UINT32 ReduceDoubleReadOrWrites : 1;
+        UINT32 Reserved1 : 18;
+        UINT32 ScanOrder : 1;
+        UINT32 BandMode : 3;
+        UINT32 BlockMode : 2;
+        UINT32 Rotation : 1;
+        UINT32 HorizontalFlip : 1;
+        UINT32 VerticalFlip : 1;
+        UINT32 ThresholdEnable : 1;
+        UINT32 ConditionalAccessPolarity : 1;
+        UINT32 ConditionalAccessEnable : 1;
+        UINT32 FrameWidth : 13; // Max 8192 Pixel
+        UINT32 FrameHeight : 12; // Max 4096 Pixel
+        UINT32 EndOfLineInterrupt : 1;
+        UINT32 Reserved2 : 9;
+    };
+    UINT32 Word0[5];
+} CPMEM_WORD0_PLANAR_REG;
+
+// CPMEM_WORD1_PLANAR - Non interleaved
+typedef union {
+    struct {
+        UINT32 ExtMemBuffer0Address : 29;
+        UINT32 ExtMemBuffer1Address : 29;
+        UINT32 InterlaceOffset : 20;
+        UINT32 NumberOfPixelsInWholeBurstAccess : 7;
+        UINT32 PixelFormatSelect : 4;
+        UINT32 AlphaUsed : 1;
+        UINT32 AlphaChannelMapping : 3;
+        UINT32 AxiId : 2;
+        UINT32 Threshold : 7;
+        UINT32 StrideLine : 14;
+        UINT32 Reserved1 : 9;
+        UINT32 Width3 : 3;
+        UINT32 StrideLineUV : 14;
+        UINT32 Reserved2 : 7;
+        UINT32 ConditionalReadEnable : 1;
+        UINT32 Reserved3 : 10;
+    };
+    UINT32 Word1[5];
+} CPMEM_WORD1_PLANAR_REG;
+
+// CPMEM_WORD0_PACKED - Interlaved
+typedef union {
+    struct {
+        UINT32 XVVirtualCoordinate : 10;
+        UINT32 YVVirtualCoordinate : 9;
+        UINT32 XBinnerBlockCoordinate : 13;
+        UINT32 YBinnerBlockCoordinate : 12;
+        UINT32 NewSubBlock : 1;
+        UINT32 CurrentField : 1;
+        UINT32 ScrollXCounter : 12;
+        UINT32 ScrollYCounter : 11;
+        UINT32 NumberOfScroll : 10;
+        UINT32 ScrollDeltaX : 7;
+        UINT32 ScrollMax : 10;
+        UINT32 ScrollingConfiguration : 1;
+        UINT32 ScrollingEnable : 1;
+        UINT32 ScrollDeltaY : 7;
+        UINT32 ScrollHorizontalDirection : 1;
+        UINT32 ScrollVerticalDirection : 1;
+        UINT32 BitsPerPixel : 3;
+        UINT32 DecodeAddressSelect : 2;
+        UINT32 AccessDimension : 1;
+        UINT32 ScanOrder : 1;
+        UINT32 BandMode : 3;
+        UINT32 BlockMode : 2;
+        UINT32 Rotation : 1;
+        UINT32 HorizontalFlip : 1;
+        UINT32 VerticalFlip : 1;
+        UINT32 ThresholdEnable : 1;
+        UINT32 ConditionalAccessPolarity : 1;
+        UINT32 ConditionalAccessEnable : 1;
+        UINT32 FrameWidth : 13; // Max 8192 Pixel
+        UINT32 FrameHeight : 12; // Max 4096 Pixel
+        UINT32 EndOfLineInterrupt : 1;
+        UINT32 Reserved2 : 9;
+    };
+    UINT32 Word0[5];
+} CPMEM_WORD0_PACKED_REG;
+
+// CPMEM_WORD1_PACKED - Non interleaved
+typedef union {
+    struct {
+        UINT32 ExtMemBuffer0Address : 29;
+        UINT32 ExtMemBuffer1Address : 29;
+        UINT32 InterlaceOffset : 20;
+        UINT32 NumberOfPixelsInWholeBurstAccess : 7;
+        UINT32 PixelFormatSelect : 4;
+        UINT32 AlphaUsed : 1;
+        UINT32 AlphaChannelMapping : 3;
+        UINT32 AxiId : 2;
+        UINT32 Threshold : 7;
+        UINT32 StrideLine : 14;
+        UINT32 Width0 : 3;
+        UINT32 Width1 : 3;
+        UINT32 Width2 : 3;
+        UINT32 Width3 : 3;
+        UINT32 Offset0 : 5;
+        UINT32 Offset1 : 5;
+        UINT32 Offset2 : 5;
+        UINT32 Offset3 : 5;
+        UINT32 SelectSXSYSet : 1;
+        UINT32 ConditionalReadEnable : 1;
+        UINT32 Reserved1 : 10;
+    };
+    UINT32 Word1[5];
+} CPMEM_WORD1_PACKED_REG;
+
+typedef struct _CPMEM_PARAM {
+    union {
+        CPMEM_WORD0_PLANAR_REG Word0Planar;
+        CPMEM_WORD0_PACKED_REG Word0Pack;
+    };
+    UINT32 Reserved1[3];
+    union {
+        CPMEM_WORD1_PLANAR_REG Word1Planar;
+        CPMEM_WORD1_PACKED_REG Word1Pack;
+    };
+    UINT32 Reserved2[3];
+}CPMEM_PARAM, *PCPMEM_PARAM;
+
+#pragma pack(pop)
+
+OS_STATUS ConfigureCPMEMFrameBuffer (
+    DISPLAY_INTERFACE_CONTEXT* DIContextPtr,
+    UINT32 Channel,
+    SURFACE_INFO* FrameBufferPtr
+    );
+
+#endif
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/Ddc.c b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Ddc.c
new file mode 100644
index 000000000000..fc128760df32
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Ddc.c
@@ -0,0 +1,58 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Copyright 2018 NXP
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "osal.h"
+
+#include "Display.h"
+#include "Edid.h"
+#include "Ddc.h"
+#include "Hdmi.h"
+#include "Lvds.h"
+
+OS_STATUS IMX6DDCRead (
+    DISPLAY_CONTEXT* DisplayContextPtr,
+    DISPLAY_INTERFACE DisplayInterface,
+    UINT8 SlaveAddress,
+    UINT8 RegisterAddress,
+    UINT32 ReadSize,
+    UINT8* DataReadPtr)
+{
+    OS_STATUS status;
+
+    switch (DisplayInterface)
+    {
+    case HDMI_DISPLAY:
+        status = HDMIDDCRead(
+            &DisplayContextPtr->DIContext[HDMI_DISPLAY],
+            SlaveAddress,
+            RegisterAddress,
+            ReadSize,
+            HDMI_DDC_STANDARD_MODE,
+            DataReadPtr);
+        if (status != OS_STATUS_SUCCESS) {
+            OS_ERROR("HDMIDDCRead failed\n");
+        }
+        break;
+    case MIPI_DISPLAY:
+    case LVDS0_DISPLAY:
+    case LVDS1_DISPLAY:
+    default:
+        status = OS_STATUS_UNSUPPORTED;
+        break;
+    }
+
+    return status;
+}
+
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/Ddc.h b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Ddc.h
new file mode 100644
index 000000000000..169af54aa6b4
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Ddc.h
@@ -0,0 +1,27 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _DDC_H_
+#define _DDC_H_
+
+OS_STATUS IMX6DDCRead (
+    DISPLAY_CONTEXT* DisplayContextPtr,
+    DISPLAY_INTERFACE DisplayInterface,
+    UINT8 SlaveAddress,
+    UINT8 RegisterAddress,
+    UINT32 ReadSize,
+    UINT8* DataReadPtr
+    );
+
+#endif
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/Display.c b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Display.c
new file mode 100644
index 000000000000..801b3cf4edd4
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Display.c
@@ -0,0 +1,442 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Copyright 2018 NXP
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "Osal.h"
+
+// Display muxing register
+#include "iMX6.h"
+
+#include "Display.h"
+#include "Edid.h"
+#include "Hdmi.h"
+#include "Lvds.h"
+#include "DisplayInterface.h"
+#include "DisplayController.h"
+#include "CPMem.h"
+#include "Ipu.h"
+#include "IoMux.h"
+
+DISPLAY_TIMING DefaultTiming =
+{
+    65000000,   // PixelClock
+    1024,       // HActive
+    320,        // HBlank
+    768,        // VActive
+    38,         // VBlank
+    136,        // HSync
+    6,          // VSync
+    24,         // HSyncOffset;
+    3,          // VSyncOffset;
+    1024,       // HImageSize
+    768,        // VImageSize
+    0,          // HBorder
+    0,          // VBorder
+    0,          // EdidFlags
+    0,          // Flags
+    1,          // PixelRepetition
+    32,          // Bpp
+    PIXEL_FORMAT_BGRA32,       // PixelFormat
+};
+
+DISPLAY_TIMING Hannstar_XGA =
+{
+    65000000,   // PixelClock
+    1024,       // HActive
+    320,        // HBlank
+    768,        // VActive
+    38,         // VBlank
+    60,         // HSync
+    10,         // VSync
+    24,         // HSyncOffset;
+    3,          // VSyncOffset;
+    1024,       // HImageSize
+    768,        // VImageSize
+    0,          // HBorder
+    0,          // VBorder
+    0,          // EdidFlags
+    0,          // Flags
+    1,          // PixelRepetition
+    32,         // Bpp
+    PIXEL_FORMAT_BGRA32,       // PixelFormat
+};
+
+OS_STATUS GetPreferedTiming (
+    UINT8* EdidDataPtr,
+    UINT32 EdidDataSize,
+    DISPLAY_TIMING* PreferredTimingPtr
+    )
+{
+    OS_STATUS status;
+
+    if (FeaturePcdGet(PcdLvdsEnable)) {
+        *PreferredTimingPtr = Hannstar_XGA;
+        status = OS_STATUS_SUCCESS;
+    } else {
+        status = GetEDIDPreferedTiming(
+            EdidDataPtr,
+            EdidDataSize,
+            PreferredTimingPtr);
+        if (status != OS_STATUS_SUCCESS) {
+            // If EDID is unavailable use the default timing
+            status = OS_STATUS_SUCCESS;
+            *PreferredTimingPtr = DefaultTiming;
+            OS_WARNING("EDID data not available, falling back to default timing\n");
+        }
+    }
+
+    // Only support 8 bit per pixel and no pixel pixel repetition for now
+    PreferredTimingPtr->PixelRepetition = 1;
+    PreferredTimingPtr->PixelFormat = PIXEL_FORMAT_BGRA32;
+    PreferredTimingPtr->Bpp = 32;
+
+#ifdef DEBUG
+    PrintDisplayTiming(
+        "Preferred Timing",
+        PreferredTimingPtr);
+#endif
+    OS_WARNING("--GetPreferedTiming()\r\n");
+    return status;
+}
+
+OS_STATUS InitDisplay (
+    DISPLAY_CONTEXT** DisplayConfigPPtr
+    )
+{
+    OS_STATUS status;
+    DISPLAY_INTERFACE displayCounter;
+    DISPLAY_CONTEXT* tempDisplayContext;
+
+    status = OS_ALLOC_CONTIGUOUS_MEMORY(
+        sizeof(*tempDisplayContext),
+        &tempDisplayContext);
+    if (status != OS_STATUS_SUCCESS) {
+        OS_ERROR("Fail to allocate display context\n");
+        goto Exit;
+    }
+
+    OS_ZERO_MEM(tempDisplayContext, sizeof(*tempDisplayContext));
+
+    tempDisplayContext->IoMuxMmioBasePtr =
+        (VOID*)OS_MMIO_MAP(IOMUXC_GPR_BASE_ADDRESS);
+    if (tempDisplayContext->IoMuxMmioBasePtr == NULL) {
+        OS_ERROR("Fail to map IO Mux register");
+        goto Exit;
+    }
+
+    tempDisplayContext->IpuMmioBasePtr[IPU1] =
+        (VOID*)OS_MMIO_MAP(IPU1_BASE);
+    if (tempDisplayContext->IoMuxMmioBasePtr == NULL) {
+        OS_ERROR("Fail to map IPU1 IO Mux register");
+        goto Exit;
+    }
+#if !defined(CPU_IMX6SDL)
+    tempDisplayContext->IpuMmioBasePtr[IPU2] =
+        (VOID*)OS_MMIO_MAP(IPU2_BASE);
+    if (tempDisplayContext->IoMuxMmioBasePtr == NULL) {
+        OS_ERROR("Fail to map IPU2 IO Mux register");
+        goto Exit;
+    }
+#endif
+    for (displayCounter = HDMI_DISPLAY;
+         displayCounter < MAX_DISPLAY;
+         ++displayCounter) {
+        tempDisplayContext->DIContext[displayCounter].displayInterface =
+            displayCounter;
+    }
+
+    if (FeaturePcdGet(PcdLvdsEnable)) {
+        status = InitLVDS(tempDisplayContext);
+        if (status != OS_STATUS_SUCCESS) {
+            OS_ERROR("Fail to intialize LVDS\n");
+            goto Exit;
+        }
+    } else {
+        status = InitHDMI(tempDisplayContext);
+        if (status != OS_STATUS_SUCCESS) {
+            OS_ERROR("Fail to intialize HDMI\n");
+            goto Exit;
+        }
+    }
+
+    *DisplayConfigPPtr = tempDisplayContext;
+
+Exit:
+    return status;
+}
+
+
+OS_STATUS DeInitDisplay (
+    DISPLAY_CONTEXT* DisplayContextPtr
+    )
+{
+
+    return OS_STATUS_SUCCESS;
+}
+
+OS_STATUS ValidateDisplayConfig (
+    DISPLAY_CONTEXT* DisplayContextPtr,
+    DISPLAY_MODE DisplayMode,
+    DISPLAY_INTERFACE* DIOrder
+    )
+{
+    OS_STATUS status;
+    DISPLAY_INTERFACE DisplayDevice;
+
+    if (FeaturePcdGet(PcdLvdsEnable)) {
+        DisplayDevice = LVDS0_DISPLAY;
+    } else {
+        DisplayDevice = HDMI_DISPLAY;
+    }
+
+    // Currently only support single display mode on HDMI/LVDS
+    if (DisplayMode != SINGLE_MODE && DIOrder[0] != DisplayDevice) {
+        status = OS_STATUS_UNSUPPORTED;
+        goto Exit;
+    }
+
+    // Currently going to a very simplistic approach of enabling HDMI/LVDS single
+    // display on HDMI/LVDS port. This configuration is applied regardless if
+    // there is a monitor connected. No hot plug, monitor detection support.
+
+    status = OS_STATUS_SUCCESS;
+
+Exit:
+    return status;
+}
+
+OS_STATUS SetDisplayConfig (
+    DISPLAY_CONTEXT* DisplayContextPtr,
+    DISPLAY_MODE DisplayMode,
+    DISPLAY_INTERFACE* DIOrder
+    )
+{
+    OS_STATUS status;
+    IPU_INDEX iPUIndex;
+    DI_INDEX diIndex;
+    UINT32 displayModeIndex;
+    UINT32 diOffset[DI_TOTAL] =
+        { IPU_DI0_GENERAL_OFFSET, IPU_DI1_GENERAL_OFFSET };
+
+    status = ValidateDisplayConfig(
+        DisplayContextPtr,
+        DisplayMode,
+        DIOrder);
+    if (status != OS_STATUS_SUCCESS) {
+        DisplayContextPtr->DisplayConfig.DisplayMode = UNKNOWN_MODE;
+        OS_ZERO_MEM(
+            DisplayContextPtr->DisplayConfig.DIOrder,
+            sizeof(DisplayContextPtr->DisplayConfig.DIOrder));
+        OS_ERROR("Unsupported display configuration\n");
+        status = OS_STATUS_UNSUPPORTED;
+        goto Exit;
+    }
+
+    DisplayContextPtr->DisplayConfig.DisplayMode = DisplayMode;
+
+    OS_ZERO_MEM(
+        DisplayContextPtr->DisplayConfig.DIOrder,
+        sizeof(DisplayContextPtr->DisplayConfig.DIOrder));
+
+    // Assigning display interface in order. Require mode information on IPU
+    // and DI valid combination
+    for (iPUIndex = IPU1, displayModeIndex = 0;
+         iPUIndex < IPU_TOTAL && displayModeIndex < (UINT32)DisplayMode;
+        ++iPUIndex) {
+        for (diIndex = DI0;
+            diIndex < DI_TOTAL && displayModeIndex < (UINT32)DisplayMode;
+            ++diIndex) {
+            DisplayContextPtr->DisplayConfig.DIOrder[diIndex] =
+                DIOrder[diIndex];
+            DISPLAY_INTERFACE_CONTEXT* diContextPtr =
+                &DisplayContextPtr->DIContext[DIOrder[diIndex]];
+            diContextPtr->IpuMmioBasePtr =
+                DisplayContextPtr->IpuMmioBasePtr[iPUIndex];
+            diContextPtr->IpuDiRegsPtr =
+                (IPU_DIx_REGS*)(((UINTN)DisplayContextPtr->IpuMmioBasePtr[iPUIndex]) +
+                    diOffset[diIndex]);
+            diContextPtr->CpMemParamBasePtr = (VOID *)
+                (((UINTN)diContextPtr->IpuMmioBasePtr) + CSP_IPUV3_CPMEM_REGS_OFFSET);
+            ++displayModeIndex;
+        }
+    }
+
+    status = OS_STATUS_SUCCESS;
+
+Exit:
+    return status;
+}
+
+OS_STATUS ApplyDisplayConfig (
+    DISPLAY_CONTEXT* DisplayContextPtr,
+    DISPLAY_MODE DisplayMode,
+    DISPLAY_INTERFACE* DIOrder
+    )
+{
+    DISPLAY_CONFIG* displayConfigPtr = &DisplayContextPtr->DisplayConfig;
+    UINT32 displayModeIndex;
+    OS_STATUS status;
+
+    status = SetDisplayConfig(
+        DisplayContextPtr,
+        DisplayMode,
+        DIOrder);
+    if (status != OS_STATUS_SUCCESS) {
+        OS_ERROR("Fail to set display configuration %d\n", DisplayMode);
+        status = OS_STATUS_UNSUPPORTED;
+        goto Exit;
+    }
+
+    // Setup muxing first before configuring DI and DC
+    status = SetupDisplayMux(
+        DisplayContextPtr);
+    if (status != OS_STATUS_SUCCESS) {
+        OS_ERROR("SetDisplayMux failed \n");
+        goto Exit;
+    }
+
+    for (displayModeIndex = 0;
+         displayModeIndex < (UINT32)displayConfigPtr->DisplayMode;
+         ++displayModeIndex) {
+        UINT32 currentDI = displayConfigPtr->DIOrder[displayModeIndex];
+        DISPLAY_INTERFACE_CONTEXT* displayInterfaceContextPtr =
+            &DisplayContextPtr->DIContext[currentDI];
+        DISPLAY_TIMING* currentDisplayTimingPtr =
+            &displayConfigPtr->DisplayTiming[displayModeIndex];
+
+        status = ConfigureDCChannel(
+            displayInterfaceContextPtr,
+            currentDI,
+            displayModeIndex,
+            currentDisplayTimingPtr);
+        if (status != OS_STATUS_SUCCESS) {
+            OS_ERROR(
+                "ConfigureDCChannel fail display %d index %d\n",
+                currentDI,
+                displayModeIndex);
+            goto Exit;
+        }
+
+        status = ConfigureDI(
+            displayInterfaceContextPtr,
+            displayModeIndex,
+            currentDisplayTimingPtr);
+        if (status != OS_STATUS_SUCCESS) {
+            OS_ERROR("Fail to configure DI\n");
+            goto Exit;
+        }
+
+        switch (currentDI)
+        {
+            case HDMI_DISPLAY:
+                status = SetHDMIDisplay(
+                    displayInterfaceContextPtr,
+                    currentDisplayTimingPtr);
+                if (status != OS_STATUS_SUCCESS) {
+                    OS_ERROR("Fail to set HDMI timing\n");
+                    goto Exit;
+                }
+                break;
+            case LVDS0_DISPLAY:
+            case LVDS1_DISPLAY:
+                break;
+            default:
+                status = OS_STATUS_UNSUPPORTED;
+                goto Exit;
+        }
+
+        status = ConfigureFrameBuffer(
+            displayInterfaceContextPtr,
+            &displayConfigPtr->DisplaySurface[displayModeIndex]);
+        if (status != OS_STATUS_SUCCESS) {
+            OS_ERROR("Fail to configure frame buffer (%d)\n", displayModeIndex);
+            goto Exit;
+        }
+    }
+
+Exit:
+    return status;
+}
+
+OS_STATUS AllocateFrameBuffer (
+    SURFACE_INFO* SurfaceInfoPtr
+    )
+{
+    OS_STATUS status;
+    OS_INFO("++AllocateFrameBuffer()\r\n");
+    if((SurfaceInfoPtr->Width == 0) ||
+            (SurfaceInfoPtr->Height == 0)) {
+        status = OS_STATUS_INVALID_PARAM;
+        goto Exit;
+    }
+
+    OS_INFO("AllocateFrameBuffer() Frame Buffer AddrP=%Xh\r\n",FixedPcdGet32(PcdFrameBufferBase));
+    OS_INFO("AllocateFrameBuffer() Frame Buffer Size=%Xh\r\n",FixedPcdGet32(PcdFrameBufferSize));
+    SurfaceInfoPtr->VirtAddrPtr = (VOID*)(UINTN)FixedPcdGet32(PcdFrameBufferBase);
+
+    SurfaceInfoPtr->PhyAddr =
+        (UINT32)OS_VIRT_TO_PHY_ADDR(SurfaceInfoPtr->VirtAddrPtr);
+    SurfaceInfoPtr->Pitch = SurfaceInfoPtr->Width;
+
+    OS_INFO(
+        "Allocate FB PhyAddr %x VirtAddr %x\n",
+        SurfaceInfoPtr->PhyAddr,
+        SurfaceInfoPtr->VirtAddrPtr);
+
+    status = OS_STATUS_SUCCESS;
+
+Exit:
+    OS_INFO("--AllocateFrameBuffer()=%Xh\r\n",status);
+    return status;
+}
+
+OS_STATUS ConfigureFrameBuffer (
+    DISPLAY_INTERFACE_CONTEXT* DIContextPtr,
+    SURFACE_INFO* FrameBufferPtr
+    )
+{
+    OS_STATUS status;
+
+    // Only support single display for now
+    status = ConfigureCPMEMFrameBuffer(
+        DIContextPtr,
+        IDMAC_CHANNEL_DP_PRIMARY_FLOW_MAIN_PLANE,
+        FrameBufferPtr);
+    if (status != OS_STATUS_SUCCESS) {
+        OS_ERROR("Fail to configure CPMEM\n");
+        goto Exit;
+    }
+
+Exit:
+    return status;
+}
+
+UINT32 GetColorDepth (
+    PIXEL_FORMAT PixelFormat
+    )
+{
+    UINT32 bitDepth;
+
+    switch(PixelFormat)
+    {
+        case PIXEL_FORMAT_ARGB32:
+        case PIXEL_FORMAT_BGRA32:
+            bitDepth = 8;
+            break;
+        default:
+            bitDepth = 0;
+    }
+
+    return bitDepth;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/Display.h b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Display.h
new file mode 100644
index 000000000000..4a348bffed3a
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Display.h
@@ -0,0 +1,171 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Copyright 2018 NXP
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _DISPLAY_H_
+#define _DISPLAY_H_
+
+typedef enum {
+   UNKNOWN_MODE,
+   SINGLE_MODE,
+   DUAL_MODE,
+} DISPLAY_MODE;
+
+typedef enum {
+    IPU1,
+#if !defined(CPU_IMX6SDL)
+    IPU2,
+#endif
+    IPU_TOTAL,
+} IPU_INDEX;
+
+typedef enum {
+    DI0,
+    DI1,
+    DI_TOTAL,
+} DI_INDEX;
+
+typedef enum {
+    HDMI_DISPLAY,
+    MIPI_DISPLAY,
+    LVDS0_DISPLAY,
+    LVDS1_DISPLAY,
+    MAX_DISPLAY, // Only 4 display supported by IPU
+    NO_DISPLAY = MAX_DISPLAY,
+} DISPLAY_INTERFACE;
+
+typedef struct _SURFACE_INFO {
+    UINT32 PhyAddr;
+    UINT32* VirtAddrPtr;
+    UINT32 Width;
+    UINT32 Height;
+    UINT32 Pitch;
+    UINT32 Bpp;
+    PIXEL_FORMAT PixelFormat;
+}SURFACE_INFO, *PSURFACE_INFO;
+
+typedef struct _IPU_DIx_REGS {
+    UINT32 DIxGENERAL;
+    UINT32 DIxBS_CLKGEN0;
+    UINT32 DIxBS_CLKGEN1;
+    UINT32 DIxSW_GEN0_1;
+    UINT32 DIxSW_GEN0_2;
+    UINT32 DIxSW_GEN0_3;
+    UINT32 DIxSW_GEN0_4;
+    UINT32 DIxSW_GEN0_5;
+    UINT32 DIxSW_GEN0_6;
+    UINT32 DIxSW_GEN0_7;
+    UINT32 DIxSW_GEN0_8;
+    UINT32 DIxSW_GEN0_9;
+    UINT32 DIxSW_GEN1_1;
+    UINT32 DIxSW_GEN1_2;
+    UINT32 DIxSW_GEN1_3;
+    UINT32 DIxSW_GEN1_4;
+    UINT32 DIxSW_GEN1_5;
+    UINT32 DIxSW_GEN1_6;
+    UINT32 DIxSW_GEN1_7;
+    UINT32 DIxSW_GEN1_8;
+    UINT32 DIxSW_GEN1_9;
+    UINT32 DIxSYNC_AS_GEN;
+    UINT32 DIxDW_GEN[12];
+    UINT32 DIxDW_SET0[12];
+    UINT32 DIxDW_SET1[12];
+    UINT32 DIxDW_SET2[12];
+    UINT32 DIxDW_SET3[12];
+    UINT32 DIxSTP_REP[4];
+    UINT32 DIxSTP_REP_9;
+    UINT32 DIxSER_CONF;
+    UINT32 DIxSSC;
+    UINT32 DIxPOL;
+    UINT32 DIxAW0;
+    UINT32 DIxAW1;
+    UINT32 DIxSCR_CONF;
+    UINT32 DIxSTAT;
+} IPU_DIx_REGS, *PIPU_DIx_REGS;
+
+typedef struct _DISPLAY_INTERFACE_CONTEXT {
+    DISPLAY_INTERFACE displayInterface;
+
+    VOID* MmioBasePtr;
+    VOID* IpuMmioBasePtr;
+    VOID* CpMemParamBasePtr;
+    IPU_DIx_REGS* IpuDiRegsPtr;
+    UINT32 EdidDataSize;
+    UINT8 EdidData[256];
+    DISPLAY_TIMING PreferedTiming;
+}DISPLAY_INTERFACE_CONTEXT, *PDISPLAY_INTERFACE_CONTEXT;
+
+typedef struct _DISPLAY_CONFIG {
+    DISPLAY_MODE DisplayMode;
+    DISPLAY_INTERFACE DIOrder[MAX_DISPLAY];
+    SURFACE_INFO DisplaySurface[MAX_DISPLAY];
+    DISPLAY_TIMING DisplayTiming[MAX_DISPLAY];
+    UINT32 OsHandle[MAX_DISPLAY];
+}DISPLAY_CONFIG, *PDISPLAY_CONFIG;
+
+typedef struct _DISPLAY_CONTEXT {
+    DISPLAY_CONFIG DisplayConfig;
+    VOID* IoMuxMmioBasePtr;
+    VOID* IpuMmioBasePtr[IPU_TOTAL];
+    DISPLAY_INTERFACE_CONTEXT DIContext[MAX_DISPLAY];
+}DISPLAY_CONTEXT, *PDISPLAY_CONTEXT;
+
+extern DISPLAY_TIMING DefaultTiming;
+
+OS_STATUS GetPreferedTiming (
+    UINT8* EdidDataPtr,
+    UINT32 EdidDataSize,
+    DISPLAY_TIMING* PreferedTimingPtr
+    );
+
+OS_STATUS InitDisplay (
+    DISPLAY_CONTEXT** DisplayConfigPPtr
+    );
+
+OS_STATUS DeInitDisplay (
+    DISPLAY_CONTEXT* DisplayContextPtr
+    );
+
+OS_STATUS ValidateDisplayConfig (
+    DISPLAY_CONTEXT* DisplayContextPtr,
+    DISPLAY_MODE DisplayMode,
+    DISPLAY_INTERFACE* DIOrder
+    );
+
+OS_STATUS SetDisplayConfig (
+    DISPLAY_CONTEXT* DisplayContextPtr,
+    DISPLAY_MODE DisplayMode,
+    DISPLAY_INTERFACE* DIOrder
+    );
+
+OS_STATUS ApplyDisplayConfig (
+    DISPLAY_CONTEXT* DisplayContextPtr,
+    DISPLAY_MODE DisplayMode,
+    DISPLAY_INTERFACE* DIOrder
+    );
+
+OS_STATUS AllocateFrameBuffer (
+    SURFACE_INFO* SurfaceInfoPtr
+    );
+
+OS_STATUS ConfigureFrameBuffer (
+    DISPLAY_INTERFACE_CONTEXT* DIContextPtr,
+    SURFACE_INFO* FrameBufferPtr
+    );
+
+UINT32 GetColorDepth (
+    PIXEL_FORMAT PixelFormat
+    );
+
+#endif
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayController.c b/Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayController.c
new file mode 100644
index 000000000000..58830e98bd2b
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayController.c
@@ -0,0 +1,388 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Copyright 2018 NXP
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "osal.h"
+
+#include "Ipu.h"
+#include "Display.h"
+#include "DisplayController.h"
+#include "DisplayInterface.h"
+
+VOID DumpBasicDCReg(
+    VOID* IpuMmioBasePtr)
+{
+    UINT32 regVal;
+    UINT32 counter, index;
+
+    OS_INFO("---------- DC Register Dump ----------\n");
+    OS_INFO("## Configuration\n\n");
+    regVal = IpuRead32(IpuMmioBasePtr, IPU_DC_WR_CH_CONF_5_OFFSET);
+    OS_INFO("IPU_DC_WR_CH_CONF_5_OFFSET %x\n", regVal);
+    regVal = IpuRead32(IpuMmioBasePtr, IPU_DC_WR_CH_CONF_1_OFFSET);
+    OS_INFO("IPU_DC_WR_CH_CONF_1_OFFSET %x\n", regVal);
+    regVal = IpuRead32(IpuMmioBasePtr, IPU_DC_DISP_CONF1_0_OFFSET);
+    OS_INFO("IPU_DC_DISP_CONF1_0_OFFSET %x\n", regVal);
+    regVal = IpuRead32(IpuMmioBasePtr, IPU_DC_DISP_CONF1_1_OFFSET);
+    OS_INFO("IPU_DC_DISP_CONF1_1_OFFSET %x\n", regVal);
+    regVal = IpuRead32(IpuMmioBasePtr, IPU_DC_DISP_CONF1_2_OFFSET);
+    OS_INFO("IPU_DC_DISP_CONF1_2_OFFSET %x\n", regVal);
+    regVal = IpuRead32(IpuMmioBasePtr, IPU_DC_DISP_CONF1_3_OFFSET);
+    OS_INFO("IPU_DC_DISP_CONF1_3_OFFSET %x\n", regVal);
+    regVal = IpuRead32(IpuMmioBasePtr, IPU_DC_DISP_CONF2_0_OFFSET);
+    OS_INFO("IPU_DC_DISP_CONF2_0_OFFSET %x\n", regVal);
+    regVal = IpuRead32(IpuMmioBasePtr, IPU_DC_GEN_OFFSET);
+    OS_INFO("IPU_DC_GEN_OFFSET %x\n", regVal);
+    OS_INFO("## Bus MAPPING\n\n");
+    {
+        for (counter = 0, index = 0; index < 26; counter += 4, ++index) {
+            regVal = IpuRead32(IpuMmioBasePtr, IPU_DC_MAP_CONF_0_OFFSET + counter);
+            OS_INFO("IPU_DC_MAP_CONF_%d %x\n", index, regVal);
+        }
+    }
+
+    OS_INFO("## Channel MicroCode setup\n\n");
+    {
+        // Only print out channel 5 as we only support single mode for now
+        regVal = IpuRead32(IpuMmioBasePtr, IPU_DC_RL0_CH_5_OFFSET);
+        OS_INFO("IPU_DC_RL0_CH_5_OFFSET %x\n", regVal);
+        regVal = IpuRead32(IpuMmioBasePtr, IPU_DC_RL1_CH_5_OFFSET);
+        OS_INFO("IPU_DC_RL1_CH_5_OFFSET %x\n", regVal);
+        regVal = IpuRead32(IpuMmioBasePtr, IPU_DC_RL2_CH_5_OFFSET);
+        OS_INFO("IPU_DC_RL2_CH_5_OFFSET %x\n", regVal);
+        regVal = IpuRead32(IpuMmioBasePtr, IPU_DC_RL3_CH_5_OFFSET);
+        OS_INFO("IPU_DC_RL3_CH_5_OFFSET %x\n", regVal);
+        regVal = IpuRead32(IpuMmioBasePtr, IPU_DC_RL4_CH_5_OFFSET);
+        OS_INFO("IPU_DC_RL4_CH_5_OFFSET %x\n", regVal);
+    }
+
+    OS_INFO("## MicroCode\n\n");
+    {
+        // There are 256 template, only print out the first 10
+        for (counter = 0, index = 0; index < 10; counter += 8, ++index) {
+            OS_INFO("(%d)", index);
+            regVal = IpuRead32(
+                IpuMmioBasePtr,
+                IPU_DC_TEMPLATE_REGS_ADDR_OFFSET + counter);
+            OS_INFO("- %8x", regVal);
+            regVal = IpuRead32(
+                IpuMmioBasePtr,
+                IPU_DC_TEMPLATE_REGS_ADDR_OFFSET + counter + 4);
+            OS_INFO(" %8x -\n", regVal);
+        }
+    }
+    OS_INFO("------------------------------------\n\n");
+}
+
+#pragma pack(push, 1)
+typedef union {
+    struct {
+        UINT32 SYNC : 4;
+        UINT32 GLUELOGIC : 7;
+        UINT32 WAVEFORM : 4;
+        UINT32 MAPPING : 5;
+        UINT32 DATA : 16;
+        UINT32 OPCODE : 5;
+        UINT32 STOP : 1;
+        UINT32 Unused : 22;
+    };
+    struct     {
+        UINT32 LowWord;
+        UINT32 HighWord;
+    };
+} DC_WROD_COMMAND_TEMPLATE;
+#pragma pack(pop)
+
+OS_STATUS WriteWRODCommand (
+    VOID* IpuMmioBasePtr,
+    UINT32 MicroCodeAddr,
+    UINT32 Data,
+    UINT32 Mapping,
+    UINT32 WaveForm,
+    UINT32 GlueLogic,
+    UINT32 Sync)
+{
+    DC_WROD_COMMAND_TEMPLATE wrodCommand;
+    UINT32 microCodeAddrOffset =
+        IPU_DC_TEMPLATE_REGS_ADDR_OFFSET + (MicroCodeAddr * 8);
+
+    OS_ZERO_MEM((void*)&wrodCommand, sizeof(wrodCommand));
+    wrodCommand.STOP = 1;
+    wrodCommand.OPCODE = 0x18;
+    wrodCommand.DATA = Data;
+    wrodCommand.MAPPING = Mapping;
+    wrodCommand.WAVEFORM = WaveForm + 1;
+    wrodCommand.GLUELOGIC = GlueLogic;
+    wrodCommand.SYNC = Sync;
+
+    IpuWrite32(IpuMmioBasePtr, microCodeAddrOffset, wrodCommand.LowWord);
+    IpuWrite32(IpuMmioBasePtr, microCodeAddrOffset + 4, wrodCommand.HighWord);
+
+    return OS_STATUS_SUCCESS;
+}
+
+OS_STATUS SetDCChannelState (
+    VOID* IpuMmioBasePtr,
+    PROG_CHAN_TYP ChannelType
+    )
+{
+    IPU_DC_WR_CH_CONF_5_REG wrChConfigReg;
+
+    wrChConfigReg.Reg = IpuRead32(IpuMmioBasePtr, IPU_DC_WR_CH_CONF_5_OFFSET);
+
+    wrChConfigReg.PROG_CHAN_TYP = ChannelType;
+
+    IpuWrite32(IpuMmioBasePtr, IPU_DC_WR_CH_CONF_5_OFFSET, wrChConfigReg.Reg);
+
+    return OS_STATUS_SUCCESS;
+}
+
+OS_STATUS ConfigureDCChannel (
+    DISPLAY_INTERFACE_CONTEXT* DIContextPtr,
+    DISPLAY_INTERFACE DisplayInterface,
+    UINT32 DisplayIndex,
+    DISPLAY_TIMING* DisplayTimingPtr)
+{
+    OS_STATUS status;
+    IPU_DC_WR_CH_CONF_5_REG wrChConfigReg;
+    VOID* ipuMmioBasePtr = DIContextPtr->IpuMmioBasePtr;
+
+    OS_ZERO_MEM((void*)&wrChConfigReg, sizeof(wrChConfigReg));
+    wrChConfigReg.PROG_START_TIME = 0;
+    wrChConfigReg.FILED_MODE = 0;
+    wrChConfigReg.CHAN_MASK_DEFAULT = 0; // only used highest priority
+    wrChConfigReg.PROG_CHAN_TYP = 0; // Begin as disable
+    wrChConfigReg.PROG_DISP_ID = DisplayInterface;
+    wrChConfigReg.PROG_DI_ID = DisplayIndex % 2;
+    wrChConfigReg.W_SIZE = 0x02; // 24 Bits
+    wrChConfigReg.Reserved1 = 0;
+    wrChConfigReg.Reserved2 = 0;
+
+    // Channel 5 is used main primary flow
+    IpuWrite32(ipuMmioBasePtr, IPU_DC_WR_CH_CONF_5_OFFSET, wrChConfigReg.Reg);
+    // Start address of memory always 0
+    IpuWrite32(ipuMmioBasePtr, IPU_DC_WR_CH_ADDR_5_OFFSET, 0);
+
+    OS_ZERO_MEM((void*)&wrChConfigReg, sizeof(wrChConfigReg));
+    wrChConfigReg.FILED_MODE = 0;
+    wrChConfigReg.CHAN_MASK_DEFAULT = 0; // only used highest priority
+    wrChConfigReg.PROG_CHAN_TYP = 4; // Enable
+    wrChConfigReg.PROG_DISP_ID = DisplayInterface;
+    wrChConfigReg.PROG_DI_ID = DisplayIndex % 2;
+    wrChConfigReg.W_SIZE = 0x02; // 1 Bits
+    wrChConfigReg.Reserved1 = 0;
+    wrChConfigReg.Reserved2 = 0;
+
+    // Channel 1 is used as sync/async flow
+    IpuWrite32(ipuMmioBasePtr, IPU_DC_WR_CH_CONF_1_OFFSET, wrChConfigReg.Reg);
+    IpuWrite32(ipuMmioBasePtr, IPU_DC_WR_CH_ADDR_1_OFFSET, 0);
+
+    {
+        IPUx_DC_DISP_CONF1_REG dispConf1Reg;
+
+        dispConf1Reg.DISP_TYP = 0x02; // What is byte_enabled
+        dispConf1Reg.ADDR_INCREMENT = 0; // Increase by 1 byte
+        dispConf1Reg.ADDR_BE_L_INC = 0;
+        dispConf1Reg.MCU_ACC_LB_MASK_3 = 0;
+        dispConf1Reg.DISP_RD_VALUE_PTR = 0;
+        IpuWrite32(ipuMmioBasePtr, IPU_DC_DISP_CONF1_0_OFFSET, dispConf1Reg.Reg);
+
+        // set stride
+        IpuWrite32(ipuMmioBasePtr, IPU_DC_DISP_CONF2_0_OFFSET, DisplayTimingPtr->VActive);
+    }
+
+    // Setup general register
+    {
+        IPUx_IPU_DC_GEN_REG dcGenReg;
+
+        dcGenReg.Sync_1_6 = 2; // Sync flow
+        dcGenReg.MASK_EN = 0; // Disable masking
+        dcGenReg.MASK4CHAN_5 = 0; // Ignore as mask is disabled
+        dcGenReg.SYNC_PRIORITY_5 = 1; // Higher sync priority for channel 5 which is the main channel
+        dcGenReg.SYNC_PRIORITY_1 = 0; // Lower sync priority
+        dcGenReg.DC_CH5_TYPE = 0; // Normal mode, sync flow throuh channel 5
+        dcGenReg.DC_BK_EN = 0; // No cursor support
+        dcGenReg.DC_BKDIV = 0; // No cursor support
+
+        IpuWrite32(ipuMmioBasePtr, IPU_DC_GEN_OFFSET, dcGenReg.Reg);
+    }
+
+    // Do not use any user event
+    IpuWrite32(ipuMmioBasePtr, IPU_DC_UGDE0_0_OFFSET, 0);
+    IpuWrite32(ipuMmioBasePtr, IPU_DC_UGDE1_0_OFFSET, 0);
+    IpuWrite32(ipuMmioBasePtr, IPU_DC_UGDE2_0_OFFSET, 0);
+    IpuWrite32(ipuMmioBasePtr, IPU_DC_UGDE3_0_OFFSET, 0);
+
+    {
+        IPUx_DC_MAP_CONF_MAP_REG dcMapConf0Reg;
+        DC_MAP_CONF_OFFSET_MASK_REG dcConfOffsetMaskReg;
+        UINT32 mask0, mask1, mask2;
+        UINT32 offset0, offset1, offset2;
+
+        dcMapConf0Reg.MAPPING_PNTR_BYTE0_X = 0;
+        dcMapConf0Reg.MAPPING_PNTR_BYTE1_X = 1;
+        dcMapConf0Reg.MAPPING_PNTR_BYTE2_X = 2;
+        dcMapConf0Reg.MAPPING_PNTR_BYTE0_Y = 3; // Unused
+        dcMapConf0Reg.MAPPING_PNTR_BYTE1_Y = 4; // Unused
+        dcMapConf0Reg.MAPPING_PNTR_BYTE2_Y = 5; // Unused
+
+        IpuWrite32(ipuMmioBasePtr, IPU_DC_MAP_CONF_0_OFFSET, dcMapConf0Reg.Reg);
+
+        switch (DisplayInterface)
+        {
+            // PixelFormat RGB24
+            case HDMI_DISPLAY:
+                mask0 = mask1 = mask2 = 0xFF;
+                offset0 = 7;
+                offset1 = 15;
+                offset2 = 23;
+                break;
+            // PixelFormat RGB666
+            case LVDS0_DISPLAY:
+            case LVDS1_DISPLAY:
+                mask0 = mask1 = mask2 = 0xFC;
+                offset0 = 5;
+                offset1 = 11;
+                offset2 = 17;
+                break;
+            default:
+                ASSERT(FALSE);
+                status = OS_STATUS_UNSUPPORTED;
+                goto Exit;
+        }
+
+        dcConfOffsetMaskReg.MD_MASK_X = mask0;
+        dcConfOffsetMaskReg.MD_OFFSET_X = offset0; // Blue
+        dcConfOffsetMaskReg.MD_MASK_Y = mask1;
+        dcConfOffsetMaskReg.MD_OFFSET_Y = offset1; // Green
+
+        IpuWrite32(ipuMmioBasePtr, IPU_DC_MAP_CONF_15_OFFSET, dcConfOffsetMaskReg.Reg);
+
+        dcConfOffsetMaskReg.MD_MASK_X = mask2;
+        dcConfOffsetMaskReg.MD_OFFSET_X = offset2; // Red
+        dcConfOffsetMaskReg.MD_MASK_Y = 0x00;
+        dcConfOffsetMaskReg.MD_OFFSET_Y = 0; // Unused
+
+        IpuWrite32(ipuMmioBasePtr, IPU_DC_MAP_CONF_16_OFFSET, dcConfOffsetMaskReg.Reg);
+    }
+
+    // Setup microcode
+    {
+        IPU_DC_RL0_CH_5_REG dcRl0Ch5Reg;
+        IPU_DC_RL2_CH_5_REG dcRl2Ch5Reg;
+        IPU_DC_RL4_CH_5_REG dcRl4Ch5Reg;
+
+        // New line event point to the first microcode (0)
+        OS_ZERO_MEM((void*)&dcRl0Ch5Reg, sizeof(dcRl0Ch5Reg));
+        dcRl0Ch5Reg.COD_NL_START_CHAN_5 = 0;
+        dcRl0Ch5Reg.COD_NL_PRIORITY_CHAN_5 = 3;
+        IpuWrite32(ipuMmioBasePtr, IPU_DC_RL0_CH_5_OFFSET, dcRl0Ch5Reg.Reg);
+
+        // End of line event point to the second microcode (1)
+        OS_ZERO_MEM((void*)&dcRl2Ch5Reg, sizeof(dcRl2Ch5Reg));
+        dcRl2Ch5Reg.COD_EOL_START_CHAN_5 = 1;
+        dcRl2Ch5Reg.COD_EOL_PRIORITY_CHAN_5 = 2;
+        IpuWrite32(ipuMmioBasePtr, IPU_DC_RL2_CH_5_OFFSET, dcRl2Ch5Reg.Reg);
+
+        // New data event point to the first microcode (2)
+        OS_ZERO_MEM((void*)&dcRl4Ch5Reg, sizeof(dcRl4Ch5Reg));
+        dcRl4Ch5Reg.COD_NEW_DATA_START_CHAN_5 = 2;
+        dcRl4Ch5Reg.COD_NEW_DATA_PRIORITY_CHAN_5 = 1;
+        IpuWrite32(ipuMmioBasePtr, IPU_DC_RL4_CH_5_OFFSET, dcRl4Ch5Reg.Reg);
+
+        // MicroCodeAddr
+        // - 0 set for new line event
+        // Data
+        // - Unsused
+        // Map to mapping parameter 0
+        // - In order to point to MAPPING_PNTR_BYTE2_0, MAPPING_PNTR_BYTE1_0,
+        //   MAPPING_PNTR_BYTE0_0 the user should write 1 to the MAPPING field
+        // WaveForm
+        // - Points to DI0_DW_GEN_0 or DI1_DW_GEN_0 (Define which waveform
+        //   register is used, default to first IPUx_DI0_DW_SET0_1)
+        // GlueLogic
+        // - Once the signal is asserted then it remains asserted (high or low
+        //   according to the polarity)
+        // Sync
+        // - Sync with counter 5
+        WriteWRODCommand(
+            ipuMmioBasePtr,
+            0,
+            0,
+            1,
+            DW_GEN_0,
+            8,
+            DI_COUNTER_5_ACTIVE_CLOCK);
+
+        // MicroCodeAddr
+        // - 1 set for end of line event
+        // Data
+        // - Unsused
+        // Map to mapping parameter 0
+        // - In order to point to MAPPING_PNTR_BYTE2_0, MAPPING_PNTR_BYTE1_0,
+        //   MAPPING_PNTR_BYTE0_0 the user should write 1 to the MAPPING field
+        // WaveForm
+        // - Points to DI0_DW_GEN_0 or DI1_DW_GEN_0 (Define which waveform
+        //   register is used, default to first IPUx_DI0_DW_SET0_1)
+        // GlueLogic
+        // - Once the signal is negated then it remains negated (high or low
+        //   according to the polarity)
+        // Sync
+        // - Sync with counter 5
+        WriteWRODCommand(
+            ipuMmioBasePtr,
+            1,
+            0,
+            1,
+            DW_GEN_0,
+            4,
+            DI_COUNTER_5_ACTIVE_CLOCK);
+
+        // MicroCodeAddr
+        // - 2 set for new data event
+        // Data
+        // - Unsused
+        // Map to mapping parameter 0
+        // - In order to point to MAPPING_PNTR_BYTE2_0, MAPPING_PNTR_BYTE1_0,
+        //   MAPPING_PNTR_BYTE0_0 the user should write 1 to the MAPPING field
+        // WaveForm
+        // - Points to DI0_DW_GEN_0 or DI1_DW_GEN_0 (Define which waveform
+        //   register is used, default to first IPUx_DI0_DW_SET0_1)
+        // GlueLogic
+        // - CS mode No impact on the waveform
+        // Sync
+        // - Sync with channel 5
+        WriteWRODCommand(
+            ipuMmioBasePtr,
+            2,
+            0,
+            1,
+            DW_GEN_0,
+            8,
+            DI_COUNTER_5_ACTIVE_CLOCK);
+    }
+
+    // Turn on channel without anti tearing
+    SetDCChannelState(DIContextPtr->IpuMmioBasePtr, PROG_CHAN_TYP_NORMAL);
+
+    // Register dump, commented out by default
+#ifdef REGISTER_DUMP
+    DumpBasicDCReg(ipuMmioBasePtr);
+#endif
+
+    status = OS_STATUS_SUCCESS;
+
+Exit:
+    return status;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayController.h b/Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayController.h
new file mode 100644
index 000000000000..085632117367
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayController.h
@@ -0,0 +1,312 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _DC_H_
+#define _DC_H_
+
+#define IPU_DC_OFFSET 0x00058000
+
+// DC Registers
+#define IPU_DC_READ_CH_CONF_OFFSET              IPU_DC_OFFSET + 0x0000
+#define IPU_DC_READ_CH_ADDR_OFFSET              IPU_DC_OFFSET + 0x0004
+#define IPU_DC_RL0_CH_0_OFFSET                  IPU_DC_OFFSET + 0x0008
+#define IPU_DC_RL1_CH_0_OFFSET                  IPU_DC_OFFSET + 0x000C
+#define IPU_DC_RL2_CH_0_OFFSET                  IPU_DC_OFFSET + 0x0010
+#define IPU_DC_RL3_CH_0_OFFSET                  IPU_DC_OFFSET + 0x0014
+#define IPU_DC_RL4_CH_0_OFFSET                  IPU_DC_OFFSET + 0x0018
+#define IPU_DC_WR_CH_CONF_1_OFFSET              IPU_DC_OFFSET + 0x001C
+#define IPU_DC_WR_CH_ADDR_1_OFFSET              IPU_DC_OFFSET + 0x0020
+#define IPU_DC_RL0_CH_1_OFFSET                  IPU_DC_OFFSET + 0x0024
+#define IPU_DC_RL1_CH_1_OFFSET                  IPU_DC_OFFSET + 0x0028
+#define IPU_DC_RL2_CH_1_OFFSET                  IPU_DC_OFFSET + 0x002C
+#define IPU_DC_RL3_CH_1_OFFSET                  IPU_DC_OFFSET + 0x0030
+#define IPU_DC_RL4_CH_1_OFFSET                  IPU_DC_OFFSET + 0x0034
+#define IPU_DC_WR_CH_CONF_2_OFFSET              IPU_DC_OFFSET + 0x0038
+#define IPU_DC_WR_CH_ADDR_2_OFFSET              IPU_DC_OFFSET + 0x003C
+#define IPU_DC_RL0_CH_2_OFFSET                  IPU_DC_OFFSET + 0x0040
+#define IPU_DC_RL1_CH_2_OFFSET                  IPU_DC_OFFSET + 0x0044
+#define IPU_DC_RL2_CH_2_OFFSET                  IPU_DC_OFFSET + 0x0048
+#define IPU_DC_RL3_CH_2_OFFSET                  IPU_DC_OFFSET + 0x004C
+#define IPU_DC_RL4_CH_2_OFFSET                  IPU_DC_OFFSET + 0x0050
+#define IPU_DC_CMD_CH_CONF_3_OFFSET             IPU_DC_OFFSET + 0x0054
+#define IPU_DC_CMD_CH_CONF_4_OFFSET             IPU_DC_OFFSET + 0x0058
+#define IPU_DC_WR_CH_CONF_5_OFFSET              IPU_DC_OFFSET + 0x005C
+#define IPU_DC_WR_CH_ADDR_5_OFFSET              IPU_DC_OFFSET + 0x0060
+#define IPU_DC_RL0_CH_5_OFFSET                  IPU_DC_OFFSET + 0x0064
+#define IPU_DC_RL1_CH_5_OFFSET                  IPU_DC_OFFSET + 0x0068
+#define IPU_DC_RL2_CH_5_OFFSET                  IPU_DC_OFFSET + 0x006C
+#define IPU_DC_RL3_CH_5_OFFSET                  IPU_DC_OFFSET + 0x0070
+#define IPU_DC_RL4_CH_5_OFFSET                  IPU_DC_OFFSET + 0x0074
+#define IPU_DC_WR_CH_CONF_6_OFFSET              IPU_DC_OFFSET + 0x0078
+#define IPU_DC_WR_CH_ADDR_6_OFFSET              IPU_DC_OFFSET + 0x007C
+#define IPU_DC_RL0_CH_6_OFFSET                  IPU_DC_OFFSET + 0x0080
+#define IPU_DC_RL1_CH_6_OFFSET                  IPU_DC_OFFSET + 0x0084
+#define IPU_DC_RL2_CH_6_OFFSET                  IPU_DC_OFFSET + 0x0088
+#define IPU_DC_RL3_CH_6_OFFSET                  IPU_DC_OFFSET + 0x008C
+#define IPU_DC_RL4_CH_6_OFFSET                  IPU_DC_OFFSET + 0x0090
+#define IPU_DC_WR_CH_CONF1_8_OFFSET             IPU_DC_OFFSET + 0x0094
+#define IPU_DC_WR_CH_CONF2_8_OFFSET             IPU_DC_OFFSET + 0x0098
+#define IPU_DC_RL1_CH_8_OFFSET                  IPU_DC_OFFSET + 0x009C
+#define IPU_DC_RL2_CH_8_OFFSET                  IPU_DC_OFFSET + 0x00A0
+#define IPU_DC_RL3_CH_8_OFFSET                  IPU_DC_OFFSET + 0x00A4
+#define IPU_DC_RL4_CH_8_OFFSET                  IPU_DC_OFFSET + 0x00A8
+#define IPU_DC_RL5_CH_8_OFFSET                  IPU_DC_OFFSET + 0x00AC
+#define IPU_DC_RL6_CH_8_OFFSET                  IPU_DC_OFFSET + 0x00B0
+#define IPU_DC_WR_CH_CONF1_9_OFFSET             IPU_DC_OFFSET + 0x00B4
+#define IPU_DC_WR_CH_CONF2_9_OFFSET             IPU_DC_OFFSET + 0x00B8
+#define IPU_DC_RL1_CH_9_OFFSET                  IPU_DC_OFFSET + 0x00BC
+#define IPU_DC_RL2_CH_9_OFFSET                  IPU_DC_OFFSET + 0x00C0
+#define IPU_DC_RL3_CH_9_OFFSET                  IPU_DC_OFFSET + 0x00C4
+#define IPU_DC_RL4_CH_9_OFFSET                  IPU_DC_OFFSET + 0x00C8
+#define IPU_DC_RL5_CH_9_OFFSET                  IPU_DC_OFFSET + 0x00CC
+#define IPU_DC_RL6_CH_9_OFFSET                  IPU_DC_OFFSET + 0x00D0
+#define IPU_DC_GEN_OFFSET                       IPU_DC_OFFSET + 0x00D4
+#define IPU_DC_DISP_CONF1_0_OFFSET              IPU_DC_OFFSET + 0x00D8
+#define IPU_DC_DISP_CONF1_1_OFFSET              IPU_DC_OFFSET + 0x00DC
+#define IPU_DC_DISP_CONF1_2_OFFSET              IPU_DC_OFFSET + 0x00E0
+#define IPU_DC_DISP_CONF1_3_OFFSET              IPU_DC_OFFSET + 0x00E4
+#define IPU_DC_DISP_CONF2_0_OFFSET              IPU_DC_OFFSET + 0x00E8
+#define IPU_DC_DISP_CONF2_1_OFFSET              IPU_DC_OFFSET + 0x00EC
+#define IPU_DC_DISP_CONF2_2_OFFSET              IPU_DC_OFFSET + 0x00F0
+#define IPU_DC_DISP_CONF2_3_OFFSET              IPU_DC_OFFSET + 0x00F4
+#define IPU_DC_DI0_CONF1_OFFSET                 IPU_DC_OFFSET + 0x00F8
+#define IPU_DC_DI0_CONF2_OFFSET                 IPU_DC_OFFSET + 0x00FC
+#define IPU_DC_DI1_CONF1_OFFSET                 IPU_DC_OFFSET + 0x0100
+#define IPU_DC_DI1_CONF2_OFFSET                 IPU_DC_OFFSET + 0x0104
+#define IPU_DC_MAP_CONF_0_OFFSET                IPU_DC_OFFSET + 0x0108
+#define IPU_DC_MAP_CONF_1_OFFSET                IPU_DC_OFFSET + 0x010C
+#define IPU_DC_MAP_CONF_2_OFFSET                IPU_DC_OFFSET + 0x0110
+#define IPU_DC_MAP_CONF_3_OFFSET                IPU_DC_OFFSET + 0x0114
+#define IPU_DC_MAP_CONF_4_OFFSET                IPU_DC_OFFSET + 0x0118
+#define IPU_DC_MAP_CONF_5_OFFSET                IPU_DC_OFFSET + 0x011C
+#define IPU_DC_MAP_CONF_6_OFFSET                IPU_DC_OFFSET + 0x0120
+#define IPU_DC_MAP_CONF_7_OFFSET                IPU_DC_OFFSET + 0x0124
+#define IPU_DC_MAP_CONF_8_OFFSET                IPU_DC_OFFSET + 0x0128
+#define IPU_DC_MAP_CONF_9_OFFSET                IPU_DC_OFFSET + 0x012C
+#define IPU_DC_MAP_CONF_10_OFFSET               IPU_DC_OFFSET + 0x0130
+#define IPU_DC_MAP_CONF_11_OFFSET               IPU_DC_OFFSET + 0x0134
+#define IPU_DC_MAP_CONF_12_OFFSET               IPU_DC_OFFSET + 0x0138
+#define IPU_DC_MAP_CONF_13_OFFSET               IPU_DC_OFFSET + 0x013C
+#define IPU_DC_MAP_CONF_14_OFFSET               IPU_DC_OFFSET + 0x0140
+#define IPU_DC_MAP_CONF_15_OFFSET               IPU_DC_OFFSET + 0x0144
+#define IPU_DC_MAP_CONF_16_OFFSET               IPU_DC_OFFSET + 0x0148
+#define IPU_DC_MAP_CONF_17_OFFSET               IPU_DC_OFFSET + 0x014C
+#define IPU_DC_MAP_CONF_18_OFFSET               IPU_DC_OFFSET + 0x0150
+#define IPU_DC_MAP_CONF_19_OFFSET               IPU_DC_OFFSET + 0x0154
+#define IPU_DC_MAP_CONF_20_OFFSET               IPU_DC_OFFSET + 0x0158
+#define IPU_DC_MAP_CONF_21_OFFSET               IPU_DC_OFFSET + 0x015C
+#define IPU_DC_MAP_CONF_22_OFFSET               IPU_DC_OFFSET + 0x0160
+#define IPU_DC_MAP_CONF_23_OFFSET               IPU_DC_OFFSET + 0x0164
+#define IPU_DC_MAP_CONF_24_OFFSET               IPU_DC_OFFSET + 0x0168
+#define IPU_DC_MAP_CONF_25_OFFSET               IPU_DC_OFFSET + 0x016C
+#define IPU_DC_MAP_CONF_26_OFFSET               IPU_DC_OFFSET + 0x0170
+#define IPU_DC_UGDE0_0_OFFSET                   IPU_DC_OFFSET + 0x0174
+#define IPU_DC_UGDE0_1_OFFSET                   IPU_DC_OFFSET + 0x0178
+#define IPU_DC_UGDE0_2_OFFSET                   IPU_DC_OFFSET + 0x017C
+#define IPU_DC_UGDE0_3_OFFSET                   IPU_DC_OFFSET + 0x0180
+#define IPU_DC_UGDE1_0_OFFSET                   IPU_DC_OFFSET + 0x0184
+#define IPU_DC_UGDE1_1_OFFSET                   IPU_DC_OFFSET + 0x0188
+#define IPU_DC_UGDE1_2_OFFSET                   IPU_DC_OFFSET + 0x018C
+#define IPU_DC_UGDE1_3_OFFSET                   IPU_DC_OFFSET + 0x0190
+#define IPU_DC_UGDE2_0_OFFSET                   IPU_DC_OFFSET + 0x0194
+#define IPU_DC_UGDE2_1_OFFSET                   IPU_DC_OFFSET + 0x0198
+#define IPU_DC_UGDE2_2_OFFSET                   IPU_DC_OFFSET + 0x019C
+#define IPU_DC_UGDE2_3_OFFSET                   IPU_DC_OFFSET + 0x01A0
+#define IPU_DC_UGDE3_0_OFFSET                   IPU_DC_OFFSET + 0x01A4
+#define IPU_DC_UGDE3_1_OFFSET                   IPU_DC_OFFSET + 0x01A8
+#define IPU_DC_UGDE3_2_OFFSET                   IPU_DC_OFFSET + 0x01AC
+#define IPU_DC_UGDE3_3_OFFSET                   IPU_DC_OFFSET + 0x01B0
+#define IPU_DC_LLA0_OFFSET                      IPU_DC_OFFSET + 0x01B4
+#define IPU_DC_LLA1_OFFSET                      IPU_DC_OFFSET + 0x01B8
+#define IPU_DC_R_LLA0_OFFSET                    IPU_DC_OFFSET + 0x01BC
+#define IPU_DC_R_LLA1_OFFSET                    IPU_DC_OFFSET + 0x01C0
+#define IPU_DC_WR_CH_ADDR_5_ALT_OFFSET          IPU_DC_OFFSET + 0x01C4
+#define IPU_DC_STAT_OFFSET                      IPU_DC_OFFSET + 0x01C8
+
+// Microcode template
+#define IPU_DC_TEMPLATE_REGS_ADDR_OFFSET        0x00180000
+
+typedef enum {
+    DC_CHANNEL_READ = 0,
+    DC_CHANNEL_DC_SYNC_ASYNC = 1,
+    DC_CHANNEL_DC_ASYNC = 2,
+    DC_CHANNEL_DP_MAIN = 5,
+    DC_CHANNEL_DP_SECONDARY = 6,
+} DC_CHANNEL;
+
+#pragma pack(push, 1)
+
+// IPU_DC_WR_CH_CONF_1 0x1C
+// IPU_DC_WR_CH_CONF_5 0x5C
+typedef union {
+    struct {
+        UINT32 W_SIZE : 2;
+        UINT32 PROG_DI_ID : 1;
+        UINT32 PROG_DISP_ID : 2;
+        UINT32 PROG_CHAN_TYP : 3;
+        UINT32 CHAN_MASK_DEFAULT : 1;
+        UINT32 FILED_MODE : 1;
+        UINT32 Reserved1 : 6;
+        UINT32 PROG_START_TIME : 11;
+        UINT32 Reserved2 : 5;
+    };
+    UINT32 Reg;
+} IPU_DC_WR_CH_CONF_1_REG, IPU_DC_WR_CH_CONF_5_REG;
+
+typedef enum {
+    PROG_CHAN_TYP_DISABLED,
+    PROG_CHAN_TYP_RESERVED1,
+    PROG_CHAN_TYP_NORMAL = 4,
+    PROG_CHAN_TYP_NORMAL_ANTI_TEARING,
+    PROG_CHAN_TYP_RESERVED2,
+} PROG_CHAN_TYP;
+
+// IPU_DC_GEN 0xD4
+typedef union {
+    struct {
+        UINT32 Reserved1 : 1;
+        UINT32 Sync_1_6 : 2;
+        UINT32 Reserved2 : 1;
+        UINT32 MASK_EN : 1;
+        UINT32 MASK4CHAN_5 : 1;
+        UINT32 SYNC_PRIORITY_5 : 1;
+        UINT32 SYNC_PRIORITY_1 : 1;
+        UINT32 DC_CH5_TYPE : 1;
+        UINT32 Reserved3 : 7;
+        UINT32 DC_BKDIV : 8;
+        UINT32 DC_BK_EN : 1;
+        UINT32 Reserved4 : 7;
+    };
+    UINT32 Reg;
+} IPUx_IPU_DC_GEN_REG;
+
+// IPU_DC_RL0_CH_5 0x0064
+typedef union {
+    struct {
+        UINT32 COD_NF_PRIORITY_CHAN_5 : 4;
+        UINT32 Reserved1 : 4;
+        UINT32 COD_NF_START_CHAN_5 : 8;
+        UINT32 COD_NL_PRIORITY_CHAN_5 : 4;
+        UINT32 Reserved2 : 4;
+        UINT32 COD_NL_START_CHAN_5 : 24;
+    };
+    UINT32 Reg;
+} IPU_DC_RL0_CH_5_REG;
+
+// IPU_DC_RL1_CH_5 0x006C
+typedef union {
+    struct {
+        UINT32 COD_EOF_PRIORITY_CHAN_5 : 4;
+        UINT32 Reserved1 : 4;
+        UINT32 COD_EOF_START_CHAN_5 : 8;
+        UINT32 COD_NFIELD_PRIORITY_CHAN_5 : 4;
+        UINT32 Reserved2 : 4;
+        UINT32 COD_NFIELD_START_CHAN_5 : 24;
+    };
+    UINT32 Reg;
+} IPU_DC_RL1_CH_5_REG;
+
+// IPU_DC_RL2_CH_5 0x0068
+typedef union {
+    struct {
+        UINT32 COD_EOL_PRIORITY_CHAN_5 : 4;
+        UINT32 Reserved1 : 4;
+        UINT32 COD_EOL_START_CHAN_5 : 8;
+        UINT32 COD_EOFIELD_PRIORITY_CHAN_5 : 4;
+        UINT32 Reserved2 : 4;
+        UINT32 COD_EOFIELD_START_CHAN_5 : 24;
+    };
+    UINT32 Reg;
+} IPU_DC_RL2_CH_5_REG;
+
+// IPU_DC_RL3_CH_5 0x0070
+typedef union {
+    struct {
+        UINT32 COD_NEW_ADDR_PRIORITY_CHAN_5 : 4;
+        UINT32 Reserved1 : 4;
+        UINT32 COD_NEW_ADDR_START_CHAN_5 : 8;
+        UINT32 COD_NEW_CHAN_PRIORITY_CHAN_5 : 4;
+        UINT32 Reserved2 : 4;
+        UINT32 COD_NEW_CHAN_START_CHAN_5 : 24;
+    };
+    UINT32 Reg;
+} IPU_DC_RL3_CH_5_REG;
+
+// IPU_DC_RL4_CH_5 0x0074
+typedef union {
+    struct {
+        UINT32 COD_NEW_DATA_PRIORITY_CHAN_5 : 4;
+        UINT32 Reserved1 : 4;
+        UINT32 COD_NEW_DATA_START_CHAN_5 : 8;
+        UINT32 Reserved2 : 16;
+    };
+    UINT32 Reg;
+} IPU_DC_RL4_CH_5_REG;
+
+// DC_DISP_CONF1 0xD8 - 0xE4
+typedef union {
+    struct {
+        UINT32 DISP_TYP : 2;
+        UINT32 ADDR_INCREMENT : 2;
+        UINT32 ADDR_BE_L_INC : 2;
+        UINT32 MCU_ACC_LB_MASK_3 : 1;
+        UINT32 DISP_RD_VALUE_PTR : 1;
+        UINT32 Reserved : 24;
+    };
+    UINT32 Reg;
+} IPUx_DC_DISP_CONF1_REG;
+
+// DC_MAP_CONF_MAP_OFFSET 0x0108 - 0x0140
+typedef union {
+    struct {
+        UINT32 MAPPING_PNTR_BYTE0_X : 5;
+        UINT32 MAPPING_PNTR_BYTE1_X : 5;
+        UINT32 MAPPING_PNTR_BYTE2_X : 5;
+        UINT32 Reserved1 : 1;
+        UINT32 MAPPING_PNTR_BYTE0_Y : 5;
+        UINT32 MAPPING_PNTR_BYTE1_Y : 5;
+        UINT32 MAPPING_PNTR_BYTE2_Y : 5;
+        UINT32 Reserved2 : 1;
+    };
+    UINT32 Reg;
+} IPUx_DC_MAP_CONF_MAP_REG;
+
+// DC_MAP_CONF_OFFSET_MASK_OFFSET 0x0144 - 0x0170
+typedef union {
+    struct {
+        UINT32 MD_MASK_X : 8;
+        UINT32 MD_OFFSET_X : 5;
+        UINT32 Reserved1 : 3;
+        UINT32 MD_MASK_Y : 8;
+        UINT32 MD_OFFSET_Y : 5;
+        UINT32 Reserved2 : 3;
+    };
+    UINT32 Reg;
+} DC_MAP_CONF_OFFSET_MASK_REG;
+
+#pragma pack(pop)
+
+OS_STATUS SetDCChannelState (
+    VOID* IpuMmioBasePtr,
+    PROG_CHAN_TYP State
+    );
+
+OS_STATUS ConfigureDCChannel (
+    DISPLAY_INTERFACE_CONTEXT* DIContextPtr,
+    DISPLAY_INTERFACE DisplayInterface,
+    UINT32 DisplayIndex,
+    DISPLAY_TIMING* DisplayTimingPtr
+    );
+
+#endif
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayInterface.c b/Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayInterface.c
new file mode 100644
index 000000000000..468cb4c90609
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayInterface.c
@@ -0,0 +1,444 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "Osal.h"
+
+#include "Ipu.h"
+#include "Display.h"
+#include "DisplayInterface.h"
+
+#define READ_WAVE_GEN(IPU_BASE, GEN_INDEX) \
+    DiRead32(IPU_BASE, IPU_DIx_DW_GEN_OFFSET + (GEN_INDEX * 0x4))
+
+#define WRITE_WAVE_GEN(IPU_BASE, GEN_INDEX, VALUE) \
+    DiWrite32(IPU_BASE, IPU_DIx_DW_GEN_OFFSET + (GEN_INDEX * 0x4), VALUE)
+
+#define READ_WAVE_SET(IPU_BASE, GEN_INDEX, SET_NUMBER) \
+    DiRead32(IPU_BASE, IPU_DIx_DW_SET0_OFFSET + (SET_NUMBER * 0x30) + (GEN_INDEX * 0x4))
+
+#define WRITE_WAVE_SET(IPU_BASE, GEN_INDEX, SET_NUMBER, VALUE) \
+    DiWrite32(IPU_BASE, IPU_DIx_DW_SET0_OFFSET + (SET_NUMBER * 0x30) + (GEN_INDEX * 0x4), VALUE)
+
+VOID DumpBasicDIReg (
+    VOID* IpuMmioBasePtr,
+    IPU_DIx_REGS* IpuDiRegsPtr
+    )
+{
+    UINT32 index, setNumber, regVal;
+    UINT32 printTotalGen = 8; // Limit printing (max 12)
+
+    OS_INFO("---------- DI Register Dump ----------\n");
+    // Print out generator value for D0
+    OS_INFO("## Wave Gen\n");
+    for (index = 0; index < printTotalGen; ++index) {
+        regVal = READ_WAVE_GEN(IpuDiRegsPtr, index);
+        OS_INFO("DI0_DW_GEN_%d 0x%08x\n", index, regVal);
+    }
+    // Print out generator value for D0
+    OS_INFO("## Wave Set\n");
+    for (index = 0; index < printTotalGen; ++index) {
+        for (setNumber = 0; setNumber < 4; ++setNumber) {
+            regVal = READ_WAVE_SET(IpuDiRegsPtr, index, setNumber);
+            OS_INFO("DI0_DW_SET%d_%d 0x%08x\n", setNumber, index, regVal);
+        }
+    }
+
+    regVal = IpuRead32(IpuMmioBasePtr, IPU_IPU_PM_OFFSET);
+    OS_INFO("IPU_IPU_PM_OFFSET %x\n", regVal);
+
+    regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_BS_CLKGEN0_OFFSET);
+    OS_INFO("IPU_DIx_BS_CLKGEN0_OFFSET %x\n", regVal);
+    regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_BS_CLKGEN1_OFFSET);
+    OS_INFO("IPU_DIx_BS_CLKGEN1_OFFSET %x\n", regVal);
+    regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_SCR_CONF_OFFSET);
+    OS_INFO("IPU_DIx_SCR_CONF_OFFSET %x\n", regVal);
+    regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_SW_GEN0_1_OFFSET);
+    OS_INFO("IPU_DIx_SW_GEN0_1_OFFSET %x\n", regVal);
+    regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_SW_GEN1_1_OFFSET);
+    OS_INFO("IPU_DIx_SW_GEN1_1_OFFSET %x\n", regVal);
+    regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_SW_GEN0_2_OFFSET);
+    OS_INFO("IPU_DIx_SW_GEN0_2_OFFSET %x\n", regVal);
+    regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_SW_GEN1_2_OFFSET);
+    OS_INFO("IPU_DIx_SW_GEN1_2_OFFSET %x\n", regVal);
+    regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_SW_GEN0_3_OFFSET);
+    OS_INFO("IPU_DIx_SW_GEN0_3_OFFSET %x\n", regVal);
+    regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_SW_GEN1_3_OFFSET);
+    OS_INFO("IPU_DIx_SW_GEN1_3_OFFSET %x\n", regVal);
+    regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_SW_GEN0_4_OFFSET);
+    OS_INFO("IPU_DIx_SW_GEN0_4_OFFSET %x\n", regVal);
+    regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_SW_GEN1_4_OFFSET);
+    OS_INFO("IPU_DIx_SW_GEN1_4_OFFSET %x\n", regVal);
+    regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_SW_GEN0_5_OFFSET);
+    OS_INFO("IPU_DIx_SW_GEN0_5_OFFSET %x\n", regVal);
+    regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_SW_GEN1_5_OFFSET);
+    OS_INFO("IPU_DIx_SW_GEN1_5_OFFSET %x\n", regVal);
+
+    for (index = 0; index < 5; ++index) {
+        regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_STP_REP_OFFSET +  (index * 0x4));
+        OS_INFO("IPU_DIx_STP_%d_REP_OFFSET %x\n", index + 1, regVal);
+    }
+
+    regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_SYNC_AS_GEN_OFFSET);
+    OS_INFO("IPU_DIx_SYNC_AS_GEN_OFFSET %x\n", regVal);
+    regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_GENERAL_OFFSET);
+    OS_INFO("IPU_DIx_GENERAL_OFFSET %x\n", regVal);
+    regVal = DiRead32(IpuDiRegsPtr, IPU_DIx_POL_OFFSET);
+    OS_INFO("IPU_DIx_POL_OFFSET %x\n", regVal);
+    regVal = DiRead32(IpuDiRegsPtr, IPU_IPU_DISP_GEN_OFFSET);
+    OS_INFO("IPU_IPU_DISP_GEN_OFFSET %x\n", regVal);
+    OS_INFO("------------------------------------\n\n");
+}
+
+VOID ConfigureSyncWave (
+    VOID* IpuMmioBasePtr,
+    IPU_DIx_REGS* IpuDiRegsPtr,
+    UINT32 CounterIndex,
+    UINT32 RunValue,
+    UINT32 RunResolution,
+    UINT32 OffsetValue,
+    UINT32 OffsetResolution,
+    UINT32 CounterPolarityGenEn,
+    UINT32 CounterAutoReload,
+    UINT32 CounterClearSelect,
+    UINT32 CounterDown,
+    UINT32 CounterPolarityTriggerSelect,
+    UINT32 CounterPolarityClearSelect,
+    UINT32 CounterUp,
+    UINT32 StepRepeat
+    )
+{
+    IPUx_DIx_SW_GEN0_x_REG diSwGen0Reg;
+    IPUx_DIx_SW_GEN1_x_REG diSwGen1Reg;
+    IPUx_DIx_STP_REP_REG stepRepeatReg;
+
+    OS_ZERO_MEM((void*)&diSwGen0Reg, sizeof(diSwGen0Reg));
+    diSwGen0Reg.dix_offset_resolution = OffsetResolution;
+    diSwGen0Reg.dix_offset_value = OffsetValue;
+    diSwGen0Reg.dix_run_resolution = RunResolution;
+    diSwGen0Reg.dix_run_value_m1 = RunValue;
+
+    DiWrite32(
+        IpuDiRegsPtr,
+        IPU_DIx_SW_GEN0_1_OFFSET + ((CounterIndex - 1) * 0x04),
+        diSwGen0Reg.Reg);
+
+    OS_ZERO_MEM((void*)&diSwGen1Reg, sizeof(diSwGen1Reg));
+    diSwGen1Reg.dix_cnt_up = CounterUp;
+    diSwGen1Reg.dix_cnt_polarity_clr_sel = CounterPolarityClearSelect;
+    diSwGen1Reg.dix_cnt_polarity_trigger_sel = CounterPolarityTriggerSelect;
+    diSwGen1Reg.dix_cnt_down = CounterDown;
+    diSwGen1Reg.dix_cnt_clr_sel = CounterClearSelect;
+    diSwGen1Reg.dix_cnt_auto_reload = CounterAutoReload;
+    diSwGen1Reg.dix_cnt_polarity_gen_en = CounterPolarityGenEn;
+
+    DiWrite32(
+        IpuDiRegsPtr,
+        IPU_DIx_SW_GEN1_1_OFFSET + ((CounterIndex - 1) * 0x04),
+        diSwGen1Reg.Reg);
+
+    {
+        UINT32 stepIndex = (CounterIndex - 1) / 2;
+
+        stepRepeatReg.Reg = IpuRead32(
+            IpuMmioBasePtr,
+            IPU_DI0_STP_REP_OFFSET + (stepIndex * 0x4));
+
+        if (CounterIndex % 2) {
+            stepRepeatReg.dix_step_repeat_2i_minus_1 = StepRepeat;
+        } else {
+            stepRepeatReg.dix_step_repeat_2i = StepRepeat;
+        }
+
+        IpuWrite32(
+            IpuMmioBasePtr,
+            IPU_DI0_STP_REP_OFFSET + (stepIndex * 0x4),
+            stepRepeatReg.Reg);
+    }
+}
+
+OS_STATUS ConfigureDI (
+    DISPLAY_INTERFACE_CONTEXT* DIContextPtr,
+    UINT32 DisplayIndex,
+    DISPLAY_TIMING* DisplayTimingPtr
+    )
+{
+    OS_STATUS status;
+    UINT32 baseDiv;
+    UINT64 diFreq = DisplayTimingPtr->PixelClock;
+    UINT32 hTotal = DisplayTimingPtr->HActive + DisplayTimingPtr->HBlank;
+    UINT32 vTotal = DisplayTimingPtr->VActive + DisplayTimingPtr->VBlank;
+    VOID* ipuMmioBasePtr = DIContextPtr->IpuMmioBasePtr;
+    IPU_DIx_REGS* ipuDiRegsPtr = DIContextPtr->IpuDiRegsPtr;
+
+    status = ImxSetPll5ReferenceRate(DisplayTimingPtr->PixelClock);
+    if (status != OS_STATUS_SUCCESS) {
+        OS_ERROR("Fail to setup PLL5=%r\n", status);
+        goto Exit;
+    }
+
+    // Setup base timer (fundamental timer). The base timer should already
+    // setup to match the pixel clock frequency.
+    // Shift 4 as the bottom 4 bits are fractional
+    baseDiv = (UINT32)((diFreq << 4) / DisplayTimingPtr->PixelClock);
+
+    DiWrite32(ipuDiRegsPtr, IPU_DIx_BS_CLKGEN0_OFFSET, baseDiv);
+
+    // Up is always set to 0. Down is half of the pixel clock period where
+    // the first bit is fraction
+    baseDiv >>= 4;
+
+    DiWrite32(ipuDiRegsPtr, IPU_DIx_BS_CLKGEN1_OFFSET, baseDiv << 16);
+    // Calculate divisor, again this would usually be 1.
+    baseDiv = (UINT32)(diFreq / DisplayTimingPtr->PixelClock);
+
+    // Set up wave, there 12 wave quartet, for now default to the first.
+    // Each wave quartet has 4 set register
+    {
+        IPUx_DIx_DW_SET_REG dixDwSetReg;
+        IPUx_DIx_DW_GEN_REG dixDwGenReg;
+
+        // Set 0 is just a blank signal where up and down is set to 0
+        OS_ZERO_MEM((void*)&dixDwSetReg, sizeof(dixDwSetReg));
+        dixDwSetReg.dix_data_cnt_upx_i = 0;
+        dixDwSetReg.dix_data_cnt_downx_i = 0;
+        WRITE_WAVE_SET(
+            ipuDiRegsPtr,
+            DW_GEN_0,
+            DW_SET_0,
+            dixDwSetReg.Reg);
+
+        // Set 3 is setup to match pixel clock
+        OS_ZERO_MEM((void*)&dixDwSetReg, sizeof(dixDwSetReg));
+        dixDwSetReg.dix_data_cnt_upx_i = 0;
+        dixDwSetReg.dix_data_cnt_downx_i = baseDiv * 2;
+        WRITE_WAVE_SET(
+            ipuDiRegsPtr,
+            DW_GEN_0,
+            DW_SET_3,
+            dixDwSetReg.Reg);
+
+        // All pins blank signal except pin 15
+        // Need to get pin mapping documentation
+        OS_ZERO_MEM((void*)&dixDwGenReg, sizeof(dixDwGenReg));
+        dixDwGenReg.dix_pt_0_i = DW_SET_0;
+        dixDwGenReg.dix_pt_1_i = DW_SET_0;
+        dixDwGenReg.dix_pt_2_i = DW_SET_0;
+        dixDwGenReg.dix_pt_3_i = DW_SET_0;
+        dixDwGenReg.dix_pt_4_i = DW_SET_3;
+        dixDwGenReg.dix_pt_5_i = DW_SET_0;
+        dixDwGenReg.dix_pt_6_i = DW_SET_0;
+        dixDwGenReg.dix_cst_i = DW_SET_0;
+
+        // Reuse the base divisor to determine extra IPU cycles.
+        dixDwGenReg.dix_componnent_size_i = dixDwGenReg.dix_access_size_i =
+            baseDiv - 1;
+        WRITE_WAVE_GEN(ipuDiRegsPtr, DW_GEN_0, dixDwGenReg.Reg);
+    }
+
+    // Spec mention this as number of display rows but display only works
+    // proper if this is setup as vertical total
+    DiWrite32(ipuDiRegsPtr, IPU_DIx_SCR_CONF_OFFSET, vTotal - 1);
+
+    {
+        // Internal HSYNC
+        ConfigureSyncWave(
+            ipuMmioBasePtr,
+            ipuDiRegsPtr,
+            DI_COUNTER_1_INTERNAL_HSYNC, // CounterIndex
+            hTotal - 1,   // Runvalue
+            DI_COUNTER_0_DISPLAY_CLOCK + 1, // RunResolution
+            0,            // OffsetValue
+            0,            // OffsetResolution
+            0,            // CounterPolarityGenEn
+            1,            // CounterAutoReload
+            DI_COUNTER_DISABLED, // CounterClearSelect
+            0,            // CountDown
+            0,            // CounterPolarityTriggerSelect
+            0,            // CounterPolarityClearSelect
+            0,            // CounterUp
+            0);           // StepRepeat
+
+        // Output HSYNC
+        ConfigureSyncWave(
+            ipuMmioBasePtr,
+            ipuDiRegsPtr,
+            DI_COUNTER_2_OUTPUT_HSYNC, // CounterIndex
+            hTotal - 1,   // Runvalue
+            DI_COUNTER_0_DISPLAY_CLOCK + 1, // RunResolution
+            0,            // OffsetValue
+            DI_COUNTER_0_DISPLAY_CLOCK + 1, // OffsetResolution - Display clock
+            1,            // CounterPolarityGenEn
+            1,            // CounterAutoReload
+            DI_COUNTER_DISABLED, // CounterClearSelect
+            DisplayTimingPtr->HSync * 2,    // CountDown
+            1,            // CounterPolarityTriggerSelect
+            0,            // CounterPolarityClearSelect
+            0,            // CounterUp
+            0);           // StepRepeat
+
+        // Output VSYNC
+        ConfigureSyncWave(
+            ipuMmioBasePtr,
+            ipuDiRegsPtr,
+            DI_COUNTER_3_OUTPUT_VSYNC, // CounterIndex
+            vTotal - 1,   // Runvalue
+            DI_COUNTER_1_INTERNAL_HSYNC + 1, // RunResolution - Counter 1
+            0,            // OffsetValue
+            0,            // OffsetResolution
+            1,            // CounterPolarityGenEn
+            1,            // CounterAutoReload
+            DI_COUNTER_DISABLED, // CounterClearSelect
+            DisplayTimingPtr->VSync * 2,    // CountDown
+            2,            // CounterPolarityTriggerSelect
+            0,            // CounterPolarityClearSelect
+            0,            // CounterUp
+            0);           // StepRepeat
+
+        // Active lines
+        ConfigureSyncWave(
+            ipuMmioBasePtr,
+            ipuDiRegsPtr,
+            DI_COUNTER_4_ACTIVE_LINE , // CounterIndex
+            0,            // Runvalue
+            DI_COUNTER_2_OUTPUT_HSYNC + 1, // RunResolution - Counter 2
+            DisplayTimingPtr->VSync + DisplayTimingPtr->VSyncOffset, // Offset
+            DI_COUNTER_2_OUTPUT_HSYNC + 1,// OffsetResolution - Counter 2
+            0,            // CounterPolarityGenEn
+            0,            // CounterAutoReload
+            DI_COUNTER_3_OUTPUT_VSYNC + 1, // CounterClearSelect - Counter 3
+            0,            // CountDown
+            0,            // CounterPolarityTriggerSelect
+            0,            // CounterPolarityClearSelect
+            0,            // CounterUp
+            DisplayTimingPtr->VActive); // StepRepeat repeat for total VActive
+
+        // Active clock
+        ConfigureSyncWave(
+            ipuMmioBasePtr,
+            ipuDiRegsPtr,
+            DI_COUNTER_5_ACTIVE_CLOCK, // CounterIndex
+            0,            // Runvalue
+            DI_COUNTER_0_DISPLAY_CLOCK + 1, // RunResolution - Display clock
+            DisplayTimingPtr->HSync + DisplayTimingPtr->HSyncOffset, // Offset
+            DI_COUNTER_0_DISPLAY_CLOCK + 1, // OffsetResolution - Display clock
+            0,            // CounterPolarityGenEn
+            0,            // CounterAutoReload
+            DI_COUNTER_4_ACTIVE_LINE + 1, // CounterClearSelect - Counter 4
+            0,            // CountDown
+            0,            // CounterPolarityTriggerSelect
+            0,            // CounterPolarityClearSelect
+            0,            // CounterUp
+            DisplayTimingPtr->HActive); // StepRepeat
+    }
+
+    {
+        IPUx_DIx_SYNC_AS_GEN_REG dixSyncAsGenReg;
+
+        OS_ZERO_MEM((void*)&dixSyncAsGenReg, sizeof(dixSyncAsGenReg));
+        // VSYNC is setup as counter 3 above, 0 index based
+        dixSyncAsGenReg.dix_vsync_sel = 3 - 1;
+        // Number of row DI prepares next frame data.
+        // This seem to be the default value.
+        dixSyncAsGenReg.dix_sync_start = 2;
+        DiWrite32(ipuDiRegsPtr, IPU_DIx_SYNC_AS_GEN_OFFSET, dixSyncAsGenReg.Reg);
+    }
+
+    // Setup general register
+    {
+        IPUx_DIx_GENERAL_REG dixGeneralReg;
+
+        OS_ZERO_MEM((void*)&dixGeneralReg, sizeof(dixGeneralReg));
+        // Counter 1 as display line
+        dixGeneralReg.dix_disp_y_sel = DI_COUNTER_1_INTERNAL_HSYNC - 1;
+        // Stop at the next edge of the display clock
+        dixGeneralReg.DIx_CLOCK_STOP_MODE = 0;
+        // The display's clock is stopped after the next VSYNC
+        dixGeneralReg.DIx_DISP_CLOCK_INIT = 0;
+        // IPP_PIN_2 is coming from counter #2
+        dixGeneralReg.dix_mask_sel = 0;
+        // External clock - for not the video PLL
+        dixGeneralReg.dix_vsync_ext = 1;
+        // External clock - for not the video PLL
+        dixGeneralReg.dix_clk_ext = 1;
+        // 4 cycle watch dog based on BSP
+        dixGeneralReg.DIx_WATCHDOG_MODE = 0;
+        // default sync to counter 0
+        dixGeneralReg.dix_sync_count_sel = DI_COUNTER_1_INTERNAL_HSYNC - 1;
+        // In the event of error drive the last component
+        dixGeneralReg.dix_err_treatment = 0;
+        // An internal VSYNC signal asserted 2 lines before the DI's VSYNC
+        dixGeneralReg.dix_erm_vsync_sel = 0;
+
+        switch(DIContextPtr->displayInterface)
+        {
+            case HDMI_DISPLAY:
+                // Zero for HDMI display
+                dixGeneralReg.dix_polarity_disp_clk = 0;
+                dixGeneralReg.dix_polarity_cs1 = 0;
+                dixGeneralReg.dix_polarity_cs0 = 0;
+                dixGeneralReg.dix_polarity_i_1 = 0;
+                break;
+            default:
+                status = OS_STATUS_UNSUPPORTED;
+                OS_ERROR(
+                    "Unsupported display interface %d",
+                    DIContextPtr->displayInterface);
+                goto Exit;
+        }
+
+        DiWrite32(ipuDiRegsPtr, IPU_DIx_GENERAL_OFFSET, dixGeneralReg.Reg);
+    }
+
+    {
+        IPUx_DIx_POL_REG dixPolReg;
+
+        OS_ZERO_MEM((void*)&dixPolReg, sizeof(dixPolReg));
+        // CS0
+        dixPolReg.DIx_CS0_DATA_POLARITY = 1;
+        dixPolReg.dix_cs0_polarity = 0x7F;
+        // CS1
+        dixPolReg.DIx_CS1_DATA_POLARITY = 1;
+        dixPolReg.dix_cs1_polarity = 0x7F;
+        // DRDY
+        dixPolReg.DIx_DRDY_DATA_POLARITY = 0;
+        dixPolReg.dix_drdy_polarity = 0x7F;
+        // Wait
+        dixPolReg.DIx_WAIT_POLARITY = 0;
+        // CS0 byte enable polarity
+        dixPolReg.DIx_CS0_BYTE_EN_POLARITY = 0;
+        // CS1 byte enable polarity
+        dixPolReg.DIx_CS1_BYTE_EN_POLARITY = 0;
+
+        DiWrite32(ipuDiRegsPtr, IPU_DIx_POL_OFFSET, dixPolReg.Reg);
+    }
+
+    {
+        UINT32 dispGenReg;
+
+        dispGenReg = IpuRead32(ipuMmioBasePtr, IPU_IPU_DISP_GEN_OFFSET);
+        dispGenReg &= ~(0x0F << 18);
+        dispGenReg |= (2 << 18);
+        IpuWrite32(ipuMmioBasePtr, IPU_IPU_DISP_GEN_OFFSET, dispGenReg);
+    }
+
+    // Register dump, commented out by default
+#ifdef REGISTER_DUMP
+    DumpBasicDIReg(ipuMmioBasePtr, ipuDiRegsPtr);
+#endif
+
+    status = OS_STATUS_SUCCESS;
+
+Exit:
+    return status;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayInterface.h b/Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayInterface.h
new file mode 100644
index 000000000000..0c8ede1e8fde
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/DisplayInterface.h
@@ -0,0 +1,182 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _DI_H_
+#define _DI_H_
+
+OS_STATUS ConfigureDI (
+    DISPLAY_INTERFACE_CONTEXT* DIContextPtr,
+    UINT32 DisplayIndex,
+    DISPLAY_TIMING* DisplayTimingPtr
+    );
+
+enum {
+    DW_GEN_0 = 0,
+    DW_GEN_1 = 1,
+    DW_GEN_2 = 2,
+    DW_GEN_3 = 3,
+    DW_GEN_4 = 4,
+    DW_GEN_5 = 5,
+    DW_GEN_6 = 6,
+    DW_GEN_7 = 7,
+    DW_GEN_8 = 8,
+    DW_GEN_9 = 9,
+    DW_GEN_10 = 10,
+    DW_GEN_11 = 11,
+};
+
+enum {
+    DW_SET_0 = 0,
+    DW_SET_1 = 1,
+    DW_SET_2 = 2,
+    DW_SET_3 = 3,
+};
+
+enum {
+    DI_COUNTER_DISABLED = 0,
+    DI_COUNTER_0_DISPLAY_CLOCK = 0,
+    DI_COUNTER_1_INTERNAL_HSYNC = 1,
+    DI_COUNTER_2_OUTPUT_HSYNC = 2,
+    DI_COUNTER_3_OUTPUT_VSYNC = 3,
+    DI_COUNTER_4_ACTIVE_LINE = 4,
+    DI_COUNTER_5_ACTIVE_CLOCK = 5,
+};
+
+#pragma pack(push, 1)
+
+// IPUx_DIx_GENERAL
+typedef union {
+    struct {
+        UINT32 dix_polarity_i_1 : 8;
+        UINT32 dix_polarity_cs0 : 1;
+        UINT32 dix_polarity_cs1 : 1;
+        UINT32 dix_erm_vsync_sel : 1;
+        UINT32 dix_err_treatment : 1;
+        UINT32 dix_sync_count_sel : 4;
+        UINT32 Reserved : 1;
+        UINT32 dix_polarity_disp_clk : 1;
+        UINT32 DIx_WATCHDOG_MODE : 2;
+        UINT32 dix_clk_ext : 1;
+        UINT32 dix_vsync_ext : 1;
+        UINT32 dix_mask_sel : 1;
+        UINT32 DIx_DISP_CLOCK_INIT : 1;
+        UINT32 DIx_CLOCK_STOP_MODE : 4;
+        UINT32 dix_disp_y_sel : 3;
+        UINT32 dix_pin8_pin15_sel : 1;
+    };
+    UINT32 Reg;
+} IPUx_DIx_GENERAL_REG;
+
+// IPUx_DIx_SYNC_AS_GEN
+typedef union {
+    struct {
+        UINT32 dix_sync_start : 12;
+        UINT32 Reserved1 : 1;
+        UINT32 dix_vsync_sel : 3;
+        UINT32 Reserved2 : 12;
+        UINT32 di0_sync_start_en : 1;
+        UINT32 Reserved3 : 3;
+    };
+    UINT32 Reg;
+} IPUx_DIx_SYNC_AS_GEN_REG;
+
+// IPUx_DIx_DW_SET
+typedef union {
+    struct {
+        UINT32 dix_data_cnt_upx_i : 9;
+        UINT32 Reserved1 : 7;
+        UINT32 dix_data_cnt_downx_i : 9;
+        UINT32 Reserved2 : 7;
+    };
+    UINT32 Reg;
+} IPUx_DIx_DW_SET_REG;
+
+// IPUx_DIx_DW_GEN
+typedef union {
+    struct {
+        UINT32 dix_pt_0_i : 2;  // Pin 11
+        UINT32 dix_pt_1_i : 2;  // Pin 12
+        UINT32 dix_pt_2_i : 2;  // Pin 13
+        UINT32 dix_pt_3_i : 2;  // Pin 14
+        UINT32 dix_pt_4_i : 2;  // Pin 15
+        UINT32 dix_pt_5_i : 2;  // Pin 16
+        UINT32 dix_pt_6_i : 2;  // Pin 17
+        UINT32 dix_cst_i : 2;   // Chip Select
+        UINT32 dix_componnent_size_i : 8;
+        UINT32 dix_access_size_i : 8;
+    };
+    UINT32 Reg;
+} IPUx_DIx_DW_GEN_REG;
+
+
+// IPUx_DIx_SW_GEN0_x_REG
+typedef union {
+    struct {
+        UINT32 dix_offset_resolution : 3;
+        UINT32 dix_offset_value : 12;
+        UINT32 Reserved1: 1;
+        UINT32 dix_run_resolution : 3;
+        UINT32 dix_run_value_m1 : 12;
+        UINT32 Reserved2 : 1;
+    };
+    UINT32 Reg;
+} IPUx_DIx_SW_GEN0_x_REG;
+
+// IPUx_DIx_SW_GEN1_x_REG
+typedef union {
+    struct {
+        UINT32 dix_cnt_up : 9;
+        UINT32 dix_cnt_polarity_clr_sel : 3;
+        UINT32 dix_cnt_polarity_trigger_sel : 3;
+        UINT32 Reserved1 : 1;
+        UINT32 dix_cnt_down: 9;
+        UINT32 dix_cnt_clr_sel : 3;
+        UINT32 dix_cnt_auto_reload : 1;
+        UINT32 dix_cnt_polarity_gen_en : 2;
+        UINT32 Reserved2 : 1;
+    };
+    UINT32 Reg;
+} IPUx_DIx_SW_GEN1_x_REG;
+
+// IPUx_DIx_STP_REP
+typedef union {
+    struct {
+        UINT32 dix_step_repeat_2i_minus_1 : 12;
+        UINT32 Reserved1 : 4;
+        UINT32 dix_step_repeat_2i : 12;
+        UINT32 Reserved2 : 4;
+    };
+    UINT32 Reg;
+} IPUx_DIx_STP_REP_REG;
+
+// IPUx_DIx_POL
+typedef union {
+    struct {
+        UINT32 dix_drdy_polarity : 7;
+        UINT32 DIx_DRDY_DATA_POLARITY : 1;
+        UINT32 dix_cs0_polarity : 7;
+        UINT32 DIx_CS0_DATA_POLARITY : 1;
+        UINT32 dix_cs1_polarity : 7;
+        UINT32 DIx_CS1_DATA_POLARITY : 1;
+        UINT32 DIx_CS0_BYTE_EN_POLARITY : 1;
+        UINT32 DIx_CS1_BYTE_EN_POLARITY : 1;
+        UINT32 DIx_WAIT_POLARITY : 1;
+        UINT32 Reserved : 5;
+    };
+    UINT32 Reg;
+} IPUx_DIx_POL_REG;
+
+#pragma pack(pop)
+
+#endif
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/Edid.c b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Edid.c
new file mode 100644
index 000000000000..85f8bd137963
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Edid.c
@@ -0,0 +1,82 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "Osal.h"
+#include <iMXDisplay.h>
+#include "Display.h"
+#include "Edid.h"
+#include "Ddc.h"
+
+OS_STATUS ReadEDID (
+    DISPLAY_CONTEXT* DisplayContextPtr,
+    DISPLAY_INTERFACE DisplayInterface,
+    UINT8* EdidDataPtr,
+    UINT32* EdidDataSizePtr)
+{
+    OS_STATUS status;
+
+    status = IMX6DDCRead(
+        DisplayContextPtr,
+        DisplayInterface,
+        EDID_I2C_ADDRESS,
+        0,
+        EDID_MIN_SIZE,
+        EdidDataPtr);
+    if (status != OS_STATUS_SUCCESS) {
+        goto Exit;
+    }
+
+    status = ValidateEdidData(
+        EdidDataPtr);
+    if (status != OS_STATUS_SUCCESS) {
+        OS_WARNING("Invalid EDID data\n");
+        goto Exit;
+    }
+
+    OS_INFO("EDID initialized\n");
+
+    *EdidDataSizePtr = EDID_MIN_SIZE;
+
+Exit:
+    return status;
+}
+
+OS_STATUS GetEDIDPreferedTiming (
+    UINT8* EdidDataPtr,
+    UINT32 EdidDataSizePtr,
+    DISPLAY_TIMING* PreferedTiming
+)
+{
+    OS_STATUS status;
+    DETAILED_TIMING_DESCRIPTOR* edidPreferedtiming;
+
+    if (EdidDataSizePtr < EDID_MIN_SIZE) {
+        OS_WARNING("Insufficient EDID data\n");
+        status = OS_STATUS_INVALID_PARAM;
+        goto Exit;
+    }
+
+    edidPreferedtiming =
+        (DETAILED_TIMING_DESCRIPTOR*)&EdidDataPtr[EDID_DTD_1_OFFSET];
+
+    status = ConvertDTDToDisplayTiming(edidPreferedtiming, PreferedTiming);
+    if (status != OS_STATUS_SUCCESS) {
+        OS_ERROR("Conversion to display timing failed\n");
+        goto Exit;
+    }
+
+Exit:
+
+    return status;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/Edid.h b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Edid.h
new file mode 100644
index 000000000000..578f938a304d
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Edid.h
@@ -0,0 +1,31 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _EDID_H_
+#define _EDID_H_
+
+OS_STATUS ReadEDID (
+    DISPLAY_CONTEXT* DisplayContextPtr,
+    DISPLAY_INTERFACE DisplayInterface,
+    UINT8* EdidDataPtr,
+    UINT32* EdidDataSizePtr
+    );
+
+OS_STATUS GetEDIDPreferedTiming (
+    UINT8* EdidDataPtr,
+    UINT32 EdidDataSizePtr,
+    DISPLAY_TIMING* PreferedTiming
+    );
+
+#endif
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/Hdmi.c b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Hdmi.c
new file mode 100644
index 000000000000..91901ea42b02
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Hdmi.c
@@ -0,0 +1,608 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "Osal.h"
+
+#include "Display.h"
+#include "Hdmi.h"
+#include "Edid.h"
+
+PLL_MPLL_CONFIG PllMpllGenericConfigSetting[] = {
+    { 13500000,2,8,{ { 3,0,3,3,0,0,0,0, } }, { { 4,3,4,4,0, } }, { { 0,0,0, } },  },
+    { 13500000,2,10,{ { 1,4,3,3,0,0,1,0, } }, { { 4,3,4,4,0, } }, { { 0,0,0, } },  },
+    { 13500000,2,12,{ { 2,4,3,3,0,0,2,0, } }, { { 4,3,3,3,0, } }, { { 0,0,0, } },  },
+    { 13500000,2,16,{ { 3,1,3,2,0,0,3,0, } }, { { 4,3,4,4,0, } }, { { 1,0,0, } },  },
+    { 13500000,4,8,{ { 3,1,3,2,0,0,0,0, } }, { { 4,3,4,4,0, } }, { { 1,0,0, } },  },
+    { 13500000,4,10,{ { 1,5,3,2,0,0,1,0, } }, { { 4,3,4,4,0, } }, { { 1,0,0, } },  },
+    { 13500000,4,12,{ { 2,5,3,2,0,0,2,0, } }, { { 4,3,3,3,0, } }, { { 1,0,0, } },  },
+    { 13500000,4,16,{ { 3,2,3,1,0,0,3,0, } }, { { 4,3,4,4,0, } }, { { 2,0,0, } },  },
+    { 18000000,3,8,{ { 2,1,3,2,0,0,0,0, } }, { { 4,3,4,4,0, } }, { { 1,0,0, } },  },
+    { 18000000,3,16,{ { 2,2,3,1,0,0,3,0, } }, { { 4,3,4,4,0, } }, { { 2,0,0, } },  },
+    { 24175000,1,8,{ { 0,0,3,3,0,0,0,0, } }, { { 4,3,4,4,0, } }, { { 0,0,0, } },  },
+    { 24175000,1,10,{ { 1,0,3,3,0,0,1,0, } }, { { 4,3,4,4,0, } }, { { 0,0,0, } },  },
+    { 24175000,1,12,{ { 2,0,3,3,0,0,2,0, } }, { { 4,3,3,3,0, } }, { { 0,0,0, } },  },
+    { 24175000,1,16,{ { 3,0,2,2,0,0,3,0, } }, { { 4,3,4,4,0, } }, { { 1,1,0, } },  },
+    { 27000000,1,8,{ { 0,0,3,3,0,0,0,0, } }, { { 4,3,4,4,0, } }, { { 0,0,0, } },  },
+    { 27000000,1,10,{ { 1,0,3,3,0,0,1,0, } }, { { 4,3,4,4,0, } }, { { 0,0,0, } },  },
+    { 27000000,1,12,{ { 2,0,3,3,0,0,2,0, } }, { { 4,3,3,3,0, } }, { { 0,0,0, } },  },
+    { 27000000,1,16,{ { 3,0,2,2,0,0,3,0, } }, { { 4,3,5,4,0, } }, { { 1,0,0, } },  },
+    { 27000000,2,8,{ { 3,0,2,2,0,0,0,0, } }, { { 4,3,4,4,0, } }, { { 1,1,0, } },  },
+    { 27000000,2,10,{ { 1,1,3,2,0,0,1,0, } }, { { 4,3,4,4,0, } }, { { 1,0,0, } },  },
+    { 27000000,2,12,{ { 2,1,3,2,0,0,2,0, } }, { { 4,3,3,3,0, } }, { { 1,0,0, } },  },
+    { 27000000,2,16,{ { 3,1,2,1,0,0,3,0, } }, { { 4,3,4,4,0, } }, { { 2,1,0, } },  },
+    { 27000000,4,8,{ { 3,1,2,1,0,0,0,0, } }, { { 4,3,4,4,0, } }, { { 2,1,0, } },  },
+    { 27000000,4,10,{ { 1,2,3,1,0,0,1,0, } }, { { 4,3,4,4,0, } }, { { 2,0,0, } },  },
+    { 27000000,4,12,{ { 2,2,3,1,0,0,2,0, } }, { { 4,3,3,3,0, } }, { { 2,0,0, } },  },
+    { 27000000,4,16,{ { 3,2,2,0,0,0,3,0, } }, { { 4,3,4,4,0, } }, { { 3,1,0, } },  },
+    { 36000000,1,8,{ { 0,0,3,3,0,0,0,0, } }, { { 4,3,4,4,0, } }, { { 0,0,0, } },  },
+    { 36000000,1,16,{ { 3,0,2,2,0,0,3,0, } }, { { 4,3,4,4,0, } }, { { 1,1,0, } },  },
+    { 50350000,1,8,{ { 0,0,2,2,0,0,0,0, } }, { { 4,3,4,4,0, } }, { { 1,1,0, } },  },
+    { 50350000,1,10,{ { 1,0,2,2,0,0,1,0, } }, { { 4,3,4,4,0, } }, { { 1,1,0, } },  },
+    { 50350000,1,12,{ { 2,0,2,2,0,0,2,0, } }, { { 4,3,3,3,0, } }, { { 1,1,0, } },  },
+    { 50350000,1,16,{ { 3,0,1,1,0,0,3,0, } }, { { 4,3,4,4,0, } }, { { 2,2,0, } },  },
+    { 50350000,2,8,{ { 3,0,1,1,0,0,0,0, } }, { { 4,3,4,4,0, } }, { { 2,2,0, } },  },
+    { 50350000,2,10,{ { 1,1,2,1,0,0,1,0, } }, { { 4,3,4,4,0, } }, { { 2,1,0, } },  },
+    { 50350000,2,12,{ { 2,1,2,1,0,0,2,0, } }, { { 4,3,3,3,0, } }, { { 2,1,0, } },  },
+    { 50350000,2,16,{ { 3,1,1,0,0,0,3,0, } }, { { 4,3,4,4,0, } }, { { 3,2,0, } },  },
+    { 54000000,1,8,{ { 0,0,2,2,0,0,0,0, } }, { { 4,3,4,4,0, } }, { { 1,1,0, } },  },
+    { 54000000,1,10,{ { 1,0,2,2,0,0,1,0, } }, { { 4,3,4,4,0, } }, { { 1,1,0, } },  },
+    { 54000000,1,12,{ { 2,0,2,2,0,0,2,0, } }, { { 4,3,3,3,0, } }, { { 1,1,0, } },  },
+    { 54000000,1,16,{ { 3,0,1,1,0,0,3,0, } }, { { 4,3,4,4,0, } }, { { 2,2,0, } },  },
+    { 54000000,2,8,{ { 3,0,1,1,0,0,0,0, } }, { { 4,3,4,4,0, } }, { { 2,2,0, } },  },
+    { 54000000,2,10,{ { 1,1,2,1,0,0,1,0, } }, { { 4,3,4,4,0, } }, { { 2,1,0, } },  },
+    { 54000000,2,12,{ { 2,1,2,1,0,0,2,0, } }, { { 4,3,3,3,0, } }, { { 2,1,0, } },  },
+    { 54000000,2,16,{ { 3,1,1,0,0,0,3,0, } }, { { 4,3,4,4,0, } }, { { 3,2,0, } },  },
+    { 58400000,1,8,{ { 0,0,2,2,0,0,0,0, } }, { { 4,3,4,4,0, } }, { { 1,1,0, } },  },
+    { 58400000,1,10,{ { 1,0,2,2,0,0,1,0, } }, { { 4,3,3,3,0, } }, { { 1,1,0, } },  },
+    { 58400000,1,12,{ { 2,0,2,2,0,0,2,0, } }, { { 4,3,3,3,0, } }, { { 1,1,0, } },  },
+    { 58400000,1,16,{ { 3,0,1,1,0,0,3,0, } }, { { 4,3,4,4,0, } }, { { 2,2,0, } },  },
+    { 72000000,1,8,{ { 0,0,2,2,0,0,0,0, } }, { { 4,3,3,3,0, } }, { { 1,1,0, } },  },
+    { 72000000,1,10,{ { 1,0,2,2,0,0,1,0, } }, { { 4,3,3,3,0, } }, { { 1,1,0, } },  },
+    { 72000000,1,12,{ { 2,0,1,1,0,0,2,0, } }, { { 4,3,4,4,0, } }, { { 2,2,0, } },  },
+    { 72000000,1,16,{ { 3,0,1,1,0,0,3,0, } }, { { 4,3,3,3,0, } }, { { 2,2,0, } },  },
+    { 74250000,1,8,{ { 0,0,2,2,0,0,0,0, } }, { { 4,3,3,3,0, } }, { { 1,1,0, } },  },
+    { 74250000,1,10,{ { 1,0,1,1,0,0,1,0, } }, { { 4,3,5,5,0, } }, { { 2,2,0, } },  },
+    { 74250000,1,12,{ { 2,0,1,1,0,0,2,0, } }, { { 4,3,4,4,0, } }, { { 2,2,0, } },  },
+    { 74250000,1,16,{ { 3,0,1,1,0,0,3,0, } }, { { 4,3,3,3,0, } }, { { 2,2,0, } },  },
+    { 108000000,1,8,{ { 0,0,1,1,0,0,0,0, } }, { { 4,3,4,4,0, } }, { { 2,2,0, } },  },
+    { 108000000,1,10,{ { 1,0,1,1,0,0,1,0, } }, { { 4,3,4,4,0, } }, { { 2,2,0, } },  },
+    { 108000000,1,12,{ { 2,0,1,1,0,0,2,0, } }, { { 4,3,3,3,0, } }, { { 2,2,0, } },  },
+    { 108000000,1,16,{ { 3,0,0,0,0,0,3,0, } }, { { 4,3,4,4,0, } }, { { 3,3,0, } },  },
+    { 118800000,1,8,{ { 0,0,1,1,0,0,0,0, } }, { { 4,3,4,4,0, } }, { { 2,2,0, } },  },
+    { 118800000,1,10,{ { 1,0,1,1,0,0,1,0, } }, { { 4,3,4,4,0, } }, { { 2,2,0, } },  },
+    { 118800000,1,12,{ { 2,0,1,1,0,0,2,0, } }, { { 4,3,3,3,0, } }, { { 2,2,0, } },  },
+    { 118800000,1,16,{ { 3,0,0,0,0,0,3,0, } }, { { 4,3,4,4,0, } }, { { 3,3,0, } },  },
+    { 144000000,1,8,{ { 0,0,1,1,0,0,0,0, } }, { { 4,3,3,3,0, } }, { { 2,2,0, } },  },
+    { 144000000,1,10,{ { 1,0,0,0,0,0,1,0, } }, { { 4,3,5,5,0, } }, { { 3,3,0, } },  },
+    { 144000000,1,12,{ { 2,0,0,0,0,0,2,0, } }, { { 4,3,4,4,0, } }, { { 3,3,0, } },  },
+    { 144000000,1,16,{ { 3,0,0,0,0,0,3,0, } }, { { 4,3,3,3,0, } }, { { 3,3,0, } },  },
+    { 148500000,1,8,{ { 0,0,1,1,0,0,0,0, } }, { { 4,3,3,3,0, } }, { { 2,2,0, } },  },
+    { 148500000,1,10,{ { 1,0,0,0,0,0,1,0, } }, { { 4,3,5,5,0, } }, { { 3,3,0, } },  },
+    { 148500000,1,12,{ { 2,0,0,0,0,0,2,0, } }, { { 4,3,4,4,0, } }, { { 3,3,0, } },  },
+    { 148500000,1,16,{ { 3,0,0,0,0,0,3,0, } }, { { 4,3,3,3,0, } }, { { 3,3,0, } },  },
+    { 216000000,1,8,{ { 0,0,1,1,0,0,0,0, } }, { { 4,3,3,3,0, } }, { { 2,2,0, } },  },
+    { 216000000,1,10,{ { 1,0,0,0,0,0,1,0, } }, { { 4,3,5,5,0, } }, { { 3,3,0, } },  },
+    { 216000000,1,12,{ { 2,0,0,0,0,0,2,0, } }, { { 4,3,4,4,0, } }, { { 3,3,0, } },  },
+    // Fallback
+    { 65000000,1,8,{ { 0,0,1,1,0,0,0,0, } },{ { 4,3,3,3,0, } },{ { 2,2,0, } }, },
+};
+
+BOOLEAN HDMIPhyPollI2CDone (
+    DISPLAY_INTERFACE_CONTEXT* HdmiDisplayContextPtr,
+    UINT32 TimeOut
+    )
+{
+    BOOLEAN waitResult = FALSE;
+    HDMI_IH_I2CMPHY_STAT0_REG I2cMPhyStat0Reg;
+
+    do {
+        I2cMPhyStat0Reg.Reg = HDMIRead8(HDMI_IH_I2CMPHY_STAT0);
+        if (I2cMPhyStat0Reg.i2cmphydone)
+        {
+            waitResult = TRUE;
+            break;
+        }
+
+        if (--TimeOut == 0)
+        {
+            break;
+        }
+
+        OS_SLEEP(1);
+    } while (I2cMPhyStat0Reg.i2cmphydone == 0);
+
+#if DBG
+    if ((TimeOut == 0) || (I2cMPhyStat0Reg.i2cmphyerror == 1)) {
+        OS_ERROR(
+            "HDMI I2C failed value %x time out %d\n",
+            I2cMPhyStat0Reg.Reg,
+            TimeOut));
+    }
+#endif
+
+    return waitResult;
+}
+
+BOOLEAN HDMIPhyI2cRead (
+    DISPLAY_INTERFACE_CONTEXT* HdmiDisplayContextPtr,
+    UINT8 Addr,
+    UINT16* DataPtr
+    )
+{
+    BOOLEAN readStatus;
+    UINT16 data0, data1;
+    HDMI_IH_I2CMPHY_STAT0_REG I2cmPhyStat0Reg = { { 1, 1, 0 } };
+
+    HDMIWrite8(HDMI_IH_I2CMPHY_STAT0, I2cmPhyStat0Reg.Reg);
+    HDMIWrite8(HDMI_PHY_I2CM_ADDRESS_ADDR, Addr);
+
+    {
+        HDMI_PHY_I2CM_OPERATION_ADDR_REG I2cmOperationReg;
+
+        I2cmOperationReg.Reg = HDMIRead8(HDMI_PHY_I2CM_OPERATION_ADDR);
+        I2cmOperationReg.read = 1;
+        HDMIWrite8(HDMI_PHY_I2CM_OPERATION_ADDR, I2cmOperationReg.Reg);
+    }
+
+    readStatus = HDMIPhyPollI2CDone(HdmiDisplayContextPtr, 1000);
+    if (!readStatus) {
+        OS_ERROR("Fail to read I2c HDMI Phy\n");
+        goto Exit;
+    }
+
+    data0 = HDMIRead8(HDMI_PHY_I2CM_DATAI_0_ADDR);
+    data1 = HDMIRead8(HDMI_PHY_I2CM_DATAI_1_ADDR);
+
+    *DataPtr = data0 | (data1 << 8);
+
+Exit:
+    return readStatus;
+}
+
+BOOLEAN HDMIPhyI2cWrite (
+    DISPLAY_INTERFACE_CONTEXT* HdmiDisplayContextPtr,
+    UINT8 Addr,
+    UINT16 Data
+    )
+{
+    UINT8 data1 = (Data >> 8);
+    UINT8 data0 = (Data & 0x00FF);
+    HDMI_IH_I2CMPHY_STAT0_REG I2cmPhyStat0Reg = { { 1, 1, 0 } };
+
+    HDMIWrite8(HDMI_IH_I2CMPHY_STAT0, I2cmPhyStat0Reg.Reg);
+    HDMIWrite8(HDMI_PHY_I2CM_ADDRESS_ADDR, Addr);
+    HDMIWrite8(HDMI_PHY_I2CM_DATAO_0_ADDR, data0);
+    HDMIWrite8(HDMI_PHY_I2CM_DATAO_1_ADDR, data1);
+
+    {
+        HDMI_PHY_I2CM_OPERATION_ADDR_REG I2cmOperationReg = { { 0, 0, 0, 0 } };
+
+        I2cmOperationReg.write = 1;
+        HDMIWrite8(HDMI_PHY_I2CM_OPERATION_ADDR, I2cmOperationReg.Reg);
+    }
+
+    return HDMIPhyPollI2CDone(HdmiDisplayContextPtr, 1000);
+}
+
+BOOLEAN GetGenericConfigSetting (
+    DISPLAY_TIMING* DisplayTimingPtr,
+    PLL_MPLL_CONFIG** ConfigGenericSettingPPtr
+    )
+{
+    BOOLEAN foundConfig = FALSE;
+    UINT32 settingIndex;
+
+    for (settingIndex = 0;
+         settingIndex < ARRAYSIZE(PllMpllGenericConfigSetting);
+        ++settingIndex) {
+
+        if ((DisplayTimingPtr->PixelClock ==
+                PllMpllGenericConfigSetting[settingIndex].PixelClock) &&
+            (DisplayTimingPtr->PixelRepetition ==
+                PllMpllGenericConfigSetting[settingIndex].PixelRepetition) &&
+            (GetColorDepth(DisplayTimingPtr->PixelFormat) ==
+                PllMpllGenericConfigSetting[settingIndex].ColorDepth)) {
+
+            foundConfig = TRUE;
+            *ConfigGenericSettingPPtr = &PllMpllGenericConfigSetting[settingIndex];
+            break;
+        }
+    }
+
+    // Use the fallback value the last index if no configuration is found
+    if (foundConfig == FALSE) {
+        *ConfigGenericSettingPPtr =
+            &PllMpllGenericConfigSetting[ARRAYSIZE(PllMpllGenericConfigSetting)];
+        foundConfig = TRUE;
+    }
+
+    return foundConfig;
+}
+
+OS_STATUS InitHDMI (
+    DISPLAY_CONTEXT* DisplayContextPtr
+    )
+{
+    DISPLAY_INTERFACE_CONTEXT* HdmiDisplayContextPtr =
+        &DisplayContextPtr->DIContext[HDMI_DISPLAY];
+    OS_STATUS status = 0;
+
+    OS_ZERO_MEM(HdmiDisplayContextPtr, sizeof(*HdmiDisplayContextPtr));
+
+    HdmiDisplayContextPtr->MmioBasePtr = (VOID*)OS_MMIO_MAP(HDMI_BASE);
+    if (HdmiDisplayContextPtr->MmioBasePtr == NULL) {
+        OS_ERROR("Fail to map HDMI register\n");
+        goto Exit;
+    }
+
+    // Setup HDMI DDC muxing
+    OS_WRITE32(IOMUXC_SW_MUX_CTL_PAD_KEY_COL3, 0x00000012);
+    OS_WRITE32(IOMUXC_SW_MUX_CTL_PAD_KEY_ROW3, 0x00000012);
+    OS_WRITE32(IOMUXC_HDMI_II2C_CLKIN_SELECT_INPUT, 0x00000001);
+    OS_WRITE32(IOMUXC_HDMI_II2C_DATAIN_SELECT_INPUT, 0x00000001);
+
+    SetHDMIPower(HdmiDisplayContextPtr, TRUE);
+
+    // Mask all HDMI PHY interrupt
+    HDMIWrite8(HDMI_PHY_MASK0, 0xFF);
+
+    status = ReadEDID(
+        DisplayContextPtr,
+        HDMI_DISPLAY,
+        HdmiDisplayContextPtr->EdidData,
+        &HdmiDisplayContextPtr->EdidDataSize);
+    if (status != OS_STATUS_SUCCESS) {
+        OS_WARNING("Fail to read HDMI EDID data\n");
+        status = OS_STATUS_SUCCESS;
+    }
+
+    status = GetPreferedTiming(
+        HdmiDisplayContextPtr->EdidData,
+        HdmiDisplayContextPtr->EdidDataSize,
+        &HdmiDisplayContextPtr->PreferedTiming);
+    if (status != OS_STATUS_SUCCESS) {
+        OS_ERROR("Fail to retrieve HDMI prefered timing\n");
+        goto Exit;
+    }
+
+    if ((HdmiDisplayContextPtr->PreferedTiming.HActive == 1920) &&
+        (HdmiDisplayContextPtr->PreferedTiming.VActive == 1080)) {
+        HdmiDisplayContextPtr->PreferedTiming.HBlank -= 6;
+    }
+
+Exit:
+    return status;
+}
+
+OS_STATUS SetHDMIPower (
+    DISPLAY_INTERFACE_CONTEXT* HdmiDisplayContextPtr,
+    BOOLEAN PowerState
+    )
+{
+    HDMI_PHY_CONF0_REG CurrentHDMIPhyConf0;
+
+    CurrentHDMIPhyConf0.Reg = HDMIRead8(HDMI_PHY_CONF0);
+    if (PowerState) {
+        // Setup PHY
+        CurrentHDMIPhyConf0.PDZ = 1;
+        CurrentHDMIPhyConf0.ENTMDS = 1;
+        CurrentHDMIPhyConf0.gen2_pddq = 1;
+        CurrentHDMIPhyConf0.gen2_txpwron = 1;
+        CurrentHDMIPhyConf0.seldataenpol = 1;
+        CurrentHDMIPhyConf0.seldipif = 0;
+    } else {
+        // Just power down PHY for shutdown
+        CurrentHDMIPhyConf0.PDZ = 0;
+    }
+
+    HDMIWrite8(HDMI_PHY_CONF0, CurrentHDMIPhyConf0.Reg);
+
+    OS_SLEEP(3);
+
+    return OS_STATUS_SUCCESS;
+}
+
+OS_STATUS SetHDMIPhy (
+    DISPLAY_INTERFACE_CONTEXT* HdmiDisplayContextPtr,
+    DISPLAY_TIMING* Timings
+    )
+{
+    OS_STATUS status;
+    HDMI_PHY_CONF0_REG CurrentHDMIPhyConf0;
+    PLL_MPLL_CONFIG*  pllMpllConfig;
+
+    // Disable Audio
+    {
+        HDMI_FC_AUDSCONF_REG fcAudsConf;
+
+        fcAudsConf.Reg = HDMIRead8(HDMI_FC_AUDSCONF);
+        fcAudsConf.aud_packet_layout = 0;
+        HDMIWrite8(HDMI_FC_AUDSCONF, fcAudsConf.Reg);
+    }
+
+    // Minimum PCLK period / frequency (pixel repetition) : 74 ns / 13.5 MHz
+    // Minimum PCLK period / frequency (no pixel repetition) : 39.7 ns / 24.175 MHz
+    if(Timings->PixelClock < 13500000) {
+        OS_ERROR("Unsupported pixel clock %d\n", Timings->PixelClock);
+        status = OS_STATUS_INVALID_PARAM;
+        goto Exit;
+    }
+
+    if (GetGenericConfigSetting(Timings, &pllMpllConfig) == FALSE) {
+        OS_ERROR("No compatible generic config found\n");
+        status = OS_STATUS_UNSUPPORTED;
+        goto Exit;
+    }
+
+    // Color Space Converter : Not used in UEFI
+    {
+        HDMI_MC_CLKDIS_REG McClkdis;
+
+        McClkdis.Reg = HDMIRead8(HDMI_MC_CLKDIS);
+
+        // Disable CEC, color converter, audio & pixel repitition
+        McClkdis.cecclk_disable = 1;
+        McClkdis.cscclk_disable = 1;
+        McClkdis.audclk_disable = 1;
+        McClkdis.prepclk_disable = 1;
+        McClkdis.hdcpclk_disable = 1;
+        McClkdis.tmdsclk_disable = 0;
+        McClkdis.pixelclk_disable = 0;
+
+        HDMIWrite8(HDMI_MC_CLKDIS, McClkdis.Reg);
+    }
+
+    // Power down the PHY
+    // To set the HDMI_PHY in Power-down mode, set the TX_PWRON signal to 1'b0
+    // and the PDDQ signal to 1'b1. To power up the HDMI 3D Tx PHY and place it
+    // in Active mode, set TX_PWRON to 1'b1 and PDDQ to 1'b0. Any configuration
+    // programmed on the HDMI_PHY must be done in Power-down mode.
+    CurrentHDMIPhyConf0.Reg = HDMIRead8(HDMI_PHY_CONF0);
+    CurrentHDMIPhyConf0.gen2_txpwron = 0;
+    CurrentHDMIPhyConf0.gen2_pddq = 1;
+    HDMIWrite8(HDMI_PHY_CONF0, CurrentHDMIPhyConf0.Reg);
+
+    // Let's reset the PHY to a well defined state based on spec.
+    // The PHY_RESET signal is used to place the digital section of the IP in
+    // a well - defined state
+    {
+        HDMI_MC_PHYRSTZ_REG phyRstzReg;
+        HDMI_MC_HEACPHY_RST_REG heacphyRst;
+
+        phyRstzReg.Reg = HDMIRead8(HDMI_MC_PHYRSTZ);
+        heacphyRst.Reg = HDMIRead8(HDMI_MC_HEACPHY_RST);
+
+        phyRstzReg.phyrstz = 1;
+        HDMIWrite8(HDMI_MC_PHYRSTZ, phyRstzReg.Reg);
+        phyRstzReg.phyrstz = 0;
+        OS_SLEEP(10);
+        HDMIWrite8(HDMI_MC_PHYRSTZ, phyRstzReg.Reg);
+
+        // Even though we dont currently support this, reset the ethernet audio
+        // control too
+        heacphyRst.heacphyrst = 1;
+        HDMIWrite8(HDMI_MC_HEACPHY_RST, heacphyRst.Reg);
+    }
+
+    // Program clock
+    // PLL / MPLL Operation
+    // The PLL / MPLL can be configured in Coherent mode or Non - Coherent mode (default).In
+    //  Coherent mode, the TMDS clock is the MPLL feedback clock, which is coherent with the
+    //  MPLL's high-speed output clock, because both clocks are shaped by the MPLL response.
+    //  In Non - Coherent mode, the TMDS clock is the MPLL reference clock, which is not
+    //  coherent with the MPLL's high-speed output clock.
+    if (HDMIPhyI2cWrite(
+            HdmiDisplayContextPtr,
+            HDMI_PHY_CPCE_CTRL,
+            pllMpllConfig->HdmiPhyCpceCtrl.Reg) == 0) {
+        OS_ERROR("Fail to write to HDMI_PHY_CPCE_CTRL %x\n",
+            pllMpllConfig->HdmiPhyCpceCtrl.Reg);
+        status = OS_STATUS_DEVICE_ERROR;
+        goto Exit;
+    }
+
+    if (HDMIPhyI2cWrite(
+            HdmiDisplayContextPtr,
+            HDMI_PHY_CURRCTRL,
+            pllMpllConfig->HdmiPhyCurrctrl.Reg) == 0) {
+        OS_ERROR("Fail to write to HDMI_PHY_CURRCTRL\n");
+        status = OS_STATUS_DEVICE_ERROR;
+        goto Exit;
+    };
+
+    if (HDMIPhyI2cWrite(
+            HdmiDisplayContextPtr,
+            HDMI_PHY_GMPCTRL,
+            pllMpllConfig->HdmiPhyGmpctrl.Reg) == 0) {
+        OS_ERROR("Fail to write to HDMI_PHY_GMPCTRL\n");
+        status = OS_STATUS_DEVICE_ERROR;
+        goto Exit;
+    }
+
+    // Maintaining the order of phy register writes
+    if (HDMIPhyI2cWrite(
+            HdmiDisplayContextPtr,
+            HDMI_PHY_PLLPHBYCTRL,
+            0x0000) == 0) {
+        OS_ERROR("Fail to write to HDMI_PHY_PLLPHBYCTRL\n");
+        status = OS_STATUS_DEVICE_ERROR;
+        goto Exit;
+    }
+
+    // Coherent  mode
+    if (HDMIPhyI2cWrite(
+            HdmiDisplayContextPtr,
+            HDMI_PHY_MSM_CTRL,
+            0x0006) == 0) {
+        OS_ERROR("Fail to write to HDMI_PHY_MSM_CTRL\n");
+        status = OS_STATUS_DEVICE_ERROR;
+        goto Exit;
+    }
+
+    // Resistance value 133.33 ohm
+    if (HDMIPhyI2cWrite(
+            HdmiDisplayContextPtr,
+            HDMI_PHY_TXTERM,
+            0x0005) == 0) {
+        OS_ERROR("Fail to write to HDMI_PHY_TXTERM\n");
+        status = OS_STATUS_DEVICE_ERROR;
+        goto Exit;
+    }
+
+    // Enable clock symbol
+    if (HDMIPhyI2cWrite(
+            HdmiDisplayContextPtr,
+            HDMI_PHY_CKSYMTXCTRL,
+            0x8009) == 0) {
+        OS_ERROR("Fail to write to HDMI_PHY_CKSYMTXCTRL\n");
+        status = OS_STATUS_DEVICE_ERROR;
+        goto Exit;
+    }
+
+    if (HDMIPhyI2cWrite(
+            HdmiDisplayContextPtr,
+            HDMI_PHY_VLEVCTRL,
+            0x0210) == 0) {
+        OS_ERROR("Fail to write to HDMI_PHY_VLEVCTRL\n");
+        status = OS_STATUS_DEVICE_ERROR;
+        goto Exit;
+    }
+
+    // Enable override
+    if (HDMIPhyI2cWrite(
+        HdmiDisplayContextPtr,
+            HDMI_PHY_CKCALCTRL,
+            0x8000) == 0) {
+        OS_ERROR("Fail to write to HDMI_PHY_CKCALCTRL\n");
+        status = OS_STATUS_DEVICE_ERROR;
+        goto Exit;
+    }
+
+    CurrentHDMIPhyConf0.gen2_txpwron = 1;
+    CurrentHDMIPhyConf0.gen2_pddq = 0;
+    HDMIWrite8(HDMI_PHY_CONF0, CurrentHDMIPhyConf0.Reg);
+
+    {
+        HDMI_PHY_STAT0_REG phyStat0;
+        UINT32 poolTimeOut = 5;
+
+        status = OS_STATUS_DEVICE_ERROR;
+
+        do {
+            phyStat0.Reg = HDMIRead8(HDMI_PHY_STAT0);
+
+            if (!phyStat0.TX_PHY_LOCK) {
+                status = OS_STATUS_SUCCESS;
+                break;
+            }
+
+            OS_SLEEP(1000);
+            --poolTimeOut;
+        } while (poolTimeOut);
+
+        if (poolTimeOut == 0) {
+            OS_ERROR("TX PHY remain unlock\n");
+        }
+    }
+
+Exit:
+    return status;
+}
+
+OS_STATUS SetHDMIDisplay (
+    DISPLAY_INTERFACE_CONTEXT* HdmiDisplayContextPtr,
+    DISPLAY_TIMING* Timings
+    )
+{
+    OS_STATUS status;
+
+    status = SetHDMIPhy(HdmiDisplayContextPtr, Timings);
+    if (status != OS_STATUS_SUCCESS) {
+        OS_ERROR("SetHDMIPhy failed\n");
+        goto Exit;
+    }
+
+Exit:
+    return status;
+}
+
+VOID SetDDCSpeed (
+    DISPLAY_INTERFACE_CONTEXT* HdmiDisplayContextPtr,
+    DDC_MODE mode
+    )
+{
+    HDMIWrite8(HDMI_I2CM_DIV, mode);
+}
+
+OS_STATUS HDMIDDCRead (
+    DISPLAY_INTERFACE_CONTEXT* HdmiDisplayContextPtr,
+    UINT8 SlaveAddress,
+    UINT8 RegisterAddress,
+    UINT32 ReadSize,
+    DDC_MODE DDCMode,
+    UINT8* DataReadPtr
+    )
+{
+    OS_STATUS status;
+    UINT32 AddrCount;
+    UINT8* CurrentDataReadPtr = DataReadPtr;
+
+    // Setup EDID transaction and loop through all byte request
+    SetDDCSpeed(HdmiDisplayContextPtr, DDCMode);
+
+    HDMIWrite8(HDMI_IH_I2CM_STAT0, I2C_MASTER_ERROR | I2C_MASTER_DONE);
+    HDMIWrite8(HDMI_I2CM_SLAVE, SlaveAddress);
+
+    for (AddrCount = 0; AddrCount < ReadSize; ++AddrCount) {
+        UINT32 i2CTimeOut = 1000;
+
+        HDMIWrite8(HDMI_I2CM_ADDRESS, (UINT8)( RegisterAddress + AddrCount));
+        HDMIWrite8(HDMI_I2CM_SEGADDR, 0x00);
+        HDMIWrite8(HDMI_I2CM_OPERATION, DDC_READ_OPERATION);
+
+        // Poll for completion
+        UINT8 i2CMIntStatus = HDMIRead8(HDMI_IH_I2CM_STAT0);
+
+        while ((i2CMIntStatus == 0) && (i2CTimeOut)) {
+            i2CMIntStatus = HDMIRead8(HDMI_IH_I2CM_STAT0);
+            --i2CTimeOut;
+        }
+
+        if (i2CTimeOut == 0) {
+            status = OS_STATUS_DEVICE_ERROR;
+            OS_ERROR("Timeout waiting for interrupt 0x%02x\n", i2CMIntStatus);
+            goto Exit;
+        }
+
+        if (i2CMIntStatus & I2C_MASTER_ERROR) {
+            status = OS_STATUS_DEVICE_ERROR;
+            OS_ERROR("Failed to read with DDC 0x%02x\n", i2CMIntStatus);
+            goto Exit;
+        } else if (i2CMIntStatus & I2C_MASTER_DONE) {
+            *CurrentDataReadPtr = HDMIRead8(HDMI_I2CM_DATAI);
+            CurrentDataReadPtr++;
+        } else {
+            status = OS_STATUS_DEVICE_ERROR;
+            OS_ERROR("Failed to read DDC unknown status 0x%02x\n", i2CMIntStatus);
+            goto Exit;
+        }
+
+        HDMIWrite8(HDMI_IH_I2CM_STAT0, 0xFF);
+    }
+
+    status = OS_STATUS_SUCCESS;
+
+Exit:
+    return status;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/Hdmi.h b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Hdmi.h
new file mode 100644
index 000000000000..f186f57105f7
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Hdmi.h
@@ -0,0 +1,537 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _HDMI_H_
+#define _HDMI_H_
+
+#define HDMIRead8(a) \
+            OS_READ8((UINT32)HdmiDisplayContextPtr->MmioBasePtr + a)
+
+#define HDMIWrite8(a, b) \
+            OS_WRITE8((UINT32)HdmiDisplayContextPtr->MmioBasePtr + a, b)
+
+
+// HDMI Register Base Address
+#define HDMI_BASE 0x00120000
+
+// Interrupt Register Offset
+#define HDMI_IH_FC_STAT0                0x0100
+#define HDMI_IH_FC_STAT1                0x0101
+#define HDMI_IH_FC_STAT2                0x0102
+#define HDMI_IH_AS_STAT0                0x0103
+#define HDMI_IH_PHY_STAT0               0x0104
+#define HDMI_IH_I2CM_STAT0              0x0105
+#define HDMI_IH_CEC_STAT0               0x0106
+#define HDMI_IH_VP_STAT0                0x0107
+#define HDMI_IH_I2CMPHY_STAT0           0x0108
+#define HDMI_IH_AHBDMAAUD_STAT0         0x0180
+#define HDMI_IH_MUTE_FC_STAT1           0x0181
+#define HDMI_IH_MUTE_FC_STAT2           0x0182
+#define HDMI_IH_MUTE_AS_STAT0           0x0183
+#define HDMI_IH_MUTE_PHY_STAT0          0x0184
+#define HDMI_IH_MUTE_I2CM_STAT0         0x0185
+#define HDMI_IH_MUTE_CEC_STAT0          0x0186
+#define HDMI_IH_MUTE_VP_STAT0           0x0187
+#define HDMI_IH_MUTE_I2CMPHY_STAT0      0x0188
+#define HDMI_IH_MUTE_AHBDMAAUD_STAT0    0x0189
+#define HDMI_IH_MUTE                    0x01FF
+
+#define HDMI_FC_INVIDCONF               0x1000
+#define HDMI_FC_INHACTV0                0x1001
+#define HDMI_FC_INHACTV1                0x1002
+#define HDMI_FC_INHBLANK0               0x1003
+#define HDMI_FC_INHBLANK1               0x1004
+#define HDMI_FC_INVACTV0                0x1005
+#define HDMI_FC_INVACTV1                0x1006
+#define HDMI_FC_INVBLANK                0x1007
+#define HDMI_FC_HSYNCINDELAY0           0x1008
+#define HDMI_FC_HSYNCINDELAY1           0x1009
+#define HDMI_FC_HSYNCINWIDTH0           0x100A
+#define HDMI_FC_HSYNCINWIDTH1           0x100B
+#define HDMI_FC_VSYNCINDELAY            0x100C
+#define HDMI_FC_VSYNCINWIDTH            0x100D
+#define HDMI_FC_INFREQ0                 0x100E
+#define HDMI_FC_INFREQ1                 0x100F
+#define HDMI_FC_INFREQ2                 0x1010
+#define HDMI_FC_CTRLDUR                 0x1011
+#define HDMI_FC_EXCTRLDUR               0x1012
+#define HDMI_FC_EXCTRLSPAC              0x1013
+#define HDMI_FC_CH0PREAM                0x1014
+#define HDMI_FC_CH1PREAM                0x1015
+#define HDMI_FC_CH2PREAM                0x1016
+#define HDMI_FC_AVICONF3                0x1017
+#define HDMI_FC_GCP                     0x1018
+#define HDMI_FC_AVICONF0                0x1019
+#define HDMI_FC_AVICONF1                0x101A
+#define HDMI_FC_AVICONF2                0x101B
+#define HDMI_FC_AVIVID                  0x101C
+#define HDMI_FC_AVIETB0                 0x101D
+#define HDMI_FC_AVIETB1                 0x101E
+#define HDMI_FC_AVISBB0                 0x101F
+#define HDMI_FC_AVISBB1                 0x1020
+#define HDMI_FC_AVIELB0                 0x1021
+#define HDMI_FC_AVIELB1                 0x1022
+#define HDMI_FC_AVISRB0                 0x1023
+#define HDMI_FC_AVISRB1                 0x1024
+#define HDMI_FC_AUDICONF0               0x1025
+#define HDMI_FC_AUDICONF1               0x1026
+#define HDMI_FC_AUDICONF2               0x1027
+#define HDMI_FC_AUDICONF3               0x1028
+#define HDMI_FC_VSDIEEEID0              0x1029
+#define HDMI_FC_VSDSIZE                 0x102A
+#define HDMI_FC_VSDIEEEID1              0x1030
+#define HDMI_FC_VSDIEEEID2              0x1031
+#define HDMI_FC_VSDPAYLOAD0             0x1032
+#define HDMI_FC_VSDPAYLOAD1             0x1033
+#define HDMI_FC_VSDPAYLOAD2             0x1034
+#define HDMI_FC_VSDPAYLOAD3             0x1035
+#define HDMI_FC_VSDPAYLOAD4             0x1036
+#define HDMI_FC_VSDPAYLOAD5             0x1037
+#define HDMI_FC_VSDPAYLOAD6             0x1038
+#define HDMI_FC_VSDPAYLOAD7             0x1039
+#define HDMI_FC_VSDPAYLOAD8             0x103A
+#define HDMI_FC_VSDPAYLOAD9             0x103B
+#define HDMI_FC_VSDPAYLOAD10            0x103C
+#define HDMI_FC_VSDPAYLOAD11            0x103D
+#define HDMI_FC_VSDPAYLOAD12            0x103E
+#define HDMI_FC_VSDPAYLOAD13            0x103F
+#define HDMI_FC_VSDPAYLOAD14            0x1040
+#define HDMI_FC_VSDPAYLOAD15            0x1041
+#define HDMI_FC_VSDPAYLOAD16            0x1042
+#define HDMI_FC_VSDPAYLOAD17            0x1043
+#define HDMI_FC_VSDPAYLOAD18            0x1044
+#define HDMI_FC_VSDPAYLOAD19            0x1045
+#define HDMI_FC_VSDPAYLOAD20            0x1046
+#define HDMI_FC_VSDPAYLOAD21            0x1047
+#define HDMI_FC_VSDPAYLOAD22            0x1048
+#define HDMI_FC_VSDPAYLOAD23            0x1049
+#define HDMI_FC_SPDVENDORNAME0          0x104A
+#define HDMI_FC_SPDVENDORNAME1          0x104B
+#define HDMI_FC_SPDVENDORNAME2          0x104C
+#define HDMI_FC_SPDVENDORNAME3          0x104D
+#define HDMI_FC_SPDVENDORNAME4          0x104E
+#define HDMI_FC_SPDVENDORNAME5          0x104F
+#define HDMI_FC_SPDVENDORNAME6          0x1050
+#define HDMI_FC_SPDVENDORNAME7          0x1051
+#define HDMI_FC_SDPPRODUCTNAME0         0x1052
+#define HDMI_FC_SDPPRODUCTNAME1         0x1053
+#define HDMI_FC_SDPPRODUCTNAME2         0x1054
+#define HDMI_FC_SDPPRODUCTNAME3         0x1055
+#define HDMI_FC_SDPPRODUCTNAME4         0x1056
+#define HDMI_FC_SDPPRODUCTNAME5         0x1057
+#define HDMI_FC_SDPPRODUCTNAME6         0x1058
+#define HDMI_FC_SDPPRODUCTNAME7         0x1059
+#define HDMI_FC_SDPPRODUCTNAME8         0x105A
+#define HDMI_FC_SDPPRODUCTNAME9         0x105B
+#define HDMI_FC_SDPPRODUCTNAME10        0x105C
+#define HDMI_FC_SDPPRODUCTNAME11        0x105D
+#define HDMI_FC_SDPPRODUCTNAME12        0x105E
+#define HDMI_FC_SDPPRODUCTNAME13        0x105F
+#define HDMI_FC_SDPPRODUCTNAME14        0x1060
+#define HDMI_FC_SPDPRODUCTNAME15        0x1061
+#define HDMI_FC_SPDDEVICEINF            0x1062
+#define HDMI_FC_AUDSCONF                0x1063
+#define HDMI_FC_AUDSSTAT                0x1064
+#define HDMI_FC_AUDSV                   0x1065
+#define HDMI_FC_AUDSU                   0x1066
+#define HDMI_FC_AUDSCHNLS0              0x1067
+#define HDMI_FC_AUDSCHNLS1              0x1068
+#define HDMI_FC_AUDSCHNLS2              0x1069
+#define HDMI_FC_AUDSCHNLS3              0x106A
+#define HDMI_FC_AUDSCHNLS4              0x106B
+#define HDMI_FC_AUDSCHNLS5              0x106C
+#define HDMI_FC_AUDSCHNLS6              0x106D
+#define HDMI_FC_AUDSCHNLS7              0x106E
+#define HDMI_FC_AUDSCHNLS8              0x106F
+#define HDMI_FC_DATACH0FILL             0x1070
+#define HDMI_FC_DATACH1FILL             0x1071
+#define HDMI_FC_DATACH2FILL             0x1072
+#define HDMI_FC_CTRLQHIGH               0x1073
+#define HDMI_FC_CTRLQLOW                0x1074
+#define HDMI_FC_ACP0                    0x1075
+#define HDMI_FC_ACP28                   0x1076
+#define HDMI_FC_ACP27                   0x1077
+#define HDMI_FC_ACP26                   0x1078
+#define HDMI_FC_ACP25                   0x1079
+#define HDMI_FC_ACP24                   0x107A
+#define HDMI_FC_ACP23                   0x107B
+#define HDMI_FC_ACP22                   0x107C
+#define HDMI_FC_ACP21                   0x107D
+#define HDMI_FC_ACP20                   0x107E
+#define HDMI_FC_ACP19                   0x107F
+#define HDMI_FC_ACP18                   0x1080
+#define HDMI_FC_ACP17                   0x1081
+#define HDMI_FC_ACP16                   0x1082
+#define HDMI_FC_ACP15                   0x1083
+#define HDMI_FC_ACP14                   0x1084
+#define HDMI_FC_ACP13                   0x1085
+#define HDMI_FC_ACP12                   0x1086
+#define HDMI_FC_ACP11                   0x1087
+#define HDMI_FC_ACP10                   0x1088
+#define HDMI_FC_ACP9                    0x1089
+#define HDMI_FC_ACP8                    0x108A
+#define HDMI_FC_ACP7                    0x108B
+#define HDMI_FC_ACP6                    0x108C
+#define HDMI_FC_ACP5                    0x108D
+#define HDMI_FC_ACP4                    0x108E
+#define HDMI_FC_ACP3                    0x108F
+#define HDMI_FC_ACP2                    0x1090
+#define HDMI_FC_ACP1                    0x1091
+#define HDMI_FC_ISCR1_0                 0x1092
+#define HDMI_FC_ISCR1_16                0x1093
+#define HDMI_FC_ISCR1_15                0x1094
+#define HDMI_FC_ISCR1_14                0x1095
+#define HDMI_FC_ISCR1_13                0x1096
+#define HDMI_FC_ISCR1_12                0x1097
+#define HDMI_FC_ISCR1_11                0x1098
+#define HDMI_FC_ISCR1_10                0x1099
+#define HDMI_FC_ISCR1_9                 0x109A
+#define HDMI_FC_ISCR1_8                 0x109B
+#define HDMI_FC_ISCR1_7                 0x109C
+#define HDMI_FC_ISCR1_6                 0x109D
+#define HDMI_FC_ISCR1_5                 0x109E
+#define HDMI_FC_ISCR1_4                 0x109F
+#define HDMI_FC_ISCR1_3                 0x10A0
+#define HDMI_FC_ISCR1_2                 0x10A1
+#define HDMI_FC_ISCR1_1                 0x10A2
+#define HDMI_FC_ISCR2_15                0x10A3
+#define HDMI_FC_ISCR2_14                0x10A4
+#define HDMI_FC_ISCR2_13                0x10A5
+#define HDMI_FC_ISCR2_12                0x10A6
+#define HDMI_FC_ISCR2_11                0x10A7
+#define HDMI_FC_ISCR2_10                0x10A8
+#define HDMI_FC_ISCR2_9                 0x10A9
+#define HDMI_FC_ISCR2_8                 0x10AA
+#define HDMI_FC_ISCR2_7                 0x10AB
+#define HDMI_FC_ISCR2_6                 0x10AC
+#define HDMI_FC_ISCR2_5                 0x10AD
+#define HDMI_FC_ISCR2_4                 0x10AE
+#define HDMI_FC_ISCR2_3                 0x10AF
+#define HDMI_FC_ISCR2_2                 0x10B0
+#define HDMI_FC_ISCR2_1                 0x10B1
+#define HDMI_FC_ISCR2_0                 0x10B2
+#define HDMI_FC_DATAUTO0                0x10B3
+#define HDMI_FC_DATAUTO1                0x10B4
+#define HDMI_FC_DATAUTO2                0x10B5
+#define HDMI_FC_DATMAN                  0x10B6
+#define HDMI_FC_DATAUTO3                0x10B7
+#define HDMI_FC_RDRB0                   0x10B8
+#define HDMI_FC_RDRB1                   0x10B9
+#define HDMI_FC_RDRB2                   0x10BA
+#define HDMI_FC_RDRB3                   0x10BB
+#define HDMI_FC_RDRB4                   0x10BC
+#define HDMI_FC_RDRB5                   0x10BD
+#define HDMI_FC_RDRB6                   0x10BE
+#define HDMI_FC_RDRB7                   0x10BF
+#define HDMI_FC_STAT0                   0x10D0
+#define HDMI_FC_INT0                    0x10D1
+#define HDMI_FC_MASK0                   0x10D2
+#define HDMI_FC_POL0                    0x10D3
+#define HDMI_FC_STAT1                   0x10D4
+#define HDMI_FC_INT1                    0x10D5
+#define HDMI_FC_MASK1                   0x10D6
+#define HDMI_FC_POL1                    0x10D7
+#define HDMI_FC_STAT2                   0x10D8
+#define HDMI_FC_INT2                    0x10D9
+#define HDMI_FC_MASK2                   0x10DA
+#define HDMI_FC_POL2                    0x10DB
+#define HDMI_FC_PRCONF                  0x10E0
+
+// HDMI PHY Register Offset
+#define HDMI_PHY_CONF0                      0x3000
+#define HDMI_PHY_TST0                       0x3001
+#define HDMI_PHY_TST1                       0x3002
+#define HDMI_PHY_TST2                       0x3003
+#define HDMI_PHY_STAT0                      0x3004
+#define HDMI_PHY_INT0                       0x3005
+#define HDMI_PHY_MASK0                      0x3006
+#define HDMI_PHY_POL0                       0x3007
+#define HDMI_PHY_I2CM_SLAVE_ADDR            0x3020
+#define HDMI_PHY_I2CM_ADDRESS_ADDR          0x3021
+#define HDMI_PHY_I2CM_DATAO_1_ADDR          0x3022
+#define HDMI_PHY_I2CM_DATAO_0_ADDR          0x3023
+#define HDMI_PHY_I2CM_DATAI_1_ADDR          0x3024
+#define HDMI_PHY_I2CM_DATAI_0_ADDR          0x3025
+#define HDMI_PHY_I2CM_OPERATION_ADDR        0x3026
+#define HDMI_PHY_I2CM_INT_ADDR              0x3027
+#define HDMI_PHY_I2CM_CTLINT_ADDR           0x3028
+#define HDMI_PHY_I2CM_DIV_ADDR              0x3029
+#define HDMI_PHY_I2CM_SOFTRSTZ_ADDR         0x302a
+#define HDMI_PHY_I2CM_SS_SCL_HCNT_1_ADDR    0x302b
+#define HDMI_PHY_I2CM_SS_SCL_HCNT_0_ADDR    0x302c
+#define HDMI_PHY_I2CM_SS_SCL_LCNT_1_ADDR    0x302d
+#define HDMI_PHY_I2CM_SS_SCL_LCNT_0_ADDR    0x302e
+#define HDMI_PHY_I2CM_FS_SCL_HCNT_1_ADDR    0x302f
+#define HDMI_PHY_I2CM_FS_SCL_HCNT_0_ADDR    0x3030
+#define HDMI_PHY_I2CM_FS_SCL_LCNT_1_ADDR    0x3031
+#define HDMI_PHY_I2CM_FS_SCL_LCNT_0_ADDR    0x3032
+
+// Main Controller Registers
+#define HDMI_MC_CLKDIS          0x4001
+#define HDMI_MC_SWRSTZ          0x4002
+#define HDMI_MC_OPCTRL          0x4003
+#define HDMI_MC_FLOWCTRL        0x4004
+#define HDMI_MC_PHYRSTZ         0x4005
+#define HDMI_MC_LOCKONCLOCK     0x4006
+#define HDMI_MC_HEACPHY_RST     0x4007
+
+// HDMI_PHY absolute address
+#define HDMI_PHY_PWRCTRL        0x00
+#define HDMI_PHY_SERDIVCTRL     0x01
+#define HDMI_PHY_SERCKCTRL      0x02
+#define HDMI_PHY_SERCKKILLCTRL  0x03
+#define HDMI_PHY_TXRESCTRL      0x04
+#define HDMI_PHY_CKCALCTRL      0x05
+#define HDMI_PHY_CPCE_CTRL      0x06
+#define HDMI_PHY_TXCLKMEASCTRL  0x07
+#define HDMI_PHY_TXMEASCTRL     0x08
+#define HDMI_PHY_CKSYMTXCTRL    0x09
+#define HDMI_PHY_CMPSEQCTRL     0x0A
+#define HDMI_PHY_CMPPWRCTRL     0x0B
+#define HDMI_PHY_CMPMODECTRL    0x0C
+#define HDMI_PHY_MEASCTRL       0x0D
+#define HDMI_PHY_VLEVCTRL       0x0E
+#define HDMI_PHY_D2ACTRL        0x0F
+#define HDMI_PHY_CURRCTRL       0x10
+#define HDMI_PHY_DRVANACTRL     0x11
+#define HDMI_PHY_PLLMEASCTRL    0x12
+#define HDMI_PHY_PLLPHBYCTRL    0x13
+#define HDMI_PHY_GRP_CTRL       0x14
+#define HDMI_PHY_GMPCTRL        0x15
+#define HDMI_PHY_MPLLMEASCTRL   0x16
+#define HDMI_PHY_MSM_CTRL       0x17
+#define HDMI_PHY_SCRPB_STATUS   0x18
+#define HDMI_PHY_TXTERM         0x19
+#define HDMI_PHY_PTRPT_ENBL     0x1A
+#define HDMI_PHY_PATTERNGEN     0x1B
+#define HDMI_PHY_SDCAP_MODE     0x1C
+#define HDMI_PHY_SCOPEMODE      0x1D
+#define HDMI_PHY_DIGTXMODE      0x1E
+#define HDMI_PHY_STR_STATUS     0x1F
+#define HDMI_PHY_SCOPECNT0      0x20
+#define HDMI_PHY_SCOPECNT1      0x21
+#define HDMI_PHY_SCOPECNT2      0x22
+#define HDMI_PHY_SCOPECNTCLK    0x23
+#define HDMI_PHY_SCOPESAMPLE    0x24
+#define HDMI_PHY_SCOPECNTMSB01  0x25
+#define HDMI_PHY_SCOPECNTMSB2CK 0x26
+
+// Register struct
+
+#pragma pack(push, 1)
+
+// HDMI_PHY_CONF0 0x0100
+typedef union {
+    struct {
+        UINT8 seldipif : 1;
+        UINT8 seldataenpol : 1;
+        UINT8 gen2_enhpdrxsense : 1;
+        UINT8 gen2_txpwron : 1;
+        UINT8 gen2_pddq : 1;
+        UINT8 sparectrl : 1;
+        UINT8 ENTMDS : 1;
+        UINT8 PDZ : 1;
+    };
+    UINT8 Reg;
+}  HDMI_PHY_CONF0_REG;
+
+// HDMI_IH_I2CMPHY_STAT0 0x0108
+typedef union {
+    struct {
+        UINT8 i2cmphyerror : 1;
+        UINT8 i2cmphydone : 1;
+        UINT8 reserved : 6;
+    };
+    UINT8 Reg;
+}  HDMI_IH_I2CMPHY_STAT0_REG;
+
+// HDMI_FC_AUDSCONF 0x01063
+typedef union {
+    struct {
+        UINT8 aud_packet_layout : 1;
+        UINT8 reserved : 4;
+        UINT8 aud_packet_sampfit : 4;
+    };
+    UINT8 Reg;
+}  HDMI_FC_AUDSCONF_REG;
+
+// HDMI_PHY_STAT0 0x3004
+typedef union {
+    struct {
+        UINT8 TX_PHY_LOCK : 1;
+        UINT8 HPD : 1;
+        UINT8 reserved : 2;
+        UINT8 RX_SENSE0 : 1;
+        UINT8 RX_SENSE1 : 1;
+        UINT8 RX_SENSE2 : 1;
+        UINT8 RX_SENSE3 : 1;
+    };
+    UINT8 Reg;
+
+}  HDMI_PHY_STAT0_REG;
+
+// HDMI_PHY_I2CM_OPERATION_ADDR 0x3026
+typedef union {
+    struct {
+        UINT8 read : 1;
+        UINT8 reserved0 : 3;
+        UINT8 write : 1;
+        UINT8 reserved1 : 3;
+    };
+    UINT8 Reg;
+}  HDMI_PHY_I2CM_OPERATION_ADDR_REG;
+
+// HDMI_MC_CLKDIS 0x4001
+typedef union {
+    struct {
+        UINT8 pixelclk_disable : 1;
+        UINT8 tmdsclk_disable : 1;
+        UINT8 prepclk_disable : 1;
+        UINT8 audclk_disable : 1;
+        UINT8 cscclk_disable : 1;
+        UINT8 cecclk_disable : 1;
+        UINT8 hdcpclk_disable : 1;
+        UINT8 reserved : 1;
+    };
+    UINT8 Reg;
+} HDMI_MC_CLKDIS_REG;
+
+// HDMI_MC_PHYRSTZ 0x4005
+typedef union {
+    struct {
+        UINT8 phyrstz : 1;
+        UINT8 reserved : 7;
+    };
+    UINT8 Reg;
+}  HDMI_MC_PHYRSTZ_REG;
+
+// HDMI_MC_HEACPHY_RST 0x4007
+typedef union {
+    struct {
+        UINT8 heacphyrst : 1;
+        UINT8 reserved : 7;
+    };
+    UINT8 Reg;
+}  HDMI_MC_HEACPHY_RST_REG;
+
+// HDMI PHY : HDMI_PHY_CPCE_CTRL 0x06
+typedef union {
+    struct {
+        UINT16 clr_dpth : 2;
+        UINT16 pixel_rep : 3;
+        UINT16 pll_n_cntrl : 2;
+        UINT16 mpll_n_cntrl : 2;
+        UINT16 ck_edgerate : 2;
+        UINT16 tx_edgerate : 2;
+        UINT16 prep_div : 2;
+        UINT16 reserved : 1;
+    };
+    UINT16 Reg;
+}  HDMI_PHY_CPCE_CTRL_REG;
+
+// HDMI PHY : HDMI_PHY_CURRCTRL 0x10
+typedef union {
+    struct {
+        UINT16 pll_int_cntrl : 3;
+        UINT16 pll_prop_cntrl : 3;
+        UINT16 mpll_int_cntrl : 3;
+        UINT16 mpll_prop_cntrl : 3;
+        UINT16 reserved : 4;
+    };
+    UINT16 Reg;
+}  HDMI_PHY_CURRCTRL_REG;
+
+// HDMI PHY : HDMI_PHY_GMPCTRL 0x15
+typedef union {
+    struct {
+        UINT16 mpll_gmp_cntrl : 2;
+        UINT16 pll_gmp_cntrl : 2;
+        UINT16 reserved : 12;
+    };
+    UINT16 Reg;
+}  HDMI_PHY_GMPCTRL_REG;
+
+#pragma pack(pop)
+
+// HDMI DDC offset
+#define HDMI_I2CM_SLAVE                 0x7E00
+#define HDMI_I2CM_ADDRESS               0x7E01
+#define HDMI_I2CM_DATAO                 0x7E02
+#define HDMI_I2CM_DATAI                 0x7E03
+#define HDMI_I2CM_OPERATION             0x7E04
+#define HDMI_I2CM_INT                   0x7E05
+#define HDMI_I2CM_CTLINT                0x7E06
+#define HDMI_I2CM_DIV                   0x7E07
+#define HDMI_I2CM_SEGADDR               0x7E08
+#define HDMI_I2CM_SOFTRSTZ              0x7E09
+#define HDMI_I2CM_SEGPTR                0x7E0A
+#define HDMI_I2CM_SS_SCL_HCNT_1_ADDR    0x7E0B
+#define HDMI_I2CM_SS_SCL_HCNT_0_ADDR    0x7E0C
+#define HDMI_I2CM_SS_SCL_LCNT_1_ADDR    0x7E0D
+#define HDMI_I2CM_SS_SCL_LCNT_0_ADDR    0x7E0E
+#define HDMI_I2CM_FS_SCL_HCNT_1_ADDR    0x7E0F
+#define HDMI_I2CM_FS_SCL_HCNT_0_ADDR    0x7E10
+#define HDMI_I2CM_FS_SCL_LCNT_1_ADDR    0x7E11
+#define HDMI_I2CM_FS_SCL_LCNT_0_ADDR    0x7E12
+
+// DDC Interrupt status
+#define I2C_MASTER_ERROR                0x01
+#define I2C_MASTER_DONE                 0x02
+
+// HDMI bit configuration
+typedef enum
+{
+    DDC_READ_OPERATION = 0x01,
+    DDC_READ_EXT_OPERATION = 0x02,
+    DDC_WRITE_OPERATION = 0x10,
+}DDC_OPERATION;
+
+typedef enum
+{
+    HDMI_DDC_STANDARD_MODE = 0x00,
+    HDMI_DDC_FAST_MODE = 0x04,
+}DDC_MODE;
+
+typedef struct _PLL_MPLL_CONFIG {
+    UINT32 PixelClock;
+    UINT8 PixelRepetition;
+    UINT8 ColorDepth;
+    HDMI_PHY_CPCE_CTRL_REG HdmiPhyCpceCtrl;
+    HDMI_PHY_CURRCTRL_REG HdmiPhyCurrctrl;
+    HDMI_PHY_GMPCTRL_REG HdmiPhyGmpctrl;
+}PLL_MPLL_CONFIG, *PPLL_MPLL_CONFIG;
+
+OS_STATUS InitHDMI (
+    DISPLAY_CONTEXT* DisplayContextPtr
+    );
+
+OS_STATUS SetHDMIPower (
+    DISPLAY_INTERFACE_CONTEXT* HdmiDisplayContextPtr,
+    BOOLEAN PowerState
+    );
+
+OS_STATUS SetHDMIDisplay (
+    DISPLAY_INTERFACE_CONTEXT* HdmiDisplayContextPtr,
+    DISPLAY_TIMING* Timings
+    );
+
+OS_STATUS HDMIDDCRead (
+    DISPLAY_INTERFACE_CONTEXT* HdmiDisplayContextPtr,
+    UINT8 SlaveAddress,
+    UINT8 RegisterAddress,
+    UINT32 ReadSize,
+    DDC_MODE DDCMode,
+    UINT8* DataReadPtr);
+
+#endif
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/IoMux.c b/Silicon/NXP/iMX6Pkg/Drivers/GOP/IoMux.c
new file mode 100644
index 000000000000..7e5d575922a2
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/IoMux.c
@@ -0,0 +1,83 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Copyright 2018 NXP
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "Osal.h"
+#include "Display.h"
+#include "IoMux.h"
+
+OS_STATUS SetupDisplayMux (
+    DISPLAY_CONTEXT* DisplayContextPtr
+    )
+{
+    OS_STATUS status;
+    DISPLAY_MODE displayMode = DisplayContextPtr->DisplayConfig.DisplayMode;
+    DISPLAY_INTERFACE* displayInterface =
+        DisplayContextPtr->DisplayConfig.DIOrder;
+    UINT32 regGPR3, sourceMask, sourceVal, dIIndex;
+    volatile IMX_IOMUXC_GPR_REGISTERS* ioMuxcGprRegisters =
+        DisplayContextPtr->IoMuxMmioBasePtr;
+
+    regGPR3 =
+        OS_READ32(&ioMuxcGprRegisters->GPR3);
+
+    regGPR3 &= ~(HDMI_MUX_CTL_MASK |
+                 MIPI_MUX_CTL_MASK |
+                 LVDS0_MUX_CTL_MASK |
+                 LVDS1_MUX_CTL_MASK);
+
+    OS_WRITE32(
+        &ioMuxcGprRegisters->GPR3,
+        regGPR3);
+
+    for (dIIndex = 0; dIIndex < (UINT32)displayMode; ++dIIndex) {
+        regGPR3 =
+            OS_READ32(&ioMuxcGprRegisters->GPR3);
+
+        switch (displayInterface[dIIndex])
+        {
+        case HDMI_DISPLAY:
+            sourceMask = HDMI_MUX_CTL_MASK;
+            sourceVal = dIIndex << HDMI_MUX_CTL_OFFSET;
+            break;
+        case MIPI_DISPLAY:
+            sourceMask = MIPI_MUX_CTL_MASK;
+            sourceVal = dIIndex << MIPI_MUX_CTL_OFFSET;
+            break;
+        case LVDS0_DISPLAY:
+            sourceMask = LVDS0_MUX_CTL_MASK;
+            sourceVal = dIIndex << LVDS0_MUX_CTL_OFFSET;
+            break;
+        case LVDS1_DISPLAY:
+            sourceMask = LVDS1_MUX_CTL_MASK;
+            sourceVal = dIIndex << LVDS1_MUX_CTL_OFFSET;
+            break;
+        default:
+            status = OS_STATUS_UNSUPPORTED;
+            goto Exit;
+        }
+
+        regGPR3 &= ~sourceMask;
+        regGPR3 |= sourceVal;
+
+        OS_WRITE32(
+            &ioMuxcGprRegisters->GPR3,
+            regGPR3);
+    }
+
+    status = OS_STATUS_SUCCESS;
+
+Exit:
+    return status;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/IoMux.h b/Silicon/NXP/iMX6Pkg/Drivers/GOP/IoMux.h
new file mode 100644
index 000000000000..5755b03ef8db
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/IoMux.h
@@ -0,0 +1,31 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _IO_MUX_H_
+#define _IO_MUX_H_
+
+#define HDMI_MUX_CTL_OFFSET         2
+#define HDMI_MUX_CTL_MASK           0x000C
+#define MIPI_MUX_CTL_OFFSET         4
+#define MIPI_MUX_CTL_MASK           0x0030
+#define LVDS0_MUX_CTL_OFFSET        6
+#define LVDS0_MUX_CTL_MASK          0x00C0
+#define LVDS1_MUX_CTL_OFFSET        8
+#define LVDS1_MUX_CTL_MASK          0x0300
+
+OS_STATUS SetupDisplayMux (
+    DISPLAY_CONTEXT* DisplayContextPtr
+    );
+
+#endif
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/Ipu.h b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Ipu.h
new file mode 100644
index 000000000000..7fdb118c99be
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Ipu.h
@@ -0,0 +1,236 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _IPU_H_
+#define _IPU_H_
+
+#define IPU1_BASE      0x02600000
+#define IPU2_BASE      0x02A00000
+
+#define IpuRead32(IPU_BASE, OFFSET) \
+            OS_READ32(((unsigned char*)IPU_BASE + OFFSET))
+
+#define IpuWrite32(IPU_BASE, OFFSET, VALUE) \
+            OS_WRITE32(((unsigned char*)IPU_BASE + OFFSET), VALUE)
+
+#define DiRead32(DI_BASE, OFFSET) \
+            OS_READ32(((unsigned char*)DI_BASE + OFFSET))
+
+#define DiWrite32(DI_BASE, OFFSET, VALUE) \
+            OS_WRITE32(((unsigned char*)DI_BASE + OFFSET), VALUE)
+
+// IPU Registers
+#define IPU_IPU_CONF_OFFSET                     0x00000000
+#define IPU_SISG_CTRL0_OFFSET                   0x00000004
+#define IPU_SISG_CTRL1_OFFSET                   0x00000008
+#define IPU_SISG_SET_OFFSET                     0x0000000C
+#define IPU_SISG_CLR_OFFSET                     0x00000024
+#define IPU_IPU_INT_CTRL_1_OFFSET               0x0000003C
+#define IPU_IPU_INT_CTRL_2_OFFSET               0x00000040
+#define IPU_IPU_INT_CTRL_3_OFFSET               0x00000044
+#define IPU_IPU_INT_CTRL_4_OFFSET               0x00000048
+#define IPU_IPU_INT_CTRL_5_OFFSET               0x0000004C
+#define IPU_IPU_INT_CTRL_6_OFFSET               0x00000050
+#define IPU_IPU_INT_CTRL_7_OFFSET               0x00000054
+#define IPU_IPU_INT_CTRL_8_OFFSET               0x00000058
+#define IPU_IPU_INT_CTRL_9_OFFSET               0x0000005C
+#define IPU_IPU_INT_CTRL_10_OFFSET              0x00000060
+#define IPU_IPU_INT_CTRL_11_OFFSET              0x00000064
+#define IPU_IPU_INT_CTRL_12_OFFSET              0x00000068
+#define IPU_IPU_INT_CTRL_13_OFFSET              0x0000006C
+#define IPU_IPU_INT_CTRL_14_OFFSET              0x00000070
+#define IPU_IPU_INT_CTRL_15_OFFSET              0x00000074
+#define IPU_IPU_SDMA_EVENT_1_OFFSET             0x00000078
+#define IPU_IPU_SDMA_EVENT_2_OFFSET             0x0000007C
+#define IPU_IPU_SDMA_EVENT_3_OFFSET             0x00000080
+#define IPU_IPU_SDMA_EVENT_4_OFFSET             0x00000084
+#define IPU_IPU_SDMA_EVENT_7_OFFSET             0x00000088
+#define IPU_IPU_SDMA_EVENT_8_OFFSET             0x0000008C
+#define IPU_IPU_SDMA_EVENT_11_OFFSET            0x00000090
+#define IPU_IPU_SDMA_EVENT_12_OFFSET            0x00000094
+#define IPU_IPU_SDMA_EVENT_13_OFFSET            0x00000098
+#define IPU_IPU_SDMA_EVENT_14_OFFSET            0x0000009C
+#define IPU_IPU_SRM_PRI1_OFFSET                 0x000000A0
+#define IPU_IPU_SRM_PRI2_OFFSET                 0x000000A4
+#define IPU_IPU_FS_PROC_FLOW1_OFFSET            0x000000A8
+#define IPU_IPU_FS_PROC_FLOW2_OFFSET            0x000000AC
+#define IPU_IPU_FS_PROC_FLOW3_OFFSET            0x000000B0
+#define IPU_IPU_FS_DISP_FLOW1_OFFSET            0x000000B4
+#define IPU_IPU_FS_DISP_FLOW2_OFFSET            0x000000B8
+#define IPU_IPU_SKIP_OFFSET                     0x000000BC
+#define IPU_IPU_DISP_ALT_CONF_OFFSET            0x000000C0
+#define IPU_IPU_DISP_GEN_OFFSET                 0x000000C4
+#define IPU_IPU_DISP_ALT1_OFFSET                0x000000C8
+#define IPU_IPU_DISP_ALT2_OFFSET                0x000000CC
+#define IPU_IPU_DISP_ALT3_OFFSET                0x000000D0
+#define IPU_IPU_DISP_ALT4_OFFSET                0x000000D4
+#define IPU_IPU_SNOOP_OFFSET                    0x000000D8
+#define IPU_IPU_MEM_RST_OFFSET                  0x000000DC
+#define IPU_IPU_PM_OFFSET                       0x000000E0
+#define IPU_IPU_GPR_OFFSET                      0x000000E4
+#define IPU_IPU_INT_STAT_1_OFFSET               0x000000E8
+#define IPU_IPU_INT_STAT_2_OFFSET               0x000000EC
+#define IPU_IPU_INT_STAT_3_OFFSET               0x000000F0
+#define IPU_IPU_INT_STAT_4_OFFSET               0x000000F4
+#define IPU_IPU_INT_STAT_5_OFFSET               0x000000F8
+#define IPU_IPU_INT_STAT_6_OFFSET               0x000000FC
+#define IPU_IPU_INT_STAT_7_OFFSET               0x00000100
+#define IPU_IPU_INT_STAT_8_OFFSET               0x00000104
+#define IPU_IPU_INT_STAT_9_OFFSET               0x00000108
+#define IPU_IPU_INT_STAT_10_OFFSET              0x0000010C
+#define IPU_IPU_INT_STAT_11_OFFSET              0x00000110
+#define IPU_IPU_INT_STAT_12_OFFSET              0x00000114
+#define IPU_IPU_INT_STAT_13_OFFSET              0x00000118
+#define IPU_IPU_INT_STAT_14_OFFSET              0x0000011C
+#define IPU_IPU_INT_STAT_15_OFFSET              0x00000120
+#define IPU_IPU_CUR_BUF_0_OFFSET                0x00000124
+#define IPU_IPU_CUR_BUF_1_OFFSET                0x00000128
+#define IPU_IPU_ALT_CUR_BUF_0_OFFSET            0x0000012C
+#define IPU_IPU_ALT_CUR_BUF_1_OFFSET            0x00000130
+#define IPU_IPU_SRM_STAT_OFFSET                 0x00000134
+#define IPU_IPU_PROC_TASKS_STAT_OFFSET          0x00000138
+#define IPU_IPU_DISP_TASKS_STAT_OFFSET          0x0000013C
+#define IPU_IPU_CH_BUF0_RDY0_OFFSET             0x00000140
+#define IPU_IPU_CH_BUF0_RDY1_OFFSET             0x00000144
+#define IPU_IPU_CH_BUF1_RDY0_OFFSET             0x00000148
+#define IPU_IPU_CH_BUF1_RDY1_OFFSET             0x0000014C
+#define IPU_IPU_CH_DB_MODE_SEL0_OFFSET          0x00000150
+#define IPU_IPU_CH_DB_MODE_SEL1_OFFSET          0x00000154
+#define IPU_IPU_ALT_CH_BUF0_RDY0_OFFSET         0x00000158
+#define IPU_IPU_ALT_CH_BUF0_RDY1_OFFSET         0x0000015C
+#define IPU_IPU_ALT_CH_BUF1_RDY0_OFFSET         0x00000160
+#define IPU_IPU_ALT_CH_BUF1_RDY1_OFFSET         0x00000164
+#define IPU_IPU_ALT_CH_DB_MODE_SEL0_OFFSET      0x00000168
+#define IPU_IPU_ALT_CH_DB_MODE_SEL1_OFFSET      0x0000016C
+#define CSP_IPUV3_CPMEM_REGS_OFFSET             0x00100000
+
+// IPU DIx Registers
+#define IPU_DIx_GENERAL_OFFSET                  0x00000000
+#define IPU_DIx_BS_CLKGEN0_OFFSET               0x00000004
+#define IPU_DIx_BS_CLKGEN1_OFFSET               0x00000008
+#define IPU_DIx_SW_GEN0_1_OFFSET                0x0000000C
+#define IPU_DIx_SW_GEN0_2_OFFSET                0x00000010
+#define IPU_DIx_SW_GEN0_3_OFFSET                0x00000014
+#define IPU_DIx_SW_GEN0_4_OFFSET                0x00000018
+#define IPU_DIx_SW_GEN0_5_OFFSET                0x0000001C
+#define IPU_DIx_SW_GEN0_6_OFFSET                0x00000020
+#define IPU_DIx_SW_GEN0_7_OFFSET                0x00000024
+#define IPU_DIx_SW_GEN0_8_OFFSET                0x00000028
+#define IPU_DIx_SW_GEN0_9_OFFSET                0x0000002C
+#define IPU_DIx_SW_GEN1_1_OFFSET                0x00000030
+#define IPU_DIx_SW_GEN1_2_OFFSET                0x00000034
+#define IPU_DIx_SW_GEN1_3_OFFSET                0x00000038
+#define IPU_DIx_SW_GEN1_4_OFFSET                0x0000003C
+#define IPU_DIx_SW_GEN1_5_OFFSET                0x00000040
+#define IPU_DIx_SW_GEN1_6_OFFSET                0x00000044
+#define IPU_DIx_SW_GEN1_7_OFFSET                0x00000048
+#define IPU_DIx_SW_GEN1_8_OFFSET                0x0000004C
+#define IPU_DIx_SW_GEN1_9_OFFSET                0x00000050
+#define IPU_DIx_SYNC_AS_GEN_OFFSET              0x00000054
+#define IPU_DIx_DW_GEN_OFFSET                   0x00000058
+#define IPU_DIx_DW_SET0_OFFSET                  0x00000088
+#define IPU_DIx_DW_SET1_OFFSET                  0x000000B8
+#define IPU_DIx_DW_SET2_OFFSET                  0x000000E8
+#define IPU_DIx_DW_SET3_OFFSET                  0x00000118
+#define IPU_DIx_STP_REP_OFFSET                  0x00000148
+#define IPU_DIx_STP_REP_9_OFFSET                0x00000158
+#define IPU_DIx_SER_CONF_OFFSET                 0x0000015C
+#define IPU_DIx_SSC_OFFSET                      0x00000160
+#define IPU_DIx_POL_OFFSET                      0x00000164
+#define IPU_DIx_AW0_OFFSET                      0x00000168
+#define IPU_DIx_AW1_OFFSET                      0x0000016C
+#define IPU_DIx_SCR_CONF_OFFSET                 0x00000170
+#define IPU_DIx_STAT_OFFSET                     0x00000174
+
+// IPU IDMAC Registers
+#define IPU_IDMAC_LOCK_EN_1                     0x00008024
+#define IPU_IDMAC_LOCK_EN_2                     0x00008028
+
+// IPU DI0 Registers
+#define IPU_DI0_GENERAL_OFFSET                  0x00040000
+#define IPU_DI0_BS_CLKGEN0_OFFSET               0x00040004
+#define IPU_DI0_BS_CLKGEN1_OFFSET               0x00040008
+#define IPU_DI0_SW_GEN0_1_OFFSET                0x0004000C
+#define IPU_DI0_SW_GEN0_2_OFFSET                0x00040010
+#define IPU_DI0_SW_GEN0_3_OFFSET                0x00040014
+#define IPU_DI0_SW_GEN0_4_OFFSET                0x00040018
+#define IPU_DI0_SW_GEN0_5_OFFSET                0x0004001C
+#define IPU_DI0_SW_GEN0_6_OFFSET                0x00040020
+#define IPU_DI0_SW_GEN0_7_OFFSET                0x00040024
+#define IPU_DI0_SW_GEN0_8_OFFSET                0x00040028
+#define IPU_DI0_SW_GEN0_9_OFFSET                0x0004002C
+#define IPU_DI0_SW_GEN1_1_OFFSET                0x00040030
+#define IPU_DI0_SW_GEN1_2_OFFSET                0x00040034
+#define IPU_DI0_SW_GEN1_3_OFFSET                0x00040038
+#define IPU_DI0_SW_GEN1_4_OFFSET                0x0004003C
+#define IPU_DI0_SW_GEN1_5_OFFSET                0x00040040
+#define IPU_DI0_SW_GEN1_6_OFFSET                0x00040044
+#define IPU_DI0_SW_GEN1_7_OFFSET                0x00040048
+#define IPU_DI0_SW_GEN1_8_OFFSET                0x0004004C
+#define IPU_DI0_SW_GEN1_9_OFFSET                0x00040050
+#define IPU_DI0_SYNC_AS_GEN_OFFSET              0x00040054
+#define IPU_DI0_DW_GEN_OFFSET                   0x00040058
+#define IPU_DI0_DW_SET0_OFFSET                  0x00040088
+#define IPU_DI0_DW_SET1_OFFSET                  0x000400B8
+#define IPU_DI0_DW_SET2_OFFSET                  0x000400E8
+#define IPU_DI0_DW_SET3_OFFSET                  0x00040118
+#define IPU_DI0_STP_REP_OFFSET                  0x00040148
+#define IPU_DI0_STP_REP_9_OFFSET                0x00040158
+#define IPU_DI0_SER_CONF_OFFSET                 0x0004015C
+#define IPU_DI0_SSC_OFFSET                      0x00040160
+#define IPU_DI0_POL_OFFSET                      0x00040164
+#define IPU_DI0_AW0_OFFSET                      0x00040168
+#define IPU_DI0_AW1_OFFSET                      0x0004016C
+#define IPU_DI0_SCR_CONF_OFFSET                 0x00040170
+#define IPU_DI0_STAT_OFFSET                     0x00040174
+
+// IPU DI1 Registers
+#define IPU_DI1_GENERAL_OFFSET                  0x00048000
+#define IPU_DI1_BS_CLKGEN0_OFFSET               0x00048004
+#define IPU_DI1_BS_CLKGEN1_OFFSET               0x00048008
+#define IPU_DI1_SW_GEN0_1_OFFSET                0x0004800C
+#define IPU_DI1_SW_GEN0_2_OFFSET                0x00048010
+#define IPU_DI1_SW_GEN0_3_OFFSET                0x00048014
+#define IPU_DI1_SW_GEN0_4_OFFSET                0x00048018
+#define IPU_DI1_SW_GEN0_5_OFFSET                0x0004801C
+#define IPU_DI1_SW_GEN0_6_OFFSET                0x00048020
+#define IPU_DI1_SW_GEN0_7_OFFSET                0x00048024
+#define IPU_DI1_SW_GEN0_8_OFFSET                0x00048028
+#define IPU_DI1_SW_GEN0_9_OFFSET                0x0004802C
+#define IPU_DI1_SW_GEN1_1_OFFSET                0x00048030
+#define IPU_DI1_SW_GEN1_2_OFFSET                0x00048034
+#define IPU_DI1_SW_GEN1_3_OFFSET                0x00048038
+#define IPU_DI1_SW_GEN1_4_OFFSET                0x0004803C
+#define IPU_DI1_SW_GEN1_5_OFFSET                0x00048040
+#define IPU_DI1_SW_GEN1_6_OFFSET                0x00048044
+#define IPU_DI1_SW_GEN1_7_OFFSET                0x00048048
+#define IPU_DI1_SW_GEN1_8_OFFSET                0x0004804C
+#define IPU_DI1_SW_GEN1_9_OFFSET                0x00048050
+#define IPU_DI1_SYNC_AS_GEN_OFFSET              0x00048054
+#define IPU_DI1_DW_GEN_OFFSET                   0x00048058
+#define IPU_DI1_DW_SET0_OFFSET                  0x00048088
+#define IPU_DI1_DW_SET1_OFFSET                  0x000480B8
+#define IPU_DI1_DW_SET2_OFFSET                  0x000480E8
+#define IPU_DI1_DW_SET3_OFFSET                  0x00048118
+#define IPU_DI1_STP_REP_OFFSET                  0x00048148
+#define IPU_DI1_STP_REP_9_OFFSET                0x00048158
+#define IPU_DI1_SER_CONF_OFFSET                 0x0004815C
+#define IPU_DI1_SSC_OFFSET                      0x00048160
+#define IPU_DI1_POL_OFFSET                      0x00048164
+#define IPU_DI1_AW0_OFFSET                      0x00048168
+#define IPU_DI1_AW1_OFFSET                      0x0004816C
+#define IPU_DI1_SCR_CONF_OFFSET                 0x00048170
+#define IPU_DI1_STAT_OFFSET                     0x00048174
+
+#endif
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/Lvds.c b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Lvds.c
new file mode 100644
index 000000000000..325e81974888
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Lvds.c
@@ -0,0 +1,81 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Copyright 2018 NXP
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "Osal.h"
+#include "Display.h"
+#include "Lvds.h"
+#include "Edid.h"
+
+OS_STATUS InitLVDS (
+    DISPLAY_CONTEXT* DisplayContextPtr
+    )
+{
+    DISPLAY_INTERFACE_CONTEXT* LvdsDisplayContextPtr = &DisplayContextPtr->DIContext[LVDS0_DISPLAY];
+    OS_STATUS status = 0;
+
+    OS_ZERO_MEM(LvdsDisplayContextPtr, sizeof(*LvdsDisplayContextPtr));
+
+    LvdsDisplayContextPtr->MmioBasePtr = (VOID*)OS_MMIO_MAP(LDB_BASE);
+    if (LvdsDisplayContextPtr->MmioBasePtr == NULL) {
+        OS_ERROR("Fail to map LDB register\n");
+        goto Exit;
+    }
+
+
+    // LVDS CH1 enabled, routed to DI0; ipu_di01_vsync_active_low
+    {
+
+
+        LDB_CTRL_REG LdbCtrlReg;
+        LdbCtrlReg.Reg = LVDSRead32(LDB_CTRL);
+        LdbCtrlReg.ch0_mode = 1;
+        LdbCtrlReg.ch1_mode = 1;
+        LdbCtrlReg.di0_vs_polarity = 1;
+        LdbCtrlReg.di1_vs_polarity = 1;
+        LVDSWrite32(LDB_CTRL, LdbCtrlReg.Reg);
+    }
+
+    // No EDID available
+    LvdsDisplayContextPtr->EdidDataSize = 0;
+
+    status = GetPreferedTiming(
+        LvdsDisplayContextPtr->EdidData,
+        LvdsDisplayContextPtr->EdidDataSize,
+        &LvdsDisplayContextPtr->PreferedTiming);
+    if (status != OS_STATUS_SUCCESS) {
+        OS_ERROR("Fail to retrieve LVDS prefered timing\n");
+        goto Exit;
+    }
+
+Exit:
+    return status;
+}
+
+OS_STATUS SetLVDSPower (
+    DISPLAY_INTERFACE_CONTEXT* HdmiDisplayContextPtr,
+    BOOLEAN PowerState
+    )
+{
+    return OS_STATUS_UNSUPPORTED;
+}
+
+OS_STATUS SetLVDSDisplay (
+    DISPLAY_INTERFACE_CONTEXT* LvdsDisplayContextPtr,
+    DISPLAY_TIMING* Timings
+    )
+{
+    return OS_STATUS_UNSUPPORTED;
+}
+
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/Lvds.h b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Lvds.h
new file mode 100644
index 000000000000..f98b4aac0061
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Lvds.h
@@ -0,0 +1,72 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Copyright 2018 NXP
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _LVDS_H_
+#define _LVDS_H_
+
+#define LVDSRead32(a) \
+            OS_READ32((UINT32)LvdsDisplayContextPtr->MmioBasePtr + (a))
+
+#define LVDSWrite32(a, b) \
+            OS_WRITE32((UINT32)LvdsDisplayContextPtr->MmioBasePtr + (a), (b))
+
+// LDB Register Base Address
+#define LDB_BASE 0x020E0008
+
+// LDB Control Register offset
+#define LDB_CTRL    0
+
+// Register struct
+
+#pragma pack(push, 1)
+
+// LDB_CTRL_REG
+typedef union {
+    struct {
+        UINT32 ch0_mode : 2;
+        UINT32 ch1_mode : 2;
+        UINT32 split_mode_en : 1;
+        UINT32 data_width_ch0 : 1;
+        UINT32 bit_mapping_ch0 : 1;
+        UINT32 data_width_ch1 : 1;
+        UINT32 bit_mapping_ch1 : 1;
+        UINT32 di0_vs_polarity : 1;
+        UINT32 di1_vs_polarity : 1;
+        UINT32 Reserved11_15 : 5;
+        UINT32 lvds_clk_shift : 3;
+        UINT32 Reserved19 : 1;
+        UINT32 counter_reset_val : 2;
+        UINT32 Reserved22_31 : 10;
+    };
+    UINT32 Reg;
+}  LDB_CTRL_REG;
+
+#pragma pack(pop)
+
+OS_STATUS InitLVDS (
+    DISPLAY_CONTEXT* DisplayContextPtr
+    );
+
+OS_STATUS SetLVDSPower (
+    DISPLAY_INTERFACE_CONTEXT* LvdsDisplayContextPtr,
+    BOOLEAN PowerState
+    );
+
+OS_STATUS SetLVDSDisplay (
+    DISPLAY_INTERFACE_CONTEXT* LvdsDisplayContextPtr,
+    DISPLAY_TIMING* Timings
+    );
+
+#endif
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/Osal.c b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Osal.c
new file mode 100644
index 000000000000..664f9e008f1c
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Osal.c
@@ -0,0 +1,38 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include "Osal.h"
+#include "Display.h"
+#include "Ipu.h"
+
+OS_STATUS UefiAllocContiguousMemory (
+    UINT32 AllocSize,
+    VOID** MemoryPointer)
+{
+    OS_STATUS status;
+
+    *MemoryPointer = NULL;
+
+    *MemoryPointer = AllocateRuntimePool(AllocSize);
+    if (*MemoryPointer == NULL) {
+        OS_ERROR("AllocateRuntimePool failed\n");
+        status = OS_STATUS_INSUFFICIENT_RESOURCE;
+        goto Exit;
+    }
+
+    status = OS_STATUS_SUCCESS;
+
+Exit:
+    return status;
+}
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/Osal.h b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Osal.h
new file mode 100644
index 000000000000..7719b0a1bddb
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/Osal.h
@@ -0,0 +1,74 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#ifndef _OSAL_H_
+#define _OSAL_H_
+
+// OS abstraction header
+
+#ifdef WIN32 // Windows
+
+#else // UEFI
+
+#include <Uefi.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+// UEFI only headers
+#include <iMX6.h>
+#include <iMXDisplay.h>
+#include <iMX6ClkPwr.h>
+
+#define OS_READ8(ADDRESS)  MmioRead8(ADDRESS)
+#define OS_WRITE8(ADDRESS, VALUE)  MmioWrite8(ADDRESS, VALUE)
+#define OS_READ32(ADDRESS)  MmioRead32((UINT32)ADDRESS)
+#define OS_WRITE32(ADDRESS, VALUE)  MmioWrite32((UINT32)ADDRESS, VALUE)
+
+#ifndef ARRAYSIZE
+#define ARRAYSIZE(__array__) (sizeof((__array__))/sizeof((__array__[0])))
+#endif
+
+#define OS_STATUS                           EFI_STATUS
+#define OS_STATUS_SUCCESS                   EFI_SUCCESS
+#define OS_STATUS_INVALID_PARAM             EFI_INVALID_PARAMETER
+#define OS_STATUS_DEVICE_ERROR              EFI_DEVICE_ERROR
+#define OS_STATUS_UNSUPPORTED               EFI_UNSUPPORTED
+#define OS_STATUS_INSUFFICIENT_RESOURCE     EFI_OUT_OF_RESOURCES
+
+OS_STATUS UefiAllocContiguousMemory (
+    UINT32 AllocSize,
+    VOID** MemoryPointer
+    );
+
+#define OS_MMIO_MAP(PHYSICAL_ADDRESS)           PHYSICAL_ADDRESS
+#define OS_SLEEP(MILISECOND)                    gBS->Stall(MILISECOND)
+#define OS_ALLOC_CONTIGUOUS_MEMORY(ALLOC_SIZE, MEMORY_POINTER) \
+            UefiAllocContiguousMemory(ALLOC_SIZE, (VOID**) MEMORY_POINTER)
+#define OS_VIRT_TO_PHY_ADDR(VIRT_ADDR)          (VIRT_ADDR)
+#define OS_MEM_COPY(DEST, SRC, SIZE)            CopyMem(DEST, SRC, SIZE)
+#define OS_ZERO_MEM(VIRT_ADDR, SIZE)            ZeroMem(VIRT_ADDR, SIZE)
+
+#define OS_LOG_FMT_HELPER(FMT, ...) \
+    "iMX6Gop:" FMT "%a", __VA_ARGS__
+
+#define OS_INFO(...) DEBUG((DEBUG_INFO, OS_LOG_FMT_HELPER(__VA_ARGS__, "")))
+#define OS_WARNING(...) DEBUG((DEBUG_WARN, OS_LOG_FMT_HELPER(__VA_ARGS__, "")))
+#define OS_ERROR(...) DEBUG((DEBUG_ERROR, OS_LOG_FMT_HELPER(__VA_ARGS__, "")))
+
+#endif
+
+#endif
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/iMX6GOP.inf b/Silicon/NXP/iMX6Pkg/Drivers/GOP/iMX6GOP.inf
new file mode 100644
index 000000000000..49e4788c0781
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/iMX6GOP.inf
@@ -0,0 +1,71 @@
+#/** @file
+#
+#  Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+#  Copyright (c) Microsoft Corporation. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = iMX6GOPDxe
+  FILE_GUID                      = E68088EF-D1A4-4336-C1DB-4D3A204730A6
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = VideoiMX6DxeInitialize
+
+[Sources.common]
+  iMXVideoDxe.c
+  Osal.c
+  Ddc.c
+  Display.c
+  Hdmi.c
+  Lvds.c
+  Edid.c
+  DisplayInterface.c
+  DisplayController.c
+  CPMem.c
+  IoMux.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Silicon/NXP/iMX6Pkg/iMX6Pkg.dec
+
+[LibraryClasses]
+  ArmLib
+  UefiLib
+  BaseLib
+  DebugLib
+  TimerLib
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  IoLib
+  BaseMemoryLib
+  iMX6ClkPwrLib
+  iMXDisplayLib
+
+[Protocols]
+  gEfiDevicePathProtocolGuid                    # Produced
+  gEfiGraphicsOutputProtocolGuid                # Produced
+  gEfiEdidDiscoveredProtocolGuid                # Produced
+  gEfiEdidActiveProtocolGuid                    # Produced
+  gEfiDevicePathToTextProtocolGuid
+
+[Pcd]
+  giMX6TokenSpaceGuid.PcdFrameBufferBase
+  giMX6TokenSpaceGuid.PcdFrameBufferSize
+  giMX6TokenSpaceGuid.PcdLvdsEnable
+
+[Depex]
+  gEfiCpuArchProtocolGuid AND gEfiTimerArchProtocolGuid
diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GOP/iMXVideoDxe.c b/Silicon/NXP/iMX6Pkg/Drivers/GOP/iMXVideoDxe.c
new file mode 100644
index 000000000000..f65c0df8f148
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/Drivers/GOP/iMXVideoDxe.c
@@ -0,0 +1,488 @@
+/** @file
+*
+*  Copyright (c) Microsoft Corporation. All rights reserved.
+*  Copyright 2018 NXP
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD License
+*  which accompanies this distribution.  The full text of the license may be found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+*
+**/
+
+#include <Uefi.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/EmbeddedExternalDevice.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/Cpu.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/EdidDiscovered.h>
+#include <Protocol/EdidActive.h>
+
+#include "Osal.h"
+#include "Display.h"
+#include "Hdmi.h"
+#include "Lvds.h"
+
+#define PIXEL_BYTES 4
+
+typedef struct {
+    VENDOR_DEVICE_PATH Mmc;
+    EFI_DEVICE_PATH End;
+} VID_DEVICE_PATH;
+
+DISPLAY_TIMING const FullHDTiming =
+{
+    148500000,  // Full 1080p HD PixelClock
+    1920,       // HActive
+    280,        // HBlank
+    1080,       // VActive
+    45,         // VBlank
+    44,         // HSync
+    5,          // VSync
+    88,         // HSyncOffset;
+    4,          // VSyncOffset;
+    1920,       // HImageSize
+    1080,       // VImageSize
+    0,          // HBorder
+    0,          // VBorder
+    30,         // EdidFlags
+    0,          // Flags
+    1,          // PixelRepetition
+    32,         // Bpp
+    PIXEL_FORMAT_BGRA32,       // PixelFormat
+};
+
+EFI_STATUS
+EFIAPI
+VidGopQueryMode(
+    IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+    IN UINT32 ModeNumber,
+    OUT UINTN *SizeOfInfo,
+    OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
+    );
+
+EFI_STATUS
+VidGopSetMode(
+    IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+    IN UINT32 ModeNumber
+    );
+
+EFI_STATUS
+VidGopBlt(
+    IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+    IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer,
+    IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+    IN UINTN SourceX,
+    IN UINTN SourceY,
+    IN UINTN DestinationX,
+    IN UINTN DestinationY,
+    IN UINTN Width,
+    IN UINTN Height,
+    IN UINTN Delta
+    );
+
+//--------------------------------------------------------------------- Globals.
+
+static VID_DEVICE_PATH g_VidDevicePath =
+{
+    {
+        {
+            HARDWARE_DEVICE_PATH,
+            HW_VENDOR_DP,
+            {
+                (UINT8)sizeof(VENDOR_DEVICE_PATH),
+                (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8),
+            }
+        },
+        {
+            0xa6b94ebe,
+            0x5ba3,
+            0x44b0,
+            { 0x95, 0x92, 0xdc, 0x04, 0x5e, 0xb8, 0xf8, 0x9e }
+        }
+    },
+    {
+        END_DEVICE_PATH_TYPE,
+        END_ENTIRE_DEVICE_PATH_SUBTYPE,
+        {
+            sizeof(EFI_DEVICE_PATH_PROTOCOL),
+            0
+        }
+    }
+};
+
+static EFI_GRAPHICS_OUTPUT_MODE_INFORMATION g_VidGopModeInfo;
+static EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE g_VidGopMode;
+
+static EFI_GRAPHICS_OUTPUT_PROTOCOL g_VidGop =
+{
+    VidGopQueryMode, // QueryMode
+    VidGopSetMode,   // SetMode
+    VidGopBlt,       // Blt
+    &g_VidGopMode    // Mode
+};
+
+EFI_EDID_DISCOVERED_PROTOCOL g_EdidDiscovered = {
+    0,
+    NULL
+};
+
+EFI_EDID_ACTIVE_PROTOCOL g_EdidActive = {
+    0,
+    NULL
+};
+
+DISPLAY_CONTEXT* DisplayContextPtr;
+
+DISPLAY_INTERFACE DisplayDevice;
+
+EFI_STATUS
+VideoiMX6DxeInitialize (
+    IN EFI_HANDLE       ImageHandle,
+    IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+    EFI_STATUS status;
+    UINT32 ReservedDisplayMemorySize;
+    UINT32 RequestedDisplayMemorySize;
+    DEBUG((DEBUG_INFO,"++VideoiMX6DxeInitialize()\r\n"));
+
+       ReservedDisplayMemorySize = FixedPcdGet32(PcdFrameBufferSize);
+
+    if (FeaturePcdGet(PcdLvdsEnable)) {
+        DisplayDevice = LVDS0_DISPLAY;
+    } else {
+        DisplayDevice = HDMI_DISPLAY;
+    }
+
+    status = InitDisplay(&DisplayContextPtr);
+    if (EFI_ERROR(status)) {
+        DEBUG(
+            (DEBUG_ERROR,
+            "VideoiMX6DxeInitialize: Fail to init display, status=%r\n",
+            status));
+        goto Exit;
+    }
+
+    DEBUG((DEBUG_INFO,"VideoiMX6DxeInitialize - Allocate frame buffer\r\n"));
+    // To allocate frame buffer dynamically, there isn`t a built in graphic memory
+    // manager for UEFI, so we are allocating frame buffer manually. Currently only
+    // support single display, so allocate single(1) frame buffer
+    {
+        // Allocate frame buffer
+        DisplayContextPtr->DisplayConfig.DisplaySurface[0].Width =
+            DisplayContextPtr->DIContext[DisplayDevice].PreferedTiming.HActive;
+        DisplayContextPtr->DisplayConfig.DisplaySurface[0].Height =
+            DisplayContextPtr->DIContext[DisplayDevice].PreferedTiming.VActive;
+        DisplayContextPtr->DisplayConfig.DisplaySurface[0].Bpp =
+            DisplayContextPtr->DIContext[DisplayDevice].PreferedTiming.Bpp;
+        DisplayContextPtr->DisplayConfig.DisplaySurface[0].PixelFormat =
+            DisplayContextPtr->DIContext[DisplayDevice].PreferedTiming.PixelFormat;
+
+        // iMX6 UEFI reserves display memory for fullHD buffer size.
+        // PcdFrameBufferSize=800000h or 8388608 bytes - 1920x1080x4 bytes
+        // to prevent larger displays overrun our reserved memory size, cap display resolution to fullHD
+        // NOTE: for displays which do not have supported 1920x1080 mode may cause poor or missing picture
+
+        RequestedDisplayMemorySize=DisplayContextPtr->DisplayConfig.DisplaySurface[0].Width *
+            DisplayContextPtr->DisplayConfig.DisplaySurface[0].Height *
+            (DisplayContextPtr->DisplayConfig.DisplaySurface[0].Bpp/8);
+
+        DEBUG((DEBUG_INFO,"VideoiMX6DxeInitialize: Display Memory: Needed=%d, Available=%d\r\n",RequestedDisplayMemorySize,
+            ReservedDisplayMemorySize));
+
+        if (RequestedDisplayMemorySize > ReservedDisplayMemorySize) {
+            DEBUG((DEBUG_INFO,"VideoiMX6DxeInitialize WARNING. Display resolution needs more video memory than reserved by %d bytes\r\n",
+                RequestedDisplayMemorySize - ReservedDisplayMemorySize));
+            DEBUG((DEBUG_ERROR,"VideoiMX6DxeInitialize - display horizontal resolution too big. Cap to HD 1080p\r\n"));
+
+            DisplayContextPtr->DisplayConfig.DisplaySurface[0].Width = FullHDTiming.HActive;
+            DisplayContextPtr->DisplayConfig.DisplaySurface[0].Height = FullHDTiming.VActive;
+            DisplayContextPtr->DisplayConfig.DisplaySurface[0].Bpp = FullHDTiming.Bpp;
+
+             OS_MEM_COPY(&DisplayContextPtr->DIContext[DisplayDevice].PreferedTiming,
+                    &FullHDTiming, sizeof(DISPLAY_TIMING));
+        }
+
+        DEBUG((DEBUG_INFO,"VideoiMX6DxeInitialize - allocating frame buffer... \r\n"));
+        status = AllocateFrameBuffer(
+            &DisplayContextPtr->DisplayConfig.DisplaySurface[0]);
+        if (EFI_ERROR(status)) {
+            DEBUG(
+                (DEBUG_ERROR,
+                "VideoiMX6DxeInitialize: Fail to allocate fb, status=%r\n",
+                status));
+            goto Exit;
+        };
+
+        DEBUG((DEBUG_INFO,"VideoiMX6DxeInitialize - Initialize the frame buffer to black\r\n"));
+        // Initialize the frame buffer to black
+        SetMem32(
+            (void*)DisplayContextPtr->DisplayConfig.DisplaySurface[0].PhyAddr,
+            DisplayContextPtr->DisplayConfig.DisplaySurface[0].Width *
+                DisplayContextPtr->DisplayConfig.DisplaySurface[0].Height * 4,
+            0xFF000000);
+
+    }
+
+    DEBUG((DEBUG_INFO,"VideoiMX6DxeInitialize - set the display configuration to single HDMI mode\r\n"));
+    // Set the display configuration to single HDMI/LVDS mode
+    {
+        DISPLAY_INTERFACE displayInterfaceOrder[MAX_DISPLAY] = {
+            DisplayDevice,
+            NO_DISPLAY,
+            NO_DISPLAY,
+            NO_DISPLAY,
+        };
+
+        DisplayContextPtr->DisplayConfig.DisplayTiming[0] =
+            DisplayContextPtr->DIContext[DisplayDevice].PreferedTiming;
+
+        status = ApplyDisplayConfig(
+            DisplayContextPtr,
+            SINGLE_MODE,
+            displayInterfaceOrder);
+        if (EFI_ERROR(status)) {
+            DEBUG(
+                (DEBUG_ERROR,
+                "VideoiMX6DxeInitialize: Fail to set display. Exit status=%r\n",
+                status));
+            goto Exit;
+        }
+    }
+
+    g_VidGopModeInfo.Version = 0;
+    g_VidGopModeInfo.HorizontalResolution =
+        DisplayContextPtr->DisplayConfig.DisplayTiming[0].HActive;
+    g_VidGopModeInfo.VerticalResolution =
+        DisplayContextPtr->DisplayConfig.DisplayTiming[0].VActive;
+    g_VidGopModeInfo.PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
+
+    OS_ZERO_MEM(
+        &g_VidGopModeInfo.PixelInformation,
+        sizeof(g_VidGopModeInfo.PixelInformation));
+
+    g_VidGopModeInfo.PixelsPerScanLine = g_VidGopModeInfo.HorizontalResolution;
+    g_VidGopMode.MaxMode = 1;
+    g_VidGopMode.Mode = 0;
+    g_VidGopMode.Info = &g_VidGopModeInfo;
+    g_VidGopMode.SizeOfInfo = sizeof(g_VidGopModeInfo);
+    g_VidGopMode.FrameBufferBase =
+        (EFI_PHYSICAL_ADDRESS)
+            DisplayContextPtr->DisplayConfig.DisplaySurface[0].PhyAddr;
+    g_VidGopMode.FrameBufferSize =
+        g_VidGopModeInfo.HorizontalResolution *
+            g_VidGopModeInfo.VerticalResolution *
+            (DisplayContextPtr->DisplayConfig.DisplaySurface[0].Bpp / 8);
+
+    DisplayContextPtr->DisplayConfig.OsHandle[0] = (UINT32)&ImageHandle;
+
+    status = gBS->InstallMultipleProtocolInterfaces(
+        &ImageHandle,
+        &gEfiGraphicsOutputProtocolGuid,
+        &g_VidGop,
+        &gEfiDevicePathProtocolGuid,
+        &g_VidDevicePath,
+        NULL);
+    if (EFI_ERROR(status)) {
+        DEBUG(
+            (DEBUG_ERROR,
+            "VideoiMX6DxeInitialize: Fail to install protocol, status=%r\n",
+            status));
+        goto Exit;
+    }
+
+Exit:
+    DEBUG((DEBUG_INFO,"--VideoiMX6DxeInitialize()=%Xh\r\n",status));
+    return status;
+}
+
+//---------------------------------------------------------------- GOP routines.
+
+EFI_STATUS
+EFIAPI
+VidGopQueryMode (
+    IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+    IN UINT32 ModeNumber,
+    OUT UINTN *SizeOfInfo,
+    OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
+    )
+{
+    EFI_STATUS status;
+    EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *outputMode;
+
+    if (FeaturePcdGet(PcdLvdsEnable)) {
+        DisplayDevice = LVDS0_DISPLAY;
+    } else {
+        DisplayDevice = HDMI_DISPLAY;
+    }
+
+
+    g_EdidDiscovered.SizeOfEdid =
+        DisplayContextPtr->DIContext[DisplayDevice].EdidDataSize;
+    g_EdidDiscovered.Edid =
+        DisplayContextPtr->DIContext[DisplayDevice].EdidData;
+    g_EdidActive.SizeOfEdid =
+        DisplayContextPtr->DIContext[DisplayDevice].EdidDataSize;
+    g_EdidActive.Edid =
+        DisplayContextPtr->DIContext[DisplayDevice].EdidData;
+
+    status = gBS->InstallMultipleProtocolInterfaces(
+        (EFI_HANDLE)DisplayContextPtr->DisplayConfig.OsHandle[0],
+        &gEfiEdidDiscoveredProtocolGuid,
+        &g_EdidDiscovered,
+        &gEfiEdidActiveProtocolGuid,
+        &g_EdidActive,
+        NULL);
+    if (EFI_ERROR(status)) {
+        DEBUG(
+            (DEBUG_ERROR,
+            "Fail to install EDID discover and active protocol status=%r\n",
+            status));
+    }
+
+    if (ModeNumber != 0) {
+        DEBUG((DEBUG_ERROR, "VidGopQueryMode: Saw request to query mode %d\n", ModeNumber));
+        status = EFI_INVALID_PARAMETER;
+        goto Exit;
+    }
+
+    outputMode = (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *)
+        AllocatePool (sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION));
+    if (outputMode == NULL) {
+        status = EFI_OUT_OF_RESOURCES;
+        goto Exit;
+    }
+
+    outputMode->Version = 0;
+    outputMode->HorizontalResolution = g_VidGopModeInfo.HorizontalResolution;
+    outputMode->VerticalResolution = g_VidGopModeInfo.VerticalResolution;
+    outputMode->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
+
+    outputMode->PixelsPerScanLine = g_VidGopModeInfo.HorizontalResolution;
+    *SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
+    *Info = outputMode;
+
+    status = EFI_SUCCESS;
+
+Exit:
+    return status;
+}
+
+EFI_STATUS
+VidGopSetMode (
+    IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+    IN UINT32 ModeNumber
+    )
+{
+    OS_STATUS status;
+
+    if (ModeNumber != 0) {
+        DEBUG((DEBUG_ERROR, "VidGopSetMode: Saw request to set mode to %d\n", ModeNumber));
+        status = OS_STATUS_UNSUPPORTED;
+        goto Exit;
+    }
+
+    status = OS_STATUS_SUCCESS;
+
+Exit:
+    return status;
+}
+
+EFI_STATUS
+VidGopBlt (
+    IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+    IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
+    IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+    IN UINTN SourceX,
+    IN UINTN SourceY,
+    IN UINTN DestinationX,
+    IN UINTN DestinationY,
+    IN UINTN Width,
+    IN UINTN Height,
+    IN UINTN Delta OPTIONAL
+    )
+{
+    UINT32 *frameBuffer;
+    UINT32 frameWidth;
+    UINT32 frameOffset;
+    UINT32 bufferOffset;
+    UINT32 bufferWidth;
+    UINT32 i;
+
+    frameBuffer = (UINT32 *) (UINTN) g_VidGopMode.FrameBufferBase;
+    frameWidth = g_VidGopModeInfo.HorizontalResolution;
+
+    if (Delta == 0) {
+        bufferWidth = Width;
+    } else {
+        bufferWidth = Delta / PIXEL_BYTES;
+    }
+
+    if (BltOperation == EfiBltVideoFill) {
+
+        frameOffset = frameWidth * DestinationY + DestinationX;
+        for (i = DestinationY; i < DestinationY + Height; i++) {
+            SetMem32(frameBuffer + frameOffset,
+                     Width * PIXEL_BYTES,
+                     *(UINT32 *)BltBuffer
+                     );
+            frameOffset += frameWidth;
+        }
+    } else if (BltOperation == EfiBltVideoToBltBuffer) {
+
+        frameOffset = frameWidth * SourceY + SourceX;
+        bufferOffset = bufferWidth * DestinationY + DestinationX;
+
+        for (i = SourceY; i < SourceY + Height; i++) {
+            CopyMem(BltBuffer + bufferOffset,
+                    frameBuffer + frameOffset,
+                    Width * PIXEL_BYTES);
+            frameOffset += frameWidth;
+            bufferOffset += bufferWidth;
+        }
+    } else if (BltOperation == EfiBltBufferToVideo) {
+
+        frameOffset = frameWidth * DestinationY + DestinationX;
+        bufferOffset = bufferWidth * SourceY + SourceX;
+
+        for (i = SourceY; i < SourceY + Height; i++) {
+            CopyMem(frameBuffer + frameOffset,
+                    BltBuffer + bufferOffset,
+                    Width * PIXEL_BYTES);
+            frameOffset += frameWidth;
+            bufferOffset += bufferWidth;
+        }
+
+    } else if (BltOperation == EfiBltVideoToVideo) {
+
+        frameOffset = frameWidth * DestinationY + DestinationX;
+        bufferOffset = frameWidth * SourceY + SourceX;
+
+        for (i = SourceY; i < SourceY + Height; i++) {
+            CopyMem(frameBuffer + frameOffset,
+                    frameBuffer + bufferOffset,
+                    Width * PIXEL_BYTES);
+            frameOffset += frameWidth;
+            bufferOffset += frameWidth;
+        }
+
+    } else {
+        DEBUG((DEBUG_ERROR, "VideoDxe:VidGopBlt not impl %d\n", BltOperation));
+        return EFI_INVALID_PARAMETER;
+    }
+
+    return EFI_SUCCESS;
+}
-- 
2.16.2.gvfs.1.33.gf5370f1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH edk2-platforms 13/13] Silicon/NXP: Add i.MX6 common dsc and fdf files
  2018-07-20  6:33 [PATCH edk2-platforms 00/13] Silicon/NXP: Import NXP i.MX6 Package Chris Co
                   ` (11 preceding siblings ...)
  2018-07-20  6:34 ` [PATCH edk2-platforms 12/13] Silicon/NXP: Add i.MX6 GOP driver Chris Co
@ 2018-07-20  6:34 ` Chris Co
  12 siblings, 0 replies; 14+ messages in thread
From: Chris Co @ 2018-07-20  6:34 UTC (permalink / raw)
  To: edk2-devel@lists.01.org; +Cc: Ard Biesheuvel, Leif Lindholm, Michael D Kinney

This adds the common dsc and fdf definitions for NXP i.MX6 platforms.
Platform dsc definitions will define $(BOARD_NAME), $(IMX_FAMILY),
$(IMX_CHIP_TYPE), $(DRAM_SIZE), and $(BOARD_DIR) to indicate
i.MX SoC family and board-specific configurations.

Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Christopher Co <christopher.co@microsoft.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Leif Lindholm <leif.lindholm@linaro.org>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
---
 Silicon/NXP/iMX6Pkg/iMX6CommonDsc.inc | 918 ++++++++++++++++++++
 Silicon/NXP/iMX6Pkg/iMX6CommonFdf.inc | 385 ++++++++
 Silicon/NXP/iMX6Pkg/iMX6ConfigDsc.inc | 115 +++
 3 files changed, 1418 insertions(+)

diff --git a/Silicon/NXP/iMX6Pkg/iMX6CommonDsc.inc b/Silicon/NXP/iMX6Pkg/iMX6CommonDsc.inc
new file mode 100644
index 000000000000..b82ce2d2c975
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/iMX6CommonDsc.inc
@@ -0,0 +1,918 @@
+## @file
+#
+#  Copyright (c) Microsoft Corporation. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+################################################################################
+#
+# [Defines] Section
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = iMX6
+  PLATFORM_GUID                  = F01954EE-8AC4-45BC-80E5-511EAE64C38C
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x00010019
+  OUTPUT_DIRECTORY               = Build/$(BOARD_NAME)
+  SUPPORTED_ARCHITECTURES        = ARM
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+
+!include Silicon/NXP/iMX6Pkg/iMX6ConfigDsc.inc
+
+################################################################################
+#
+# [BuildOptions] Section
+#
+################################################################################
+[BuildOptions]
+  GCC:*_*_*_CC_FLAGS = -D$(BOARD_NAME) -DCPU_$(IMX_FAMILY) -Wno-unused-local-typedefs
+  GCC:*_*_*_OBJCOPY_PATH = noop
+  GCC:*_*_*_SYMRENAME_PATH = noop
+  *_*_*_ASL_PATH == asl.exe
+  *_*_*_ASL_FLAGS == /MsftInternal
+  *_*_*_ASL_OUTFLAGS == /Fo=
+
+# CPU_* compiler flag is used to select constants for iMX6.h
+
+[BuildOptions.common.EDKII.DXE_CORE,BuildOptions.common.EDKII.DXE_DRIVER,BuildOptions.common.EDKII.UEFI_DRIVER,BuildOptions.common.EDKII.UEFI_APPLICATION]
+  GCC:*_*_*_DLINK_FLAGS = -z common-page-size=0x1000
+
+[BuildOptions.common.EDKII.DXE_RUNTIME_DRIVER]
+  GCC:*_*_ARM_DLINK_FLAGS = -z common-page-size=0x1000
+
+################################################################################
+#
+# [LibraryClasses] Sections
+#
+# When parsing the DSC file, the precedence rules will followed.
+#  1. If a Library Class Instance (INF) is specified in the EDK II [Components] section
+#     (INF files <LibraryClasses> sub-section,) then it will be used.
+#  2. If not specified in the [Components] section, then the Library Class Instance that is
+#     defined in the [LibraryClasses.$(ARCH).$(MODULE_TYPE)] section will be used.
+#  3. If not specified in the [LibraryClasses.$(ARCH).$(MODULE_TYPE)] section, then
+#     the Library Class Instance that is defined in the
+#     [LibraryClasses.Common.$(MODULE_TYPE)] section will be used.
+#  4. If not specified in the [LibraryClasses.Common.$(MODULE_TYPE)] section, then
+#     the Library Class Instance that is defined in the [LibraryClasses.$(ARCH)] section
+#     will be used.
+#  5. If not specified in the [LibraryClasses.$(ARCH)] section, then the Library Class
+#     Instance that is defined in the [LibraryClasses] Section or
+#     [LibraryClasses.Common] section will be used.
+#  6. It is an error if it has not been specified in one of the above sections
+#
+################################################################################
+
+[LibraryClasses.common]
+  #
+  # CPU and Timing
+  #
+  ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
+  ArmMmuLib|ArmPkg/Library/ArmMmuLib/ArmMmuBaseLib.inf
+  ArmPlatformLib|$(BOARD_DIR)/Library/iMX6BoardLib/iMX6BoardLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  ArmSmcLib|ArmPkg/Library/ArmSmcLib/ArmSmcLib.inf
+  CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+  ArmDisassemblerLib|ArmPkg/Library/ArmDisassemblerLib/ArmDisassemblerLib.inf
+  UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
+  RealTimeClockLib|Silicon/NXP/iMXPlatformPkg/Library/VirtualRealTimeClockLib/VirtualRealTimeClockLib.inf
+  DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
+  CpuExceptionHandlerLib|ArmPkg/Library/ArmExceptionLib/ArmExceptionLib.inf
+  TimerLib|Silicon/NXP/iMX6Pkg/Library/TimerLib/TimerLib.inf
+
+  #
+  # Memory
+  #
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+  DmaLib|EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+
+  #
+  # Platform
+  #
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+  ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
+  EfiResetSystemLib|ArmPkg/Library/ArmPsciResetSystemLib/ArmPsciResetSystemLib.inf
+
+  #
+  # Peripherals
+  #
+  UefiUsbLib|MdePkg/Library/UefiUsbLib/UefiUsbLib.inf
+  PciLib|MdePkg/Library/BasePciLibCf8/BasePciLibCf8.inf
+  NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
+
+  #
+  # UEFI Services and Runtime
+  #
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
+
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+
+  PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
+
+  #
+  # Human Interface Infrastructure (HII)
+  #
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
+
+  #
+  # BDS
+  #
+  BootLogoLib|MdeModulePkg/Library/BootLogoLib/BootLogoLib.inf
+  UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
+  PlatformBootManagerLib|ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+  FdtLib|EmbeddedPkg/Library/FdtLib/FdtLib.inf
+  CustomizedDisplayLib|MdeModulePkg/Library/CustomizedDisplayLib/CustomizedDisplayLib.inf
+
+  #
+  # Shell
+  #
+  ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
+  SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
+
+  #
+  # Serial, Console and Debugging
+  #
+  DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+  SerialPortLib|Silicon/NXP/iMXPlatformPkg/Library/UartSerialPortLib/UartSerialPortLib.inf
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+
+  # Enable debug prints in both release and debug builds
+  DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
+  DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
+  #
+  # The Standard IO window in the debugger will show load and unload events for symbols.
+  #
+!if $(CONFIG_DUMP_SYMBOL_INFO) == TRUE
+  PeCoffExtraActionLib|Platform/Microsoft/Library/LauterbachPeCoffExtraActionLib/LauterbachPeCoffExtraActionLib.inf
+!else
+  PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+!endif
+
+  #
+  # Display
+  #
+  iMXDisplayLib|Silicon/NXP/iMXPlatformPkg/Library/iMXDisplayLib/iMXDisplayLib.inf
+
+  #
+  # Security
+  #
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+  Tcg2PhysicalPresenceLib|SecurityPkg/Library/DxeTcg2PhysicalPresenceLib/DxeTcg2PhysicalPresenceLib.inf
+  Tcg2PpVendorLib|SecurityPkg/Library/Tcg2PpVendorLibNull/Tcg2PpVendorLibNull.inf
+
+  #
+  # iMX6 Specifics
+  #
+  iMXIoMuxLib|Silicon/NXP/iMX6Pkg/Library/iMX6IoMuxLib/iMX6IoMuxLib.inf
+  iMX6ClkPwrLib|Silicon/NXP/iMX6Pkg/Library/iMX6ClkPwrLib/iMX6ClkPwrLib.inf
+  iMX6UsbPhyLib|Silicon/NXP/iMX6Pkg/Library/iMX6UsbPhyLib/iMX6UsbPhyLib.inf
+
+[LibraryClasses.ARM]
+  #
+  # It is not possible to prevent the ARM compiler for generic intrinsic functions.
+  # This library provides the instrinsic functions generate by a given compiler.
+  # [LibraryClasses.ARM] and NULL mean link this library into all ARM images.
+  #
+  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+
+[LibraryClasses.common.SEC]
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
+  ArmGicArchLib|ArmPkg/Library/ArmGicArchSecLib/ArmGicArchSecLib.inf
+  ArmPlatformStackLib|ArmPlatformPkg/Library/ArmPlatformStackLib/ArmPlatformStackLib.inf
+  ExtractGuidedSectionLib|EmbeddedPkg/Library/PrePiExtractGuidedSectionLib/PrePiExtractGuidedSectionLib.inf
+  HobLib|EmbeddedPkg/Library/PrePiHobLib/PrePiHobLib.inf
+  LzmaDecompressLib|MdeModulePkg/Library/LzmaCustomDecompressLib/LzmaCustomDecompressLib.inf
+  MemoryAllocationLib|EmbeddedPkg/Library/PrePiMemoryAllocationLib/PrePiMemoryAllocationLib.inf
+  MemoryInitPeiLib|ArmPlatformPkg/MemoryInitPei/MemoryInitPeiLib.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  PerformanceLib|MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
+  PlatformPeiLib|ArmPlatformPkg/PlatformPei/PlatformPeiLib.inf
+  PrePiHobListPointerLib|ArmPlatformPkg/Library/PrePiHobListPointerLib/PrePiHobListPointerLib.inf
+  PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+  DefaultExceptionHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLibBase.inf
+
+[LibraryClasses.common.PEI_CORE]
+  PcdLib|MdePkg/Library/PeiPcdLib/PeiPcdLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/PeiExtractGuidedSectionLib/PeiExtractGuidedSectionLib.inf
+  MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+  ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
+
+[LibraryClasses.common.DXE_CORE]
+  DxeCoreEntryPoint|MdePkg/Library/DxeCoreEntryPoint/DxeCoreEntryPoint.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+  HobLib|MdePkg/Library/DxeCoreHobLib/DxeCoreHobLib.inf
+  MemoryAllocationLib|MdeModulePkg/Library/DxeCoreMemoryAllocationLib/DxeCoreMemoryAllocationLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxeCorePerformanceLib/DxeCorePerformanceLib.inf
+
+[LibraryClasses.common.DXE_DRIVER]
+  ArmGicLib|ArmPkg/Drivers/ArmGic/ArmGicLib.inf
+  ArmGicArchLib|ArmPkg/Library/ArmGicArchLib/ArmGicArchLib.inf
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+  DmaLib|EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  PlatformBootManagerLib|ArmPkg/Library/PlatformBootManagerLib/PlatformBootManagerLib.inf
+  SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
+  ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
+
+!if $(CONFIG_OPTEE) == TRUE
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+  HashLib|SecurityPkg/Library/HashLibBaseCryptoRouter/HashLibBaseCryptoRouterDxe.inf
+  Tpm2CommandLib|SecurityPkg/Library/Tpm2CommandLib/Tpm2CommandLib.inf
+!endif
+
+[LibraryClasses.common.UEFI_APPLICATION]
+  PcdLib|MdePkg/Library/DxePcdLib/DxePcdLib.inf
+  FileExplorerLib|MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+  UefiDecompressLib|IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
+  IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  ArmSoftFloatLib|ArmPkg/Library/ArmSoftFloatLib/ArmSoftFloatLib.inf
+
+!if $(CONFIG_OPTEE) == TRUE
+  BaseCryptLib|CryptoPkg/Library/BaseCryptLib/BaseCryptLib.inf
+  OpensslLib|CryptoPkg/Library/OpensslLib/OpensslLib.inf
+!endif
+
+[LibraryClasses.common.UEFI_DRIVER]
+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+  UefiDecompressLib|IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
+  ExtractGuidedSectionLib|MdePkg/Library/DxeExtractGuidedSectionLib/DxeExtractGuidedSectionLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+
+[LibraryClasses.common.DXE_RUNTIME_DRIVER]
+  HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  ReportStatusCodeLib|IntelFrameworkModulePkg/Library/DxeReportStatusCodeLibFramework/DxeReportStatusCodeLib.inf
+  CapsuleLib|MdeModulePkg/Library/DxeCapsuleLibNull/DxeCapsuleLibNull.inf
+  PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  PerformanceLib|MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
+
+!if $(CONFIG_OPTEE) == TRUE
+!if $(CONFIG_MEASURED_BOOT) == TRUE
+  TpmMeasurementLib|SecurityPkg/Library/DxeTpmMeasurementLib/DxeTpmMeasurementLib.inf
+!endif
+!endif
+
+################################################################################
+#
+# PCD Sections
+#
+################################################################################
+
+########################
+#
+# ArmPkg PCDs
+#
+########################
+[PcdsFeatureFlag.common]
+  #
+  # Use the Vector Table location in CpuDxe. We will not copy the Vector Table at
+  # PcdCpuVectorBaseAddress
+  #
+  gArmTokenSpaceGuid.PcdRelocateVectorTable|FALSE
+
+[PcdsFixedAtBuild.common]
+  gArmTokenSpaceGuid.PcdTrustzoneSupport|FALSE
+  gArmTokenSpaceGuid.PcdVFPEnabled|1
+
+  #
+  # ARM General Interrupt Controller settings
+  #
+  gArmTokenSpaceGuid.PcdGicDistributorBase|0x00A01000
+  gArmTokenSpaceGuid.PcdGicInterruptInterfaceBase|0x00A00100
+  gArmTokenSpaceGuid.PcdArmPrimaryCore|0x000
+
+  #
+  # ARM L2x0 PCDs
+  #
+  #gArmTokenSpaceGuid.PcdL2x0ControllerBase|0x00A02000
+
+  #
+  # GPT Timer Frequency
+  # Set to 1KHz, which equals to 1us resolution
+  #
+  gArmTokenSpaceGuid.PcdArmArchTimerFreqInHz|1000000
+
+########################
+#
+# ArmPlatformPkg PCDs
+#
+########################
+[PcdsFixedAtBuild.common]
+  # Size of the region used by UEFI in permanent memory (Reserved 16MB)
+  gArmPlatformTokenSpaceGuid.PcdSystemMemoryUefiRegionSize|0x01000000
+
+!if $(IMX_FAMILY) == IMX6SX
+  #
+  # Refer to the detailed memory map at OpteeClientPkg PCDs section below
+  #
+  gArmTokenSpaceGuid.PcdSystemMemoryBase|0x829D4000
+  !if $(DRAM_SIZE) == DRAM_512MB
+  #
+  # Board DDR starts at 0x80000000 and ends 0x9FFF0000 (512MB)
+  # SystemMemorySize is 0x9FFF0000 - PcdSystemMemoryBase
+  #
+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x1D61C000
+  !elseif $(DRAM_SIZE) == DRAM_1GB
+  #
+  # Board DDR starts at 0x80000000 and ends 0xBFFF0000 (1GB)
+  # SystemMemorySize is 0xBFFF0000 - PcdSystemMemoryBase
+  #
+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x3D61C000
+  !else
+  #
+  # Board DDR starts at 0x80000000 and ends 0xFFFF0000 (2GB)
+  # SystemMemorySize is 0xFFFF0000 - PcdSystemMemoryBase
+  #
+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x7D61C000
+  !endif
+!else
+  gArmTokenSpaceGuid.PcdSystemMemoryBase|0x12A00000
+
+  !if $(DRAM_SIZE) == DRAM_512MB
+  #
+  # Board DDR starts at 0x10000000 and ends 0x2FFF0000 (512MB)
+  # SystemMemorySize is 0x2FFF0000 - PcdSystemMemoryBase
+  #
+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x1D5F0000
+  !elseif $(DRAM_SIZE) == DRAM_1GB
+  #
+  # Board DDR starts at 0x10000000 and ends 0x4FFF0000 (1GB)
+  # SystemMemorySize is 0x4FFF0000 - PcdSystemMemoryBase
+  #
+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x3D5F0000
+  !else
+  #
+  # Board DDR starts at 0x10000000 and ends 0x8FFF0000 (2GB)
+  # SystemMemorySize is 0x8FFF0000 - PcdSystemMemoryBase
+  #
+  gArmTokenSpaceGuid.PcdSystemMemorySize|0x7D5F0000
+  !endif
+!endif
+
+!if $(CONFIG_MPCORE) == TRUE
+  !if $(IMX_CHIP_TYPE) == QUAD
+  gArmPlatformTokenSpaceGuid.PcdCoreCount|4
+  !elseif (($(IMX_CHIP_TYPE) == DUAL) || ($(IMX_CHIP_TYPE) == DUALLITE))
+  gArmPlatformTokenSpaceGuid.PcdCoreCount|2
+  !else
+  gArmPlatformTokenSpaceGuid.PcdCoreCount|1
+  !endif
+!else
+  gArmPlatformTokenSpaceGuid.PcdCoreCount|1
+!endif
+
+########################
+#
+# MdePkg PCDs
+#
+########################
+[PcdsFeatureFlag.common]
+  gEfiMdePkgTokenSpaceGuid.PcdComponentNameDisable|TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnosticsDisable|TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdComponentName2Disable|TRUE
+  gEfiMdePkgTokenSpaceGuid.PcdDriverDiagnostics2Disable|TRUE
+
+[PcdsFixedAtBuild.common]
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumUnicodeStringLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength|1000000
+  gEfiMdePkgTokenSpaceGuid.PcdSpinLockTimeout|10000000
+  gEfiMdePkgTokenSpaceGuid.PcdDebugClearMemoryValue|0xAF
+  gEfiMdePkgTokenSpaceGuid.PcdPostCodePropertyMask|0
+  gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|320
+  gEfiMdePkgTokenSpaceGuid.PcdPerformanceLibraryPropertyMask|1
+
+  #
+  # DEBUG_ASSERT_ENABLED       0x01
+  # DEBUG_PRINT_ENABLED        0x02
+  # DEBUG_CODE_ENABLED         0x04
+  # CLEAR_MEMORY_ENABLED       0x08
+  # ASSERT_BREAKPOINT_ENABLED  0x10
+  # ASSERT_DEADLOOP_ENABLED    0x20
+  #
+  !if $(TARGET) == RELEASE
+    gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x23
+  !else
+    gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f
+  !endif
+
+  #
+  # Debug Flags as defined in DebugLib.h
+  #
+  # DEBUG_INIT      0x00000001  // Initialization
+  # DEBUG_WARN      0x00000002  // Warnings
+  # DEBUG_LOAD      0x00000004  // Load events
+  # DEBUG_FS        0x00000008  // EFI File system
+  # DEBUG_POOL      0x00000010  // Alloc & Free (pool)
+  # DEBUG_PAGE      0x00000020  // Alloc & Free (page)
+  # DEBUG_INFO      0x00000040  // Informational debug messages
+  # DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
+  # DEBUG_VARIABLE  0x00000100  // Variable
+  # DEBUG_BM        0x00000400  // Boot Manager
+  # DEBUG_BLKIO     0x00001000  // BlkIo Driver
+  # DEBUG_NET       0x00004000  // Network Io Driver
+  # DEBUG_UNDI      0x00010000  // UNDI Driver
+  # DEBUG_LOADFILE  0x00020000  // LoadFile
+  # DEBUG_TEEC      0x00040000  // TEE Client Tracings
+  # DEBUG_EVENT     0x00080000  // Event messages
+  # DEBUG_GCD       0x00100000  // Global Coherency Database changes
+  # DEBUG_CACHE     0x00200000  // Memory range cachability changes
+  # DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
+  #                             // significantly impact boot performance
+  # DEBUG_ERROR     0x80000000  // Error
+  #
+  # By default only enable init, error, warning and load debug prints to minimize
+  # debug messages. Use "0x8FEF4DCF" for detailed debugging purposes.
+  #
+!if $(TARGET) == RELEASE
+  #
+  # In release builds enable error, warning, and load (base and entry point)
+  #
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel| 0x80000006
+!else
+  #
+  # In debug builds enable error, cache, info, load, warn, and init
+  #
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel| 0x80000047
+!endif
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+  gEfiMdePkgTokenSpaceGuid.PcdPlatformBootTimeOut|0
+
+########################
+#
+# MdeModulePkg PCDs
+#
+########################
+[PcdsFeatureFlag.common]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdTurnOffUsbLegacySupport|TRUE
+
+  ## If TRUE, Graphics Output Protocol will be installed on virtual handle created by ConsplitterDxe.
+  #  It could be set FALSE to save size.
+  gEfiMdeModulePkgTokenSpaceGuid.PcdConOutGopSupport|TRUE
+
+[PcdsFixedAtBuild.common]
+  gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x2000
+  gEfiMdePkgTokenSpaceGuid.PcdDefaultTerminalType|4
+  gEfiMdeModulePkgTokenSpaceGuid.PcdResetOnMemoryTypeInformationChange|FALSE
+  # GUID of the UI app
+  gEfiMdeModulePkgTokenSpaceGuid.PcdBootManagerMenuFile|{ 0x21, 0xaa, 0x2c, 0x46, 0x14, 0x76, 0x03, 0x45, 0x83, 0x6e, 0x8a, 0xb6, 0xf4, 0x66, 0x23, 0x31 }
+
+[PcdsPatchableInModule]
+  # Console Resolution
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoHorizontalResolution|1920
+  gEfiMdeModulePkgTokenSpaceGuid.PcdVideoVerticalResolution|1080
+
+########################
+#
+# EmbeddedPkg PCDs
+#
+########################
+[PcdsFeatureFlag.common]
+  gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|TRUE
+
+[PcdsFixedAtBuild.common]
+  #
+  # Optional feature to help prevent EFI memory map fragments
+  # Turned on and off via: PcdPrePiProduceMemoryTypeInformationHob
+  # Values are in EFI Pages (4K). DXE Core will make sure that
+  # at least this much of each type of memory can be allocated
+  # from a single memory range. This way you only end up with
+  # maximum of two fragements for each type in the memory map
+  # (the memory used, and the free memory that was prereserved
+  # but not used).
+  #
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIReclaimMemory|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiACPIMemoryNVS|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiReservedMemoryType|0
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesData|80
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiRuntimeServicesCode|40
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesCode|400
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiBootServicesData|3000
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderCode|10
+  gEmbeddedTokenSpaceGuid.PcdMemoryTypeEfiLoaderData|0
+
+  #
+  # Timer Configuration
+  #
+  # The timer period is configured in units of 100ns. We configure it for 10ms
+  # timer ticks which will be used mainly by DXE Core to keep track of system
+  # time and hence keep track of all events.
+  #
+  gEmbeddedTokenSpaceGuid.PcdTimerPeriod|100000
+
+########################
+#
+# IntelFrameworkModulePkg PCDs
+#
+########################
+[PcdsFixedAtBuild.common]
+  # GUID of the UEFI Shell
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile|{ 0x83, 0xA5, 0x04, 0x7C, 0x3E, 0x9E, 0x1C, 0x4F, 0xAD, 0x65, 0xE0, 0x52, 0x68, 0xD0, 0xB4, 0xD1 }
+
+########################
+#
+# OpteeClientPkg PCDs
+#
+########################
+[PcdsFixedAtBuild.common]
+!if $(IMX_FAMILY) == IMX6SX
+  #
+  # Reserved for TPM2 ACPI
+  # 0x82000000 - 0x82002FFF
+  #
+  gOpteeClientPkgTokenSpaceGuid.PcdTpm2AcpiBufferBase|0x82000000
+  gOpteeClientPkgTokenSpaceGuid.PcdTpm2AcpiBufferSize|0x3000
+
+  #
+  # iMX Plaform Memory Layout
+  #                                        PcdSystemMemoryBase
+  # +-------------------+===> (0x80000000) PcdTrustZonePrivateMemoryBase (OPTEE image base address)
+  # | TZ Private Memory |  ^
+  # | (OPTEE)           |  |  (0x01E00000) PcdTrustZonePrivateMemorySize 30MB
+  # |                   |  v
+  # +-------------------+===> (0x81E00000) PcdTrustZoneSharedMemoryBase (includes mobj bookkeeping page)
+  # | TZ Shared Memory  |  ^
+  # |                   |  |  (0x00200000) PcdTrustZoneSharedMemorySize 2MB
+  # |                   |  v
+  # +-------------------|===> (0x82000000) PcdTpm2AcpiBufferBase
+  # | TPM2 Control Area |  ^
+  # |                   |  |  (0x00003000) PcdTpm2AcpiBufferSize 12KB
+  # |                   |  v
+  # +-------------------+===> (0x82003000) PcdGlobalDataBaseAddress
+  # | Global Data       |  ^
+  # |                   |  |  (0x00001000) PcdGlobalDataSize 4KB
+  # |                   |  v
+  # +-------------------+===> (0x82004000) PcdFdBaseAddress (UEFI Load Address)
+  # | UEFI              |  ^
+  # |                   |  |  (0x001D0000) PcdFdSize 1856KB
+  # |                   |  v
+  # +-------------------+===> (0x821D4000) PcdFrameBufferBase
+  # | FrameBuffer       |  ^
+  # |                   |  |  (0x00800000) PcdFrameBufferSize 8MB
+  # |                   |  v
+  # +-------------------+===> (0x829D4000)
+  # | Operating System  |  ^
+  # | Memory            |  |
+  # |                   |  |
+  # |                   |  v
+  # +------------------ +===>
+
+  DEFINE GLOBAL_DATA_BASE_ADDRESS = 0x82003000
+
+  gOpteeClientPkgTokenSpaceGuid.PcdTrustZonePrivateMemoryBase|0x80000000
+  gOpteeClientPkgTokenSpaceGuid.PcdTrustZonePrivateMemorySize|0x01E00000
+
+  #
+  # TrustZone shared memory (2Mb)
+  # This memory is managed by the normal world but shared with the OpTEE OS.
+  # It must match OpTEE optee_os/core/arch/arm/plat-imx/platform_config.h:
+  #    CFG_SHMEM_START & CFG_SHMEM_SIZE
+  # NOTE: The first page of the SHMEM is owned by OPTEE for mobj bookkeeping
+  # and we should not touch it. We will skip the first 4K of SHMEM and take that
+  # into account for SHMEM size in PcdTrustZoneSharedMemorySize.
+  #
+  gOpteeClientPkgTokenSpaceGuid.PcdTrustZoneSharedMemoryBase|0x81E00000
+  gOpteeClientPkgTokenSpaceGuid.PcdTrustZoneSharedMemorySize|0x00200000
+
+  giMX6TokenSpaceGuid.PcdFrameBufferBase|0x821D4000
+
+!else
+  #
+  # Reserved for TPM2 ACPI
+  # 0x10814000 - 0x10816FFF
+  #
+  gOpteeClientPkgTokenSpaceGuid.PcdTpm2AcpiBufferBase|0x10814000
+  gOpteeClientPkgTokenSpaceGuid.PcdTpm2AcpiBufferSize|0x3000
+
+  #
+  # iMX Plaform Memory Layout
+  #
+  # +-------------------+===> (0x10000000) PcdFrameBufferBase (DDR Start Address)
+  # |Frame Buffer       |  ^
+  # |                   |  |  (0x00800000) PcdFrameBufferSize 8MB
+  # |                   |  v
+  # +-------------------+===
+  # |                   |     Gap
+  # +-------------------|===> (0x10814000) PcdTpm2AcpiBufferBase
+  # |TPM2 Control Area  |  ^
+  # |                   |  |  (0x3000) 12KB
+  # |                   |  v
+  # +-------------------+===> (0x10817000) PcdGlobalDataBaseAddress
+  # | Global Data       |  ^
+  # |                   |  |  (0x1000) PcdGlobalDataSize 4KB
+  # |                   |  v
+  # +-------------------+===
+  # | Gap               |
+  # +-------------------+===> (0x10820000) UEFI Load Address
+  # | UEFI              |  ^
+  # |                   |  |  (0x1D0000) 1920KB
+  # |                   |  v
+  # +-------------------+===> (0x10A00000) PcdTrustZonePrivateMemoryBase (OPTEE image base address)
+  # | TZ Private Memory |  ^
+  # | (OPTEE)           |  |  (0x1E00000) 30MB
+  # |                   |  v
+  # +-------------------+===> (0x12800000) PcdTrustZoneSharedMemoryBase (includes mobj bookkeeping page)
+  # | TZ Shared Memory  |  ^
+  # |                   |  |  (0x200000) 2MB
+  # |                   |  v
+  # +-------------------+===> (0x12A00000) PcdSystemMemoryBase
+  # | Operating System  |  ^
+  # | Memory            |  |  (0x3D5F0000) 982MB for 1GB DRAM OR
+  # |                   |  |  (0x7D5F0000) 2005MB for 2GB DRAM
+  # |                   |  v
+  # +------------------ +===
+  #
+  # Reserved for Optee private memory (31M)
+  # 0x10A00000 - 0x127FFFFF
+  #
+  # TrustZone private memory (?Mb OPTEE + ?Mb PSCI)
+  # 0x8E000000 - 8FEFFFFF
+  # This memory is managed privately by the OpTEE OS.
+  #    CFG_DDR_TEETZ_RESERVED_START & CFG_DDR_TEETZ_RESERVED_START
+  #
+
+  DEFINE GLOBAL_DATA_BASE_ADDRESS = 0x10817000
+
+  gOpteeClientPkgTokenSpaceGuid.PcdTrustZonePrivateMemoryBase|0x10A00000
+  gOpteeClientPkgTokenSpaceGuid.PcdTrustZonePrivateMemorySize|0x01E00000
+
+  #
+  # TrustZone shared memory (2Mb)
+  # 0x12800000 - 0x129FFFFF
+  # This memory is managed by the normal world but shared with the OpTEE OS.
+  # It must match OpTEE optee_os/core/arch/arm/plat-imx/platform_config.h:
+  #    CFG_SHMEM_START & CFG_SHMEM_SIZE
+  # NOTE: The first page of the SHMEM is owned by OPTEE for mobj bookkeeping
+  # and we should not touch it. We will skip the first 4K of SHMEM and take that
+  # into account for SHMEM size in PcdTrustZoneSharedMemorySize.
+  #
+  gOpteeClientPkgTokenSpaceGuid.PcdTrustZoneSharedMemoryBase|0x12800000
+  gOpteeClientPkgTokenSpaceGuid.PcdTrustZoneSharedMemorySize|0x00200000
+
+  giMX6TokenSpaceGuid.PcdFrameBufferBase|0x10000000
+
+!endif
+########################
+#
+# SecurityPkg PCDs
+#
+########################
+[PcdsFixedAtBuild.common]
+  #
+  # Override the default values from SecurityPkg to ensure images from all sources are verified in secure boot
+  #
+  gEfiSecurityPkgTokenSpaceGuid.PcdOptionRomImageVerificationPolicy|0x04
+  gEfiSecurityPkgTokenSpaceGuid.PcdFixedMediaImageVerificationPolicy|0x04
+  gEfiSecurityPkgTokenSpaceGuid.PcdRemovableMediaImageVerificationPolicy|0x04
+
+  #
+  # PcdTpmInstanceGuid tells the Tcg2 Driver which TPM version is being used.
+  # The below GUID is TPMv2 GUID.
+  #
+  gEfiSecurityPkgTokenSpaceGuid.PcdTpmInstanceGuid|{ 0x5a, 0xf2, 0x6b, 0x28, 0xc3, 0xc2, 0x8c, 0x40, 0xb3, 0xb4, 0x25, 0xe6, 0x75, 0x8b, 0x73, 0x17 }
+
+  ## Sets the default Physical Presence flags that are consumed by the PP TrEE library.
+  #
+  # Options are defined in TrEEPhysicalPresenceData.h
+  # Current setting:
+  #   TREE_FLAG_NO_PPI_CLEAR
+  #
+  #gEfiSecurityPkgTokenSpaceGuid.PcdPPDefaultTrEEFlags|0x02
+
+  ## Indicates whether or not the Tcg2Dxe should measure CRTM instead of PEI.
+  # TRUE means the Tcg2Dxe will measure CRTM.
+  #
+  #gEfiSecurityPkgTokenSpaceGuid.PcdLateMeasureCRTM|TRUE
+
+[PcdsDynamicExDefault.common.DEFAULT]
+  gEfiSecurityPkgTokenSpaceGuid.PcdTcg2HashAlgorithmBitmap|0x0
+
+########################
+#
+# MsPkg PCDs
+#
+########################
+[PcdsFixedAtBuild.common]
+
+  #
+  # SD first FAT partition device path:
+  # VenHw(AAFB8DAA-7340-43AC-8D49-0CCE14812489,03000000)/SD(0x0)/HD(1,MBR,0xAE420040,0x1000,0x20000)
+  #
+  # eMMC first FAT partition device path:
+  # VenHw(AAFB8DAA-7340-43AC-8D49-0CCE14812489,04000000)/eMMC(0x0)/HD(1,MBR,0xAE420040,0x1000,0x20000)
+  #
+  # Use the SDCard first FAT partition for logging and misc storage.
+  #
+  gMsPkgTokenSpaceGuid.PcdStorageMediaPartitionDevicePath|L"VenHw(AAFB8DAA-7340-43AC-8D49-0CCE14812489,03000000)/SD(0x0)/HD(1,MBR,0xAE420040,0x1000,0x20000)"
+
+!if $(CONFIG_SECURE_BOOT) == TRUE
+  gMsPkgTokenSpaceGuid.PcdSecureBootEnable|TRUE
+!else
+  gMsPkgTokenSpaceGuid.PcdSecureBootEnable|FALSE
+!endif
+
+########################
+#
+# iMXPlatformPkg PCDs
+#
+########################
+[PcdsFixedAtBuild.common]
+
+  # Global data area
+  giMXPlatformTokenSpaceGuid.PcdGlobalDataBaseAddress|$(GLOBAL_DATA_BASE_ADDRESS)
+  giMXPlatformTokenSpaceGuid.PcdGlobalDataSize|0x1000
+
+################################################################################
+#
+# [Components] Section
+#
+################################################################################
+[Components.common]
+
+  #
+  # SEC (PrePi)
+  #
+  ArmPlatformPkg/PrePi/PeiMPCore.inf
+
+  #
+  # DXE Core
+  #
+  MdeModulePkg/Core/Dxe/DxeMain.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DxeCrc32GuidedSectionExtractLib/DxeCrc32GuidedSectionExtractLib.inf
+  }
+  MdeModulePkg/Universal/PCD/Dxe/Pcd.inf {
+    <LibraryClasses>
+      PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+  }
+
+  #
+  # DXE required Architectural Protocols as defined by UEFI 2.6 specs
+  #
+  # BDS Arch Protocol
+  # CPU Arch Protocol
+  # Metronome Arch Protocol
+  # Real Time Clock Arch Protocol
+  # Reset Arch Protocol
+  # Runtime Arch Protocol
+  # Security Arch Protocol
+  # Timer Arch Protocol
+  # Variable Arch Protocol
+  # Variable Write Arch Protocol
+  # EFI Capsule Arch Protocol
+  # Watchdog Timer Arch Protocol
+  #
+
+  ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+  EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+  EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+  MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf {
+    <LibraryClasses>
+      NULL|SecurityPkg/Library/DxeImageVerificationLib/DxeImageVerificationLib.inf
+      NULL|SecurityPkg/Library/DxeTpm2MeasureBootLib/DxeTpm2MeasureBootLib.inf
+  }
+  Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/TimerDxe.inf
+  MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+  ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+  MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+
+  #
+  # Serial Console
+  #
+  MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+  EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
+  MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+
+  #
+  # Filesystem Stack
+  #
+  MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+  FatPkg/EnhancedFatDxe/Fat.inf
+  Platform/Microsoft/Drivers/SdMmcDxe/SdMmcDxe.inf
+  Silicon/NXP/iMXPlatformPkg/Drivers/SdhcDxe/SdhcDxe.inf
+
+  #
+  # PCIe support
+  #
+  Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.inf
+
+  #
+  # Display Support
+  #
+!if $(CONFIG_HEADLESS) == FALSE
+  MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  !if $(IMX_FAMILY) == IMX6SX
+    #
+    # Use board-specific GOP for SoloX
+    #
+    $(BOARD_DIR)/Drivers/GraphicsOutputDxe/GraphicsOutputDxe.inf
+  !else
+    Silicon/NXP/iMX6Pkg/Drivers/GOP/iMX6GOP.inf
+  !endif
+!endif
+
+  #
+  # ACPI Support
+  #
+  MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+  MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+  $(BOARD_DIR)/AcpiTables/AcpiTables.inf
+
+  #
+  # SMBIOS Support
+  #
+  $(BOARD_DIR)/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.inf
+  MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+
+  #
+  # Generic Bds
+  #
+  MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+  MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+  MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  MdeModulePkg/Application/UiApp/UiApp.inf {
+    <LibraryClasses>
+      NULL|MdeModulePkg/Library/DeviceManagerUiLib/DeviceManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootManagerUiLib/BootManagerUiLib.inf
+      NULL|MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerUiLib.inf
+  }
+
+  #
+  # Shell
+  #
+  ShellPkg/Application/Shell/Shell.inf {
+    <LibraryClasses>
+      ShellCommandLib|ShellPkg/Library/UefiShellCommandLib/UefiShellCommandLib.inf
+      BcfgCommandLib|ShellPkg/Library/UefiShellBcfgCommandLib/UefiShellBcfgCommandLib.inf
+      HandleParsingLib|ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf
+      NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellDriver1CommandsLib/UefiShellDriver1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel1CommandsLib/UefiShellLevel1CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellLevel3CommandsLib/UefiShellLevel3CommandsLib.inf
+      NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf
+      PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+
+    <PcdsFixedAtBuild>
+      gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0xFF
+      gEfiShellPkgTokenSpaceGuid.PcdShellLibAutoInitialize|FALSE
+      gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|8000
+  }
+
+MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
+
+#
+# Boilerplate for compiling UEFI applications and UEFI drivers with the
+# standard library.
+#
+!include StdLib/StdLib.inc
diff --git a/Silicon/NXP/iMX6Pkg/iMX6CommonFdf.inc b/Silicon/NXP/iMX6Pkg/iMX6CommonFdf.inc
new file mode 100644
index 000000000000..89a133158f08
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/iMX6CommonFdf.inc
@@ -0,0 +1,385 @@
+## @file
+#
+#  Copyright (c) Microsoft Corporation. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+################################################################################
+#
+# FD Section
+# The [FD] Section is made up of the definition statements and a
+# description of what goes into  the Flash Device Image.  Each FD section
+# defines one flash "device" image.  A flash device image may be one of
+# the following: Removable media bootable image (like a boot floppy
+# image,) an Option ROM image (that would be "flashed" into an add-in
+# card,) a System "Flash"  image (that would be burned into a system's
+# flash) or an Update ("Capsule") image that will be used to update and
+# existing system flash.
+#
+################################################################################
+
+
+[FD.iMXBoard_EFI]
+!if $(IMX_FAMILY) == IMX6SX
+BaseAddress   = 0x82004000|gArmTokenSpaceGuid.PcdFdBaseAddress  #The base address of UEFI image
+!else
+BaseAddress   = 0x10820000|gArmTokenSpaceGuid.PcdFdBaseAddress  #The base address of UEFI image
+!endif
+Size          = 0x001D0000|gArmTokenSpaceGuid.PcdFdSize         #The size in bytes of UEFI image
+ErasePolarity = 1
+BlockSize     = 0x1
+NumBlocks     = 0x001D0000
+
+################################################################################
+#
+# Following are lists of FD Region layout which correspond to the locations of different
+# images within the flash device.
+#
+# Regions must be defined in ascending order and may not overlap.
+#
+# A Layout Region start with a eight digit hex offset (leading "0x" required) followed by
+# the pipe "|" character, followed by the size of the region, also in hex with the leading
+# "0x" characters. Like:
+# Offset|Size
+# PcdOffsetCName|PcdSizeCName
+# RegionType <FV, DATA, or FILE>
+#
+################################################################################
+0x00000000|0x001D0000    # 1792Kb for the Pei phase boot
+
+gArmTokenSpaceGuid.PcdFvBaseAddress|gArmTokenSpaceGuid.PcdFvSize
+FV = FVMAIN_COMPACT
+
+################################################################################
+#
+# FV Section
+#
+# [FV] section is used to define what components or modules are placed within a flash
+# device file.  This section also defines order the components and modules are positioned
+# within the image.  The [FV] section consists of define statements, set statements and
+# module statements.
+#
+################################################################################
+[FV.FvMain]
+BlockSize          = 0x1
+NumBlocks          = 0         # This FV gets compressed so make it just big enough
+FvAlignment        = 8         # FV alignment and FV attributes setting.
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+  INF MdeModulePkg/Core/Dxe/DxeMain.inf
+  INF MdeModulePkg/Universal/PCD/Dxe/Pcd.inf
+
+  #
+  # PI DXE Drivers producing Architectural Protocols (EFI Services)
+  #
+  INF ArmPkg/Drivers/CpuDxe/CpuDxe.inf
+
+  INF MdeModulePkg/Core/RuntimeDxe/RuntimeDxe.inf
+  INF MdeModulePkg/Universal/SecurityStubDxe/SecurityStubDxe.inf
+  INF MdeModulePkg/Universal/WatchdogTimerDxe/WatchdogTimer.inf
+  INF MdeModulePkg/Universal/CapsuleRuntimeDxe/CapsuleRuntimeDxe.inf
+  INF MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+  INF ArmPkg/Drivers/ArmGic/ArmGicDxe.inf
+  INF Silicon/NXP/iMX6Pkg/Drivers/TimerDxe/TimerDxe.inf
+  INF MdeModulePkg/Universal/SerialDxe/SerialDxe.inf
+  INF MdeModulePkg/Universal/Console/TerminalDxe/TerminalDxe.inf
+  INF EmbeddedPkg/SimpleTextInOutSerial/SimpleTextInOutSerial.inf
+  INF EmbeddedPkg/ResetRuntimeDxe/ResetRuntimeDxe.inf
+  INF EmbeddedPkg/RealTimeClockRuntimeDxe/RealTimeClockRuntimeDxe.inf
+  INF EmbeddedPkg/MetronomeDxe/MetronomeDxe.inf
+
+  #
+  # Filesystem Stack
+  #
+  INF MdeModulePkg/Universal/Disk/DiskIoDxe/DiskIoDxe.inf
+  INF MdeModulePkg/Universal/Disk/PartitionDxe/PartitionDxe.inf
+  INF FatBinPkg/EnhancedFatDxe/Fat.inf
+  INF MdeModulePkg/Universal/Disk/UnicodeCollation/EnglishDxe/EnglishDxe.inf
+  INF Platform/Microsoft/Drivers/SdMmcDxe/SdMmcDxe.inf
+  INF Silicon/NXP/iMXPlatformPkg/Drivers/SdhcDxe/SdhcDxe.inf
+
+  #
+  # PCIe
+  #
+  INF Silicon/NXP/iMX6Pkg/Drivers/PciExpress/iMX6PciExpress.inf
+
+  #
+  # ACPI
+  #
+  INF MdeModulePkg/Universal/Acpi/AcpiTableDxe/AcpiTableDxe.inf
+  INF MdeModulePkg/Universal/Acpi/AcpiPlatformDxe/AcpiPlatformDxe.inf
+  INF RuleOverride=ACPITABLE $(BOARD_DIR)/AcpiTables/AcpiTables.inf
+
+!if $(CONFIG_HEADLESS) == FALSE
+  INF MdeModulePkg/Universal/Console/ConPlatformDxe/ConPlatformDxe.inf
+  INF MdeModulePkg/Universal/Console/ConSplitterDxe/ConSplitterDxe.inf
+  INF MdeModulePkg/Universal/Console/GraphicsConsoleDxe/GraphicsConsoleDxe.inf
+  !if $(IMX_FAMILY) == IMX6SX
+    #
+    # Use board-specific GOP for SoloX
+    #
+    INF $(BOARD_DIR)/Drivers/GraphicsOutputDxe/GraphicsOutputDxe.inf
+  !else
+    INF Silicon/NXP/iMX6Pkg/Drivers/GOP/iMX6GOP.inf
+  !endif
+!endif
+
+  #
+  # SMBIOS Support
+  #
+  INF $(BOARD_DIR)/Drivers/PlatformSmbiosDxe/PlatformSmbiosDxe.inf
+  INF MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
+
+  #
+  # Bds
+  #
+  INF MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+  INF MdeModulePkg/Universal/HiiDatabaseDxe/HiiDatabaseDxe.inf
+  INF MdeModulePkg/Universal/SetupBrowserDxe/SetupBrowserDxe.inf
+  INF MdeModulePkg/Universal/DisplayEngineDxe/DisplayEngineDxe.inf
+  INF MdeModulePkg/Universal/BdsDxe/BdsDxe.inf
+  INF MdeModulePkg/Application/UiApp/UiApp.inf
+
+  #
+  # UEFI application (Shell Embedded Boot Loader)
+  #
+  INF ShellPkg/Application/Shell/Shell.inf
+
+INF MdeModulePkg/Universal/Variable/EmuRuntimeDxe/EmuVariableRuntimeDxe.inf
+
+[FV.FVMAIN_COMPACT]
+FvAlignment        = 8
+ERASE_POLARITY     = 1
+MEMORY_MAPPED      = TRUE
+STICKY_WRITE       = TRUE
+LOCK_CAP           = TRUE
+LOCK_STATUS        = TRUE
+WRITE_DISABLED_CAP = TRUE
+WRITE_ENABLED_CAP  = TRUE
+WRITE_STATUS       = TRUE
+WRITE_LOCK_CAP     = TRUE
+WRITE_LOCK_STATUS  = TRUE
+READ_DISABLED_CAP  = TRUE
+READ_ENABLED_CAP   = TRUE
+READ_STATUS        = TRUE
+READ_LOCK_CAP      = TRUE
+READ_LOCK_STATUS   = TRUE
+
+  INF ArmPlatformPkg/PrePi/PeiMPCore.inf
+
+  FILE FV_IMAGE = 9E21FD93-9C72-4c15-8C4B-E77F1DB2D792 {
+    SECTION GUIDED EE4E5898-3914-4259-9D6E-DC7BD79403CF PROCESSING_REQUIRED = TRUE {
+      SECTION FV_IMAGE = FVMAIN
+    }
+  }
+
+
+################################################################################
+#
+# Rules are use with the [FV] section's module INF type to define
+# how an FFS file is created for a given INF file. The following Rule are the default
+# rules for the different module type. User can add the customized rules to define the
+# content of the FFS file.
+#
+################################################################################
+
+
+############################################################################
+# Example of a DXE_DRIVER FFS file with a Checksum encapsulation section   #
+############################################################################
+#
+#[Rule.Common.DXE_DRIVER]
+#  FILE DRIVER = $(NAMED_GUID) {
+#    DXE_DEPEX    DXE_DEPEX               Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+#    COMPRESS PI_STD {
+#      GUIDED {
+#        PE32     PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+#        UI       STRING="$(MODULE_NAME)" Optional
+#        VERSION  STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+#      }
+#    }
+#  }
+#
+############################################################################
+!if 0
+[Rule.Common.SEC]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+    TE  TE    Align = 32                $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID) {
+    TE     TE                           $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI     STRING ="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID) {
+     PEI_DEPEX PEI_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+     PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI       STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.PEIM.TIANOCOMPRESSED]
+  FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 {
+    PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+    GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
+      PE32      PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+      UI        STRING="$(MODULE_NAME)" Optional
+    }
+  }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    PE32     PE32                       $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+  }
+
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    UI     STRING ="$(MODULE_NAME)" Optional
+    PE32   PE32                         $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional      |.depex
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+!endif
+
+[Rule.Common.SEC]
+  FILE SEC = $(NAMED_GUID) RELOCS_STRIPPED {
+    TE  TE    Align = 32                $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+[Rule.Common.PEI_CORE]
+  FILE PEI_CORE = $(NAMED_GUID) {
+    TE     TE                           $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI     STRING ="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.PEIM]
+  FILE PEIM = $(NAMED_GUID) {
+     PEI_DEPEX PEI_DEPEX Optional       $(INF_OUTPUT)/$(MODULE_NAME).depex
+     PE32      PE32                     $(INF_OUTPUT)/$(MODULE_NAME).efi
+     UI       STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.PEIM.TIANOCOMPRESSED]
+  FILE PEIM = $(NAMED_GUID) DEBUG_MYTOOLS_IA32 {
+    PEI_DEPEX PEI_DEPEX Optional        $(INF_OUTPUT)/$(MODULE_NAME).depex
+    GUIDED A31280AD-481E-41B6-95E8-127F4C984779 PROCESSING_REQUIRED = TRUE {
+      PE32      PE32                    $(INF_OUTPUT)/$(MODULE_NAME).efi
+      UI        STRING="$(MODULE_NAME)" Optional
+    }
+  }
+
+[Rule.Common.DXE_CORE]
+  FILE DXE_CORE = $(NAMED_GUID) {
+    PE32     PE32                       $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI       STRING="$(MODULE_NAME)" Optional
+  }
+
+
+[Rule.Common.UEFI_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.DXE_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.DXE_RUNTIME_DRIVER]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX    DXE_DEPEX              Optional $(INF_OUTPUT)/$(MODULE_NAME).depex
+    PE32         PE32                   $(INF_OUTPUT)/$(MODULE_NAME).efi
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.UEFI_APPLICATION]
+  FILE APPLICATION = $(NAMED_GUID) {
+    UI     STRING ="$(MODULE_NAME)" Optional
+    PE32   PE32                         $(INF_OUTPUT)/$(MODULE_NAME).efi
+  }
+
+[Rule.Common.USER_DEFINED.ACPITABLE]
+  FILE FREEFORM = $(NAMED_GUID) {
+    RAW          ACPI                 |.acpi
+    RAW          ASL Optional         |.aml
+    UI           STRING="$(MODULE_NAME)" Optional
+  }
+
+[Rule.Common.UEFI_DRIVER.BINARY]
+  FILE DRIVER = $(NAMED_GUID) {
+    DXE_DEPEX DXE_DEPEX Optional      |.depex
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
+
+[Rule.Common.UEFI_APPLICATION.BINARY]
+  FILE APPLICATION = $(NAMED_GUID) {
+    PE32      PE32                    |.efi
+    UI        STRING="$(MODULE_NAME)" Optional
+    VERSION   STRING="$(INF_VERSION)" Optional BUILD_NUM=$(BUILD_NUMBER)
+  }
diff --git a/Silicon/NXP/iMX6Pkg/iMX6ConfigDsc.inc b/Silicon/NXP/iMX6Pkg/iMX6ConfigDsc.inc
new file mode 100644
index 000000000000..4c95859dbb34
--- /dev/null
+++ b/Silicon/NXP/iMX6Pkg/iMX6ConfigDsc.inc
@@ -0,0 +1,115 @@
+## @file
+#
+#  Copyright (c) Microsoft Corporation. All rights reserved.
+#
+#  This program and the accompanying materials
+#  are licensed and made available under the terms and conditions of the BSD License
+#  which accompanies this distribution.  The full text of the license may be found at
+#  http://opensource.org/licenses/bsd-license.php
+#
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+
+  # Do not draw to display surface
+!ifndef CONFIG_HEADLESS
+  DEFINE CONFIG_HEADLESS = FALSE
+!endif
+
+  # Useful if working with Lauterbach JTAG. Will dump to console the complete
+  # command to copy and past into the Lauterbach command line to load symbols
+  # for each module.
+  # Use in conjution with Informational debug messages:
+  # DEBUG_INFO      0x00000040
+!ifndef CONFIG_DUMP_SYMBOL_INFO
+  DEFINE CONFIG_DUMP_SYMBOL_INFO = TRUE
+!endif
+
+  # Enable if PSCI is implemented.
+!ifndef CONFIG_MPCORE
+  DEFINE CONFIG_MPCORE = TRUE
+!endif
+
+  # Disable the PCIexpress stack by default. Enable on demand.
+!ifndef CONFIG_PCIE
+  DEFINE CONFIG_PCIE = FALSE
+!endif
+
+  # States whether OPTEE boot flow is in effect or not. This has the following
+  # implications:
+  # - OPTEE owns the SecureWorld and UEFI has to run in NormalWorld.
+  # - Specific memory layout that is defined in the platform .dsc file.
+  # - Temp: Running in single-core until PSCI is enabled.
+  # WARNING: Don't set this to FALSE unless you know what you are doing. Running
+  # UEFI in SecureWorld will most likely result in boot failure due to lack of
+  # proper CPU sec configuration. That is by UEFI design.
+!ifndef CONFIG_OPTEE
+  DEFINE CONFIG_OPTEE = TRUE
+!endif
+
+  # Allow collecting performance tracing from OPTEE hot code paths
+  # Performance summary results can be inspected with the shell app Dp.efi
+!ifndef CONFIG_OPTEE_PROFILE
+  DEFINE CONFIG_OPTEE_PROFILE = FALSE
+!endif
+
+!ifndef CONFIG_AUTH_VAR
+  DEFINE CONFIG_AUTH_VAR = FALSE
+!endif
+
+!ifndef CONFIG_MEASURED_BOOT
+  DEFINE CONFIG_MEASURED_BOOT = FALSE
+!endif
+
+!ifndef CONFIG_SECURE_BOOT
+  DEFINE CONFIG_SECURE_BOOT = FALSE
+!endif
+
+[BuildOptions]
+#
+# For each enabled CONFIG_* flag in the dsc files, define that flag in C code.
+# Note: The = sign in BuildOptions section appends to the existing macro, while
+# == can be used to replace its value. See the EDK2 DSC specs.
+#
+!if $(CONFIG_HEADLESS) == TRUE
+  GCC:*_*_*_CC_FLAGS = -DCONFIG_HEADLESS=1
+!endif
+
+!if $(CONFIG_DUMP_SYMBOL_INFO) == TRUE
+  GCC:*_*_*_CC_FLAGS = -DCONFIG_DUMP_SYMBOL_INFO=1
+!endif
+
+!if $(CONFIG_MPCORE) == TRUE
+  GCC:*_*_*_CC_FLAGS = -DCONFIG_MPCORE=1
+!endif
+
+!if $(CONFIG_PCIE) == TRUE
+  GCC:*_*_*_CC_FLAGS = -DCONFIG_PCIE=1
+!endif
+
+!if $(CONFIG_OPTEE) == TRUE
+  GCC:*_*_*_CC_FLAGS = -DCONFIG_OPTEE=1
+!endif
+
+!if $(CONFIG_OPTEE_PROFILE) == TRUE
+  GCC:*_*_*_CC_FLAGS = -DOPTEE_PROFILE=1
+!endif
+
+!if $(CONFIG_AUTH_VAR) == TRUE
+  GCC:*_*_*_CC_FLAGS = -DCONFIG_AUTH_VAR=1
+!endif
+
+!if $(CONFIG_MEASURED_BOOT) == TRUE
+  GCC:*_*_*_CC_FLAGS = -DCONFIG_MEASURED_BOOT=1
+!endif
+
+!if $(CONFIG_SECURE_BOOT) == TRUE
+  GCC:*_*_*_CC_FLAGS = -DCONFIG_SECURE_BOOT=1
+!endif
+
+!if $(CONFIG_SECURE_BOOT_AUTO_CONFIG) == TRUE
+  GCC:*_*_*_CC_FLAGS = -DCONFIG_SECURE_BOOT_AUTO_CONFIG=1
+!endif
-- 
2.16.2.gvfs.1.33.gf5370f1



^ permalink raw reply related	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2018-07-20  6:34 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-07-20  6:33 [PATCH edk2-platforms 00/13] Silicon/NXP: Import NXP i.MX6 Package Chris Co
2018-07-20  6:33 ` [PATCH edk2-platforms 01/13] Silicon/NXP: Add i.MX6 SoC header files Chris Co
2018-07-20  6:33 ` [PATCH edk2-platforms 02/13] Silicon/NXP: Add i.MX6 GPT and EPIT timer headers Chris Co
2018-07-20  6:33 ` [PATCH edk2-platforms 03/13] Silicon/NXP: Add iMX6Pkg dec Chris Co
2018-07-20  6:33 ` [PATCH edk2-platforms 04/13] Silicon/NXP: Add i.MX6 Timer DXE driver Chris Co
2018-07-20  6:33 ` [PATCH edk2-platforms 05/13] Silicon/NXP: Add i.MX6 GPT Timer library Chris Co
2018-07-20  6:33 ` [PATCH edk2-platforms 06/13] Silicon/NXP: Add i.MX6 USB Phy Library Chris Co
2018-07-20  6:33 ` [PATCH edk2-platforms 07/13] Silicon/NXP: Add i.MX6 I/O MUX library Chris Co
2018-07-20  6:33 ` [PATCH edk2-platforms 08/13] Silicon/NXP: Add i.MX6 Clock Library Chris Co
2018-07-20  6:33 ` [PATCH edk2-platforms 09/13] Silicon/NXP: Add i.MX6 ACPI tables Chris Co
2018-07-20  6:33 ` [PATCH edk2-platforms 10/13] Silicon/NXP: Add i.MX6 Board init library Chris Co
2018-07-20  6:34 ` [PATCH edk2-platforms 11/13] Silicon/NXP: Add i.MX6 PCIe DXE driver Chris Co
2018-07-20  6:34 ` [PATCH edk2-platforms 12/13] Silicon/NXP: Add i.MX6 GOP driver Chris Co
2018-07-20  6:34 ` [PATCH edk2-platforms 13/13] Silicon/NXP: Add i.MX6 common dsc and fdf files Chris Co

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox