public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Leif Lindholm <leif.lindholm@linaro.org>
To: Chris Co <Christopher.Co@microsoft.com>
Cc: "edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	Michael D Kinney <michael.d.kinney@intel.com>
Subject: Re: [PATCH edk2-platforms 22/27] Silicon/NXP: Add i.MX6 GOP driver
Date: Fri, 14 Dec 2018 22:37:43 +0000	[thread overview]
Message-ID: <20181214223743.b6txd5zchffy6apr@bivouac.eciton.net> (raw)
In-Reply-To: <20180921082542.35768-23-christopher.co@microsoft.com>

On Fri, Sep 21, 2018 at 08:26:15AM +0000, Chris Co wrote:
> 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>

This patch is massive. I would be lying if I said I have given it a
proper review - but I do have some comments sprinkled below.

> ---
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/CPMem.c             | 423 +++++++++++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/CPMem.h             | 277 +++++++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Ddc.c               |  69 ++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Ddc.h               |  28 +
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Display.c           | 455 ++++++++++++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Display.h           | 175 +++++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/DisplayController.c | 399 ++++++++++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/DisplayController.h | 331 +++++++++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/DisplayInterface.c  | 458 ++++++++++++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/DisplayInterface.h  | 195 +++++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Edid.c              |  96 +++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Edid.h              |  33 +
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/GopDxe.c            | 475 ++++++++++++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/GopDxe.h            |  20 +
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/GopDxe.inf          |  70 ++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Hdmi.c              | 761 ++++++++++++++++++++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Hdmi.h              | 529 ++++++++++++++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/IoMux.c             |  88 +++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/IoMux.h             |  32 +
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Ipu.h               | 236 ++++++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Lvds.c              |  93 +++
>  Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Lvds.h              |  67 ++
>  22 files changed, 5310 insertions(+)
> 
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/CPMem.c b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/CPMem.c
> new file mode 100644
> index 000000000000..a8ab78128719
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/CPMem.c

What does CP stand for? Worth adding to the file header.

> @@ -0,0 +1,423 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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 <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include <iMX6.h>
> +#include <iMX6ClkPwr.h>
> +#include <iMXDisplay.h>
> +
> +#include "Display.h"
> +#include "CPMem.h"
> +#include "GopDxe.h"
> +#include "Ipu.h"
> +
> +CPMEM_PARAM *CpMemParamBasePtr = (CPMEM_PARAM *)(IPU1_BASE + CSP_IPUV3_CPMEM_REGS_OFFSET);

Is this meant to be externally visible, or could it be STATIC?
It needs a g- or m-prefix.

