From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mx.groups.io; dkim=missing; spf=fail (domain: intel.com, ip: , mailfrom: michael.d.kinney@intel.com) Received: from mga07.intel.com (mga07.intel.com []) by groups.io with SMTP; Thu, 09 May 2019 20:34:39 -0700 X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga105.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 May 2019 20:34:38 -0700 X-ExtLoop1: 1 Received: from unknown (HELO mdkinney-MOBL2.amr.corp.intel.com) ([10.241.98.74]) by orsmga002.jf.intel.com with ESMTP; 09 May 2019 20:34:37 -0700 From: "Michael D Kinney" To: devel@edk2.groups.io Cc: Leif Lindholm , Ard Biesheuvel Subject: [edk2-platforms: Patch 1/8] Silicon/TexasInsturments: Import Omap35xxPkg from edk2 Date: Thu, 9 May 2019 20:34:28 -0700 Message-Id: <20190510033435.24112-2-michael.d.kinney@intel.com> X-Mailer: git-send-email 2.21.0.windows.1 In-Reply-To: <20190510033435.24112-1-michael.d.kinney@intel.com> References: <20190510033435.24112-1-michael.d.kinney@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit https://bugzilla.tianocore.org/show_bug.cgi?id=1467 Import Omap35xxPkg from edk2/master. Cc: Leif Lindholm Cc: Ard Biesheuvel Signed-off-by: Michael D Kinney --- .../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.
+ + 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.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef FLASH_H +#define FLASH_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#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.
+# 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.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include + +#include + +#include + +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.
+# 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.
+ + 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.
+ + 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.
+ + 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.
+ + 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.
+ + 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.
+ + 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.
+ + 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.
+ Copyright (c) 2016, Linaro Ltd. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __OMAP3530INTERRUPT_H__ +#define __OMAP3530INTERRUPT_H__ + +#include + +#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.
+ + 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.
+ + 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.
+ + 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.
+ + 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.
+ + 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.
+ + 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.
+ + 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.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +// +// 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.
+# 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.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + + **/ + +#include +#include +#include +#include +#include +#include + +#include + +#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.
+ 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.
+ SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __OMAP3_DSS_GRAPHICS__ +#define __OMAP3_DSS_GRAPHICS__ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include + +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.
+# 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.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ +#include +#include +#include +#include +#include +#include + +#include + + +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.
+# +# 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.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +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.
+# 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.
+# +# 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.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +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.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include + + +/** + 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.
+# 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.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include + +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.
+# 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 + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + + +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.
+ Copyright (c) 2015, Intel Corporation. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include +#include +#include +#include +#include +#include + +/* + + 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.
+# Copyright (c) 2009, Apple Inc. All rights reserved.
+# +# 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.
+ + 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.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef _MMCHS_H_ +#define _MMCHS_H_ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#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.
+# 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#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.
+# +# 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.
+# Copyright (c) 2016, Linaro Ltd. All rights reserved.
+# +# 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.
+ Copyright (c) 2016, Linaro, Ltd. All rights reserved.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include +#include +#include +#include +#include + +#include + +#include +#include + +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.
+ Copyright (c) 2016, Linaro, Ltd. All rights reserved.
+ + 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.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include +#include + +#include +#include +#include + +#include + +#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.
+# 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.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include + +#include + +#include +#include +#include +#include + +#include +#include + +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.
+# 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.
+ + SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + + +// 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.
+# 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