[edk2-devel] [edk2-platforms: Patch 1/8] Silicon/TexasInsturments: Import Omap35xxPkg from edk2

Michael D Kinney michael.d.kinney at intel.com
Fri May 10 03:34:28 UTC 2019


https://bugzilla.tianocore.org/show_bug.cgi?id=1467

Import Omap35xxPkg from edk2/master.

Cc: Leif Lindholm <leif.lindholm at linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Signed-off-by: Michael D Kinney <michael.d.kinney at intel.com>
---
 .../Omap35xxPkg/Flash/Flash.c                 |  768 +++++++++
 .../Omap35xxPkg/Flash/Flash.h                 |  100 ++
 .../Omap35xxPkg/Flash/Flash.inf               |   42 +
 .../TexasInsturments/Omap35xxPkg/Gpio/Gpio.c  |  129 ++
 .../Omap35xxPkg/Gpio/Gpio.inf                 |   39 +
 .../Omap35xxPkg/Include/Library/OmapDmaLib.h  |   84 +
 .../Omap35xxPkg/Include/Library/OmapLib.h     |   38 +
 .../Omap35xxPkg/Include/Omap3530/Omap3530.h   |   34 +
 .../Include/Omap3530/Omap3530Dma.h            |  124 ++
 .../Include/Omap3530/Omap3530Gpio.h           |  125 ++
 .../Include/Omap3530/Omap3530Gpmc.h           |  101 ++
 .../Include/Omap3530/Omap3530I2c.h            |   56 +
 .../Include/Omap3530/Omap3530Interrupt.h      |   45 +
 .../Include/Omap3530/Omap3530MMCHS.h          |  208 +++
 .../Omap3530/Omap3530PadConfiguration.h       |  297 ++++
 .../Include/Omap3530/Omap3530Prcm.h           |  159 ++
 .../Include/Omap3530/Omap3530Timer.h          |   76 +
 .../Include/Omap3530/Omap3530Uart.h           |   48 +
 .../Include/Omap3530/Omap3530Usb.h            |   42 +
 .../Omap35xxPkg/Include/TPS65950.h            |   74 +
 .../InterruptDxe/HardwareInterrupt.c          |  396 +++++
 .../Omap35xxPkg/InterruptDxe/InterruptDxe.inf |   48 +
 .../LcdGraphicsOutputBlt.c                    |  439 +++++
 .../LcdGraphicsOutputDxe.c                    |  394 +++++
 .../LcdGraphicsOutputDxe.h                    |  151 ++
 .../LcdGraphicsOutputDxe.inf                  |   46 +
 .../DebugAgentTimerLib/DebugAgentTimerLib.c   |  159 ++
 .../DebugAgentTimerLib/DebugAgentTimerLib.inf |   42 +
 .../Library/GdbSerialLib/GdbSerialLib.c       |   96 ++
 .../Library/GdbSerialLib/GdbSerialLib.inf     |   35 +
 .../Omap35xxTimerLib/Omap35xxTimerLib.inf     |   40 +
 .../Library/Omap35xxTimerLib/TimerLib.c       |  151 ++
 .../Library/OmapDmaLib/OmapDmaLib.c           |  170 ++
 .../Library/OmapDmaLib/OmapDmaLib.inf         |   43 +
 .../Omap35xxPkg/Library/OmapLib/OmapLib.c     |   77 +
 .../Omap35xxPkg/Library/OmapLib/OmapLib.inf   |   31 +
 .../RealTimeClockLib/RealTimeClockLib.c       |  291 ++++
 .../RealTimeClockLib/RealTimeClockLib.inf     |   32 +
 .../Library/SerialPortLib/SerialPortLib.c     |  208 +++
 .../Library/SerialPortLib/SerialPortLib.inf   |   40 +
 .../Omap35xxPkg/MMCHSDxe/MMCHS.c              | 1492 +++++++++++++++++
 .../Omap35xxPkg/MMCHSDxe/MMCHS.h              |  169 ++
 .../Omap35xxPkg/MMCHSDxe/MMCHS.inf            |   48 +
 .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.c       |  671 ++++++++
 .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.h       |   38 +
 .../Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf     |   47 +
 .../Omap35xxPkg/Omap35xxPkg.dec               |   52 +
 .../Omap35xxPkg/Omap35xxPkg.dsc               |  183 ++
 .../Omap35xxPkg/PciEmulation/PciEmulation.c   |  107 ++
 .../Omap35xxPkg/PciEmulation/PciEmulation.inf |   41 +
 .../Omap35xxPkg/SmbusDxe/Smbus.c              |  319 ++++
 .../Omap35xxPkg/SmbusDxe/Smbus.inf            |   39 +
 .../Omap35xxPkg/TPS65950Dxe/TPS65950.c        |  110 ++
 .../Omap35xxPkg/TPS65950Dxe/TPS65950.inf      |   42 +
 .../Omap35xxPkg/TimerDxe/Timer.c              |  370 ++++
 .../Omap35xxPkg/TimerDxe/TimerDxe.inf         |   51 +
 56 files changed, 9257 insertions(+)
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapDmaLib.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapLib.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Dma.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpio.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpmc.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530I2c.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Interrupt.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530MMCHS.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530PadConfiguration.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Prcm.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Timer.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Uart.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Usb.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Include/TPS65950.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/HardwareInterrupt.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/InterruptDxe.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/Omap35xxTimerLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/TimerLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.h
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dec
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dsc
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.inf
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/Timer.c
 create mode 100644 Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/TimerDxe.inf

diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c b/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c
new file mode 100644
index 0000000000..43f8f4279e
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.c
@@ -0,0 +1,768 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "Flash.h"
+
+NAND_PART_INFO_TABLE gNandPartInfoTable[1] = {
+  { 0x2C, 0xBA, 17, 11 }
+};
+
+NAND_FLASH_INFO *gNandFlashInfo = NULL;
+UINT8           *gEccCode;
+UINTN           gNum512BytesChunks = 0;
+
+//
+
+// Device path for SemiHosting. It contains our autogened Caller ID GUID.
+
+//
+
+typedef struct {
+
+  VENDOR_DEVICE_PATH        Guid;
+
+  EFI_DEVICE_PATH_PROTOCOL  End;
+
+} FLASH_DEVICE_PATH;
+
+
+
+FLASH_DEVICE_PATH gDevicePath = {
+  {
+    { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0 } },
+    EFI_CALLER_ID_GUID
+  },
+  { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0} }
+};
+
+
+
+//Actual page address = Column address + Page address + Block address.
+UINTN
+GetActualPageAddressInBytes (
+  UINTN BlockIndex,
+  UINTN PageIndex
+)
+{
+  //BlockAddressStart = Start of the Block address in actual NAND
+  //PageAddressStart = Start of the Page address in actual NAND
+  return ((BlockIndex << gNandFlashInfo->BlockAddressStart) + (PageIndex << gNandFlashInfo->PageAddressStart));
+}
+
+VOID
+NandSendCommand (
+  UINT8 Command
+)
+{
+  MmioWrite16(GPMC_NAND_COMMAND_0, Command);
+}
+
+VOID
+NandSendAddress (
+  UINT8 Address
+)
+{
+  MmioWrite16(GPMC_NAND_ADDRESS_0, Address);
+}
+
+UINT16
+NandReadStatus (
+  VOID
+  )
+{
+  //Send READ STATUS command
+  NandSendCommand(READ_STATUS_CMD);
+
+  //Read status.
+  return MmioRead16(GPMC_NAND_DATA_0);
+}
+
+VOID
+NandSendAddressCycles (
+  UINTN Address
+)
+{
+  //Column address
+  NandSendAddress(Address & 0xff);
+  Address >>= 8;
+
+  //Column address
+  NandSendAddress(Address & 0x07);
+  Address >>= 3;
+
+  //Page and Block address
+  NandSendAddress(Address & 0xff);
+  Address >>= 8;
+
+  //Block address
+  NandSendAddress(Address & 0xff);
+  Address >>= 8;
+
+  //Block address
+  NandSendAddress(Address & 0x01);
+}
+
+VOID
+GpmcInit (
+  VOID
+  )
+{
+  //Enable Smart-idle mode.
+  MmioWrite32 (GPMC_SYSCONFIG, SMARTIDLEMODE);
+
+  //Set IRQSTATUS and IRQENABLE to the reset value
+  MmioWrite32 (GPMC_IRQSTATUS, 0x0);
+  MmioWrite32 (GPMC_IRQENABLE, 0x0);
+
+  //Disable GPMC timeout control.
+  MmioWrite32 (GPMC_TIMEOUT_CONTROL, TIMEOUTDISABLE);
+
+  //Set WRITEPROTECT bit to enable write access.
+  MmioWrite32 (GPMC_CONFIG, WRITEPROTECT_HIGH);
+
+  //NOTE: Following GPMC_CONFIGi_0 register settings are taken from u-boot memory dump.
+  MmioWrite32 (GPMC_CONFIG1_0, DEVICETYPE_NAND | DEVICESIZE_X16);
+  MmioWrite32 (GPMC_CONFIG2_0, CSRDOFFTIME | CSWROFFTIME);
+  MmioWrite32 (GPMC_CONFIG3_0, ADVRDOFFTIME | ADVWROFFTIME);
+  MmioWrite32 (GPMC_CONFIG4_0, OEONTIME | OEOFFTIME | WEONTIME | WEOFFTIME);
+  MmioWrite32 (GPMC_CONFIG5_0, RDCYCLETIME | WRCYCLETIME | RDACCESSTIME | PAGEBURSTACCESSTIME);
+  MmioWrite32 (GPMC_CONFIG6_0, WRACCESSTIME | WRDATAONADMUXBUS | CYCLE2CYCLEDELAY | CYCLE2CYCLESAMECSEN);
+  MmioWrite32 (GPMC_CONFIG7_0, MASKADDRESS_128MB | CSVALID | BASEADDRESS);
+}
+
+EFI_STATUS
+NandDetectPart (
+  VOID
+)
+{
+  UINT8      NandInfo = 0;
+  UINT8      PartInfo[5];
+  UINTN      Index;
+  BOOLEAN    Found = FALSE;
+
+  //Send READ ID command
+  NandSendCommand(READ_ID_CMD);
+
+  //Send one address cycle.
+  NandSendAddress(0);
+
+  //Read 5-bytes to idenfity code programmed into the NAND flash devices.
+  //BYTE 0 = Manufacture ID
+  //Byte 1 = Device ID
+  //Byte 2, 3, 4 = Nand part specific information (Page size, Block size etc)
+  for (Index = 0; Index < sizeof(PartInfo); Index++) {
+    PartInfo[Index] = MmioRead16(GPMC_NAND_DATA_0);
+  }
+
+  //Check if the ManufactureId and DeviceId are part of the currently supported nand parts.
+  for (Index = 0; Index < sizeof(gNandPartInfoTable)/sizeof(NAND_PART_INFO_TABLE); Index++) {
+    if (gNandPartInfoTable[Index].ManufactureId == PartInfo[0] && gNandPartInfoTable[Index].DeviceId == PartInfo[1]) {
+      gNandFlashInfo->BlockAddressStart = gNandPartInfoTable[Index].BlockAddressStart;
+      gNandFlashInfo->PageAddressStart = gNandPartInfoTable[Index].PageAddressStart;
+      Found = TRUE;
+      break;
+    }
+  }
+
+  if (Found == FALSE) {
+    DEBUG ((EFI_D_ERROR, "Nand part is not currently supported. Manufacture id: %x, Device id: %x\n", PartInfo[0], PartInfo[1]));
+    return EFI_NOT_FOUND;
+  }
+
+  //Populate NAND_FLASH_INFO based on the result of READ ID command.
+  gNandFlashInfo->ManufactureId = PartInfo[0];
+  gNandFlashInfo->DeviceId = PartInfo[1];
+  NandInfo = PartInfo[3];
+
+  if (PAGE_SIZE(NandInfo) == PAGE_SIZE_2K_VAL) {
+    gNandFlashInfo->PageSize = PAGE_SIZE_2K;
+  } else {
+    DEBUG ((EFI_D_ERROR, "Unknown Page size.\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (SPARE_AREA_SIZE(NandInfo) == SPARE_AREA_SIZE_64B_VAL) {
+    gNandFlashInfo->SparePageSize = SPARE_AREA_SIZE_64B;
+  } else {
+    DEBUG ((EFI_D_ERROR, "Unknown Spare area size.\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (BLOCK_SIZE(NandInfo) == BLOCK_SIZE_128K_VAL) {
+    gNandFlashInfo->BlockSize = BLOCK_SIZE_128K;
+  } else {
+    DEBUG ((EFI_D_ERROR, "Unknown Block size.\n"));
+    return EFI_DEVICE_ERROR;
+  }
+
+  if (ORGANIZATION(NandInfo) == ORGANIZATION_X8) {
+    gNandFlashInfo->Organization = 0;
+  } else if (ORGANIZATION(NandInfo) == ORGANIZATION_X16) {
+    gNandFlashInfo->Organization = 1;
+  }
+
+  //Calculate total number of blocks.
+  gNandFlashInfo->NumPagesPerBlock = DivU64x32(gNandFlashInfo->BlockSize, gNandFlashInfo->PageSize);
+
+  return EFI_SUCCESS;
+}
+
+VOID
+NandConfigureEcc (
+  VOID
+  )
+{
+  //Define ECC size 0 and size 1 to 512 bytes
+  MmioWrite32 (GPMC_ECC_SIZE_CONFIG, (ECCSIZE0_512BYTES | ECCSIZE1_512BYTES));
+}
+
+VOID
+NandEnableEcc (
+  VOID
+  )
+{
+  //Clear all the ECC result registers and select ECC result register 1
+  MmioWrite32 (GPMC_ECC_CONTROL, (ECCCLEAR | ECCPOINTER_REG1));
+
+  //Enable ECC engine on CS0
+  MmioWrite32 (GPMC_ECC_CONFIG, (ECCENABLE | ECCCS_0 | ECC16B));
+}
+
+VOID
+NandDisableEcc (
+  VOID
+  )
+{
+  //Turn off ECC engine.
+  MmioWrite32 (GPMC_ECC_CONFIG, ECCDISABLE);
+}
+
+VOID
+NandCalculateEcc (
+  VOID
+  )
+{
+  UINTN Index;
+  UINTN EccResultRegister;
+  UINTN EccResult;
+
+  //Capture 32-bit ECC result for each 512-bytes chunk.
+  //In our case PageSize is 2K so read ECC1-ECC4 result registers and
+  //generate total of 12-bytes of ECC code for the particular page.
+
+  EccResultRegister = GPMC_ECC1_RESULT;
+
+  for (Index = 0; Index < gNum512BytesChunks; Index++) {
+
+    EccResult = MmioRead32 (EccResultRegister);
+
+    //Calculate ECC code from 32-bit ECC result value.
+    //NOTE: Following calculation is not part of TRM. We got this information
+    //from Beagleboard mailing list.
+    gEccCode[Index * 3] = EccResult & 0xFF;
+    gEccCode[(Index * 3) + 1] = (EccResult >> 16) & 0xFF;
+    gEccCode[(Index * 3) + 2] = (((EccResult >> 20) & 0xF0) | ((EccResult >> 8) & 0x0F));
+
+    //Point to next ECC result register.
+    EccResultRegister += 4;
+  }
+}
+
+EFI_STATUS
+NandReadPage (
+  IN  UINTN                         BlockIndex,
+  IN  UINTN                         PageIndex,
+  OUT VOID                          *Buffer,
+  OUT UINT8                         *SpareBuffer
+)
+{
+  UINTN      Address;
+  UINTN      Index;
+  UINTN      NumMainAreaWords = (gNandFlashInfo->PageSize/2);
+  UINTN      NumSpareAreaWords = (gNandFlashInfo->SparePageSize/2);
+  UINT16     *MainAreaWordBuffer = Buffer;
+  UINT16     *SpareAreaWordBuffer = (UINT16 *)SpareBuffer;
+  UINTN      Timeout = MAX_RETRY_COUNT;
+
+  //Generate device address in bytes to access specific block and page index
+  Address = GetActualPageAddressInBytes(BlockIndex, PageIndex);
+
+  //Send READ command
+  NandSendCommand(PAGE_READ_CMD);
+
+  //Send 5 Address cycles to access specific device address
+  NandSendAddressCycles(Address);
+
+  //Send READ CONFIRM command
+  NandSendCommand(PAGE_READ_CONFIRM_CMD);
+
+  //Poll till device is busy.
+  while (Timeout) {
+    if ((NandReadStatus() & NAND_READY) == NAND_READY) {
+      break;
+    }
+    Timeout--;
+  }
+
+  if (Timeout == 0) {
+    DEBUG ((EFI_D_ERROR, "Read page timed out.\n"));
+    return EFI_TIMEOUT;
+  }
+
+  //Reissue READ command
+  NandSendCommand(PAGE_READ_CMD);
+
+  //Enable ECC engine.
+  NandEnableEcc();
+
+  //Read data into the buffer.
+  for (Index = 0; Index < NumMainAreaWords; Index++) {
+    *MainAreaWordBuffer++ = MmioRead16(GPMC_NAND_DATA_0);
+  }
+
+  //Read spare area into the buffer.
+  for (Index = 0; Index < NumSpareAreaWords; Index++) {
+    *SpareAreaWordBuffer++ = MmioRead16(GPMC_NAND_DATA_0);
+  }
+
+  //Calculate ECC.
+  NandCalculateEcc();
+
+  //Turn off ECC engine.
+  NandDisableEcc();
+
+  //Perform ECC correction.
+  //Need to implement..
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+NandWritePage (
+  IN  UINTN                         BlockIndex,
+  IN  UINTN                         PageIndex,
+  OUT VOID                          *Buffer,
+  IN  UINT8                         *SpareBuffer
+)
+{
+  UINTN      Address;
+  UINT16     *MainAreaWordBuffer = Buffer;
+  UINT16     *SpareAreaWordBuffer = (UINT16 *)SpareBuffer;
+  UINTN      Index;
+  UINTN      NandStatus;
+  UINTN      Timeout = MAX_RETRY_COUNT;
+
+  //Generate device address in bytes to access specific block and page index
+  Address = GetActualPageAddressInBytes(BlockIndex, PageIndex);
+
+  //Send SERIAL DATA INPUT command
+  NandSendCommand(PROGRAM_PAGE_CMD);
+
+  //Send 5 Address cycles to access specific device address
+  NandSendAddressCycles(Address);
+
+  //Enable ECC engine.
+  NandEnableEcc();
+
+  //Data input from Buffer
+  for (Index = 0; Index < (gNandFlashInfo->PageSize/2); Index++) {
+    MmioWrite16(GPMC_NAND_DATA_0, *MainAreaWordBuffer++);
+
+    //After each write access, device has to wait to accept data.
+    //Currently we may not be programming proper timing parameters to
+    //the GPMC_CONFIGi_0 registers and we would need to figure that out.
+    //Without following delay, page programming fails.
+    gBS->Stall(1);
+  }
+
+  //Calculate ECC.
+  NandCalculateEcc();
+
+  //Turn off ECC engine.
+  NandDisableEcc();
+
+  //Prepare Spare area buffer with ECC codes.
+  SetMem(SpareBuffer, gNandFlashInfo->SparePageSize, 0xFF);
+  CopyMem(&SpareBuffer[ECC_POSITION], gEccCode, gNum512BytesChunks * 3);
+
+  //Program spare area with calculated ECC.
+  for (Index = 0; Index < (gNandFlashInfo->SparePageSize/2); Index++) {
+    MmioWrite16(GPMC_NAND_DATA_0, *SpareAreaWordBuffer++);
+  }
+
+  //Send PROGRAM command
+  NandSendCommand(PROGRAM_PAGE_CONFIRM_CMD);
+
+  //Poll till device is busy.
+  NandStatus = 0;
+  while (Timeout) {
+    NandStatus = NandReadStatus();
+    if ((NandStatus & NAND_READY) == NAND_READY) {
+      break;
+    }
+    Timeout--;
+  }
+
+  if (Timeout == 0) {
+    DEBUG ((EFI_D_ERROR, "Program page timed out.\n"));
+    return EFI_TIMEOUT;
+  }
+
+  //Bit0 indicates Pass/Fail status
+  if (NandStatus & NAND_FAILURE) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+NandEraseBlock (
+  IN UINTN BlockIndex
+)
+{
+  UINTN      Address;
+  UINTN      NandStatus;
+  UINTN      Timeout = MAX_RETRY_COUNT;
+
+  //Generate device address in bytes to access specific block and page index
+  Address = GetActualPageAddressInBytes(BlockIndex, 0);
+
+  //Send ERASE SETUP command
+  NandSendCommand(BLOCK_ERASE_CMD);
+
+  //Send 3 address cycles to device to access Page address and Block address
+  Address >>= 11; //Ignore column addresses
+
+  NandSendAddress(Address & 0xff);
+  Address >>= 8;
+
+  NandSendAddress(Address & 0xff);
+  Address >>= 8;
+
+  NandSendAddress(Address & 0xff);
+
+  //Send ERASE CONFIRM command
+  NandSendCommand(BLOCK_ERASE_CONFIRM_CMD);
+
+  //Poll till device is busy.
+  NandStatus = 0;
+  while (Timeout) {
+    NandStatus = NandReadStatus();
+    if ((NandStatus & NAND_READY) == NAND_READY) {
+      break;
+    }
+    Timeout--;
+    gBS->Stall(1);
+  }
+
+  if (Timeout == 0) {
+    DEBUG ((EFI_D_ERROR, "Erase block timed out for Block: %d.\n", BlockIndex));
+    return EFI_TIMEOUT;
+  }
+
+  //Bit0 indicates Pass/Fail status
+  if (NandStatus & NAND_FAILURE) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+NandReadBlock (
+  IN UINTN                          StartBlockIndex,
+  IN UINTN                          EndBlockIndex,
+  OUT VOID                          *Buffer,
+  OUT VOID                          *SpareBuffer
+)
+{
+  UINTN      BlockIndex;
+  UINTN      PageIndex;
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  for (BlockIndex = StartBlockIndex; BlockIndex <= EndBlockIndex; BlockIndex++) {
+    //For each block read number of pages
+    for (PageIndex = 0; PageIndex < gNandFlashInfo->NumPagesPerBlock; PageIndex++) {
+      Status = NandReadPage(BlockIndex, PageIndex, Buffer, SpareBuffer);
+      if (EFI_ERROR(Status)) {
+        return Status;
+      }
+      Buffer = ((UINT8 *)Buffer + gNandFlashInfo->PageSize);
+    }
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+NandWriteBlock (
+  IN UINTN                          StartBlockIndex,
+  IN UINTN                          EndBlockIndex,
+  OUT VOID                          *Buffer,
+  OUT VOID                          *SpareBuffer
+  )
+{
+  UINTN      BlockIndex;
+  UINTN      PageIndex;
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  for (BlockIndex = StartBlockIndex; BlockIndex <= EndBlockIndex; BlockIndex++) {
+    //Page programming.
+    for (PageIndex = 0; PageIndex < gNandFlashInfo->NumPagesPerBlock; PageIndex++) {
+      Status = NandWritePage(BlockIndex, PageIndex, Buffer, SpareBuffer);
+      if (EFI_ERROR(Status)) {
+        return Status;
+      }
+      Buffer = ((UINT8 *)Buffer + gNandFlashInfo->PageSize);
+    }
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+NandFlashReset (
+  IN EFI_BLOCK_IO_PROTOCOL          *This,
+  IN BOOLEAN                        ExtendedVerification
+  )
+{
+  UINTN BusyStall = 50;                            // microSeconds
+  UINTN ResetBusyTimeout = (1000000 / BusyStall);  // 1 Second
+
+  //Send RESET command to device.
+  NandSendCommand(RESET_CMD);
+
+  //Wait for 1ms before we check status register.
+  gBS->Stall(1000);
+
+  //Check BIT#5 & BIT#6 in Status register to make sure RESET is done.
+  while ((NandReadStatus() & NAND_RESET_STATUS) != NAND_RESET_STATUS) {
+
+    //In case of extended verification, wait for extended amount of time
+    //to make sure device is reset.
+    if (ExtendedVerification) {
+      if (ResetBusyTimeout == 0) {
+        return EFI_DEVICE_ERROR;
+      }
+
+      gBS->Stall(BusyStall);
+      ResetBusyTimeout--;
+    }
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+NandFlashReadBlocks (
+  IN EFI_BLOCK_IO_PROTOCOL          *This,
+  IN UINT32                         MediaId,
+  IN EFI_LBA                        Lba,
+  IN UINTN                          BufferSize,
+  OUT VOID                          *Buffer
+  )
+{
+  UINTN      NumBlocks;
+  UINTN      EndBlockIndex;
+  EFI_STATUS Status;
+  UINT8      *SpareBuffer = NULL;
+
+  if (Buffer == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto exit;
+  }
+
+  if (Lba > LAST_BLOCK) {
+    Status = EFI_INVALID_PARAMETER;
+    goto exit;
+  }
+
+  if ((BufferSize % gNandFlashInfo->BlockSize) != 0) {
+    Status = EFI_BAD_BUFFER_SIZE;
+    goto exit;
+  }
+
+  NumBlocks = DivU64x32(BufferSize, gNandFlashInfo->BlockSize);
+  EndBlockIndex = ((UINTN)Lba + NumBlocks) - 1;
+
+  SpareBuffer = (UINT8 *)AllocatePool(gNandFlashInfo->SparePageSize);
+  if (SpareBuffer == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto exit;
+  }
+
+  //Read block
+  Status = NandReadBlock((UINTN)Lba, EndBlockIndex, Buffer, SpareBuffer);
+  if (EFI_ERROR(Status)) {
+    DEBUG((EFI_D_ERROR, "Read block fails: %x\n", Status));
+    goto exit;
+  }
+
+exit:
+  if (SpareBuffer != NULL) {
+    FreePool (SpareBuffer);
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+NandFlashWriteBlocks (
+  IN EFI_BLOCK_IO_PROTOCOL          *This,
+  IN UINT32                         MediaId,
+  IN EFI_LBA                        Lba,
+  IN UINTN                          BufferSize,
+  IN VOID                           *Buffer
+  )
+{
+  UINTN      BlockIndex;
+  UINTN      NumBlocks;
+  UINTN      EndBlockIndex;
+  EFI_STATUS Status;
+  UINT8      *SpareBuffer = NULL;
+
+  if (Buffer == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto exit;
+  }
+
+  if (Lba > LAST_BLOCK) {
+    Status = EFI_INVALID_PARAMETER;
+    goto exit;
+  }
+
+  if ((BufferSize % gNandFlashInfo->BlockSize) != 0) {
+    Status = EFI_BAD_BUFFER_SIZE;
+    goto exit;
+  }
+
+  NumBlocks = DivU64x32(BufferSize, gNandFlashInfo->BlockSize);
+  EndBlockIndex = ((UINTN)Lba + NumBlocks) - 1;
+
+  SpareBuffer = (UINT8 *)AllocatePool(gNandFlashInfo->SparePageSize);
+  if (SpareBuffer == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto exit;
+  }
+
+  // Erase block
+  for (BlockIndex = (UINTN)Lba; BlockIndex <= EndBlockIndex; BlockIndex++) {
+    Status = NandEraseBlock(BlockIndex);
+    if (EFI_ERROR(Status)) {
+      DEBUG((EFI_D_ERROR, "Erase block failed. Status: %x\n", Status));
+      goto exit;
+    }
+  }
+
+  // Program data
+  Status = NandWriteBlock((UINTN)Lba, EndBlockIndex, Buffer, SpareBuffer);
+  if (EFI_ERROR(Status)) {
+    DEBUG((EFI_D_ERROR, "Block write fails: %x\n", Status));
+    goto exit;
+  }
+
+exit:
+  if (SpareBuffer != NULL) {
+    FreePool (SpareBuffer);
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+NandFlashFlushBlocks (
+  IN EFI_BLOCK_IO_PROTOCOL  *This
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
+
+EFI_BLOCK_IO_MEDIA gNandFlashMedia = {
+  SIGNATURE_32('n','a','n','d'),            // MediaId
+  FALSE,                                    // RemovableMedia
+  TRUE,                                     // MediaPresent
+  FALSE,                                    // LogicalPartition
+  FALSE,                                    // ReadOnly
+  FALSE,                                    // WriteCaching
+  0,                                        // BlockSize
+  2,                                        // IoAlign
+  0,                                        // Pad
+  0                                         // LastBlock
+};
+
+EFI_BLOCK_IO_PROTOCOL BlockIo =
+{
+  EFI_BLOCK_IO_INTERFACE_REVISION,  // Revision
+  &gNandFlashMedia,                  // *Media
+  NandFlashReset,                   // Reset
+  NandFlashReadBlocks,              // ReadBlocks
+  NandFlashWriteBlocks,             // WriteBlocks
+  NandFlashFlushBlocks              // FlushBlocks
+};
+
+EFI_STATUS
+NandFlashInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  gNandFlashInfo = (NAND_FLASH_INFO *)AllocateZeroPool (sizeof(NAND_FLASH_INFO));
+
+  //Initialize GPMC module.
+  GpmcInit();
+
+  //Reset NAND part
+  NandFlashReset(&BlockIo, FALSE);
+
+  //Detect NAND part and populate gNandFlashInfo structure
+  Status = NandDetectPart ();
+  if (EFI_ERROR(Status)) {
+    DEBUG((EFI_D_ERROR, "Nand part id detection failure: Status: %x\n", Status));
+    return Status;
+  }
+
+  //Count total number of 512Bytes chunk based on the page size.
+  if (gNandFlashInfo->PageSize == PAGE_SIZE_512B) {
+    gNum512BytesChunks = 1;
+  } else if (gNandFlashInfo->PageSize == PAGE_SIZE_2K) {
+    gNum512BytesChunks = 4;
+  } else if (gNandFlashInfo->PageSize == PAGE_SIZE_4K) {
+    gNum512BytesChunks = 8;
+  }
+
+  gEccCode = (UINT8 *)AllocatePool(gNum512BytesChunks * 3);
+  if (gEccCode == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  //Configure ECC
+  NandConfigureEcc ();
+
+  //Patch EFI_BLOCK_IO_MEDIA structure.
+  gNandFlashMedia.BlockSize = gNandFlashInfo->BlockSize;
+  gNandFlashMedia.LastBlock = LAST_BLOCK;
+
+  //Publish BlockIO.
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gEfiBlockIoProtocolGuid, &BlockIo,
+                  &gEfiDevicePathProtocolGuid, &gDevicePath,
+                  NULL
+                  );
+  return Status;
+}
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.h b/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.h
new file mode 100644
index 0000000000..62f7eb30dc
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.h
@@ -0,0 +1,100 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef FLASH_H
+#define FLASH_H
+
+#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 <Library/IoLib.h>
+
+#include <Protocol/BlockIo.h>
+#include <Protocol/Cpu.h>
+#include <Omap3530/Omap3530.h>
+
+#define PAGE_SIZE(x)             ((x) & 0x01)
+#define PAGE_SIZE_2K_VAL         (0x01UL)
+
+#define SPARE_AREA_SIZE(x)       (((x) >> 2) & 0x01)
+#define SPARE_AREA_SIZE_64B_VAL  (0x1UL)
+
+#define BLOCK_SIZE(x)            (((x) >> 4) & 0x01)
+#define BLOCK_SIZE_128K_VAL      (0x01UL)
+
+#define ORGANIZATION(x)          (((x) >> 6) & 0x01)
+#define ORGANIZATION_X8          (0x0UL)
+#define ORGANIZATION_X16         (0x1UL)
+
+#define PAGE_SIZE_512B           (512)
+#define PAGE_SIZE_2K             (2048)
+#define PAGE_SIZE_4K             (4096)
+#define SPARE_AREA_SIZE_16B      (16)
+#define SPARE_AREA_SIZE_64B      (64)
+
+#define BLOCK_SIZE_16K           (16*1024)
+#define BLOCK_SIZE_128K          (128*1024)
+
+#define BLOCK_COUNT              (2048)
+#define LAST_BLOCK               (BLOCK_COUNT - 1)
+
+#define ECC_POSITION             2
+
+//List of commands.
+#define RESET_CMD                0xFF
+#define READ_ID_CMD              0x90
+
+#define READ_STATUS_CMD          0x70
+
+#define PAGE_READ_CMD            0x00
+#define PAGE_READ_CONFIRM_CMD    0x30
+
+#define BLOCK_ERASE_CMD          0x60
+#define BLOCK_ERASE_CONFIRM_CMD  0xD0
+
+#define PROGRAM_PAGE_CMD         0x80
+#define PROGRAM_PAGE_CONFIRM_CMD 0x10
+
+//Nand status register bit definition
+#define NAND_SUCCESS             (0x0UL << 0)
+#define NAND_FAILURE             BIT0
+
+#define NAND_BUSY                (0x0UL << 6)
+#define NAND_READY               BIT6
+
+#define NAND_RESET_STATUS        (0x60UL << 0)
+
+#define MAX_RETRY_COUNT          1500
+
+
+typedef struct {
+  UINT8 ManufactureId;
+  UINT8 DeviceId;
+  UINT8 BlockAddressStart; //Start of the Block address in actual NAND
+  UINT8 PageAddressStart;  //Start of the Page address in actual NAND
+} NAND_PART_INFO_TABLE;
+
+typedef struct {
+  UINT8     ManufactureId;
+  UINT8     DeviceId;
+  UINT8     Organization;      //x8 or x16
+  UINT32    PageSize;
+  UINT32    SparePageSize;
+  UINT32    BlockSize;
+  UINT32    NumPagesPerBlock;
+  UINT8     BlockAddressStart; //Start of the Block address in actual NAND
+  UINT8     PageAddressStart;  //Start of the Page address in actual NAND
+} NAND_FLASH_INFO;
+
+#endif //FLASH_H
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.inf b/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.inf
new file mode 100644
index 0000000000..39e36ec9ce
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Flash/Flash.inf
@@ -0,0 +1,42 @@
+#/** @file
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = NandFlash
+  FILE_GUID                      = 4d00ef14-c4e0-426b-81b7-30a00a14aad6
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = NandFlashInitialize
+
+
+[Sources.common]
+  Flash.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  UefiLib
+  UefiDriverEntryPoint
+  MemoryAllocationLib
+  IoLib
+
+[Guids]
+
+[Protocols]
+  gEfiBlockIoProtocolGuid
+  gEfiCpuArchProtocolGuid
+
+[Pcd]
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxGpmcOffset
+
+[depex]
+  TRUE
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.c b/Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.c
new file mode 100644
index 0000000000..6ea096bcef
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.c
@@ -0,0 +1,129 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/IoLib.h>
+#include <Library/OmapLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/EmbeddedGpio.h>
+
+#include <Omap3530/Omap3530.h>
+
+EFI_STATUS
+Get (
+  IN  EMBEDDED_GPIO     *This,
+  IN  EMBEDDED_GPIO_PIN Gpio,
+  OUT UINTN               *Value
+  )
+{
+  UINTN  Port;
+  UINTN  Pin;
+  UINT32 DataInRegister;
+
+  if (Value == NULL)
+  {
+    return EFI_UNSUPPORTED;
+  }
+
+  Port    = GPIO_PORT(Gpio);
+  Pin     = GPIO_PIN(Gpio);
+
+  DataInRegister = GpioBase(Port) + GPIO_DATAIN;
+
+  if (MmioRead32 (DataInRegister) & GPIO_DATAIN_MASK(Pin)) {
+    *Value = 1;
+  } else {
+    *Value = 0;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+Set (
+  IN  EMBEDDED_GPIO       *This,
+  IN  EMBEDDED_GPIO_PIN   Gpio,
+  IN  EMBEDDED_GPIO_MODE  Mode
+  )
+{
+  UINTN  Port;
+  UINTN  Pin;
+  UINT32 OutputEnableRegister;
+  UINT32 SetDataOutRegister;
+  UINT32 ClearDataOutRegister;
+
+  Port    = GPIO_PORT(Gpio);
+  Pin     = GPIO_PIN(Gpio);
+
+  OutputEnableRegister = GpioBase(Port) + GPIO_OE;
+  SetDataOutRegister   = GpioBase(Port) + GPIO_SETDATAOUT;
+  ClearDataOutRegister = GpioBase(Port) + GPIO_CLEARDATAOUT;
+
+  switch (Mode)
+  {
+    case GPIO_MODE_INPUT:
+      MmioAndThenOr32(OutputEnableRegister, ~GPIO_OE_MASK(Pin), GPIO_OE_INPUT(Pin));
+      break;
+
+    case GPIO_MODE_OUTPUT_0:
+      MmioWrite32 (ClearDataOutRegister, GPIO_CLEARDATAOUT_BIT(Pin));
+      MmioAndThenOr32(OutputEnableRegister, ~GPIO_OE_MASK(Pin), GPIO_OE_OUTPUT(Pin));
+      break;
+
+    case GPIO_MODE_OUTPUT_1:
+      MmioWrite32 (SetDataOutRegister, GPIO_SETDATAOUT_BIT(Pin));
+      MmioAndThenOr32(OutputEnableRegister, ~GPIO_OE_MASK(Pin), GPIO_OE_OUTPUT(Pin));
+      break;
+
+    default:
+      return EFI_UNSUPPORTED;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetMode (
+  IN  EMBEDDED_GPIO       *This,
+  IN  EMBEDDED_GPIO_PIN   Gpio,
+  OUT EMBEDDED_GPIO_MODE  *Mode
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+SetPull (
+  IN  EMBEDDED_GPIO       *This,
+  IN  EMBEDDED_GPIO_PIN   Gpio,
+  IN  EMBEDDED_GPIO_PULL  Direction
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+EMBEDDED_GPIO Gpio = {
+  Get,
+  Set,
+  GetMode,
+  SetPull
+};
+
+EFI_STATUS
+GpioInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = gBS->InstallMultipleProtocolInterfaces(&ImageHandle, &gEmbeddedGpioProtocolGuid, &Gpio, NULL);
+  return Status;
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.inf b/Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.inf
new file mode 100644
index 0000000000..16850a3e66
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Gpio/Gpio.inf
@@ -0,0 +1,39 @@
+#/** @file
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = Gpio
+  FILE_GUID                      = E7D9CAE1-6930-46E3-BDF9-0027446E7DF2
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = GpioInitialize
+
+
+[Sources.common]
+  Gpio.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  IoLib
+  UefiDriverEntryPoint
+  OmapLib
+
+[Guids]
+
+[Protocols]
+  gEmbeddedGpioProtocolGuid
+
+[Pcd]
+
+[depex]
+  TRUE
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapDmaLib.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapDmaLib.h
new file mode 100644
index 0000000000..21987d0e6b
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapDmaLib.h
@@ -0,0 +1,84 @@
+/** @file
+
+  Abstractions for simple OMAP DMA.
+  OMAP_DMA4 structure elements are described in the OMAP35xx TRM.
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP_DMA_LIB_H__
+#define __OMAP_DMA_LIB_H__
+
+
+// Example from DMA chapter of the OMAP35xx spec
+typedef struct {
+  UINT8     DataType;                      // DMA4_CSDPi[1:0]
+  UINT8     ReadPortAccessType;            // DMA4_CSDPi[8:7]
+  UINT8     WritePortAccessType;           // DMA4_CSDPi[15:14]
+  UINT8     SourceEndiansim;               // DMA4_CSDPi[21]
+  UINT8     DestinationEndianism;          // DMA4_CSDPi[19]
+  UINT8     WriteMode;                     // DMA4_CSDPi[17:16]
+  UINT8     SourcePacked;                  // DMA4_CSDPi[6]
+  UINT8     DestinationPacked;             // DMA4_CSDPi[13]
+  UINT32    NumberOfElementPerFrame;       // DMA4_CENi
+  UINT32    NumberOfFramePerTransferBlock; // DMA4_CFNi
+  UINT32    SourceStartAddress;            // DMA4_CSSAi
+  UINT32    DestinationStartAddress;       // DMA4_CDSAi
+  UINT32    SourceElementIndex;            // DMA4_CSEi
+  UINT32    SourceFrameIndex;              // DMA4_CSFi
+  UINT32    DestinationElementIndex;       // DMA4_CDEi
+  UINT32    DestinationFrameIndex;         // DMA4_CDFi
+  UINT8     ReadPortAccessMode;            // DMA4_CCRi[13:12]
+  UINT8     WritePortAccessMode;           // DMA4_CCRi[15:14]
+  UINT8     ReadPriority;                  // DMA4_CCRi[6]
+  UINT8     WritePriority;                 // DMA4_CCRi[23]
+  UINT8     ReadRequestNumber;             // DMA4_CCRi[4:0]
+  UINT8     WriteRequestNumber;            // DMA4_CCRi[20:19]
+} OMAP_DMA4;
+
+
+/**
+  Configure OMAP DMA Channel
+
+  @param  Channel               DMA Channel to configure
+  @param  Dma4                  Pointer to structure used to initialize DMA registers for the Channel
+
+  @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.
+  @retval EFI_INVALID_PARAMETER Channel is not valid
+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested information.
+
+**/
+EFI_STATUS
+EFIAPI
+EnableDmaChannel (
+  IN  UINTN       Channel,
+  IN  OMAP_DMA4   *Dma4
+  );
+
+/**
+  Turn of DMA channel configured by EnableDma().
+
+  @param  Channel               DMA Channel to configure
+  @param  SuccesMask            Bits in DMA4_CSR register indicate EFI_SUCCESS
+  @param  ErrorMask             Bits in DMA4_CSR register indicate EFI_DEVICE_ERROR
+
+  @retval EFI_SUCCESS           DMA hardware disabled
+  @retval EFI_INVALID_PARAMETER Channel is not valid
+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested information.
+
+**/
+EFI_STATUS
+EFIAPI
+DisableDmaChannel (
+  IN  UINTN       Channel,
+  IN  UINT32      SuccessMask,
+  IN  UINT32      ErrorMask
+  );
+
+
+
+#endif
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapLib.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapLib.h
new file mode 100644
index 0000000000..e92a5aee4b
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Library/OmapLib.h
@@ -0,0 +1,38 @@
+/** @file
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAPLIB_H__
+#define __OMAPLIB_H__
+
+UINT32
+EFIAPI
+GpioBase (
+  IN  UINTN Port
+  );
+
+UINT32
+EFIAPI
+TimerBase (
+  IN  UINTN Timer
+  );
+
+UINTN
+EFIAPI
+InterruptVectorForTimer (
+  IN  UINTN TImer
+  );
+
+UINT32
+EFIAPI
+UartBase (
+  IN  UINTN Uart
+  );
+
+
+#endif // __OMAPLIB_H__
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530.h
new file mode 100644
index 0000000000..1658d597ff
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530.h
@@ -0,0 +1,34 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530_H__
+#define __OMAP3530_H__
+
+#include "Omap3530Gpio.h"
+#include "Omap3530Interrupt.h"
+#include "Omap3530Prcm.h"
+#include "Omap3530Timer.h"
+#include "Omap3530Uart.h"
+#include "Omap3530Usb.h"
+#include "Omap3530MMCHS.h"
+#include "Omap3530I2c.h"
+#include "Omap3530PadConfiguration.h"
+#include "Omap3530Gpmc.h"
+#include "Omap3530Dma.h"
+
+
+//CONTROL_PBIAS_LITE
+#define CONTROL_PBIAS_LITE    0x48002520
+#define PBIASLITEVMODE0       BIT0
+#define PBIASLITEPWRDNZ0      BIT1
+#define PBIASSPEEDCTRL0       BIT2
+#define PBIASLITEVMODE1       BIT8
+#define PBIASLITEWRDNZ1       BIT9
+
+#endif // __OMAP3530_H__
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Dma.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Dma.h
new file mode 100644
index 0000000000..c04fb7f70a
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Dma.h
@@ -0,0 +1,124 @@
+/** @file
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530DMA_H__
+#define __OMAP3530DMA_H__
+
+
+#define DMA4_MAX_CHANNEL 31
+
+#define DMA4_IRQENABLE_L(_i)  (0x48056018 + (0x4*(_i)))
+
+#define DMA4_CCR(_i)  (0x48056080 + (0x60*(_i)))
+#define DMA4_CICR(_i) (0x48056088 + (0x60*(_i)))
+#define DMA4_CSR(_i)  (0x4805608c + (0x60*(_i)))
+#define DMA4_CSDP(_i) (0x48056090 + (0x60*(_i)))
+#define DMA4_CEN(_i)  (0x48056094 + (0x60*(_i)))
+#define DMA4_CFN(_i)  (0x48056098 + (0x60*(_i)))
+#define DMA4_CSSA(_i) (0x4805609c + (0x60*(_i)))
+#define DMA4_CDSA(_i) (0x480560a0 + (0x60*(_i)))
+#define DMA4_CSEI(_i) (0x480560a4 + (0x60*(_i)))
+#define DMA4_CSFI(_i) (0x480560a8 + (0x60*(_i)))
+#define DMA4_CDEI(_i) (0x480560ac + (0x60*(_i)))
+#define DMA4_CDFI(_i) (0x480560b0 + (0x60*(_i)))
+
+#define DMA4_GCR      (0x48056078)
+
+// Channel Source Destination parameters
+#define DMA4_CSDP_DATA_TYPE8    0
+#define DMA4_CSDP_DATA_TYPE16   1
+#define DMA4_CSDP_DATA_TYPE32   2
+
+#define DMA4_CSDP_SRC_PACKED      BIT6
+#define DMA4_CSDP_SRC_NONPACKED   0
+
+#define DMA4_CSDP_SRC_BURST_EN    (0x0 << 7)
+#define DMA4_CSDP_SRC_BURST_EN16  (0x1 << 7)
+#define DMA4_CSDP_SRC_BURST_EN32  (0x2 << 7)
+#define DMA4_CSDP_SRC_BURST_EN64  (0x3 << 7)
+
+#define DMA4_CSDP_DST_PACKED      BIT13
+#define DMA4_CSDP_DST_NONPACKED   0
+
+#define DMA4_CSDP_BURST_EN        (0x0 << 14)
+#define DMA4_CSDP_BURST_EN16      (0x1 << 14)
+#define DMA4_CSDP_BURST_EN32      (0x2 << 14)
+#define DMA4_CSDP_BURST_EN64      (0x3 << 14)
+
+#define DMA4_CSDP_WRITE_MODE_NONE_POSTED      (0x0 << 16)
+#define DMA4_CSDP_WRITE_MODE_POSTED           (0x1 << 16)
+#define DMA4_CSDP_WRITE_MODE_LAST_NON_POSTED  (0x2 << 16)
+
+#define DMA4_CSDP_DST_ENDIAN_LOCK_LOCK    BIT18
+#define DMA4_CSDP_DST_ENDIAN_LOCK_ADAPT   0
+
+#define DMA4_CSDP_DST_ENDIAN_BIG          BIT19
+#define DMA4_CSDP_DST_ENDIAN_LITTLE       0
+
+#define DMA4_CSDP_SRC_ENDIAN_LOCK_LOCK    BIT20
+#define DMA4_CSDP_SRC_ENDIAN_LOCK_ADAPT   0
+
+#define DMA4_CSDP_SRC_ENDIAN_BIG          BIT21
+#define DMA4_CSDP_SRC_ENDIAN_LITTLE       0
+
+// Channel Control
+#define DMA4_CCR_SYNCHRO_CONTROL_MASK     0x1f
+
+#define DMA4_CCR_FS_ELEMENT     (0    | 0)
+#define DMA4_CCR_FS_BLOCK       (0    | BIT18)
+#define DMA4_CCR_FS_FRAME       (BIT5 | 0)
+#define DMA4_CCR_FS_PACKET      (BIT5 | BIT18)
+
+#define DMA4_CCR_READ_PRIORITY_HIGH   BIT6
+#define DMA4_CCR_READ_PRIORITY_LOW    0
+
+#define DMA4_CCR_ENABLE               BIT7
+#define DMA4_CCR_DISABLE              0
+
+#define DMA4_CCR_SUSPEND_SENSITIVE_IGNORE BIT8
+#define DMA4_CCR_SUSPEND_SENSITIVE        0
+
+#define DMA4_CCR_RD_ACTIVE                BIT9
+#define DMA4_CCR_WR_ACTIVE                BIT10
+
+#define DMA4_CCR_SRC_AMODE                (0     | 0)
+#define DMA4_CCR_SRC_AMODE_POST_INC       (0     | BIT12)
+#define DMA4_CCR_SRC_AMODE_SINGLE_INDEX   (BIT13 | 0)
+#define DMA4_CCR_SRC_AMODE_DOUBLE_INDEX   (BIT13 | BIT12)
+
+#define DMA4_CCR_DST_AMODE                (0     | 0)
+#define DMA4_CCR_DST_AMODE_POST_INC       (0     | BIT14)
+#define DMA4_CCR_DST_AMODE_SINGLE_INDEX   (BIT15 | 0)
+#define DMA4_CCR_DST_AMODE_DOUBLE_INDEX   (BIT15 | BIT14)
+
+#define DMA4_CCR_CONST_FILL_ENABLE        BIT16
+#define DMA4_CCR_TRANSPARENT_COPY_ENABLE  BIT17
+
+#define DMA4_CCR_SEL_SRC_DEST_SYNC_SOURCE BIT24
+
+#define DMA4_CSR_DROP                     BIT1
+#define DMA4_CSR_HALF                     BIT2
+#define DMA4_CSR_FRAME                    BIT3
+#define DMA4_CSR_LAST                     BIT4
+#define DMA4_CSR_BLOCK                    BIT5
+#define DMA4_CSR_SYNC                     BIT6
+#define DMA4_CSR_PKT                      BIT7
+#define DMA4_CSR_TRANS_ERR                BIT8
+#define DMA4_CSR_SECURE_ERR               BIT9
+#define DMA4_CSR_SUPERVISOR_ERR           BIT10
+#define DMA4_CSR_MISALIGNED_ADRS_ERR      BIT11
+#define DMA4_CSR_DRAIN_END                BIT12
+#define DMA4_CSR_RESET                    0x1FE
+#define DMA4_CSR_ERR                      (DMA4_CSR_TRANS_ERR | DMA4_CSR_SECURE_ERR | DMA4_CSR_SUPERVISOR_ERR | DMA4_CSR_MISALIGNED_ADRS_ERR)
+
+// same mapping as CSR except for SYNC. Enable all since we are polling
+#define DMA4_CICR_ENABLE_ALL              0x1FBE
+
+
+#endif
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpio.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpio.h
new file mode 100644
index 0000000000..51ccd17146
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpio.h
@@ -0,0 +1,125 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530GPIO_H__
+#define __OMAP3530GPIO_H__
+
+#define GPIO1_BASE (0x48310000)
+#define GPIO2_BASE (0x49050000)
+#define GPIO3_BASE (0x49052000)
+#define GPIO4_BASE (0x49054000)
+#define GPIO5_BASE (0x49056000)
+#define GPIO6_BASE (0x49058000)
+
+#define GPIO_SYSCONFIG        (0x0010)
+#define GPIO_SYSSTATUS        (0x0014)
+#define GPIO_IRQSTATUS1       (0x0018)
+#define GPIO_IRQENABLE1       (0x001C)
+#define GPIO_WAKEUPENABLE     (0x0020)
+#define GPIO_IRQSTATUS2       (0x0028)
+#define GPIO_IRQENABLE2       (0x002C)
+#define GPIO_CTRL             (0x0030)
+#define GPIO_OE               (0x0034)
+#define GPIO_DATAIN           (0x0038)
+#define GPIO_DATAOUT          (0x003C)
+#define GPIO_LEVELDETECT0     (0x0040)
+#define GPIO_LEVELDETECT1     (0x0044)
+#define GPIO_RISINGDETECT     (0x0048)
+#define GPIO_FALLINGDETECT    (0x004C)
+#define GPIO_DEBOUNCENABLE    (0x0050)
+#define GPIO_DEBOUNCINGTIME   (0x0054)
+#define GPIO_CLEARIRQENABLE1  (0x0060)
+#define GPIO_SETIRQENABLE1    (0x0064)
+#define GPIO_CLEARIRQENABLE2  (0x0070)
+#define GPIO_SETIRQENABLE2    (0x0074)
+#define GPIO_CLEARWKUENA      (0x0080)
+#define GPIO_SETWKUENA        (0x0084)
+#define GPIO_CLEARDATAOUT     (0x0090)
+#define GPIO_SETDATAOUT       (0x0094)
+
+#define GPIO_SYSCONFIG_IDLEMODE_MASK      (3UL << 3)
+#define GPIO_SYSCONFIG_IDLEMODE_FORCE     (0UL << 3)
+#define GPIO_SYSCONFIG_IDLEMODE_NONE      BIT3
+#define GPIO_SYSCONFIG_IDLEMODE_SMART     (2UL << 3)
+#define GPIO_SYSCONFIG_ENAWAKEUP_MASK     BIT2
+#define GPIO_SYSCONFIG_ENAWAKEUP_DISABLE  (0UL << 2)
+#define GPIO_SYSCONFIG_ENAWAKEUP_ENABLE   BIT2
+#define GPIO_SYSCONFIG_SOFTRESET_MASK     BIT1
+#define GPIO_SYSCONFIG_SOFTRESET_NORMAL   (0UL << 1)
+#define GPIO_SYSCONFIG_SOFTRESET_RESET    BIT1
+#define GPIO_SYSCONFIG_AUTOIDLE_MASK      BIT0
+#define GPIO_SYSCONFIG_AUTOIDLE_FREE_RUN  (0UL << 0)
+#define GPIO_SYSCONFIG_AUTOIDLE_ON        BIT0
+
+#define GPIO_SYSSTATUS_RESETDONE_MASK     BIT0
+#define GPIO_SYSSTATUS_RESETDONE_ONGOING  (0UL << 0)
+#define GPIO_SYSSTATUS_RESETDONE_COMPLETE BIT0
+
+#define GPIO_IRQSTATUS_MASK(x)            (1UL << (x))
+#define GPIO_IRQSTATUS_NOT_TRIGGERED(x)   (0UL << (x))
+#define GPIO_IRQSTATUS_TRIGGERED(x)       (1UL << (x))
+#define GPIO_IRQSTATUS_CLEAR(x)           (1UL << (x))
+
+#define GPIO_IRQENABLE_MASK(x)            (1UL << (x))
+#define GPIO_IRQENABLE_DISABLE(x)         (0UL << (x))
+#define GPIO_IRQENABLE_ENABLE(x)          (1UL << (x))
+
+#define GPIO_WAKEUPENABLE_MASK(x)         (1UL << (x))
+#define GPIO_WAKEUPENABLE_DISABLE(x)      (0UL << (x))
+#define GPIO_WAKEUPENABLE_ENABLE(x)       (1UL << (x))
+
+#define GPIO_CTRL_GATINGRATIO_MASK        (3UL << 1)
+#define GPIO_CTRL_GATINGRATIO_DIV_1       (0UL << 1)
+#define GPIO_CTRL_GATINGRATIO_DIV_2       BIT1
+#define GPIO_CTRL_GATINGRATIO_DIV_4       (2UL << 1)
+#define GPIO_CTRL_GATINGRATIO_DIV_8       (3UL << 1)
+#define GPIO_CTRL_DISABLEMODULE_MASK      BIT0
+#define GPIO_CTRL_DISABLEMODULE_ENABLE    (0UL << 0)
+#define GPIO_CTRL_DISABLEMODULE_DISABLE   BIT0
+
+#define GPIO_OE_MASK(x)                   (1UL << (x))
+#define GPIO_OE_OUTPUT(x)                 (0UL << (x))
+#define GPIO_OE_INPUT(x)                  (1UL << (x))
+
+#define GPIO_DATAIN_MASK(x)               (1UL << (x))
+
+#define GPIO_DATAOUT_MASK(x)              (1UL << (x))
+
+#define GPIO_LEVELDETECT_MASK(x)          (1UL << (x))
+#define GPIO_LEVELDETECT_DISABLE(x)       (0UL << (x))
+#define GPIO_LEVELDETECT_ENABLE(x)        (1UL << (x))
+
+#define GPIO_RISINGDETECT_MASK(x)         (1UL << (x))
+#define GPIO_RISINGDETECT_DISABLE(x)      (0UL << (x))
+#define GPIO_RISINGDETECT_ENABLE(x)       (1UL << (x))
+
+#define GPIO_FALLINGDETECT_MASK(x)        (1UL << (x))
+#define GPIO_FALLINGDETECT_DISABLE(x)     (0UL << (x))
+#define GPIO_FALLINGDETECT_ENABLE(x)      (1UL << (x))
+
+#define GPIO_DEBOUNCENABLE_MASK(x)        (1UL << (x))
+#define GPIO_DEBOUNCENABLE_DISABLE(x)     (0UL << (x))
+#define GPIO_DEBOUNCENABLE_ENABLE(x)      (1UL << (x))
+
+#define GPIO_DEBOUNCINGTIME_MASK          (0xFF)
+#define GPIO_DEBOUNCINGTIME_US(x)         ((((x) / 31) - 1) & GPIO_DEBOUNCINGTIME_MASK)
+
+#define GPIO_CLEARIRQENABLE_BIT(x)        (1UL << (x))
+
+#define GPIO_SETIRQENABLE_BIT(x)          (1UL << (x))
+
+#define GPIO_CLEARWKUENA_BIT(x)           (1UL << (x))
+
+#define GPIO_SETWKUENA_BIT(x)             (1UL << (x))
+
+#define GPIO_CLEARDATAOUT_BIT(x)          (1UL << (x))
+
+#define GPIO_SETDATAOUT_BIT(x)            (1UL << (x))
+
+#endif // __OMAP3530GPIO_H__
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpmc.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpmc.h
new file mode 100644
index 0000000000..4465b4fa2b
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Gpmc.h
@@ -0,0 +1,101 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530GPMC_H__
+#define __OMAP3530GPMC_H__
+
+#define GPMC_BASE             (0x6E000000)
+
+//GPMC NAND definitions.
+#define GPMC_SYSCONFIG        (GPMC_BASE + 0x10)
+#define SMARTIDLEMODE         (0x2UL << 3)
+
+#define GPMC_SYSSTATUS        (GPMC_BASE + 0x14)
+#define GPMC_IRQSTATUS        (GPMC_BASE + 0x18)
+#define GPMC_IRQENABLE        (GPMC_BASE + 0x1C)
+
+#define GPMC_TIMEOUT_CONTROL  (GPMC_BASE + 0x40)
+#define TIMEOUTENABLE         BIT0
+#define TIMEOUTDISABLE        (0x0UL << 0)
+
+#define GPMC_ERR_ADDRESS      (GPMC_BASE + 0x44)
+#define GPMC_ERR_TYPE         (GPMC_BASE + 0x48)
+
+#define GPMC_CONFIG           (GPMC_BASE + 0x50)
+#define WRITEPROTECT_HIGH     BIT4
+#define WRITEPROTECT_LOW      (0x0UL << 4)
+
+#define GPMC_STATUS           (GPMC_BASE + 0x54)
+
+#define GPMC_CONFIG1_0        (GPMC_BASE + 0x60)
+#define DEVICETYPE_NOR        (0x0UL << 10)
+#define DEVICETYPE_NAND       (0x2UL << 10)
+#define DEVICESIZE_X8         (0x0UL << 12)
+#define DEVICESIZE_X16        BIT12
+
+#define GPMC_CONFIG2_0        (GPMC_BASE + 0x64)
+#define CSONTIME              (0x0UL << 0)
+#define CSRDOFFTIME           (0x14UL << 8)
+#define CSWROFFTIME           (0x14UL << 16)
+
+#define GPMC_CONFIG3_0        (GPMC_BASE + 0x68)
+#define ADVRDOFFTIME          (0x14UL << 8)
+#define ADVWROFFTIME          (0x14UL << 16)
+
+#define GPMC_CONFIG4_0        (GPMC_BASE + 0x6C)
+#define OEONTIME              BIT0
+#define OEOFFTIME             (0xFUL << 8)
+#define WEONTIME              BIT16
+#define WEOFFTIME             (0xFUL << 24)
+
+#define GPMC_CONFIG5_0        (GPMC_BASE + 0x70)
+#define RDCYCLETIME           (0x14UL << 0)
+#define WRCYCLETIME           (0x14UL << 8)
+#define RDACCESSTIME          (0xCUL << 16)
+#define PAGEBURSTACCESSTIME   BIT24
+
+#define GPMC_CONFIG6_0        (GPMC_BASE + 0x74)
+#define CYCLE2CYCLESAMECSEN   BIT7
+#define CYCLE2CYCLEDELAY      (0xAUL << 8)
+#define WRDATAONADMUXBUS      (0xFUL << 16)
+#define WRACCESSTIME          BIT24
+
+#define GPMC_CONFIG7_0        (GPMC_BASE + 0x78)
+#define BASEADDRESS           (0x30UL << 0)
+#define CSVALID               BIT6
+#define MASKADDRESS_128MB     (0x8UL << 8)
+
+#define GPMC_NAND_COMMAND_0   (GPMC_BASE + 0x7C)
+#define GPMC_NAND_ADDRESS_0   (GPMC_BASE + 0x80)
+#define GPMC_NAND_DATA_0      (GPMC_BASE + 0x84)
+
+#define GPMC_ECC_CONFIG       (GPMC_BASE + 0x1F4)
+#define ECCENABLE             BIT0
+#define ECCDISABLE            (0x0UL << 0)
+#define ECCCS_0               (0x0UL << 1)
+#define ECC16B                BIT7
+
+#define GPMC_ECC_CONTROL      (GPMC_BASE + 0x1F8)
+#define ECCPOINTER_REG1       BIT0
+#define ECCCLEAR              BIT8
+
+#define GPMC_ECC_SIZE_CONFIG  (GPMC_BASE + 0x1FC)
+#define ECCSIZE0_512BYTES     (0xFFUL << 12)
+#define ECCSIZE1_512BYTES     (0xFFUL << 22)
+
+#define GPMC_ECC1_RESULT      (GPMC_BASE + 0x200)
+#define GPMC_ECC2_RESULT      (GPMC_BASE + 0x204)
+#define GPMC_ECC3_RESULT      (GPMC_BASE + 0x208)
+#define GPMC_ECC4_RESULT      (GPMC_BASE + 0x20C)
+#define GPMC_ECC5_RESULT      (GPMC_BASE + 0x210)
+#define GPMC_ECC6_RESULT      (GPMC_BASE + 0x214)
+#define GPMC_ECC7_RESULT      (GPMC_BASE + 0x218)
+#define GPMC_ECC8_RESULT      (GPMC_BASE + 0x21C)
+#define GPMC_ECC9_RESULT      (GPMC_BASE + 0x220)
+
+#endif //__OMAP3530GPMC_H__
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530I2c.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530I2c.h
new file mode 100644
index 0000000000..e91f421b80
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530I2c.h
@@ -0,0 +1,56 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530I2C_H__
+#define __OMAP3530I2C_H__
+
+//I2C register definitions.
+#define I2C1BASE        0x48070000
+
+#define I2C_IE          (I2C1BASE + 0x4)
+#define XRDY_IE         BIT4
+#define RRDY_IE         BIT3
+#define ARDY_IE         BIT2
+#define NACK_IE         BIT1
+
+#define I2C_STAT        (I2C1BASE + 0x8)
+#define BB              BIT12
+#define XRDY            BIT4
+#define RRDY            BIT3
+#define ARDY            BIT2
+#define NACK            BIT1
+
+#define I2C_WE          (I2C1BASE + 0xC)
+#define I2C_SYSS        (I2C1BASE + 0x10)
+#define I2C_BUF         (I2C1BASE + 0x14)
+#define I2C_CNT         (I2C1BASE + 0x18)
+#define I2C_DATA        (I2C1BASE + 0x1C)
+#define I2C_SYSC        (I2C1BASE + 0x20)
+
+#define I2C_CON         (I2C1BASE + 0x24)
+#define STT             BIT0
+#define STP             BIT1
+#define XSA             BIT8
+#define TRX             BIT9
+#define MST             BIT10
+#define I2C_EN          BIT15
+
+#define I2C_OA0         (I2C1BASE + 0x28)
+#define I2C_SA          (I2C1BASE + 0x2C)
+#define I2C_PSC         (I2C1BASE + 0x30)
+#define I2C_SCLL        (I2C1BASE + 0x34)
+#define I2C_SCLH        (I2C1BASE + 0x38)
+#define I2C_SYSTEST     (I2C1BASE + 0x3C)
+#define I2C_BUFSTAT     (I2C1BASE + 0x40)
+#define I2C_OA1         (I2C1BASE + 0x44)
+#define I2C_OA2         (I2C1BASE + 0x48)
+#define I2C_OA3         (I2C1BASE + 0x4C)
+#define I2C_ACTOA       (I2C1BASE + 0x50)
+#define I2C_SBLOCK      (I2C1BASE + 0x54)
+
+#endif //__OMAP3530I2C_H__
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Interrupt.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Interrupt.h
new file mode 100644
index 0000000000..20339e2bd5
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Interrupt.h
@@ -0,0 +1,45 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530INTERRUPT_H__
+#define __OMAP3530INTERRUPT_H__
+
+#include <Library/PcdLib.h>
+
+#define INTERRUPT_BASE        (PcdGet32 (PcdInterruptBaseAddress))
+
+#define INT_NROF_VECTORS      (96)
+#define MAX_VECTOR            (INT_NROF_VECTORS - 1)
+#define INTCPS_SYSCONFIG      (INTERRUPT_BASE + 0x0010)
+#define INTCPS_SYSSTATUS      (INTERRUPT_BASE + 0x0014)
+#define INTCPS_SIR_IRQ        (INTERRUPT_BASE + 0x0040)
+#define INTCPS_SIR_IFQ        (INTERRUPT_BASE + 0x0044)
+#define INTCPS_CONTROL        (INTERRUPT_BASE + 0x0048)
+#define INTCPS_PROTECTION     (INTERRUPT_BASE + 0x004C)
+#define INTCPS_IDLE           (INTERRUPT_BASE + 0x0050)
+#define INTCPS_IRQ_PRIORITY   (INTERRUPT_BASE + 0x0060)
+#define INTCPS_FIQ_PRIORITY   (INTERRUPT_BASE + 0x0064)
+#define INTCPS_THRESHOLD      (INTERRUPT_BASE + 0x0068)
+#define INTCPS_ITR(n)         (INTERRUPT_BASE + 0x0080 + (0x20 * (n)))
+#define INTCPS_MIR(n)         (INTERRUPT_BASE + 0x0084 + (0x20 * (n)))
+#define INTCPS_MIR_CLEAR(n)   (INTERRUPT_BASE + 0x0088 + (0x20 * (n)))
+#define INTCPS_MIR_SET(n)     (INTERRUPT_BASE + 0x008C + (0x20 * (n)))
+#define INTCPS_ISR_SET(n)     (INTERRUPT_BASE + 0x0090 + (0x20 * (n)))
+#define INTCPS_ISR_CLEAR(n)   (INTERRUPT_BASE + 0x0094 + (0x20 * (n)))
+#define INTCPS_PENDING_IRQ(n) (INTERRUPT_BASE + 0x0098 + (0x20 * (n)))
+#define INTCPS_PENDING_FIQ(n) (INTERRUPT_BASE + 0x009C + (0x20 * (n)))
+#define INTCPS_ILR(m)         (INTERRUPT_BASE + 0x0100 + (0x04 * (m)))
+
+#define INTCPS_ILR_FIQ            BIT0
+#define INTCPS_SIR_IRQ_MASK       (0x7F)
+#define INTCPS_CONTROL_NEWIRQAGR  BIT0
+#define INTCPS_CONTROL_NEWFIQAGR  BIT1
+
+#endif // __OMAP3530INTERRUPT_H__
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530MMCHS.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530MMCHS.h
new file mode 100644
index 0000000000..1819ff5031
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530MMCHS.h
@@ -0,0 +1,208 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530SDIO_H__
+#define __OMAP3530SDIO_H__
+
+//MMC/SD/SDIO1 register definitions.
+#define MMCHS1BASE        0x4809C000
+#define MMC_REFERENCE_CLK (96000000)
+
+#define MMCHS_SYSCONFIG   (MMCHS1BASE + 0x10)
+#define SOFTRESET         BIT1
+#define ENAWAKEUP         BIT2
+
+#define MMCHS_SYSSTATUS   (MMCHS1BASE + 0x14)
+#define RESETDONE_MASK    BIT0
+#define RESETDONE         BIT0
+
+#define MMCHS_CSRE        (MMCHS1BASE + 0x24)
+#define MMCHS_SYSTEST     (MMCHS1BASE + 0x28)
+
+#define MMCHS_CON         (MMCHS1BASE + 0x2C)
+#define OD                BIT0
+#define NOINIT            (0x0UL << 1)
+#define INIT              BIT1
+#define HR                BIT2
+#define STR               BIT3
+#define MODE              BIT4
+#define DW8_1_4_BIT       (0x0UL << 5)
+#define DW8_8_BIT         BIT5
+#define MIT               BIT6
+#define CDP               BIT7
+#define WPP               BIT8
+#define CTPL              BIT11
+#define CEATA_OFF         (0x0UL << 12)
+#define CEATA_ON          BIT12
+
+#define MMCHS_PWCNT       (MMCHS1BASE + 0x30)
+
+#define MMCHS_BLK         (MMCHS1BASE + 0x104)
+#define BLEN_512BYTES     (0x200UL << 0)
+
+#define MMCHS_ARG         (MMCHS1BASE + 0x108)
+
+#define MMCHS_CMD         (MMCHS1BASE + 0x10C)
+#define DE_ENABLE         BIT0
+#define BCE_ENABLE        BIT1
+#define ACEN_ENABLE       BIT2
+#define DDIR_READ         BIT4
+#define DDIR_WRITE        (0x0UL << 4)
+#define MSBS_SGLEBLK      (0x0UL << 5)
+#define MSBS_MULTBLK      BIT5
+#define RSP_TYPE_MASK     (0x3UL << 16)
+#define RSP_TYPE_136BITS  BIT16
+#define RSP_TYPE_48BITS   (0x2UL << 16)
+#define CCCE_ENABLE       BIT19
+#define CICE_ENABLE       BIT20
+#define DP_ENABLE         BIT21
+#define INDX(CMD_INDX)    ((CMD_INDX & 0x3F) << 24)
+
+#define MMCHS_RSP10       (MMCHS1BASE + 0x110)
+#define MMCHS_RSP32       (MMCHS1BASE + 0x114)
+#define MMCHS_RSP54       (MMCHS1BASE + 0x118)
+#define MMCHS_RSP76       (MMCHS1BASE + 0x11C)
+#define MMCHS_DATA        (MMCHS1BASE + 0x120)
+
+#define MMCHS_PSTATE      (MMCHS1BASE + 0x124)
+#define CMDI_MASK         BIT0
+#define CMDI_ALLOWED      (0x0UL << 0)
+#define CMDI_NOT_ALLOWED  BIT0
+#define DATI_MASK         BIT1
+#define DATI_ALLOWED      (0x0UL << 1)
+#define DATI_NOT_ALLOWED  BIT1
+
+#define MMCHS_HCTL        (MMCHS1BASE + 0x128)
+#define DTW_1_BIT         (0x0UL << 1)
+#define DTW_4_BIT         BIT1
+#define SDBP_MASK         BIT8
+#define SDBP_OFF          (0x0UL << 8)
+#define SDBP_ON           BIT8
+#define SDVS_1_8_V        (0x5UL << 9)
+#define SDVS_3_0_V        (0x6UL << 9)
+#define IWE               BIT24
+
+#define MMCHS_SYSCTL      (MMCHS1BASE + 0x12C)
+#define ICE               BIT0
+#define ICS_MASK          BIT1
+#define ICS               BIT1
+#define CEN               BIT2
+#define CLKD_MASK         (0x3FFUL << 6)
+#define CLKD_80KHZ        (0x258UL) //(96*1000/80)/2
+#define CLKD_400KHZ       (0xF0UL)
+#define DTO_MASK          (0xFUL << 16)
+#define DTO_VAL           (0xEUL << 16)
+#define SRA               BIT24
+#define SRC_MASK          BIT25
+#define SRC               BIT25
+#define SRD               BIT26
+
+#define MMCHS_STAT        (MMCHS1BASE + 0x130)
+#define CC                BIT0
+#define TC                BIT1
+#define BWR               BIT4
+#define BRR               BIT5
+#define ERRI              BIT15
+#define CTO               BIT16
+#define DTO               BIT20
+#define DCRC              BIT21
+#define DEB               BIT22
+
+#define MMCHS_IE          (MMCHS1BASE + 0x134)
+#define CC_EN             BIT0
+#define TC_EN             BIT1
+#define BWR_EN            BIT4
+#define BRR_EN            BIT5
+#define CTO_EN            BIT16
+#define CCRC_EN           BIT17
+#define CEB_EN            BIT18
+#define CIE_EN            BIT19
+#define DTO_EN            BIT20
+#define DCRC_EN           BIT21
+#define DEB_EN            BIT22
+#define CERR_EN           BIT28
+#define BADA_EN           BIT29
+
+#define MMCHS_ISE         (MMCHS1BASE + 0x138)
+#define CC_SIGEN          BIT0
+#define TC_SIGEN          BIT1
+#define BWR_SIGEN         BIT4
+#define BRR_SIGEN         BIT5
+#define CTO_SIGEN         BIT16
+#define CCRC_SIGEN        BIT17
+#define CEB_SIGEN         BIT18
+#define CIE_SIGEN         BIT19
+#define DTO_SIGEN         BIT20
+#define DCRC_SIGEN        BIT21
+#define DEB_SIGEN         BIT22
+#define CERR_SIGEN        BIT28
+#define BADA_SIGEN        BIT29
+
+#define MMCHS_AC12        (MMCHS1BASE + 0x13C)
+
+#define MMCHS_CAPA        (MMCHS1BASE + 0x140)
+#define VS30              BIT25
+#define VS18              BIT26
+
+#define MMCHS_CUR_CAPA    (MMCHS1BASE + 0x148)
+#define MMCHS_REV         (MMCHS1BASE + 0x1FC)
+
+#define CMD0              INDX(0)
+#define CMD0_INT_EN       (CC_EN | CEB_EN)
+
+#define CMD1              (INDX(1) | RSP_TYPE_48BITS)
+#define CMD1_INT_EN       (CC_EN | CEB_EN | CTO_EN)
+
+#define CMD2              (INDX(2) | CCCE_ENABLE | RSP_TYPE_136BITS)
+#define CMD2_INT_EN       (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#define CMD3              (INDX(3) | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS)
+#define CMD3_INT_EN       (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#define CMD5              (INDX(5) | RSP_TYPE_48BITS)
+#define CMD5_INT_EN       (CC_EN | CEB_EN | CTO_EN)
+
+#define CMD7              (INDX(7) | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS)
+#define CMD7_INT_EN       (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#define CMD8              (INDX(8) | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS)
+#define CMD8_INT_EN       (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+//Reserved(0)[12:31], Supply voltage(1)[11:8], check pattern(0xCE)[7:0] = 0x1CE
+#define CMD8_ARG          (0x0UL << 12 | BIT8 | 0xCEUL << 0)
+
+#define CMD9              (INDX(9) | CCCE_ENABLE | RSP_TYPE_136BITS)
+#define CMD9_INT_EN       (CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#define CMD16             (INDX(16) | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS)
+#define CMD16_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#define CMD17             (INDX(17) | DP_ENABLE | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS | DDIR_READ)
+#define CMD17_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | TC_EN | BRR_EN | CTO_EN | DTO_EN | DCRC_EN | DEB_EN | CEB_EN)
+
+#define CMD18             (INDX(18) | DP_ENABLE | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS | MSBS_MULTBLK | DDIR_READ | BCE_ENABLE | DE_ENABLE)
+#define CMD18_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | TC_EN | BRR_EN | CTO_EN | DTO_EN | DCRC_EN | DEB_EN | CEB_EN)
+
+#define CMD23             (INDX(23) | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS)
+#define CMD23_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#define CMD24             (INDX(24) | DP_ENABLE | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS | DDIR_WRITE)
+#define CMD24_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | TC_EN | BWR_EN | CTO_EN | DTO_EN | DCRC_EN | DEB_EN | CEB_EN)
+
+#define CMD25             (INDX(25) | DP_ENABLE | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS | MSBS_MULTBLK | DDIR_READ | BCE_ENABLE | DE_ENABLE)
+#define CMD25_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | TC_EN | BRR_EN | CTO_EN | DTO_EN | DCRC_EN | DEB_EN | CEB_EN)
+
+#define CMD55             (INDX(55) | CICE_ENABLE | CCCE_ENABLE | RSP_TYPE_48BITS)
+#define CMD55_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#define ACMD41            (INDX(41) | RSP_TYPE_48BITS)
+#define ACMD41_INT_EN     (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#define ACMD6             (INDX(6) | RSP_TYPE_48BITS)
+#define ACMD6_INT_EN      (CERR_EN | CIE_EN | CCRC_EN | CC_EN | CEB_EN | CTO_EN)
+
+#endif //__OMAP3530SDIO_H__
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530PadConfiguration.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530PadConfiguration.h
new file mode 100644
index 0000000000..53456a820d
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530PadConfiguration.h
@@ -0,0 +1,297 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530_PAD_CONFIGURATION_H__
+#define __OMAP3530_PAD_CONFIGURATION_H__
+
+#define SYSTEM_CONTROL_MODULE_BASE  0x48002000
+
+//Pin definition
+#define SDRC_D0             (SYSTEM_CONTROL_MODULE_BASE + 0x030)
+#define SDRC_D1             (SYSTEM_CONTROL_MODULE_BASE + 0x032)
+#define SDRC_D2             (SYSTEM_CONTROL_MODULE_BASE + 0x034)
+#define SDRC_D3             (SYSTEM_CONTROL_MODULE_BASE + 0x036)
+#define SDRC_D4             (SYSTEM_CONTROL_MODULE_BASE + 0x038)
+#define SDRC_D5             (SYSTEM_CONTROL_MODULE_BASE + 0x03A)
+#define SDRC_D6             (SYSTEM_CONTROL_MODULE_BASE + 0x03C)
+#define SDRC_D7             (SYSTEM_CONTROL_MODULE_BASE + 0x03E)
+#define SDRC_D8             (SYSTEM_CONTROL_MODULE_BASE + 0x040)
+#define SDRC_D9             (SYSTEM_CONTROL_MODULE_BASE + 0x042)
+#define SDRC_D10            (SYSTEM_CONTROL_MODULE_BASE + 0x044)
+#define SDRC_D11            (SYSTEM_CONTROL_MODULE_BASE + 0x046)
+#define SDRC_D12            (SYSTEM_CONTROL_MODULE_BASE + 0x048)
+#define SDRC_D13            (SYSTEM_CONTROL_MODULE_BASE + 0x04A)
+#define SDRC_D14            (SYSTEM_CONTROL_MODULE_BASE + 0x04C)
+#define SDRC_D15            (SYSTEM_CONTROL_MODULE_BASE + 0x04E)
+#define SDRC_D16            (SYSTEM_CONTROL_MODULE_BASE + 0x050)
+#define SDRC_D17            (SYSTEM_CONTROL_MODULE_BASE + 0x052)
+#define SDRC_D18            (SYSTEM_CONTROL_MODULE_BASE + 0x054)
+#define SDRC_D19            (SYSTEM_CONTROL_MODULE_BASE + 0x056)
+#define SDRC_D20            (SYSTEM_CONTROL_MODULE_BASE + 0x058)
+#define SDRC_D21            (SYSTEM_CONTROL_MODULE_BASE + 0x05A)
+#define SDRC_D22            (SYSTEM_CONTROL_MODULE_BASE + 0x05C)
+#define SDRC_D23            (SYSTEM_CONTROL_MODULE_BASE + 0x05E)
+#define SDRC_D24            (SYSTEM_CONTROL_MODULE_BASE + 0x060)
+#define SDRC_D25            (SYSTEM_CONTROL_MODULE_BASE + 0x062)
+#define SDRC_D26            (SYSTEM_CONTROL_MODULE_BASE + 0x064)
+#define SDRC_D27            (SYSTEM_CONTROL_MODULE_BASE + 0x066)
+#define SDRC_D28            (SYSTEM_CONTROL_MODULE_BASE + 0x068)
+#define SDRC_D29            (SYSTEM_CONTROL_MODULE_BASE + 0x06A)
+#define SDRC_D30            (SYSTEM_CONTROL_MODULE_BASE + 0x06C)
+#define SDRC_D31            (SYSTEM_CONTROL_MODULE_BASE + 0x06E)
+#define SDRC_CLK            (SYSTEM_CONTROL_MODULE_BASE + 0x070)
+#define SDRC_DQS0           (SYSTEM_CONTROL_MODULE_BASE + 0x072)
+#define SDRC_CKE0           (SYSTEM_CONTROL_MODULE_BASE + 0x262)
+#define SDRC_CKE1           (SYSTEM_CONTROL_MODULE_BASE + 0x264)
+#define SDRC_DQS1           (SYSTEM_CONTROL_MODULE_BASE + 0x074)
+#define SDRC_DQS2           (SYSTEM_CONTROL_MODULE_BASE + 0x076)
+#define SDRC_DQS3           (SYSTEM_CONTROL_MODULE_BASE + 0x078)
+#define GPMC_A1             (SYSTEM_CONTROL_MODULE_BASE + 0x07A)
+#define GPMC_A2             (SYSTEM_CONTROL_MODULE_BASE + 0x07C)
+#define GPMC_A3             (SYSTEM_CONTROL_MODULE_BASE + 0x07E)
+#define GPMC_A4             (SYSTEM_CONTROL_MODULE_BASE + 0x080)
+#define GPMC_A5             (SYSTEM_CONTROL_MODULE_BASE + 0x082)
+#define GPMC_A6             (SYSTEM_CONTROL_MODULE_BASE + 0x084)
+#define GPMC_A7             (SYSTEM_CONTROL_MODULE_BASE + 0x086)
+#define GPMC_A8             (SYSTEM_CONTROL_MODULE_BASE + 0x088)
+#define GPMC_A9             (SYSTEM_CONTROL_MODULE_BASE + 0x08A)
+#define GPMC_A10            (SYSTEM_CONTROL_MODULE_BASE + 0x08C)
+#define GPMC_D0             (SYSTEM_CONTROL_MODULE_BASE + 0x08E)
+#define GPMC_D1             (SYSTEM_CONTROL_MODULE_BASE + 0x090)
+#define GPMC_D2             (SYSTEM_CONTROL_MODULE_BASE + 0x092)
+#define GPMC_D3             (SYSTEM_CONTROL_MODULE_BASE + 0x094)
+#define GPMC_D4             (SYSTEM_CONTROL_MODULE_BASE + 0x096)
+#define GPMC_D5             (SYSTEM_CONTROL_MODULE_BASE + 0x098)
+#define GPMC_D6             (SYSTEM_CONTROL_MODULE_BASE + 0x09A)
+#define GPMC_D7             (SYSTEM_CONTROL_MODULE_BASE + 0x09C)
+#define GPMC_D8             (SYSTEM_CONTROL_MODULE_BASE + 0x09E)
+#define GPMC_D9             (SYSTEM_CONTROL_MODULE_BASE + 0x0A0)
+#define GPMC_D10            (SYSTEM_CONTROL_MODULE_BASE + 0x0A2)
+#define GPMC_D11            (SYSTEM_CONTROL_MODULE_BASE + 0x0A4)
+#define GPMC_D12            (SYSTEM_CONTROL_MODULE_BASE + 0x0A6)
+#define GPMC_D13            (SYSTEM_CONTROL_MODULE_BASE + 0x0A8)
+#define GPMC_D14            (SYSTEM_CONTROL_MODULE_BASE + 0x0AA)
+#define GPMC_D15            (SYSTEM_CONTROL_MODULE_BASE + 0x0AC)
+#define GPMC_NCS0           (SYSTEM_CONTROL_MODULE_BASE + 0x0AE)
+#define GPMC_NCS1           (SYSTEM_CONTROL_MODULE_BASE + 0x0B0)
+#define GPMC_NCS2           (SYSTEM_CONTROL_MODULE_BASE + 0x0B2)
+#define GPMC_NCS3           (SYSTEM_CONTROL_MODULE_BASE + 0x0B4)
+#define GPMC_NCS4           (SYSTEM_CONTROL_MODULE_BASE + 0x0B6)
+#define GPMC_NCS5           (SYSTEM_CONTROL_MODULE_BASE + 0x0B8)
+#define GPMC_NCS6           (SYSTEM_CONTROL_MODULE_BASE + 0x0BA)
+#define GPMC_NCS7           (SYSTEM_CONTROL_MODULE_BASE + 0x0BC)
+#define GPMC_CLK            (SYSTEM_CONTROL_MODULE_BASE + 0x0BE)
+#define GPMC_NADV_ALE       (SYSTEM_CONTROL_MODULE_BASE + 0x0C0)
+#define GPMC_NOE            (SYSTEM_CONTROL_MODULE_BASE + 0x0C2)
+#define GPMC_NWE            (SYSTEM_CONTROL_MODULE_BASE + 0x0C4)
+#define GPMC_NBE0_CLE       (SYSTEM_CONTROL_MODULE_BASE + 0x0C6)
+#define GPMC_NBE1           (SYSTEM_CONTROL_MODULE_BASE + 0x0C8)
+#define GPMC_NWP            (SYSTEM_CONTROL_MODULE_BASE + 0x0CA)
+#define GPMC_WAIT0          (SYSTEM_CONTROL_MODULE_BASE + 0x0CC)
+#define GPMC_WAIT1          (SYSTEM_CONTROL_MODULE_BASE + 0x0CE)
+#define GPMC_WAIT2          (SYSTEM_CONTROL_MODULE_BASE + 0x0D0)
+#define GPMC_WAIT3          (SYSTEM_CONTROL_MODULE_BASE + 0x0D2)
+#define DSS_PCLK            (SYSTEM_CONTROL_MODULE_BASE + 0x0D4)
+#define DSS_HSYNC           (SYSTEM_CONTROL_MODULE_BASE + 0x0D6)
+#define DSS_PSYNC           (SYSTEM_CONTROL_MODULE_BASE + 0x0D8)
+#define DSS_ACBIAS          (SYSTEM_CONTROL_MODULE_BASE + 0x0DA)
+#define DSS_DATA0           (SYSTEM_CONTROL_MODULE_BASE + 0x0DC)
+#define DSS_DATA1           (SYSTEM_CONTROL_MODULE_BASE + 0x0DE)
+#define DSS_DATA2           (SYSTEM_CONTROL_MODULE_BASE + 0x0E0)
+#define DSS_DATA3           (SYSTEM_CONTROL_MODULE_BASE + 0x0E2)
+#define DSS_DATA4           (SYSTEM_CONTROL_MODULE_BASE + 0x0E4)
+#define DSS_DATA5           (SYSTEM_CONTROL_MODULE_BASE + 0x0E6)
+#define DSS_DATA6           (SYSTEM_CONTROL_MODULE_BASE + 0x0E8)
+#define DSS_DATA7           (SYSTEM_CONTROL_MODULE_BASE + 0x0EA)
+#define DSS_DATA8           (SYSTEM_CONTROL_MODULE_BASE + 0x0EC)
+#define DSS_DATA9           (SYSTEM_CONTROL_MODULE_BASE + 0x0EE)
+#define DSS_DATA10          (SYSTEM_CONTROL_MODULE_BASE + 0x0F0)
+#define DSS_DATA11          (SYSTEM_CONTROL_MODULE_BASE + 0x0F2)
+#define DSS_DATA12          (SYSTEM_CONTROL_MODULE_BASE + 0x0F4)
+#define DSS_DATA13          (SYSTEM_CONTROL_MODULE_BASE + 0x0F6)
+#define DSS_DATA14          (SYSTEM_CONTROL_MODULE_BASE + 0x0F8)
+#define DSS_DATA15          (SYSTEM_CONTROL_MODULE_BASE + 0x0FA)
+#define DSS_DATA16          (SYSTEM_CONTROL_MODULE_BASE + 0x0FC)
+#define DSS_DATA17          (SYSTEM_CONTROL_MODULE_BASE + 0x0FE)
+#define DSS_DATA18          (SYSTEM_CONTROL_MODULE_BASE + 0x100)
+#define DSS_DATA19          (SYSTEM_CONTROL_MODULE_BASE + 0x102)
+#define DSS_DATA20          (SYSTEM_CONTROL_MODULE_BASE + 0x104)
+#define DSS_DATA21          (SYSTEM_CONTROL_MODULE_BASE + 0x106)
+#define DSS_DATA22          (SYSTEM_CONTROL_MODULE_BASE + 0x108)
+#define DSS_DATA23          (SYSTEM_CONTROL_MODULE_BASE + 0x10A)
+#define CAM_HS              (SYSTEM_CONTROL_MODULE_BASE + 0x10C)
+#define CAM_VS              (SYSTEM_CONTROL_MODULE_BASE + 0x10E)
+#define CAM_XCLKA           (SYSTEM_CONTROL_MODULE_BASE + 0x110)
+#define CAM_PCLK            (SYSTEM_CONTROL_MODULE_BASE + 0x112)
+#define CAM_FLD             (SYSTEM_CONTROL_MODULE_BASE + 0x114)
+#define CAM_D0              (SYSTEM_CONTROL_MODULE_BASE + 0x116)
+#define CAM_D1              (SYSTEM_CONTROL_MODULE_BASE + 0x118)
+#define CAM_D2              (SYSTEM_CONTROL_MODULE_BASE + 0x11A)
+#define CAM_D3              (SYSTEM_CONTROL_MODULE_BASE + 0x11C)
+#define CAM_D4              (SYSTEM_CONTROL_MODULE_BASE + 0x11E)
+#define CAM_D5              (SYSTEM_CONTROL_MODULE_BASE + 0x120)
+#define CAM_D6              (SYSTEM_CONTROL_MODULE_BASE + 0x122)
+#define CAM_D7              (SYSTEM_CONTROL_MODULE_BASE + 0x124)
+#define CAM_D8              (SYSTEM_CONTROL_MODULE_BASE + 0x126)
+#define CAM_D9              (SYSTEM_CONTROL_MODULE_BASE + 0x128)
+#define CAM_D10             (SYSTEM_CONTROL_MODULE_BASE + 0x12A)
+#define CAM_D11             (SYSTEM_CONTROL_MODULE_BASE + 0x12C)
+#define CAM_XCLKB           (SYSTEM_CONTROL_MODULE_BASE + 0x12E)
+#define CAM_WEN             (SYSTEM_CONTROL_MODULE_BASE + 0x130)
+#define CAM_STROBE          (SYSTEM_CONTROL_MODULE_BASE + 0x132)
+#define CSI2_DX0            (SYSTEM_CONTROL_MODULE_BASE + 0x134)
+#define CSI2_DY0            (SYSTEM_CONTROL_MODULE_BASE + 0x136)
+#define CSI2_DX1            (SYSTEM_CONTROL_MODULE_BASE + 0x138)
+#define CSI2_DY1            (SYSTEM_CONTROL_MODULE_BASE + 0x13A)
+#define MCBSP2_FSX          (SYSTEM_CONTROL_MODULE_BASE + 0x13C)
+#define MCBSP2_CLKX         (SYSTEM_CONTROL_MODULE_BASE + 0x13E)
+#define MCBSP2_DR           (SYSTEM_CONTROL_MODULE_BASE + 0x140)
+#define MCBSP2_DX           (SYSTEM_CONTROL_MODULE_BASE + 0x142)
+#define MMC1_CLK            (SYSTEM_CONTROL_MODULE_BASE + 0x144)
+#define MMC1_CMD            (SYSTEM_CONTROL_MODULE_BASE + 0x146)
+#define MMC1_DAT0           (SYSTEM_CONTROL_MODULE_BASE + 0x148)
+#define MMC1_DAT1           (SYSTEM_CONTROL_MODULE_BASE + 0x14A)
+#define MMC1_DAT2           (SYSTEM_CONTROL_MODULE_BASE + 0x14C)
+#define MMC1_DAT3           (SYSTEM_CONTROL_MODULE_BASE + 0x14E)
+#define MMC1_DAT4           (SYSTEM_CONTROL_MODULE_BASE + 0x150)
+#define MMC1_DAT5           (SYSTEM_CONTROL_MODULE_BASE + 0x152)
+#define MMC1_DAT6           (SYSTEM_CONTROL_MODULE_BASE + 0x154)
+#define MMC1_DAT7           (SYSTEM_CONTROL_MODULE_BASE + 0x156)
+#define MMC2_CLK            (SYSTEM_CONTROL_MODULE_BASE + 0x158)
+#define MMC2_CMD            (SYSTEM_CONTROL_MODULE_BASE + 0x15A)
+#define MMC2_DAT0           (SYSTEM_CONTROL_MODULE_BASE + 0x15C)
+#define MMC2_DAT1           (SYSTEM_CONTROL_MODULE_BASE + 0x15E)
+#define MMC2_DAT2           (SYSTEM_CONTROL_MODULE_BASE + 0x160)
+#define MMC2_DAT3           (SYSTEM_CONTROL_MODULE_BASE + 0x162)
+#define MMC2_DAT4           (SYSTEM_CONTROL_MODULE_BASE + 0x164)
+#define MMC2_DAT5           (SYSTEM_CONTROL_MODULE_BASE + 0x166)
+#define MMC2_DAT6           (SYSTEM_CONTROL_MODULE_BASE + 0x168)
+#define MMC2_DAT7           (SYSTEM_CONTROL_MODULE_BASE + 0x16A)
+#define MCBSP3_DX           (SYSTEM_CONTROL_MODULE_BASE + 0x16C)
+#define MCBSP3_DR           (SYSTEM_CONTROL_MODULE_BASE + 0x16E)
+#define MCBSP3_CLKX         (SYSTEM_CONTROL_MODULE_BASE + 0x170)
+#define MCBSP3_FSX          (SYSTEM_CONTROL_MODULE_BASE + 0x172)
+#define UART2_CTS           (SYSTEM_CONTROL_MODULE_BASE + 0x174)
+#define UART2_RTS           (SYSTEM_CONTROL_MODULE_BASE + 0x176)
+#define UART2_TX            (SYSTEM_CONTROL_MODULE_BASE + 0x178)
+#define UART2_RX            (SYSTEM_CONTROL_MODULE_BASE + 0x17A)
+#define UART1_TX            (SYSTEM_CONTROL_MODULE_BASE + 0x17C)
+#define UART1_RTS           (SYSTEM_CONTROL_MODULE_BASE + 0x17E)
+#define UART1_CTS           (SYSTEM_CONTROL_MODULE_BASE + 0x180)
+#define UART1_RX            (SYSTEM_CONTROL_MODULE_BASE + 0x182)
+#define MCBSP4_CLKX         (SYSTEM_CONTROL_MODULE_BASE + 0x184)
+#define MCBSP4_DR           (SYSTEM_CONTROL_MODULE_BASE + 0x186)
+#define MCBSP4_DX           (SYSTEM_CONTROL_MODULE_BASE + 0x188)
+#define MCBSP4_FSX          (SYSTEM_CONTROL_MODULE_BASE + 0x18A)
+#define MCBSP1_CLKR         (SYSTEM_CONTROL_MODULE_BASE + 0x18C)
+#define MCBSP1_FSR          (SYSTEM_CONTROL_MODULE_BASE + 0x18E)
+#define MCBSP1_DX           (SYSTEM_CONTROL_MODULE_BASE + 0x190)
+#define MCBSP1_DR           (SYSTEM_CONTROL_MODULE_BASE + 0x192)
+#define MCBSP1_CLKS         (SYSTEM_CONTROL_MODULE_BASE + 0x194)
+#define MCBSP1_FSX          (SYSTEM_CONTROL_MODULE_BASE + 0x196)
+#define MCBSP1_CLKX         (SYSTEM_CONTROL_MODULE_BASE + 0x198)
+#define UART3_CTS_RCTX      (SYSTEM_CONTROL_MODULE_BASE + 0x19A)
+#define UART3_RTS_SD        (SYSTEM_CONTROL_MODULE_BASE + 0x19C)
+#define UART3_RX_IRRX       (SYSTEM_CONTROL_MODULE_BASE + 0x19E)
+#define UART3_TX_IRTX       (SYSTEM_CONTROL_MODULE_BASE + 0x1A0)
+#define HSUSB0_CLK          (SYSTEM_CONTROL_MODULE_BASE + 0x1A2)
+#define HSUSB0_STP          (SYSTEM_CONTROL_MODULE_BASE + 0x1A4)
+#define HSUSB0_DIR          (SYSTEM_CONTROL_MODULE_BASE + 0x1A6)
+#define HSUSB0_NXT          (SYSTEM_CONTROL_MODULE_BASE + 0x1A8)
+#define HSUSB0_DATA0        (SYSTEM_CONTROL_MODULE_BASE + 0x1AA)
+#define HSUSB0_DATA1        (SYSTEM_CONTROL_MODULE_BASE + 0x1AC)
+#define HSUSB0_DATA2        (SYSTEM_CONTROL_MODULE_BASE + 0x1AE)
+#define HSUSB0_DATA3        (SYSTEM_CONTROL_MODULE_BASE + 0x1B0)
+#define HSUSB0_DATA4        (SYSTEM_CONTROL_MODULE_BASE + 0x1B2)
+#define HSUSB0_DATA5        (SYSTEM_CONTROL_MODULE_BASE + 0x1B4)
+#define HSUSB0_DATA6        (SYSTEM_CONTROL_MODULE_BASE + 0x1B6)
+#define HSUSB0_DATA7        (SYSTEM_CONTROL_MODULE_BASE + 0x1B8)
+#define I2C1_SCL            (SYSTEM_CONTROL_MODULE_BASE + 0x1BA)
+#define I2C1_SDA            (SYSTEM_CONTROL_MODULE_BASE + 0x1BC)
+#define I2C2_SCL            (SYSTEM_CONTROL_MODULE_BASE + 0x1BE)
+#define I2C2_SDA            (SYSTEM_CONTROL_MODULE_BASE + 0x1C0)
+#define I2C3_SCL            (SYSTEM_CONTROL_MODULE_BASE + 0x1C2)
+#define I2C3_SDA            (SYSTEM_CONTROL_MODULE_BASE + 0x1C4)
+#define HDQ_SIO             (SYSTEM_CONTROL_MODULE_BASE + 0x1C6)
+#define MCSPI1_CLK          (SYSTEM_CONTROL_MODULE_BASE + 0x1C8)
+#define MCSPI1_SIMO         (SYSTEM_CONTROL_MODULE_BASE + 0x1CA)
+#define MCSPI1_SOMI         (SYSTEM_CONTROL_MODULE_BASE + 0x1CC)
+#define MCSPI1_CS0          (SYSTEM_CONTROL_MODULE_BASE + 0x1CE)
+#define MCSPI1_CS1          (SYSTEM_CONTROL_MODULE_BASE + 0x1D0)
+#define MCSPI1_CS2          (SYSTEM_CONTROL_MODULE_BASE + 0x1D2)
+#define MCSPI1_CS3          (SYSTEM_CONTROL_MODULE_BASE + 0x1D4)
+#define MCSPI2_CLK          (SYSTEM_CONTROL_MODULE_BASE + 0x1D6)
+#define MCSPI2_SIMO         (SYSTEM_CONTROL_MODULE_BASE + 0x1D8)
+#define MCSPI2_SOMI         (SYSTEM_CONTROL_MODULE_BASE + 0x1DA)
+#define MCSPI2_CS0          (SYSTEM_CONTROL_MODULE_BASE + 0x1DC)
+#define MCSPI2_CS1          (SYSTEM_CONTROL_MODULE_BASE + 0x1DE)
+#define SYS_NIRQ            (SYSTEM_CONTROL_MODULE_BASE + 0x1E0)
+#define SYS_CLKOUT2         (SYSTEM_CONTROL_MODULE_BASE + 0x1E2)
+#define ETK_CLK             (SYSTEM_CONTROL_MODULE_BASE + 0x5D8)
+#define ETK_CTL             (SYSTEM_CONTROL_MODULE_BASE + 0x5DA)
+#define ETK_D0              (SYSTEM_CONTROL_MODULE_BASE + 0x5DC)
+#define ETK_D1              (SYSTEM_CONTROL_MODULE_BASE + 0x5DE)
+#define ETK_D2              (SYSTEM_CONTROL_MODULE_BASE + 0x5E0)
+#define ETK_D3              (SYSTEM_CONTROL_MODULE_BASE + 0x5E2)
+#define ETK_D4              (SYSTEM_CONTROL_MODULE_BASE + 0x5E4)
+#define ETK_D5              (SYSTEM_CONTROL_MODULE_BASE + 0x5E6)
+#define ETK_D6              (SYSTEM_CONTROL_MODULE_BASE + 0x5E8)
+#define ETK_D7              (SYSTEM_CONTROL_MODULE_BASE + 0x5EA)
+#define ETK_D8              (SYSTEM_CONTROL_MODULE_BASE + 0x5EC)
+#define ETK_D9              (SYSTEM_CONTROL_MODULE_BASE + 0x5EE)
+#define ETK_D10             (SYSTEM_CONTROL_MODULE_BASE + 0x5F0)
+#define ETK_D11             (SYSTEM_CONTROL_MODULE_BASE + 0x5F2)
+#define ETK_D12             (SYSTEM_CONTROL_MODULE_BASE + 0x5F4)
+#define ETK_D13             (SYSTEM_CONTROL_MODULE_BASE + 0x5F6)
+#define ETK_D14             (SYSTEM_CONTROL_MODULE_BASE + 0x5F8)
+#define ETK_D15             (SYSTEM_CONTROL_MODULE_BASE + 0x5FA)
+#define SYS_BOOT0           (SYSTEM_CONTROL_MODULE_BASE + 0xA0A)
+#define SYS_BOOT1           (SYSTEM_CONTROL_MODULE_BASE + 0xA0C)
+#define SYS_BOOT3           (SYSTEM_CONTROL_MODULE_BASE + 0xA10)
+#define SYS_BOOT4           (SYSTEM_CONTROL_MODULE_BASE + 0xA12)
+#define SYS_BOOT5           (SYSTEM_CONTROL_MODULE_BASE + 0xA14)
+#define SYS_BOOT6           (SYSTEM_CONTROL_MODULE_BASE + 0xA16)
+
+//Mux modes
+#define MUXMODE0            (0x0UL)
+#define MUXMODE1            (0x1UL)
+#define MUXMODE2            (0x2UL)
+#define MUXMODE3            (0x3UL)
+#define MUXMODE4            (0x4UL)
+#define MUXMODE5            (0x5UL)
+#define MUXMODE6            (0x6UL)
+#define MUXMODE7            (0x7UL)
+
+//Pad configuration register.
+#define PAD_CONFIG_MASK      (0xFFFFUL)
+#define MUXMODE_OFFSET       0
+#define MUXMODE_MASK         (0x7UL << MUXMODE_OFFSET)
+#define PULL_CONFIG_OFFSET   3
+#define PULL_CONFIG_MASK     (0x3UL << PULL_CONFIG_OFFSET)
+#define INPUTENABLE_OFFSET   8
+#define INPUTENABLE_MASK     (0x1UL << INPUTENABLE_OFFSET)
+#define OFFMODE_VALUE_OFFSET 9
+#define OFFMODE_VALUE_MASK   (0x1FUL << OFFMODE_VALUE_OFFSET)
+#define WAKEUP_OFFSET        14
+#define WAKEUP_MASK          (0x2UL << WAKEUP_OFFSET)
+
+#define PULL_DOWN_SELECTED   ((0x0UL << 1) | BIT0)
+#define PULL_UP_SELECTED     (BIT1 | BIT0)
+#define PULL_DISABLED        (0x0UL << 0)
+
+#define OUTPUT               (0x0UL) //Pin is configured in output only mode.
+#define INPUT                (0x1UL) //Pin is configured in bi-directional mode.
+
+typedef struct {
+  UINTN   Pin;
+  UINTN   MuxMode;
+  UINTN   PullConfig;
+  UINTN   InputEnable;
+} PAD_CONFIGURATION;
+
+#endif //__OMAP3530_PAD_CONFIGURATION_H__
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Prcm.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Prcm.h
new file mode 100644
index 0000000000..80853e460e
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Prcm.h
@@ -0,0 +1,159 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530PRCM_H__
+#define __OMAP3530PRCM_H__
+
+#define CM_FCLKEN1_CORE   (0x48004A00)
+#define CM_FCLKEN3_CORE   (0x48004A08)
+#define CM_ICLKEN1_CORE   (0x48004A10)
+#define CM_ICLKEN3_CORE   (0x48004A18)
+#define CM_CLKEN2_PLL     (0x48004D04)
+#define CM_CLKSEL4_PLL    (0x48004D4C)
+#define CM_CLKSEL5_PLL    (0x48004D50)
+#define CM_FCLKEN_USBHOST  (0x48005400)
+#define CM_ICLKEN_USBHOST  (0x48005410)
+#define CM_CLKSTST_USBHOST (0x4800544c)
+
+//Wakeup clock defintion
+#define CM_FCLKEN_WKUP    (0x48004C00)
+#define CM_ICLKEN_WKUP    (0x48004C10)
+
+//Peripheral clock definition
+#define CM_FCLKEN_PER     (0x48005000)
+#define CM_ICLKEN_PER     (0x48005010)
+#define CM_CLKSEL_PER     (0x48005040)
+
+//Reset management definition
+#define PRM_RSTCTRL       (0x48307250)
+#define PRM_RSTST         (0x48307258)
+
+//CORE clock
+#define CM_FCLKEN1_CORE_EN_I2C1_MASK    BIT15
+#define CM_FCLKEN1_CORE_EN_I2C1_DISABLE (0UL << 15)
+#define CM_FCLKEN1_CORE_EN_I2C1_ENABLE  BIT15
+
+#define CM_ICLKEN1_CORE_EN_I2C1_MASK    BIT15
+#define CM_ICLKEN1_CORE_EN_I2C1_DISABLE (0UL << 15)
+#define CM_ICLKEN1_CORE_EN_I2C1_ENABLE  BIT15
+
+#define CM_FCLKEN1_CORE_EN_MMC1_MASK    BIT24
+#define CM_FCLKEN1_CORE_EN_MMC1_DISABLE (0UL << 24)
+#define CM_FCLKEN1_CORE_EN_MMC1_ENABLE  BIT24
+
+#define CM_FCLKEN3_CORE_EN_USBTLL_MASK    BIT2
+#define CM_FCLKEN3_CORE_EN_USBTLL_DISABLE (0UL << 2)
+#define CM_FCLKEN3_CORE_EN_USBTLL_ENABLE  BIT2
+
+#define CM_ICLKEN1_CORE_EN_MMC1_MASK    BIT24
+#define CM_ICLKEN1_CORE_EN_MMC1_DISABLE (0UL << 24)
+#define CM_ICLKEN1_CORE_EN_MMC1_ENABLE  BIT24
+
+#define CM_ICLKEN3_CORE_EN_USBTLL_MASK    BIT2
+#define CM_ICLKEN3_CORE_EN_USBTLL_DISABLE (0UL << 2)
+#define CM_ICLKEN3_CORE_EN_USBTLL_ENABLE  BIT2
+
+#define CM_CLKEN_FREQSEL_075_100        (0x03UL << 4)
+#define CM_CLKEN_ENABLE                 (7UL << 0)
+
+#define CM_CLKSEL_PLL_MULT(x)           (((x) & 0x07FF) << 8)
+#define CM_CLKSEL_PLL_DIV(x)            ((((x) - 1) & 0x7F) << 0)
+
+#define CM_CLKSEL_DIV_120M(x)           (((x) & 0x1F) << 0)
+
+#define CM_FCLKEN_USBHOST_EN_USBHOST2_MASK    BIT1
+#define CM_FCLKEN_USBHOST_EN_USBHOST2_DISABLE (0UL << 1)
+#define CM_FCLKEN_USBHOST_EN_USBHOST2_ENABLE  BIT1
+
+#define CM_FCLKEN_USBHOST_EN_USBHOST1_MASK    BIT0
+#define CM_FCLKEN_USBHOST_EN_USBHOST1_DISABLE (0UL << 0)
+#define CM_FCLKEN_USBHOST_EN_USBHOST1_ENABLE  BIT0
+
+#define CM_ICLKEN_USBHOST_EN_USBHOST_MASK     BIT0
+#define CM_ICLKEN_USBHOST_EN_USBHOST_DISABLE  (0UL << 0)
+#define CM_ICLKEN_USBHOST_EN_USBHOST_ENABLE   BIT0
+
+//Wakeup functional clock
+#define CM_FCLKEN_WKUP_EN_GPIO1_DISABLE       (0UL << 3)
+#define CM_FCLKEN_WKUP_EN_GPIO1_ENABLE        BIT3
+
+#define CM_FCLKEN_WKUP_EN_WDT2_DISABLE        (0UL << 5)
+#define CM_FCLKEN_WKUP_EN_WDT2_ENABLE         BIT5
+
+//Wakeup interface clock
+#define CM_ICLKEN_WKUP_EN_GPIO1_DISABLE       (0UL << 3)
+#define CM_ICLKEN_WKUP_EN_GPIO1_ENABLE        BIT3
+
+#define CM_ICLKEN_WKUP_EN_WDT2_DISABLE        (0UL << 5)
+#define CM_ICLKEN_WKUP_EN_WDT2_ENABLE         BIT5
+
+//Peripheral functional clock
+#define CM_FCLKEN_PER_EN_GPT3_DISABLE         (0UL << 4)
+#define CM_FCLKEN_PER_EN_GPT3_ENABLE          BIT4
+
+#define CM_FCLKEN_PER_EN_GPT4_DISABLE         (0UL << 5)
+#define CM_FCLKEN_PER_EN_GPT4_ENABLE          BIT5
+
+#define CM_FCLKEN_PER_EN_UART3_DISABLE        (0UL << 11)
+#define CM_FCLKEN_PER_EN_UART3_ENABLE         BIT11
+
+#define CM_FCLKEN_PER_EN_GPIO2_DISABLE        (0UL << 13)
+#define CM_FCLKEN_PER_EN_GPIO2_ENABLE         BIT13
+
+#define CM_FCLKEN_PER_EN_GPIO3_DISABLE        (0UL << 14)
+#define CM_FCLKEN_PER_EN_GPIO3_ENABLE         BIT14
+
+#define CM_FCLKEN_PER_EN_GPIO4_DISABLE        (0UL << 15)
+#define CM_FCLKEN_PER_EN_GPIO4_ENABLE         BIT15
+
+#define CM_FCLKEN_PER_EN_GPIO5_DISABLE        (0UL << 16)
+#define CM_FCLKEN_PER_EN_GPIO5_ENABLE         BIT16
+
+#define CM_FCLKEN_PER_EN_GPIO6_DISABLE        (0UL << 17)
+#define CM_FCLKEN_PER_EN_GPIO6_ENABLE         BIT17
+
+//Peripheral interface clock
+#define CM_ICLKEN_PER_EN_GPT3_DISABLE         (0UL << 4)
+#define CM_ICLKEN_PER_EN_GPT3_ENABLE          BIT4
+
+#define CM_ICLKEN_PER_EN_GPT4_DISABLE         (0UL << 5)
+#define CM_ICLKEN_PER_EN_GPT4_ENABLE          BIT5
+
+#define CM_ICLKEN_PER_EN_UART3_DISABLE        (0UL << 11)
+#define CM_ICLKEN_PER_EN_UART3_ENABLE         BIT11
+
+#define CM_ICLKEN_PER_EN_GPIO2_DISABLE        (0UL << 13)
+#define CM_ICLKEN_PER_EN_GPIO2_ENABLE         BIT13
+
+#define CM_ICLKEN_PER_EN_GPIO3_DISABLE        (0UL << 14)
+#define CM_ICLKEN_PER_EN_GPIO3_ENABLE         BIT14
+
+#define CM_ICLKEN_PER_EN_GPIO4_DISABLE        (0UL << 15)
+#define CM_ICLKEN_PER_EN_GPIO4_ENABLE         BIT15
+
+#define CM_ICLKEN_PER_EN_GPIO5_DISABLE        (0UL << 16)
+#define CM_ICLKEN_PER_EN_GPIO5_ENABLE         BIT16
+
+#define CM_ICLKEN_PER_EN_GPIO6_DISABLE        (0UL << 17)
+#define CM_ICLKEN_PER_EN_GPIO6_ENABLE         BIT17
+
+//Timer source clock selection
+#define CM_CLKSEL_PER_CLKSEL_GPT3_32K         (0UL << 1)
+#define CM_CLKSEL_PER_CLKSEL_GPT3_SYS         BIT1
+
+#define CM_CLKSEL_PER_CLKSEL_GPT4_32K         (0UL << 2)
+#define CM_CLKSEL_PER_CLKSEL_GPT4_SYS         BIT2
+
+//Reset management (Global and Cold reset)
+#define RST_GS            BIT1
+#define RST_DPLL3         BIT2
+#define GLOBAL_SW_RST     BIT1
+#define GLOBAL_COLD_RST   (0x0UL << 0)
+
+#endif // __OMAP3530PRCM_H__
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Timer.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Timer.h
new file mode 100644
index 0000000000..26ddcd536d
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Timer.h
@@ -0,0 +1,76 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530TIMER_H__
+#define __OMAP3530TIMER_H__
+
+#define GPTIMER1_BASE   (0x48313000)
+#define GPTIMER2_BASE   (0x49032000)
+#define GPTIMER3_BASE   (0x49034000)
+#define GPTIMER4_BASE   (0x49036000)
+#define GPTIMER5_BASE   (0x49038000)
+#define GPTIMER6_BASE   (0x4903A000)
+#define GPTIMER7_BASE   (0x4903C000)
+#define GPTIMER8_BASE   (0x4903E000)
+#define GPTIMER9_BASE   (0x49040000)
+#define GPTIMER10_BASE  (0x48086000)
+#define GPTIMER11_BASE  (0x48088000)
+#define GPTIMER12_BASE  (0x48304000)
+#define WDTIMER2_BASE   (0x48314000)
+
+#define GPTIMER_TIOCP_CFG (0x0010)
+#define GPTIMER_TISTAT    (0x0014)
+#define GPTIMER_TISR      (0x0018)
+#define GPTIMER_TIER      (0x001C)
+#define GPTIMER_TWER      (0x0020)
+#define GPTIMER_TCLR      (0x0024)
+#define GPTIMER_TCRR      (0x0028)
+#define GPTIMER_TLDR      (0x002C)
+#define GPTIMER_TTGR      (0x0030)
+#define GPTIMER_TWPS      (0x0034)
+#define GPTIMER_TMAR      (0x0038)
+#define GPTIMER_TCAR1     (0x003C)
+#define GPTIMER_TSICR     (0x0040)
+#define GPTIMER_TCAR2     (0x0044)
+#define GPTIMER_TPIR      (0x0048)
+#define GPTIMER_TNIR      (0x004C)
+#define GPTIMER_TCVR      (0x0050)
+#define GPTIMER_TOCR      (0x0054)
+#define GPTIMER_TOWR      (0x0058)
+
+#define WSPR              (0x048)
+
+#define TISR_TCAR_IT_FLAG_MASK  BIT2
+#define TISR_OVF_IT_FLAG_MASK   BIT1
+#define TISR_MAT_IT_FLAG_MASK   BIT0
+#define TISR_ALL_INTERRUPT_MASK (TISR_TCAR_IT_FLAG_MASK | TISR_OVF_IT_FLAG_MASK | TISR_MAT_IT_FLAG_MASK)
+
+#define TISR_TCAR_IT_FLAG_NOT_PENDING   (0UL << 2)
+#define TISR_OVF_IT_FLAG_NOT_PENDING    (0UL << 1)
+#define TISR_MAT_IT_FLAG_NOT_PENDING    (0UL << 0)
+#define TISR_NO_INTERRUPTS_PENDING      (TISR_TCAR_IT_FLAG_NOT_PENDING | TISR_OVF_IT_FLAG_NOT_PENDING | TISR_MAT_IT_FLAG_NOT_PENDING)
+
+#define TISR_TCAR_IT_FLAG_CLEAR BIT2
+#define TISR_OVF_IT_FLAG_CLEAR  BIT1
+#define TISR_MAT_IT_FLAG_CLEAR  BIT0
+#define TISR_CLEAR_ALL          (TISR_TCAR_IT_FLAG_CLEAR | TISR_OVF_IT_FLAG_CLEAR | TISR_MAT_IT_FLAG_CLEAR)
+
+#define TCLR_AR_AUTORELOAD      BIT1
+#define TCLR_AR_ONESHOT         (0UL << 1)
+#define TCLR_ST_ON              BIT0
+#define TCLR_ST_OFF             (0UL << 0)
+
+#define TIER_TCAR_IT_ENABLE     (BIT2
+#define TIER_TCAR_IT_DISABLE    (0UL << 2)
+#define TIER_OVF_IT_ENABLE      BIT1
+#define TIER_OVF_IT_DISABLE     (0UL << 1)
+#define TIER_MAT_IT_ENABLE      BIT0
+#define TIER_MAT_IT_DISABLE     (0UL << 0)
+
+#endif // __OMAP3530TIMER_H__
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Uart.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Uart.h
new file mode 100644
index 0000000000..54be17b1d7
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Uart.h
@@ -0,0 +1,48 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530UART_H__
+#define __OMAP3530UART_H__
+
+#define UART1_BASE  (0x4806A000)
+#define UART2_BASE  (0x4806C000)
+#define UART3_BASE  (0x49020000)
+
+#define UART_DLL_REG  (0x0000)
+#define UART_RBR_REG  (0x0000)
+#define UART_THR_REG  (0x0000)
+#define UART_DLH_REG  (0x0004)
+#define UART_FCR_REG  (0x0008)
+#define UART_LCR_REG  (0x000C)
+#define UART_MCR_REG  (0x0010)
+#define UART_LSR_REG  (0x0014)
+#define UART_MDR1_REG (0x0020)
+
+#define UART_FCR_TX_FIFO_CLEAR          BIT2
+#define UART_FCR_RX_FIFO_CLEAR          BIT1
+#define UART_FCR_FIFO_ENABLE            BIT0
+
+#define UART_LCR_DIV_EN_ENABLE          BIT7
+#define UART_LCR_DIV_EN_DISABLE         (0UL << 7)
+#define UART_LCR_CHAR_LENGTH_8          (BIT1 | BIT0)
+
+#define UART_MCR_RTS_FORCE_ACTIVE       BIT1
+#define UART_MCR_DTR_FORCE_ACTIVE       BIT0
+
+#define UART_LSR_TX_FIFO_E_MASK         BIT5
+#define UART_LSR_TX_FIFO_E_NOT_EMPTY    (0UL << 5)
+#define UART_LSR_TX_FIFO_E_EMPTY        BIT5
+#define UART_LSR_RX_FIFO_E_MASK         BIT0
+#define UART_LSR_RX_FIFO_E_NOT_EMPTY    BIT0
+#define UART_LSR_RX_FIFO_E_EMPTY        (0UL << 0)
+
+// BIT2:BIT0
+#define UART_MDR1_MODE_SELECT_DISABLE   (7UL)
+#define UART_MDR1_MODE_SELECT_UART_16X  (0UL)
+
+#endif // __OMAP3530UART_H__
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Usb.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Usb.h
new file mode 100644
index 0000000000..a438117232
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/Omap3530/Omap3530Usb.h
@@ -0,0 +1,42 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3530USB_H__
+#define __OMAP3530USB_H__
+
+#define USB_BASE            (0x48060000)
+
+#define UHH_SYSCONFIG       (USB_BASE + 0x4010)
+#define UHH_HOSTCONFIG      (USB_BASE + 0x4040)
+#define UHH_SYSSTATUS       (USB_BASE + 0x4014)
+
+#define USB_EHCI_HCCAPBASE  (USB_BASE + 0x4800)
+
+#define UHH_SYSCONFIG_MIDLEMODE_NO_STANDBY  BIT12
+#define UHH_SYSCONFIG_CLOCKACTIVITY_ON      BIT8
+#define UHH_SYSCONFIG_SIDLEMODE_NO_STANDBY  BIT3
+#define UHH_SYSCONFIG_ENAWAKEUP_ENABLE      BIT2
+#define UHH_SYSCONFIG_SOFTRESET             BIT1
+#define UHH_SYSCONFIG_AUTOIDLE_ALWAYS_RUN   (0UL <<  0)
+
+#define UHH_HOSTCONFIG_P3_CONNECT_STATUS_DISCONNECT (0UL << 10)
+#define UHH_HOSTCONFIG_P2_CONNECT_STATUS_DISCONNECT (0UL <<  9)
+#define UHH_HOSTCONFIG_P1_CONNECT_STATUS_DISCONNECT (0UL <<  8)
+#define UHH_HOSTCONFIG_ENA_INCR_ALIGN_DISABLE       (0UL <<  5)
+#define UHH_HOSTCONFIG_ENA_INCR16_ENABLE            BIT4
+#define UHH_HOSTCONFIG_ENA_INCR8_ENABLE             BIT3
+#define UHH_HOSTCONFIG_ENA_INCR4_ENABLE             BIT2
+#define UHH_HOSTCONFIG_AUTOPPD_ON_OVERCUR_EN_ON     (0UL <<  1)
+#define UHH_HOSTCONFIG_P1_ULPI_BYPASS_ULPI_MODE     (0UL <<  0)
+
+#define UHH_SYSSTATUS_RESETDONE                (BIT0 | BIT1 | BIT2)
+
+#endif // __OMAP3530USB_H__
+
+
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Include/TPS65950.h b/Silicon/TexasInsturments/Omap35xxPkg/Include/TPS65950.h
new file mode 100644
index 0000000000..d0f2950b06
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Include/TPS65950.h
@@ -0,0 +1,74 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __TPS65950_H__
+#define __TPS65950_H__
+
+#define EXTERNAL_DEVICE_REGISTER_TO_SLAVE_ADDRESS(x)     (((x) >> 8) & 0xFF)
+#define EXTERNAL_DEVICE_REGISTER_TO_REGISTER(x)          ((x) & 0xFF)
+#define EXTERNAL_DEVICE_REGISTER(SlaveAddress, Register) (((SlaveAddress) & 0xFF) << 8 | ((Register) & 0xFF))
+
+// I2C Address group
+#define I2C_ADDR_GRP_ID1      0x48
+#define I2C_ADDR_GRP_ID2      0x49
+#define I2C_ADDR_GRP_ID3      0x4A
+#define I2C_ADDR_GRP_ID4      0x4B
+#define I2C_ADDR_GRP_ID5      0x12
+
+// MMC definitions.
+#define VMMC1_DEV_GRP         0x82
+#define DEV_GRP_P1            BIT5
+
+#define VMMC1_DEDICATED_REG   0x85
+#define VSEL_1_85V            0x0
+#define VSEL_2_85V            0x1
+#define VSEL_3_00V            0x2
+#define VSEL_3_15V            0x3
+
+#define TPS65950_GPIO_CTRL    0xaa  //I2C_ADDR_GRP_ID2
+#define CARD_DETECT_ENABLE    (BIT2 | BIT0) // GPIO ON + GPIO CD1 enabled
+
+
+#define GPIODATAIN1           0x98  //I2C_ADDR_GRP_ID2
+#define CARD_DETECT_BIT       BIT0
+
+// LEDEN register
+#define LEDEN                 0xEE
+#define LEDAON                BIT0
+#define LEDBON                BIT1
+#define LEDAPWM               BIT4
+#define LEDBPWM               BIT5
+
+// RTC registers
+#define SECONDS_REG           0x1C
+#define MINUTES_REG           0x1D
+#define HOURS_REG             0x1E
+#define DAYS_REG              0x1F
+#define MONTHS_REG            0x20
+#define YEARS_REG             0x21
+#define WEEKS_REG             0x22
+#define RTC_CTRL_REG          0x29
+
+// USB PHY power
+#define VAUX2_DEDICATED       0x79
+#define VAUX2_DEV_GRP         0x76
+
+#define VAUX_DEV_GRP_NONE     0x00
+#define VAUX_DEV_GRP_P1       0x20
+#define VAUX_DEV_GRP_P2       0x40
+#define VAUX_DEV_GRP_P3       0x80
+#define VAUX_DEDICATED_18V    0x05
+
+// Display subsystem
+#define VPLL2_DEDICATED       0x91
+#define VPLL2_DEV_GRP         0x8E
+
+#define GPIODATADIR1          0x9B
+#define SETGPIODATAOUT1       0xA4
+
+#endif //__TPS65950_H__
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/HardwareInterrupt.c b/Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/HardwareInterrupt.c
new file mode 100644
index 0000000000..d15e68edfc
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/HardwareInterrupt.c
@@ -0,0 +1,396 @@
+/** @file
+  Handle OMAP35xx interrupt controller
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/ArmLib.h>
+
+#include <Protocol/Cpu.h>
+#include <Protocol/HardwareInterrupt.h>
+
+#include <Omap3530/Omap3530.h>
+
+//
+// Notifications
+//
+EFI_EVENT EfiExitBootServicesEvent      = (EFI_EVENT)NULL;
+
+
+HARDWARE_INTERRUPT_HANDLER  gRegisteredInterruptHandlers[INT_NROF_VECTORS];
+
+/**
+  Shutdown our hardware
+
+  DXE Core will disable interrupts and turn off the timer and disable interrupts
+  after all the event handlers have run.
+
+  @param[in]  Event   The Event that is being processed
+  @param[in]  Context Event Context
+**/
+VOID
+EFIAPI
+ExitBootServicesEvent (
+  IN EFI_EVENT  Event,
+  IN VOID       *Context
+  )
+{
+  // Disable all interrupts
+  MmioWrite32 (INTCPS_MIR(0), 0xFFFFFFFF);
+  MmioWrite32 (INTCPS_MIR(1), 0xFFFFFFFF);
+  MmioWrite32 (INTCPS_MIR(2), 0xFFFFFFFF);
+  MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
+
+  // Add code here to disable all FIQs as debugger may have turned one on
+}
+
+/**
+  Register Handler for the specified interrupt source.
+
+  @param This     Instance pointer for this protocol
+  @param Source   Hardware source of the interrupt
+  @param Handler  Callback for interrupt. NULL to unregister
+
+  @retval EFI_SUCCESS Source was updated to support Handler.
+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+RegisterInterruptSource (
+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
+  IN HARDWARE_INTERRUPT_SOURCE          Source,
+  IN HARDWARE_INTERRUPT_HANDLER         Handler
+  )
+{
+  if (Source > MAX_VECTOR) {
+    ASSERT(FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  if ((MmioRead32 (INTCPS_ILR(Source)) & INTCPS_ILR_FIQ) == INTCPS_ILR_FIQ) {
+    // This vector has been programmed as FIQ so we can't use it for IRQ
+    // EFI does not use FIQ, but the debugger can use it to check for
+    // ctrl-c. So this ASSERT means you have a conflict with the debug agent
+    ASSERT (FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  if ((Handler == NULL) && (gRegisteredInterruptHandlers[Source] == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((Handler != NULL) && (gRegisteredInterruptHandlers[Source] != NULL)) {
+    return EFI_ALREADY_STARTED;
+  }
+
+  gRegisteredInterruptHandlers[Source] = Handler;
+  return This->EnableInterruptSource(This, Source);
+}
+
+
+/**
+  Enable interrupt source Source.
+
+  @param This     Instance pointer for this protocol
+  @param Source   Hardware source of the interrupt
+
+  @retval EFI_SUCCESS       Source interrupt enabled.
+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+EnableInterruptSource (
+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
+  IN HARDWARE_INTERRUPT_SOURCE          Source
+  )
+{
+  UINTN Bank;
+  UINTN Bit;
+
+  if (Source > MAX_VECTOR) {
+    ASSERT(FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  Bank = Source / 32;
+  Bit  = 1UL << (Source % 32);
+
+  MmioWrite32 (INTCPS_MIR_CLEAR(Bank), Bit);
+
+  return EFI_SUCCESS;
+}
+
+
+/**
+  Disable interrupt source Source.
+
+  @param This     Instance pointer for this protocol
+  @param Source   Hardware source of the interrupt
+
+  @retval EFI_SUCCESS       Source interrupt disabled.
+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+DisableInterruptSource (
+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
+  IN HARDWARE_INTERRUPT_SOURCE          Source
+  )
+{
+  UINTN Bank;
+  UINTN Bit;
+
+  if (Source > MAX_VECTOR) {
+    ASSERT(FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  Bank = Source / 32;
+  Bit  = 1UL << (Source % 32);
+
+  MmioWrite32 (INTCPS_MIR_SET(Bank), Bit);
+
+  return EFI_SUCCESS;
+}
+
+
+
+/**
+  Return current state of interrupt source Source.
+
+  @param This     Instance pointer for this protocol
+  @param Source   Hardware source of the interrupt
+  @param InterruptState  TRUE: source enabled, FALSE: source disabled.
+
+  @retval EFI_SUCCESS       InterruptState is valid
+  @retval EFI_DEVICE_ERROR  InterruptState is not valid
+
+**/
+EFI_STATUS
+EFIAPI
+GetInterruptSourceState (
+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
+  IN HARDWARE_INTERRUPT_SOURCE          Source,
+  IN BOOLEAN                            *InterruptState
+  )
+{
+  UINTN Bank;
+  UINTN Bit;
+
+  if (InterruptState == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Source > MAX_VECTOR) {
+    ASSERT(FALSE);
+    return EFI_UNSUPPORTED;
+  }
+
+  Bank = Source / 32;
+  Bit  = 1UL << (Source % 32);
+
+  if ((MmioRead32(INTCPS_MIR(Bank)) & Bit) == Bit) {
+    *InterruptState = FALSE;
+  } else {
+    *InterruptState = TRUE;
+  }
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Signal to the hardware that the End Of Intrrupt state
+  has been reached.
+
+  @param This     Instance pointer for this protocol
+  @param Source   Hardware source of the interrupt
+
+  @retval EFI_SUCCESS       Source interrupt EOI'ed.
+  @retval EFI_DEVICE_ERROR  Hardware could not be programmed.
+
+**/
+EFI_STATUS
+EFIAPI
+EndOfInterrupt (
+  IN EFI_HARDWARE_INTERRUPT_PROTOCOL    *This,
+  IN HARDWARE_INTERRUPT_SOURCE          Source
+  )
+{
+  MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
+  ArmDataSynchronizationBarrier ();
+  return EFI_SUCCESS;
+}
+
+
+/**
+  EFI_CPU_INTERRUPT_HANDLER that is called when a processor interrupt occurs.
+
+  @param  InterruptType    Defines the type of interrupt or exception that
+                           occurred on the processor.This parameter is processor architecture specific.
+  @param  SystemContext    A pointer to the processor context when
+                           the interrupt occurred on the processor.
+
+  @return None
+
+**/
+VOID
+EFIAPI
+IrqInterruptHandler (
+  IN EFI_EXCEPTION_TYPE           InterruptType,
+  IN EFI_SYSTEM_CONTEXT           SystemContext
+  )
+{
+  UINT32                     Vector;
+  HARDWARE_INTERRUPT_HANDLER InterruptHandler;
+
+  Vector = MmioRead32 (INTCPS_SIR_IRQ) & INTCPS_SIR_IRQ_MASK;
+
+  // Needed to prevent infinite nesting when Time Driver lowers TPL
+  MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
+  ArmDataSynchronizationBarrier ();
+
+  InterruptHandler = gRegisteredInterruptHandlers[Vector];
+  if (InterruptHandler != NULL) {
+    // Call the registered interrupt handler.
+    InterruptHandler (Vector, SystemContext);
+  }
+
+  // Needed to clear after running the handler
+  MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
+  ArmDataSynchronizationBarrier ();
+}
+
+//
+// Making this global saves a few bytes in image size
+//
+EFI_HANDLE  gHardwareInterruptHandle = NULL;
+
+//
+// The protocol instance produced by this driver
+//
+EFI_HARDWARE_INTERRUPT_PROTOCOL gHardwareInterruptProtocol = {
+  RegisterInterruptSource,
+  EnableInterruptSource,
+  DisableInterruptSource,
+  GetInterruptSourceState,
+  EndOfInterrupt
+};
+
+STATIC VOID *mCpuArchProtocolNotifyEventRegistration;
+
+STATIC
+VOID
+EFIAPI
+CpuArchEventProtocolNotify (
+  IN  EFI_EVENT       Event,
+  IN  VOID            *Context
+  )
+{
+  EFI_CPU_ARCH_PROTOCOL   *Cpu;
+  EFI_STATUS              Status;
+
+  //
+  // Get the CPU protocol that this driver requires.
+  //
+  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: gBS->LocateProtocol() - %r\n", __FUNCTION__,
+      Status));
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Unregister the default exception handler.
+  //
+  Status = Cpu->RegisterInterruptHandler (Cpu, EXCEPT_ARM_IRQ, NULL);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Cpu->RegisterInterruptHandler() - %r\n",
+      __FUNCTION__, Status));
+    ASSERT (FALSE);
+    return;
+  }
+
+  //
+  // Register to receive interrupts
+  //
+  Status = Cpu->RegisterInterruptHandler (Cpu, EXCEPT_ARM_IRQ,
+                  IrqInterruptHandler);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((DEBUG_ERROR, "%a: Cpu->RegisterInterruptHandler() - %r\n",
+      __FUNCTION__, Status));
+    ASSERT (FALSE);
+    return;
+  }
+}
+
+/**
+  Initialize the state information for the CPU Architectural Protocol
+
+  @param  ImageHandle   of the loaded driver
+  @param  SystemTable   Pointer to the System Table
+
+  @retval EFI_SUCCESS           Protocol registered
+  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure
+  @retval EFI_DEVICE_ERROR      Hardware problems
+
+**/
+EFI_STATUS
+InterruptDxeInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+  EFI_EVENT   CpuArchEvent;
+
+  // Make sure the Interrupt Controller Protocol is not already installed in the system.
+  ASSERT_PROTOCOL_ALREADY_INSTALLED (NULL, &gHardwareInterruptProtocolGuid);
+
+  // Make sure all interrupts are disabled by default.
+  MmioWrite32 (INTCPS_MIR(0), 0xFFFFFFFF);
+  MmioWrite32 (INTCPS_MIR(1), 0xFFFFFFFF);
+  MmioWrite32 (INTCPS_MIR(2), 0xFFFFFFFF);
+  MmioOr32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWIRQAGR);
+
+  Status = gBS->InstallMultipleProtocolInterfaces(&gHardwareInterruptHandle,
+                                                  &gHardwareInterruptProtocolGuid,   &gHardwareInterruptProtocol,
+                                                  NULL);
+  ASSERT_EFI_ERROR(Status);
+
+  //
+  // Install the interrupt handler as soon as the CPU arch protocol appears.
+  //
+  CpuArchEvent = EfiCreateProtocolNotifyEvent (
+                   &gEfiCpuArchProtocolGuid,
+                   TPL_CALLBACK,
+                   CpuArchEventProtocolNotify,
+                   NULL,
+                   &mCpuArchProtocolNotifyEventRegistration
+                   );
+  ASSERT (CpuArchEvent != NULL);
+
+  // Register for an ExitBootServicesEvent
+  Status = gBS->CreateEvent(EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_NOTIFY, ExitBootServicesEvent, NULL, &EfiExitBootServicesEvent);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    gBS->CloseEvent (CpuArchEvent);
+  }
+
+  return Status;
+}
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/InterruptDxe.inf b/Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/InterruptDxe.inf
new file mode 100644
index 0000000000..2a956c2767
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/InterruptDxe/InterruptDxe.inf
@@ -0,0 +1,48 @@
+#/** @file
+#
+#  Interrupt DXE driver
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = Omap35xxBoardInterruptDxe
+  FILE_GUID                      = 23eed05d-1b93-4a1a-8e1b-931d69e37952
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = InterruptDxeInitialize
+
+
+[Sources.common]
+  HardwareInterrupt.c
+
+
+[Packages]
+  ArmPkg/ArmPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  UefiLib
+  UefiBootServicesTableLib
+  DebugLib
+  PrintLib
+  UefiDriverEntryPoint
+  IoLib
+  ArmLib
+
+[Protocols]
+  gHardwareInterruptProtocolGuid  ## PRODUCES
+  gEfiCpuArchProtocolGuid         ## CONSUMES ## NOTIFY
+
+[FixedPcd.common]
+  gEmbeddedTokenSpaceGuid.PcdInterruptBaseAddress
+
+[Depex]
+  TRUE
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c b/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c
new file mode 100644
index 0000000000..f8af498056
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputBlt.c
@@ -0,0 +1,439 @@
+/** @file
+
+ Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ **/
+
+#include <PiDxe.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Guid/GlobalVariable.h>
+
+#include "LcdGraphicsOutputDxe.h"
+
+extern BOOLEAN mDisplayInitialized;
+
+//
+// Function Definitions
+//
+
+STATIC
+EFI_STATUS
+VideoCopyNoHorizontalOverlap (
+  IN UINTN          BitsPerPixel,
+  IN volatile VOID  *FrameBufferBase,
+  IN UINT32         HorizontalResolution,
+  IN UINTN          SourceX,
+  IN UINTN          SourceY,
+  IN UINTN          DestinationX,
+  IN UINTN          DestinationY,
+  IN UINTN          Width,
+  IN UINTN          Height
+  )
+{
+  EFI_STATUS    Status = EFI_SUCCESS;
+  UINTN         SourceLine;
+  UINTN         DestinationLine;
+  UINTN         WidthInBytes;
+  UINTN         LineCount;
+  INTN          Step;
+  VOID          *SourceAddr;
+  VOID          *DestinationAddr;
+
+  if( DestinationY <= SourceY ) {
+    // scrolling up (or horizontally but without overlap)
+    SourceLine       = SourceY;
+    DestinationLine  = DestinationY;
+    Step             = 1;
+  } else {
+    // scrolling down
+    SourceLine       = SourceY + Height;
+    DestinationLine  = DestinationY + Height;
+    Step             = -1;
+  }
+
+  WidthInBytes = Width * 2;
+
+  for( LineCount = 0; LineCount < Height; LineCount++ ) {
+    // Update the start addresses of source & destination using 16bit pointer arithmetic
+    SourceAddr      = (VOID *)((UINT16 *)FrameBufferBase + SourceLine      * HorizontalResolution + SourceX     );
+    DestinationAddr = (VOID *)((UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationX);
+
+    // Copy the entire line Y from video ram to the temp buffer
+    CopyMem( DestinationAddr, SourceAddr, WidthInBytes);
+
+    // Update the line numbers
+    SourceLine      += Step;
+    DestinationLine += Step;
+  }
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+VideoCopyHorizontalOverlap (
+  IN UINTN          BitsPerPixel,
+  IN volatile VOID  *FrameBufferBase,
+  UINT32            HorizontalResolution,
+  IN UINTN          SourceX,
+  IN UINTN          SourceY,
+  IN UINTN          DestinationX,
+  IN UINTN          DestinationY,
+  IN UINTN          Width,
+  IN UINTN          Height
+  )
+{
+  EFI_STATUS      Status = EFI_SUCCESS;
+
+  UINT16 *PixelBuffer16bit;
+  UINT16 *SourcePixel16bit;
+  UINT16 *DestinationPixel16bit;
+
+  UINT32          SourcePixelY;
+  UINT32          DestinationPixelY;
+  UINTN           SizeIn16Bits;
+
+  // Allocate a temporary buffer
+  PixelBuffer16bit = (UINT16 *) AllocatePool((Height * Width) * sizeof(UINT16));
+
+  if (PixelBuffer16bit == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto EXIT;
+  }
+
+  // Access each pixel inside the source area of the Video Memory and copy it to the temp buffer
+
+  SizeIn16Bits = Width * 2;
+
+  for (SourcePixelY = SourceY, DestinationPixel16bit = PixelBuffer16bit;
+       SourcePixelY < SourceY + Height;
+       SourcePixelY++, DestinationPixel16bit += Width)
+  {
+    // Calculate the source address:
+    SourcePixel16bit = (UINT16 *)FrameBufferBase + SourcePixelY * HorizontalResolution + SourceX;
+
+    // Copy the entire line Y from Video to the temp buffer
+    CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits);
+  }
+
+  // Copy from the temp buffer into the destination area of the Video Memory
+
+  for (DestinationPixelY = DestinationY, SourcePixel16bit = PixelBuffer16bit;
+       DestinationPixelY < DestinationY + Height;
+       DestinationPixelY++, SourcePixel16bit += Width)
+  {
+    // Calculate the target address:
+    DestinationPixel16bit = (UINT16 *)FrameBufferBase + (DestinationPixelY * HorizontalResolution + DestinationX);
+
+    // Copy the entire line Y from the temp buffer to Video
+    CopyMem( (VOID *)DestinationPixel16bit, (CONST VOID *)SourcePixel16bit, SizeIn16Bits);
+  }
+
+  // Free the allocated memory
+  FreePool((VOID *) PixelBuffer16bit);
+
+
+EXIT:
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+BltVideoFill (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *EfiSourcePixel,     OPTIONAL
+  IN UINTN                               SourceX,
+  IN UINTN                               SourceY,
+  IN UINTN                               DestinationX,
+  IN UINTN                               DestinationY,
+  IN UINTN                               Width,
+  IN UINTN                               Height,
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
+  )
+{
+  EFI_PIXEL_BITMASK*  PixelInformation;
+  EFI_STATUS          Status;
+  UINT32              HorizontalResolution;
+  VOID                *FrameBufferBase;
+  UINT16              *DestinationPixel16bit;
+  UINT16              Pixel16bit;
+  UINT32              DestinationPixelX;
+  UINT32              DestinationLine;
+
+  Status           = EFI_SUCCESS;
+  PixelInformation = &This->Mode->Info->PixelInformation;
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;
+
+  // Convert the EFI pixel at the start of the BltBuffer(0,0) into a video display pixel
+  Pixel16bit = (UINT16) (
+      ( (EfiSourcePixel->Red      <<  8) & PixelInformation->RedMask      )
+    | ( (EfiSourcePixel->Green    <<  3) & PixelInformation->GreenMask    )
+    | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )
+   );
+
+  // Copy the SourcePixel into every pixel inside the target rectangle
+  for (DestinationLine = DestinationY;
+       DestinationLine < DestinationY + Height;
+       DestinationLine++)
+  {
+    for (DestinationPixelX = DestinationX;
+         DestinationPixelX < DestinationX + Width;
+         DestinationPixelX++)
+    {
+      // Calculate the target address:
+      DestinationPixel16bit =  (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution  + DestinationPixelX;
+
+      // Copy the pixel into the new target
+      *DestinationPixel16bit = Pixel16bit;
+    }
+  }
+
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+BltVideoToBltBuffer (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL
+  IN UINTN                               SourceX,
+  IN UINTN                               SourceY,
+  IN UINTN                               DestinationX,
+  IN UINTN                               DestinationY,
+  IN UINTN                               Width,
+  IN UINTN                               Height,
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
+  )
+{
+  EFI_STATUS         Status;
+  UINT32             HorizontalResolution;
+  EFI_PIXEL_BITMASK  *PixelInformation;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiDestinationPixel;
+  VOID               *FrameBufferBase;
+  UINT16             *SourcePixel16bit;
+  UINT16             Pixel16bit;
+  UINT32             SourcePixelX;
+  UINT32             SourceLine;
+  UINT32             DestinationPixelX;
+  UINT32             DestinationLine;
+  UINT32             BltBufferHorizontalResolution;
+
+  Status = EFI_SUCCESS;
+  PixelInformation = &This->Mode->Info->PixelInformation;
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
+
+  if(( Delta != 0 ) && ( Delta != Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+    // Delta is not zero and it is different from the width.
+    // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
+    BltBufferHorizontalResolution = (UINT32) (Delta / sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+  } else {
+    BltBufferHorizontalResolution = Width;
+  }
+
+  // Access each pixel inside the Video Memory
+  for (SourceLine = SourceY, DestinationLine = DestinationY;
+       SourceLine < SourceY + Height;
+       SourceLine++, DestinationLine++)
+  {
+    for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
+         SourcePixelX < SourceX + Width;
+         SourcePixelX++, DestinationPixelX++)
+    {
+      // Calculate the source and target addresses:
+      SourcePixel16bit = (UINT16 *)FrameBufferBase + SourceLine * HorizontalResolution + SourcePixelX;
+      EfiDestinationPixel = BltBuffer + DestinationLine * BltBufferHorizontalResolution + DestinationPixelX;
+
+      // Snapshot the pixel from the video buffer once, to speed up the operation.
+      // If we were dereferencing the pointer, as it is volatile, we would perform 3 memory read operations.
+      Pixel16bit = *SourcePixel16bit;
+
+      // Copy the pixel into the new target
+      EfiDestinationPixel->Red      = (UINT8) ( (Pixel16bit & PixelInformation->RedMask     ) >>  8 );
+      EfiDestinationPixel->Green    = (UINT8) ( (Pixel16bit & PixelInformation->GreenMask   ) >>  3 );
+      EfiDestinationPixel->Blue     = (UINT8) ( (Pixel16bit & PixelInformation->BlueMask    ) <<  3 );
+    }
+  }
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+BltBufferToVideo (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL
+  IN UINTN                               SourceX,
+  IN UINTN                               SourceY,
+  IN UINTN                               DestinationX,
+  IN UINTN                               DestinationY,
+  IN UINTN                               Width,
+  IN UINTN                               Height,
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
+  )
+{
+  EFI_STATUS         Status;
+  UINT32             HorizontalResolution;
+  EFI_PIXEL_BITMASK  *PixelInformation;
+  EFI_GRAPHICS_OUTPUT_BLT_PIXEL *EfiSourcePixel;
+  VOID               *FrameBufferBase;
+  UINT16             *DestinationPixel16bit;
+  UINT32             SourcePixelX;
+  UINT32             SourceLine;
+  UINT32             DestinationPixelX;
+  UINT32             DestinationLine;
+  UINT32             BltBufferHorizontalResolution;
+
+  Status = EFI_SUCCESS;
+  PixelInformation = &This->Mode->Info->PixelInformation;
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
+
+  if(( Delta != 0 ) && ( Delta != Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL))) {
+    // Delta is not zero and it is different from the width.
+    // Divide it by the size of a pixel to find out the buffer's horizontal resolution.
+    BltBufferHorizontalResolution = (UINT32) (Delta / sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+  } else {
+    BltBufferHorizontalResolution = Width;
+  }
+
+  // Access each pixel inside the BltBuffer Memory
+  for (SourceLine = SourceY, DestinationLine = DestinationY;
+       SourceLine < SourceY + Height;
+       SourceLine++, DestinationLine++) {
+
+    for (SourcePixelX = SourceX, DestinationPixelX = DestinationX;
+         SourcePixelX < SourceX + Width;
+         SourcePixelX++, DestinationPixelX++)
+    {
+      // Calculate the source and target addresses:
+      EfiSourcePixel  = BltBuffer + SourceLine * BltBufferHorizontalResolution + SourcePixelX;
+      DestinationPixel16bit = (UINT16 *)FrameBufferBase + DestinationLine * HorizontalResolution + DestinationPixelX;
+
+      // Copy the pixel into the new target
+      // Only the most significant bits will be copied across:
+      // To convert from 8 bits to 5 bits per pixel we throw away the 3 least significant bits
+        *DestinationPixel16bit = (UINT16) (
+              ( (EfiSourcePixel->Red      <<  8) & PixelInformation->RedMask      )
+            | ( (EfiSourcePixel->Green    <<  3) & PixelInformation->GreenMask    )
+            | ( (EfiSourcePixel->Blue     >>  3) & PixelInformation->BlueMask     )
+            );
+      }
+    }
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+BltVideoToVideo (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL        *This,
+  IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL   *BltBuffer,     OPTIONAL
+  IN UINTN                               SourceX,
+  IN UINTN                               SourceY,
+  IN UINTN                               DestinationX,
+  IN UINTN                               DestinationY,
+  IN UINTN                               Width,
+  IN UINTN                               Height,
+  IN UINTN                               Delta           OPTIONAL   // Number of BYTES in a row of the BltBuffer
+  )
+{
+  EFI_STATUS         Status;
+  UINT32             HorizontalResolution;
+  UINTN              BitsPerPixel;
+  VOID               *FrameBufferBase;
+
+  BitsPerPixel = 16;
+
+  HorizontalResolution = This->Mode->Info->HorizontalResolution;
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
+
+  //
+  // BltVideo to BltVideo:
+  //
+  //  Source is the Video Memory,
+  //  Destination is the Video Memory
+
+  FrameBufferBase = (UINTN *)((UINTN)(This->Mode->FrameBufferBase));
+
+  // The UEFI spec currently states:
+  // "There is no limitation on the overlapping of the source and destination rectangles"
+  // Therefore, we must be careful to avoid overwriting the source data
+  if( SourceY == DestinationY ) {
+    // Copying within the same height, e.g. horizontal shift
+    if( SourceX == DestinationX ) {
+      // Nothing to do
+      Status = EFI_SUCCESS;
+    } else if( ((SourceX>DestinationX)?(SourceX - DestinationX):(DestinationX - SourceX)) < Width ) {
+      // There is overlap
+      Status = VideoCopyHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
+    } else {
+      // No overlap
+      Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
+    }
+  } else {
+    // Copying from different heights
+    Status = VideoCopyNoHorizontalOverlap (BitsPerPixel, FrameBufferBase, HorizontalResolution, SourceX, SourceY, DestinationX, DestinationY, Width, Height );
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsBlt (
+  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   // Number of BYTES in a row of the BltBuffer
+  )
+{
+  EFI_STATUS    Status;
+  LCD_INSTANCE  *Instance;
+
+  Instance = LCD_INSTANCE_FROM_GOP_THIS(This);
+
+  if (!mDisplayInitialized) {
+    InitializeDisplay (Instance);
+  }
+
+  switch (BltOperation) {
+  case EfiBltVideoFill:
+    Status = BltVideoFill (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
+    break;
+
+  case EfiBltVideoToBltBuffer:
+    Status = BltVideoToBltBuffer (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
+    break;
+
+  case EfiBltBufferToVideo:
+    Status = BltBufferToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
+    break;
+
+  case EfiBltVideoToVideo:
+    Status = BltVideoToVideo (This, BltBuffer, SourceX, SourceY, DestinationX, DestinationY, Width, Height, Delta);
+    break;
+
+  case EfiGraphicsOutputBltOperationMax:
+  default:
+    DEBUG((DEBUG_ERROR, "LcdGraphicsBlt: Invalid Operation\n"));
+    Status = EFI_INVALID_PARAMETER;
+    break;
+}
+
+  return Status;
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c b/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c
new file mode 100644
index 0000000000..ebb520a0ac
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.c
@@ -0,0 +1,394 @@
+/** @file
+
+ Copyright (c) 2011-2014, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "LcdGraphicsOutputDxe.h"
+
+BOOLEAN mDisplayInitialized = FALSE;
+
+LCD_MODE LcdModes[] = {
+  {
+    0, 640, 480,
+    9, 4,
+    96, 16, 48,
+    2, 10, 33
+  },
+  {
+    1, 800, 600,
+    11, 2,
+    120, 56, 64,
+    5, 37, 22
+  },
+  {
+    2, 1024, 768,
+    6, 2,
+    96, 16, 48,
+    2, 10, 33
+  },
+};
+
+LCD_INSTANCE mLcdTemplate = {
+  LCD_INSTANCE_SIGNATURE,
+  NULL, // Handle
+  { // ModeInfo
+    0, // Version
+    0, // HorizontalResolution
+    0, // VerticalResolution
+    PixelBltOnly, // PixelFormat
+    {
+      0xF800, //RedMask;
+      0x7E0, //GreenMask;
+      0x1F, //BlueMask;
+      0x0//ReservedMask
+    }, // PixelInformation
+    0, // PixelsPerScanLine
+  },
+  { // Mode
+    3, // MaxMode;
+    0, // Mode;
+    NULL, // Info;
+    0, // SizeOfInfo;
+    0, // FrameBufferBase;
+    0 // FrameBufferSize;
+  },
+  { // Gop
+    LcdGraphicsQueryMode,  // QueryMode
+    LcdGraphicsSetMode,    // SetMode
+    LcdGraphicsBlt,        // Blt
+    NULL                     // *Mode
+  },
+  { // DevicePath
+    {
+      {
+        HARDWARE_DEVICE_PATH, HW_VENDOR_DP,
+        { (UINT8) (sizeof(VENDOR_DEVICE_PATH)), (UINT8) ((sizeof(VENDOR_DEVICE_PATH)) >> 8) },
+      },
+      // Hardware Device Path for Lcd
+      EFI_CALLER_ID_GUID // Use the driver's GUID
+    },
+    {
+      END_DEVICE_PATH_TYPE,
+      END_ENTIRE_DEVICE_PATH_SUBTYPE,
+      { sizeof(EFI_DEVICE_PATH_PROTOCOL), 0}
+    }
+  }
+};
+
+EFI_STATUS
+LcdInstanceContructor (
+  OUT LCD_INSTANCE** NewInstance
+  )
+{
+  LCD_INSTANCE* Instance;
+
+  Instance = AllocateCopyPool (sizeof(LCD_INSTANCE), &mLcdTemplate);
+  if (Instance == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  Instance->Gop.Mode          = &Instance->Mode;
+  Instance->Mode.Info         = &Instance->ModeInfo;
+
+  *NewInstance = Instance;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+LcdPlatformGetVram (
+  OUT EFI_PHYSICAL_ADDRESS*  VramBaseAddress,
+  OUT UINTN*                 VramSize
+  )
+{
+  EFI_STATUS             Status;
+  EFI_CPU_ARCH_PROTOCOL  *Cpu;
+  UINTN                  MaxSize;
+
+  MaxSize = 0x500000;
+  *VramSize = MaxSize;
+
+  // Allocate VRAM from DRAM
+  Status = gBS->AllocatePages (AllocateAnyPages, EfiBootServicesData, EFI_SIZE_TO_PAGES((MaxSize)), VramBaseAddress);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  // Ensure the Cpu architectural protocol is already installed
+  Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu);
+  ASSERT_EFI_ERROR(Status);
+
+  // Mark the VRAM as un-cacheable. The VRAM is inside the DRAM, which is cacheable.
+  Status = Cpu->SetMemoryAttributes (Cpu, *VramBaseAddress, *VramSize, EFI_MEMORY_UC);
+  if (EFI_ERROR(Status)) {
+    gBS->FreePool (VramBaseAddress);
+    return Status;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DssSetMode (
+  UINT32 VramBaseAddress,
+  UINTN  ModeNumber
+  )
+{
+  // Make sure the interface clock is running
+  MmioWrite32 (CM_ICLKEN_DSS, EN_DSS);
+
+  // Stop the functional clocks
+  MmioAnd32 (CM_FCLKEN_DSS, ~(EN_DSS1 | EN_DSS2 | EN_TV));
+
+  // Program the DSS clock divisor
+  MmioWrite32 (CM_CLKSEL_DSS, 0x1000 | (LcdModes[ModeNumber].DssDivisor));
+
+  // Start the functional clocks
+  MmioOr32 (CM_FCLKEN_DSS, (EN_DSS1 | EN_DSS2 | EN_TV));
+
+  // Wait for DSS to stabilize
+  gBS->Stall(1);
+
+  // Reset the subsystem
+  MmioWrite32(DSS_SYSCONFIG, DSS_SOFTRESET);
+  while (!(MmioRead32 (DSS_SYSSTATUS) & DSS_RESETDONE));
+
+  // Configure LCD parameters
+  MmioWrite32 (DISPC_SIZE_LCD,
+               ((LcdModes[ModeNumber].HorizontalResolution - 1)
+               | ((LcdModes[ModeNumber].VerticalResolution - 1) << 16))
+              );
+  MmioWrite32 (DISPC_TIMING_H,
+               ( (LcdModes[ModeNumber].HSync - 1)
+               | ((LcdModes[ModeNumber].HFrontPorch - 1) << 8)
+               | ((LcdModes[ModeNumber].HBackPorch - 1) << 20))
+              );
+  MmioWrite32 (DISPC_TIMING_V,
+               ( (LcdModes[ModeNumber].VSync - 1)
+               | ((LcdModes[ModeNumber].VFrontPorch - 1) << 8)
+               | ((LcdModes[ModeNumber].VBackPorch - 1) << 20))
+              );
+
+  // Set the framebuffer to only load frames (no gamma tables)
+  MmioAnd32 (DISPC_CONFIG, CLEARLOADMODE);
+  MmioOr32  (DISPC_CONFIG, LOAD_FRAME_ONLY);
+
+  // Divisor for the pixel clock
+  MmioWrite32(DISPC_DIVISOR, ((1 << 16) | LcdModes[ModeNumber].DispcDivisor) );
+
+  // Set up the graphics layer
+  MmioWrite32 (DISPC_GFX_PRELD, 0x2D8);
+  MmioWrite32 (DISPC_GFX_BA0, VramBaseAddress);
+  MmioWrite32 (DISPC_GFX_SIZE,
+               ((LcdModes[ModeNumber].HorizontalResolution - 1)
+               | ((LcdModes[ModeNumber].VerticalResolution - 1) << 16))
+              );
+
+  MmioWrite32(DISPC_GFX_ATTR, (GFXENABLE | RGB16 | BURSTSIZE16));
+
+  // Start it all
+  MmioOr32 (DISPC_CONTROL, (LCDENABLE | ACTIVEMATRIX | DATALINES24 | BYPASS_MODE | LCDENABLESIGNAL));
+  MmioOr32 (DISPC_CONTROL, GOLCD);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+HwInitializeDisplay (
+  UINTN VramBaseAddress,
+  UINTN VramSize
+  )
+{
+  EFI_STATUS    Status;
+  UINT8         Data;
+  EFI_TPL       OldTpl;
+  EMBEDDED_EXTERNAL_DEVICE   *gTPS65950;
+
+  // Enable power lines used by TFP410
+  Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950);
+  ASSERT_EFI_ERROR (Status);
+
+  OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
+  Data = VAUX_DEV_GRP_P1;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VPLL2_DEV_GRP), 1, &Data);
+  ASSERT_EFI_ERROR(Status);
+
+  Data = VAUX_DEDICATED_18V;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VPLL2_DEDICATED), 1, &Data);
+  ASSERT_EFI_ERROR (Status);
+
+  // Power up TFP410 (set GPIO2 on TPS - for BeagleBoard-xM)
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, GPIODATADIR1), 1, &Data);
+  ASSERT_EFI_ERROR (Status);
+  Data |= BIT2;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, GPIODATADIR1), 1, &Data);
+  ASSERT_EFI_ERROR (Status);
+
+  Data = BIT2;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, SETGPIODATAOUT1), 1, &Data);
+  ASSERT_EFI_ERROR (Status);
+
+  gBS->RestoreTPL(OldTpl);
+
+  // Power up TFP410 (set GPIO 170 - for older BeagleBoards)
+  MmioAnd32 (GPIO6_BASE + GPIO_OE, ~BIT10);
+  MmioOr32  (GPIO6_BASE + GPIO_SETDATAOUT, BIT10);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InitializeDisplay (
+  IN LCD_INSTANCE* Instance
+  )
+{
+  EFI_STATUS           Status;
+  UINTN                VramSize;
+  EFI_PHYSICAL_ADDRESS VramBaseAddress;
+
+  Status = LcdPlatformGetVram (&VramBaseAddress, &VramSize);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Instance->Mode.FrameBufferBase = VramBaseAddress;
+  Instance->Mode.FrameBufferSize = VramSize;
+
+  Status = HwInitializeDisplay((UINTN)VramBaseAddress, VramSize);
+  if (!EFI_ERROR (Status)) {
+    mDisplayInitialized = TRUE;
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsQueryMode (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL            *This,
+  IN UINT32                                  ModeNumber,
+  OUT UINTN                                  *SizeOfInfo,
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION   **Info
+  )
+{
+  LCD_INSTANCE  *Instance;
+
+  Instance = LCD_INSTANCE_FROM_GOP_THIS(This);
+
+  if (!mDisplayInitialized) {
+    InitializeDisplay (Instance);
+  }
+
+  // Error checking
+  if ( (This == NULL) || (Info == NULL) || (SizeOfInfo == NULL) || (ModeNumber >= This->Mode->MaxMode) ) {
+    DEBUG((DEBUG_ERROR, "LcdGraphicsQueryMode: ERROR - For mode number %d : Invalid Parameter.\n", ModeNumber ));
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *Info = AllocateCopyPool(sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION), &Instance->ModeInfo);
+  if (*Info == NULL) {
+    return EFI_OUT_OF_RESOURCES;
+  }
+
+  *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
+
+  (*Info)->Version = 0;
+  (*Info)->HorizontalResolution = LcdModes[ModeNumber].HorizontalResolution;
+  (*Info)->VerticalResolution = LcdModes[ModeNumber].VerticalResolution;
+  (*Info)->PixelFormat = PixelBltOnly;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsSetMode (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL   *This,
+  IN UINT32                         ModeNumber
+  )
+{
+  LCD_INSTANCE  *Instance;
+
+  Instance = LCD_INSTANCE_FROM_GOP_THIS(This);
+
+  if (ModeNumber >= Instance->Mode.MaxMode) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if (!mDisplayInitialized) {
+    InitializeDisplay (Instance);
+  }
+
+  DssSetMode((UINT32)Instance->Mode.FrameBufferBase, ModeNumber);
+
+  Instance->Mode.Mode = ModeNumber;
+  Instance->ModeInfo.HorizontalResolution = LcdModes[ModeNumber].HorizontalResolution;
+  Instance->ModeInfo.VerticalResolution = LcdModes[ModeNumber].VerticalResolution;
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsOutputDxeInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+  LCD_INSTANCE* Instance;
+
+  Status = LcdInstanceContructor (&Instance);
+  if (EFI_ERROR(Status)) {
+    goto EXIT;
+  }
+
+  // Install the Graphics Output Protocol and the Device Path
+  Status = gBS->InstallMultipleProtocolInterfaces(
+             &Instance->Handle,
+             &gEfiGraphicsOutputProtocolGuid, &Instance->Gop,
+             &gEfiDevicePathProtocolGuid,     &Instance->DevicePath,
+             NULL
+             );
+
+  if (EFI_ERROR(Status)) {
+    DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the protocol. Exit Status=%r\n", Status));
+    goto EXIT;
+  }
+
+  // Register for an ExitBootServicesEvent
+  // When ExitBootServices starts, this function here will make sure that the graphics driver will shut down properly,
+  // i.e. it will free up all allocated memory and perform any necessary hardware re-configuration.
+  /*Status = gBS->CreateEvent (
+               EVT_SIGNAL_EXIT_BOOT_SERVICES,
+               TPL_NOTIFY,
+               LcdGraphicsExitBootServicesEvent, NULL,
+               &Instance->ExitBootServicesEvent
+               );
+
+  if (EFI_ERROR(Status)) {
+    DEBUG((DEBUG_ERROR, "GraphicsOutputDxeInitialize: Can not install the ExitBootServicesEvent handler. Exit Status=%r\n", Status));
+    goto EXIT_ERROR_UNINSTALL_PROTOCOL;
+  }*/
+
+  // To get here, everything must be fine, so just exit
+  goto EXIT;
+
+//EXIT_ERROR_UNINSTALL_PROTOCOL:
+  /* The following function could return an error message,
+   * however, to get here something must have gone wrong already,
+   * so preserve the original error, i.e. don't change
+   * the Status variable, even it fails to uninstall the protocol.
+   */
+  /*  gBS->UninstallMultipleProtocolInterfaces (
+        Instance->Handle,
+        &gEfiGraphicsOutputProtocolGuid, &Instance->Gop, // Uninstall Graphics Output protocol
+        &gEfiDevicePathProtocolGuid,     &Instance->DevicePath,     // Uninstall device path
+        NULL
+        );*/
+
+EXIT:
+  return Status;
+
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h b/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h
new file mode 100644
index 0000000000..c4671ab444
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.h
@@ -0,0 +1,151 @@
+/** @file
+
+ Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef __OMAP3_DSS_GRAPHICS__
+#define __OMAP3_DSS_GRAPHICS__
+
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/IoLib.h>
+
+#include <Protocol/DevicePathToText.h>
+#include <Protocol/EmbeddedExternalDevice.h>
+#include <Protocol/Cpu.h>
+
+#include <Guid/GlobalVariable.h>
+
+#include <Omap3530/Omap3530.h>
+#include <TPS65950.h>
+
+typedef struct {
+  VENDOR_DEVICE_PATH            Guid;
+  EFI_DEVICE_PATH_PROTOCOL      End;
+} LCD_GRAPHICS_DEVICE_PATH;
+
+typedef struct {
+  UINTN                                 Signature;
+  EFI_HANDLE                            Handle;
+  EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  ModeInfo;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE     Mode;
+  EFI_GRAPHICS_OUTPUT_PROTOCOL          Gop;
+  LCD_GRAPHICS_DEVICE_PATH              DevicePath;
+//  EFI_EVENT                             ExitBootServicesEvent;
+} LCD_INSTANCE;
+
+#define LCD_INSTANCE_SIGNATURE  SIGNATURE_32('l', 'c', 'd', '0')
+#define LCD_INSTANCE_FROM_GOP_THIS(a)     CR (a, LCD_INSTANCE, Gop, LCD_INSTANCE_SIGNATURE)
+
+typedef struct {
+  UINTN             Mode;
+  UINTN             HorizontalResolution;
+  UINTN             VerticalResolution;
+
+  UINT32            DssDivisor;
+  UINT32            DispcDivisor;
+
+  UINT32            HSync;
+  UINT32            HFrontPorch;
+  UINT32            HBackPorch;
+
+  UINT32            VSync;
+  UINT32            VFrontPorch;
+  UINT32            VBackPorch;
+} LCD_MODE;
+
+EFI_STATUS
+InitializeDisplay (
+  IN LCD_INSTANCE* Instance
+);
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsQueryMode (
+  IN  EFI_GRAPHICS_OUTPUT_PROTOCOL          *This,
+  IN  UINT32                                ModeNumber,
+  OUT UINTN                                 *SizeOfInfo,
+  OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION  **Info
+);
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsSetMode (
+  IN EFI_GRAPHICS_OUTPUT_PROTOCOL  *This,
+  IN UINT32                        ModeNumber
+);
+
+EFI_STATUS
+EFIAPI
+LcdGraphicsBlt (
+  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   // Number of BYTES in a row of the BltBuffer
+);
+
+// HW registers
+#define CM_FCLKEN_DSS   0x48004E00
+#define CM_ICLKEN_DSS   0x48004E10
+
+#define DSS_CONTROL     0x48050040
+#define DSS_SYSCONFIG   0x48050010
+#define DSS_SYSSTATUS   0x48050014
+
+#define DISPC_CONTROL   0x48050440
+#define DISPC_CONFIG    0x48050444
+#define DISPC_SIZE_LCD  0x4805047C
+#define DISPC_TIMING_H  0x48050464
+#define DISPC_TIMING_V  0x48050468
+
+#define CM_CLKSEL_DSS   0x48004E40
+#define DISPC_DIVISOR   0x48050470
+#define DISPC_POL_FREQ  0x4805046C
+
+#define DISPC_GFX_TABLE_BA 0x480504B8
+#define DISPC_GFX_BA0   0x48050480
+#define DISPC_GFX_BA1   0x48050484
+#define DISPC_GFX_POS   0x48050488
+#define DISPC_GFX_SIZE  0x4805048C
+#define DISPC_GFX_ATTR  0x480504A0
+#define DISPC_GFX_PRELD 0x4805062C
+
+#define DISPC_DEFAULT_COLOR_0 0x4805044C
+
+//#define DISPC_IRQSTATUS
+
+// Bits
+#define EN_TV           0x4
+#define EN_DSS2         0x2
+#define EN_DSS1         0x1
+#define EN_DSS          0x1
+
+#define DSS_SOFTRESET   0x2
+#define DSS_RESETDONE   0x1
+
+#define BYPASS_MODE     (BIT15 | BIT16)
+
+#define LCDENABLE       BIT0
+#define ACTIVEMATRIX    BIT3
+#define GOLCD           BIT5
+#define DATALINES24     (BIT8 | BIT9)
+#define LCDENABLESIGNAL BIT28
+
+#define GFXENABLE       BIT0
+#define RGB16           (0x6 << 1)
+#define BURSTSIZE16     (0x2 << 6)
+
+#define CLEARLOADMODE   ~(BIT2 | BIT1)
+#define LOAD_FRAME_ONLY BIT2
+
+#endif
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf b/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
new file mode 100644
index 0000000000..b017d8bf92
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
@@ -0,0 +1,46 @@
+#/** @file
+#
+#  Copyright (c) 2011, ARM Ltd. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = LcdGraphicsDxe
+  FILE_GUID                      = E68088EF-D1A4-4336-C1DB-4D3A204730A6
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+  ENTRY_POINT                    = LcdGraphicsOutputDxeInitialize
+
+[Sources.common]
+  LcdGraphicsOutputDxe.c
+  LcdGraphicsOutputBlt.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  ArmPkg/ArmPkg.dec
+  ArmPlatformPkg/ArmPlatformPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+
+[LibraryClasses]
+  ArmLib
+  UefiLib
+  BaseLib
+  DebugLib
+  TimerLib
+  UefiDriverEntryPoint
+  UefiBootServicesTableLib
+  IoLib
+  BaseMemoryLib
+
+[Protocols]
+  gEfiDevicePathProtocolGuid
+  gEfiGraphicsOutputProtocolGuid
+  gEfiDevicePathToTextProtocolGuid
+  gEmbeddedExternalDeviceProtocolGuid
+
+[Depex]
+  gEfiCpuArchProtocolGuid AND gEfiTimerArchProtocolGuid
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c b/Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c
new file mode 100644
index 0000000000..d0e77e12e5
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.c
@@ -0,0 +1,159 @@
+/** @file
+  Debug Agent timer lib for OMAP 35xx.
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <Base.h>
+#include <Library/BaseLib.h>
+#include <Library/IoLib.h>
+#include <Library/OmapLib.h>
+#include <Library/ArmLib.h>
+#include <Library/PcdLib.h>
+
+#include <Omap3530/Omap3530.h>
+
+
+volatile UINT32 gVector;
+
+// Cached registers
+volatile UINT32 gTISR;
+volatile UINT32 gTCLR;
+volatile UINT32 gTLDR;
+volatile UINT32 gTCRR;
+volatile UINT32 gTIER;
+
+VOID
+EnableInterruptSource (
+  VOID
+  )
+{
+  UINTN Bank;
+  UINTN Bit;
+
+  // Map vector to FIQ, IRQ is default
+  MmioWrite32 (INTCPS_ILR (gVector), 1);
+
+  Bank = gVector / 32;
+  Bit  = 1UL << (gVector % 32);
+
+  MmioWrite32 (INTCPS_MIR_CLEAR(Bank), Bit);
+}
+
+VOID
+DisableInterruptSource (
+  VOID
+  )
+{
+  UINTN Bank;
+  UINTN Bit;
+
+  Bank = gVector / 32;
+  Bit  = 1UL << (gVector % 32);
+
+  MmioWrite32 (INTCPS_MIR_SET(Bank), Bit);
+}
+
+
+
+/**
+  Setup all the hardware needed for the debug agents timer.
+
+  This function is used to set up debug enviroment. It may enable interrupts.
+
+**/
+VOID
+EFIAPI
+DebugAgentTimerIntialize (
+  VOID
+  )
+{
+  UINT32      TimerBaseAddress;
+  UINT32      TimerNumber;
+
+  TimerNumber = PcdGet32(PcdOmap35xxDebugAgentTimer);
+  gVector = InterruptVectorForTimer (TimerNumber);
+
+  // Set up the timer registers
+  TimerBaseAddress = TimerBase (TimerNumber);
+  gTISR = TimerBaseAddress + GPTIMER_TISR;
+  gTCLR = TimerBaseAddress + GPTIMER_TCLR;
+  gTLDR = TimerBaseAddress + GPTIMER_TLDR;
+  gTCRR = TimerBaseAddress + GPTIMER_TCRR;
+  gTIER = TimerBaseAddress + GPTIMER_TIER;
+
+  if ((TimerNumber < 2) || (TimerNumber > 9)) {
+    // This code assumes one the General Purpose timers is used
+    // GPT2 - GPT9
+    CpuDeadLoop ();
+  }
+  // Set source clock for GPT2 - GPT9 to SYS_CLK
+  MmioOr32 (CM_CLKSEL_PER, 1 << (TimerNumber - 2));
+
+}
+
+
+/**
+  Set the period for the debug agent timer. Zero means disable the timer.
+
+  @param[in] TimerPeriodMilliseconds    Frequency of the debug agent timer.
+
+**/
+VOID
+EFIAPI
+DebugAgentTimerSetPeriod (
+  IN  UINT32  TimerPeriodMilliseconds
+  )
+{
+  UINT64      TimerCount;
+  INT32       LoadValue;
+
+  if (TimerPeriodMilliseconds == 0) {
+    // Turn off GPTIMER3
+    MmioWrite32 (gTCLR, TCLR_ST_OFF);
+
+    DisableInterruptSource ();
+  } else {
+    // Calculate required timer count
+    TimerCount = DivU64x32(TimerPeriodMilliseconds * 1000000, PcdGet32(PcdDebugAgentTimerFreqNanoSeconds));
+
+    // Set GPTIMER5 Load register
+    LoadValue = (INT32) -TimerCount;
+    MmioWrite32 (gTLDR, LoadValue);
+    MmioWrite32 (gTCRR, LoadValue);
+
+    // Enable Overflow interrupt
+    MmioWrite32 (gTIER, TIER_TCAR_IT_DISABLE | TIER_OVF_IT_ENABLE | TIER_MAT_IT_DISABLE);
+
+    // Turn on GPTIMER3, it will reload at overflow
+    MmioWrite32 (gTCLR, TCLR_AR_AUTORELOAD | TCLR_ST_ON);
+
+    EnableInterruptSource ();
+  }
+}
+
+
+/**
+  Perform End Of Interrupt for the debug agent timer. This is called in the
+  interrupt handler after the interrupt has been processed.
+
+**/
+VOID
+EFIAPI
+DebugAgentTimerEndOfInterrupt (
+  VOID
+  )
+{
+   // Clear all timer interrupts
+  MmioWrite32 (gTISR, TISR_CLEAR_ALL);
+
+  // Poll interrupt status bits to ensure clearing
+  while ((MmioRead32 (gTISR) & TISR_ALL_INTERRUPT_MASK) != TISR_NO_INTERRUPTS_PENDING);
+
+  MmioWrite32 (INTCPS_CONTROL, INTCPS_CONTROL_NEWFIQAGR);
+  ArmDataSynchronizationBarrier ();
+
+}
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf b/Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
new file mode 100644
index 0000000000..ee178e7bd2
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
@@ -0,0 +1,42 @@
+#/** @file
+# Component description file for Base PCI Cf8 Library.
+#
+# PCI CF8 Library that uses I/O ports 0xCF8 and 0xCFC to perform PCI Configuration cycles.
+#  Layers on top of an I/O Library instance.
+# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = DebugAgentTimerLibNull
+  FILE_GUID                      = E82F99DE-74ED-4e56-BBA1-B143FCA3F69A
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = DebugAgentTimerLib|SEC BASE DXE_CORE
+
+
+[Sources.common]
+  DebugAgentTimerLib.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+  ArmPkg/ArmPkg.dec
+
+
+[LibraryClasses]
+  BaseLib
+  IoLib
+  OmapLib
+  ArmLib
+
+[Pcd]
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxDebugAgentTimer
+  gOmap35xxTokenSpaceGuid.PcdDebugAgentTimerFreqNanoSeconds
+  gEmbeddedTokenSpaceGuid.PcdInterruptBaseAddress
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.c b/Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.c
new file mode 100644
index 0000000000..4e9fa0175b
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.c
@@ -0,0 +1,96 @@
+/** @file
+  Basic serial IO abstaction for GDB
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Library/GdbSerialLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/DebugLib.h>
+#include <Library/OmapLib.h>
+#include <Omap3530/Omap3530.h>
+
+RETURN_STATUS
+EFIAPI
+GdbSerialLibConstructor (
+  VOID
+  )
+{
+  return RETURN_SUCCESS;
+}
+
+RETURN_STATUS
+EFIAPI
+GdbSerialInit (
+  IN UINT64     BaudRate,
+  IN UINT8      Parity,
+  IN UINT8      DataBits,
+  IN UINT8      StopBits
+  )
+{
+  return RETURN_SUCCESS;
+}
+
+BOOLEAN
+EFIAPI
+GdbIsCharAvailable (
+  VOID
+  )
+{
+  UINT32 LSR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_LSR_REG;
+
+  if ((MmioRead8(LSR) & UART_LSR_RX_FIFO_E_MASK) == UART_LSR_RX_FIFO_E_NOT_EMPTY) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+CHAR8
+EFIAPI
+GdbGetChar (
+  VOID
+  )
+{
+  UINT32  LSR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_LSR_REG;
+  UINT32  RBR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_RBR_REG;
+  CHAR8   Char;
+
+  while ((MmioRead8(LSR) & UART_LSR_RX_FIFO_E_MASK) == UART_LSR_RX_FIFO_E_EMPTY);
+  Char = MmioRead8(RBR);
+
+  return Char;
+}
+
+VOID
+EFIAPI
+GdbPutChar (
+  IN  CHAR8   Char
+  )
+{
+  UINT32  LSR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_LSR_REG;
+  UINT32  THR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_THR_REG;
+
+  while ((MmioRead8(LSR) & UART_LSR_TX_FIFO_E_MASK) == UART_LSR_TX_FIFO_E_NOT_EMPTY);
+  MmioWrite8(THR, Char);
+}
+
+VOID
+GdbPutString (
+  IN CHAR8  *String
+  )
+{
+  while (*String != '\0') {
+    GdbPutChar (*String);
+    String++;
+  }
+}
+
+
+
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.inf b/Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.inf
new file mode 100644
index 0000000000..c372e35c55
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.inf
@@ -0,0 +1,35 @@
+#/** @file
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = GdbSerialLib
+  FILE_GUID                      = E2423349-EF5D-439B-95F5-8B8D8E3B443F
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = GdbSerialLib
+
+  CONSTRUCTOR                    = GdbSerialLibConstructor
+
+
+[Sources.common]
+  GdbSerialLib.c
+
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  IoLib
+  OmapLib
+
+[FixedPcd]
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxConsoleUart
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/Omap35xxTimerLib.inf b/Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/Omap35xxTimerLib.inf
new file mode 100644
index 0000000000..ddb95c6542
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/Omap35xxTimerLib.inf
@@ -0,0 +1,40 @@
+#/** @file
+# Timer library implementation
+#
+# A non-functional instance of the Timer Library that can be used as a template
+#  for the implementation of a functional timer library instance. This library instance can
+#  also be used to test build DXE, Runtime, DXE SAL, and DXE SMM modules that require timer
+#  services as well as EBC modules that require timer services
+# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BeagleBoardTimerLib
+  FILE_GUID                      = fe1d7183-9abb-42ce-9a3b-36d7c6a8959f
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = TimerLib
+
+[Sources.common]
+  TimerLib.c
+
+[Packages]
+  Omap35xxPkg/Omap35xxPkg.dec
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  OmapLib
+  IoLib
+
+[Pcd]
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPerformanceCounterFrequencyInHz
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPerformanceCounterPeriodInNanoseconds
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxFreeTimer
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/TimerLib.c b/Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/TimerLib.c
new file mode 100644
index 0000000000..a69cad83a9
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/Omap35xxTimerLib/TimerLib.c
@@ -0,0 +1,151 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/TimerLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/OmapLib.h>
+
+#include <Omap3530/Omap3530.h>
+
+RETURN_STATUS
+EFIAPI
+TimerConstructor (
+  VOID
+  )
+{
+  UINTN  Timer            = PcdGet32(PcdOmap35xxFreeTimer);
+  UINT32 TimerBaseAddress = TimerBase(Timer);
+
+  if ((MmioRead32 (TimerBaseAddress + GPTIMER_TCLR) & TCLR_ST_ON) == 0) {
+    // Set source clock for GPT3 & GPT4 to SYS_CLK
+    MmioOr32 (CM_CLKSEL_PER, CM_CLKSEL_PER_CLKSEL_GPT3_SYS | CM_CLKSEL_PER_CLKSEL_GPT4_SYS);
+
+    // Set count & reload registers
+    MmioWrite32 (TimerBaseAddress + GPTIMER_TCRR, 0x00000000);
+    MmioWrite32 (TimerBaseAddress + GPTIMER_TLDR, 0x00000000);
+
+    // Disable interrupts
+    MmioWrite32 (TimerBaseAddress + GPTIMER_TIER, TIER_TCAR_IT_DISABLE | TIER_OVF_IT_DISABLE | TIER_MAT_IT_DISABLE);
+
+    // Start Timer
+    MmioWrite32 (TimerBaseAddress + GPTIMER_TCLR, TCLR_AR_AUTORELOAD | TCLR_ST_ON);
+
+    // Disable OMAP Watchdog timer (WDT2)
+    MmioWrite32 (WDTIMER2_BASE + WSPR, 0xAAAA);
+    DEBUG ((EFI_D_ERROR, "Magic delay to disable watchdog timers properly.\n"));
+    MmioWrite32 (WDTIMER2_BASE + WSPR, 0x5555);
+  }
+  return EFI_SUCCESS;
+}
+
+UINTN
+EFIAPI
+MicroSecondDelay (
+  IN  UINTN MicroSeconds
+  )
+{
+  UINT64  NanoSeconds;
+
+  NanoSeconds = MultU64x32(MicroSeconds, 1000);
+
+  while (NanoSeconds > (UINTN)-1) {
+    NanoSecondDelay((UINTN)-1);
+    NanoSeconds -= (UINTN)-1;
+  }
+
+  NanoSecondDelay(NanoSeconds);
+
+  return MicroSeconds;
+}
+
+UINTN
+EFIAPI
+NanoSecondDelay (
+  IN  UINTN NanoSeconds
+  )
+{
+  UINT32  Delay;
+  UINT32  StartTime;
+  UINT32  CurrentTime;
+  UINT32  ElapsedTime;
+  UINT32  TimerCountRegister;
+
+  Delay = (NanoSeconds / PcdGet32(PcdEmbeddedPerformanceCounterPeriodInNanoseconds)) + 1;
+
+  TimerCountRegister = TimerBase(PcdGet32(PcdOmap35xxFreeTimer)) + GPTIMER_TCRR;
+
+  StartTime = MmioRead32 (TimerCountRegister);
+
+  do
+  {
+    CurrentTime = MmioRead32 (TimerCountRegister);
+    ElapsedTime = CurrentTime - StartTime;
+  } while (ElapsedTime < Delay);
+
+  NanoSeconds = ElapsedTime * PcdGet32(PcdEmbeddedPerformanceCounterPeriodInNanoseconds);
+
+  return NanoSeconds;
+}
+
+UINT64
+EFIAPI
+GetPerformanceCounter (
+  VOID
+  )
+{
+  return (UINT64)MmioRead32 (TimerBase(PcdGet32(PcdOmap35xxFreeTimer)) + GPTIMER_TCRR);
+}
+
+UINT64
+EFIAPI
+GetPerformanceCounterProperties (
+  OUT UINT64  *StartValue,  OPTIONAL
+  OUT UINT64  *EndValue     OPTIONAL
+  )
+{
+  if (StartValue != NULL) {
+    // Timer starts with the reload value
+    *StartValue = (UINT64)MmioRead32 (TimerBase(PcdGet32(PcdOmap35xxFreeTimer)) + GPTIMER_TLDR);
+  }
+
+  if (EndValue != NULL) {
+    // Timer counts up to 0xFFFFFFFF
+    *EndValue = 0xFFFFFFFF;
+  }
+
+  return PcdGet64(PcdEmbeddedPerformanceCounterFrequencyInHz);
+}
+
+/**
+  Converts elapsed ticks of performance counter to time in nanoseconds.
+
+  This function converts the elapsed ticks of running performance counter to
+  time value in unit of nanoseconds.
+
+  @param  Ticks     The number of elapsed ticks of running performance counter.
+
+  @return The elapsed time in nanoseconds.
+
+**/
+UINT64
+EFIAPI
+GetTimeInNanoSecond (
+  IN      UINT64                     Ticks
+  )
+{
+  UINT32 Period;
+
+  Period = PcdGet32 (PcdEmbeddedPerformanceCounterPeriodInNanoseconds);
+
+  return (Ticks * Period);
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c b/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c
new file mode 100644
index 0000000000..22393389b9
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.c
@@ -0,0 +1,170 @@
+/** @file
+  Abstractions for simple OMAP DMA channel.
+
+
+  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/DebugLib.h>
+#include <Library/OmapDmaLib.h>
+#include <Library/IoLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Omap3530/Omap3530.h>
+
+
+/**
+  Configure OMAP DMA Channel
+
+  @param  Channel               DMA Channel to configure
+  @param  Dma4                  Pointer to structure used to initialize DMA registers for the Channel
+
+  @retval EFI_SUCCESS           The range was mapped for the returned NumberOfBytes.
+  @retval EFI_INVALID_PARAMETER Channel is not valid
+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested information.
+
+**/
+EFI_STATUS
+EFIAPI
+EnableDmaChannel (
+  IN  UINTN       Channel,
+  IN  OMAP_DMA4   *DMA4
+  )
+{
+  UINT32  RegVal;
+
+
+  if (Channel > DMA4_MAX_CHANNEL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  /* 1) Configure the transfer parameters in the logical DMA registers */
+  /*-------------------------------------------------------------------*/
+
+  /* a) Set the data type CSDP[1:0], the Read/Write Port access type
+        CSDP[8:7]/[15:14], the Source/dest endianism CSDP[21]/CSDP[19],
+        write mode CSDP[17:16], source/dest packed or nonpacked CSDP[6]/CSDP[13] */
+
+  // Read CSDP
+  RegVal = MmioRead32 (DMA4_CSDP (Channel));
+
+  // Build reg
+  RegVal = ((RegVal & ~ 0x3) | DMA4->DataType );
+  RegVal = ((RegVal & ~(0x3 <<  7)) | (DMA4->ReadPortAccessType << 7));
+  RegVal = ((RegVal & ~(0x3 << 14)) | (DMA4->WritePortAccessType << 14));
+  RegVal = ((RegVal & ~(0x1 << 21)) | (DMA4->SourceEndiansim << 21));
+  RegVal = ((RegVal & ~(0x1 << 19)) | (DMA4->DestinationEndianism << 19));
+  RegVal = ((RegVal & ~(0x3 << 16)) | (DMA4->WriteMode << 16));
+  RegVal = ((RegVal & ~(0x1 <<  6)) | (DMA4->SourcePacked << 6));
+  RegVal = ((RegVal & ~(0x1 << 13)) | (DMA4->DestinationPacked << 13));
+  // Write CSDP
+  MmioWrite32 (DMA4_CSDP (Channel), RegVal);
+
+  /* b) Set the number of element per frame CEN[23:0]*/
+  MmioWrite32 (DMA4_CEN (Channel), DMA4->NumberOfElementPerFrame);
+
+  /* c) Set the number of frame per block CFN[15:0]*/
+  MmioWrite32 (DMA4_CFN (Channel), DMA4->NumberOfFramePerTransferBlock);
+
+  /* d) Set the Source/dest start address index CSSA[31:0]/CDSA[31:0]*/
+  MmioWrite32 (DMA4_CSSA (Channel), DMA4->SourceStartAddress);
+  MmioWrite32 (DMA4_CDSA (Channel), DMA4->DestinationStartAddress);
+
+  /* e) Set the Read Port addressing mode CCR[13:12], the Write Port addressing mode CCR[15:14],
+        read/write priority CCR[6]/CCR[26]
+        I changed LCH CCR[20:19]=00 and CCR[4:0]=00000 to
+        LCH CCR[20:19]= DMA4->WriteRequestNumber and CCR[4:0]=DMA4->ReadRequestNumber
+  */
+
+  // Read CCR
+  RegVal = MmioRead32 (DMA4_CCR (Channel));
+
+  // Build reg
+  RegVal  = ((RegVal &  ~0x1f)            | DMA4->ReadRequestNumber);
+  RegVal  = ((RegVal &  ~(BIT20 | BIT19)) | DMA4->WriteRequestNumber << 19);
+  RegVal  = ((RegVal & ~(0x3 << 12)) | (DMA4->ReadPortAccessMode << 12));
+  RegVal  = ((RegVal & ~(0x3 << 14)) | (DMA4->WritePortAccessMode << 14));
+  RegVal  = ((RegVal & ~(0x1 <<  6)) | (DMA4->ReadPriority << 6));
+  RegVal  = ((RegVal & ~(0x1 << 26)) | (DMA4->WritePriority << 26));
+
+  // Write CCR
+  MmioWrite32 (DMA4_CCR (Channel), RegVal);
+
+  /* f)- Set the source element index CSEI[15:0]*/
+  MmioWrite32 (DMA4_CSEI (Channel), DMA4->SourceElementIndex);
+
+  /* - Set the source frame index CSFI[15:0]*/
+  MmioWrite32 (DMA4_CSFI (Channel), DMA4->SourceFrameIndex);
+
+
+  /* - Set the destination element index CDEI[15:0]*/
+  MmioWrite32 (DMA4_CDEI (Channel), DMA4->DestinationElementIndex);
+
+  /* - Set the destination frame index CDFI[31:0]*/
+  MmioWrite32 (DMA4_CDFI (Channel), DMA4->DestinationFrameIndex);
+
+  MmioWrite32 (DMA4_CDFI (Channel), DMA4->DestinationFrameIndex);
+
+  // Enable all the status bits since we are polling
+  MmioWrite32 (DMA4_CICR (Channel), DMA4_CICR_ENABLE_ALL);
+  MmioWrite32 (DMA4_CSR (Channel),  DMA4_CSR_RESET);
+
+  /* 2) Start the DMA transfer by Setting the enable bit CCR[7]=1 */
+  /*--------------------------------------------------------------*/
+  //write enable bit
+  MmioOr32 (DMA4_CCR(Channel), DMA4_CCR_ENABLE); //Launch transfer
+
+  return EFI_SUCCESS;
+}
+
+/**
+  Turn of DMA channel configured by EnableDma().
+
+  @param  Channel               DMA Channel to configure
+  @param  SuccesMask            Bits in DMA4_CSR register indicate EFI_SUCCESS
+  @param  ErrorMask             Bits in DMA4_CSR register indicate EFI_DEVICE_ERROR
+
+  @retval EFI_SUCCESS           DMA hardware disabled
+  @retval EFI_INVALID_PARAMETER Channel is not valid
+  @retval EFI_DEVICE_ERROR      The system hardware could not map the requested information.
+
+**/
+EFI_STATUS
+EFIAPI
+DisableDmaChannel (
+  IN  UINTN       Channel,
+  IN  UINT32      SuccessMask,
+  IN  UINT32      ErrorMask
+  )
+{
+  EFI_STATUS  Status = EFI_SUCCESS;
+  UINT32      Reg;
+
+
+  if (Channel > DMA4_MAX_CHANNEL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  do {
+    Reg = MmioRead32 (DMA4_CSR(Channel));
+    if ((Reg & ErrorMask) != 0) {
+      Status = EFI_DEVICE_ERROR;
+      DEBUG ((EFI_D_ERROR, "DMA Error (%d) %x\n", Channel, Reg));
+      break;
+    }
+  } while ((Reg & SuccessMask) != SuccessMask);
+
+
+  // Disable all status bits and clear them
+  MmioWrite32 (DMA4_CICR (Channel), 0);
+  MmioWrite32 (DMA4_CSR (Channel),  DMA4_CSR_RESET);
+
+  MmioAnd32 (DMA4_CCR(0), ~(DMA4_CCR_ENABLE | DMA4_CCR_RD_ACTIVE | DMA4_CCR_WR_ACTIVE));
+  return Status;
+}
+
+
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf b/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
new file mode 100644
index 0000000000..68a0606cdf
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
@@ -0,0 +1,43 @@
+#/** @file
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = OmapDmaLib
+  FILE_GUID                      = 09B17D99-BB07-49a8-B0D2-06D6AFCBE3AB
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = OmapDmaLib
+
+
+[Sources.common]
+  OmapDmaLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  DebugLib
+  UefiBootServicesTableLib
+  MemoryAllocationLib
+  IoLib
+  BaseMemoryLib
+  ArmLib
+
+
+[Protocols]
+  gEfiCpuArchProtocolGuid
+
+[Guids]
+
+[Pcd]
+
+[Depex]
+  gEfiCpuArchProtocolGuid
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.c b/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.c
new file mode 100644
index 0000000000..cfea62e6d6
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.c
@@ -0,0 +1,77 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/DebugLib.h>
+#include <Library/OmapLib.h>
+#include <Omap3530/Omap3530.h>
+
+UINT32
+GpioBase (
+  IN  UINTN Port
+  )
+{
+  switch (Port) {
+  case 1:  return GPIO1_BASE;
+  case 2:  return GPIO2_BASE;
+  case 3:  return GPIO3_BASE;
+  case 4:  return GPIO4_BASE;
+  case 5:  return GPIO5_BASE;
+  case 6:  return GPIO6_BASE;
+  default: ASSERT(FALSE); return 0;
+  }
+}
+
+UINT32
+TimerBase (
+  IN  UINTN Timer
+  )
+{
+  switch (Timer) {
+  case  1: return GPTIMER1_BASE;
+  case  2: return GPTIMER2_BASE;
+  case  3: return GPTIMER3_BASE;
+  case  4: return GPTIMER4_BASE;
+  case  5: return GPTIMER5_BASE;
+  case  6: return GPTIMER6_BASE;
+  case  7: return GPTIMER7_BASE;
+  case  8: return GPTIMER8_BASE;
+  case  9: return GPTIMER9_BASE;
+  case 10: return GPTIMER10_BASE;
+  case 11: return GPTIMER11_BASE;
+  case 12: return GPTIMER12_BASE;
+  default: return 0;
+  }
+}
+
+UINTN
+InterruptVectorForTimer (
+  IN  UINTN Timer
+  )
+{
+  if ((Timer < 1) || (Timer > 12)) {
+    ASSERT(FALSE);
+    return 0xFFFFFFFF;
+  }
+
+  return 36 + Timer;
+}
+
+UINT32
+UartBase (
+  IN  UINTN Uart
+  )
+{
+  switch (Uart) {
+  case 1:  return UART1_BASE;
+  case 2:  return UART2_BASE;
+  case 3:  return UART3_BASE;
+  default: ASSERT(FALSE); return 0;
+  }
+}
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.inf b/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.inf
new file mode 100644
index 0000000000..df37387622
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/OmapLib/OmapLib.inf
@@ -0,0 +1,31 @@
+#/** @file
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = OmapLib
+  FILE_GUID                      = d035f5c2-1b92-4746-9f6c-5ff6202970df
+  MODULE_TYPE                    = UEFI_DRIVER
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = OmapLib
+
+[Sources.common]
+  OmapLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  DebugLib
+
+[Protocols]
+
+[Guids]
+
+[Pcd]
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.c b/Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.c
new file mode 100644
index 0000000000..ddde1868ac
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.c
@@ -0,0 +1,291 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include <Uefi.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+
+#include <Protocol/RealTimeClock.h>
+#include <Protocol/EmbeddedExternalDevice.h>
+
+#include <Omap3530/Omap3530.h>
+#include <TPS65950.h>
+
+
+EMBEDDED_EXTERNAL_DEVICE   *gTPS65950;
+INT16                      TimeZone = EFI_UNSPECIFIED_TIMEZONE;
+
+/**
+  Returns the current time and date information, and the time-keeping capabilities
+  of the hardware platform.
+
+  @param  Time                  A pointer to storage to receive a snapshot of the current time.
+  @param  Capabilities          An optional pointer to a buffer to receive the real time clock
+                                device's capabilities.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER Time is NULL.
+  @retval EFI_DEVICE_ERROR      The time could not be retrieved due to hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+LibGetTime (
+  OUT EFI_TIME                *Time,
+  OUT EFI_TIME_CAPABILITIES   *Capabilities
+  )
+{
+  EFI_STATUS            Status;
+  UINT8                 Data;
+  EFI_TPL               OldTpl;
+
+  if (Time == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
+
+  /* Get time and date */
+  ZeroMem(Time, sizeof(EFI_TIME));
+
+  // Latch values
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, RTC_CTRL_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+  Data |= BIT6;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, RTC_CTRL_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+
+  // Read registers
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, YEARS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+  Time->Year = 2000 + ((Data >> 4) & 0xF) * 10 + (Data & 0xF);
+
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, MONTHS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+  Time->Month = ((Data >> 4) & 0x1) * 10 + (Data & 0xF);
+
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, DAYS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+  Time->Day = ((Data >> 4) & 0x3) * 10 + (Data & 0xF);
+
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, HOURS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+  Time->Hour = ((Data >> 4) & 0x3) * 10 + (Data & 0xF);
+
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, MINUTES_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+  Time->Minute = ((Data >> 4) & 0x7) * 10 + (Data & 0xF);
+
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, SECONDS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+  Time->Second = ((Data >> 4) & 0x7) * 10 + (Data & 0xF);
+
+  Time->TimeZone = TimeZone;
+  // TODO: check what to use here
+  Time->Daylight = EFI_TIME_ADJUST_DAYLIGHT;
+
+  // Set capabilities
+
+  // TODO: Set real capabilities
+  if (Capabilities != NULL) {
+    Capabilities->Resolution = 1;
+    Capabilities->Accuracy = 50000000;
+    Capabilities->SetsToZero = FALSE;
+  }
+
+EXIT:
+  gBS->RestoreTPL(OldTpl);
+
+  return (Status == EFI_SUCCESS) ? Status : EFI_DEVICE_ERROR;
+}
+
+/**
+  Sets the current local time and date information.
+
+  @param  Time                  A pointer to the current time.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+  @retval EFI_INVALID_PARAMETER A time field is out of range.
+  @retval EFI_DEVICE_ERROR      The time could not be set due due to hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+LibSetTime (
+  IN EFI_TIME                *Time
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Data;
+  UINT8      MonthDayCount[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+  EFI_TPL    OldTpl;
+
+  // Input validation according both to UEFI spec and hardware constraints
+  // UEFI spec says valid year range is 1900-9999 but TPS only supports 2000-2099
+  if ( (Time == NULL)
+    || (Time->Year < 2000 || Time->Year > 2099)
+    || (Time->Month < 1 || Time->Month > 12)
+    || (Time->Day < 1 || Time->Day > MonthDayCount[Time->Month])
+    || (Time->Hour > 23)
+    || (Time->Minute > 59)
+    || (Time->Second > 59)
+    || (Time->Nanosecond > 999999999)
+    || ((Time->TimeZone < -1440 || Time->TimeZone > 1440) && Time->TimeZone != 2047)
+  ) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
+
+  Data = Time->Year - 2000;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, YEARS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+
+  Data = ((Time->Month / 10) << 4) | (Time->Month % 10);
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, MONTHS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+
+  Data = ((Time->Day / 10) << 4) | (Time->Day % 10);
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, DAYS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+
+  Data = ((Time->Hour / 10) << 4) | (Time->Hour % 10);
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, HOURS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+
+  Data = ((Time->Minute / 10) << 4) | (Time->Minute % 10);
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, MINUTES_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+
+  Data = ((Time->Second / 10) << 4) | (Time->Second % 10);
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, SECONDS_REG), 1, &Data);
+  if (Status != EFI_SUCCESS) goto EXIT;
+
+  TimeZone = Time->TimeZone;
+
+EXIT:
+  gBS->RestoreTPL(OldTpl);
+
+  return (Status == EFI_SUCCESS) ? Status : EFI_DEVICE_ERROR;
+}
+
+/**
+  Returns the current wakeup alarm clock setting.
+
+  @param  Enabled               Indicates if the alarm is currently enabled or disabled.
+  @param  Pending               Indicates if the alarm signal is pending and requires acknowledgement.
+  @param  Time                  The current alarm setting.
+
+  @retval EFI_SUCCESS           The alarm settings were returned.
+  @retval EFI_INVALID_PARAMETER Any parameter is NULL.
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be retrieved due to a hardware error.
+
+**/
+EFI_STATUS
+EFIAPI
+LibGetWakeupTime (
+  OUT BOOLEAN     *Enabled,
+  OUT BOOLEAN     *Pending,
+  OUT EFI_TIME    *Time
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  Sets the system wakeup alarm clock time.
+
+  @param  Enabled               Enable or disable the wakeup alarm.
+  @param  Time                  If Enable is TRUE, the time to set the wakeup alarm for.
+
+  @retval EFI_SUCCESS           If Enable is TRUE, then the wakeup alarm was enabled. If
+                                Enable is FALSE, then the wakeup alarm was disabled.
+  @retval EFI_INVALID_PARAMETER A time field is out of range.
+  @retval EFI_DEVICE_ERROR      The wakeup time could not be set due to a hardware error.
+  @retval EFI_UNSUPPORTED       A wakeup timer is not supported on this platform.
+
+**/
+EFI_STATUS
+EFIAPI
+LibSetWakeupTime (
+  IN BOOLEAN      Enabled,
+  OUT EFI_TIME    *Time
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+/**
+  This is the declaration of an EFI image entry point. This can be the entry point to an application
+  written to this specification, an EFI boot service driver, or an EFI runtime driver.
+
+  @param  ImageHandle           Handle that identifies the loaded image.
+  @param  SystemTable           System Table for this image.
+
+  @retval EFI_SUCCESS           The operation completed successfully.
+
+**/
+EFI_STATUS
+EFIAPI
+LibRtcInitialize (
+  IN EFI_HANDLE                            ImageHandle,
+  IN EFI_SYSTEM_TABLE                      *SystemTable
+  )
+{
+  EFI_STATUS    Status;
+  EFI_HANDLE    Handle;
+  UINT8         Data;
+  EFI_TPL       OldTpl;
+
+  Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950);
+  ASSERT_EFI_ERROR(Status);
+
+  OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
+  Data = 1;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, RTC_CTRL_REG), 1, &Data);
+  ASSERT_EFI_ERROR(Status);
+  gBS->RestoreTPL(OldTpl);
+
+  // Setup the setters and getters
+  gRT->GetTime       = LibGetTime;
+  gRT->SetTime       = LibSetTime;
+  gRT->GetWakeupTime = LibGetWakeupTime;
+  gRT->SetWakeupTime = LibSetWakeupTime;
+
+  // Install the protocol
+  Handle = NULL;
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gEfiRealTimeClockArchProtocolGuid,  NULL,
+                  NULL
+                 );
+
+  return Status;
+}
+
+/**
+  Fixup internal data so that EFI can be call in virtual mode.
+  Call the passed in Child Notify event and convert any pointers in
+  lib to virtual mode.
+
+  @param[in]    Event   The Event that is being processed
+  @param[in]    Context Event Context
+**/
+VOID
+EFIAPI
+LibRtcVirtualNotifyEvent (
+  IN EFI_EVENT        Event,
+  IN VOID             *Context
+  )
+{
+  return;
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.inf b/Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.inf
new file mode 100644
index 0000000000..85c914796b
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.inf
@@ -0,0 +1,32 @@
+#  Copyright (c) 2011, ARM Limited. All rights reserved.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = RealTimeClockLib
+  FILE_GUID                      = EC1713DB-7DB5-4c99-8FE2-6F52F95A1132
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = RealTimeClockLib
+
+[Sources.common]
+  RealTimeClockLib.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  IoLib
+  UefiLib
+  DebugLib
+  PcdLib
+
+[Protocols]
+  gEmbeddedExternalDeviceProtocolGuid
+
+[depex]
+  gEmbeddedExternalDeviceProtocolGuid
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.c b/Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.c
new file mode 100644
index 0000000000..2b94f0bfc2
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.c
@@ -0,0 +1,208 @@
+/** @file
+  Serial I/O Port library functions with no library constructor/destructor
+
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Base.h>
+#include <Library/DebugLib.h>
+#include <Library/SerialPortLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/OmapLib.h>
+#include <Omap3530/Omap3530.h>
+
+/*
+
+  Programmed hardware of Serial port.
+
+  @return    Always return EFI_UNSUPPORTED.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortInitialize (
+  VOID
+  )
+{
+  // assume assembly code at reset vector has setup UART
+  return RETURN_SUCCESS;
+}
+
+/**
+  Write data to serial device.
+
+  @param  Buffer           Point of data buffer which need to be writed.
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+  @retval 0                Write data failed.
+  @retval !0               Actual number of bytes writed to serial device.
+
+**/
+UINTN
+EFIAPI
+SerialPortWrite (
+  IN UINT8     *Buffer,
+  IN UINTN     NumberOfBytes
+)
+{
+  UINT32  LSR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_LSR_REG;
+  UINT32  THR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_THR_REG;
+  UINTN   Count;
+
+  for (Count = 0; Count < NumberOfBytes; Count++, Buffer++) {
+    while ((MmioRead8(LSR) & UART_LSR_TX_FIFO_E_MASK) == UART_LSR_TX_FIFO_E_NOT_EMPTY);
+    MmioWrite8(THR, *Buffer);
+  }
+
+  return NumberOfBytes;
+}
+
+
+/**
+  Read data from serial device and save the datas in buffer.
+
+  @param  Buffer           Point of data buffer which need to be writed.
+  @param  NumberOfBytes    Number of output bytes which are cached in Buffer.
+
+  @retval 0                Read data failed.
+  @retval !0               Aactual number of bytes read from serial device.
+
+**/
+UINTN
+EFIAPI
+SerialPortRead (
+  OUT UINT8     *Buffer,
+  IN  UINTN     NumberOfBytes
+)
+{
+  UINT32  LSR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_LSR_REG;
+  UINT32  RBR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_RBR_REG;
+  UINTN   Count;
+
+  for (Count = 0; Count < NumberOfBytes; Count++, Buffer++) {
+    while ((MmioRead8(LSR) & UART_LSR_RX_FIFO_E_MASK) == UART_LSR_RX_FIFO_E_EMPTY);
+    *Buffer = MmioRead8(RBR);
+  }
+
+  return NumberOfBytes;
+}
+
+
+/**
+  Check to see if any data is avaiable to be read from the debug device.
+
+  @retval EFI_SUCCESS       At least one byte of data is avaiable to be read
+  @retval EFI_NOT_READY     No data is avaiable to be read
+  @retval EFI_DEVICE_ERROR  The serial device is not functioning properly
+
+**/
+BOOLEAN
+EFIAPI
+SerialPortPoll (
+  VOID
+  )
+{
+  UINT32 LSR = UartBase(PcdGet32(PcdOmap35xxConsoleUart)) + UART_LSR_REG;
+
+  if ((MmioRead8(LSR) & UART_LSR_RX_FIFO_E_MASK) == UART_LSR_RX_FIFO_E_NOT_EMPTY) {
+    return TRUE;
+  } else {
+    return FALSE;
+  }
+}
+
+/**
+  Sets the control bits on a serial device.
+
+  @param[in] Control            Sets the bits of Control that are settable.
+
+  @retval RETURN_SUCCESS        The new control bits were set on the serial device.
+  @retval RETURN_UNSUPPORTED    The serial device does not support this operation.
+  @retval RETURN_DEVICE_ERROR   The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetControl (
+  IN UINT32 Control
+  )
+{
+  return RETURN_UNSUPPORTED;
+}
+
+/**
+  Retrieve the status of the control bits on a serial device.
+
+  @param[out] Control           A pointer to return the current control signals from the serial device.
+
+  @retval RETURN_SUCCESS        The control bits were read from the serial device.
+  @retval RETURN_UNSUPPORTED    The serial device does not support this operation.
+  @retval RETURN_DEVICE_ERROR   The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortGetControl (
+  OUT UINT32 *Control
+  )
+{
+  *Control = 0;
+  if (!SerialPortPoll ()) {
+    *Control = EFI_SERIAL_INPUT_BUFFER_EMPTY;
+  }
+  return RETURN_SUCCESS;
+}
+
+/**
+  Sets the baud rate, receive FIFO depth, transmit/receice time out, parity,
+  data bits, and stop bits on a serial device.
+
+  @param BaudRate           The requested baud rate. A BaudRate value of 0 will use the
+                            device's default interface speed.
+                            On output, the value actually set.
+  @param ReveiveFifoDepth   The requested depth of the FIFO on the receive side of the
+                            serial interface. A ReceiveFifoDepth value of 0 will use
+                            the device's default FIFO depth.
+                            On output, the value actually set.
+  @param Timeout            The requested time out for a single character in microseconds.
+                            This timeout applies to both the transmit and receive side of the
+                            interface. A Timeout value of 0 will use the device's default time
+                            out value.
+                            On output, the value actually set.
+  @param Parity             The type of parity to use on this serial device. A Parity value of
+                            DefaultParity will use the device's default parity value.
+                            On output, the value actually set.
+  @param DataBits           The number of data bits to use on the serial device. A DataBits
+                            vaule of 0 will use the device's default data bit setting.
+                            On output, the value actually set.
+  @param StopBits           The number of stop bits to use on this serial device. A StopBits
+                            value of DefaultStopBits will use the device's default number of
+                            stop bits.
+                            On output, the value actually set.
+
+  @retval RETURN_SUCCESS            The new attributes were set on the serial device.
+  @retval RETURN_UNSUPPORTED        The serial device does not support this operation.
+  @retval RETURN_INVALID_PARAMETER  One or more of the attributes has an unsupported value.
+  @retval RETURN_DEVICE_ERROR       The serial device is not functioning correctly.
+
+**/
+RETURN_STATUS
+EFIAPI
+SerialPortSetAttributes (
+  IN OUT UINT64             *BaudRate,
+  IN OUT UINT32             *ReceiveFifoDepth,
+  IN OUT UINT32             *Timeout,
+  IN OUT EFI_PARITY_TYPE    *Parity,
+  IN OUT UINT8              *DataBits,
+  IN OUT EFI_STOP_BITS_TYPE *StopBits
+  )
+{
+  return RETURN_UNSUPPORTED;
+}
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.inf b/Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.inf
new file mode 100644
index 0000000000..086ed3c2a9
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Library/SerialPortLib/SerialPortLib.inf
@@ -0,0 +1,40 @@
+#/** @file
+# EDK Serial port lib
+#
+#  Copyright (c) 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BeagleBoardSerialPortLib
+  FILE_GUID                      = 97546cbd-c0ff-4c48-ab0b-e4f58862acd3
+  MODULE_TYPE                    = BASE
+  VERSION_STRING                 = 1.0
+  LIBRARY_CLASS                  = SerialPortLib
+
+
+#
+#  VALID_ARCHITECTURES           = ARM IA32 X64 EBC
+#
+
+[Sources.common]
+  SerialPortLib.c
+
+[LibraryClasses]
+  DebugLib
+  IoLib
+  OmapLib
+
+[Packages]
+  EmbeddedPkg/EmbeddedPkg.dec
+  MdePkg/MdePkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[FixedPcd]
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxConsoleUart
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.c b/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.c
new file mode 100644
index 0000000000..099e37c469
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.c
@@ -0,0 +1,1492 @@
+/** @file
+  MMC/SD Card driver for OMAP 35xx (SDIO not supported)
+
+  This driver always produces a BlockIo protocol but it starts off with no Media
+  present. A TimerCallBack detects when media is inserted or removed and after
+  a media change event a call to BlockIo ReadBlocks/WriteBlocks will cause the
+  media to be detected (or removed) and the BlockIo Media structure will get
+  updated. No MMC/SD Card harward registers are updated until the first BlockIo
+  ReadBlocks/WriteBlocks after media has been insterted (booting with a card
+  plugged in counts as an insertion event).
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include "MMCHS.h"
+
+EFI_BLOCK_IO_MEDIA gMMCHSMedia = {
+  SIGNATURE_32('s','d','i','o'),            // MediaId
+  TRUE,                                     // RemovableMedia
+  FALSE,                                    // MediaPresent
+  FALSE,                                    // LogicalPartition
+  FALSE,                                    // ReadOnly
+  FALSE,                                    // WriteCaching
+  512,                                      // BlockSize
+  4,                                        // IoAlign
+  0,                                        // Pad
+  0                                         // LastBlock
+};
+
+typedef struct {
+  VENDOR_DEVICE_PATH  Mmc;
+  EFI_DEVICE_PATH     End;
+} MMCHS_DEVICE_PATH;
+
+MMCHS_DEVICE_PATH gMmcHsDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      {
+        (UINT8)(sizeof(VENDOR_DEVICE_PATH)),
+        (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8),
+      },
+    },
+    { 0xb615f1f5, 0x5088, 0x43cd, { 0x80, 0x9c, 0xa1, 0x6e, 0x52, 0x48, 0x7d, 0x00 } },
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
+  }
+};
+
+CARD_INFO                  gCardInfo;
+EMBEDDED_EXTERNAL_DEVICE   *gTPS65950;
+EFI_EVENT                  gTimerEvent;
+BOOLEAN                    gMediaChange = FALSE;
+
+//
+// Internal Functions
+//
+
+
+VOID
+ParseCardCIDData (
+  UINT32 Response0,
+  UINT32 Response1,
+  UINT32 Response2,
+  UINT32 Response3
+  )
+{
+  gCardInfo.CIDData.MDT = ((Response0 >> 8) & 0xFFF);
+  gCardInfo.CIDData.PSN = (((Response0 >> 24) & 0xFF) | ((Response1 & 0xFFFFFF) << 8));
+  gCardInfo.CIDData.PRV = ((Response1 >> 24) & 0xFF);
+  gCardInfo.CIDData.PNM[4] = ((Response2) & 0xFF);
+  gCardInfo.CIDData.PNM[3] = ((Response2 >> 8) & 0xFF);
+  gCardInfo.CIDData.PNM[2] = ((Response2 >> 16) & 0xFF);
+  gCardInfo.CIDData.PNM[1] = ((Response2 >> 24) & 0xFF);
+  gCardInfo.CIDData.PNM[0] = ((Response3) & 0xFF);
+  gCardInfo.CIDData.OID = ((Response3 >> 8) & 0xFFFF);
+  gCardInfo.CIDData.MID = ((Response3 >> 24) & 0xFF);
+}
+
+
+VOID
+UpdateMMCHSClkFrequency (
+  UINTN NewCLKD
+  )
+{
+  //Set Clock enable to 0x0 to not provide the clock to the card
+  MmioAnd32 (MMCHS_SYSCTL, ~CEN);
+
+  //Set new clock frequency.
+  MmioAndThenOr32 (MMCHS_SYSCTL, ~CLKD_MASK, NewCLKD << 6);
+
+  //Poll till Internal Clock Stable
+  while ((MmioRead32 (MMCHS_SYSCTL) & ICS_MASK) != ICS);
+
+  //Set Clock enable to 0x1 to provide the clock to the card
+  MmioOr32 (MMCHS_SYSCTL, CEN);
+}
+
+
+EFI_STATUS
+SendCmd (
+  UINTN Cmd,
+  UINTN CmdInterruptEnableVal,
+  UINTN CmdArgument
+  )
+{
+  UINTN MmcStatus;
+  UINTN RetryCount = 0;
+
+  //Check if command line is in use or not. Poll till command line is available.
+  while ((MmioRead32 (MMCHS_PSTATE) & DATI_MASK) == DATI_NOT_ALLOWED);
+
+  //Provide the block size.
+  MmioWrite32 (MMCHS_BLK, BLEN_512BYTES);
+
+  //Setting Data timeout counter value to max value.
+  MmioAndThenOr32 (MMCHS_SYSCTL, ~DTO_MASK, DTO_VAL);
+
+  //Clear Status register.
+  MmioWrite32 (MMCHS_STAT, 0xFFFFFFFF);
+
+  //Set command argument register
+  MmioWrite32 (MMCHS_ARG, CmdArgument);
+
+  //Enable interrupt enable events to occur
+  MmioWrite32 (MMCHS_IE, CmdInterruptEnableVal);
+
+  //Send a command
+  MmioWrite32 (MMCHS_CMD, Cmd);
+
+  //Check for the command status.
+  while (RetryCount < MAX_RETRY_COUNT) {
+    do {
+      MmcStatus = MmioRead32 (MMCHS_STAT);
+    } while (MmcStatus == 0);
+
+    //Read status of command response
+    if ((MmcStatus & ERRI) != 0) {
+
+      //Perform soft-reset for mmci_cmd line.
+      MmioOr32 (MMCHS_SYSCTL, SRC);
+      while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
+
+      DEBUG ((EFI_D_INFO, "MmcStatus: %x\n", MmcStatus));
+      return EFI_DEVICE_ERROR;
+    }
+
+    //Check if command is completed.
+    if ((MmcStatus & CC) == CC) {
+      MmioWrite32 (MMCHS_STAT, CC);
+      break;
+    }
+
+    RetryCount++;
+  }
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+VOID
+GetBlockInformation (
+  UINTN *BlockSize,
+  UINTN *NumBlocks
+  )
+{
+  CSD_SDV2 *CsdSDV2Data;
+  UINTN    CardSize;
+
+  if (gCardInfo.CardType == SD_CARD_2_HIGH) {
+    CsdSDV2Data = (CSD_SDV2 *)&gCardInfo.CSDData;
+
+    //Populate BlockSize.
+    *BlockSize = (0x1UL << CsdSDV2Data->READ_BL_LEN);
+
+    //Calculate Total number of blocks.
+    CardSize = CsdSDV2Data->C_SIZELow16 | (CsdSDV2Data->C_SIZEHigh6 << 2);
+    *NumBlocks = ((CardSize + 1) * 1024);
+  } else {
+    //Populate BlockSize.
+    *BlockSize = (0x1UL << gCardInfo.CSDData.READ_BL_LEN);
+
+    //Calculate Total number of blocks.
+    CardSize = gCardInfo.CSDData.C_SIZELow2 | (gCardInfo.CSDData.C_SIZEHigh10 << 2);
+    *NumBlocks = (CardSize + 1) * (1 << (gCardInfo.CSDData.C_SIZE_MULT + 2));
+  }
+
+  //For >=2G card, BlockSize may be 1K, but the transfer size is 512 bytes.
+  if (*BlockSize > 512) {
+    *NumBlocks = MultU64x32(*NumBlocks, *BlockSize/2);
+    *BlockSize = 512;
+  }
+
+  DEBUG ((EFI_D_INFO, "Card type: %x, BlockSize: %x, NumBlocks: %x\n", gCardInfo.CardType, *BlockSize, *NumBlocks));
+}
+
+
+VOID
+CalculateCardCLKD (
+  UINTN *ClockFrequencySelect
+  )
+{
+  UINT8    MaxDataTransferRate;
+  UINTN    TransferRateValue = 0;
+  UINTN    TimeValue = 0 ;
+  UINTN    Frequency = 0;
+
+  MaxDataTransferRate = gCardInfo.CSDData.TRAN_SPEED;
+
+  // For SD Cards  we would need to send CMD6 to set
+  // speeds abouve 25MHz. High Speed mode 50 MHz and up
+
+  //Calculate Transfer rate unit (Bits 2:0 of TRAN_SPEED)
+  switch (MaxDataTransferRate & 0x7) {
+    case 0:
+      TransferRateValue = 100 * 1000;
+      break;
+
+    case 1:
+      TransferRateValue = 1 * 1000 * 1000;
+      break;
+
+    case 2:
+      TransferRateValue = 10 * 1000 * 1000;
+      break;
+
+    case 3:
+      TransferRateValue = 100 * 1000 * 1000;
+      break;
+
+    default:
+      DEBUG((EFI_D_ERROR, "Invalid parameter.\n"));
+      ASSERT(FALSE);
+  }
+
+  //Calculate Time value (Bits 6:3 of TRAN_SPEED)
+  switch ((MaxDataTransferRate >> 3) & 0xF) {
+    case 1:
+      TimeValue = 10;
+      break;
+
+    case 2:
+      TimeValue = 12;
+      break;
+
+    case 3:
+      TimeValue = 13;
+      break;
+
+    case 4:
+      TimeValue = 15;
+      break;
+
+    case 5:
+      TimeValue = 20;
+      break;
+
+    case 6:
+      TimeValue = 25;
+      break;
+
+    case 7:
+      TimeValue = 30;
+      break;
+
+    case 8:
+      TimeValue = 35;
+      break;
+
+    case 9:
+      TimeValue = 40;
+      break;
+
+    case 10:
+      TimeValue = 45;
+      break;
+
+    case 11:
+      TimeValue = 50;
+      break;
+
+    case 12:
+      TimeValue = 55;
+      break;
+
+    case 13:
+      TimeValue = 60;
+      break;
+
+    case 14:
+      TimeValue = 70;
+      break;
+
+    case 15:
+      TimeValue = 80;
+      break;
+
+    default:
+      DEBUG((EFI_D_ERROR, "Invalid parameter.\n"));
+      ASSERT(FALSE);
+  }
+
+  Frequency = TransferRateValue * TimeValue/10;
+
+  //Calculate Clock divider value to program in MMCHS_SYSCTL[CLKD] field.
+  *ClockFrequencySelect = ((MMC_REFERENCE_CLK/Frequency) + 1);
+
+  DEBUG ((EFI_D_INFO, "MaxDataTransferRate: 0x%x, Frequency: %d KHz, ClockFrequencySelect: %x\n", MaxDataTransferRate, Frequency/1000, *ClockFrequencySelect));
+}
+
+
+VOID
+GetCardConfigurationData (
+  VOID
+  )
+{
+  UINTN  BlockSize;
+  UINTN  NumBlocks;
+  UINTN  ClockFrequencySelect;
+
+  //Calculate BlockSize and Total number of blocks in the detected card.
+  GetBlockInformation(&BlockSize, &NumBlocks);
+  gCardInfo.BlockSize = BlockSize;
+  gCardInfo.NumBlocks = NumBlocks;
+
+  //Calculate Card clock divider value.
+  CalculateCardCLKD(&ClockFrequencySelect);
+  gCardInfo.ClockFrequencySelect = ClockFrequencySelect;
+}
+
+
+EFI_STATUS
+InitializeMMCHS (
+  VOID
+  )
+{
+  UINT8      Data = 0;
+  EFI_STATUS Status;
+
+  //Select Device group to belong to P1 device group in Power IC.
+  Data = DEV_GRP_P1;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VMMC1_DEV_GRP), 1, &Data);
+  ASSERT_EFI_ERROR(Status);
+
+  //Configure voltage regulator for MMC1 in Power IC to output 3.0 voltage.
+  Data = VSEL_3_00V;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VMMC1_DEDICATED_REG), 1, &Data);
+  ASSERT_EFI_ERROR(Status);
+
+  //After ramping up voltage, set VDDS stable bit to indicate that voltage level is stable.
+  MmioOr32 (CONTROL_PBIAS_LITE, (PBIASLITEVMODE0 | PBIASLITEPWRDNZ0 | PBIASSPEEDCTRL0 | PBIASLITEVMODE1 | PBIASLITEWRDNZ1));
+
+  // Enable WP GPIO
+  MmioAndThenOr32 (GPIO1_BASE + GPIO_OE, ~BIT23, BIT23);
+
+  // Enable Card Detect
+  Data = CARD_DETECT_ENABLE;
+  gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, TPS65950_GPIO_CTRL), 1, &Data);
+
+
+  return Status;
+}
+
+
+EFI_STATUS
+PerformCardIdenfication (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+  UINTN      CmdArgument = 0;
+  UINTN      Response = 0;
+  UINTN      RetryCount = 0;
+  BOOLEAN    SDCmd8Supported = FALSE;
+
+  //Enable interrupts.
+  MmioWrite32 (MMCHS_IE, (BADA_EN | CERR_EN | DEB_EN | DCRC_EN | DTO_EN | CIE_EN |
+    CEB_EN | CCRC_EN | CTO_EN | BRR_EN | BWR_EN | TC_EN | CC_EN));
+
+  //Controller INIT procedure start.
+  MmioOr32 (MMCHS_CON, INIT);
+  MmioWrite32 (MMCHS_CMD, 0x00000000);
+  while (!(MmioRead32 (MMCHS_STAT) & CC));
+
+  //Wait for 1 ms
+  gBS->Stall(1000);
+
+  //Set CC bit to 0x1 to clear the flag
+  MmioOr32 (MMCHS_STAT, CC);
+
+  //Retry INIT procedure.
+  MmioWrite32 (MMCHS_CMD, 0x00000000);
+  while (!(MmioRead32 (MMCHS_STAT) & CC));
+
+  //End initialization sequence
+  MmioAnd32 (MMCHS_CON, ~INIT);
+
+  MmioOr32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_ON));
+
+  //Change clock frequency to 400KHz to fit protocol
+  UpdateMMCHSClkFrequency(CLKD_400KHZ);
+
+  MmioOr32 (MMCHS_CON, OD);
+
+  //Send CMD0 command.
+  Status = SendCmd (CMD0, CMD0_INT_EN, CmdArgument);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "Cmd0 fails.\n"));
+    return Status;
+  }
+
+  DEBUG ((EFI_D_INFO, "CMD0 response: %x\n", MmioRead32 (MMCHS_RSP10)));
+
+  //Send CMD5 command.
+  Status = SendCmd (CMD5, CMD5_INT_EN, CmdArgument);
+  if (Status == EFI_SUCCESS) {
+    DEBUG ((EFI_D_ERROR, "CMD5 Success. SDIO card. Follow SDIO card specification.\n"));
+    DEBUG ((EFI_D_INFO, "CMD5 response: %x\n", MmioRead32 (MMCHS_RSP10)));
+    //NOTE: Returning unsupported error for now. Need to implement SDIO specification.
+    return EFI_UNSUPPORTED;
+  } else {
+    DEBUG ((EFI_D_INFO, "CMD5 fails. Not an SDIO card.\n"));
+  }
+
+  MmioOr32 (MMCHS_SYSCTL, SRC);
+  gBS->Stall(1000);
+  while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
+
+  //Send CMD8 command. (New v2.00 command for Voltage check)
+  //Only 2.7V - 3.6V is supported for SD2.0, only SD 2.0 card can pass.
+  //MMC & SD1.1 card will fail this command.
+  CmdArgument = CMD8_ARG;
+  Status = SendCmd (CMD8, CMD8_INT_EN, CmdArgument);
+  if (Status == EFI_SUCCESS) {
+    Response = MmioRead32 (MMCHS_RSP10);
+    DEBUG ((EFI_D_INFO, "CMD8 success. CMD8 response: %x\n", Response));
+    if (Response != CmdArgument) {
+      return EFI_DEVICE_ERROR;
+    }
+    DEBUG ((EFI_D_INFO, "Card is SD2.0\n"));
+    SDCmd8Supported = TRUE; //Supports high capacity.
+  } else {
+    DEBUG ((EFI_D_INFO, "CMD8 fails. Not an SD2.0 card.\n"));
+  }
+
+  MmioOr32 (MMCHS_SYSCTL, SRC);
+  gBS->Stall(1000);
+  while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
+
+  //Poll till card is busy
+  while (RetryCount < MAX_RETRY_COUNT) {
+    //Send CMD55 command.
+    CmdArgument = 0;
+    Status = SendCmd (CMD55, CMD55_INT_EN, CmdArgument);
+    if (Status == EFI_SUCCESS) {
+      DEBUG ((EFI_D_INFO, "CMD55 success. CMD55 response: %x\n", MmioRead32 (MMCHS_RSP10)));
+      gCardInfo.CardType = SD_CARD;
+    } else {
+      DEBUG ((EFI_D_INFO, "CMD55 fails.\n"));
+      gCardInfo.CardType = MMC_CARD;
+    }
+
+    //Send appropriate command for the card type which got detected.
+    if (gCardInfo.CardType == SD_CARD) {
+      CmdArgument = ((UINTN *) &(gCardInfo.OCRData))[0];
+
+      //Set HCS bit.
+      if (SDCmd8Supported) {
+        CmdArgument |= HCS;
+      }
+
+      Status = SendCmd (ACMD41, ACMD41_INT_EN, CmdArgument);
+      if (EFI_ERROR(Status)) {
+        DEBUG ((EFI_D_INFO, "ACMD41 fails.\n"));
+        return Status;
+      }
+      ((UINT32 *) &(gCardInfo.OCRData))[0] = MmioRead32 (MMCHS_RSP10);
+      DEBUG ((EFI_D_INFO, "SD card detected. ACMD41 OCR: %x\n", ((UINT32 *) &(gCardInfo.OCRData))[0]));
+    } else if (gCardInfo.CardType == MMC_CARD) {
+      CmdArgument = 0;
+      Status = SendCmd (CMD1, CMD1_INT_EN, CmdArgument);
+      if (EFI_ERROR(Status)) {
+        DEBUG ((EFI_D_INFO, "CMD1 fails.\n"));
+        return Status;
+      }
+      Response = MmioRead32 (MMCHS_RSP10);
+      DEBUG ((EFI_D_INFO, "MMC card detected.. CMD1 response: %x\n", Response));
+
+      //NOTE: For now, I am skipping this since I only have an SD card.
+      //Compare card OCR and host OCR (Section 22.6.1.3.2.4)
+      return EFI_UNSUPPORTED; //For now, MMC is not supported.
+    }
+
+    //Poll the card until it is out of its power-up sequence.
+    if (gCardInfo.OCRData.Busy == 1) {
+
+      if (SDCmd8Supported) {
+        gCardInfo.CardType = SD_CARD_2;
+      }
+
+      //Card is ready. Check CCS (Card capacity status) bit (bit#30).
+      //SD 2.0 standard card will response with CCS 0, SD high capacity card will respond with CCS 1.
+      if (gCardInfo.OCRData.AccessMode & BIT1) {
+        gCardInfo.CardType = SD_CARD_2_HIGH;
+        DEBUG ((EFI_D_INFO, "High capacity card.\n"));
+      } else {
+        DEBUG ((EFI_D_INFO, "Standard capacity card.\n"));
+      }
+
+      break;
+    }
+
+    gBS->Stall(1000);
+    RetryCount++;
+  }
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    DEBUG ((EFI_D_ERROR, "Timeout error. RetryCount: %d\n", RetryCount));
+    return EFI_TIMEOUT;
+  }
+
+  //Read CID data.
+  CmdArgument = 0;
+  Status = SendCmd (CMD2, CMD2_INT_EN, CmdArgument);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "CMD2 fails. Status: %x\n", Status));
+    return Status;
+  }
+
+  DEBUG ((EFI_D_INFO, "CMD2 response: %x %x %x %x\n", MmioRead32 (MMCHS_RSP10), MmioRead32 (MMCHS_RSP32), MmioRead32 (MMCHS_RSP54), MmioRead32 (MMCHS_RSP76)));
+
+  //Parse CID register data.
+  ParseCardCIDData(MmioRead32 (MMCHS_RSP10), MmioRead32 (MMCHS_RSP32), MmioRead32 (MMCHS_RSP54), MmioRead32 (MMCHS_RSP76));
+
+  //Read RCA
+  CmdArgument = 0;
+  Status = SendCmd (CMD3, CMD3_INT_EN, CmdArgument);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "CMD3 fails. Status: %x\n", Status));
+    return Status;
+  }
+
+  //Set RCA for the detected card. RCA is CMD3 response.
+  gCardInfo.RCA = (MmioRead32 (MMCHS_RSP10) >> 16);
+  DEBUG ((EFI_D_INFO, "CMD3 response: RCA %x\n", gCardInfo.RCA));
+
+  //MMC Bus setting change after card identification.
+  MmioAnd32 (MMCHS_CON, ~OD);
+  MmioOr32 (MMCHS_HCTL, SDVS_3_0_V);
+  UpdateMMCHSClkFrequency(CLKD_400KHZ); //Set the clock frequency to 400KHz.
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+GetCardSpecificData (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+  UINTN      CmdArgument;
+
+  //Send CMD9 to retrieve CSD.
+  CmdArgument = gCardInfo.RCA << 16;
+  Status = SendCmd (CMD9, CMD9_INT_EN, CmdArgument);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "CMD9 fails. Status: %x\n", Status));
+    return Status;
+  }
+
+  //Populate 128-bit CSD register data.
+  ((UINT32 *)&(gCardInfo.CSDData))[0] = MmioRead32 (MMCHS_RSP10);
+  ((UINT32 *)&(gCardInfo.CSDData))[1] = MmioRead32 (MMCHS_RSP32);
+  ((UINT32 *)&(gCardInfo.CSDData))[2] = MmioRead32 (MMCHS_RSP54);
+  ((UINT32 *)&(gCardInfo.CSDData))[3] = MmioRead32 (MMCHS_RSP76);
+
+  DEBUG ((EFI_D_INFO, "CMD9 response: %x %x %x %x\n", MmioRead32 (MMCHS_RSP10), MmioRead32 (MMCHS_RSP32), MmioRead32 (MMCHS_RSP54), MmioRead32 (MMCHS_RSP76)));
+
+  //Calculate total number of blocks and max. data transfer rate supported by the detected card.
+  GetCardConfigurationData();
+
+  return Status;
+}
+
+
+EFI_STATUS
+PerformCardConfiguration (
+  VOID
+  )
+{
+  UINTN      CmdArgument = 0;
+  EFI_STATUS Status;
+
+  //Send CMD7
+  CmdArgument = gCardInfo.RCA << 16;
+  Status = SendCmd (CMD7, CMD7_INT_EN, CmdArgument);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "CMD7 fails. Status: %x\n", Status));
+    return Status;
+  }
+
+  if ((gCardInfo.CardType != UNKNOWN_CARD) && (gCardInfo.CardType != MMC_CARD)) {
+    // We could read SCR register, but SD Card Phys spec stats any SD Card shall
+    // set SCR.SD_BUS_WIDTHS to support 4-bit mode, so why bother?
+
+    // Send ACMD6 (application specific commands must be prefixed with CMD55)
+    Status = SendCmd (CMD55, CMD55_INT_EN, CmdArgument);
+    if (!EFI_ERROR (Status)) {
+      // set device into 4-bit data bus mode
+      Status = SendCmd (ACMD6, ACMD6_INT_EN, 0x2);
+      if (!EFI_ERROR (Status)) {
+        // Set host controler into 4-bit mode
+        MmioOr32 (MMCHS_HCTL, DTW_4_BIT);
+        DEBUG ((EFI_D_INFO, "SD Memory Card set to 4-bit mode\n"));
+      }
+    }
+  }
+
+  //Send CMD16 to set the block length
+  CmdArgument = gCardInfo.BlockSize;
+  Status = SendCmd (CMD16, CMD16_INT_EN, CmdArgument);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "CMD16 fails. Status: %x\n", Status));
+    return Status;
+  }
+
+  //Change MMCHS clock frequency to what detected card can support.
+  UpdateMMCHSClkFrequency(gCardInfo.ClockFrequencySelect);
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+ReadBlockData (
+  IN  EFI_BLOCK_IO_PROTOCOL       *This,
+  OUT VOID                        *Buffer
+  )
+{
+  UINTN MmcStatus;
+  UINTN *DataBuffer = Buffer;
+  UINTN DataSize = This->Media->BlockSize/4;
+  UINTN Count;
+  UINTN RetryCount = 0;
+
+  //Check controller status to make sure there is no error.
+  while (RetryCount < MAX_RETRY_COUNT) {
+    do {
+      //Read Status.
+      MmcStatus = MmioRead32 (MMCHS_STAT);
+    } while(MmcStatus == 0);
+
+    //Check if Buffer read ready (BRR) bit is set?
+    if (MmcStatus & BRR) {
+
+      //Clear BRR bit
+      MmioOr32 (MMCHS_STAT, BRR);
+
+      //Read block worth of data.
+      for (Count = 0; Count < DataSize; Count++) {
+        *DataBuffer++ = MmioRead32 (MMCHS_DATA);
+      }
+      break;
+    }
+    RetryCount++;
+  }
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+WriteBlockData (
+  IN  EFI_BLOCK_IO_PROTOCOL       *This,
+  OUT VOID                        *Buffer
+  )
+{
+  UINTN MmcStatus;
+  UINTN *DataBuffer = Buffer;
+  UINTN DataSize = This->Media->BlockSize/4;
+  UINTN Count;
+  UINTN RetryCount = 0;
+
+  //Check controller status to make sure there is no error.
+  while (RetryCount < MAX_RETRY_COUNT) {
+    do {
+      //Read Status.
+      MmcStatus = MmioRead32 (MMCHS_STAT);
+    } while(MmcStatus == 0);
+
+    //Check if Buffer write ready (BWR) bit is set?
+    if (MmcStatus & BWR) {
+
+      //Clear BWR bit
+      MmioOr32 (MMCHS_STAT, BWR);
+
+      //Write block worth of data.
+      for (Count = 0; Count < DataSize; Count++) {
+        MmioWrite32 (MMCHS_DATA, *DataBuffer++);
+      }
+
+      break;
+    }
+    RetryCount++;
+  }
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+DmaBlocks (
+  IN EFI_BLOCK_IO_PROTOCOL        *This,
+  IN  UINTN                       Lba,
+  IN OUT VOID                     *Buffer,
+  IN  UINTN                       BlockCount,
+  IN  OPERATION_TYPE              OperationType
+  )
+{
+  EFI_STATUS            Status;
+  UINTN                 DmaSize = 0;
+  UINTN                 Cmd = 0;
+  UINTN                 CmdInterruptEnable;
+  UINTN                 CmdArgument;
+  VOID                  *BufferMap;
+  EFI_PHYSICAL_ADDRESS  BufferAddress;
+  OMAP_DMA4             Dma4;
+  DMA_MAP_OPERATION     DmaOperation;
+  EFI_STATUS            MmcStatus;
+  UINTN                 RetryCount = 0;
+
+CpuDeadLoop ();
+  // Map passed in buffer for DMA xfer
+  DmaSize = BlockCount * This->Media->BlockSize;
+  Status = DmaMap (DmaOperation, Buffer, &DmaSize, &BufferAddress, &BufferMap);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ZeroMem (&DmaOperation, sizeof (DMA_MAP_OPERATION));
+
+
+  Dma4.DataType = 2;                      // DMA4_CSDPi[1:0]   32-bit elements from MMCHS_DATA
+
+  Dma4.SourceEndiansim = 0;               // DMA4_CSDPi[21]
+
+  Dma4.DestinationEndianism = 0;          // DMA4_CSDPi[19]
+
+  Dma4.SourcePacked = 0;                  // DMA4_CSDPi[6]
+
+  Dma4.DestinationPacked = 0;             // DMA4_CSDPi[13]
+
+  Dma4.NumberOfElementPerFrame = This->Media->BlockSize/4; // DMA4_CENi  (TRM 4K is optimum value)
+
+  Dma4.NumberOfFramePerTransferBlock = BlockCount;         // DMA4_CFNi
+
+  Dma4.ReadPriority = 0;                  // DMA4_CCRi[6]      Low priority read
+
+  Dma4.WritePriority = 0;                 // DMA4_CCRi[23]     Prefetech disabled
+
+
+  //Populate the command information based on the operation type.
+  if (OperationType == READ) {
+    Cmd = CMD18; //Multiple block read
+    CmdInterruptEnable = CMD18_INT_EN;
+    DmaOperation = MapOperationBusMasterCommonBuffer;
+
+    Dma4.ReadPortAccessType =0 ;            // DMA4_CSDPi[8:7]   Can not burst MMCHS_DATA reg
+
+    Dma4.WritePortAccessType = 3;           // DMA4_CSDPi[15:14] Memory burst 16x32
+
+    Dma4.WriteMode = 1;                     // DMA4_CSDPi[17:16] Write posted
+
+
+
+    Dma4.SourceStartAddress = MMCHS_DATA;                   // DMA4_CSSAi
+
+    Dma4.DestinationStartAddress = (UINT32)BufferAddress;   // DMA4_CDSAi
+
+    Dma4.SourceElementIndex = 1;                            // DMA4_CSEi
+
+    Dma4.SourceFrameIndex = 0x200;                          // DMA4_CSFi
+
+    Dma4.DestinationElementIndex = 1;                       // DMA4_CDEi
+
+    Dma4.DestinationFrameIndex = 0;                         // DMA4_CDFi
+
+
+
+    Dma4.ReadPortAccessMode = 0;            // DMA4_CCRi[13:12]  Always read MMCHS_DATA
+
+    Dma4.WritePortAccessMode = 1;           // DMA4_CCRi[15:14]  Post increment memory address
+
+    Dma4.ReadRequestNumber = 0x1e;          // DMA4_CCRi[4:0]    Syncro with MMCA_DMA_RX (61)
+
+    Dma4.WriteRequestNumber = 1;            // DMA4_CCRi[20:19]  Syncro upper 0x3e == 62 (one based)
+
+  } else if (OperationType == WRITE) {
+    Cmd = CMD25; //Multiple block write
+    CmdInterruptEnable = CMD25_INT_EN;
+    DmaOperation = MapOperationBusMasterRead;
+
+    Dma4.ReadPortAccessType = 3;            // DMA4_CSDPi[8:7]   Memory burst 16x32
+
+    Dma4.WritePortAccessType = 0;           // DMA4_CSDPi[15:14] Can not burst MMCHS_DATA reg
+
+    Dma4.WriteMode = 1;                     // DMA4_CSDPi[17:16] Write posted ???
+
+
+
+    Dma4.SourceStartAddress = (UINT32)BufferAddress;        // DMA4_CSSAi
+
+    Dma4.DestinationStartAddress = MMCHS_DATA;              // DMA4_CDSAi
+
+    Dma4.SourceElementIndex = 1;                            // DMA4_CSEi
+
+    Dma4.SourceFrameIndex = 0x200;                          // DMA4_CSFi
+
+    Dma4.DestinationElementIndex = 1;                       // DMA4_CDEi
+
+    Dma4.DestinationFrameIndex = 0;                         // DMA4_CDFi
+
+
+
+    Dma4.ReadPortAccessMode = 1;            // DMA4_CCRi[13:12]  Post increment memory address
+
+    Dma4.WritePortAccessMode = 0;           // DMA4_CCRi[15:14]  Always write MMCHS_DATA
+
+    Dma4.ReadRequestNumber = 0x1d;          // DMA4_CCRi[4:0]    Syncro with MMCA_DMA_TX (60)
+
+    Dma4.WriteRequestNumber = 1;            // DMA4_CCRi[20:19]  Syncro upper 0x3d == 61 (one based)
+
+  } else {
+    return EFI_INVALID_PARAMETER;
+  }
+
+
+  EnableDmaChannel (2, &Dma4);
+
+
+  //Set command argument based on the card access mode (Byte mode or Block mode)
+  if (gCardInfo.OCRData.AccessMode & BIT1) {
+    CmdArgument = Lba;
+  } else {
+    CmdArgument = Lba * This->Media->BlockSize;
+  }
+
+  //Send Command.
+  Status = SendCmd (Cmd, CmdInterruptEnable, CmdArgument);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_ERROR, "CMD fails. Status: %x\n", Status));
+    return Status;
+  }
+
+    //Check for the Transfer completion.
+  while (RetryCount < MAX_RETRY_COUNT) {
+    //Read Status
+    do {
+      MmcStatus = MmioRead32 (MMCHS_STAT);
+    } while (MmcStatus == 0);
+
+    //Check if Transfer complete (TC) bit is set?
+    if (MmcStatus & TC) {
+      break;
+    } else {
+      DEBUG ((EFI_D_ERROR, "MmcStatus for TC: %x\n", MmcStatus));
+      //Check if DEB, DCRC or DTO interrupt occured.
+      if ((MmcStatus & DEB) | (MmcStatus & DCRC) | (MmcStatus & DTO)) {
+        //There was an error during the data transfer.
+
+        //Set SRD bit to 1 and wait until it return to 0x0.
+        MmioOr32 (MMCHS_SYSCTL, SRD);
+        while((MmioRead32 (MMCHS_SYSCTL) & SRD) != 0x0);
+
+        DisableDmaChannel (2, DMA4_CSR_BLOCK, DMA4_CSR_ERR);
+        DmaUnmap (BufferMap);
+        return EFI_DEVICE_ERROR;
+      }
+    }
+    RetryCount++;
+  }
+
+  DisableDmaChannel (2, DMA4_CSR_BLOCK, DMA4_CSR_ERR);
+  Status = DmaUnmap (BufferMap);
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    DEBUG ((EFI_D_ERROR, "TransferBlockData timed out.\n"));
+    return EFI_TIMEOUT;
+  }
+
+  return Status;
+}
+
+
+EFI_STATUS
+TransferBlock (
+  IN EFI_BLOCK_IO_PROTOCOL        *This,
+  IN  UINTN                       Lba,
+  IN OUT VOID                     *Buffer,
+  IN  OPERATION_TYPE              OperationType
+  )
+{
+  EFI_STATUS Status;
+  UINTN      MmcStatus;
+  UINTN      RetryCount = 0;
+  UINTN      Cmd = 0;
+  UINTN      CmdInterruptEnable = 0;
+  UINTN      CmdArgument = 0;
+
+
+  //Populate the command information based on the operation type.
+  if (OperationType == READ) {
+    Cmd = CMD17; //Single block read
+    CmdInterruptEnable = CMD18_INT_EN;
+  } else if (OperationType == WRITE) {
+    Cmd = CMD24; //Single block write
+    CmdInterruptEnable = CMD24_INT_EN;
+  }
+
+  //Set command argument based on the card access mode (Byte mode or Block mode)
+  if (gCardInfo.OCRData.AccessMode & BIT1) {
+    CmdArgument = Lba;
+  } else {
+    CmdArgument = Lba * This->Media->BlockSize;
+  }
+
+  //Send Command.
+  Status = SendCmd (Cmd, CmdInterruptEnable, CmdArgument);
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "CMD fails. Status: %x\n", Status));
+    return Status;
+  }
+
+  //Read or Write data.
+  if (OperationType == READ) {
+    Status = ReadBlockData (This, Buffer);
+    if (EFI_ERROR(Status)) {
+      DEBUG((EFI_D_ERROR, "ReadBlockData fails.\n"));
+      return Status;
+    }
+  } else if (OperationType == WRITE) {
+    Status = WriteBlockData (This, Buffer);
+    if (EFI_ERROR(Status)) {
+      DEBUG((EFI_D_ERROR, "WriteBlockData fails.\n"));
+      return Status;
+    }
+  }
+
+  //Check for the Transfer completion.
+  while (RetryCount < MAX_RETRY_COUNT) {
+    //Read Status
+    do {
+      MmcStatus = MmioRead32 (MMCHS_STAT);
+    } while (MmcStatus == 0);
+
+    //Check if Transfer complete (TC) bit is set?
+    if (MmcStatus & TC) {
+      break;
+    } else {
+      DEBUG ((EFI_D_ERROR, "MmcStatus for TC: %x\n", MmcStatus));
+      //Check if DEB, DCRC or DTO interrupt occured.
+      if ((MmcStatus & DEB) | (MmcStatus & DCRC) | (MmcStatus & DTO)) {
+        //There was an error during the data transfer.
+
+        //Set SRD bit to 1 and wait until it return to 0x0.
+        MmioOr32 (MMCHS_SYSCTL, SRD);
+        while((MmioRead32 (MMCHS_SYSCTL) & SRD) != 0x0);
+
+        return EFI_DEVICE_ERROR;
+      }
+    }
+    RetryCount++;
+  }
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    DEBUG ((EFI_D_ERROR, "TransferBlockData timed out.\n"));
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+BOOLEAN
+CardPresent (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       Data;
+
+  //
+  // Card detect is a GPIO0 on the TPS65950
+  //
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, GPIODATAIN1), 1, &Data);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  if ((Data & CARD_DETECT_BIT) == CARD_DETECT_BIT) {
+    // No Card present
+    return FALSE;
+  } else {
+    return TRUE;
+  }
+}
+
+EFI_STATUS
+DetectCard (
+  VOID
+  )
+{
+  EFI_STATUS    Status;
+
+  if (!CardPresent ()) {
+    return EFI_NO_MEDIA;
+  }
+
+  //Initialize MMC host controller clocks.
+  Status = InitializeMMCHS ();
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "Initialize MMC host controller fails. Status: %x\n", Status));
+    return Status;
+  }
+
+  //Software reset of the MMCHS host controller.
+  MmioWrite32 (MMCHS_SYSCONFIG, SOFTRESET);
+  gBS->Stall(1000);
+  while ((MmioRead32 (MMCHS_SYSSTATUS) & RESETDONE_MASK) != RESETDONE);
+
+  //Soft reset for all.
+  MmioWrite32 (MMCHS_SYSCTL, SRA);
+  gBS->Stall(1000);
+  while ((MmioRead32 (MMCHS_SYSCTL) & SRA) != 0x0);
+
+  //Voltage capabilities initialization. Activate VS18 and VS30.
+  MmioOr32 (MMCHS_CAPA, (VS30 | VS18));
+
+  //Wakeup configuration
+  MmioOr32 (MMCHS_SYSCONFIG, ENAWAKEUP);
+  MmioOr32 (MMCHS_HCTL, IWE);
+
+  //MMCHS Controller default initialization
+  MmioOr32 (MMCHS_CON, (OD | DW8_1_4_BIT | CEATA_OFF));
+
+  MmioWrite32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_OFF));
+
+  //Enable internal clock
+  MmioOr32 (MMCHS_SYSCTL, ICE);
+
+  //Set the clock frequency to 80KHz.
+  UpdateMMCHSClkFrequency (CLKD_80KHZ);
+
+  //Enable SD bus power.
+  MmioOr32 (MMCHS_HCTL, (SDBP_ON));
+
+  //Poll till SD bus power bit is set.
+  while ((MmioRead32 (MMCHS_HCTL) & SDBP_MASK) != SDBP_ON);
+
+  //Card idenfication
+  Status = PerformCardIdenfication ();
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "No MMC/SD card detected.\n"));
+    return Status;
+  }
+
+  //Get CSD (Card specific data) for the detected card.
+  Status = GetCardSpecificData();
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //Configure the card in data transfer mode.
+  Status = PerformCardConfiguration();
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //Patch the Media structure.
+  gMMCHSMedia.LastBlock    = (gCardInfo.NumBlocks - 1);
+  gMMCHSMedia.BlockSize    = gCardInfo.BlockSize;
+  gMMCHSMedia.ReadOnly     = (MmioRead32 (GPIO1_BASE + GPIO_DATAIN) & BIT23) == BIT23;
+  gMMCHSMedia.MediaPresent = TRUE;
+  gMMCHSMedia.MediaId++;
+
+  DEBUG ((EFI_D_INFO, "SD Card Media Change on Handle 0x%08x\n", gImageHandle));
+
+  return Status;
+}
+
+#define MAX_MMCHS_TRANSFER_SIZE  0x4000
+
+EFI_STATUS
+SdReadWrite (
+  IN EFI_BLOCK_IO_PROTOCOL    *This,
+  IN  UINTN                   Lba,
+  OUT VOID                    *Buffer,
+  IN  UINTN                   BufferSize,
+  IN  OPERATION_TYPE          OperationType
+  )
+{
+  EFI_STATUS Status = EFI_SUCCESS;
+  UINTN      RetryCount = 0;
+  UINTN      BlockCount;
+  UINTN      BytesToBeTranferedThisPass = 0;
+  UINTN      BytesRemainingToBeTransfered;
+  EFI_TPL    OldTpl;
+
+  BOOLEAN    Update;
+
+
+
+  Update               = FALSE;
+
+  if (gMediaChange) {
+    Update = TRUE;
+    Status = DetectCard  ();
+    if (EFI_ERROR (Status)) {
+      // We detected a removal
+      gMMCHSMedia.MediaPresent = FALSE;
+      gMMCHSMedia.LastBlock    = 0;
+      gMMCHSMedia.BlockSize    = 512;  // Should be zero but there is a bug in DiskIo
+      gMMCHSMedia.ReadOnly     = FALSE;
+    }
+    gMediaChange             = FALSE;
+  } else if (!gMMCHSMedia.MediaPresent) {
+    Status = EFI_NO_MEDIA;
+    goto Done;
+  }
+
+  if (Update) {
+    DEBUG ((EFI_D_INFO, "SD Card ReinstallProtocolInterface ()\n"));
+    gBS->ReinstallProtocolInterface (
+          gImageHandle,
+          &gEfiBlockIoProtocolGuid,
+          &gBlockIo,
+          &gBlockIo
+          );
+    return EFI_MEDIA_CHANGED;
+  }
+
+  if (EFI_ERROR (Status)) {
+    goto Done;
+  }
+
+  if (Buffer == NULL) {
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  if (Lba > This->Media->LastBlock) {
+    Status = EFI_INVALID_PARAMETER;
+    goto Done;
+  }
+
+  if ((BufferSize % This->Media->BlockSize) != 0) {
+    Status = EFI_BAD_BUFFER_SIZE;
+    goto Done;
+  }
+
+  //Check if the data lines are not in use.
+  while ((RetryCount++ < MAX_RETRY_COUNT) && ((MmioRead32 (MMCHS_PSTATE) & DATI_MASK) != DATI_ALLOWED));
+  if (RetryCount == MAX_RETRY_COUNT) {
+    Status = EFI_TIMEOUT;
+    goto Done;
+  }
+
+  OldTpl = gBS->RaiseTPL (TPL_NOTIFY);
+
+  BytesRemainingToBeTransfered = BufferSize;
+  while (BytesRemainingToBeTransfered > 0) {
+
+    if (gMediaChange) {
+      Status = EFI_NO_MEDIA;
+      DEBUG ((EFI_D_INFO, "SdReadWrite() EFI_NO_MEDIA due to gMediaChange\n"));
+      goto DoneRestoreTPL;
+    }
+
+    // Turn OFF DMA path until it is debugged
+    // BytesToBeTranferedThisPass = (BytesToBeTranferedThisPass >= MAX_MMCHS_TRANSFER_SIZE) ? MAX_MMCHS_TRANSFER_SIZE : BytesRemainingToBeTransfered;
+    BytesToBeTranferedThisPass   = This->Media->BlockSize;
+
+    BlockCount = BytesToBeTranferedThisPass/This->Media->BlockSize;
+
+    if (BlockCount > 1) {
+      Status = DmaBlocks (This, Lba, Buffer, BlockCount, OperationType);
+    } else {
+      //Transfer a block worth of data.
+      Status = TransferBlock (This, Lba, Buffer, OperationType);
+    }
+
+    if (EFI_ERROR(Status)) {
+      DEBUG ((EFI_D_ERROR, "TransferBlockData fails. %x\n", Status));
+      goto DoneRestoreTPL;
+    }
+
+    BytesRemainingToBeTransfered -= BytesToBeTranferedThisPass;
+    Lba    += BlockCount;
+    Buffer = (UINT8 *)Buffer + This->Media->BlockSize;
+  }
+
+DoneRestoreTPL:
+
+  gBS->RestoreTPL (OldTpl);
+
+Done:
+
+  return Status;
+
+}
+
+
+/**
+
+  Reset the Block Device.
+
+
+
+  @param  This                 Indicates a pointer to the calling context.
+
+  @param  ExtendedVerification Driver may perform diagnostics on reset.
+
+
+
+  @retval EFI_SUCCESS          The device was reset.
+
+  @retval EFI_DEVICE_ERROR     The device is not functioning properly and could
+
+                               not be reset.
+
+
+
+**/
+EFI_STATUS
+EFIAPI
+MMCHSReset (
+  IN EFI_BLOCK_IO_PROTOCOL          *This,
+  IN BOOLEAN                        ExtendedVerification
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
+/**
+
+  Read BufferSize bytes from Lba into Buffer.
+
+
+
+  @param  This       Indicates a pointer to the calling context.
+
+  @param  MediaId    Id of the media, changes every time the media is replaced.
+
+  @param  Lba        The starting Logical Block Address to read from
+
+  @param  BufferSize Size of Buffer, must be a multiple of device block size.
+
+  @param  Buffer     A pointer to the destination buffer for the data. The caller is
+
+                     responsible for either having implicit or explicit ownership of the buffer.
+
+
+
+  @retval EFI_SUCCESS           The data was read correctly from the device.
+
+  @retval EFI_DEVICE_ERROR      The device reported an error while performing the read.
+
+  @retval EFI_NO_MEDIA          There is no media in the device.
+
+  @retval EFI_MEDIA_CHANGED     The MediaId does not matched the current device.
+
+  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
+
+  @retval EFI_INVALID_PARAMETER The read request contains LBAs that are not valid,
+
+                                or the buffer is not on proper alignment.
+
+EFI_STATUS
+
+**/
+EFI_STATUS
+EFIAPI
+MMCHSReadBlocks (
+  IN EFI_BLOCK_IO_PROTOCOL          *This,
+  IN UINT32                         MediaId,
+  IN EFI_LBA                        Lba,
+  IN UINTN                          BufferSize,
+  OUT VOID                          *Buffer
+  )
+{
+  EFI_STATUS Status;
+
+  //Perform Read operation.
+  Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, READ);
+
+  return Status;
+
+}
+
+
+/**
+
+  Write BufferSize bytes from Lba into Buffer.
+
+
+
+  @param  This       Indicates a pointer to the calling context.
+
+  @param  MediaId    The media ID that the write request is for.
+
+  @param  Lba        The starting logical block address to be written. The caller is
+
+                     responsible for writing to only legitimate locations.
+
+  @param  BufferSize Size of Buffer, must be a multiple of device block size.
+
+  @param  Buffer     A pointer to the source buffer for the data.
+
+
+
+  @retval EFI_SUCCESS           The data was written correctly to the device.
+
+  @retval EFI_WRITE_PROTECTED   The device can not be written to.
+
+  @retval EFI_DEVICE_ERROR      The device reported an error while performing the write.
+
+  @retval EFI_NO_MEDIA          There is no media in the device.
+
+  @retval EFI_MEDIA_CHNAGED     The MediaId does not matched the current device.
+
+  @retval EFI_BAD_BUFFER_SIZE   The Buffer was not a multiple of the block size of the device.
+
+  @retval EFI_INVALID_PARAMETER The write request contains LBAs that are not valid,
+
+                                or the buffer is not on proper alignment.
+
+
+
+**/
+EFI_STATUS
+EFIAPI
+MMCHSWriteBlocks (
+  IN EFI_BLOCK_IO_PROTOCOL          *This,
+  IN UINT32                         MediaId,
+  IN EFI_LBA                        Lba,
+  IN UINTN                          BufferSize,
+  IN VOID                           *Buffer
+  )
+{
+  EFI_STATUS  Status;
+
+  //Perform write operation.
+  Status = SdReadWrite (This, (UINTN)Lba, Buffer, BufferSize, WRITE);
+
+
+  return Status;
+
+}
+
+
+/**
+
+  Flush the Block Device.
+
+
+
+  @param  This              Indicates a pointer to the calling context.
+
+
+
+  @retval EFI_SUCCESS       All outstanding data was written to the device
+
+  @retval EFI_DEVICE_ERROR  The device reported an error while writting back the data
+
+  @retval EFI_NO_MEDIA      There is no media in the device.
+
+
+
+**/
+EFI_STATUS
+EFIAPI
+MMCHSFlushBlocks (
+  IN EFI_BLOCK_IO_PROTOCOL  *This
+  )
+{
+  return EFI_SUCCESS;
+}
+
+
+EFI_BLOCK_IO_PROTOCOL gBlockIo = {
+  EFI_BLOCK_IO_INTERFACE_REVISION,   // Revision
+  &gMMCHSMedia,                      // *Media
+  MMCHSReset,                        // Reset
+  MMCHSReadBlocks,                   // ReadBlocks
+  MMCHSWriteBlocks,                  // WriteBlocks
+  MMCHSFlushBlocks                   // FlushBlocks
+};
+
+
+/**
+
+  Timer callback to convert card present hardware into a boolean that indicates
+
+  a media change event has happened. If you just check the GPIO you could see
+
+  card 1 and then check again after card 1 was removed and card 2 was inserted
+
+  and you would still see media present. Thus you need the timer tick to catch
+
+  the toggle event.
+
+
+
+  @param  Event                 Event whose notification function is being invoked.
+
+  @param  Context               The pointer to the notification function's context,
+
+                                which is implementation-dependent. Not used.
+
+
+
+**/
+VOID
+EFIAPI
+TimerCallback (
+  IN  EFI_EVENT   Event,
+  IN  VOID        *Context
+  )
+{
+  BOOLEAN Present;
+
+  Present = CardPresent ();
+  if (gMMCHSMedia.MediaPresent) {
+    if (!Present && !gMediaChange) {
+      gMediaChange = TRUE;
+    }
+  } else {
+    if (Present && !gMediaChange) {
+      gMediaChange = TRUE;
+    }
+  }
+}
+
+
+EFI_STATUS
+EFIAPI
+MMCHSInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950);
+  ASSERT_EFI_ERROR(Status);
+
+  ZeroMem (&gCardInfo, sizeof (CARD_INFO));
+
+  Status = gBS->CreateEvent (EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_CALLBACK, TimerCallback, NULL, &gTimerEvent);
+  ASSERT_EFI_ERROR (Status);
+
+  Status = gBS->SetTimer (gTimerEvent, TimerPeriodic, FixedPcdGet32 (PcdMmchsTimerFreq100NanoSeconds));
+  ASSERT_EFI_ERROR (Status);
+
+  //Publish BlockIO.
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &ImageHandle,
+                  &gEfiBlockIoProtocolGuid,    &gBlockIo,
+                  &gEfiDevicePathProtocolGuid, &gMmcHsDevicePath,
+                  NULL
+                  );
+  return Status;
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.h b/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.h
new file mode 100644
index 0000000000..63eaf2354a
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.h
@@ -0,0 +1,169 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef _MMCHS_H_
+#define _MMCHS_H_
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/OmapLib.h>
+#include <Library/OmapDmaLib.h>
+#include <Library/DmaLib.h>
+
+#include <Protocol/EmbeddedExternalDevice.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DevicePath.h>
+
+#include <Omap3530/Omap3530.h>
+#include <TPS65950.h>
+
+#define MAX_RETRY_COUNT  (100*5)
+
+#define HCS               BIT30 //Host capacity support/1 = Supporting high capacity
+#define CCS               BIT30 //Card capacity status/1 = High capacity card
+typedef struct {
+  UINT32  Reserved0:   7; // 0
+  UINT32  V170_V195:   1; // 1.70V - 1.95V
+  UINT32  V200_V260:   7; // 2.00V - 2.60V
+  UINT32  V270_V360:   9; // 2.70V - 3.60V
+  UINT32  RESERVED_1:  5; // Reserved
+  UINT32  AccessMode:  2; // 00b (byte mode), 10b (sector mode)
+  UINT32  Busy:        1; // This bit is set to LOW if the card has not finished the power up routine
+}OCR;
+
+typedef struct {
+  UINT32  NOT_USED;   // 1 [0:0]
+  UINT32  CRC;        // CRC7 checksum [7:1]
+  UINT32  MDT;        // Manufacturing date [19:8]
+  UINT32  RESERVED_1; // Reserved [23:20]
+  UINT32  PSN;        // Product serial number [55:24]
+  UINT8   PRV;        // Product revision [63:56]
+  UINT8   PNM[5];     // Product name [64:103]
+  UINT16  OID;        // OEM/Application ID [119:104]
+  UINT8   MID;        // Manufacturer ID [127:120]
+}CID;
+
+typedef struct {
+  UINT8   NOT_USED:           1; // Not used, always 1 [0:0]
+  UINT8   CRC:                7; // CRC [7:1]
+
+  UINT8   RESERVED_1:         2; // Reserved [9:8]
+  UINT8   FILE_FORMAT:        2; // File format [11:10]
+  UINT8   TMP_WRITE_PROTECT:  1; // Temporary write protection [12:12]
+  UINT8   PERM_WRITE_PROTECT: 1; // Permanent write protection [13:13]
+  UINT8   COPY:               1; // Copy flag (OTP) [14:14]
+  UINT8   FILE_FORMAT_GRP:    1; // File format group [15:15]
+
+  UINT16  RESERVED_2:         5; // Reserved [20:16]
+  UINT16  WRITE_BL_PARTIAL:   1; // Partial blocks for write allowed [21:21]
+  UINT16  WRITE_BL_LEN:       4; // Max. write data block length [25:22]
+  UINT16  R2W_FACTOR:         3; // Write speed factor [28:26]
+  UINT16  RESERVED_3:         2; // Reserved [30:29]
+  UINT16  WP_GRP_ENABLE:      1; // Write protect group enable [31:31]
+
+  UINT32  WP_GRP_SIZE:        7; // Write protect group size [38:32]
+  UINT32  SECTOR_SIZE:        7; // Erase sector size [45:39]
+  UINT32  ERASE_BLK_EN:       1; // Erase single block enable [46:46]
+  UINT32  C_SIZE_MULT:        3; // Device size multiplier [49:47]
+  UINT32  VDD_W_CURR_MAX:     3; // Max. write current @ VDD max [52:50]
+  UINT32  VDD_W_CURR_MIN:     3; // Max. write current @ VDD min [55:53]
+  UINT32  VDD_R_CURR_MAX:     3; // Max. read current @ VDD max [58:56]
+  UINT32  VDD_R_CURR_MIN:     3; // Max. read current @ VDD min [61:59]
+  UINT32  C_SIZELow2:         2; // Device size [63:62]
+
+  UINT32  C_SIZEHigh10:       10;// Device size [73:64]
+  UINT32  RESERVED_4:         2; // Reserved [75:74]
+  UINT32  DSR_IMP:            1; // DSR implemented [76:76]
+  UINT32  READ_BLK_MISALIGN:  1; // Read block misalignment [77:77]
+  UINT32  WRITE_BLK_MISALIGN: 1; // Write block misalignment [78:78]
+  UINT32  READ_BL_PARTIAL:    1; // Partial blocks for read allowed [79:79]
+  UINT32  READ_BL_LEN:        4; // Max. read data block length [83:80]
+  UINT32  CCC:                12;// Card command classes [95:84]
+
+  UINT8   TRAN_SPEED          ;  // Max. bus clock frequency [103:96]
+  UINT8   NSAC                ;  // Data read access-time 2 in CLK cycles (NSAC*100) [111:104]
+  UINT8   TAAC                ;  // Data read access-time 1 [119:112]
+
+  UINT8   RESERVED_5:         6; // Reserved [125:120]
+  UINT8   CSD_STRUCTURE:      2; // CSD structure [127:126]
+}CSD;
+
+typedef struct {
+  UINT8   NOT_USED:           1; // Not used, always 1 [0:0]
+  UINT8   CRC:                7; // CRC [7:1]
+  UINT8   RESERVED_1:         2; // Reserved [9:8]
+  UINT8   FILE_FORMAT:        2; // File format [11:10]
+  UINT8   TMP_WRITE_PROTECT:  1; // Temporary write protection [12:12]
+  UINT8   PERM_WRITE_PROTECT: 1; // Permanent write protection [13:13]
+  UINT8   COPY:               1; // Copy flag (OTP) [14:14]
+  UINT8   FILE_FORMAT_GRP:    1; // File format group [15:15]
+  UINT16  RESERVED_2:         5; // Reserved [20:16]
+  UINT16  WRITE_BL_PARTIAL:   1; // Partial blocks for write allowed [21:21]
+  UINT16  WRITE_BL_LEN:       4; // Max. write data block length [25:22]
+  UINT16  R2W_FACTOR:         3; // Write speed factor [28:26]
+  UINT16  RESERVED_3:         2; // Reserved [30:29]
+  UINT16  WP_GRP_ENABLE:      1; // Write protect group enable [31:31]
+  UINT16  WP_GRP_SIZE:        7; // Write protect group size [38:32]
+  UINT16  SECTOR_SIZE:        7; // Erase sector size [45:39]
+  UINT16  ERASE_BLK_EN:       1; // Erase single block enable [46:46]
+  UINT16  RESERVED_4:         1; // Reserved [47:47]
+  UINT32  C_SIZELow16:        16;// Device size [69:48]
+  UINT32  C_SIZEHigh6:        6; // Device size [69:48]
+  UINT32  RESERVED_5:         6; // Reserved [75:70]
+  UINT32  DSR_IMP:            1; // DSR implemented [76:76]
+  UINT32  READ_BLK_MISALIGN:  1; // Read block misalignment [77:77]
+  UINT32  WRITE_BLK_MISALIGN: 1; // Write block misalignment [78:78]
+  UINT32  READ_BL_PARTIAL:    1; // Partial blocks for read allowed [79:79]
+  UINT16  READ_BL_LEN:        4; // Max. read data block length [83:80]
+  UINT16  CCC:                12;// Card command classes [95:84]
+  UINT8   TRAN_SPEED          ;  // Max. bus clock frequency [103:96]
+  UINT8   NSAC                ;  // Data read access-time 2 in CLK cycles (NSAC*100) [111:104]
+  UINT8   TAAC                ;  // Data read access-time 1 [119:112]
+  UINT8   RESERVED_6:         6; // 0 [125:120]
+  UINT8   CSD_STRUCTURE:      2; // CSD structure [127:126]
+}CSD_SDV2;
+
+typedef enum {
+  UNKNOWN_CARD,
+  MMC_CARD,              //MMC card
+  SD_CARD,               //SD 1.1 card
+  SD_CARD_2,             //SD 2.0 or above standard card
+  SD_CARD_2_HIGH         //SD 2.0 or above high capacity card
+} CARD_TYPE;
+
+typedef enum {
+  READ,
+  WRITE
+} OPERATION_TYPE;
+
+typedef struct  {
+  UINT16    RCA;
+  UINTN     BlockSize;
+  UINTN     NumBlocks;
+  UINTN     ClockFrequencySelect;
+  CARD_TYPE CardType;
+  OCR       OCRData;
+  CID       CIDData;
+  CSD       CSDData;
+} CARD_INFO;
+
+EFI_STATUS
+DetectCard (
+  VOID
+  );
+
+extern EFI_BLOCK_IO_PROTOCOL gBlockIo;
+
+#endif
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.inf b/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.inf
new file mode 100644
index 0000000000..a759f59394
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/MMCHSDxe/MMCHS.inf
@@ -0,0 +1,48 @@
+#/** @file
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = MMCHS
+  FILE_GUID                      = 100c2cfa-b586-4198-9b4c-1683d195b1da
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = MMCHSInitialize
+
+
+[Sources.common]
+  MMCHS.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  UefiLib
+  UefiDriverEntryPoint
+  MemoryAllocationLib
+  IoLib
+  OmapDmaLib
+  DmaLib
+
+[Guids]
+
+[Protocols]
+  gEfiBlockIoProtocolGuid
+  gEfiCpuArchProtocolGuid
+  gEfiDevicePathProtocolGuid
+  gEmbeddedExternalDeviceProtocolGuid
+
+[Pcd]
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxMMCHS1Base
+  gOmap35xxTokenSpaceGuid.PcdMmchsTimerFreq100NanoSeconds
+
+[depex]
+  gEmbeddedExternalDeviceProtocolGuid
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.c b/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.c
new file mode 100644
index 0000000000..410fed9366
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.c
@@ -0,0 +1,671 @@
+/** @file
+*
+*  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
+*  Copyright (c) 2011 - 2014, ARM Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#include "MmcHostDxe.h"
+
+EMBEDDED_EXTERNAL_DEVICE   *gTPS65950;
+UINT8                      mMaxDataTransferRate = 0;
+UINT32                     mRca = 0;
+BOOLEAN                    mBitModeSet = FALSE;
+
+
+typedef struct {
+  VENDOR_DEVICE_PATH  Mmc;
+  EFI_DEVICE_PATH     End;
+} MMCHS_DEVICE_PATH;
+
+MMCHS_DEVICE_PATH gMMCDevicePath = {
+  {
+    {
+      HARDWARE_DEVICE_PATH,
+      HW_VENDOR_DP,
+      { (UINT8)(sizeof(VENDOR_DEVICE_PATH)), (UINT8)((sizeof(VENDOR_DEVICE_PATH)) >> 8) },
+    },
+    { 0xb615f1f5, 0x5088, 0x43cd, { 0x80, 0x9c, 0xa1, 0x6e, 0x52, 0x48, 0x7d, 0x00 } }
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
+  }
+};
+
+BOOLEAN
+IgnoreCommand (
+  UINT32 Command
+  )
+{
+  switch(Command) {
+    case MMC_CMD12:
+      return TRUE;
+    case MMC_CMD13:
+      return TRUE;
+    default:
+      return FALSE;
+  }
+}
+
+UINT32
+TranslateCommand (
+  UINT32 Command
+  )
+{
+  UINT32 Translation;
+
+  switch(Command) {
+    case MMC_CMD2:
+      Translation = CMD2;
+      break;
+    case MMC_CMD3:
+      Translation = CMD3;
+      break;
+    /*case MMC_CMD6:
+      Translation = CMD6;
+      break;*/
+    case MMC_CMD7:
+      Translation = CMD7;
+      break;
+    case MMC_CMD8:
+      Translation = CMD8;
+      break;
+    case MMC_CMD9:
+      Translation = CMD9;
+      break;
+    /*case MMC_CMD12:
+      Translation = CMD12;
+      break;
+    case MMC_CMD13:
+      Translation = CMD13;
+      break;*/
+    case MMC_CMD16:
+      Translation = CMD16;
+      break;
+    case MMC_CMD17:
+      Translation = 0x113A0014;//CMD17;
+      break;
+    case MMC_CMD24:
+      Translation = CMD24 | 4;
+      break;
+    case MMC_CMD55:
+      Translation = CMD55;
+      break;
+    case MMC_ACMD41:
+      Translation = ACMD41;
+      break;
+    default:
+      Translation = Command;
+  }
+
+  return Translation;
+}
+
+VOID
+CalculateCardCLKD (
+  UINTN *ClockFrequencySelect
+  )
+{
+  UINTN    TransferRateValue = 0;
+  UINTN    TimeValue = 0 ;
+  UINTN    Frequency = 0;
+
+  DEBUG ((DEBUG_BLKIO, "CalculateCardCLKD()\n"));
+
+  // For SD Cards  we would need to send CMD6 to set
+  // speeds abouve 25MHz. High Speed mode 50 MHz and up
+
+  // Calculate Transfer rate unit (Bits 2:0 of TRAN_SPEED)
+  switch (mMaxDataTransferRate & 0x7) { // 2
+    case 0:
+      TransferRateValue = 100 * 1000;
+      break;
+
+    case 1:
+      TransferRateValue = 1 * 1000 * 1000;
+      break;
+
+    case 2:
+      TransferRateValue = 10 * 1000 * 1000;
+      break;
+
+    case 3:
+      TransferRateValue = 100 * 1000 * 1000;
+      break;
+
+    default:
+      DEBUG ((DEBUG_BLKIO, "Invalid parameter.\n"));
+      ASSERT(FALSE);
+      return;
+  }
+
+  //Calculate Time value (Bits 6:3 of TRAN_SPEED)
+  switch ((mMaxDataTransferRate >> 3) & 0xF) { // 6
+    case 1:
+      TimeValue = 10;
+      break;
+
+    case 2:
+      TimeValue = 12;
+      break;
+
+    case 3:
+      TimeValue = 13;
+      break;
+
+    case 4:
+      TimeValue = 15;
+      break;
+
+    case 5:
+      TimeValue = 20;
+      break;
+
+    case 6:
+      TimeValue = 25;
+      break;
+
+    case 7:
+      TimeValue = 30;
+      break;
+
+    case 8:
+      TimeValue = 35;
+      break;
+
+    case 9:
+      TimeValue = 40;
+      break;
+
+    case 10:
+      TimeValue = 45;
+      break;
+
+    case 11:
+      TimeValue = 50;
+      break;
+
+    case 12:
+      TimeValue = 55;
+      break;
+
+    case 13:
+      TimeValue = 60;
+      break;
+
+    case 14:
+      TimeValue = 70;
+      break;
+
+    case 15:
+      TimeValue = 80;
+      break;
+
+    default:
+      DEBUG ((DEBUG_BLKIO, "Invalid parameter.\n"));
+      ASSERT(FALSE);
+      return;
+  }
+
+  Frequency = TransferRateValue * TimeValue/10;
+
+  // Calculate Clock divider value to program in MMCHS_SYSCTL[CLKD] field.
+  *ClockFrequencySelect = ((MMC_REFERENCE_CLK/Frequency) + 1);
+
+  DEBUG ((DEBUG_BLKIO, "mMaxDataTransferRate: 0x%x, Frequency: %d KHz, ClockFrequencySelect: %x\n", mMaxDataTransferRate, Frequency/1000, *ClockFrequencySelect));
+}
+
+VOID
+UpdateMMCHSClkFrequency (
+  UINTN NewCLKD
+  )
+{
+  DEBUG ((DEBUG_BLKIO, "UpdateMMCHSClkFrequency()\n"));
+
+  // Set Clock enable to 0x0 to not provide the clock to the card
+  MmioAnd32 (MMCHS_SYSCTL, ~CEN);
+
+  // Set new clock frequency.
+  MmioAndThenOr32 (MMCHS_SYSCTL, ~CLKD_MASK, NewCLKD << 6);
+
+  // Poll till Internal Clock Stable
+  while ((MmioRead32 (MMCHS_SYSCTL) & ICS_MASK) != ICS);
+
+  // Set Clock enable to 0x1 to provide the clock to the card
+  MmioOr32 (MMCHS_SYSCTL, CEN);
+}
+
+EFI_STATUS
+InitializeMMCHS (
+  VOID
+  )
+{
+  UINT8      Data;
+  EFI_STATUS Status;
+
+  DEBUG ((DEBUG_BLKIO, "InitializeMMCHS()\n"));
+
+  // Select Device group to belong to P1 device group in Power IC.
+  Data = DEV_GRP_P1;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VMMC1_DEV_GRP), 1, &Data);
+  ASSERT_EFI_ERROR(Status);
+
+  // Configure voltage regulator for MMC1 in Power IC to output 3.0 voltage.
+  Data = VSEL_3_00V;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VMMC1_DEDICATED_REG), 1, &Data);
+  ASSERT_EFI_ERROR(Status);
+
+  // After ramping up voltage, set VDDS stable bit to indicate that voltage level is stable.
+  MmioOr32 (CONTROL_PBIAS_LITE, (PBIASLITEVMODE0 | PBIASLITEPWRDNZ0 | PBIASSPEEDCTRL0 | PBIASLITEVMODE1 | PBIASLITEWRDNZ1));
+
+  // Enable WP GPIO
+  MmioAndThenOr32 (GPIO1_BASE + GPIO_OE, ~BIT23, BIT23);
+
+  // Enable Card Detect
+  Data = CARD_DETECT_ENABLE;
+  gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, TPS65950_GPIO_CTRL), 1, &Data);
+
+  return Status;
+}
+
+BOOLEAN
+MMCIsCardPresent (
+  IN EFI_MMC_HOST_PROTOCOL     *This
+  )
+{
+  EFI_STATUS  Status;
+  UINT8       Data;
+
+  //
+  // Card detect is a GPIO0 on the TPS65950
+  //
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID2, GPIODATAIN1), 1, &Data);
+  if (EFI_ERROR (Status)) {
+    return FALSE;
+  }
+
+  return !(Data & CARD_DETECT_BIT);
+}
+
+BOOLEAN
+MMCIsReadOnly (
+  IN EFI_MMC_HOST_PROTOCOL     *This
+  )
+{
+  /* Note:
+   * On our BeagleBoard the SD card WP pin is always read as TRUE.
+   * Probably something wrong with GPIO configuration.
+   * BeagleBoard-xM uses microSD cards so there is no write protect at all.
+   * Hence commenting out SD card WP pin read status.
+   */
+  //return (MmioRead32 (GPIO1_BASE + GPIO_DATAIN) & BIT23) == BIT23;
+  return 0;
+
+}
+
+// TODO
+EFI_GUID mPL180MciDevicePathGuid = EFI_CALLER_ID_GUID;
+
+EFI_STATUS
+MMCBuildDevicePath (
+  IN EFI_MMC_HOST_PROTOCOL     *This,
+  IN EFI_DEVICE_PATH_PROTOCOL  **DevicePath
+  )
+{
+  EFI_DEVICE_PATH_PROTOCOL    *NewDevicePathNode;
+
+  NewDevicePathNode = CreateDeviceNode(HARDWARE_DEVICE_PATH,HW_VENDOR_DP,sizeof(VENDOR_DEVICE_PATH));
+  CopyGuid(&((VENDOR_DEVICE_PATH*)NewDevicePathNode)->Guid,&mPL180MciDevicePathGuid);
+  *DevicePath = NewDevicePathNode;
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MMCSendCommand (
+  IN EFI_MMC_HOST_PROTOCOL     *This,
+  IN MMC_CMD                   MmcCmd,
+  IN UINT32                    Argument
+  )
+{
+  UINTN MmcStatus;
+  UINTN RetryCount = 0;
+
+  if (IgnoreCommand(MmcCmd))
+    return EFI_SUCCESS;
+
+  MmcCmd = TranslateCommand(MmcCmd);
+
+  //DEBUG ((EFI_D_ERROR, "MMCSendCommand(%d)\n", MmcCmd));
+
+  // Check if command line is in use or not. Poll till command line is available.
+  while ((MmioRead32 (MMCHS_PSTATE) & DATI_MASK) == DATI_NOT_ALLOWED);
+
+  // Provide the block size.
+  MmioWrite32 (MMCHS_BLK, BLEN_512BYTES);
+
+  // Setting Data timeout counter value to max value.
+  MmioAndThenOr32 (MMCHS_SYSCTL, ~DTO_MASK, DTO_VAL);
+
+  // Clear Status register.
+  MmioWrite32 (MMCHS_STAT, 0xFFFFFFFF);
+
+  // Set command argument register
+  MmioWrite32 (MMCHS_ARG, Argument);
+
+  //TODO: fix this
+  //Enable interrupt enable events to occur
+  //MmioWrite32 (MMCHS_IE, CmdInterruptEnableVal);
+
+  // Send a command
+  MmioWrite32 (MMCHS_CMD, MmcCmd);
+
+  // Check for the command status.
+  while (RetryCount < MAX_RETRY_COUNT) {
+    do {
+      MmcStatus = MmioRead32 (MMCHS_STAT);
+    } while (MmcStatus == 0);
+
+    // Read status of command response
+    if ((MmcStatus & ERRI) != 0) {
+
+      // Perform soft-reset for mmci_cmd line.
+      MmioOr32 (MMCHS_SYSCTL, SRC);
+      while ((MmioRead32 (MMCHS_SYSCTL) & SRC));
+
+      //DEBUG ((EFI_D_INFO, "MmcStatus: 0x%x\n", MmcStatus));
+      return EFI_DEVICE_ERROR;
+    }
+
+    // Check if command is completed.
+    if ((MmcStatus & CC) == CC) {
+      MmioWrite32 (MMCHS_STAT, CC);
+      break;
+    }
+
+    RetryCount++;
+  }
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    DEBUG ((DEBUG_BLKIO, "MMCSendCommand: Timeout\n"));
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MMCNotifyState (
+  IN EFI_MMC_HOST_PROTOCOL    *This,
+  IN MMC_STATE                State
+  )
+{
+  EFI_STATUS              Status;
+  UINTN                   FreqSel;
+
+  switch(State) {
+    case MmcInvalidState:
+      ASSERT(0);
+      break;
+    case MmcHwInitializationState:
+      mBitModeSet = FALSE;
+
+      DEBUG ((DEBUG_BLKIO, "MMCHwInitializationState()\n"));
+      Status = InitializeMMCHS ();
+      if (EFI_ERROR(Status)) {
+        DEBUG ((DEBUG_BLKIO, "Initialize MMC host controller fails. Status: %x\n", Status));
+        return Status;
+      }
+
+      // Software reset of the MMCHS host controller.
+      MmioWrite32 (MMCHS_SYSCONFIG, SOFTRESET);
+      gBS->Stall(1000);
+      while ((MmioRead32 (MMCHS_SYSSTATUS) & RESETDONE_MASK) != RESETDONE);
+
+      // Soft reset for all.
+      MmioWrite32 (MMCHS_SYSCTL, SRA);
+      gBS->Stall(1000);
+      while ((MmioRead32 (MMCHS_SYSCTL) & SRA) != 0x0);
+
+      //Voltage capabilities initialization. Activate VS18 and VS30.
+      MmioOr32 (MMCHS_CAPA, (VS30 | VS18));
+
+      // Wakeup configuration
+      MmioOr32 (MMCHS_SYSCONFIG, ENAWAKEUP);
+      MmioOr32 (MMCHS_HCTL, IWE);
+
+      // MMCHS Controller default initialization
+      MmioOr32 (MMCHS_CON, (OD | DW8_1_4_BIT | CEATA_OFF));
+
+      MmioWrite32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_OFF));
+
+      // Enable internal clock
+      MmioOr32 (MMCHS_SYSCTL, ICE);
+
+      // Set the clock frequency to 80KHz.
+      UpdateMMCHSClkFrequency (CLKD_80KHZ);
+
+      // Enable SD bus power.
+      MmioOr32 (MMCHS_HCTL, (SDBP_ON));
+
+      // Poll till SD bus power bit is set.
+      while ((MmioRead32 (MMCHS_HCTL) & SDBP_MASK) != SDBP_ON);
+
+      // Enable interrupts.
+      MmioWrite32 (MMCHS_IE, (BADA_EN | CERR_EN | DEB_EN | DCRC_EN | DTO_EN | CIE_EN |
+        CEB_EN | CCRC_EN | CTO_EN | BRR_EN | BWR_EN | TC_EN | CC_EN));
+
+      // Controller INIT procedure start.
+      MmioOr32 (MMCHS_CON, INIT);
+      MmioWrite32 (MMCHS_CMD, 0x00000000);
+      while (!(MmioRead32 (MMCHS_STAT) & CC));
+
+      // Wait for 1 ms
+      gBS->Stall (1000);
+
+      // Set CC bit to 0x1 to clear the flag
+      MmioOr32 (MMCHS_STAT, CC);
+
+      // Retry INIT procedure.
+      MmioWrite32 (MMCHS_CMD, 0x00000000);
+      while (!(MmioRead32 (MMCHS_STAT) & CC));
+
+      // End initialization sequence
+      MmioAnd32 (MMCHS_CON, ~INIT);
+
+      MmioOr32 (MMCHS_HCTL, (SDVS_3_0_V | DTW_1_BIT | SDBP_ON));
+
+      // Change clock frequency to 400KHz to fit protocol
+      UpdateMMCHSClkFrequency(CLKD_400KHZ);
+
+      MmioOr32 (MMCHS_CON, OD);
+      break;
+    case MmcIdleState:
+      break;
+    case MmcReadyState:
+      break;
+    case MmcIdentificationState:
+      break;
+    case MmcStandByState:
+      CalculateCardCLKD (&FreqSel);
+      UpdateMMCHSClkFrequency (FreqSel);
+      break;
+    case MmcTransferState:
+      if (!mBitModeSet) {
+        Status = MMCSendCommand (This, CMD55, mRca << 16);
+        if (!EFI_ERROR (Status)) {
+          // Set device into 4-bit data bus mode
+          Status = MMCSendCommand (This, ACMD6, 0x2);
+          if (!EFI_ERROR (Status)) {
+            // Set host controler into 4-bit mode
+            MmioOr32 (MMCHS_HCTL, DTW_4_BIT);
+            DEBUG ((DEBUG_BLKIO, "SD Memory Card set to 4-bit mode\n"));
+            mBitModeSet = TRUE;
+          }
+        }
+      }
+      break;
+    case MmcSendingDataState:
+      break;
+    case MmcReceiveDataState:
+      break;
+    case MmcProgrammingState:
+      break;
+    case MmcDisconnectState:
+    default:
+      ASSERT(0);
+  }
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MMCReceiveResponse (
+  IN EFI_MMC_HOST_PROTOCOL     *This,
+  IN MMC_RESPONSE_TYPE         Type,
+  IN UINT32*                   Buffer
+  )
+{
+  if (Buffer == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (Type == MMC_RESPONSE_TYPE_R2) {
+    Buffer[0] = MmioRead32 (MMCHS_RSP10);
+    Buffer[1] = MmioRead32 (MMCHS_RSP32);
+    Buffer[2] = MmioRead32 (MMCHS_RSP54);
+    Buffer[3] = MmioRead32 (MMCHS_RSP76);
+  } else {
+    Buffer[0] = MmioRead32 (MMCHS_RSP10);
+  }
+
+  if (Type == MMC_RESPONSE_TYPE_CSD) {
+    mMaxDataTransferRate = Buffer[3] & 0xFF;
+  } else if (Type == MMC_RESPONSE_TYPE_RCA) {
+    mRca = Buffer[0] >> 16;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MMCReadBlockData (
+  IN EFI_MMC_HOST_PROTOCOL      *This,
+  IN EFI_LBA                    Lba,
+  IN UINTN                      Length,
+  IN UINT32*                    Buffer
+  )
+{
+  UINTN MmcStatus;
+  UINTN Count;
+  UINTN RetryCount = 0;
+
+  DEBUG ((DEBUG_BLKIO, "MMCReadBlockData(LBA: 0x%x, Length: 0x%x, Buffer: 0x%x)\n", Lba, Length, Buffer));
+
+  // Check controller status to make sure there is no error.
+  while (RetryCount < MAX_RETRY_COUNT) {
+    do {
+      // Read Status.
+      MmcStatus = MmioRead32 (MMCHS_STAT);
+    } while(MmcStatus == 0);
+
+    // Check if Buffer read ready (BRR) bit is set?
+    if (MmcStatus & BRR) {
+
+      // Clear BRR bit
+      MmioOr32 (MMCHS_STAT, BRR);
+
+      for (Count = 0; Count < Length / 4; Count++) {
+        *Buffer++ = MmioRead32(MMCHS_DATA);
+      }
+      break;
+    }
+    RetryCount++;
+  }
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+MMCWriteBlockData (
+  IN EFI_MMC_HOST_PROTOCOL    *This,
+  IN EFI_LBA                  Lba,
+  IN UINTN                    Length,
+  IN UINT32*                  Buffer
+  )
+{
+  UINTN MmcStatus;
+  UINTN Count;
+  UINTN RetryCount = 0;
+
+  // Check controller status to make sure there is no error.
+  while (RetryCount < MAX_RETRY_COUNT) {
+    do {
+      // Read Status.
+      MmcStatus = MmioRead32 (MMCHS_STAT);
+    } while(MmcStatus == 0);
+
+    // Check if Buffer write ready (BWR) bit is set?
+    if (MmcStatus & BWR) {
+
+      // Clear BWR bit
+      MmioOr32 (MMCHS_STAT, BWR);
+
+      // Write block worth of data.
+      for (Count = 0; Count < Length / 4; Count++) {
+        MmioWrite32 (MMCHS_DATA, *Buffer++);
+      }
+
+      break;
+    }
+    RetryCount++;
+  }
+
+  if (RetryCount == MAX_RETRY_COUNT) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+EFI_MMC_HOST_PROTOCOL gMMCHost = {
+  MMC_HOST_PROTOCOL_REVISION,
+  MMCIsCardPresent,
+  MMCIsReadOnly,
+  MMCBuildDevicePath,
+  MMCNotifyState,
+  MMCSendCommand,
+  MMCReceiveResponse,
+  MMCReadBlockData,
+  MMCWriteBlockData
+};
+
+EFI_STATUS
+MMCInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS    Status;
+  EFI_HANDLE    Handle = NULL;
+
+  DEBUG ((DEBUG_BLKIO, "MMCInitialize()\n"));
+
+  Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gEfiMmcHostProtocolGuid,         &gMMCHost,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR (Status);
+
+  return Status;
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.h b/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.h
new file mode 100644
index 0000000000..7c043ae726
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.h
@@ -0,0 +1,38 @@
+/** @file
+*
+*  Copyright (c) 2011, ARM Limited. All rights reserved.
+*
+*  SPDX-License-Identifier: BSD-2-Clause-Patent
+*
+**/
+
+#ifndef _MMC_HOST_DXE_H_
+#define _MMC_HOST_DXE_H_
+
+#include <Uefi.h>
+
+#include <Library/BaseLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/IoLib.h>
+#include <Library/PcdLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/OmapLib.h>
+#include <Library/OmapDmaLib.h>
+#include <Library/DmaLib.h>
+
+#include <Protocol/EmbeddedExternalDevice.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/MmcHost.h>
+
+#include <Omap3530/Omap3530.h>
+#include <TPS65950.h>
+
+#define MAX_RETRY_COUNT  (100*5)
+
+extern EFI_BLOCK_IO_PROTOCOL gBlockIo;
+
+#endif
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf b/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf
new file mode 100644
index 0000000000..88407211a5
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf
@@ -0,0 +1,47 @@
+#  Copyright (c) 2011, ARM Limited. All rights reserved.
+#
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = MMC
+  FILE_GUID                      = 100c2cfa-b586-4198-9b4c-1683d195b1da
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = MMCInitialize
+
+
+[Sources.common]
+  MmcHostDxe.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  UefiLib
+  UefiDriverEntryPoint
+  MemoryAllocationLib
+  IoLib
+  OmapDmaLib
+  DmaLib
+
+[Guids]
+
+[Protocols]
+  gEfiBlockIoProtocolGuid
+  gEfiCpuArchProtocolGuid
+  gEfiDevicePathProtocolGuid
+  gEmbeddedExternalDeviceProtocolGuid
+  gEfiMmcHostProtocolGuid
+
+[Pcd]
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxMMCHS1Base
+  gOmap35xxTokenSpaceGuid.PcdMmchsTimerFreq100NanoSeconds
+
+[depex]
+  gEmbeddedExternalDeviceProtocolGuid
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dec b/Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dec
new file mode 100644
index 0000000000..3415e1c087
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dec
@@ -0,0 +1,52 @@
+#/** @file
+# Omap35xx SoC package.
+#
+# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
+#
+#    SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  DEC_SPECIFICATION              = 0x00010005
+  PACKAGE_NAME                   = Omap35xxPkg
+  PACKAGE_GUID                   = D196A631-B7B7-4953-A3EE-0F773CBABF20
+  PACKAGE_VERSION                = 0.1
+
+################################################################################
+#
+# Include Section - list of Include Paths that are provided by this package.
+#                   Comments are used for Keywords and Module Types.
+#
+# Supported Module Types:
+#  BASE SEC PEI_CORE PEIM DXE_CORE DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SMM_DRIVER DXE_SAL_DRIVER UEFI_DRIVER UEFI_APPLICATION
+#
+################################################################################
+[Includes.common]
+  Include                        # Root include for the package
+
+[LibraryClasses]
+  ##  @libraryclass  Abstract location of basic OMAP components
+  ##
+  OmapLib|Include/Library/OmapLib.h
+
+  ##  @libraryclass  Abstract OMAP and ARM DMA, modeled after PCI IO protocol
+  ##
+  OmapDmaLib|Include/Library/OmapDmaLib.h
+
+
+[Guids.common]
+  gOmap35xxTokenSpaceGuid    =  { 0x24b09abe, 0x4e47, 0x481c, { 0xa9, 0xad, 0xce, 0xf1, 0x2c, 0x39, 0x23, 0x27} }
+
+[PcdsFeatureFlag.common]
+
+[PcdsFixedAtBuild.common]
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxConsoleUart|3|UINT32|0x00000202
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxGpmcOffset|0x00000000|UINT32|0x00000203
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxMMCHS1Base|0x00000000|UINT32|0x00000204
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxArchTimer|3|UINT32|0x00000205
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxFreeTimer|4|UINT32|0x00000206
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxDebugAgentTimer|5|UINT32|0x00000207
+  gOmap35xxTokenSpaceGuid.PcdDebugAgentTimerFreqNanoSeconds|77|UINT32|0x00000208
+  gOmap35xxTokenSpaceGuid.PcdMmchsTimerFreq100NanoSeconds|1000000|UINT32|0x00000209
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dsc b/Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dsc
new file mode 100644
index 0000000000..1ad991a8ab
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/Omap35xxPkg.dsc
@@ -0,0 +1,183 @@
+#/** @file
+# Omap35xx SoC package.
+#
+# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
+# Copyright (c) 2016, Linaro Ltd. All rights reserved.<BR>
+#
+#    SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+################################################################################
+#
+# Defines Section - statements that will be processed to create a Makefile.
+#
+################################################################################
+[Defines]
+  PLATFORM_NAME                  = Omap35xxPkg
+  PLATFORM_GUID                  = D196A631-B7B7-4953-A3EE-0F773CBABF20
+  PLATFORM_VERSION               = 0.1
+  DSC_SPECIFICATION              = 0x00010005
+  OUTPUT_DIRECTORY               = Build/Omap35xxPkg
+  SUPPORTED_ARCHITECTURES        = ARM
+  BUILD_TARGETS                  = DEBUG|RELEASE
+  SKUID_IDENTIFIER               = DEFAULT
+  DEFINE TARGET_HACK             = DEBUG
+
+
+[LibraryClasses.common]
+  DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+
+  ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+
+  BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+  BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
+
+  PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
+
+  CacheMaintenanceLib|ArmPkg/Library/ArmCacheMaintenanceLib/ArmCacheMaintenanceLib.inf
+  DefaultExceptioHandlerLib|ArmPkg/Library/DefaultExceptionHandlerLib/DefaultExceptionHandlerLib.inf
+  PrePiLib|EmbeddedPkg/Library/PrePiLib/PrePiLib.inf
+
+  RealTimeClockLib|EmbeddedPkg/Library/TemplateRealTimeClockLib/TemplateRealTimeClockLib.inf
+
+  IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
+  OmapLib|Omap35xxPkg/Library/OmapLib/OmapLib.inf
+  OmapDmaLib|Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
+
+  MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
+  UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
+  UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
+  DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+  UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
+
+  DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
+  UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
+  UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
+  DmaLib|EmbeddedPkg/Library/NonCoherentDmaLib/NonCoherentDmaLib.inf
+
+  TimerLib|Omap35xxPkg/Library/Omap35xxTimerLib/Omap35xxTimerLib.inf
+
+#
+# Assume everything is fixed at build
+#
+  PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
+  UefiRuntimeLib|MdePkg/Library/UefiRuntimeLib/UefiRuntimeLib.inf
+
+  CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
+
+
+[LibraryClasses.common.DXE_DRIVER]
+  DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
+  NonDiscoverableDeviceRegistrationLib|MdeModulePkg/Library/NonDiscoverableDeviceRegistrationLib/NonDiscoverableDeviceRegistrationLib.inf
+
+[LibraryClasses.ARM]
+  NULL|ArmPkg/Library/CompilerIntrinsicsLib/CompilerIntrinsicsLib.inf
+  NULL|MdePkg/Library/BaseStackCheckLib/BaseStackCheckLib.inf
+
+[BuildOptions]
+  XCODE:*_*_ARM_ARCHCC_FLAGS     == -arch armv7 -march=armv7
+  XCODE:*_*_ARM_ARCHASM_FLAGS    == -arch armv7
+  XCODE:*_*_ARM_ARCHDLINK_FLAGS  == -arch armv7
+
+  GCC:*_*_ARM_ARCHCC_FLAGS     == -march=armv7-a -mthumb
+  GCC:*_*_ARM_ARCHASM_FLAGS    == -march=armv7-a
+
+  RVCT:*_*_ARM_ARCHCC_FLAGS     == --cpu 7-A
+  RVCT:*_*_ARM_ARCHASM_FLAGS    == --cpu 7-A
+
+  *_*_*_CC_FLAGS = -DDISABLE_NEW_DEPRECATED_INTERFACES
+
+################################################################################
+#
+# Pcd Section - list of all EDK II PCD Entries defined by this Platform
+#
+################################################################################
+
+
+[PcdsFixedAtBuild.common]
+
+# DEBUG_ASSERT_ENABLED       0x01
+# DEBUG_PRINT_ENABLED        0x02
+# DEBUG_CODE_ENABLED         0x04
+# CLEAR_MEMORY_ENABLED       0x08
+# ASSERT_BREAKPOINT_ENABLED  0x10
+# ASSERT_DEADLOOP_ENABLED    0x20
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPropertyMask|0x2f
+
+#  DEBUG_INIT      0x00000001  // Initialization
+#  DEBUG_WARN      0x00000002  // Warnings
+#  DEBUG_LOAD      0x00000004  // Load events
+#  DEBUG_FS        0x00000008  // EFI File system
+#  DEBUG_POOL      0x00000010  // Alloc & Free (pool)
+#  DEBUG_PAGE      0x00000020  // Alloc & Free (page)
+#  DEBUG_INFO      0x00000040  // Informational debug messages
+#  DEBUG_DISPATCH  0x00000080  // PEI/DXE/SMM Dispatchers
+#  DEBUG_VARIABLE  0x00000100  // Variable
+#  DEBUG_BM        0x00000400  // Boot Manager
+#  DEBUG_BLKIO     0x00001000  // BlkIo Driver
+#  DEBUG_NET       0x00004000  // SNP Driver
+#  DEBUG_UNDI      0x00010000  // UNDI Driver
+#  DEBUG_LOADFILE  0x00020000  // LoadFile
+#  DEBUG_EVENT     0x00080000  // Event messages
+#  DEBUG_GCD       0x00100000  // Global Coherency Database changes
+#  DEBUG_CACHE     0x00200000  // Memory range cachability changes
+#  DEBUG_VERBOSE   0x00400000  // Detailed debug messages that may
+#                              // significantly impact boot performance
+#  DEBUG_ERROR     0x80000000  // Error
+  gEfiMdePkgTokenSpaceGuid.PcdDebugPrintErrorLevel|0x80000004
+
+  gEfiMdePkgTokenSpaceGuid.PcdReportStatusCodePropertyMask|0x07
+
+  gEmbeddedTokenSpaceGuid.PcdFlashFvMainBase|0
+  gEmbeddedTokenSpaceGuid.PcdFlashFvMainSize|0
+  gEmbeddedTokenSpaceGuid.PcdPrePiStackBase|0x87FE0000 # stack at top of memory
+  gEmbeddedTokenSpaceGuid.PcdPrePiStackSize|0x20000  # 128K stack
+  gArmTokenSpaceGuid.PcdCpuVectorBaseAddress|0x80000000
+  gArmTokenSpaceGuid.PcdCpuResetAddress|0x80008000
+
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxGpmcOffset|0x6E000000
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxMMCHS1Base|0x4809C000
+
+  # Console
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxConsoleUart|3
+
+  # Timers
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxArchTimer|3
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxFreeTimer|4
+  gEmbeddedTokenSpaceGuid.PcdTimerPeriod|100000
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPerformanceCounterPeriodInNanoseconds|77
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPerformanceCounterFrequencyInHz|13000000
+
+  # OMAP Interrupt Controller
+  gEmbeddedTokenSpaceGuid.PcdInterruptBaseAddress|0x48200000
+
+################################################################################
+#
+# Components Section - list of all EDK II Modules needed by this Platform
+#
+################################################################################
+[Components.common]
+  Omap35xxPkg/Library/Omap35xxTimerLib/Omap35xxTimerLib.inf
+  Omap35xxPkg/Library/OmapLib/OmapLib.inf
+  Omap35xxPkg/Library/OmapDmaLib/OmapDmaLib.inf
+
+  Omap35xxPkg/Flash/Flash.inf
+  Omap35xxPkg/MMCHSDxe/MMCHS.inf
+  Omap35xxPkg/SmbusDxe/Smbus.inf
+  Omap35xxPkg/Gpio/Gpio.inf
+  Omap35xxPkg/InterruptDxe/InterruptDxe.inf
+  Omap35xxPkg/TimerDxe/TimerDxe.inf
+  Omap35xxPkg/TPS65950Dxe/TPS65950.inf
+
+  Omap35xxPkg/LcdGraphicsOutputDxe/LcdGraphicsOutputDxe.inf
+  Omap35xxPkg/Library/DebugAgentTimerLib/DebugAgentTimerLib.inf
+  Omap35xxPkg/Library/GdbSerialLib/GdbSerialLib.inf
+  Omap35xxPkg/Library/RealTimeClockLib/RealTimeClockLib.inf
+  Omap35xxPkg/Library/SerialPortLib/SerialPortLib.inf
+  Omap35xxPkg/MmcHostDxe/MmcHostDxe.inf
+  Omap35xxPkg/PciEmulation/PciEmulation.inf
+
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.c b/Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.c
new file mode 100644
index 0000000000..a05d98183a
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.c
@@ -0,0 +1,107 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2016, Linaro, Ltd. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/NonDiscoverableDeviceRegistrationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/EmbeddedExternalDevice.h>
+
+#include <TPS65950.h>
+#include <Omap3530/Omap3530.h>
+
+EMBEDDED_EXTERNAL_DEVICE   *gTPS65950;
+
+#define HOST_CONTROLLER_OPERATION_REG_SIZE  0x44
+
+STATIC
+EFI_STATUS
+ConfigureUSBHost (
+  NON_DISCOVERABLE_DEVICE   *Device
+  )
+{
+  EFI_STATUS Status;
+  UINT8      Data = 0;
+
+  // Take USB host out of force-standby mode
+  MmioWrite32 (UHH_SYSCONFIG, UHH_SYSCONFIG_MIDLEMODE_NO_STANDBY
+                            | UHH_SYSCONFIG_CLOCKACTIVITY_ON
+                            | UHH_SYSCONFIG_SIDLEMODE_NO_STANDBY
+                            | UHH_SYSCONFIG_ENAWAKEUP_ENABLE
+                            | UHH_SYSCONFIG_AUTOIDLE_ALWAYS_RUN);
+  MmioWrite32 (UHH_HOSTCONFIG, UHH_HOSTCONFIG_P3_CONNECT_STATUS_DISCONNECT
+                             | UHH_HOSTCONFIG_P2_CONNECT_STATUS_DISCONNECT
+                             | UHH_HOSTCONFIG_P1_CONNECT_STATUS_DISCONNECT
+                             | UHH_HOSTCONFIG_ENA_INCR_ALIGN_DISABLE
+                             | UHH_HOSTCONFIG_ENA_INCR16_ENABLE
+                             | UHH_HOSTCONFIG_ENA_INCR8_ENABLE
+                             | UHH_HOSTCONFIG_ENA_INCR4_ENABLE
+                             | UHH_HOSTCONFIG_AUTOPPD_ON_OVERCUR_EN_ON
+                             | UHH_HOSTCONFIG_P1_ULPI_BYPASS_ULPI_MODE);
+
+  // USB reset (GPIO 147 - Port 5 pin 19) output high
+  MmioAnd32 (GPIO5_BASE + GPIO_OE, ~BIT19);
+  MmioWrite32 (GPIO5_BASE + GPIO_SETDATAOUT, BIT19);
+
+  // Get the Power IC protocol
+  Status = gBS->LocateProtocol (&gEmbeddedExternalDeviceProtocolGuid, NULL, (VOID **)&gTPS65950);
+  ASSERT_EFI_ERROR (Status);
+
+  // Power the USB PHY
+  Data = VAUX_DEV_GRP_P1;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VAUX2_DEV_GRP), 1, &Data);
+  ASSERT_EFI_ERROR(Status);
+
+  Data = VAUX_DEDICATED_18V;
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID4, VAUX2_DEDICATED), 1, &Data);
+  ASSERT_EFI_ERROR (Status);
+
+  // Enable power to the USB hub
+  Status = gTPS65950->Read (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID3, LEDEN), 1, &Data);
+  ASSERT_EFI_ERROR (Status);
+
+  // LEDAON controls the power to the USB host, PWM is disabled
+  Data &= ~LEDAPWM;
+  Data |= LEDAON;
+
+  Status = gTPS65950->Write (gTPS65950, EXTERNAL_DEVICE_REGISTER(I2C_ADDR_GRP_ID3, LEDEN), 1, &Data);
+  ASSERT_EFI_ERROR (Status);
+
+  return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PciEmulationEntryPoint (
+  IN EFI_HANDLE       ImageHandle,
+  IN EFI_SYSTEM_TABLE *SystemTable
+  )
+{
+  UINT8                   CapabilityLength;
+  UINT8                   PhysicalPorts;
+  UINTN                   MemorySize;
+
+  CapabilityLength = MmioRead8 (USB_EHCI_HCCAPBASE);
+  PhysicalPorts    = MmioRead32 (USB_EHCI_HCCAPBASE + 0x4) & 0x0000000F;
+  MemorySize       = CapabilityLength + HOST_CONTROLLER_OPERATION_REG_SIZE +
+                     4 * PhysicalPorts - 1;
+
+  return RegisterNonDiscoverableMmioDevice (
+           NonDiscoverableDeviceTypeEhci,
+           NonDiscoverableDeviceDmaTypeNonCoherent,
+           ConfigureUSBHost,
+           NULL,
+           1,
+           USB_EHCI_HCCAPBASE, MemorySize
+           );
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.inf b/Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.inf
new file mode 100644
index 0000000000..2e8e258985
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/PciEmulation/PciEmulation.inf
@@ -0,0 +1,41 @@
+/** @file
+
+  Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
+  Copyright (c) 2016, Linaro, Ltd. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+[Defines]
+  INF_VERSION                     = 0x00010005
+  BASE_NAME                       = BeagleBoardPciEmulation
+  FILE_GUID                       = feaa2e2b-53ac-4d5e-ae10-1efd5da4a2ba
+  MODULE_TYPE                     = DXE_DRIVER
+  VERSION_STRING                  = 1.0
+
+  ENTRY_POINT                     = PciEmulationEntryPoint
+
+[Sources.common]
+  PciEmulation.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  MdeModulePkg/MdeModulePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  DebugLib
+  IoLib
+  NonDiscoverableDeviceRegistrationLib
+  UefiBootServicesTableLib
+  UefiDriverEntryPoint
+
+[Protocols]
+  gEmbeddedExternalDeviceProtocolGuid
+
+[Depex]
+  gEfiMetronomeArchProtocolGuid AND
+  gEmbeddedExternalDeviceProtocolGuid
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.c b/Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.c
new file mode 100644
index 0000000000..894ba3313c
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.c
@@ -0,0 +1,319 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+#include <Omap3530/Omap3530.h>
+
+#include <Library/DebugLib.h>
+#include <Library/IoLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/SmbusHc.h>
+
+#define MAX_RETRY  1000
+
+//
+// Internal Functions
+//
+STATIC
+EFI_STATUS
+WaitForBusBusy (
+  VOID
+  )
+{
+  UINTN Retry = 0;
+
+  while (++Retry < MAX_RETRY && (MmioRead16(I2C_STAT) & BB) == 0x1);
+
+  if (Retry == MAX_RETRY) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+PollForStatus(
+  UINT16 StatusBit
+  )
+{
+  UINTN Retry = 0;
+
+  while(Retry < MAX_RETRY) {
+    if (MmioRead16(I2C_STAT) & StatusBit) {
+      //Clear particular status bit from Status register.
+      MmioOr16(I2C_STAT, StatusBit);
+      break;
+    }
+    Retry++;
+  }
+
+  if (Retry == MAX_RETRY) {
+    return EFI_TIMEOUT;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+ConfigureI2c (
+  VOID
+  )
+{
+  //Program prescaler to obtain 12-MHz clock
+  MmioWrite16(I2C_PSC, 0x0000);
+
+  //Program SCLL and SCLH
+  //NOTE: Following values are the register dump after U-Boot code executed.
+  //We need to figure out how its calculated based on the I2C functional clock and I2C_PSC.
+  MmioWrite16(I2C_SCLL, 0x0035);
+  MmioWrite16(I2C_SCLH, 0x0035);
+
+  //Take the I2C controller out of reset.
+  MmioOr16(I2C_CON, I2C_EN);
+
+  //Initialize the I2C controller.
+
+  //Set I2C controller in Master mode.
+  MmioOr16(I2C_CON, MST);
+
+  //Enable interrupts for receive/transmit mode.
+  MmioOr16(I2C_IE, (XRDY_IE | RRDY_IE | ARDY_IE | NACK_IE));
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+I2CReadOneByte (
+  UINT8 *Data
+  )
+{
+  EFI_STATUS Status;
+
+  //I2C bus status checking
+  Status = WaitForBusBusy();
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //Poll till Receive ready bit is set.
+  Status = PollForStatus(RRDY);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  *Data = MmioRead8(I2C_DATA);
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+I2CWriteOneByte (
+  UINT8 Data
+  )
+{
+  EFI_STATUS Status;
+
+  //I2C bus status checking
+  Status = WaitForBusBusy();
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //Data transfer
+  //Poll till Transmit ready bit is set
+  Status = PollForStatus(XRDY);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  MmioWrite8(I2C_DATA, Data);
+
+  //Wait and check if the NACK is not set.
+  gBS->Stall(1000);
+  if (MmioRead16(I2C_STAT) & NACK) {
+    return EFI_DEVICE_ERROR;
+  }
+
+  return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+SmbusBlockRead (
+  OUT UINT8       *Buffer,
+  IN  UINTN       Length
+  )
+{
+  UINTN      Index = 0;
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  //Transfer configuration for receiving data.
+  MmioWrite16(I2C_CNT, Length);
+  //Need stop bit before sending data.
+  MmioWrite16(I2C_CON, (I2C_EN | MST | STP | STT));
+
+  while (Index < Length) {
+    //Read a byte
+    Status = I2CReadOneByte(&Buffer[Index++]);
+    if (EFI_ERROR(Status)) {
+      return Status;
+    }
+  }
+
+  //Transfer completion
+  Status = PollForStatus(ARDY);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  return Status;
+}
+
+STATIC
+EFI_STATUS
+SmbusBlockWrite (
+  IN UINT8       *Buffer,
+  IN UINTN       Length
+  )
+{
+  UINTN      Index = 0;
+  EFI_STATUS Status = EFI_SUCCESS;
+
+  //Transfer configuration for transmitting data
+  MmioWrite16(I2C_CNT, Length);
+  MmioWrite16(I2C_CON, (I2C_EN | TRX | MST | STT | STP));
+
+  while (Index < Length) {
+    //Send a byte
+    Status = I2CWriteOneByte(Buffer[Index++]);
+    if (EFI_ERROR(Status)) {
+      return Status;
+    }
+  }
+
+  //Transfer completion
+  Status = PollForStatus(ARDY);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  return Status;
+}
+
+//
+// Public Functions.
+//
+EFI_STATUS
+EFIAPI
+SmbusExecute (
+  IN CONST EFI_SMBUS_HC_PROTOCOL    *This,
+  IN CONST EFI_SMBUS_DEVICE_ADDRESS SlaveAddress,
+  IN CONST EFI_SMBUS_DEVICE_COMMAND Command,
+  IN CONST EFI_SMBUS_OPERATION      Operation,
+  IN CONST BOOLEAN                  PecCheck,
+  IN OUT   UINTN                    *Length,
+  IN OUT   VOID                     *Buffer
+  )
+{
+  UINT8      *ByteBuffer  = Buffer;
+  EFI_STATUS Status       = EFI_SUCCESS;
+  UINT8      SlaveAddr    = (UINT8)(SlaveAddress.SmbusDeviceAddress);
+
+  if (PecCheck) {
+    return EFI_UNSUPPORTED;
+  }
+
+  if ((Operation != EfiSmbusWriteBlock) && (Operation != EfiSmbusReadBlock)) {
+    return EFI_UNSUPPORTED;
+  }
+
+  //Set the Slave address.
+  MmioWrite16(I2C_SA, SlaveAddr);
+
+  if (Operation == EfiSmbusReadBlock) {
+    Status = SmbusBlockRead(ByteBuffer, *Length);
+  } else if (Operation == EfiSmbusWriteBlock) {
+    Status = SmbusBlockWrite(ByteBuffer, *Length);
+  }
+
+  return Status;
+}
+
+EFI_STATUS
+EFIAPI
+SmbusArpDevice (
+  IN CONST EFI_SMBUS_HC_PROTOCOL    *This,
+  IN       BOOLEAN                  ArpAll,
+  IN       EFI_SMBUS_UDID           *SmbusUdid OPTIONAL,
+  IN OUT   EFI_SMBUS_DEVICE_ADDRESS *SlaveAddress OPTIONAL
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+
+EFI_STATUS
+EFIAPI
+SmbusGetArpMap (
+  IN CONST EFI_SMBUS_HC_PROTOCOL    *This,
+  IN OUT   UINTN                    *Length,
+  IN OUT   EFI_SMBUS_DEVICE_MAP     **SmbusDeviceMap
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+
+EFI_STATUS
+EFIAPI
+SmbusNotify (
+  IN CONST  EFI_SMBUS_HC_PROTOCOL     *This,
+  IN CONST  EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress,
+  IN CONST  UINTN                     Data,
+  IN CONST  EFI_SMBUS_NOTIFY_FUNCTION NotifyFunction
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+EFI_SMBUS_HC_PROTOCOL SmbusProtocol =
+{
+  SmbusExecute,
+  SmbusArpDevice,
+  SmbusGetArpMap,
+  SmbusNotify
+};
+
+EFI_STATUS
+InitializeSmbus (
+    IN EFI_HANDLE       ImageHandle,
+    IN EFI_SYSTEM_TABLE *SystemTable
+    )
+{
+  EFI_HANDLE      Handle = NULL;
+  EFI_STATUS      Status;
+
+  //Configure I2C controller.
+  Status = ConfigureI2c();
+  if (EFI_ERROR(Status)) {
+    DEBUG ((EFI_D_ERROR, "InitializeI2c fails.\n"));
+    return Status;
+  }
+
+  // Install the SMBUS interface
+  Status = gBS->InstallMultipleProtocolInterfaces(&Handle, &gEfiSmbusHcProtocolGuid, &SmbusProtocol, NULL);
+  ASSERT_EFI_ERROR(Status);
+
+  return Status;
+}
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.inf b/Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.inf
new file mode 100644
index 0000000000..0a3f4240ba
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/SmbusDxe/Smbus.inf
@@ -0,0 +1,39 @@
+#/** @file
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = Smbus
+  FILE_GUID                      = d5125e0f-1226-444f-a218-0085996ed5da
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = InitializeSmbus
+
+[Sources.common]
+  Smbus.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  PcdLib
+  UefiLib
+  UefiDriverEntryPoint
+  MemoryAllocationLib
+  IoLib
+
+[Guids]
+
+[Protocols]
+  gEfiSmbusHcProtocolGuid
+
+[Pcd]
+
+[depex]
+  TRUE
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.c b/Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.c
new file mode 100644
index 0000000000..a5107dcc15
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.c
@@ -0,0 +1,110 @@
+/** @file
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <Uefi.h>
+
+#include <TPS65950.h>
+
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/EmbeddedExternalDevice.h>
+#include <Protocol/SmbusHc.h>
+
+EFI_SMBUS_HC_PROTOCOL *Smbus;
+
+EFI_STATUS
+Read (
+  IN  EMBEDDED_EXTERNAL_DEVICE    *This,
+  IN  UINTN                       Register,
+  IN  UINTN                       Length,
+  OUT VOID                        *Buffer
+  )
+{
+  EFI_STATUS               Status;
+  EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+  UINT8                    DeviceRegister;
+  UINTN                    DeviceRegisterLength = 1;
+
+  SlaveAddress.SmbusDeviceAddress = EXTERNAL_DEVICE_REGISTER_TO_SLAVE_ADDRESS(Register);
+  DeviceRegister = (UINT8)EXTERNAL_DEVICE_REGISTER_TO_REGISTER(Register);
+
+  //Write DeviceRegister.
+  Status = Smbus->Execute(Smbus, SlaveAddress, 0, EfiSmbusWriteBlock, FALSE, &DeviceRegisterLength, &DeviceRegister);
+  if (EFI_ERROR(Status)) {
+    return Status;
+  }
+
+  //Read Data
+  Status = Smbus->Execute(Smbus, SlaveAddress, 0, EfiSmbusReadBlock, FALSE, &Length, Buffer);
+  return Status;
+}
+
+EFI_STATUS
+Write (
+  IN EMBEDDED_EXTERNAL_DEVICE   *This,
+  IN UINTN                      Register,
+  IN UINTN                      Length,
+  IN VOID                       *Buffer
+  )
+{
+  EFI_STATUS               Status;
+  EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+  UINT8                    DeviceRegister;
+  UINTN                    DeviceBufferLength = Length + 1;
+  UINT8                    *DeviceBuffer;
+
+  SlaveAddress.SmbusDeviceAddress = EXTERNAL_DEVICE_REGISTER_TO_SLAVE_ADDRESS(Register);
+  DeviceRegister = (UINT8)EXTERNAL_DEVICE_REGISTER_TO_REGISTER(Register);
+
+  //Prepare buffer for writing
+  DeviceBuffer = (UINT8 *)AllocatePool(DeviceBufferLength);
+  if (DeviceBuffer == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto exit;
+  }
+
+  //Set Device register followed by data to write.
+  DeviceBuffer[0] = DeviceRegister;
+  CopyMem(&DeviceBuffer[1], Buffer, Length);
+
+  //Write Data
+  Status = Smbus->Execute(Smbus, SlaveAddress, 0, EfiSmbusWriteBlock, FALSE, &DeviceBufferLength, DeviceBuffer);
+  if (EFI_ERROR(Status)) {
+    goto exit;
+  }
+
+exit:
+  if (DeviceBuffer) {
+    FreePool(DeviceBuffer);
+  }
+
+  return Status;
+}
+
+EMBEDDED_EXTERNAL_DEVICE ExternalDevice = {
+  Read,
+  Write
+};
+
+EFI_STATUS
+TPS65950Initialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_STATUS  Status;
+
+  Status = gBS->LocateProtocol(&gEfiSmbusHcProtocolGuid, NULL, (VOID **)&Smbus);
+  ASSERT_EFI_ERROR(Status);
+
+  Status = gBS->InstallMultipleProtocolInterfaces(&ImageHandle, &gEmbeddedExternalDeviceProtocolGuid, &ExternalDevice, NULL);
+  return Status;
+}
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.inf b/Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.inf
new file mode 100644
index 0000000000..e37d0a0f52
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/TPS65950Dxe/TPS65950.inf
@@ -0,0 +1,42 @@
+#/** @file
+#
+#  Copyright (c) 2008 - 2010, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = TPS65950
+  FILE_GUID                      = 71fe861a-5450-48b6-bfb0-b93522616f99
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = TPS65950Initialize
+
+
+[Sources.common]
+  TPS65950.c
+
+[Packages]
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  Omap35xxPkg/Omap35xxPkg.dec
+
+[LibraryClasses]
+  BaseMemoryLib
+  PcdLib
+  UefiLib
+  UefiDriverEntryPoint
+  MemoryAllocationLib
+
+[Guids]
+
+[Protocols]
+  gEfiSmbusHcProtocolGuid
+  gEmbeddedExternalDeviceProtocolGuid
+
+[Pcd]
+
+[depex]
+  gEfiSmbusHcProtocolGuid
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/Timer.c b/Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/Timer.c
new file mode 100644
index 0000000000..da7cd9f6b7
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/Timer.c
@@ -0,0 +1,370 @@
+/** @file
+  Template for Timer Architecture Protocol driver of the ARM flavor
+
+  Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
+
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <PiDxe.h>
+
+#include <Library/BaseLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/PcdLib.h>
+#include <Library/IoLib.h>
+#include <Library/OmapLib.h>
+
+#include <Protocol/Timer.h>
+#include <Protocol/HardwareInterrupt.h>
+
+#include <Omap3530/Omap3530.h>
+
+
+// The notification function to call on every timer interrupt.
+volatile EFI_TIMER_NOTIFY      mTimerNotifyFunction   = (EFI_TIMER_NOTIFY)NULL;
+
+
+// The current period of the timer interrupt
+volatile UINT64 mTimerPeriod = 0;
+
+// Cached copy of the Hardware Interrupt protocol instance
+EFI_HARDWARE_INTERRUPT_PROTOCOL *gInterrupt = NULL;
+
+// Cached registers
+volatile UINT32 TISR;
+volatile UINT32 TCLR;
+volatile UINT32 TLDR;
+volatile UINT32 TCRR;
+volatile UINT32 TIER;
+
+// Cached interrupt vector
+volatile UINTN  gVector;
+
+
+/**
+
+  C Interrupt Handler calledin the interrupt context when Source interrupt is active.
+
+
+  @param Source         Source of the interrupt. Hardware routing off a specific platform defines
+                        what source means.
+
+  @param SystemContext  Pointer to system register context. Mostly used by debuggers and will
+                        update the system context after the return from the interrupt if
+                        modified. Don't change these values unless you know what you are doing
+
+**/
+VOID
+EFIAPI
+TimerInterruptHandler (
+  IN  HARDWARE_INTERRUPT_SOURCE   Source,
+  IN  EFI_SYSTEM_CONTEXT          SystemContext
+  )
+{
+  EFI_TPL OriginalTPL;
+
+
+
+  //
+  // DXE core uses this callback for the EFI timer tick. The DXE core uses locks
+  // that raise to TPL_HIGH and then restore back to current level. Thus we need
+  // to make sure TPL level is set to TPL_HIGH while we are handling the timer tick.
+  //
+  OriginalTPL = gBS->RaiseTPL (TPL_HIGH_LEVEL);
+
+  if (mTimerNotifyFunction) {
+    mTimerNotifyFunction(mTimerPeriod);
+  }
+
+  // Clear all timer interrupts
+  MmioWrite32 (TISR, TISR_CLEAR_ALL);
+
+  // Poll interrupt status bits to ensure clearing
+  while ((MmioRead32 (TISR) & TISR_ALL_INTERRUPT_MASK) != TISR_NO_INTERRUPTS_PENDING);
+
+  gBS->RestoreTPL (OriginalTPL);
+}
+
+/**
+  This function registers the handler NotifyFunction so it is called every time
+  the timer interrupt fires.  It also passes the amount of time since the last
+  handler call to the NotifyFunction.  If NotifyFunction is NULL, then the
+  handler is unregistered.  If the handler is registered, then EFI_SUCCESS is
+  returned.  If the CPU does not support registering a timer interrupt handler,
+  then EFI_UNSUPPORTED is returned.  If an attempt is made to register a handler
+  when a handler is already registered, then EFI_ALREADY_STARTED is returned.
+  If an attempt is made to unregister a handler when a handler is not registered,
+  then EFI_INVALID_PARAMETER is returned.  If an error occurs attempting to
+  register the NotifyFunction with the timer interrupt, then EFI_DEVICE_ERROR
+  is returned.
+
+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param  NotifyFunction   The function to call when a timer interrupt fires. This
+                           function executes at TPL_HIGH_LEVEL. The DXE Core will
+                           register a handler for the timer interrupt, so it can know
+                           how much time has passed. This information is used to
+                           signal timer based events. NULL will unregister the handler.
+  @retval EFI_SUCCESS           The timer handler was registered.
+  @retval EFI_UNSUPPORTED       The platform does not support timer interrupts.
+  @retval EFI_ALREADY_STARTED   NotifyFunction is not NULL, and a handler is already
+                                registered.
+  @retval EFI_INVALID_PARAMETER NotifyFunction is NULL, and a handler was not
+                                previously registered.
+  @retval EFI_DEVICE_ERROR      The timer handler could not be registered.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverRegisterHandler (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN EFI_TIMER_NOTIFY         NotifyFunction
+  )
+{
+  if ((NotifyFunction == NULL) && (mTimerNotifyFunction == NULL)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if ((NotifyFunction != NULL) && (mTimerNotifyFunction != NULL)) {
+    return EFI_ALREADY_STARTED;
+  }
+
+  mTimerNotifyFunction = NotifyFunction;
+
+  return EFI_SUCCESS;
+}
+
+/**
+
+  This function adjusts the period of timer interrupts to the value specified
+  by TimerPeriod.  If the timer period is updated, then the selected timer
+  period is stored in EFI_TIMER.TimerPeriod, and EFI_SUCCESS is returned.  If
+  the timer hardware is not programmable, then EFI_UNSUPPORTED is returned.
+  If an error occurs while attempting to update the timer period, then the
+  timer hardware will be put back in its state prior to this call, and
+  EFI_DEVICE_ERROR is returned.  If TimerPeriod is 0, then the timer interrupt
+  is disabled.  This is not the same as disabling the CPU's interrupts.
+  Instead, it must either turn off the timer hardware, or it must adjust the
+  interrupt controller so that a CPU interrupt is not generated when the timer
+  interrupt fires.
+
+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param  TimerPeriod      The rate to program the timer interrupt in 100 nS units. If
+                           the timer hardware is not programmable, then EFI_UNSUPPORTED is
+                           returned. If the timer is programmable, then the timer period
+                           will be rounded up to the nearest timer period that is supported
+                           by the timer hardware. If TimerPeriod is set to 0, then the
+                           timer interrupts will be disabled.
+
+
+  @retval EFI_SUCCESS           The timer period was changed.
+  @retval EFI_UNSUPPORTED       The platform cannot change the period of the timer interrupt.
+  @retval EFI_DEVICE_ERROR      The timer period could not be changed due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverSetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This,
+  IN UINT64                   TimerPeriod
+  )
+{
+  EFI_STATUS  Status;
+  UINT64      TimerCount;
+  INT32       LoadValue;
+
+  if (TimerPeriod == 0) {
+    // Turn off GPTIMER3
+    MmioWrite32 (TCLR, TCLR_ST_OFF);
+
+    Status = gInterrupt->DisableInterruptSource(gInterrupt, gVector);
+  } else {
+    // Calculate required timer count
+    TimerCount = DivU64x32(TimerPeriod * 100, PcdGet32(PcdEmbeddedPerformanceCounterPeriodInNanoseconds));
+
+    // Set GPTIMER3 Load register
+    LoadValue = (INT32) -TimerCount;
+    MmioWrite32 (TLDR, LoadValue);
+    MmioWrite32 (TCRR, LoadValue);
+
+    // Enable Overflow interrupt
+    MmioWrite32 (TIER, TIER_TCAR_IT_DISABLE | TIER_OVF_IT_ENABLE | TIER_MAT_IT_DISABLE);
+
+    // Turn on GPTIMER3, it will reload at overflow
+    MmioWrite32 (TCLR, TCLR_AR_AUTORELOAD | TCLR_ST_ON);
+
+    Status = gInterrupt->EnableInterruptSource(gInterrupt, gVector);
+  }
+
+  //
+  // Save the new timer period
+  //
+  mTimerPeriod = TimerPeriod;
+  return Status;
+}
+
+
+/**
+  This function retrieves the period of timer interrupts in 100 ns units,
+  returns that value in TimerPeriod, and returns EFI_SUCCESS.  If TimerPeriod
+  is NULL, then EFI_INVALID_PARAMETER is returned.  If a TimerPeriod of 0 is
+  returned, then the timer is currently disabled.
+
+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
+  @param  TimerPeriod      A pointer to the timer period to retrieve in 100 ns units. If
+                           0 is returned, then the timer is currently disabled.
+
+
+  @retval EFI_SUCCESS           The timer period was returned in TimerPeriod.
+  @retval EFI_INVALID_PARAMETER TimerPeriod is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGetTimerPeriod (
+  IN EFI_TIMER_ARCH_PROTOCOL   *This,
+  OUT UINT64                   *TimerPeriod
+  )
+{
+  if (TimerPeriod == NULL) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  *TimerPeriod = mTimerPeriod;
+  return EFI_SUCCESS;
+}
+
+/**
+  This function generates a soft timer interrupt. If the platform does not support soft
+  timer interrupts, then EFI_UNSUPPORTED is returned. Otherwise, EFI_SUCCESS is returned.
+  If a handler has been registered through the EFI_TIMER_ARCH_PROTOCOL.RegisterHandler()
+  service, then a soft timer interrupt will be generated. If the timer interrupt is
+  enabled when this service is called, then the registered handler will be invoked. The
+  registered handler should not be able to distinguish a hardware-generated timer
+  interrupt from a software-generated timer interrupt.
+
+  @param  This             The EFI_TIMER_ARCH_PROTOCOL instance.
+
+  @retval EFI_SUCCESS           The soft timer interrupt was generated.
+  @retval EFI_UNSUPPORTED       The platform does not support the generation of soft timer interrupts.
+
+**/
+EFI_STATUS
+EFIAPI
+TimerDriverGenerateSoftInterrupt (
+  IN EFI_TIMER_ARCH_PROTOCOL  *This
+  )
+{
+  return EFI_UNSUPPORTED;
+}
+
+
+/**
+  Interface stucture for the Timer Architectural Protocol.
+
+  @par Protocol Description:
+  This protocol provides the services to initialize a periodic timer
+  interrupt, and to register a handler that is called each time the timer
+  interrupt fires.  It may also provide a service to adjust the rate of the
+  periodic timer interrupt.  When a timer interrupt occurs, the handler is
+  passed the amount of time that has passed since the previous timer
+  interrupt.
+
+  @param RegisterHandler
+  Registers a handler that will be called each time the
+  timer interrupt fires.  TimerPeriod defines the minimum
+  time between timer interrupts, so TimerPeriod will also
+  be the minimum time between calls to the registered
+  handler.
+
+  @param SetTimerPeriod
+  Sets the period of the timer interrupt in 100 nS units.
+  This function is optional, and may return EFI_UNSUPPORTED.
+  If this function is supported, then the timer period will
+  be rounded up to the nearest supported timer period.
+
+
+  @param GetTimerPeriod
+  Retrieves the period of the timer interrupt in 100 nS units.
+
+  @param GenerateSoftInterrupt
+  Generates a soft timer interrupt that simulates the firing of
+  the timer interrupt. This service can be used to invoke the   registered handler if the timer interrupt has been masked for
+  a period of time.
+
+**/
+EFI_TIMER_ARCH_PROTOCOL   gTimer = {
+  TimerDriverRegisterHandler,
+  TimerDriverSetTimerPeriod,
+  TimerDriverGetTimerPeriod,
+  TimerDriverGenerateSoftInterrupt
+};
+
+
+/**
+  Initialize the state information for the Timer Architectural Protocol and
+  the Timer Debug support protocol that allows the debugger to break into a
+  running program.
+
+  @param  ImageHandle   of the loaded driver
+  @param  SystemTable   Pointer to the System Table
+
+  @retval EFI_SUCCESS           Protocol registered
+  @retval EFI_OUT_OF_RESOURCES  Cannot allocate protocol data structure
+  @retval EFI_DEVICE_ERROR      Hardware problems
+
+**/
+EFI_STATUS
+EFIAPI
+TimerInitialize (
+  IN EFI_HANDLE         ImageHandle,
+  IN EFI_SYSTEM_TABLE   *SystemTable
+  )
+{
+  EFI_HANDLE  Handle = NULL;
+  EFI_STATUS  Status;
+  UINT32      TimerBaseAddress;
+
+  // Find the interrupt controller protocol.  ASSERT if not found.
+  Status = gBS->LocateProtocol (&gHardwareInterruptProtocolGuid, NULL, (VOID **)&gInterrupt);
+  ASSERT_EFI_ERROR (Status);
+
+  // Set up the timer registers
+  TimerBaseAddress = TimerBase (FixedPcdGet32(PcdOmap35xxArchTimer));
+  TISR = TimerBaseAddress + GPTIMER_TISR;
+  TCLR = TimerBaseAddress + GPTIMER_TCLR;
+  TLDR = TimerBaseAddress + GPTIMER_TLDR;
+  TCRR = TimerBaseAddress + GPTIMER_TCRR;
+  TIER = TimerBaseAddress + GPTIMER_TIER;
+
+  // Disable the timer
+  Status = TimerDriverSetTimerPeriod (&gTimer, 0);
+  ASSERT_EFI_ERROR (Status);
+
+  // Install interrupt handler
+  gVector = InterruptVectorForTimer (FixedPcdGet32(PcdOmap35xxArchTimer));
+  Status = gInterrupt->RegisterInterruptSource (gInterrupt, gVector, TimerInterruptHandler);
+  ASSERT_EFI_ERROR (Status);
+
+  // Turn on the functional clock for Timer
+  MmioOr32 (CM_FCLKEN_PER, CM_FCLKEN_PER_EN_GPT3_ENABLE);
+
+  // Set up default timer
+  Status = TimerDriverSetTimerPeriod (&gTimer, FixedPcdGet32(PcdTimerPeriod));
+  ASSERT_EFI_ERROR (Status);
+
+  // Install the Timer Architectural Protocol onto a new handle
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &Handle,
+                  &gEfiTimerArchProtocolGuid,      &gTimer,
+                  NULL
+                  );
+  ASSERT_EFI_ERROR(Status);
+
+  return Status;
+}
+
diff --git a/Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/TimerDxe.inf b/Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/TimerDxe.inf
new file mode 100644
index 0000000000..e072982d51
--- /dev/null
+++ b/Silicon/TexasInsturments/Omap35xxPkg/TimerDxe/TimerDxe.inf
@@ -0,0 +1,51 @@
+#/** @file
+#
+#    Component description file for Timer module
+#
+#  Copyright (c) 2009, Apple Inc. All rights reserved.<BR>
+#  SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+#**/
+
+[Defines]
+  INF_VERSION                    = 0x00010005
+  BASE_NAME                      = BeagleBoardTimerDxe
+  FILE_GUID                      = 6ddbf08b-cfc9-43cc-9e81-0784ba312ca0
+  MODULE_TYPE                    = DXE_DRIVER
+  VERSION_STRING                 = 1.0
+
+  ENTRY_POINT                    = TimerInitialize
+
+[Sources.common]
+  Timer.c
+
+[Packages]
+  Omap35xxPkg/Omap35xxPkg.dec
+  MdePkg/MdePkg.dec
+  EmbeddedPkg/EmbeddedPkg.dec
+  ArmPkg/ArmPkg.dec
+
+[LibraryClasses]
+  BaseLib
+  UefiRuntimeServicesTableLib
+  UefiLib
+  UefiBootServicesTableLib
+  BaseMemoryLib
+  DebugLib
+  UefiDriverEntryPoint
+  IoLib
+  OmapLib
+
+[Guids]
+
+[Protocols]
+  gEfiTimerArchProtocolGuid
+  gHardwareInterruptProtocolGuid
+
+[Pcd.common]
+  gEmbeddedTokenSpaceGuid.PcdTimerPeriod
+  gEmbeddedTokenSpaceGuid.PcdEmbeddedPerformanceCounterPeriodInNanoseconds
+  gOmap35xxTokenSpaceGuid.PcdOmap35xxArchTimer
+
+[Depex]
+  gHardwareInterruptProtocolGuid
-- 
2.21.0.windows.1


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#40397): https://edk2.groups.io/g/devel/message/40397
Mute This Topic: https://groups.io/mt/31573400/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-




More information about the edk2-devel-archive mailing list