> +
> +STATIC CONST UINT8 ChannelMap[] = {

Please add m-prefix.

> +  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,
> +};
> +
> +#ifdef DEBUG
> +VOID
> +DumpCpmemParamPack (
> +  IN  CPMEM_PARAM   *ParamPtr
> +  )
> +{
> +  DEBUG ((DEBUG_VERBOSE, "%a: --WORD0--\n", __FUNCTION__));
> +  DEBUG ((DEBUG_VERBOSE, "%a: XVVirtualCoordinate 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.XVVirtualCoordinate));
> +  DEBUG ((DEBUG_VERBOSE, "%a: YVVirtualCoordinate 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.YVVirtualCoordinate));
> +  DEBUG ((DEBUG_VERBOSE, "%a: XBinnerBlockCoordinate 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.XBinnerBlockCoordinate));
> +  DEBUG ((DEBUG_VERBOSE, "%a: YBinnerBlockCoordinate 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.YBinnerBlockCoordinate));
> +  DEBUG ((DEBUG_VERBOSE, "%a: NewSubBlock 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.NewSubBlock));
> +  DEBUG ((DEBUG_VERBOSE, "%a: CurrentField 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.CurrentField));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ScrollXCounter 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.ScrollXCounter));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ScrollYCounter 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.ScrollYCounter));
> +  DEBUG ((DEBUG_VERBOSE, "%a: NumberOfScroll 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.NumberOfScroll));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ScrollDeltaX 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.ScrollDeltaX));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ScrollMax 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.ScrollMax));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ScrollingConfiguration 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.ScrollingConfiguration));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ScrollingEnable 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.ScrollingEnable));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ScrollDeltaY 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.ScrollDeltaY));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ScrollHorizontalDirection 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.ScrollHorizontalDirection));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ScrollVerticalDirection 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.ScrollVerticalDirection));
> +  DEBUG ((DEBUG_VERBOSE, "%a: BitsPerPixel 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.BitsPerPixel));
> +  DEBUG ((DEBUG_VERBOSE, "%a: DecodeAddressSelect 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.DecodeAddressSelect));
> +  DEBUG ((DEBUG_VERBOSE, "%a: AccessDimension 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.AccessDimension));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ScanOrder 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.ScanOrder));
> +  DEBUG ((DEBUG_VERBOSE, "%a: BandMode 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.BandMode));
> +  DEBUG ((DEBUG_VERBOSE, "%a: BlockMode 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.BlockMode));
> +  DEBUG ((DEBUG_VERBOSE, "%a: Rotation 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.Rotation));
> +  DEBUG ((DEBUG_VERBOSE, "%a: HorizontalFlip 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.HorizontalFlip));
> +  DEBUG ((DEBUG_VERBOSE, "%a: VerticalFlip 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.VerticalFlip));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ThresholdEnable 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.ThresholdEnable));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ConditionalAccessPolarity 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.ConditionalAccessPolarity));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ConditionalAccessEnable 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.ConditionalAccessEnable));
> +  DEBUG ((DEBUG_VERBOSE, "%a: FrameWidth 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.FrameWidth));
> +  DEBUG ((DEBUG_VERBOSE, "%a: FrameHeight 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.FrameHeight));
> +  DEBUG ((DEBUG_VERBOSE, "%a: EndOfLineInterrupt 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word0Pack.EndOfLineInterrupt));
> +
> +  DEBUG ((DEBUG_VERBOSE, "%a: --WORD1--\n", __FUNCTION__));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ExtMemBuffer0Address 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.ExtMemBuffer0Address));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ExtMemBuffer1Address 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.ExtMemBuffer1Address));
> +  DEBUG ((DEBUG_VERBOSE, "%a: InterlaceOffset 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.InterlaceOffset));
> +  DEBUG ((DEBUG_VERBOSE, "%a: NumberOfPixelsInWholeBurstAccess 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.NumberOfPixelsInWholeBurstAccess));
> +  DEBUG ((DEBUG_VERBOSE, "%a: PixelFormatSelect 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.PixelFormatSelect));
> +  DEBUG ((DEBUG_VERBOSE, "%a: AlphaUsed 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.AlphaUsed));
> +  DEBUG ((DEBUG_VERBOSE, "%a: AlphaChannelMapping 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.AlphaChannelMapping));
> +  DEBUG ((DEBUG_VERBOSE, "%a: AxiId 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.AxiId));
> +  DEBUG ((DEBUG_VERBOSE, "%a: Threshold 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.Threshold));
> +  DEBUG ((DEBUG_VERBOSE, "%a: StrideLine 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.StrideLine));
> +  DEBUG ((DEBUG_VERBOSE, "%a: Width0 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.Width0));
> +  DEBUG ((DEBUG_VERBOSE, "%a: Width1 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.Width1));
> +  DEBUG ((DEBUG_VERBOSE, "%a: Width2 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.Width2));
> +  DEBUG ((DEBUG_VERBOSE, "%a: Width3 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.Width3));
> +  DEBUG ((DEBUG_VERBOSE, "%a: Offset0 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.Offset0));
> +  DEBUG ((DEBUG_VERBOSE, "%a: Offset1 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.Offset1));
> +  DEBUG ((DEBUG_VERBOSE, "%a: Offset2 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.Offset2));
> +  DEBUG ((DEBUG_VERBOSE, "%a: Offset3 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.Offset3));
> +  DEBUG ((DEBUG_VERBOSE, "%a: SelectSXSYSet 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.SelectSXSYSet));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ConditionalReadEnable 0x%08x\n", __FUNCTION__,
> +    ParamPtr->Word1Pack.ConditionalReadEnable));
> +}
> +
> +VOID
> +DumpBasicCpmemReg (
> +  IN  CPMEM_PARAM   *pCpmemChannel
> +  )
> +{
> +  DEBUG ((DEBUG_VERBOSE, "%a: ---------- CPMEM Register Dump ----------\n",
> +    __FUNCTION__));
> +  DEBUG ((DEBUG_VERBOSE, "%a: CPMEM\n", __FUNCTION__));
> +  DEBUG ((DEBUG_VERBOSE, "%a: IDMAC_CHANNEL_DP_PRIMARY_FLOW_MAIN_PLANE\n",
> +    __FUNCTION__));
> +  DumpCpmemParamPack (pCpmemChannel);
> +  DEBUG ((DEBUG_VERBOSE, "%a: ------------------------------------\n",
> +    __FUNCTION__));
> +}
> +#endif /* DEBUG */
> +
> +// Enable IDMAC lock setting, which optimises memory accesses and reduces
> +// power consumption
> +VOID
> +SetIdmacLockEn (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *DisplayInterfaceContextPtr,
> +  IN  UINT32                      Channel,
> +  IN  UINT32                      Setting
> +  )
> +{
> +  UINT32 i;
> +  UINTN   LockReg;
> +  UINT32 Shift;
> +  UINT32 Value;
> +
> +  Shift = -1;
> +
> +  for (i = 0; i < ARRAYSIZE (ChannelMap); i += 2) {
> +    if (ChannelMap[i] == Channel) {
> +      Shift = ChannelMap[i + 1];
> +      break;
> +    }
> +  }
> +
> +  if (Shift == -1) {
> +    DEBUG ((DEBUG_WARN, "%a: Channel %d does not have lock bits\n",
> +      __FUNCTION__, Channel));
> +    return;
> +  }
> +
> +  if (Channel < 29) {
> +    LockReg = (UINTN)DisplayInterfaceContextPtr->IpuMmioBasePtr + IPU_IDMAC_LOCK_EN_1;
> +  } else {
> +    LockReg = (UINTN)DisplayInterfaceContextPtr->IpuMmioBasePtr + IPU_IDMAC_LOCK_EN_2;
> +  }
> +
> +  Value = MmioRead32 ((UINT32)LockReg);
> +  Value &= ~(0x3 << Shift);
> +  Value |= (Setting & 0x3) << Shift;
> +  MmioWrite32 ((UINT32)LockReg, Value);
> +}
> +
> +EFI_STATUS
> +ConfigureCpmemFrameBuffer (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *DisplayInterfaceContextPtr,
> +  IN  UINT32                      Channel,
> +  IN  SURFACE_INFO                *FrameBufferPtr
> +  )
> +{
> +  CPMEM_PARAM *pCpmemChannel;
> +  EFI_STATUS Status;
> +  CPMEM_WORD0_PACKED_REG CpmemWord0PackedReg;
> +  CPMEM_WORD1_PACKED_REG CpmemWord1PackedReg;
> +  CPMEM_DEC_SEL DecodeAddressSelect;
> +  UINT32 PixelBurst;
> +  CPMEM_PFS_PACKED PixelFormatSelector;
> +  UINT32 Width0;
> +  UINT32 Width1;
> +  UINT32 Width2;
> +  UINT32 Width3;
> +  UINT32 Offset0;
> +  UINT32 Offset1;
> +  UINT32 Offset2;
> +  UINT32 Offset3;
> +  UINT32 BytesPerPixel;
> +
> +  pCpmemChannel = DisplayInterfaceContextPtr->CpMemParamBasePtr;
> +  Status = EFI_SUCCESS;
> +  PixelBurst = 1;
> +  DecodeAddressSelect = CPMEM_DEC_SEL_0_15; // Only applicable for 4 bpp
> +  ZeroMem (&CpmemWord0PackedReg, sizeof (CpmemWord0PackedReg));
> +  ZeroMem (&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 = EFI_UNSUPPORTED;
> +    break;
> +  }
> +  if (EFI_ERROR (Status)) {
> +    goto Exit;
> +  }
> +
> +  switch (FrameBufferPtr->Bpp) {
> +  case 8:
> +    Width0 = 0;
> +    Width1 = 0;
> +    Width2 = 0;
> +    Width3 = 0;
> +    break;
> +  case 32:
> +    if (PixelFormatSelector == CPMEM_PFS_RGB) {
> +      Width0 = 7;
> +      Width1 = 7;
> +      Width2 = 7;
> +      Width3 = 7;
> +    } else {
> +      Width0 = 0;
> +      Width1 = 0;
> +      Width2 = 0;
> +      Width3 = 0;
> +    }
> +    break;
> +  default:
> +    ASSERT (FALSE);
> +    Status = EFI_UNSUPPORTED;
> +    break;
> +  }
> +  if (EFI_ERROR (Status)) {
> +    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;
> +
> +  // Finally write into cpmem IDMAC channel
> +  pCpmemChannel = (pCpmemChannel + Channel);
> +
> +  CopyMem (
> +    &pCpmemChannel->Word0Pack,
> +    &CpmemWord0PackedReg,
> +    sizeof (pCpmemChannel->Word0Pack)
> +  );
> +
> +  CopyMem (
> +    &pCpmemChannel->Word1Pack,
> +    &CpmemWord1PackedReg,
> +    sizeof (pCpmemChannel->Word1Pack)
> +  );
> +
> +  // IDMAC will generate 8 AXI bursts upon assertion of the DMA request
> +  // This significantly reduces memory activity and power consumption
> +  SetIdmacLockEn (DisplayInterfaceContextPtr, Channel, 0x3);
> +
> +#ifdef DEBUG
> +  DumpBasicCpmemReg (pCpmemChannel);
> +#endif /* DEBUG */
> +
> +Exit:
> +  return Status;
> +}
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/CPMem.h b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/CPMem.h
> new file mode 100644
> index 000000000000..06e96538f2d1
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/CPMem.h
> @@ -0,0 +1,277 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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_

Please add an IMX6 prefix.

> +
> +// 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)
> +
> +EFI_STATUS
> +ConfigureCpmemFrameBuffer (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *DisplayInterfaceContextPtr,
> +  IN  UINT32                      Channel,
> +  IN  SURFACE_INFO                *FrameBufferPtr
> +  );
> +
> +#endif  /* _CPMEM_H_ */
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Ddc.c b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Ddc.c
> new file mode 100644
> index 000000000000..30b737b2f4f5
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Ddc.c
> @@ -0,0 +1,69 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include <iMX6.h>
> +#include <iMX6ClkPwr.h>
> +#include <iMXDisplay.h>
> +
> +#include "Display.h"
> +#include "Edid.h"
> +#include "Ddc.h"
> +#include "Hdmi.h"
> +#include "Lvds.h"
> +
> +EFI_STATUS
> +Imx6DdcRead (
> +  IN  DISPLAY_CONTEXT     *DisplayContextPtr,
> +  IN  DISPLAY_INTERFACE_TYPE   DisplayInterface,
> +  IN  UINT8               SlaveAddress,
> +  IN  UINT8               RegisterAddress,
> +  IN  UINT32              ReadSize,
> +  IN  UINT8               *DataReadPtr
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  switch (DisplayInterface) {
> +  case HdmiDisplay:
> +    Status = HdmiDdcRead (
> +               &DisplayContextPtr->DiContext[HdmiDisplay],
> +               SlaveAddress,
> +               RegisterAddress,
> +               ReadSize,
> +               HDMI_DDC_STANDARD_MODE,
> +               DataReadPtr
> +             );
> +    if (Status != EFI_SUCCESS) {
> +      DEBUG ((DEBUG_ERROR, "%a: HdmiDdcRead failed\n", __FUNCTION__));
> +    }
> +    break;
> +  case MipiDisplay:
> +  case Lvds0Display:
> +  case Lvds1Display:
> +  default:
> +    Status = EFI_UNSUPPORTED;
> +    break;
> +  }
> +
> +  return Status;
> +}
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Ddc.h b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Ddc.h
> new file mode 100644
> index 000000000000..5a10f3d0c26c
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Ddc.h
> @@ -0,0 +1,28 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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_

IMX_ prefix please.

> +
> +EFI_STATUS
> +Imx6DdcRead (
> +  IN  DISPLAY_CONTEXT     *DisplayContextPtr,
> +  IN  DISPLAY_INTERFACE_TYPE   DisplayInterface,
> +  IN  UINT8               SlaveAddress,
> +  IN  UINT8               RegisterAddress,
> +  IN  UINT32              ReadSize,
> +  IN  UINT8               *DataReadPtr
> +  );
> +
> +#endif  /* _DDC_H_ */
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Display.c b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Display.c
> new file mode 100644
> index 000000000000..334e7362d3b8
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Display.c
> @@ -0,0 +1,455 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include <iMX6.h>
> +#include <iMX6ClkPwr.h>
> +#include <iMXDisplay.h>
> +
> +// Display muxing register
> +#include "iMX6.h"

Is this not the same iMX6.h as 5 lines up?

> +
> +#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
> +};
> +
> +EFI_STATUS
> +GetPreferredTiming (
> +  IN  UINT8           *EdidDataPtr,
> +  IN  UINT32          EdidDataSize,
> +  IN  DISPLAY_TIMING  *PreferredTimingPtr
> +  )
> +{
> +  EFI_STATUS Status;
> +
> +  if (FeaturePcdGet (PcdLvdsEnable)) {
> +    *PreferredTimingPtr = Hannstar_XGA;
> +    Status = EFI_SUCCESS;
> +  } else {
> +    Status = GetEdidPreferredTiming (EdidDataPtr, EdidDataSize, PreferredTimingPtr);
> +    if (Status != EFI_SUCCESS) {
> +      // If EDID is unavailable use the default timing
> +      Status = EFI_SUCCESS;
> +      *PreferredTimingPtr = DefaultTiming;
> +      DEBUG ((DEBUG_WARN,
> +        "%a: EDID data not available, falling back to default timing\n",
> +        __FUNCTION__));
> +    }
> +  }
> +
> +  // Only support 8 bit per pixel and no pixel repetition for now
> +  PreferredTimingPtr->PixelRepetition = 1;
> +  PreferredTimingPtr->PixelFormat = PIXEL_FORMAT_BGRA32;
> +  PreferredTimingPtr->Bpp = 32;
> +
> +#ifdef DEBUG
> +  PrintDisplayTiming ("Preferred Timing", PreferredTimingPtr);
> +#endif /* DEBUG */
> +  DEBUG ((DEBUG_WARN, "%a: --GetPreferredTiming\n", __FUNCTION__));
> +  return Status;
> +}
> +
> +EFI_STATUS
> +InitDisplay (
> +  IN  DISPLAY_CONTEXT   **DisplayConfigPPtr
> +  )
> +{
> +  DISPLAY_CONTEXT     *pTempDisplayContext;
> +  DISPLAY_INTERFACE_TYPE   DisplayCounter;
> +  EFI_STATUS          Status;
> +
> +  pTempDisplayContext = AllocateRuntimePool (sizeof (*pTempDisplayContext));
> +  if (pTempDisplayContext == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to allocate display context\n", __FUNCTION__));
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Exit;
> +  }
> +
> +  ZeroMem (pTempDisplayContext, sizeof (*pTempDisplayContext));
> +
> +  pTempDisplayContext->IoMuxMmioBasePtr = (VOID *)IOMUXC_GPR_BASE_ADDRESS;
> +  if (pTempDisplayContext->IoMuxMmioBasePtr == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to map IO Mux register\n", __FUNCTION__));
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Exit;
> +  }
> +
> +  pTempDisplayContext->IpuMmioBasePtr[IPU1] = (VOID *)IPU1_BASE;
> +  if (pTempDisplayContext->IoMuxMmioBasePtr == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to map IPU1 IO Mux register\n", __FUNCTION__));
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Exit;
> +  }
> +#if !defined(CPU_IMX6SDL)
> +  pTempDisplayContext->IpuMmioBasePtr[IPU2] = (VOID *)IPU2_BASE;
> +  if (pTempDisplayContext->IoMuxMmioBasePtr == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to map IPU2 IO Mux register\n", __FUNCTION__));
> +    Status = EFI_OUT_OF_RESOURCES;
> +    goto Exit;
> +  }
> +#endif
> +  for (DisplayCounter = HdmiDisplay; DisplayCounter < DisplayTypeMax; ++DisplayCounter) {
> +    pTempDisplayContext->DiContext[DisplayCounter].displayInterface =
> +      DisplayCounter;
> +  }
> +
> +  if (FeaturePcdGet (PcdLvdsEnable)) {
> +    Status = InitLvds (pTempDisplayContext);
> +    if (Status != EFI_SUCCESS) {
> +      DEBUG ((DEBUG_ERROR, "%a: Fail to intialize LVDS\n", __FUNCTION__));
> +      goto Exit;
> +    }
> +  } else {
> +    Status = InitHdmi (pTempDisplayContext);
> +    if (Status != EFI_SUCCESS) {
> +      DEBUG ((DEBUG_ERROR, "%a: Fail to intialize HDMI\n", __FUNCTION__));
> +      goto Exit;
> +    }
> +  }
> +
> +  *DisplayConfigPPtr = pTempDisplayContext;
> +
> +Exit:
> +  return Status;
> +}
> +
> +EFI_STATUS
> +ValidateDisplayConfig (
> +  IN  DISPLAY_CONTEXT     *DisplayContextPtr,
> +  IN  DISPLAY_MODE        DisplayMode,
> +  IN  DISPLAY_INTERFACE_TYPE   *DiOrder
> +  )
> +{
> +  DISPLAY_INTERFACE_TYPE   DisplayDevice;
> +  EFI_STATUS          Status;
> +
> +  if (FeaturePcdGet (PcdLvdsEnable)) {
> +    DisplayDevice = Lvds0Display;
> +  } else {
> +    DisplayDevice = HdmiDisplay;
> +  }
> +
> +  // Currently only support single display mode on HDMI/LVDS
> +  if (DisplayMode != SINGLE_MODE && DiOrder[0] != DisplayDevice) {
> +    Status = EFI_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 = EFI_SUCCESS;
> +
> +Exit:
> +  return Status;
> +}
> +
> +EFI_STATUS
> +SetDisplayConfig (
> +  IN OUT  DISPLAY_CONTEXT     *DisplayContextPtr,
> +  IN      DISPLAY_MODE        DisplayMode,
> +  IN      DISPLAY_INTERFACE_TYPE   *DiOrder
> +  )
> +{
> +  DISPLAY_INTERFACE_CONTEXT   *pDisplayInterfaceContext;
> +  DISPLAY_INTERFACE_INDEX     DisplayInterfaceIndex;
> +  UINT32                      DisplayInterfaceOffset[DisplayInterfaceMax];
> +  UINT32                      DisplayModeIndex;
> +  IPU_INDEX                   IpuIndex;
> +  EFI_STATUS                  Status;
> +
> +  DisplayInterfaceOffset[0] = IPU_DISPLAY_INTERFACE_0_OFFSET;
> +  DisplayInterfaceOffset[1] = IPU_DISPLAY_INTERFACE_1_OFFSET;
> +  Status = ValidateDisplayConfig (DisplayContextPtr, DisplayMode, DiOrder);
> +  if (Status != EFI_SUCCESS) {
> +    DisplayContextPtr->DisplayConfig.DisplayMode = UNKNOWN_MODE;
> +    ZeroMem (
> +      DisplayContextPtr->DisplayConfig.DiOrder,
> +      sizeof (DisplayContextPtr->DisplayConfig.DiOrder)
> +    );
> +    DEBUG ((DEBUG_ERROR, "%a: Unsupported display configuration\n", __FUNCTION__));
> +    Status = EFI_UNSUPPORTED;
> +    goto Exit;
> +  }
> +
> +  DisplayContextPtr->DisplayConfig.DisplayMode = DisplayMode;
> +  ZeroMem (
> +    DisplayContextPtr->DisplayConfig.DiOrder,
> +    sizeof (DisplayContextPtr->DisplayConfig.DiOrder)
> +  );
> +
> +  // Assigning display interface in order. Require mode information on IPU
> +  // and Display Interface valid combination
> +  DisplayModeIndex = 0;
> +  for (IpuIndex = IPU1; IpuIndex < IPU_TOTAL; IpuIndex++) {
> +    for (DisplayInterfaceIndex = DisplayInterface0;
> +         DisplayInterfaceIndex < DisplayInterfaceMax;
> +         DisplayInterfaceIndex++)
> +    {
> +      if (DisplayModeIndex >= (UINT32)DisplayMode) {
> +        break;
> +      }
> +      DisplayModeIndex++;
> +
> +      DisplayContextPtr->DisplayConfig.DiOrder[DisplayInterfaceIndex] =
> +        DiOrder[DisplayInterfaceIndex];
> +      pDisplayInterfaceContext =
> +        &DisplayContextPtr->DiContext[DiOrder[DisplayInterfaceIndex]];
> +      pDisplayInterfaceContext->IpuMmioBasePtr =
> +        DisplayContextPtr->IpuMmioBasePtr[IpuIndex];
> +      pDisplayInterfaceContext->IpuDiRegsPtr =
> +        (IPU_DIx_REGS *)(((UINTN)DisplayContextPtr->IpuMmioBasePtr[IpuIndex]) +
> +                                 DisplayInterfaceOffset[DisplayInterfaceIndex]);
> +      pDisplayInterfaceContext->CpMemParamBasePtr =
> +        (VOID *)(((UINTN)pDisplayInterfaceContext->IpuMmioBasePtr) +
> +                         CSP_IPUV3_CPMEM_REGS_OFFSET);
> +    }
> +  }
> +
> +  Status = EFI_SUCCESS;
> +
> +Exit:
> +  return Status;
> +}
> +
> +EFI_STATUS
> +ApplyDisplayConfig (
> +  IN OUT  DISPLAY_CONTEXT     *DisplayContextPtr,
> +  IN      DISPLAY_MODE        DisplayMode,
> +  IN      DISPLAY_INTERFACE_TYPE   *DiOrder
> +  )
> +{
> +  DISPLAY_TIMING              *pCurrentDisplayTiming;
> +  DISPLAY_CONFIG              *pDisplayConfig;
> +  DISPLAY_INTERFACE_CONTEXT   *pDisplayInterfaceContext;

No Hungarian notation please, throughout.

> +  UINT32                      CurrentDisplayInterface;
> +  UINT32                      DisplayModeIndex;
> +  EFI_STATUS                  Status;
> +
> +  Status = EFI_SUCCESS;
> +  pDisplayConfig = &DisplayContextPtr->DisplayConfig;
> +  Status = SetDisplayConfig (DisplayContextPtr, DisplayMode, DiOrder);
> +  if (Status != EFI_SUCCESS) {
> +    DEBUG ((DEBUG_ERROR,
> +      "%a: Fail to set display configuration %d\n",
> +      __FUNCTION__, DisplayMode));
> +    Status = EFI_UNSUPPORTED;
> +    goto Exit;
> +  }
> +
> +  // Setup muxing first before configuring DI and DC
> +  Status = SetupDisplayMux (DisplayContextPtr);
> +  if (Status != EFI_SUCCESS) {

if (EFI_ERROR (Status)) {

is more idiomatic. Could you replace throughout?

> +    DEBUG ((DEBUG_ERROR, "%a: SetDisplayMux failed \n", __FUNCTION__));
> +    goto Exit;
> +  }
> +
> +  for (DisplayModeIndex = 0;
> +       DisplayModeIndex < (UINT32)pDisplayConfig->DisplayMode;
> +       ++DisplayModeIndex)
> +  {
> +    CurrentDisplayInterface = pDisplayConfig->DiOrder[DisplayModeIndex];
> +    pDisplayInterfaceContext = &DisplayContextPtr->DiContext[CurrentDisplayInterface];
> +    pCurrentDisplayTiming = &pDisplayConfig->DisplayTiming[DisplayModeIndex];
> +
> +    Status = ConfigureDisplayControllerChannel (
> +               pDisplayInterfaceContext,
> +               CurrentDisplayInterface,
> +               DisplayModeIndex,
> +               pCurrentDisplayTiming
> +             );
> +    if (Status != EFI_SUCCESS) {
> +      DEBUG ((DEBUG_ERROR,
> +        "%a:ConfigureDisplayControllerChannel fail display %d index %d\n",
> +        __FUNCTION__, CurrentDisplayInterface, DisplayModeIndex));
> +      goto Exit;
> +    }
> +
> +    Status = ConfigureDisplayInterface (
> +               pDisplayInterfaceContext,
> +               DisplayModeIndex,
> +               pCurrentDisplayTiming
> +             );
> +    if (Status != EFI_SUCCESS) {
> +      DEBUG ((DEBUG_ERROR, "%a: Fail to configure DI\n", __FUNCTION__));
> +      goto Exit;
> +    }
> +
> +    switch (CurrentDisplayInterface) {
> +    case HdmiDisplay:
> +      Status = SetHdmiDisplay (pDisplayInterfaceContext, pCurrentDisplayTiming);
> +      if (Status != EFI_SUCCESS) {
> +        DEBUG ((DEBUG_ERROR, "%a: Fail to set HDMI timing\n", __FUNCTION__));
> +        goto Exit;
> +      }
> +      break;
> +    case Lvds0Display:
> +    case Lvds1Display:
> +      break;
> +    default:
> +      Status = EFI_UNSUPPORTED;
> +      break;
> +    }
> +    if (EFI_ERROR (Status)) {
> +      goto Exit;
> +    }
> +
> +    Status = ConfigureFrameBuffer (
> +               pDisplayInterfaceContext,
> +               &pDisplayConfig->DisplaySurface[DisplayModeIndex]
> +             );
> +    if (Status != EFI_SUCCESS) {
> +      DEBUG ((DEBUG_ERROR,
> +        "%a: Fail to configure frame buffer (%d)\n",
> +        __FUNCTION__, DisplayModeIndex));
> +      goto Exit;
> +    }
> +  }
> +
> +Exit:
> +  return Status;
> +}
> +
> +EFI_STATUS
> +AllocateFrameBuffer (
> +  IN OUT  SURFACE_INFO  *SurfaceInfoPtr
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  DEBUG ((DEBUG_INFO, "%a: Enter\n", __FUNCTION__));
> +  if ((SurfaceInfoPtr->Width == 0) || (SurfaceInfoPtr->Height == 0)) {
> +    Status = EFI_INVALID_PARAMETER;
> +    goto Exit;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "%a: Frame Buffer AddrP=%Xh\n",
> +    __FUNCTION__, FixedPcdGet32 (PcdFrameBufferBase)));
> +  DEBUG ((DEBUG_INFO, "%a: Frame Buffer Size=%Xh\n",
> +    __FUNCTION__, FixedPcdGet32 (PcdFrameBufferSize)));
> +
> +  SurfaceInfoPtr->VirtAddrPtr = (VOID *)(UINTN)FixedPcdGet32 (PcdFrameBufferBase);
> +  SurfaceInfoPtr->PhyAddr = (UINT32)(SurfaceInfoPtr->VirtAddrPtr);
> +  SurfaceInfoPtr->Pitch = SurfaceInfoPtr->Width;
> +
> +  DEBUG ((DEBUG_INFO,
> +    "%a: Allocate FB PhyAddr %x VirtAddr %x\n",
> +    __FUNCTION__, SurfaceInfoPtr->PhyAddr, SurfaceInfoPtr->VirtAddrPtr));
> +
> +  Status = EFI_SUCCESS;
> +
> +Exit:
> +  DEBUG ((DEBUG_INFO, "%a: Exit = %Xh\n",
> +    __FUNCTION__, Status));
> +  return Status;
> +}
> +
> +EFI_STATUS
> +ConfigureFrameBuffer (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *DisplayInterfaceContextPtr,
> +  IN  SURFACE_INFO                *FrameBufferPtr
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  // Only support single display for now
> +  Status = ConfigureCpmemFrameBuffer (
> +             DisplayInterfaceContextPtr,
> +             IDMAC_CHANNEL_DP_PRIMARY_FLOW_MAIN_PLANE,
> +             FrameBufferPtr
> +           );
> +  if (Status != EFI_SUCCESS) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to configure CPMEM\n", __FUNCTION__));
> +    goto Exit;
> +  }
> +
> +Exit:
> +  return Status;
> +}
> +
> +UINT32
> +GetColorDepth (
> +  IN  PIXEL_FORMAT  PixelFormat
> +  )
> +{
> +  UINT32  BitDepth;
> +
> +  switch (PixelFormat) {
> +  case PIXEL_FORMAT_ARGB32:
> +  case PIXEL_FORMAT_BGRA32:
> +    BitDepth = 8;
> +    break;
> +  default:
> +    BitDepth = 0;
> +    break;
> +  }
> +
> +  return BitDepth;
> +}
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Display.h b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Display.h
> new file mode 100644
> index 000000000000..cbcea1219743
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Display.h
> @@ -0,0 +1,175 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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_

IMX_ prefix.

> +
> +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 {
> +  DisplayInterface0,
> +  DisplayInterface1,
> +  DisplayInterfaceMax,
> +} DISPLAY_INTERFACE_INDEX;
> +
> +typedef enum {
> +  HdmiDisplay,
> +  MipiDisplay,
> +  Lvds0Display,
> +  Lvds1Display,
> +  DisplayTypeMax, // Only 4 display types supported by IPU
> +  NoDisplayType = DisplayTypeMax,
> +} DISPLAY_INTERFACE_TYPE;
> +
> +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_TYPE displayInterface;
> +
> +  VOID *MmioBasePtr;
> +  VOID *IpuMmioBasePtr;
> +  VOID *CpMemParamBasePtr;
> +  IPU_DIx_REGS *IpuDiRegsPtr;
> +  UINT32 EdidDataSize;
> +  UINT8 EdidData[256];
> +  DISPLAY_TIMING PreferredTiming;
> +} DISPLAY_INTERFACE_CONTEXT, *PDISPLAY_INTERFACE_CONTEXT;
> +
> +typedef struct _DISPLAY_CONFIG {
> +  DISPLAY_MODE DisplayMode;
> +  DISPLAY_INTERFACE_TYPE DiOrder[DisplayTypeMax];
> +  SURFACE_INFO DisplaySurface[DisplayTypeMax];
> +  DISPLAY_TIMING DisplayTiming[DisplayTypeMax];
> +  UINT32 OsHandle[DisplayTypeMax];
> +} DISPLAY_CONFIG, *PDISPLAY_CONFIG;
> +
> +typedef struct _DISPLAY_CONTEXT {
> +  DISPLAY_CONFIG DisplayConfig;
> +  VOID *IoMuxMmioBasePtr;
> +  VOID *IpuMmioBasePtr[IPU_TOTAL];
> +  DISPLAY_INTERFACE_CONTEXT DiContext[DisplayTypeMax];
> +} DISPLAY_CONTEXT, *PDISPLAY_CONTEXT;
> +
> +extern DISPLAY_TIMING DefaultTiming;

g- or m- prefix for an exported variable.

> +
> +EFI_STATUS
> +GetPreferredTiming (
> +  IN  UINT8           *EdidDataPtr,
> +  IN  UINT32          EdidDataSize,
> +  IN  DISPLAY_TIMING  *PreferredTimingPtr
> +  );
> +
> +EFI_STATUS
> +InitDisplay (
> +  IN  DISPLAY_CONTEXT   **DisplayConfigPPtr
> +  );
> +
> +EFI_STATUS
> +ValidateDisplayConfig (
> +  IN  DISPLAY_CONTEXT     *DisplayContextPtr,
> +  IN  DISPLAY_MODE        DisplayMode,
> +  IN  DISPLAY_INTERFACE_TYPE   *DiOrder
> +  );
> +
> +EFI_STATUS
> +SetDisplayConfig (
> +  IN OUT  DISPLAY_CONTEXT     *DisplayContextPtr,
> +  IN      DISPLAY_MODE        DisplayMode,
> +  IN      DISPLAY_INTERFACE_TYPE   *DiOrder
> +  );
> +
> +EFI_STATUS
> +ApplyDisplayConfig (
> +  IN OUT  DISPLAY_CONTEXT     *DisplayContextPtr,
> +  IN      DISPLAY_MODE        DisplayMode,
> +  IN      DISPLAY_INTERFACE_TYPE   *DiOrder
> +  );
> +
> +EFI_STATUS
> +AllocateFrameBuffer (
> +  IN OUT  SURFACE_INFO  *SurfaceInfoPtr
> +  );
> +
> +EFI_STATUS
> +ConfigureFrameBuffer (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *DisplayInterfaceContextPtr,
> +  IN  SURFACE_INFO                *FrameBufferPtr
> +  );
> +
> +UINT32
> +GetColorDepth (
> +  IN  PIXEL_FORMAT  PixelFormat
> +  );
> +
> +#endif  /* _DISPLAY_H_ */
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/DisplayController.c b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/DisplayController.c
> new file mode 100644
> index 000000000000..7a5fc7e3d6c3
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/DisplayController.c
> @@ -0,0 +1,399 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include <iMX6.h>
> +#include <iMX6ClkPwr.h>
> +#include <iMXDisplay.h>
> +
> +#include "Ipu.h"
> +#include "Display.h"
> +#include "DisplayController.h"
> +#include "DisplayInterface.h"
> +
> +#ifdef DEBUG
> +VOID
> +DumpBasicDisplayControllerReg (
> +  IN  VOID  *IpuMmioBasePtr
> +  )
> +{
> +  UINT32 Counter;
> +  UINT32 Index;
> +  UINT32 RegVal;
> +
> +  DEBUG ((DEBUG_VERBOSE, "%a: ------- DC Register Dump -------\n", __FUNCTION__));
> +
> +  DEBUG ((DEBUG_VERBOSE, "%a: ## Configuration\n\n", __FUNCTION__));
> +  RegVal = IpuRead32 (IpuMmioBasePtr, IPU_DC_WR_CH_CONF_5_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DC_WR_CH_CONF_5_OFFSET %x\n",
> +    __FUNCTION__, RegVal));
> +  RegVal = IpuRead32 (IpuMmioBasePtr, IPU_DC_WR_CH_CONF_1_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DC_WR_CH_CONF_1_OFFSET %x\n",
> +    __FUNCTION__, RegVal));
> +  RegVal = IpuRead32 (IpuMmioBasePtr, IPU_DC_DISP_CONF1_0_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DC_DISP_CONF1_0_OFFSET %x\n",
> +    __FUNCTION__, RegVal));
> +  RegVal = IpuRead32 (IpuMmioBasePtr, IPU_DC_DISP_CONF1_1_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DC_DISP_CONF1_1_OFFSET %x\n",
> +    __FUNCTION__, RegVal));
> +  RegVal = IpuRead32 (IpuMmioBasePtr, IPU_DC_DISP_CONF1_2_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DC_DISP_CONF1_2_OFFSET %x\n",
> +    __FUNCTION__, RegVal));
> +  RegVal = IpuRead32 (IpuMmioBasePtr, IPU_DC_DISP_CONF1_3_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DC_DISP_CONF1_3_OFFSET %x\n",
> +    __FUNCTION__, RegVal));
> +  RegVal = IpuRead32 (IpuMmioBasePtr, IPU_DC_DISP_CONF2_0_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DC_DISP_CONF2_0_OFFSET %x\n",
> +    __FUNCTION__, RegVal));
> +  RegVal = IpuRead32 (IpuMmioBasePtr, IPU_DC_GEN_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DC_GEN_OFFSET %x\n",
> +    __FUNCTION__, RegVal));
> +
> +  DEBUG ((DEBUG_VERBOSE, "%a: ## Bus MAPPING\n\n", __FUNCTION__));
> +  {

Please move the { to the end of the preceding line.

> +    for (Counter = 0, Index = 0; Index < 26; Counter += 4, ++Index) {

++ suffix rather than prefix, please.

> +      RegVal = IpuRead32 (IpuMmioBasePtr, IPU_DC_MAP_CONF_0_OFFSET + Counter);
> +      DEBUG ((DEBUG_VERBOSE, "%a: IPU_DC_MAP_CONF_%d %x\n",
> +        __FUNCTION__, Index, RegVal));
> +    }
> +  }
> +
> +  DEBUG ((DEBUG_VERBOSE, "%a: ## Channel MicroCode setup\n\n", __FUNCTION__));
> +  // Only print out channel 5 as we only support single mode for now
> +  RegVal = IpuRead32 (IpuMmioBasePtr, IPU_DC_RL0_CH_5_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DC_RL0_CH_5_OFFSET %x\n",
> +    __FUNCTION__, RegVal));
> +  RegVal = IpuRead32 (IpuMmioBasePtr, IPU_DC_RL1_CH_5_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DC_RL1_CH_5_OFFSET %x\n",
> +    __FUNCTION__, RegVal));
> +  RegVal = IpuRead32 (IpuMmioBasePtr, IPU_DC_RL2_CH_5_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DC_RL2_CH_5_OFFSET %x\n",
> +    __FUNCTION__, RegVal));
> +  RegVal = IpuRead32 (IpuMmioBasePtr, IPU_DC_RL3_CH_5_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DC_RL3_CH_5_OFFSET %x\n",
> +    __FUNCTION__, RegVal));
> +  RegVal = IpuRead32 (IpuMmioBasePtr, IPU_DC_RL4_CH_5_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DC_RL4_CH_5_OFFSET %x\n",
> +    __FUNCTION__, RegVal));
> +
> +  DEBUG ((DEBUG_VERBOSE, "%a: ## MicroCode\n\n", __FUNCTION__));
> +  // There are 256 template, only print out the first 10
> +  for (Counter = 0, Index = 0; Index < 10; Counter += 8, ++Index) {
> +    DEBUG ((DEBUG_VERBOSE, "%a: (%d)\n", __FUNCTION__, Index));
> +    RegVal = IpuRead32 (
> +                IpuMmioBasePtr,
> +                IPU_DC_TEMPLATE_REGS_ADDR_OFFSET + Counter);
> +    DEBUG ((DEBUG_VERBOSE, "%a: - %8x\n", __FUNCTION__, RegVal));
> +    RegVal = IpuRead32 (
> +                IpuMmioBasePtr,
> +                IPU_DC_TEMPLATE_REGS_ADDR_OFFSET + Counter + 4);
> +    DEBUG ((DEBUG_VERBOSE, "%a:  %8x -\n", __FUNCTION__, RegVal));
> +  }
> +
> +  DEBUG ((DEBUG_VERBOSE, "%a: ---------------------------\n\n", __FUNCTION__));
> +}
> +#endif /* DEBUG */
> +
> +EFI_STATUS
> +WriteWrodCommand (
> +  IN  VOID    *IpuMmioBasePtr,
> +  IN  UINT32  MicroCodeAddr,
> +  IN  UINT32  Data,
> +  IN  UINT32  Mapping,
> +  IN  UINT32  WaveForm,
> +  IN  UINT32  GlueLogic,
> +  IN  UINT32  Sync
> +  )
> +{
> +  UINT32                            MicroCodeAddrOffset;
> +  DISPLAY_CONTROLLER_WROD_COMMAND   WrodCommand;
> +
> +
> +  MicroCodeAddrOffset = IPU_DC_TEMPLATE_REGS_ADDR_OFFSET + (MicroCodeAddr * 8);
> +  ZeroMem ((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 EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +SetDisplayControllerChannelState (
> +  IN  VOID *IpuMmioBasePtr,
> +  IN  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 EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +ConfigureDisplayControllerChannel (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *DisplayInterfaceContextPtr,
> +  IN  DISPLAY_INTERFACE_TYPE           DisplayInterface,
> +  IN  UINT32                      DisplayIndex,
> +  IN  DISPLAY_TIMING              *DisplayTimingPtr
> +  )
> +{
> +  VOID                          *pIpuMmioBase;
> +  DC_MAP_CONF_OFFSET_MASK_REG   DcConfOffsetMaskReg;
> +  IPUx_DC_MAP_CONF_MAP_REG      DcMapConf0Reg;
> +  IPU_DC_RL0_CH_5_REG           DcRl0Ch5Reg;
> +  IPU_DC_RL2_CH_5_REG           DcRl2Ch5Reg;
> +  IPU_DC_RL4_CH_5_REG           DcRl4Ch5Reg;
> +  IPUx_DC_DISP_CONF1_REG        DisplayConfig1Reg;
> +  IPUx_IPU_DC_GEN_REG           DisplayControllerGenReg;
> +  UINT32                        Mask0;
> +  UINT32                        Mask1;
> +  UINT32                        Mask2;
> +  UINT32                        Offset0;
> +  UINT32                        Offset1;
> +  UINT32                        Offset2;
> +  EFI_STATUS                    Status;
> +  IPU_DC_WR_CH_CONF_5_REG       WrChConfigReg;
> +
> +  pIpuMmioBase = DisplayInterfaceContextPtr->IpuMmioBasePtr;
> +  Status = EFI_SUCCESS;
> +
> +  ZeroMem ((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 (pIpuMmioBase, IPU_DC_WR_CH_CONF_5_OFFSET, WrChConfigReg.Reg);
> +  // Start address of memory always 0
> +  IpuWrite32 (pIpuMmioBase, IPU_DC_WR_CH_ADDR_5_OFFSET, 0);
> +
> +  ZeroMem ((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 (pIpuMmioBase, IPU_DC_WR_CH_CONF_1_OFFSET, WrChConfigReg.Reg);
> +  IpuWrite32 (pIpuMmioBase, IPU_DC_WR_CH_ADDR_1_OFFSET, 0);
> +
> +  DisplayConfig1Reg.DISP_TYP = 0x02; // What is byte_enabled
> +  DisplayConfig1Reg.ADDR_INCREMENT = 0; // Increase by 1 byte
> +  DisplayConfig1Reg.ADDR_BE_L_INC = 0;
> +  DisplayConfig1Reg.MCU_ACC_LB_MASK_3 = 0;
> +  DisplayConfig1Reg.DISP_RD_VALUE_PTR = 0;
> +  IpuWrite32 (pIpuMmioBase, IPU_DC_DISP_CONF1_0_OFFSET, DisplayConfig1Reg.Reg);
> +
> +  // Set stride
> +  IpuWrite32 (pIpuMmioBase, IPU_DC_DISP_CONF2_0_OFFSET, DisplayTimingPtr->VActive);
> +
> +  // Setup general register. Channel 5 is the main channel.
> +  DisplayControllerGenReg.Sync_1_6 = 2; // Sync flow
> +  DisplayControllerGenReg.MASK_EN = 0; // Disable masking
> +  DisplayControllerGenReg.MASK4CHAN_5 = 0; // Ignore as mask is disabled
> +  DisplayControllerGenReg.SYNC_PRIORITY_5 = 1; // Higher sync priority for channel 5
> +  DisplayControllerGenReg.SYNC_PRIORITY_1 = 0; // Lower sync priority
> +  DisplayControllerGenReg.DC_CH5_TYPE = 0; // Normal mode, sync flow through channel 5
> +  DisplayControllerGenReg.DC_BK_EN = 0; // No cursor support
> +  DisplayControllerGenReg.DC_BKDIV = 0; // No cursor support
> +  IpuWrite32 (pIpuMmioBase, IPU_DC_GEN_OFFSET, DisplayControllerGenReg.Reg);
> +
> +  // Do not use any user event
> +  IpuWrite32 (pIpuMmioBase, IPU_DC_UGDE0_0_OFFSET, 0);
> +  IpuWrite32 (pIpuMmioBase, IPU_DC_UGDE1_0_OFFSET, 0);
> +  IpuWrite32 (pIpuMmioBase, IPU_DC_UGDE2_0_OFFSET, 0);
> +  IpuWrite32 (pIpuMmioBase, IPU_DC_UGDE3_0_OFFSET, 0);
> +
> +  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 (pIpuMmioBase, IPU_DC_MAP_CONF_0_OFFSET, DcMapConf0Reg.Reg);
> +
> +  switch (DisplayInterface) {
> +  // PixelFormat RGB24
> +  case HdmiDisplay:
> +    Mask0 = 0xFF;
> +    Mask1 = 0xFF;
> +    Mask2 = 0xFF;
> +    Offset0 = 7;
> +    Offset1 = 15;
> +    Offset2 = 23;
> +    break;
> +  // PixelFormat RGB666
> +  case Lvds0Display:
> +  case Lvds1Display:
> +    Mask0 = 0xFC;
> +    Mask1 = 0xFC;
> +    Mask2 = 0xFC;
> +    Offset0 = 5;
> +    Offset1 = 11;
> +    Offset2 = 17;
> +    break;
> +  default:
> +    ASSERT (FALSE);
> +    Status = EFI_UNSUPPORTED;
> +    break;
> +  }
> +  if (EFI_ERROR (Status)) {
> +    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 (pIpuMmioBase, 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 (pIpuMmioBase, IPU_DC_MAP_CONF_16_OFFSET, DcConfOffsetMaskReg.Reg);
> +
> +  // Setup microcode
> +  // New line event point to the first microcode (0)
> +  ZeroMem ((VOID *)&DcRl0Ch5Reg, sizeof (DcRl0Ch5Reg));
> +  DcRl0Ch5Reg.COD_NL_START_CHAN_5 = 0;
> +  DcRl0Ch5Reg.COD_NL_PRIORITY_CHAN_5 = 3;
> +  IpuWrite32 (pIpuMmioBase, IPU_DC_RL0_CH_5_OFFSET, DcRl0Ch5Reg.Reg);
> +
> +  // End of line event point to the second microcode (1)
> +  ZeroMem ((VOID *)&DcRl2Ch5Reg, sizeof (DcRl2Ch5Reg));
> +  DcRl2Ch5Reg.COD_EOL_START_CHAN_5 = 1;
> +  DcRl2Ch5Reg.COD_EOL_PRIORITY_CHAN_5 = 2;
> +  IpuWrite32 (pIpuMmioBase, IPU_DC_RL2_CH_5_OFFSET, DcRl2Ch5Reg.Reg);
> +
> +  // New data event point to the first microcode (2)
> +  ZeroMem ((VOID *)&DcRl4Ch5Reg, sizeof (DcRl4Ch5Reg));
> +  DcRl4Ch5Reg.COD_NEW_DATA_START_CHAN_5 = 2;
> +  DcRl4Ch5Reg.COD_NEW_DATA_PRIORITY_CHAN_5 = 1;
> +  IpuWrite32 (pIpuMmioBase, 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 (
> +    pIpuMmioBase,
> +    0,
> +    0,
> +    1,
> +    DwGen0,
> +    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 (
> +    pIpuMmioBase,
> +    1,
> +    0,
> +    1,
> +    DwGen0,
> +    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 (
> +    pIpuMmioBase,
> +    2,
> +    0,
> +    1,
> +    DwGen0,
> +    8,
> +    DI_COUNTER_5_ACTIVE_CLOCK
> +  );
> +
> +  // Turn on channel without anti tearing
> +  SetDisplayControllerChannelState (
> +    DisplayInterfaceContextPtr->IpuMmioBasePtr,
> +    PROG_CHAN_TYP_NORMAL
> +  );
> +
> +#ifdef DEBUG
> +  DumpBasicDisplayControllerReg (pIpuMmioBase);
> +#endif /* DEBUG */
> +
> +  Status = EFI_SUCCESS;
> +
> +Exit:
> +  return Status;
> +}
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/DisplayController.h b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/DisplayController.h
> new file mode 100644
> index 000000000000..46f0fa66d674
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/DisplayController.h
> @@ -0,0 +1,331 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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 _DISPLAY_CONTROLLER_H_
> +#define _DISPLAY_CONTROLLER_H_

IMX_ prefix please.

> +
> +#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;
> +
> +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;
> +  };
> +} DISPLAY_CONTROLLER_WROD_COMMAND;
> +
> +#pragma pack(pop)
> +
> +EFI_STATUS
> +SetDisplayControllerChannelState (
> +  IN  VOID *IpuMmioBasePtr,
> +  IN  PROG_CHAN_TYP ChannelType
> +  );
> +
> +EFI_STATUS
> +ConfigureDisplayControllerChannel (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *DisplayInterfaceContextPtr,
> +  IN  DISPLAY_INTERFACE_TYPE           DisplayInterface,
> +  IN  UINT32                      DisplayIndex,
> +  IN  DISPLAY_TIMING              *DisplayTimingPtr
> +  );
> +
> +#endif  /* _DISPLAY_CONTROLLER_H_ */
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/DisplayInterface.c b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/DisplayInterface.c
> new file mode 100644
> index 000000000000..b36d03239652
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/DisplayInterface.c
> @@ -0,0 +1,458 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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 <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include <iMX6.h>
> +#include <iMX6ClkPwr.h>
> +#include <iMXDisplay.h>
> +
> +#include "Ipu.h"
> +#include "Display.h"
> +#include "DisplayInterface.h"
> +
> +#ifdef DEBUG
> +VOID
> +DumpBasicDisplayInterfaceReg (
> +  IN  VOID          *IpuMmioBasePtr,
> +  IN  IPU_DIx_REGS  *IpuDiRegsPtr
> +  )
> +{
> +  UINT32 index, setNumber, regVal;
> +  UINT32 printTotalGen = 8; // Limit printing (max 12)
> +
> +  DEBUG ((DEBUG_VERBOSE, "%a: ------- DI Register Dump -------\n", __FUNCTION__));
> +  // Print out generator value for D0
> +  DEBUG ((DEBUG_VERBOSE, "%a: ## Wave Gen\n", __FUNCTION__));
> +  for (index = 0; index < printTotalGen; ++index) {
> +    regVal = READ_WAVE_GEN (IpuDiRegsPtr, index);
> +    DEBUG ((DEBUG_VERBOSE, "%a: DI0_DW_GEN_%d 0x%08x\n",
> +      __FUNCTION__, index, regVal));
> +  }
> +  // Print out generator value for D0
> +  DEBUG ((DEBUG_VERBOSE, "%a: ## Wave Set\n", __FUNCTION__));
> +  for (index = 0; index < printTotalGen; ++index) {
> +    for (setNumber = 0; setNumber < 4; ++setNumber) {
> +      regVal = READ_WAVE_SET (IpuDiRegsPtr, index, setNumber);
> +      DEBUG ((DEBUG_VERBOSE, "%a: DI0_DW_SET%d_%d 0x%08x\n",
> +        __FUNCTION__, setNumber, index, regVal));
> +    }
> +  }
> +
> +  regVal = IpuRead32 (IpuMmioBasePtr, IPU_IPU_PM_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_IPU_PM_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_BS_CLKGEN0_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_BS_CLKGEN0_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_BS_CLKGEN1_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_BS_CLKGEN1_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_SCR_CONF_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_SCR_CONF_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_SW_GEN0_1_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_SW_GEN0_1_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_SW_GEN1_1_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_SW_GEN1_1_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_SW_GEN0_2_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_SW_GEN0_2_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_SW_GEN1_2_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_SW_GEN1_2_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_SW_GEN0_3_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_SW_GEN0_3_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_SW_GEN1_3_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_SW_GEN1_3_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_SW_GEN0_4_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_SW_GEN0_4_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_SW_GEN1_4_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_SW_GEN1_4_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_SW_GEN0_5_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_SW_GEN0_5_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_SW_GEN1_5_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_SW_GEN1_5_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +
> +  for (index = 0; index < 5; ++index) {
> +    regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_STP_REP_OFFSET +  (index * 0x4));
> +    DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_STP_%d_REP_OFFSET %x\n",
> +      __FUNCTION__, index + 1, regVal));
> +  }
> +
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_SYNC_AS_GEN_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_SYNC_AS_GEN_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_GENERAL_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_GENERAL_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_DIx_POL_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_DIx_POL_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +  regVal = DiRead32 (IpuDiRegsPtr, IPU_IPU_DISP_GEN_OFFSET);
> +  DEBUG ((DEBUG_VERBOSE, "%a: IPU_IPU_DISP_GEN_OFFSET %x\n",
> +    __FUNCTION__, regVal));
> +  DEBUG ((DEBUG_VERBOSE, "%a: ------------------------------\n\n", __FUNCTION__));
> +}
> +#endif /* DEBUG */
> +
> +VOID
> +ConfigureSyncWave (
> +  IN  VOID          *IpuMmioBasePtr,
> +  IN  IPU_DIx_REGS  *IpuDiRegsPtr,
> +  IN  UINT32        CounterIndex,
> +  IN  UINT32        RunValue,
> +  IN  UINT32        RunResolution,
> +  IN  UINT32        OffsetValue,
> +  IN  UINT32        OffsetResolution,
> +  IN  UINT32        CounterPolarityGenEn,
> +  IN  UINT32        CounterAutoReload,
> +  IN  UINT32        CounterClearSelect,
> +  IN  UINT32        CounterDown,
> +  IN  UINT32        CounterPolarityTriggerSelect,
> +  IN  UINT32        CounterPolarityClearSelect,
> +  IN  UINT32        CounterUp,
> +  IN  UINT32        StepRepeat
> +  )
> +{
> +  IPUx_DIx_SW_GEN0_x_REG  DiSwGen0Reg;
> +  IPUx_DIx_SW_GEN1_x_REG  DiSwGen1Reg;
> +  UINT32                  StepIndex;
> +  IPUx_DIx_STP_REP_REG    StepRepeatReg;
> +
> +  ZeroMem ((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
> +  );
> +
> +  ZeroMem ((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
> +  );
> +
> +  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
> +  );
> +}
> +
> +EFI_STATUS
> +ConfigureDisplayInterface (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *DisplayInterfaceContextPtr,
> +  IN  UINT32                      DisplayIndex,
> +  IN  DISPLAY_TIMING              *DisplayTimingPtr
> +  )
> +{
> +  IPU_DIx_REGS              *pIpuDiRegs;
> +  VOID                      *pIpuMmioBase;
> +  UINT32                    BaseDiv;
> +  UINT32                    DispGenReg;
> +  UINT64                    DisplayInterfaceFrequency;
> +  IPUx_DIx_DW_GEN_REG       DixDwGenReg;
> +  IPUx_DIx_DW_SET_REG       DixDwSetReg;
> +  IPUx_DIx_GENERAL_REG      DixGeneralReg;
> +  IPUx_DIx_POL_REG          DixPolReg;
> +  IPUx_DIx_SYNC_AS_GEN_REG  DixSyncAsGenReg;
> +  UINT32                    HorizontalLength;
> +  EFI_STATUS                Status;
> +  UINT32                    VerticalLength;
> +
> +  DisplayInterfaceFrequency = DisplayTimingPtr->PixelClock;
> +  HorizontalLength = DisplayTimingPtr->HActive + DisplayTimingPtr->HBlank;
> +  VerticalLength = DisplayTimingPtr->VActive + DisplayTimingPtr->VBlank;
> +  pIpuMmioBase = DisplayInterfaceContextPtr->IpuMmioBasePtr;
> +  pIpuDiRegs = DisplayInterfaceContextPtr->IpuDiRegsPtr;
> +  Status = EFI_SUCCESS;
> +
> +  Status = ImxSetPll5ReferenceRate (DisplayTimingPtr->PixelClock);
> +  if (Status != EFI_SUCCESS) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to setup PLL5=%r\n", __FUNCTION__, 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) ((DisplayInterfaceFrequency << 4) / DisplayTimingPtr->PixelClock);
> +  DiWrite32 (pIpuDiRegs, 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 (pIpuDiRegs, IPU_DIx_BS_CLKGEN1_OFFSET, BaseDiv << 16);
> +  // Calculate divisor, again this would usually be 1.
> +  BaseDiv = (UINT32) (DisplayInterfaceFrequency / DisplayTimingPtr->PixelClock);
> +
> +  // Set up wave, there 12 wave quartet, for now default to the first.
> +  // Each wave quartet has 4 set register
> +  // Set 0 is just a blank signal where up and down is set to 0
> +  ZeroMem ((VOID *)&DixDwSetReg, sizeof (DixDwSetReg));
> +  DixDwSetReg.dix_data_cnt_upx_i = 0;
> +  DixDwSetReg.dix_data_cnt_downx_i = 0;
> +  WRITE_WAVE_SET (
> +    pIpuDiRegs,
> +    DwGen0,
> +    DwSet0,
> +    DixDwSetReg.Reg
> +  );
> +
> +  // Set 3 is setup to match pixel clock
> +  ZeroMem ((VOID *)&DixDwSetReg, sizeof (DixDwSetReg));
> +  DixDwSetReg.dix_data_cnt_upx_i = 0;
> +  DixDwSetReg.dix_data_cnt_downx_i = BaseDiv * 2;
> +  WRITE_WAVE_SET (
> +    pIpuDiRegs,
> +    DwGen0,
> +    DwSet3,
> +    DixDwSetReg.Reg
> +  );
> +
> +  // All pins blank signal except pin 15
> +  ZeroMem ((VOID *)&DixDwGenReg, sizeof (DixDwGenReg));
> +  DixDwGenReg.dix_pt_0_i = DwSet0;
> +  DixDwGenReg.dix_pt_1_i = DwSet0;
> +  DixDwGenReg.dix_pt_2_i = DwSet0;
> +  DixDwGenReg.dix_pt_3_i = DwSet0;
> +  DixDwGenReg.dix_pt_4_i = DwSet3;
> +  DixDwGenReg.dix_pt_5_i = DwSet0;
> +  DixDwGenReg.dix_pt_6_i = DwSet0;
> +  DixDwGenReg.dix_cst_i = DwSet0;
> +  // Reuse the base divisor to determine extra IPU cycles.
> +  DixDwGenReg.dix_componnent_size_i = BaseDiv - 1;
> +  DixDwGenReg.dix_access_size_i = BaseDiv - 1;
> +  WRITE_WAVE_GEN (pIpuDiRegs, DwGen0, DixDwGenReg.Reg);
> +
> +  // Spec mention this as number of display rows but display only works
> +  // properly if this is setup as vertical total
> +  DiWrite32 (pIpuDiRegs, IPU_DIx_SCR_CONF_OFFSET, VerticalLength - 1);
> +
> +  // Internal HSYNC
> +  ConfigureSyncWave (
> +    pIpuMmioBase,
> +    pIpuDiRegs,
> +    DI_COUNTER_1_INTERNAL_HSYNC, // CounterIndex
> +    HorizontalLength - 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 (
> +    pIpuMmioBase,
> +    pIpuDiRegs,
> +    DI_COUNTER_2_OUTPUT_HSYNC, // CounterIndex
> +    HorizontalLength - 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 (
> +    pIpuMmioBase,
> +    pIpuDiRegs,
> +    DI_COUNTER_3_OUTPUT_VSYNC, // CounterIndex
> +    VerticalLength - 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 (
> +    pIpuMmioBase,
> +    pIpuDiRegs,
> +    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 (
> +    pIpuMmioBase,
> +    pIpuDiRegs,
> +    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
> +  );
> +
> +  ZeroMem ((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.
> +  DixSyncAsGenReg.dix_sync_start = 2;
> +  DiWrite32 (pIpuDiRegs, IPU_DIx_SYNC_AS_GEN_OFFSET, DixSyncAsGenReg.Reg);
> +
> +  // Setup general register
> +  ZeroMem ((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 (DisplayInterfaceContextPtr->displayInterface) {
> +  case HdmiDisplay:
> +    // 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 = EFI_UNSUPPORTED;
> +    DEBUG ((DEBUG_ERROR, "%a: Unsupported display interface %d\n",
> +      __FUNCTION__, DisplayInterfaceContextPtr->displayInterface));
> +    break;
> +  }
> +  if (EFI_ERROR (Status)) {
> +    goto Exit;
> +  }
> +  DiWrite32 (pIpuDiRegs, IPU_DIx_GENERAL_OFFSET, DixGeneralReg.Reg);
> +
> +  ZeroMem ((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 (pIpuDiRegs, IPU_DIx_POL_OFFSET, DixPolReg.Reg);
> +
> +  DispGenReg = IpuRead32 (pIpuMmioBase, IPU_IPU_DISP_GEN_OFFSET);
> +  DispGenReg &= ~(0x0F << 18);
> +  DispGenReg |= (2 << 18);
> +  IpuWrite32 (pIpuMmioBase, IPU_IPU_DISP_GEN_OFFSET, DispGenReg);
> +
> +#ifdef DEBUG
> +  DumpBasicDisplayInterfaceReg (pIpuMmioBase, pIpuDiRegs);
> +#endif /* DEBUG */
> +
> +  Status = EFI_SUCCESS;
> +
> +Exit:
> +  return Status;
> +}
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/DisplayInterface.h b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/DisplayInterface.h
> new file mode 100644
> index 000000000000..786ef1fff5f0
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/DisplayInterface.h
> @@ -0,0 +1,195 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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 _DISPLAY_INTERFACE_H_
> +#define _DISPLAY_INTERFACE_H_

IMX_ prefix please.

> +
> +#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)
> +
> +#define DI_COUNTER_DISABLED 0
> +#define DI_COUNTER_0_DISPLAY_CLOCK 0
> +#define DI_COUNTER_1_INTERNAL_HSYNC 1
> +#define DI_COUNTER_2_OUTPUT_HSYNC 2
> +#define DI_COUNTER_3_OUTPUT_VSYNC 3
> +#define DI_COUNTER_4_ACTIVE_LINE 4
> +#define DI_COUNTER_5_ACTIVE_CLOCK 5
> +
> +typedef enum {
> +  DwGen0,
> +  DwGen1,
> +  DwGen2,
> +  DwGen3,
> +  DwGen4,
> +  DwGen5,
> +  DwGen6,
> +  DwGen7,
> +  DwGen8,
> +  DwGen9,
> +  DwGen10,
> +  DwGen11,
> +  DwGenMax
> +} DW_GEN;
> +
> +typedef enum {
> +  DwSet0,
> +  DwSet1,
> +  DwSet2,
> +  DwSet3,
> +  DwSetMax
> +} DW_SET;
> +
> +#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)
> +
> +EFI_STATUS
> +ConfigureDisplayInterface (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *DisplayInterfaceContextPtr,
> +  IN  UINT32                      DisplayIndex,
> +  IN  DISPLAY_TIMING              *DisplayTimingPtr
> +  );
> +
> +#endif  /* _DISPLAY_INTERFACE_H_ */
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Edid.c b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Edid.c
> new file mode 100644
> index 000000000000..cc6557a58138
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Edid.c
> @@ -0,0 +1,96 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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 <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include <iMX6.h>
> +#include <iMX6ClkPwr.h>
> +#include <iMXDisplay.h>
> +
> +#include "Display.h"
> +#include "Edid.h"
> +#include "Ddc.h"
> +
> +EFI_STATUS
> +ReadEdid (
> +  IN  DISPLAY_CONTEXT     *DisplayContextPtr,
> +  IN  DISPLAY_INTERFACE_TYPE   DisplayInterface,
> +  IN  UINT8               *EdidDataPtr,
> +  OUT UINT32              *EdidDataSizePtr
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status = Imx6DdcRead (
> +             DisplayContextPtr,
> +             DisplayInterface,
> +             EDID_I2C_ADDRESS,
> +             0,
> +             EDID_MIN_SIZE,
> +             EdidDataPtr
> +           );
> +  if (Status != EFI_SUCCESS) {
> +    goto Exit;
> +  }
> +
> +  Status = ValidateEdidData (
> +             EdidDataPtr
> +           );
> +  if (Status != EFI_SUCCESS) {
> +    DEBUG ((DEBUG_WARN, "%a: Invalid EDID data\n", __FUNCTION__));
> +    goto Exit;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "%a: EDID initialized\n", __FUNCTION__));
> +
> +  *EdidDataSizePtr = EDID_MIN_SIZE;
> +
> +Exit:
> +  return Status;
> +}
> +
> +EFI_STATUS
> +GetEdidPreferredTiming (
> +  IN  UINT8           *EdidDataPtr,
> +  IN  UINT32          EdidDataSizePtr,
> +  OUT DISPLAY_TIMING  *PreferredTiming
> +  )
> +{
> +  DETAILED_TIMING_DESCRIPTOR  *pEdidPreferredTiming;
> +  EFI_STATUS                  Status;
> +
> +  if (EdidDataSizePtr < EDID_MIN_SIZE) {
> +    DEBUG ((DEBUG_WARN, "%a: Insufficient EDID data\n", __FUNCTION__));
> +    Status = EFI_INVALID_PARAMETER;
> +    goto Exit;
> +  }
> +
> +  pEdidPreferredTiming = (DETAILED_TIMING_DESCRIPTOR *)&EdidDataPtr[EDID_DTD_1_OFFSET];
> +  Status = ConvertDTDToDisplayTiming (pEdidPreferredTiming, PreferredTiming);
> +  if (Status != EFI_SUCCESS) {
> +    DEBUG ((DEBUG_ERROR, "%a: Conversion to display timing failed\n",
> +      __FUNCTION__));
> +    goto Exit;
> +  }
> +
> +Exit:
> +
> +  return Status;
> +}
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Edid.h b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Edid.h
> new file mode 100644
> index 000000000000..df714f284deb
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Edid.h
> @@ -0,0 +1,33 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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_

IMX_ prefix please.

> +
> +EFI_STATUS
> +ReadEdid (
> +  IN  DISPLAY_CONTEXT     *DisplayContextPtr,
> +  IN  DISPLAY_INTERFACE_TYPE   DisplayInterface,
> +  IN  UINT8               *EdidDataPtr,
> +  OUT UINT32              *EdidDataSizePtr
> +  );
> +
> +EFI_STATUS
> +GetEdidPreferredTiming (
> +  IN  UINT8           *EdidDataPtr,
> +  IN  UINT32          EdidDataSizePtr,
> +  OUT DISPLAY_TIMING  *PreferredTiming
> +  );
> +
> +#endif  /* _EDID_H_ */
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/GopDxe.c b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/GopDxe.c
> new file mode 100644
> index 000000000000..2e990a6b14fb
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/GopDxe.c
> @@ -0,0 +1,475 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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 <iMX6.h>
> +#include <iMX6ClkPwr.h>
> +#include <iMXDisplay.h>
> +
> +#include "Display.h"
> +#include "GopDxe.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
> +  );
> +
> +STATIC VID_DEVICE_PATH VidDevicePath = {

m-prefix for global variables, please. Throughout. (Where they're not
for edk2-global visibility and should have g.)

> +  {
> +    {
> +      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 VidGopModeInfo;
> +STATIC EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE VidGopMode;
> +
> +STATIC EFI_GRAPHICS_OUTPUT_PROTOCOL VidGop = {
> +  VidGopQueryMode, // QueryMode
> +  VidGopSetMode,   // SetMode
> +  VidGopBlt,       // Blt
> +  &VidGopMode    // Mode
> +};
> +
> +EFI_EDID_DISCOVERED_PROTOCOL EdidDiscovered = {
> +  0,
> +  NULL
> +};
> +
> +EFI_EDID_ACTIVE_PROTOCOL EdidActive = {
> +  0,
> +  NULL
> +};
> +
> +DISPLAY_CONTEXT *DisplayContextPtr;
> +
> +DISPLAY_INTERFACE_TYPE DisplayDevice;
> +
> +EFI_STATUS
> +GopDxeInitialize (
> +  IN EFI_HANDLE         ImageHandle,
> +  IN EFI_SYSTEM_TABLE   *SystemTable
> +  )
> +{
> +  DISPLAY_INTERFACE_TYPE  DisplayInterfaceOrder[DisplayTypeMax];
> +  UINT32                  i;
> +  UINT32                  RequestedDisplayMemorySize;
> +  UINT32                  ReservedDisplayMemorySize;
> +  EFI_STATUS              Status;
> +
> +  DEBUG ((DEBUG_INFO, "%a: Enter \n", __FUNCTION__));
> +
> +  for (i = 0; i < DisplayTypeMax; i++) {
> +    DisplayInterfaceOrder[i] = NoDisplayType;
> +  }
> +  ReservedDisplayMemorySize = FixedPcdGet32 (PcdFrameBufferSize);
> +  if (FeaturePcdGet (PcdLvdsEnable)) {
> +    DisplayDevice = Lvds0Display;
> +  } else {
> +    DisplayDevice = HdmiDisplay;
> +  }
> +
> +  Status = InitDisplay (&DisplayContextPtr);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR,
> +      "%a: Fail to init display, Status=%r\n", __FUNCTION__,
> +      Status));
> +    goto Exit;
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "%a: - Allocate frame buffer\n", __FUNCTION__));
> +  // 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].PreferredTiming.HActive;
> +  DisplayContextPtr->DisplayConfig.DisplaySurface[0].Height =
> +    DisplayContextPtr->DiContext[DisplayDevice].PreferredTiming.VActive;
> +  DisplayContextPtr->DisplayConfig.DisplaySurface[0].Bpp =
> +    DisplayContextPtr->DiContext[DisplayDevice].PreferredTiming.Bpp;
> +  DisplayContextPtr->DisplayConfig.DisplaySurface[0].PixelFormat =
> +    DisplayContextPtr->DiContext[DisplayDevice].PreferredTiming.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: Displays which do not have support for 1920x1080 mode may
> +  // have poor or missing picture
> +  RequestedDisplayMemorySize =
> +    DisplayContextPtr->DisplayConfig.DisplaySurface[0].Width *
> +    DisplayContextPtr->DisplayConfig.DisplaySurface[0].Height *
> +    (DisplayContextPtr->DisplayConfig.DisplaySurface[0].Bpp / 8);
> +
> +  DEBUG ((DEBUG_INFO, "%a: Display Memory: Needed=%d, Available=%d\n",
> +    __FUNCTION__, RequestedDisplayMemorySize, ReservedDisplayMemorySize));
> +
> +  if (RequestedDisplayMemorySize > ReservedDisplayMemorySize) {
> +    DEBUG ((DEBUG_INFO,
> +      "%a: WARNING. Need more video memory than reserved by %d bytes\n",
> +      __FUNCTION__, RequestedDisplayMemorySize - ReservedDisplayMemorySize));
> +    DEBUG ((DEBUG_ERROR,
> +      "%a: - display resolution too big. Cap to HD 1080p\n",
> +      __FUNCTION__));
> +    DisplayContextPtr->DisplayConfig.DisplaySurface[0].Width = FullHDTiming.HActive;
> +    DisplayContextPtr->DisplayConfig.DisplaySurface[0].Height =
> +      FullHDTiming.VActive;
> +    DisplayContextPtr->DisplayConfig.DisplaySurface[0].Bpp = FullHDTiming.Bpp;
> +    CopyMem (
> +      &DisplayContextPtr->DiContext[DisplayDevice].PreferredTiming,
> +      &FullHDTiming,
> +      sizeof (DISPLAY_TIMING)
> +    );
> +  }
> +
> +  DEBUG ((DEBUG_INFO, "%a: - allocating frame buffer... \n",
> +    __FUNCTION__));
> +  Status = AllocateFrameBuffer (&DisplayContextPtr->DisplayConfig.DisplaySurface[0]);
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to allocate fb, Status=%r\n",
> +      __FUNCTION__, Status));
> +    goto Exit;
> +  };
> +
> +  DEBUG ((DEBUG_INFO, "%a: - Initialize the frame buffer to black\n",
> +    __FUNCTION__));
> +  // 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, "%a: - set display configuration to single HDMI\n",
> +    __FUNCTION__));
> +  // Set the display configuration to single HDMI/LVDS mode
> +  DisplayInterfaceOrder[0] = DisplayDevice;
> +  DisplayContextPtr->DisplayConfig.DisplayTiming[0] =
> +    DisplayContextPtr->DiContext[DisplayDevice].PreferredTiming;
> +
> +  Status = ApplyDisplayConfig (
> +              DisplayContextPtr,
> +              SINGLE_MODE,
> +              DisplayInterfaceOrder
> +            );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to set display. Exit Status=%r\n",
> +      __FUNCTION__, Status));
> +    goto Exit;
> +  }
> +
> +  VidGopModeInfo.Version = 0;
> +  VidGopModeInfo.HorizontalResolution =
> +    DisplayContextPtr->DisplayConfig.DisplayTiming[0].HActive;
> +  VidGopModeInfo.VerticalResolution =
> +    DisplayContextPtr->DisplayConfig.DisplayTiming[0].VActive;
> +  VidGopModeInfo.PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
> +  ZeroMem (
> +    &VidGopModeInfo.PixelInformation,
> +    sizeof (VidGopModeInfo.PixelInformation)
> +  );
> +
> +  VidGopModeInfo.PixelsPerScanLine = VidGopModeInfo.HorizontalResolution;
> +  VidGopMode.MaxMode = 1;
> +  VidGopMode.Mode = 0;
> +  VidGopMode.Info = &VidGopModeInfo;
> +  VidGopMode.SizeOfInfo = sizeof (VidGopModeInfo);
> +  VidGopMode.FrameBufferBase =
> +    (EFI_PHYSICAL_ADDRESS) DisplayContextPtr->DisplayConfig.DisplaySurface[0].PhyAddr;
> +  VidGopMode.FrameBufferSize =
> +    VidGopModeInfo.HorizontalResolution *
> +    VidGopModeInfo.VerticalResolution *
> +    (DisplayContextPtr->DisplayConfig.DisplaySurface[0].Bpp / 8);
> +  DisplayContextPtr->DisplayConfig.OsHandle[0] = (UINT32)&ImageHandle;
> +
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  &ImageHandle,
> +                  &gEfiGraphicsOutputProtocolGuid,
> +                  &VidGop,
> +                  &gEfiDevicePathProtocolGuid,
> +                  &VidDevicePath,
> +                  NULL
> +                );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to install protocol, Status=%x\n",
> +      __FUNCTION__, Status));
> +    goto Exit;
> +  }
> +
> +Exit:
> +  DEBUG ((DEBUG_INFO, "%a: Exit = %Xh\n",
> +    __FUNCTION__, Status));
> +  return Status;
> +}
> +
> +EFI_STATUS
> +EFIAPI
> +VidGopQueryMode (
> +  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
> +  IN  UINT32 ModeNumber,
> +  OUT UINTN *SizeOfInfo,
> +  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
> +  )
> +{
> +  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  *OutputMode;
> +  EFI_STATUS                            Status;
> +
> +  if (FeaturePcdGet (PcdLvdsEnable)) {
> +    DisplayDevice = Lvds0Display;
> +  } else {
> +    DisplayDevice = HdmiDisplay;
> +  }
> +
> +  EdidDiscovered.SizeOfEdid = DisplayContextPtr->DiContext[DisplayDevice].EdidDataSize;
> +  EdidDiscovered.Edid = DisplayContextPtr->DiContext[DisplayDevice].EdidData;
> +  EdidActive.SizeOfEdid = DisplayContextPtr->DiContext[DisplayDevice].EdidDataSize;
> +  EdidActive.Edid = DisplayContextPtr->DiContext[DisplayDevice].EdidData;
> +  Status = gBS->InstallMultipleProtocolInterfaces (
> +                  (EFI_HANDLE)DisplayContextPtr->DisplayConfig.OsHandle[0],
> +                  &gEfiEdidDiscoveredProtocolGuid,
> +                  &EdidDiscovered,
> +                  &gEfiEdidActiveProtocolGuid,
> +                  &EdidActive,
> +                  NULL
> +                );
> +  if (EFI_ERROR (Status)) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to install EDID protocols Status=%r\n",
> +      __FUNCTION__, Status));
> +  }
> +
> +  if (ModeNumber != 0) {
> +    DEBUG ((DEBUG_ERROR, "%a: Saw request to query mode %d\n",
> +      __FUNCTION__, 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 = VidGopModeInfo.HorizontalResolution;
> +  OutputMode->VerticalResolution = VidGopModeInfo.VerticalResolution;
> +  OutputMode->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
> +  OutputMode->PixelsPerScanLine = 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
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  if (ModeNumber != 0) {
> +    DEBUG ((DEBUG_ERROR, "%a: Saw request to set mode to %d\n",
> +      __FUNCTION__, ModeNumber));
> +    Status = EFI_UNSUPPORTED;
> +    goto Exit;
> +  }
> +
> +  Status = EFI_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  BufferOffset;
> +  UINT32  BufferWidth;
> +  UINT32  FrameOffset;
> +  UINT32  FrameWidth;
> +  UINT32  i;
> +
> +  FrameBuffer = (UINT32 *)((UINTN)VidGopMode.FrameBufferBase);
> +  FrameWidth = 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, "%a: Not implemented %d\n",
> +      __FUNCTION__, BltOperation));
> +    return EFI_INVALID_PARAMETER;
> +  }
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/GopDxe.h b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/GopDxe.h
> new file mode 100644
> index 000000000000..b8622283238f
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/GopDxe.h
> @@ -0,0 +1,20 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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 _GOP_DXE_H_
> +#define _GOP_DXE_H_
> +
> +#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
> +
> +#endif  /* _GOP_DXE_H_ */

Use ARRAY_SIZE from Base.h, then this file can be deleted.

> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/GopDxe.inf b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/GopDxe.inf
> new file mode 100644
> index 000000000000..9dbe00ae1ab1
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/GopDxe.inf
> @@ -0,0 +1,70 @@
> +#/** @file
> +#
> +#  Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
> +#  Copyright (c) 2018 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                    = 0x0001001A
> +  BASE_NAME                      = GopDxe
> +  FILE_GUID                      = E68088EF-D1A4-4336-C1DB-4D3A204730A6
> +  MODULE_TYPE                    = DXE_DRIVER
> +  VERSION_STRING                 = 1.0
> +  ENTRY_POINT                    = GopDxeInitialize
> +
> +[Sources.common]
> +  CPMem.c
> +  Ddc.c
> +  Display.c
> +  DisplayController.c
> +  DisplayInterface.c
> +  Edid.c
> +  GopDxe.c
> +  Hdmi.c
> +  IoMux.c
> +  Lvds.c
> +
> +[Packages]
> +  ArmPkg/ArmPkg.dec
> +  ArmPlatformPkg/ArmPlatformPkg.dec
> +  EmbeddedPkg/EmbeddedPkg.dec
> +  MdeModulePkg/MdeModulePkg.dec
> +  MdePkg/MdePkg.dec
> +  Silicon/NXP/iMX6Pkg/iMX6Pkg.dec
> +
> +[LibraryClasses]
> +  ArmLib
> +  BaseLib
> +  BaseMemoryLib
> +  DebugLib
> +  iMX6ClkPwrLib
> +  iMXDisplayLib
> +  IoLib
> +  TimerLib
> +  UefiBootServicesTableLib
> +  UefiDriverEntryPoint
> +  UefiLib
> +
> +[Protocols]
> +  gEfiDevicePathProtocolGuid                    # Produced
> +  gEfiDevicePathToTextProtocolGuid
> +  gEfiEdidActiveProtocolGuid                    # Produced
> +  gEfiEdidDiscoveredProtocolGuid                # Produced
> +  gEfiGraphicsOutputProtocolGuid                # Produced
> +
> +[Pcd]
> +  giMX6TokenSpaceGuid.PcdFrameBufferBase
> +  giMX6TokenSpaceGuid.PcdFrameBufferSize
> +  giMX6TokenSpaceGuid.PcdLvdsEnable
> +
> +[Depex]
> +  gEfiCpuArchProtocolGuid AND gEfiTimerArchProtocolGuid
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Hdmi.c b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Hdmi.c
> new file mode 100644
> index 000000000000..fa8fb3ed4aea
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Hdmi.c
> @@ -0,0 +1,761 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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 <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include <iMX6.h>
> +#include <iMX6ClkPwr.h>
> +#include <iMXDisplay.h>
> +
> +#include "Display.h"
> +#include "GopDxe.h"
> +#include "Hdmi.h"
> +#include "Edid.h"
> +
> +PLL_MPLL_CONFIG PllMpllGenericConfigSetting[] = {

Can this be static?
m-prefix, please.

> +  {  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 (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *HdmiDisplayContextPtr,
> +  IN  UINT32                      Timeout
> +  )
> +{
> +  HDMI_IH_I2CMPHY_STAT0_REG   I2cmphyStat0Reg;
> +  BOOLEAN                     WaitResult;
> +
> +  WaitResult = FALSE;
> +  for (; Timeout > 0; Timeout--) {
> +    I2cmphyStat0Reg.Reg = MmioRead8 (
> +                            (UINT32)HdmiDisplayContextPtr->MmioBasePtr +

UINTN for addresses, please. Throughout.

> +                            HDMI_IH_I2CMPHY_STAT0
> +                          );
> +    if (I2cmphyStat0Reg.i2cmphydone) {
> +      WaitResult = TRUE;
> +      break;
> +    }
> +    gBS->Stall (1);
> +  }
> +
> +#if DEBUG
> +  if ((Timeout == 0) || (I2cmphyStat0Reg.i2cmphyerror == 1)) {
> +    DEBUG ((DEBUG_ERROR, "%a: HDMI I2C failed value %x time out %d\n",
> +      __FUNCTION__, I2cmphyStat0Reg.Reg, Timeout));
> +  }
> +#endif
> +
> +  return WaitResult;
> +}
> +
> +BOOLEAN
> +HdmiPhyI2cRead (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *HdmiDisplayContextPtr,
> +  IN  UINT8                       Addr,
> +  OUT UINT16                      *DataPtr
> +  )
> +{
> +  UINT16                            Data0;
> +  UINT16                            Data1;
> +  HDMI_PHY_I2CM_OPERATION_ADDR_REG  I2cmOperationReg;
> +  HDMI_IH_I2CMPHY_STAT0_REG         I2cmphyStat0Reg;
> +  BOOLEAN                           ReadStatus;
> +
> +  I2cmphyStat0Reg.i2cmphyerror = 1;
> +  I2cmphyStat0Reg.i2cmphydone = 1;
> +  I2cmphyStat0Reg.reserved = 0;
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_IH_I2CMPHY_STAT0,
> +    I2cmphyStat0Reg.Reg
> +  );
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_PHY_I2CM_ADDRESS_ADDR,
> +    Addr
> +  );
> +
> +  I2cmOperationReg.Reg = MmioRead8 (
> +                           (UINT32)HdmiDisplayContextPtr->MmioBasePtr +
> +                           HDMI_PHY_I2CM_OPERATION_ADDR
> +                         );
> +  I2cmOperationReg.read = 1;
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_PHY_I2CM_OPERATION_ADDR,
> +    I2cmOperationReg.Reg
> +  );
> +
> +  ReadStatus = HdmiPhyPollI2cDone (HdmiDisplayContextPtr, 1000);
> +  if (!ReadStatus) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to read I2c HDMI Phy\n", __FUNCTION__));
> +    goto Exit;
> +  }
> +
> +  Data0 = MmioRead8 (
> +            (UINT32)HdmiDisplayContextPtr->MmioBasePtr +
> +            HDMI_PHY_I2CM_DATAI_0_ADDR
> +          );
> +  Data1 = MmioRead8 (
> +            (UINT32)HdmiDisplayContextPtr->MmioBasePtr +
> +            HDMI_PHY_I2CM_DATAI_1_ADDR
> +          );
> +  *DataPtr = Data0 | (Data1 <<  8);
> +
> +Exit:
> +  return ReadStatus;
> +}
> +
> +BOOLEAN
> +HdmiPhyI2cWrite (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *HdmiDisplayContextPtr,
> +  IN  UINT8                       Addr,
> +  IN  UINT16                      Data
> +  )
> +{
> +  UINT8                             Data0;
> +  UINT8                             Data1;
> +  HDMI_PHY_I2CM_OPERATION_ADDR_REG  I2cmOperationReg;
> +  HDMI_IH_I2CMPHY_STAT0_REG         I2cmphyStat0Reg;
> +
> +  Data0 = (Data & 0x00FF);
> +  Data1 = (Data >>  8);
> +  I2cmphyStat0Reg.i2cmphyerror = 1;
> +  I2cmphyStat0Reg.i2cmphydone = 1;
> +  I2cmphyStat0Reg.reserved = 1;
> +  I2cmOperationReg.read = 0;
> +  I2cmOperationReg.reserved0 = 0;
> +  I2cmOperationReg.write = 0;
> +  I2cmOperationReg.reserved1 = 0;
> +
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_IH_I2CMPHY_STAT0,
> +    I2cmphyStat0Reg.Reg
> +  );
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_PHY_I2CM_ADDRESS_ADDR,
> +    Addr
> +  );
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_PHY_I2CM_DATAO_0_ADDR,
> +    Data0
> +  );
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_PHY_I2CM_DATAO_1_ADDR,
> +    Data1
> +  );
> +
> +  I2cmOperationReg.read = 0;
> +  I2cmOperationReg.write = 1;
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_PHY_I2CM_OPERATION_ADDR,
> +    I2cmOperationReg.Reg
> +  );
> +  return HdmiPhyPollI2cDone (HdmiDisplayContextPtr, 1000);
> +}
> +
> +BOOLEAN
> +GetGenericConfigSetting (
> +  IN  DISPLAY_TIMING    *DisplayTimingPtr,
> +  OUT PLL_MPLL_CONFIG   **ConfigGenericSettingPPtr
> +  )
> +{
> +  UINT32    ColorDepth;
> +  BOOLEAN   FoundConfig;
> +  UINT32    SettingIndex;
> +
> +  FoundConfig = FALSE;
> +  ColorDepth = GetColorDepth (DisplayTimingPtr->PixelFormat);
> +
> +  for (SettingIndex = 0;
> +       SettingIndex < ARRAYSIZE (PllMpllGenericConfigSetting);
> +       ++SettingIndex)
> +  {
> +    if ((DisplayTimingPtr->PixelClock ==
> +         PllMpllGenericConfigSetting[SettingIndex].PixelClock) &&
> +        (DisplayTimingPtr->PixelRepetition ==
> +         PllMpllGenericConfigSetting[SettingIndex].PixelRepetition) &&
> +        (ColorDepth == 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;
> +}
> +
> +EFI_STATUS
> +InitHdmi (
> +  IN  DISPLAY_CONTEXT   *DisplayContextPtr
> +  )
> +{
> +  DISPLAY_INTERFACE_CONTEXT   *pHdmiDisplayContext;
> +  EFI_STATUS                  Status;
> +
> +  pHdmiDisplayContext = &DisplayContextPtr->DiContext[HdmiDisplay];
> +  Status = EFI_SUCCESS;
> +  ZeroMem (pHdmiDisplayContext, sizeof (*pHdmiDisplayContext));
> +
> +  pHdmiDisplayContext->MmioBasePtr = (VOID *)HDMI_BASE;
> +  if (pHdmiDisplayContext->MmioBasePtr == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to map HDMI register\n", __FUNCTION__));
> +    goto Exit;
> +  }
> +
> +  // Setup HDMI DDC muxing
> +  MmioWrite32 ((UINT32)IOMUXC_SW_MUX_CTL_PAD_KEY_COL3, 0x00000012);
> +  MmioWrite32 ((UINT32)IOMUXC_SW_MUX_CTL_PAD_KEY_ROW3, 0x00000012);
> +  MmioWrite32 ((UINT32)IOMUXC_HDMI_II2C_CLKIN_SELECT_INPUT, 0x00000001);
> +  MmioWrite32 ((UINT32)IOMUXC_HDMI_II2C_DATAIN_SELECT_INPUT, 0x00000001);
> +  SetHdmiPower (pHdmiDisplayContext, TRUE);
> +
> +  // Mask all HDMI PHY interrupt
> +  MmioWrite8 (
> +    (UINT32)pHdmiDisplayContext->MmioBasePtr + HDMI_PHY_MASK0,
> +    0xFF
> +  );
> +
> +  Status = ReadEdid (
> +             DisplayContextPtr,
> +             HdmiDisplay,
> +             pHdmiDisplayContext->EdidData,
> +             &pHdmiDisplayContext->EdidDataSize
> +           );
> +  if (Status != EFI_SUCCESS) {
> +    DEBUG ((DEBUG_WARN, "%a: Fail to read HDMI EDID data\n", __FUNCTION__));
> +    Status = EFI_SUCCESS;
> +  }
> +
> +  Status = GetPreferredTiming (
> +             pHdmiDisplayContext->EdidData,
> +             pHdmiDisplayContext->EdidDataSize,
> +             &pHdmiDisplayContext->PreferredTiming
> +           );
> +  if (Status != EFI_SUCCESS) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to retrieve HDMI preferred timing\n",
> +      __FUNCTION__));
> +    goto Exit;
> +  }
> +
> +  if ((pHdmiDisplayContext->PreferredTiming.HActive == 1920) &&
> +      (pHdmiDisplayContext->PreferredTiming.VActive == 1080))
> +  {
> +    pHdmiDisplayContext->PreferredTiming.HBlank -= 6;
> +  }
> +
> +Exit:
> +  return Status;
> +}
> +
> +EFI_STATUS
> +SetHdmiPower (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *HdmiDisplayContextPtr,
> +  IN  BOOLEAN                     PowerState
> +  )
> +{
> +  HDMI_PHY_CONF0_REG  CurrentHdmiPhyConf0Reg;
> +
> +  CurrentHdmiPhyConf0Reg.Reg = MmioRead8 (
> +                                 (UINT32)HdmiDisplayContextPtr->MmioBasePtr +
> +                                 HDMI_PHY_CONF0
> +                               );
> +  if (PowerState) {
> +    // Setup PHY
> +    CurrentHdmiPhyConf0Reg.PDZ = 1;
> +    CurrentHdmiPhyConf0Reg.ENTMDS = 1;
> +    CurrentHdmiPhyConf0Reg.gen2_pddq = 1;
> +    CurrentHdmiPhyConf0Reg.gen2_txpwron = 1;
> +    CurrentHdmiPhyConf0Reg.seldataenpol = 1;
> +    CurrentHdmiPhyConf0Reg.seldipif = 0;
> +  } else {
> +    // Just power down PHY for shutdown
> +    CurrentHdmiPhyConf0Reg.PDZ = 0;
> +  }
> +
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_PHY_CONF0,
> +    CurrentHdmiPhyConf0Reg.Reg
> +  );
> +  gBS->Stall (3);
> +
> +  return EFI_SUCCESS;
> +}
> +
> +EFI_STATUS
> +SetHdmiPhy (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *HdmiDisplayContextPtr,
> +  IN  DISPLAY_TIMING              *Timings
> +  )
> +{
> +  PLL_MPLL_CONFIG           *pPllMpllConfig;
> +  HDMI_PHY_CONF0_REG        CurrentHdmiPhyConf0Reg;
> +  HDMI_FC_AUDSCONF_REG      FcAudsconfReg;
> +  HDMI_MC_HEACPHY_RST_REG   HeacphyRstReg;
> +  HDMI_MC_CLKDIS_REG        McClkdisReg;
> +  HDMI_MC_PHYRSTZ_REG       PhyRstzReg;
> +  HDMI_PHY_STAT0_REG        PhyStat0Reg;
> +  BOOLEAN                   PhyStatus;
> +  UINT32                    RetryCount;
> +  EFI_STATUS                Status;
> +
> +  // Disable Audio
> +  FcAudsconfReg.Reg = MmioRead8 (
> +                        (UINT32)HdmiDisplayContextPtr->MmioBasePtr +
> +                        HDMI_FC_AUDSCONF
> +                      );
> +  FcAudsconfReg.aud_packet_layout = 0;
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_FC_AUDSCONF,
> +    FcAudsconfReg.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) {
> +    DEBUG ((DEBUG_ERROR, "%a: Unsupported pixel clock %d\n",
> +      __FUNCTION__, Timings->PixelClock));
> +    Status = EFI_INVALID_PARAMETER;
> +    goto Exit;
> +  }
> +
> +  if (GetGenericConfigSetting (Timings, &pPllMpllConfig) == FALSE) {
> +    DEBUG ((DEBUG_ERROR, "%a: No compatible generic config found\n",
> +      __FUNCTION__));
> +    Status = EFI_UNSUPPORTED;
> +    goto Exit;
> +  }
> +
> +  // Color Space Converter : Not used in UEFI
> +  McClkdisReg.Reg = MmioRead8 (
> +                      (UINT32)HdmiDisplayContextPtr->MmioBasePtr +
> +                      HDMI_MC_CLKDIS
> +                    );
> +  // Disable CEC, color converter, audio & pixel repitition
> +  McClkdisReg.cecclk_disable = 1;
> +  McClkdisReg.cscclk_disable = 1;
> +  McClkdisReg.audclk_disable = 1;
> +  McClkdisReg.prepclk_disable = 1;
> +  McClkdisReg.hdcpclk_disable = 1;
> +  McClkdisReg.tmdsclk_disable = 0;
> +  McClkdisReg.pixelclk_disable = 0;
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_MC_CLKDIS,
> +    McClkdisReg.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.
> +  CurrentHdmiPhyConf0Reg.Reg = MmioRead8 (
> +                                 (UINT32)HdmiDisplayContextPtr->MmioBasePtr +
> +                                 HDMI_PHY_CONF0
> +                               );
> +  CurrentHdmiPhyConf0Reg.gen2_txpwron = 0;
> +  CurrentHdmiPhyConf0Reg.gen2_pddq = 1;
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_PHY_CONF0,
> +    CurrentHdmiPhyConf0Reg.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
> +  PhyRstzReg.Reg = MmioRead8 (
> +                     (UINT32)HdmiDisplayContextPtr->MmioBasePtr +
> +                     HDMI_MC_PHYRSTZ
> +                   );
> +  PhyRstzReg.phyrstz = 1;
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_MC_PHYRSTZ,
> +    PhyRstzReg.Reg
> +  );
> +  PhyRstzReg.phyrstz = 0;
> +  gBS->Stall (10);
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_MC_PHYRSTZ,
> +    PhyRstzReg.Reg
> +  );
> +
> +  HeacphyRstReg.Reg = MmioRead8 (
> +                        (UINT32)HdmiDisplayContextPtr->MmioBasePtr +
> +                        HDMI_MC_HEACPHY_RST
> +                      );
> +  HeacphyRstReg.heacphyrst = 1;
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_MC_HEACPHY_RST,
> +    HeacphyRstReg.Reg
> +  );
> +
> +  // Program clock
> +  // PLL / MPLL Operation
> +  // The PLL / MPLL can be configured in Coherent mode or NonCoherent 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 NonCoherent mode, the TMDS clock is the MPLL reference clock, which is
> +  //  not coherent with the MPLL's high-speed output clock.
> +  PhyStatus = HdmiPhyI2cWrite (
> +                HdmiDisplayContextPtr,
> +                HDMI_PHY_CPCE_CTRL,
> +                pPllMpllConfig->HdmiPhyCpceCtrl.Reg
> +              );
> +  if (PhyStatus == FALSE) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to write to HDMI_PHY_CPCE_CTRL %x\n",
> +      __FUNCTION__, pPllMpllConfig->HdmiPhyCpceCtrl.Reg));
> +    Status = EFI_DEVICE_ERROR;
> +    goto Exit;
> +  }
> +
> +  PhyStatus = HdmiPhyI2cWrite (
> +                HdmiDisplayContextPtr,
> +                HDMI_PHY_CURRCTRL,
> +                pPllMpllConfig->HdmiPhyCurrctrl.Reg
> +              );
> +  if (PhyStatus == FALSE) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to write to HDMI_PHY_CURRCTRL\n",
> +      __FUNCTION__));
> +    Status = EFI_DEVICE_ERROR;
> +    goto Exit;
> +  };
> +
> +  PhyStatus = HdmiPhyI2cWrite (
> +                HdmiDisplayContextPtr,
> +                HDMI_PHY_GMPCTRL,
> +                pPllMpllConfig->HdmiPhyGmpctrl.Reg
> +              );
> +  if (PhyStatus == FALSE) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to write to HDMI_PHY_GMPCTRL\n",
> +      __FUNCTION__));
> +    Status = EFI_DEVICE_ERROR;
> +    goto Exit;
> +  }
> +
> +  // Maintaining the order of phy register writes
> +  PhyStatus = HdmiPhyI2cWrite (
> +                HdmiDisplayContextPtr,
> +                HDMI_PHY_PLLPHBYCTRL,
> +                0x0000
> +              );
> +  if (PhyStatus == FALSE) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to write to HDMI_PHY_PLLPHBYCTRL\n",
> +      __FUNCTION__));
> +    Status = EFI_DEVICE_ERROR;
> +    goto Exit;
> +  }
> +
> +  // Coherent mode
> +  PhyStatus = HdmiPhyI2cWrite (
> +                HdmiDisplayContextPtr,
> +                HDMI_PHY_MSM_CTRL,
> +                0x0006
> +              );
> +  if (PhyStatus == FALSE) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to write to HDMI_PHY_MSM_CTRL\n",
> +      __FUNCTION__));
> +    Status = EFI_DEVICE_ERROR;
> +    goto Exit;
> +  }
> +
> +  // Resistance value 133.33 ohm
> +  PhyStatus = HdmiPhyI2cWrite (
> +                HdmiDisplayContextPtr,
> +                HDMI_PHY_TXTERM,
> +                0x0005
> +              );
> +  if (PhyStatus == FALSE) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to write to HDMI_PHY_TXTERM\n",
> +      __FUNCTION__));
> +    Status = EFI_DEVICE_ERROR;
> +    goto Exit;
> +  }
> +
> +  // Enable clock symbol
> +  PhyStatus = HdmiPhyI2cWrite (
> +                HdmiDisplayContextPtr,
> +                HDMI_PHY_CKSYMTXCTRL,
> +                0x8009
> +              );
> +  if (PhyStatus == FALSE) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to write to HDMI_PHY_CKSYMTXCTRL\n",
> +      __FUNCTION__));
> +    Status = EFI_DEVICE_ERROR;
> +    goto Exit;
> +  }
> +
> +  PhyStatus = HdmiPhyI2cWrite (
> +                HdmiDisplayContextPtr,
> +                HDMI_PHY_VLEVCTRL,
> +                0x0210
> +              );
> +  if (PhyStatus == FALSE) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to write to HDMI_PHY_VLEVCTRL\n",
> +      __FUNCTION__));
> +    Status = EFI_DEVICE_ERROR;
> +    goto Exit;
> +  }
> +
> +  // Enable override
> +  PhyStatus = HdmiPhyI2cWrite (
> +                HdmiDisplayContextPtr,
> +                HDMI_PHY_CKCALCTRL,
> +                0x8000
> +              );
> +  if (PhyStatus == FALSE) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to write to HDMI_PHY_CKCALCTRL\n",
> +      __FUNCTION__));
> +    Status = EFI_DEVICE_ERROR;
> +    goto Exit;
> +  }
> +
> +  CurrentHdmiPhyConf0Reg.gen2_txpwron = 1;
> +  CurrentHdmiPhyConf0Reg.gen2_pddq = 0;
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_PHY_CONF0,
> +    CurrentHdmiPhyConf0Reg.Reg
> +  );
> +
> +  Status = EFI_DEVICE_ERROR;
> +  for (RetryCount = 5; RetryCount > 0; RetryCount--) {
> +    PhyStat0Reg.Reg = MmioRead8 (
> +                        (UINT32)HdmiDisplayContextPtr->MmioBasePtr +
> +                        HDMI_PHY_STAT0
> +                      );
> +    if (!PhyStat0Reg.TX_PHY_LOCK) {
> +      Status = EFI_SUCCESS;
> +      break;
> +    }
> +    gBS->Stall (1000);
> +  }
> +
> +  if (RetryCount == 0) {
> +    DEBUG ((DEBUG_ERROR, "%a: TX PHY remain unlock\n", __FUNCTION__));
> +  }
> +
> +Exit:
> +  return Status;
> +}
> +
> +EFI_STATUS
> +SetHdmiDisplay (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *HdmiDisplayContextPtr,
> +  IN  DISPLAY_TIMING              *Timings
> +  )
> +{
> +  EFI_STATUS  Status;
> +
> +  Status = SetHdmiPhy (HdmiDisplayContextPtr, Timings);
> +  if (Status != EFI_SUCCESS) {
> +    DEBUG ((DEBUG_ERROR, "%a: SetHdmiPhy failed\n", __FUNCTION__));
> +    goto Exit;
> +  }
> +
> +Exit:
> +  return Status;
> +}
> +
> +VOID
> +SetDdcSpeed (
> +  IN  DISPLAY_INTERFACE_CONTEXT *HdmiDisplayContextPtr,
> +  IN  DDC_MODE                  Mode
> +  )
> +{
> +  MmioWrite8 ((UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_I2CM_DIV, Mode);
> +}
> +
> +EFI_STATUS
> +HdmiDdcRead (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *HdmiDisplayContextPtr,
> +  IN  UINT8                       SlaveAddress,
> +  IN  UINT8                       RegisterAddress,
> +  IN  UINT32                      ReadSize,
> +  IN  DDC_MODE                    DDCMode,
> +  IN  UINT8                       *DataReadPtr
> +  )
> +{
> +  UINT8       *pCurrentDataRead;
> +  UINT32      AddrCount;
> +  UINT8       I2cmIntStatus;
> +  UINT32      I2cRetryCount;
> +  EFI_STATUS  Status;
> +
> +  pCurrentDataRead = DataReadPtr;
> +  Status = EFI_SUCCESS;
> +
> +  // Setup EDID transaction and loop through all byte request
> +  SetDdcSpeed (HdmiDisplayContextPtr, DDCMode);
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_IH_I2CM_STAT0,
> +    I2C_MASTER_ERROR | I2C_MASTER_DONE
> +  );
> +  MmioWrite8 (
> +    (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_I2CM_SLAVE,
> +    SlaveAddress
> +  );
> +
> +  for (AddrCount = 0; AddrCount < ReadSize; ++AddrCount) {
> +    I2cRetryCount = 1000;
> +
> +    MmioWrite8 (
> +      (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_I2CM_ADDRESS,
> +      (UINT8) ( RegisterAddress + AddrCount)
> +    );
> +    MmioWrite8 (
> +      (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_I2CM_SEGADDR,
> +      0x00
> +    );
> +    MmioWrite8 (
> +      (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_I2CM_OPERATION,
> +      DDC_READ_OPERATION
> +    );
> +
> +    // Poll for completion
> +    I2cmIntStatus = MmioRead8 (
> +                      (UINT32)HdmiDisplayContextPtr->MmioBasePtr +
> +                      HDMI_IH_I2CM_STAT0
> +                    );
> +    for (I2cRetryCount = 1000; I2cRetryCount > 0; I2cRetryCount--) {
> +      I2cmIntStatus = MmioRead8 (
> +                        (UINT32)HdmiDisplayContextPtr->MmioBasePtr +
> +                        HDMI_IH_I2CM_STAT0
> +                      );
> +      if (I2cmIntStatus != 0) {
> +        break;
> +      }
> +    }
> +
> +    if (I2cRetryCount == 0) {
> +      Status = EFI_DEVICE_ERROR;
> +      DEBUG ((DEBUG_ERROR, "%a: Timeout waiting for interrupt 0x%02x\n",
> +        __FUNCTION__, I2cmIntStatus));
> +      goto Exit;
> +    }
> +
> +    if ((I2cmIntStatus & I2C_MASTER_DONE) &&
> +        !(I2cmIntStatus & I2C_MASTER_ERROR))
> +    {
> +      *pCurrentDataRead = MmioRead8 (
> +                            (UINT32)HdmiDisplayContextPtr->MmioBasePtr +
> +                            HDMI_I2CM_DATAI
> +                          );
> +      pCurrentDataRead++;
> +      MmioWrite8 (
> +        (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_IH_I2CM_STAT0,
> +        I2C_MASTER_ERROR | I2C_MASTER_DONE
> +      );
> +    } else {
> +      Status = EFI_DEVICE_ERROR;
> +      DEBUG ((DEBUG_ERROR, "%a: Failed to read with DDC 0x%02x\n",
> +        __FUNCTION__, I2cmIntStatus));
> +      goto Exit;
> +    }
> +
> +    MmioWrite8 (
> +      (UINT32)HdmiDisplayContextPtr->MmioBasePtr + HDMI_IH_I2CM_STAT0,
> +      I2C_MASTER_ERROR | I2C_MASTER_DONE
> +    );
> +  }
> +
> +Exit:
> +  return Status;
> +}
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Hdmi.h b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Hdmi.h
> new file mode 100644
> index 000000000000..e1b7372bc2e9
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Hdmi.h
> @@ -0,0 +1,529 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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_

IMX_ prefix, please.

> +
> +// 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
> +
> +// 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;
> +
> +#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)
> +
> +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;
> +
> +EFI_STATUS
> +InitHdmi (
> +  IN  DISPLAY_CONTEXT   *DisplayContextPtr
> +  );
> +
> +EFI_STATUS
> +SetHdmiPower (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *HdmiDisplayContextPtr,
> +  IN  BOOLEAN                     PowerState
> +  );
> +
> +EFI_STATUS
> +SetHdmiDisplay (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *HdmiDisplayContextPtr,
> +  IN  DISPLAY_TIMING              *Timings
> +  );
> +
> +EFI_STATUS
> +HdmiDdcRead (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *HdmiDisplayContextPtr,
> +  IN  UINT8                       SlaveAddress,
> +  IN  UINT8                       RegisterAddress,
> +  IN  UINT32                      ReadSize,
> +  IN  DDC_MODE                    DDCMode,
> +  IN  UINT8                       *DataReadPtr
> +  );
> +
> +#endif  /* _HDMI_H_ */
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/IoMux.c b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/IoMux.c
> new file mode 100644
> index 000000000000..b82fbd2125f5
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/IoMux.c
> @@ -0,0 +1,88 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include <iMX6.h>
> +#include <iMX6ClkPwr.h>
> +#include <iMXDisplay.h>
> +
> +#include "Display.h"
> +#include "IoMux.h"
> +
> +EFI_STATUS
> +SetupDisplayMux (
> +  IN  DISPLAY_CONTEXT   *DisplayContextPtr
> +  )
> +{
> +  DISPLAY_INTERFACE_TYPE              *pDisplayInterfaceType;
> +  volatile IMX_IOMUXC_GPR_REGISTERS   *pIomuxcGprReg;
> +  UINT32                              DisplayInterfaceIndex;
> +  DISPLAY_MODE                        DisplayMode;
> +  UINT32                              Gpr3Reg;
> +  UINT32                              SourceMask;
> +  UINT32                              SourceValue;
> +  EFI_STATUS                          Status;
> +
> +  pIomuxcGprReg = DisplayContextPtr->IoMuxMmioBasePtr;
> +  DisplayMode = DisplayContextPtr->DisplayConfig.DisplayMode;
> +  pDisplayInterfaceType = DisplayContextPtr->DisplayConfig.DiOrder;
> +  Status = EFI_SUCCESS;
> +
> +  Gpr3Reg = MmioRead32 ((UINT32)&pIomuxcGprReg->GPR3);
> +  Gpr3Reg &= ~(HDMI_MUX_CTL_MASK | MIPI_MUX_CTL_MASK |
> +               LVDS0_MUX_CTL_MASK | LVDS1_MUX_CTL_MASK);
> +  MmioWrite32 ((UINT32)&pIomuxcGprReg->GPR3, Gpr3Reg);
> +
> +  for (DisplayInterfaceIndex = 0; DisplayInterfaceIndex < (UINT32)DisplayMode; ++DisplayInterfaceIndex) {
> +    Gpr3Reg = MmioRead32 ((UINT32)&pIomuxcGprReg->GPR3);
> +    switch (pDisplayInterfaceType[DisplayInterfaceIndex]) {
> +    case HdmiDisplay:
> +      SourceMask = HDMI_MUX_CTL_MASK;
> +      SourceValue = DisplayInterfaceIndex << HDMI_MUX_CTL_OFFSET;
> +      break;
> +    case MipiDisplay:
> +      SourceMask = MIPI_MUX_CTL_MASK;
> +      SourceValue = DisplayInterfaceIndex << MIPI_MUX_CTL_OFFSET;
> +      break;
> +    case Lvds0Display:
> +      SourceMask = LVDS0_MUX_CTL_MASK;
> +      SourceValue = DisplayInterfaceIndex << LVDS0_MUX_CTL_OFFSET;
> +      break;
> +    case Lvds1Display:
> +      SourceMask = LVDS1_MUX_CTL_MASK;
> +      SourceValue = DisplayInterfaceIndex << LVDS1_MUX_CTL_OFFSET;
> +      break;
> +    default:
> +      Status = EFI_UNSUPPORTED;
> +      break;
> +    }
> +    if (EFI_ERROR (Status)) {
> +      break;
> +    }
> +
> +    Gpr3Reg &= ~SourceMask;
> +    Gpr3Reg |= SourceValue;
> +    MmioWrite32 ((UINT32)&pIomuxcGprReg->GPR3, Gpr3Reg);
> +  }
> +
> +  return Status;
> +}
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/IoMux.h b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/IoMux.h
> new file mode 100644
> index 000000000000..4946ab293ae5
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/IoMux.h
> @@ -0,0 +1,32 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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_

IMX_ prefix, please.

> +
> +#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
> +
> +EFI_STATUS
> +SetupDisplayMux (
> +  IN  DISPLAY_CONTEXT   *DisplayContextPtr
> +  );
> +
> +#endif  /* _IO_MUX_H_ */
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Ipu.h b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Ipu.h
> new file mode 100644
> index 000000000000..00d20c881b67
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Ipu.h
> @@ -0,0 +1,236 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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) \
> +            MmioRead32((UINT32)((UINT8 *)IPU_BASE + OFFSET))
> +
> +#define IpuWrite32(IPU_BASE, OFFSET, VALUE) \
> +            MmioWrite32((UINT32)((UINT8 *)IPU_BASE + OFFSET), VALUE)
> +
> +#define DiRead32(DI_BASE, OFFSET) \
> +            MmioRead32((UINT32)((UINT8 *)DI_BASE + OFFSET))
> +
> +#define DiWrite32(DI_BASE, OFFSET, VALUE) \
> +            MmioWrite32((UINT32)((UINT8 *)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 DisplayInterface0 Registers
> +#define IPU_DISPLAY_INTERFACE_0_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 DisplayInterface1 Registers
> +#define IPU_DISPLAY_INTERFACE_1_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  /* _IPU_H_ */
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Lvds.c b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Lvds.c
> new file mode 100644
> index 000000000000..e6eb3b31bb07
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Lvds.c
> @@ -0,0 +1,93 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/IoLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +
> +#include <iMX6.h>
> +#include <iMX6ClkPwr.h>
> +#include <iMXDisplay.h>
> +
> +#include "Display.h"
> +#include "Lvds.h"
> +#include "Edid.h"
> +
> +EFI_STATUS
> +InitLvds (
> +  IN  DISPLAY_CONTEXT   *DisplayContextPtr
> +  )
> +{
> +  DISPLAY_INTERFACE_CONTEXT   *pLvdsDisplayContext;
> +  EFI_STATUS                  Status;
> +  LDB_CTRL_REG                LdbCtrlReg;
> +
> +  Status = EFI_SUCCESS;
> +  pLvdsDisplayContext = &DisplayContextPtr->DiContext[Lvds0Display];
> +  ZeroMem (pLvdsDisplayContext, sizeof (*pLvdsDisplayContext));
> +
> +  pLvdsDisplayContext->MmioBasePtr = (VOID *)LDB_BASE;
> +  if (pLvdsDisplayContext->MmioBasePtr == NULL) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to map LDB register\n", __FUNCTION__));
> +    goto Exit;
> +  }
> +
> +  // LVDS CH1 enabled, routed to DisplayInterface0; ipu_di01_vsync_active_low
> +  LdbCtrlReg.Reg = MmioRead32 ((UINT32)pLvdsDisplayContext->MmioBasePtr + LDB_CTRL);
> +  LdbCtrlReg.ch0_mode = 1;
> +  LdbCtrlReg.ch1_mode = 1;
> +  LdbCtrlReg.di0_vs_polarity = 1;
> +  LdbCtrlReg.di1_vs_polarity = 1;
> +  MmioWrite32 ((UINT32)pLvdsDisplayContext->MmioBasePtr + LDB_CTRL, LdbCtrlReg.Reg);
> +
> +  // No EDID available
> +  pLvdsDisplayContext->EdidDataSize = 0;
> +
> +  Status = GetPreferredTiming (
> +             pLvdsDisplayContext->EdidData,
> +             pLvdsDisplayContext->EdidDataSize,
> +             &pLvdsDisplayContext->PreferredTiming
> +           );
> +  if (Status != EFI_SUCCESS) {
> +    DEBUG ((DEBUG_ERROR, "%a: Fail to retrieve LVDS preferred timing\n",
> +      __FUNCTION__));
> +    goto Exit;
> +  }
> +
> +Exit:
> +  return Status;
> +}
> +
> +EFI_STATUS
> +SetLvdsPower (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *HdmiDisplayContextPtr,
> +  IN  BOOLEAN                     PowerState
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> +
> +EFI_STATUS
> +SetLvdsDisplay (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *pLvdsDisplayContext,
> +  IN  DISPLAY_TIMING              *Timings
> +  )
> +{
> +  return EFI_UNSUPPORTED;
> +}
> diff --git a/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Lvds.h b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Lvds.h
> new file mode 100644
> index 000000000000..b45201fb45fc
> --- /dev/null
> +++ b/Silicon/NXP/iMX6Pkg/Drivers/GopDxe/Lvds.h
> @@ -0,0 +1,67 @@
> +/** @file
> +*
> +*  Copyright (c) 2018 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_

IMX_ prefix please.

> +
> +// LDB Register Base Address
> +#define LDB_BASE 0x020E0008
> +
> +// LDB Control Register offset
> +#define LDB_CTRL    0
> +
> +#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;

Please rename all struct members to CamelCase.

/
    Leif

> +  };
> +  UINT32 Reg;
> +}  LDB_CTRL_REG;
> +
> +#pragma pack(pop)
> +
> +EFI_STATUS
> +InitLvds (
> +  IN  DISPLAY_CONTEXT   *DisplayContextPtr
> +  );
> +
> +EFI_STATUS
> +SetLvdsPower (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *HdmiDisplayContextPtr,
> +  IN  BOOLEAN                     PowerState
> +  );
> +
> +EFI_STATUS
> +SetLvdsDisplay (
> +  IN  DISPLAY_INTERFACE_CONTEXT   *LvdsDisplayContextPtr,
> +  IN  DISPLAY_TIMING              *Timings
> +  );
> +
> +#endif  /* _LVDS_H_ */
> -- 
> 2.16.2.gvfs.1.33.gf5370f1
> 


  reply	other threads:[~2018-12-14 22:37 UTC|newest]

Thread overview: 75+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-21  8:25 [PATCH edk2-platforms 00/27] Import Hummingboard Edge platform for Windows IoT Core Chris Co
2018-09-21  8:25 ` [PATCH edk2-platforms 01/27] Platform/Microsoft: Add OpteeClientPkg dec Chris Co
2018-10-31 20:43   ` Leif Lindholm
2018-11-01 10:55     ` Sumit Garg
2018-11-02  0:41       ` Chris Co
2018-11-02  5:24         ` Sumit Garg
2018-11-02 23:55           ` Chris Co
2018-11-05 10:07             ` Sumit Garg
2018-11-06  1:53               ` Chris Co
2018-11-06 11:09                 ` Sumit Garg
2018-09-21  8:25 ` [PATCH edk2-platforms 02/27] Platform/Microsoft: Add SdMmc Dxe Driver Chris Co
2018-09-21  8:25 ` [PATCH edk2-platforms 03/27] Platform/Microsoft: Add MsPkg Chris Co
2018-10-31 21:00   ` Leif Lindholm
2018-09-21  8:25 ` [PATCH edk2-platforms 04/27] Silicon/NXP: Add iMXPlatformPkg dec Chris Co
2018-09-21  8:25 ` [PATCH edk2-platforms 05/27] Silicon/NXP: Add UART library support for i.MX platforms Chris Co
2018-11-01  8:59   ` Leif Lindholm
2018-11-02  1:46     ` Chris Co
2018-09-21  8:25 ` [PATCH edk2-platforms 06/27] Silicon/NXP: Add I2C " Chris Co
2018-11-01 17:53   ` Leif Lindholm
2018-09-21  8:25 ` [PATCH edk2-platforms 07/27] Silicon/NXP: Add i.MX display library support Chris Co
2018-11-01 18:05   ` Leif Lindholm
2018-11-29  0:55     ` Chris Co
2018-09-21  8:25 ` [PATCH edk2-platforms 08/27] Silicon/NXP: Add Virtual RTC support for i.MX platform Chris Co
2018-12-15 13:26   ` Leif Lindholm
2018-09-21  8:26 ` [PATCH edk2-platforms 10/27] Silicon/NXP: Add iMX6Pkg dec Chris Co
2018-11-01 18:25   ` Leif Lindholm
2018-09-21  8:26 ` [PATCH edk2-platforms 09/27] Silicon/NXP: Add headers for SoC-specific i.MX packages to use Chris Co
2018-11-01 18:20   ` Leif Lindholm
2018-12-01  0:22     ` Chris Co
2018-12-03  9:42       ` Leif Lindholm
2018-12-04  1:44         ` Chris Co
2018-12-04  9:33           ` Ard Biesheuvel
2018-12-04 12:22             ` Leif Lindholm
2018-09-21  8:26 ` [PATCH edk2-platforms 11/27] Silicon/NXP: Add i.MX6 SoC header files Chris Co
2018-12-13 17:11   ` Leif Lindholm
2018-09-21  8:26 ` [PATCH edk2-platforms 12/27] Silicon/NXP: Add i.MX6 I/O MUX library Chris Co
2018-11-08 18:00   ` Leif Lindholm
2018-12-04  1:41     ` Chris Co
2018-09-21  8:26 ` [PATCH edk2-platforms 13/27] Silicon/NXP: Add support for iMX SDHC Chris Co
2018-12-05 10:31   ` Leif Lindholm
2018-09-21  8:26 ` [PATCH edk2-platforms 14/27] Silicon/NXP: Add i.MX6 GPT and EPIT timer headers Chris Co
2018-11-08 18:14   ` Leif Lindholm
2018-12-04  2:06     ` Chris Co
2018-12-04 12:58       ` Leif Lindholm
2018-09-21  8:26 ` [PATCH edk2-platforms 15/27] Silicon/NXP: Add i.MX6 GPT Timer library Chris Co
2018-12-13 17:26   ` Leif Lindholm
2018-09-21  8:26 ` [PATCH edk2-platforms 16/27] Silicon/NXP: Add i.MX6 Timer DXE driver Chris Co
2018-12-13 17:33   ` Leif Lindholm
2018-09-21  8:26 ` [PATCH edk2-platforms 17/27] Silicon/NXP: Add i.MX6 USB Phy Library Chris Co
2018-12-14 17:10   ` Leif Lindholm
2018-09-21  8:26 ` [PATCH edk2-platforms 18/27] Silicon/NXP: Add i.MX6 Clock Library Chris Co
2018-12-14 18:12   ` Leif Lindholm
2018-09-21  8:26 ` [PATCH edk2-platforms 20/27] Silicon/NXP: Add i.MX6 Board init library Chris Co
2018-12-14 20:12   ` Leif Lindholm
2018-09-21  8:26 ` [PATCH edk2-platforms 19/27] Silicon/NXP: Add i.MX6 ACPI tables Chris Co
2018-12-14 19:53   ` Leif Lindholm
2018-12-17 11:14   ` Ard Biesheuvel
2019-01-08 21:43     ` Chris Co
2019-01-29 14:09       ` Ard Biesheuvel
2018-09-21  8:26 ` [PATCH edk2-platforms 21/27] Silicon/NXP: Add i.MX6 PCIe DXE driver Chris Co
2018-12-14 21:59   ` Leif Lindholm
2018-09-21  8:26 ` [PATCH edk2-platforms 23/27] Silicon/NXP: Add i.MX6 Smbios Driver Chris Co
2018-12-14 23:07   ` Leif Lindholm
2018-09-21  8:26 ` [PATCH edk2-platforms 22/27] Silicon/NXP: Add i.MX6 GOP driver Chris Co
2018-12-14 22:37   ` Leif Lindholm [this message]
2018-09-21  8:26 ` [PATCH edk2-platforms 24/27] Silicon/NXP: Add i.MX6 common dsc and fdf files Chris Co
2018-12-14 23:36   ` Leif Lindholm
2018-09-21  8:26 ` [PATCH edk2-platforms 25/27] Platform/Solidrun: Add Hummingboard Peripheral Initialization Chris Co
2018-12-15 12:12   ` Leif Lindholm
2018-09-21  8:26 ` [PATCH edk2-platforms 26/27] Platform/SolidRun: Add i.MX 6Quad Hummingboard Edge ACPI tables Chris Co
2018-12-15 12:19   ` Leif Lindholm
2018-09-21  8:26 ` [PATCH edk2-platforms 27/27] Platform/Solidrun: Add i.MX 6Quad Hummingboard Edge dsc and fdf files Chris Co
2018-12-15 12:28   ` Leif Lindholm
2018-12-15 13:32 ` [PATCH edk2-platforms 00/27] Import Hummingboard Edge platform for Windows IoT Core Leif Lindholm
2018-12-19 18:28   ` Chris Co

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181214223743.b6txd5zchffy6apr@bivouac.eciton.net \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox