From 633724f462a7117bc26838e66825e3b1bec506cc Mon Sep 17 00:00:00 2001 From: oliviermartin Date: Fri, 1 Jul 2011 15:40:16 +0000 Subject: [PATCH] ArmPkg: Move ARM Platform drivers from ArmPkg/Drivers/ to ArmPlatformPkg/Drivers/ (2) ... svn did not like my way to move folder from one directory to another one :-/ git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11957 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.c | 537 ++++++++++++++++++ ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.h | 119 ++++ .../Drivers/PL180MciDxe/PL180MciDxe.inf | 52 ++ ArmPlatformPkg/Drivers/PL301Axi/PL301Axi.c | 108 ++++ ArmPlatformPkg/Drivers/PL301Axi/PL301Axi.inf | 27 + .../Drivers/PL310L2Cache/PL310L2Cache.c | 126 ++++ .../Drivers/PL310L2Cache/PL310L2CacheSec.inf | 31 + ArmPlatformPkg/Drivers/PL34xDmc/PL341Dmc.c | 221 +++++++ ArmPlatformPkg/Drivers/PL34xDmc/PL341Dmc.inf | 29 + .../Drivers/PL35xSmc/InitializeSMC.S | 196 +++++++ .../Drivers/PL35xSmc/InitializeSMC.asm | 153 +++++ ArmPlatformPkg/Drivers/PL35xSmc/PL35xSmc.inf | 29 + .../Library/L2X0CacheLibNull/L2X0Cache.c | 30 + .../L2X0CacheLibNull/L2X0CacheLibNull.inf | 27 + 14 files changed, 1685 insertions(+) create mode 100644 ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.c create mode 100644 ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.h create mode 100755 ArmPlatformPkg/Drivers/PL180MciDxe/PL180MciDxe.inf create mode 100644 ArmPlatformPkg/Drivers/PL301Axi/PL301Axi.c create mode 100755 ArmPlatformPkg/Drivers/PL301Axi/PL301Axi.inf create mode 100644 ArmPlatformPkg/Drivers/PL310L2Cache/PL310L2Cache.c create mode 100755 ArmPlatformPkg/Drivers/PL310L2Cache/PL310L2CacheSec.inf create mode 100644 ArmPlatformPkg/Drivers/PL34xDmc/PL341Dmc.c create mode 100755 ArmPlatformPkg/Drivers/PL34xDmc/PL341Dmc.inf create mode 100755 ArmPlatformPkg/Drivers/PL35xSmc/InitializeSMC.S create mode 100755 ArmPlatformPkg/Drivers/PL35xSmc/InitializeSMC.asm create mode 100755 ArmPlatformPkg/Drivers/PL35xSmc/PL35xSmc.inf create mode 100644 ArmPlatformPkg/Library/L2X0CacheLibNull/L2X0Cache.c create mode 100755 ArmPlatformPkg/Library/L2X0CacheLibNull/L2X0CacheLibNull.inf diff --git a/ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.c b/ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.c new file mode 100644 index 0000000000..697e33f0d0 --- /dev/null +++ b/ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.c @@ -0,0 +1,537 @@ +/** @file + This file implement the MMC Host Protocol for the ARM PrimeCell PL180. + + Copyright (c) 2011, ARM Limited. All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "PL180Mci.h" + +#include +#include + +EFI_MMC_HOST_PROTOCOL *gpMmcHost; + +// Untested ... +//#define USE_STREAM + +#define MMCI0_BLOCKLEN 512 +#define MMCI0_POW2_BLOCKLEN 9 +#define MMCI0_TIMEOUT 1000 + +BOOLEAN +MciIsPowerOn ( + VOID + ) +{ + return ((MmioRead32(MCI_POWER_CONTROL_REG) & 0x3) == MCI_POWER_ON); +} + +EFI_STATUS +MciInitialize ( + VOID + ) +{ + MCI_TRACE("MciInitialize()"); + return EFI_SUCCESS; +} + +BOOLEAN +MciIsCardPresent ( + VOID + ) +{ + return (MmioRead32(FixedPcdGet32(PcdPL180SysMciRegAddress)) & 1); +} + +BOOLEAN +MciIsReadOnly ( + VOID + ) +{ + return (MmioRead32(FixedPcdGet32(PcdPL180SysMciRegAddress)) & 2); +} + +#if 0 +//Note: This function has been commented out because it is not used yet. +// This function could be used to remove the hardcoded BlockLen used +// in MciPrepareDataPath + +// Convert block size to 2^n +STATIC +UINT32 +GetPow2BlockLen ( + IN UINT32 BlockLen + ) +{ + UINTN Loop; + UINTN Pow2BlockLen; + + Loop = 0x8000; + Pow2BlockLen = 15; + do { + Loop = (Loop >> 1) & 0xFFFF; + Pow2BlockLen--; + } while (Pow2BlockLen && (!(Loop & BlockLen))); + + return Pow2BlockLen; +} +#endif + +VOID +MciPrepareDataPath ( + IN UINTN TransferDirection + ) +{ + // Set Data Length & Data Timer + MmioWrite32(MCI_DATA_TIMER_REG,0xFFFFFFF); + MmioWrite32(MCI_DATA_LENGTH_REG,MMCI0_BLOCKLEN); + +#ifndef USE_STREAM + //Note: we are using a hardcoded BlockLen (=512). If we decide to use a variable size, we could + // compute the pow2 of BlockLen with the above function GetPow2BlockLen() + MmioWrite32(MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_DMA_ENABLE | TransferDirection | (MMCI0_POW2_BLOCKLEN << 4)); +#else + MmioWrite32(MCI_DATA_CTL_REG, MCI_DATACTL_ENABLE | MCI_DATACTL_DMA_ENABLE | TransferDirection | MCI_DATACTL_STREAM_TRANS); +#endif +} + +EFI_STATUS +MciSendCommand ( + IN MMC_CMD MmcCmd, + IN UINT32 Argument + ) +{ + UINT32 Status; + UINT32 Cmd; + UINTN RetVal; + UINTN CmdCtrlReg; + + RetVal = EFI_SUCCESS; + + if ((MmcCmd == MMC_CMD17) || (MmcCmd == MMC_CMD11)) { + MciPrepareDataPath(MCI_DATACTL_CARD_TO_CONT); + } else if ((MmcCmd == MMC_CMD24) || (MmcCmd == MMC_CMD20)) { + MciPrepareDataPath(MCI_DATACTL_CONT_TO_CARD); + } + + // Create Command for PL180 + Cmd = (MMC_GET_INDX(MmcCmd) & INDX_MASK) | MCI_CPSM_ENABLED; + if (MmcCmd & MMC_CMD_WAIT_RESPONSE) { + Cmd |= MCI_CPSM_WAIT_RESPONSE; + } + + if (MmcCmd & MMC_CMD_LONG_RESPONSE) { + Cmd |= MCI_CPSM_LONG_RESPONSE; + } + + // Clear Status register static flags + MmioWrite32(MCI_CLEAR_STATUS_REG,0x7FF); + + //Write to command argument register + MmioWrite32(MCI_ARGUMENT_REG,Argument); + + //Write to command register + MmioWrite32(MCI_COMMAND_REG,Cmd); + + if (Cmd & MCI_CPSM_WAIT_RESPONSE) { + Status = MmioRead32(MCI_STATUS_REG); + while (!(Status & (MCI_STATUS_CMD_RESPEND | MCI_STATUS_CMD_CMDCRCFAIL | MCI_STATUS_CMD_CMDTIMEOUT | MCI_STATUS_CMD_START_BIT_ERROR))) { + Status = MmioRead32(MCI_STATUS_REG); + } + + if ((Status & MCI_STATUS_CMD_START_BIT_ERROR)) { + DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) Start bit Error! Response:0x%X Status:0x%x\n",(Cmd & 0x3F),MmioRead32(MCI_RESPONSE0_REG),Status)); + RetVal = EFI_NO_RESPONSE; + goto Exit; + } else if ((Status & MCI_STATUS_CMD_CMDTIMEOUT)) { + //DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) TIMEOUT! Response:0x%X Status:0x%x\n",(Cmd & 0x3F),MmioRead32(MCI_RESPONSE0_REG),Status)); + RetVal = EFI_TIMEOUT; + goto Exit; + } else if ((!(MmcCmd & MMC_CMD_NO_CRC_RESPONSE)) && (Status & MCI_STATUS_CMD_CMDCRCFAIL)) { + // The CMD1 and response type R3 do not contain CRC. We should ignore the CRC failed Status. + RetVal = EFI_CRC_ERROR; + goto Exit; + } else { + RetVal = EFI_SUCCESS; + goto Exit; + } + } else { + Status = MmioRead32(MCI_STATUS_REG); + while (!(Status & (MCI_STATUS_CMD_SENT | MCI_STATUS_CMD_CMDCRCFAIL | MCI_STATUS_CMD_CMDTIMEOUT| MCI_STATUS_CMD_START_BIT_ERROR))) { + Status = MmioRead32(MCI_STATUS_REG); + } + + if ((Status & MCI_STATUS_CMD_START_BIT_ERROR)) { + DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) Start bit Error! Response:0x%X Status:0x%x\n",(Cmd & 0x3F),MmioRead32(MCI_RESPONSE0_REG),Status)); + RetVal = EFI_NO_RESPONSE; + goto Exit; + } else if ((Status & MCI_STATUS_CMD_CMDTIMEOUT)) { + //DEBUG ((EFI_D_ERROR, "MciSendCommand(CmdIndex:%d) TIMEOUT! Response:0x%X Status:0x%x\n",(Cmd & 0x3F),MmioRead32(MCI_RESPONSE0_REG),Status)); + RetVal = EFI_TIMEOUT; + goto Exit; + } else + if ((!(MmcCmd & MMC_CMD_NO_CRC_RESPONSE)) && (Status & MCI_STATUS_CMD_CMDCRCFAIL)) { + // The CMD1 does not contain CRC. We should ignore the CRC failed Status. + RetVal = EFI_CRC_ERROR; + goto Exit; + } else { + RetVal = EFI_SUCCESS; + goto Exit; + } + } + +Exit: + //Disable Command Path + CmdCtrlReg = MmioRead32(MCI_COMMAND_REG); + MmioWrite32(MCI_COMMAND_REG, (CmdCtrlReg & ~MCI_CPSM_ENABLED)); + return RetVal; +} + +EFI_STATUS +MciReceiveResponse ( + IN MMC_RESPONSE_TYPE Type, + IN UINT32* Buffer + ) +{ + if (Buffer == NULL) { + return EFI_INVALID_PARAMETER; + } + + if ((Type == MMC_RESPONSE_TYPE_R1) || (Type == MMC_RESPONSE_TYPE_R1b) || + (Type == MMC_RESPONSE_TYPE_R3) || (Type == MMC_RESPONSE_TYPE_R6) || + (Type == MMC_RESPONSE_TYPE_R7)) + { + Buffer[0] = MmioRead32(MCI_RESPONSE0_REG); + Buffer[1] = MmioRead32(MCI_RESPONSE1_REG); + } else if (Type == MMC_RESPONSE_TYPE_R2) { + Buffer[0] = MmioRead32(MCI_RESPONSE0_REG); + Buffer[1] = MmioRead32(MCI_RESPONSE1_REG); + Buffer[2] = MmioRead32(MCI_RESPONSE2_REG); + Buffer[3] = MmioRead32(MCI_RESPONSE3_REG); + } + + return EFI_SUCCESS; +} + +EFI_STATUS +MciReadBlockData ( + IN EFI_LBA Lba, + IN UINTN Length, + IN UINT32* Buffer + ) +{ + UINTN Loop; + UINTN Finish; + UINTN Status; + EFI_STATUS RetVal; + UINTN DataCtrlReg; + + RetVal = EFI_SUCCESS; + + // Read data from the RX FIFO + Loop = 0; + Finish = MMCI0_BLOCKLEN / 4; + do { + // Read the Status flags + Status = MmioRead32(MCI_STATUS_REG); + + // Do eight reads if possible else a single read + if (Status & MCI_STATUS_CMD_RXFIFOHALFFULL) { + Buffer[Loop] = MmioRead32(MCI_FIFO_REG); + Loop++; + Buffer[Loop] = MmioRead32(MCI_FIFO_REG); + Loop++; + Buffer[Loop] = MmioRead32(MCI_FIFO_REG); + Loop++; + Buffer[Loop] = MmioRead32(MCI_FIFO_REG); + Loop++; + Buffer[Loop] = MmioRead32(MCI_FIFO_REG); + Loop++; + Buffer[Loop] = MmioRead32(MCI_FIFO_REG); + Loop++; + Buffer[Loop] = MmioRead32(MCI_FIFO_REG); + Loop++; + Buffer[Loop] = MmioRead32(MCI_FIFO_REG); + Loop++; + } else if (Status & MCI_STATUS_CMD_RXDATAAVAILBL) { + Buffer[Loop] = MmioRead32(MCI_FIFO_REG); + Loop++; + } else { + //Check for error conditions and timeouts + if(Status & MCI_STATUS_CMD_DATATIMEOUT) { + DEBUG ((EFI_D_ERROR, "MciReadBlockData(): TIMEOUT! Response:0x%X Status:0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status)); + RetVal = EFI_TIMEOUT; + break; + } else if(Status & MCI_STATUS_CMD_DATACRCFAIL) { + DEBUG ((EFI_D_ERROR, "MciReadBlockData(): CRC Error! Response:0x%X Status:0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status)); + RetVal = EFI_CRC_ERROR; + break; + } else if(Status & MCI_STATUS_CMD_START_BIT_ERROR) { + DEBUG ((EFI_D_ERROR, "MciReadBlockData(): Start-bit Error! Response:0x%X Status:0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status)); + RetVal = EFI_NO_RESPONSE; + break; + } + } + //clear RX over run flag + if(Status & MCI_STATUS_CMD_RXOVERRUN) { + MmioWrite32(MCI_CLEAR_STATUS_REG, MCI_STATUS_CMD_RXOVERRUN); + } + } while ((Loop < Finish)); + + //Clear Status flags + MmioWrite32(MCI_CLEAR_STATUS_REG, 0x7FF); + + //Disable Data path + DataCtrlReg = MmioRead32(MCI_DATA_CTL_REG); + MmioWrite32(MCI_DATA_CTL_REG, (DataCtrlReg & 0xFE)); + + return RetVal; +} + +EFI_STATUS +MciWriteBlockData ( + IN EFI_LBA Lba, + IN UINTN Length, + IN UINT32* Buffer + ) +{ + UINTN Loop; + UINTN Finish; + UINTN Timer; + UINTN Status; + EFI_STATUS RetVal; + UINTN DataCtrlReg; + + RetVal = EFI_SUCCESS; + + // Write the data to the TX FIFO + Loop = 0; + Finish = MMCI0_BLOCKLEN / 4; + Timer = MMCI0_TIMEOUT * 100; + do { + // Read the Status flags + Status = MmioRead32(MCI_STATUS_REG); + + // Do eight writes if possible else a single write + if (Status & MCI_STATUS_CMD_TXFIFOHALFEMPTY) { + MmioWrite32(MCI_FIFO_REG, Buffer[Loop]); + Loop++; + MmioWrite32(MCI_FIFO_REG, Buffer[Loop]); + Loop++; + MmioWrite32(MCI_FIFO_REG, Buffer[Loop]); + Loop++; + MmioWrite32(MCI_FIFO_REG, Buffer[Loop]); + Loop++; + MmioWrite32(MCI_FIFO_REG, Buffer[Loop]); + Loop++; + MmioWrite32(MCI_FIFO_REG, Buffer[Loop]); + Loop++; + MmioWrite32(MCI_FIFO_REG, Buffer[Loop]); + Loop++; + MmioWrite32(MCI_FIFO_REG, Buffer[Loop]); + Loop++; + } else if ((Status & MCI_STATUS_CMD_TXFIFOEMPTY)) { + MmioWrite32(MCI_FIFO_REG, Buffer[Loop]); + Loop++; + } else { + //Check for error conditions and timeouts + if(Status & MCI_STATUS_CMD_DATATIMEOUT) { + DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): TIMEOUT! Response:0x%X Status:0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status)); + RetVal = EFI_TIMEOUT; + goto Exit; + } else if(Status & MCI_STATUS_CMD_DATACRCFAIL) { + DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): CRC Error! Response:0x%X Status:0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status)); + RetVal = EFI_CRC_ERROR; + goto Exit; + } else if(Status & MCI_STATUS_CMD_TX_UNDERRUN) { + DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): TX buffer Underrun! Response:0x%X Status:0x%x, Number of bytes written 0x%x\n",MmioRead32(MCI_RESPONSE0_REG),Status, Loop)); + RetVal = EFI_BUFFER_TOO_SMALL; + ASSERT(0); + goto Exit; + } + } + } while (Loop < Finish); + + // Wait for FIFO to drain + Timer = MMCI0_TIMEOUT * 60; + Status = MmioRead32(MCI_STATUS_REG); +#ifndef USE_STREAM + // Single block + while (((Status & MCI_STATUS_CMD_TXDONE) != MCI_STATUS_CMD_TXDONE) && Timer) { +#else + // Stream + while (((Status & MCI_STATUS_CMD_DATAEND) != MCI_STATUS_CMD_DATAEND) && Timer) { +#endif + NanoSecondDelay(10); + Status = MmioRead32(MCI_STATUS_REG); + Timer--; + } + + if(Timer == 0) { + DEBUG ((EFI_D_ERROR, "MciWriteBlockData(): Data End timeout Number of bytes written 0x%x\n",Loop)); + ASSERT(Timer > 0); + return EFI_TIMEOUT; + } + + //Clear Status flags + MmioWrite32(MCI_CLEAR_STATUS_REG, 0x7FF); + if (Timer == 0) { + RetVal = EFI_TIMEOUT; + } + +Exit: + //Disable Data path + DataCtrlReg = MmioRead32(MCI_DATA_CTL_REG); + MmioWrite32(MCI_DATA_CTL_REG, (DataCtrlReg & 0xFE)); + return RetVal; +} + +EFI_STATUS +MciNotifyState ( + IN MMC_STATE State + ) +{ + UINT32 Data32; + + switch(State) { + case MmcInvalidState: + ASSERT(0); + break; + case MmcHwInitializationState: + // If device already turn on then restart it + Data32 = MmioRead32(MCI_POWER_CONTROL_REG); + if ((Data32 & 0x2) == MCI_POWER_UP) { + MCI_TRACE("MciNotifyState(MmcHwInitializationState): TurnOff MCI"); + + // Turn off + MmioWrite32(MCI_CLOCK_CONTROL_REG, 0); + MmioWrite32(MCI_POWER_CONTROL_REG, 0); + MicroSecondDelay(100); + } + + MCI_TRACE("MciNotifyState(MmcHwInitializationState): TurnOn MCI"); + // Setup clock + // - 0x1D = 29 => should be the clock divider to be less than 400kHz at MCLK = 24Mhz + MmioWrite32(MCI_CLOCK_CONTROL_REG,0x1D | MCI_CLOCK_ENABLE | MCI_CLOCK_POWERSAVE); + //MmioWrite32(MCI_CLOCK_CONTROL_REG,0x1D | MCI_CLOCK_ENABLE); + + // Set the voltage + MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_OPENDRAIN | (15<<2)); + MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_ROD | MCI_POWER_OPENDRAIN | (15<<2) | MCI_POWER_UP); + MicroSecondDelay(10); + MmioWrite32(MCI_POWER_CONTROL_REG,MCI_POWER_ROD | MCI_POWER_OPENDRAIN | (15<<2) | MCI_POWER_ON); + MicroSecondDelay(100); + + // Set Data Length & Data Timer + MmioWrite32(MCI_DATA_TIMER_REG,0xFFFFF); + MmioWrite32(MCI_DATA_LENGTH_REG,8); + + ASSERT((MmioRead32(MCI_POWER_CONTROL_REG) & 0x3) == MCI_POWER_ON); + break; + case MmcIdleState: + MCI_TRACE("MciNotifyState(MmcIdleState)"); + break; + case MmcReadyState: + MCI_TRACE("MciNotifyState(MmcReadyState)"); + break; + case MmcIdentificationState: + MCI_TRACE("MciNotifyState(MmcIdentificationState)"); + break; + case MmcStandByState:{ + volatile UINT32 PwrCtrlReg; + MCI_TRACE("MciNotifyState(MmcStandByState)"); + + // Enable MCICMD push-pull drive + PwrCtrlReg = MmioRead32(MCI_POWER_CONTROL_REG); + //Disable Open Drain output + PwrCtrlReg &=~(MCI_POWER_OPENDRAIN); + MmioWrite32(MCI_POWER_CONTROL_REG,PwrCtrlReg); + + // Set MMCI0 clock to 4MHz (24MHz may be possible with cache enabled) + // + // Note: Increasing clock speed causes TX FIFO under-run errors. + // So careful when optimising this driver for higher performance. + // + MmioWrite32(MCI_CLOCK_CONTROL_REG,0x02 | MCI_CLOCK_ENABLE | MCI_CLOCK_POWERSAVE); + // Set MMCI0 clock to 24MHz (by bypassing the divider) + //MmioWrite32(MCI_CLOCK_CONTROL_REG,MCI_CLOCK_BYPASS | MCI_CLOCK_ENABLE); + break; + } + case MmcTransferState: + //MCI_TRACE("MciNotifyState(MmcTransferState)"); + break; + case MmcSendingDataState: + MCI_TRACE("MciNotifyState(MmcSendingDataState)"); + break; + case MmcReceiveDataState: + MCI_TRACE("MciNotifyState(MmcReceiveDataState)"); + break; + case MmcProgrammingState: + MCI_TRACE("MciNotifyState(MmcProgrammingState)"); + break; + case MmcDisconnectState: + MCI_TRACE("MciNotifyState(MmcDisconnectState)"); + break; + default: + ASSERT(0); + } + return EFI_SUCCESS; +} + +EFI_GUID mPL180MciDevicePathGuid = EFI_CALLER_ID_GUID; + +EFI_STATUS +MciBuildDevicePath ( + 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_MMC_HOST_PROTOCOL gMciHost = { + MciIsCardPresent, + MciIsReadOnly, + MciBuildDevicePath, + MciNotifyState, + MciSendCommand, + MciReceiveResponse, + MciReadBlockData, + MciWriteBlockData +}; + +EFI_STATUS +PL180MciDxeInitialize ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + EFI_HANDLE Handle = NULL; + + MCI_TRACE("PL180MciDxeInitialize()"); + + //Publish Component Name, BlockIO protocol interfaces + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiMmcHostProtocolGuid, &gMciHost, + NULL + ); + ASSERT_EFI_ERROR (Status); + + return EFI_SUCCESS; +} diff --git a/ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.h b/ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.h new file mode 100644 index 0000000000..53a0b1c5af --- /dev/null +++ b/ArmPlatformPkg/Drivers/PL180MciDxe/PL180Mci.h @@ -0,0 +1,119 @@ +/** @file + Header for the MMC Host Protocol implementation for the ARM PrimeCell PL180. + + Copyright (c) 2011, ARM Limited. All rights reserved. + + This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef __PL180_MCI_H +#define __PL180_MCI_H + +#include + +#include + +#include +#include +#include +#include +#include +#include + +#define PL180_MCI_DXE_VERSION 0x10 + +#define MCI_SYSCTL FixedPcdGet32(PcdPL180MciBaseAddress) + +#define MCI_POWER_CONTROL_REG (MCI_SYSCTL+0x000) +#define MCI_CLOCK_CONTROL_REG (MCI_SYSCTL+0x004) +#define MCI_ARGUMENT_REG (MCI_SYSCTL+0x008) +#define MCI_COMMAND_REG (MCI_SYSCTL+0x00C) +#define MCI_RESPCMD_REG (MCI_SYSCTL+0x010) +#define MCI_RESPONSE0_REG (MCI_SYSCTL+0x014) +#define MCI_RESPONSE1_REG (MCI_SYSCTL+0x018) +#define MCI_RESPONSE2_REG (MCI_SYSCTL+0x01C) +#define MCI_RESPONSE3_REG (MCI_SYSCTL+0x020) +#define MCI_DATA_TIMER_REG (MCI_SYSCTL+0x024) +#define MCI_DATA_LENGTH_REG (MCI_SYSCTL+0x028) +#define MCI_DATA_CTL_REG (MCI_SYSCTL+0x02C) +#define MCI_DATA_COUNTER (MCI_SYSCTL+0x030) +#define MCI_STATUS_REG (MCI_SYSCTL+0x034) +#define MCI_CLEAR_STATUS_REG (MCI_SYSCTL+0x038) +#define MCI_INT0_MASK_REG (MCI_SYSCTL+0x03C) +#define MCI_INT1_MASK_REG (MCI_SYSCTL+0x040) +#define MCI_FIFOCOUNT_REG (MCI_SYSCTL+0x048) +#define MCI_FIFO_REG (MCI_SYSCTL+0x080) + +#define MCI_POWER_UP 0x2 +#define MCI_POWER_ON 0x3 +#define MCI_POWER_OPENDRAIN (1 << 6) +#define MCI_POWER_ROD (1 << 7) + +#define MCI_CLOCK_ENABLE 0x100 +#define MCI_CLOCK_POWERSAVE 0x200 +#define MCI_CLOCK_BYPASS 0x400 + +#define MCI_STATUS_CMD_CMDCRCFAIL 0x1 +#define MCI_STATUS_CMD_DATACRCFAIL 0x2 +#define MCI_STATUS_CMD_CMDTIMEOUT 0x4 +#define MCI_STATUS_CMD_DATATIMEOUT 0x8 +#define MCI_STATUS_CMD_TX_UNDERRUN 0x10 +#define MCI_STATUS_CMD_RXOVERRUN 0x20 +#define MCI_STATUS_CMD_RESPEND 0x40 +#define MCI_STATUS_CMD_SENT 0x80 +#define MCI_STATUS_CMD_TXDONE (MCI_STATUS_CMD_DATAEND | MCI_STATUS_CMD_DATABLOCKEND) +#define MCI_STATUS_CMD_DATAEND 0x000100 // Command Status - Data end +#define MCI_STATUS_CMD_START_BIT_ERROR 0x000200 +#define MCI_STATUS_CMD_DATABLOCKEND 0x000400 // Command Status - Data end +#define MCI_STATUS_CMD_ACTIVE 0x800 +#define MCI_STATUS_CMD_RXACTIVE (1 << 13) +#define MCI_STATUS_CMD_RXFIFOHALFFULL 0x008000 +#define MCI_STATUS_CMD_RXFIFOEMPTY 0x080000 +#define MCI_STATUS_CMD_RXDATAAVAILBL (1 << 21) +#define MCI_STATUS_CMD_TXACTIVE (1 << 12) +#define MCI_STATUS_CMD_TXFIFOFULL (1 << 16) +#define MCI_STATUS_CMD_TXFIFOHALFEMPTY (1 << 14) +#define MCI_STATUS_CMD_TXFIFOEMPTY (1 << 18) +#define MCI_STATUS_CMD_TXDATAAVAILBL (1 << 20) + +#define MCI_DATACTL_ENABLE 1 +#define MCI_DATACTL_CONT_TO_CARD 0 +#define MCI_DATACTL_CARD_TO_CONT 2 +#define MCI_DATACTL_BLOCK_TRANS 0 +#define MCI_DATACTL_STREAM_TRANS 4 +#define MCI_DATACTL_DMA_ENABLE (1 << 3) + +#define INDX_MASK 0x3F + +#define MCI_CPSM_ENABLED (1 << 10) +#define MCI_CPSM_WAIT_RESPONSE (1 << 6) +#define MCI_CPSM_LONG_RESPONSE (1 << 7) + +#define MCI_TRACE(txt) DEBUG((EFI_D_BLKIO, "ARM_MCI: " txt "\n")) + +EFI_STATUS +EFIAPI +MciGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +EFI_STATUS +EFIAPI +MciGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +#endif diff --git a/ArmPlatformPkg/Drivers/PL180MciDxe/PL180MciDxe.inf b/ArmPlatformPkg/Drivers/PL180MciDxe/PL180MciDxe.inf new file mode 100755 index 0000000000..b6d72e77a4 --- /dev/null +++ b/ArmPlatformPkg/Drivers/PL180MciDxe/PL180MciDxe.inf @@ -0,0 +1,52 @@ +#/** @file +# INF file for the MMC Host Protocol implementation for the ARM PrimeCell PL180. +# +# Copyright (c) 2011, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PL180MciDxe + FILE_GUID = 09831032-6fa3-4484-af4f-0a000a8d3a82 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + + ENTRY_POINT = PL180MciDxeInitialize + +[Sources.common] + PL180Mci.c + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + EmbeddedPkg/EmbeddedPkg.dec + MdePkg/MdePkg.dec + +[LibraryClasses] + BaseLib + UefiLib + UefiDriverEntryPoint + BaseMemoryLib + ArmLib + IoLib + TimerLib + +[Protocols] + gEfiCpuArchProtocolGuid + gEfiDevicePathProtocolGuid + gEfiMmcHostProtocolGuid + +[Pcd] + gArmPlatformTokenSpaceGuid.PcdPL180SysMciRegAddress + gArmPlatformTokenSpaceGuid.PcdPL180MciBaseAddress + +[Depex] + TRUE diff --git a/ArmPlatformPkg/Drivers/PL301Axi/PL301Axi.c b/ArmPlatformPkg/Drivers/PL301Axi/PL301Axi.c new file mode 100644 index 0000000000..7241f5cef2 --- /dev/null +++ b/ArmPlatformPkg/Drivers/PL301Axi/PL301Axi.c @@ -0,0 +1,108 @@ +/** @file +* +* Copyright (c) 2011, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include +#include + +#define PL301_QOS_TIDEMARK_MI_0 0x400 +#define PL301_QOS_ACCESSCONTROL_MI_0 0x404 + +#define PL301_QOS_TIDEMARK_MI_1 0x420 +#define PL301_QOS_ACCESSCONTROL_MI_1 0x424 + +#define PL301_QOS_TIDEMARK_MI_2 0x440 +#define PL301_QOS_ACCESSCONTROL_MI_2 0x444 + +#define PL301_AR_ARB_MI_0 0x408 +#define PL301_AW_ARB_MI_0 0x40C + +#define PL301_AR_ARB_MI_1 0x428 +#define PL301_AW_ARB_MI_1 0x42C + +#define PL301_AR_ARB_MI_2 0x448 +#define PL301_AW_ARB_MI_2 0x44C + +#define PL301_MI_1_OFFSET 0x20 +#define PL301_MI_2_OFFSET 0x40 +#define PL301_MI_3_OFFSET 0x60 +#define PL301_MI_4_OFFSET 0x80 +#define PL301_MI_5_OFFSET 0xa0 + +#define V2P_CA9_FAXI_MI0_TIDEMARK_VAL 0x6 +#define V2P_CA9_FAXI_MI0_ACCESSCNTRL_VAL 0x1 + +#define V2P_CA9_FAXI_MI1_TIDEMARK_VAL 0x6 +#define V2P_CA9_FAXI_MI1_ACCESSCNTRL_VAL 0x1 + +#define V2P_CA9_FAXI_MI2_TIDEMARK_VAL 0x6 +#define V2P_CA9_FAXI_MI2_ACCESSCNTRL_VAL 0x1 + + +#define FAxiWriteReg(reg,val) MmioWrite32(FAxiBase + reg, val) +#define FAxiReadReg(reg) MmioRead32(FAxiBase + reg) + +// IN FAxiBase +// Initialize PL301 Dynamic Memory Controller +VOID PL301AxiInit(UINTN FAxiBase) { + // Configure Tidemark Register for Master Port 0 (MI 0) + FAxiWriteReg(PL301_QOS_TIDEMARK_MI_0, V2P_CA9_FAXI_MI0_TIDEMARK_VAL); + + // Configure the Access Control Register (MI 0) + FAxiWriteReg(PL301_QOS_ACCESSCONTROL_MI_0, V2P_CA9_FAXI_MI0_ACCESSCNTRL_VAL); + + // MP0 + // Set priority for Read + FAxiWriteReg(PL301_AR_ARB_MI_0, 0x00000100); + FAxiWriteReg(PL301_AR_ARB_MI_0, 0x01000200); + FAxiWriteReg(PL301_AR_ARB_MI_0, 0x02000200); + FAxiWriteReg(PL301_AR_ARB_MI_0, 0x03000200); + FAxiWriteReg(PL301_AR_ARB_MI_0, 0x04000200); + + // Set priority for Write + FAxiWriteReg(PL301_AW_ARB_MI_0, 0x00000100); + FAxiWriteReg(PL301_AW_ARB_MI_0, 0x01000200); + FAxiWriteReg(PL301_AW_ARB_MI_0, 0x02000200); + FAxiWriteReg(PL301_AW_ARB_MI_0, 0x03000200); + FAxiWriteReg(PL301_AW_ARB_MI_0, 0x04000200); + + // MP1 + // Set priority for Read + FAxiWriteReg(PL301_AR_ARB_MI_1, 0x00000100); + FAxiWriteReg(PL301_AR_ARB_MI_1, 0x01000200); + FAxiWriteReg(PL301_AR_ARB_MI_1, 0x02000200); + FAxiWriteReg(PL301_AR_ARB_MI_1, 0x03000200); + FAxiWriteReg(PL301_AR_ARB_MI_1, 0x04000200); + + // Set priority for Write + FAxiWriteReg(PL301_AW_ARB_MI_1, 0x00000100); + FAxiWriteReg(PL301_AW_ARB_MI_1, 0x01000200); + FAxiWriteReg(PL301_AW_ARB_MI_1, 0x02000200); + FAxiWriteReg(PL301_AW_ARB_MI_1, 0x03000200); + FAxiWriteReg(PL301_AW_ARB_MI_1, 0x04000200); + + // MP2 + // Set priority for Read + FAxiWriteReg(PL301_AR_ARB_MI_2, 0x00000100); + FAxiWriteReg(PL301_AR_ARB_MI_2, 0x01000100); + FAxiWriteReg(PL301_AR_ARB_MI_2, 0x02000100); + FAxiWriteReg(PL301_AR_ARB_MI_2, 0x03000100); + FAxiWriteReg(PL301_AR_ARB_MI_2, 0x04000100); + + // Set priority for Write + FAxiWriteReg(PL301_AW_ARB_MI_2, 0x00000100); + FAxiWriteReg(PL301_AW_ARB_MI_2, 0x01000200); + FAxiWriteReg(PL301_AW_ARB_MI_2, 0x02000200); + FAxiWriteReg(PL301_AW_ARB_MI_2, 0x03000200); + FAxiWriteReg(PL301_AW_ARB_MI_2, 0x04000200); +} diff --git a/ArmPlatformPkg/Drivers/PL301Axi/PL301Axi.inf b/ArmPlatformPkg/Drivers/PL301Axi/PL301Axi.inf new file mode 100755 index 0000000000..c0fa4d1ca9 --- /dev/null +++ b/ArmPlatformPkg/Drivers/PL301Axi/PL301Axi.inf @@ -0,0 +1,27 @@ +#/* @file +# Copyright (c) 2011, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#*/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PL301Axi + FILE_GUID = 2ea84160-aba0-11df-9896-0002a5d5c51b + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = PL301AxiLib + +[Sources] + PL301Axi.c + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec diff --git a/ArmPlatformPkg/Drivers/PL310L2Cache/PL310L2Cache.c b/ArmPlatformPkg/Drivers/PL310L2Cache/PL310L2Cache.c new file mode 100644 index 0000000000..b701978da5 --- /dev/null +++ b/ArmPlatformPkg/Drivers/PL310L2Cache/PL310L2Cache.c @@ -0,0 +1,126 @@ +/** @file +* +* Copyright (c) 2011, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include +#include +#include +#include +#include + +#define L2x0WriteReg(reg,val) MmioWrite32(PcdGet32(PcdL2x0ControllerBase) + reg, val) +#define L2x0ReadReg(reg) MmioRead32(PcdGet32(PcdL2x0ControllerBase) + reg) + +// Initialize PL320 L2 Cache Controller +VOID +L2x0CacheInit ( + IN UINTN L2x0Base, + IN UINT32 L2x0TagLatencies, + IN UINT32 L2x0DataLatencies, + IN UINT32 L2x0AuxValue, + IN UINT32 L2x0AuxMask, + IN BOOLEAN CacheEnabled + ) +{ + UINT32 Data; + UINT32 Revision; + UINT32 Aux; + UINT32 PfCtl; + UINT32 PwrCtl; + + // Check if L2x0 is present and is an ARM implementation + Data = L2x0ReadReg(L2X0_CACHEID); + if ((Data >> 24) != L2X0_CACHEID_IMPLEMENTER_ARM) { + ASSERT(0); + return; + } + + // Check if L2x0 is PL310 + if (((Data >> 6) & 0xF) != L2X0_CACHEID_PARTNUM_PL310) { + ASSERT(0); + return; + } + + // RTL release + Revision = Data & 0x3F; + + // Check if L2x0 is already enabled then we disable it + Data = L2x0ReadReg(L2X0_CTRL); + if (Data & L2X0_CTRL_ENABLED) { + L2x0WriteReg(L2X0_CTRL, L2X0_CTRL_DISABLED); + } + + // + // Set up global configurations + // + + // Auxiliary register: Non-secure interrupt access Control + Event monitor bus enable + SBO + Aux = L2X0_AUXCTRL_NSAC | L2X0_AUXCTRL_EM | L2X0_AUXCTRL_SBO; + // Use AWCACHE attributes for WA + Aux |= L2x0_AUXCTRL_AW_AWCACHE; + // Use default Size + Data = L2x0ReadReg(L2X0_AUXCTRL); + Aux |= Data & L2X0_AUXCTRL_WAYSIZE_MASK; + // Use default associativity + Aux |= Data & L2X0_AUXCTRL_ASSOCIATIVITY; + // Enabled I & D Prefetch + Aux |= L2x0_AUXCTRL_IPREFETCH | L2x0_AUXCTRL_DPREFETCH; + + if (Revision >= 5) { + // Prefetch Offset Register + PfCtl = L2x0ReadReg(L2X0_PFCTRL); + // - Prefetch increment set to 0 + // - Prefetch dropping off + // - Double linefills off + L2x0WriteReg(L2X0_PFCTRL, PfCtl); + + // Power Control Register - L2X0_PWRCTRL + PwrCtl = L2x0ReadReg(L2X0_PWRCTRL); + // - Standby when idle off + // - Dynamic clock gating off + // - Nc,NC-shared dropping off + L2x0WriteReg(L2X0_PWRCTRL, PwrCtl); + } + + if (Revision >= 2) { + L2x0WriteReg(L230_TAG_LATENCY, L2x0TagLatencies); + L2x0WriteReg(L230_DATA_LATENCY, L2x0DataLatencies); + } else { + // PL310 old style latency is not supported yet + ASSERT(0); + } + + // Set the platform specific values + Aux = (Aux & L2x0AuxMask) | L2x0AuxValue; + + // Write Auxiliary value + L2x0WriteReg(L2X0_AUXCTRL, Aux); + + // + // Invalidate all entries in cache + // + L2x0WriteReg(L2X0_INVWAY, 0xffff); + // Poll cache maintenance register until invalidate operation is complete + while(L2x0ReadReg(L2X0_INVWAY) & 0xffff); + + // Write to the Lockdown D and Lockdown I Register 9 if required + // - Not required + + // Clear any residual raw interrupts + L2x0WriteReg(L2X0_INTCLEAR, 0x1FF); + + // Enable the cache + if (CacheEnabled) { + L2x0WriteReg(L2X0_CTRL, L2X0_CTRL_ENABLED); + } +} diff --git a/ArmPlatformPkg/Drivers/PL310L2Cache/PL310L2CacheSec.inf b/ArmPlatformPkg/Drivers/PL310L2Cache/PL310L2CacheSec.inf new file mode 100755 index 0000000000..1a95aa85fe --- /dev/null +++ b/ArmPlatformPkg/Drivers/PL310L2Cache/PL310L2CacheSec.inf @@ -0,0 +1,31 @@ +#/* @file +# Copyright (c) 2011, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#*/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PL310L2Cache + FILE_GUID = 16ad4fe0-b5b1-11df-8cbf-0002a5d5c51b + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = L2X0CacheLib + +[Sources] + PL310L2Cache.c + +[Packages] + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec + +[FixedPcd] + gArmTokenSpaceGuid.PcdL2x0ControllerBase diff --git a/ArmPlatformPkg/Drivers/PL34xDmc/PL341Dmc.c b/ArmPlatformPkg/Drivers/PL34xDmc/PL341Dmc.c new file mode 100644 index 0000000000..ae94def765 --- /dev/null +++ b/ArmPlatformPkg/Drivers/PL34xDmc/PL341Dmc.c @@ -0,0 +1,221 @@ +/** @file +* +* Copyright (c) 2011, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include +#include +#include + +// Macros for writing to DDR2 controller. +#define DmcWriteReg(reg,val) MmioWrite32(DmcBase + reg, val) +#define DmcReadReg(reg) MmioRead32(DmcBase + reg) + +// Macros for writing/reading to DDR2 PHY controller +#define DmcPhyWriteReg(reg,val) MmioWrite32(DmcPhyBase + reg, val) +#define DmcPhyReadReg(reg) MmioRead32(DmcPhyBase + reg) + +// Initialise PL341 Dynamic Memory Controller +VOID +PL341DmcInit ( + IN PL341_DMC_CONFIG *DmcConfig + ) +{ + UINTN DmcBase; + UINTN Index; + UINT32 Chip; + + DmcBase = DmcConfig->base; + + // Set config mode + DmcWriteReg(DMC_COMMAND_REG, DMC_COMMAND_CONFIGURE); + + // + // Setup the QoS AXI ID bits + // + if (DmcConfig->HasQos) { + // CLCD AXIID = 000 + DmcWriteReg(DMC_ID_0_CFG_REG, DMC_ID_CFG_QOS_ENABLE | DMC_ID_CFG_QOS_MIN); + + // Default disable QoS + DmcWriteReg(DMC_ID_1_CFG_REG, DMC_ID_CFG_QOS_DISABLE); + DmcWriteReg(DMC_ID_2_CFG_REG, DMC_ID_CFG_QOS_DISABLE); + DmcWriteReg(DMC_ID_3_CFG_REG, DMC_ID_CFG_QOS_DISABLE); + DmcWriteReg(DMC_ID_4_CFG_REG, DMC_ID_CFG_QOS_DISABLE); + DmcWriteReg(DMC_ID_5_CFG_REG, DMC_ID_CFG_QOS_DISABLE); + DmcWriteReg(DMC_ID_6_CFG_REG, DMC_ID_CFG_QOS_DISABLE); + DmcWriteReg(DMC_ID_7_CFG_REG, DMC_ID_CFG_QOS_DISABLE); + DmcWriteReg(DMC_ID_8_CFG_REG, DMC_ID_CFG_QOS_DISABLE); + DmcWriteReg(DMC_ID_9_CFG_REG, DMC_ID_CFG_QOS_DISABLE); + DmcWriteReg(DMC_ID_10_CFG_REG, DMC_ID_CFG_QOS_DISABLE); + DmcWriteReg(DMC_ID_11_CFG_REG, DMC_ID_CFG_QOS_DISABLE); + DmcWriteReg(DMC_ID_12_CFG_REG, DMC_ID_CFG_QOS_DISABLE); + DmcWriteReg(DMC_ID_13_CFG_REG, DMC_ID_CFG_QOS_DISABLE); + DmcWriteReg(DMC_ID_14_CFG_REG, DMC_ID_CFG_QOS_DISABLE); + DmcWriteReg(DMC_ID_15_CFG_REG, DMC_ID_CFG_QOS_DISABLE); + } + + // + // Initialise memory controlller + // + DmcWriteReg(DMC_REFRESH_PRD_REG, DmcConfig->refresh_prd); + DmcWriteReg(DMC_CAS_LATENCY_REG, DmcConfig->cas_latency); + DmcWriteReg(DMC_WRITE_LATENCY_REG, DmcConfig->write_latency); + DmcWriteReg(DMC_T_MRD_REG, DmcConfig->t_mrd); + DmcWriteReg(DMC_T_RAS_REG, DmcConfig->t_ras); + DmcWriteReg(DMC_T_RC_REG, DmcConfig->t_rc); + DmcWriteReg(DMC_T_RCD_REG, DmcConfig->t_rcd); + DmcWriteReg(DMC_T_RFC_REG, DmcConfig->t_rfc); + DmcWriteReg(DMC_T_RP_REG, DmcConfig->t_rp); + DmcWriteReg(DMC_T_RRD_REG, DmcConfig->t_rrd); + DmcWriteReg(DMC_T_WR_REG, DmcConfig->t_wr); + DmcWriteReg(DMC_T_WTR_REG, DmcConfig->t_wtr); + DmcWriteReg(DMC_T_XP_REG, DmcConfig->t_xp); + DmcWriteReg(DMC_T_XSR_REG, DmcConfig->t_xsr); + DmcWriteReg(DMC_T_ESR_REG, DmcConfig->t_esr); + DmcWriteReg(DMC_T_FAW_REG, DmcConfig->t_faw); + DmcWriteReg(DMC_T_WRLAT_DIFF, DmcConfig->t_wdata_en); + DmcWriteReg(DMC_T_RDATA_EN, DmcConfig->t_data_en); + + // + // Initialise PL341 Mem Config Registers + // + + // Set PL341 Memory Config + DmcWriteReg(DMC_MEMORY_CONFIG_REG, DmcConfig->MemoryCfg); + + // Set PL341 Memory Config 2 + DmcWriteReg(DMC_MEMORY_CFG2_REG, DmcConfig->MemoryCfg2); + + // Set PL341 Chip Select + DmcWriteReg(DMC_CHIP_0_CFG_REG, DmcConfig->ChipCfg0); + DmcWriteReg(DMC_CHIP_1_CFG_REG, DmcConfig->ChipCfg1); + DmcWriteReg(DMC_CHIP_2_CFG_REG, DmcConfig->ChipCfg2); + DmcWriteReg(DMC_CHIP_3_CFG_REG, DmcConfig->ChipCfg3); + + // Delay + for (Index = 0; Index < 10; Index++) { + DmcReadReg(DMC_STATUS_REG); + } + + // Set PL341 Memory Config 3 + DmcWriteReg(DMC_MEMORY_CFG3_REG, DmcConfig->MemoryCfg3); + + if (DmcConfig->IsUserCfg) { + // + // Set Test Chip PHY Registers via PL341 User Config Reg + // Note that user_cfgX registers are Write Only + // + // DLL Freq set = 250MHz - 266MHz + // + DmcWriteReg(DMC_USER_0_CFG_REG, DmcConfig->User0Cfg); + + // user_config2 + // ------------ + // Set defaults before calibrating the DDR2 buffer impendence + // - Disable ODT + // - Default drive strengths + DmcWriteReg(DMC_USER_2_CFG_REG, 0x40000198); + + // + // Auto calibrate the DDR2 buffers impendence + // + while (!(DmcReadReg(DMC_USER_STATUS_REG) & 0x100)); + + // Set the output driven strength + DmcWriteReg(DMC_USER_2_CFG_REG, 0x40800000 | DmcConfig->User2Cfg); + + // + // Set PL341 Feature Control Register + // + // Disable early BRESP - use to optimise CLCD performance + DmcWriteReg(DMC_FEATURE_CRTL_REG, 0x00000001); + } + + // + // Config memories + // + for (Chip = 0; Chip < DmcConfig->MaxChip; Chip++) { + // Send nop + DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(Chip) | DMC_DIRECT_CMD_MEMCMD_NOP); + + // Pre-charge all + DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(Chip) | DMC_DIRECT_CMD_MEMCMD_PRECHARGEALL); + + // Delay + for (Index = 0; Index < 10; Index++) { + DmcReadReg(DMC_STATUS_REG); + } + + // Set (EMR2) extended mode register 2 + DmcWriteReg(DMC_DIRECT_CMD_REG, + DMC_DIRECT_CMD_CHIP_ADDR(Chip) | + DMC_DIRECT_CMD_BANKADDR(2) | + DMC_DIRECT_CMD_MEMCMD_EXTMODEREG); + + // Set (EMR3) extended mode register 3 + DmcWriteReg(DMC_DIRECT_CMD_REG, + DMC_DIRECT_CMD_CHIP_ADDR(Chip) | + DMC_DIRECT_CMD_BANKADDR(3) | + DMC_DIRECT_CMD_MEMCMD_EXTMODEREG); + + // + // Set (EMR) Extended Mode Register + // + // Put into OCD default state + DmcWriteReg(DMC_DIRECT_CMD_REG,DMC_DIRECT_CMD_CHIP_ADDR(Chip) | DMC_DIRECT_CMD_BANKADDR(1) | DMC_DIRECT_CMD_MEMCMD_EXTMODEREG); + + // + // Set (MR) mode register - With DLL reset + // + DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(Chip) | DMC_DIRECT_CMD_MEMCMD_EXTMODEREG | DmcConfig->ModeReg | DDR2_MR_DLL_RESET); + + // Pre-charge all + DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(Chip) | DMC_DIRECT_CMD_MEMCMD_PRECHARGEALL); + // Auto-refresh + DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(Chip) | DMC_DIRECT_CMD_MEMCMD_AUTOREFRESH); + // Auto-refresh + DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(Chip) | DMC_DIRECT_CMD_MEMCMD_AUTOREFRESH); + + // + // Set (MR) mode register - Without DLL reset + // + DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(Chip) | DMC_DIRECT_CMD_MEMCMD_EXTMODEREG | DmcConfig->ModeReg); + + // Delay + for (Index = 0; Index < 10; Index++) { + DmcReadReg(DMC_STATUS_REG); + } + + // + // Set (EMR) extended mode register - Enable OCD defaults + // + DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(Chip) | (0x00090000) | + (1 << DDR_MODESET_SHFT) | (DDR_EMR_OCD_DEFAULT << DDR_EMR_OCD_SHIFT) | DmcConfig->ExtModeReg); + + // Delay + for (Index = 0; Index < 10; Index++) { + DmcReadReg(DMC_STATUS_REG); + } + + // Set (EMR) extended mode register - OCD Exit + DmcWriteReg(DMC_DIRECT_CMD_REG, DMC_DIRECT_CMD_CHIP_ADDR(Chip) | (0x00090000) | + (1 << DDR_MODESET_SHFT) | (DDR_EMR_OCD_NS << DDR_EMR_OCD_SHIFT) | DmcConfig->ExtModeReg); + } + + // Move DDR2 Controller to Ready state by issueing GO command + DmcWriteReg(DMC_COMMAND_REG, DMC_COMMAND_GO); + + // wait for ready + while (!(DmcReadReg(DMC_STATUS_REG) & DMC_STATUS_READY)); + +} diff --git a/ArmPlatformPkg/Drivers/PL34xDmc/PL341Dmc.inf b/ArmPlatformPkg/Drivers/PL34xDmc/PL341Dmc.inf new file mode 100755 index 0000000000..c24cf3e062 --- /dev/null +++ b/ArmPlatformPkg/Drivers/PL34xDmc/PL341Dmc.inf @@ -0,0 +1,29 @@ +#/* @file +# Copyright (c) 2011, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#*/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PL341Dmc + FILE_GUID = edf8da40-aad1-11df-a1f4-0002a5d5c51b + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = PL341DmcLib + +[Sources] + PL341Dmc.c + +[Packages] + ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec + +[FixedPcd] diff --git a/ArmPlatformPkg/Drivers/PL35xSmc/InitializeSMC.S b/ArmPlatformPkg/Drivers/PL35xSmc/InitializeSMC.S new file mode 100755 index 0000000000..789c12cfe6 --- /dev/null +++ b/ArmPlatformPkg/Drivers/PL35xSmc/InitializeSMC.S @@ -0,0 +1,196 @@ +# +# Copyright (c) 2011, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http:#opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +# + +#include +#include +#include +#include + +.text + +#Maintain 8 byte alignment +.align 3 + + +GCC_ASM_EXPORT(SMCInitializeNOR) +GCC_ASM_EXPORT(SMCInitializeSRAM) +GCC_ASM_EXPORT(SMCInitializePeripherals) +GCC_ASM_EXPORT(SMCInitializeVRAM) + + +# CS0 CS0-Interf0 NOR1 flash on the motherboard +# CS1 CS1-Interf0 Reserved for the motherboard +# CS2 CS2-Interf0 SRAM on the motherboard +# CS3 CS3-Interf0 memory-mapped Ethernet and USB controllers on the motherboard +# CS4 CS0-Interf1 NOR2 flash on the motherboard +# CS5 CS1-Interf1 memory-mapped peripherals +# CS6 CS2-Interf1 memory-mapped peripherals +# CS7 CS3-Interf1 system memory-mapped peripherals on the motherboard. + +// IN r1 SmcBase +// IN r2 ChipSelect +// NOTE: This code is been called before any stack has been setup. It means some registers +// could be overwritten (case of 'r0') +ASM_PFX(SMCInitializeNOR): +# +# Setup NOR1 (CS0-Interface0) +# + + # Write to set_cycle register(holding register for NOR 1 cycle register or NAND cycle register) + #Read cycle timeout = 0xA (0:3) + #Write cycle timeout = 0x3(7:4) + #OE Assertion Delay = 0x9(11:8) + #WE Assertion delay = 0x3(15:12) + #Page cycle timeout = 0x2(19:16) + LoadConstantToReg (0x0002393A,r0) @ldr r0, = 0x0002393A + str r0, [r1, #PL354_SMC_SET_CYCLES_OFFSET] + + # Write to set_opmode register(holding register for NOR 1 opomode register or NAND opmode register) + # 0x00000002 = MemoryWidth: 32bit + # 0x00000028 = ReadMemoryBurstLength:continuous + # 0x00000280 = WriteMemoryBurstLength:continuous + # 0x00000800 = Set Address Valid + LoadConstantToReg (0x00000AAA,r0) @ldr r0, = 0x00000AAA + str r0, [r1, #PL354_SMC_SET_OPMODE_OFFSET] + + # Write to direct_cmd register so that the NOR 1 registers(set-cycles and opmode) are updated with holding registers + # 0x00000000 = ChipSelect0-Interface 0 + # 0x00400000 = CmdTypes: UpdateRegs + LoadConstantToReg (0x00400000,r0) @ldr r0, = 0x00400000 + str r0, [r1, #PL354_SMC_DIRECT_CMD_OFFSET] + + bx lr + +ASM_PFX(SMCInitializeSRAM): +# +# Setup SRAM (CS2-Interface0) +# + LoadConstantToReg (0x00027158,r0) @ldr r0, = 0x00027158 + str r0, [r1, #PL354_SMC_SET_CYCLES_OFFSET] + + # 0x00000002 = MemoryWidth: 32bit + # 0x00000800 = Set Address Valid + LoadConstantToReg (0x00000802,r0) @ldr r0, = 0x00000802 + str r0, [r1, #PL354_SMC_SET_OPMODE_OFFSET] + + # 0x01000000 = ChipSelect2-Interface 0 + # 0x00400000 = CmdTypes: UpdateRegs + LoadConstantToReg (0x01400000,r0) @ldr r0, = 0x01400000 + str r0, [r1, #PL354_SMC_DIRECT_CMD_OFFSET] + + bx lr + +ASM_PFX(SMCInitializePeripherals): +# +# USB/Eth/VRAM (CS3-Interface0) +# + LoadConstantToReg (0x000CD2AA,r0) @ldr r0, = 0x000CD2AA + str r0, [r1, #PL354_SMC_SET_CYCLES_OFFSET] + + # 0x00000002 = MemoryWidth: 32bit + # 0x00000004 = Memory reads are synchronous + # 0x00000040 = Memory writes are synchronous + LoadConstantToReg (0x00000046,r0) @ldr r0, = 0x00000046 + str r0, [r1, #PL354_SMC_SET_OPMODE_OFFSET] + + # 0x01800000 = ChipSelect3-Interface 0 + # 0x00400000 = CmdTypes: UpdateRegs + LoadConstantToReg (0x01C00000,r0) @ldr r0, = 0x01C00000 + str r0, [r1, #PL354_SMC_DIRECT_CMD_OFFSET] + +# +# Setup NOR3 (CS0-Interface1) +# + LoadConstantToReg (0x0002393A,r0) @ldr r0, = 0x0002393A + str r0, [r1, #PL354_SMC_SET_CYCLES_OFFSET] + + # 0x00000002 = MemoryWidth: 32bit + # 0x00000028 = ReadMemoryBurstLength:continuous + # 0x00000280 = WriteMemoryBurstLength:continuous + # 0x00000800 = Set Address Valid + LoadConstantToReg (0x00000AAA,r0) @ldr r0, = 0x00000AAA + str r0, [r1, #PL354_SMC_SET_OPMODE_OFFSET] + + # 0x02000000 = ChipSelect0-Interface 1 + # 0x00400000 = CmdTypes: UpdateRegs + LoadConstantToReg (0x02400000,r0) @ldr r0, = 0x02400000 + str r0, [r1, #PL354_SMC_DIRECT_CMD_OFFSET] + +# +# Setup Peripherals (CS3-Interface1) +# + LoadConstantToReg (0x00025156,r0) @ldr r0, = 0x00025156 + str r0, [r1, #PL354_SMC_SET_CYCLES_OFFSET] + + # 0x00000002 = MemoryWidth: 32bit + # 0x00000004 = Memory reads are synchronous + # 0x00000040 = Memory writes are synchronous + LoadConstantToReg (0x00000046,r0) @ldr r0, = 0x00000046 + str r0, [r1, #PL354_SMC_SET_OPMODE_OFFSET] + + # 0x03800000 = ChipSelect3-Interface 1 + # 0x00400000 = CmdTypes: UpdateRegs + LoadConstantToReg (0x03C00000,r0) @ldr r0, = 0x03C00000 + str r0, [r1, #PL354_SMC_DIRECT_CMD_OFFSET] + bx lr + +// IN r1 SmcBase +// IN r2 VideoSRamBase +// NOTE: This code is been called before any stack has been setup. It means some registers +// could be overwritten (case of 'r0') +ASM_PFX(SMCInitializeVRAM): +# +# Setup VRAM (CS1-Interface0) +# + LoadConstantToReg (0x00049249,r0) @ldr r0, = 0x00049249 + str r0, [r1, #PL354_SMC_SET_CYCLES_OFFSET] + + # 0x00000002 = MemoryWidth: 32bit + # 0x00000004 = Memory reads are synchronous + # 0x00000040 = Memory writes are synchronous + LoadConstantToReg (0x00000046,r0) @ldr r0, = 0x00000046 + str r0, [r1, #PL354_SMC_SET_OPMODE_OFFSET] + + # 0x00800000 = ChipSelect1-Interface 0 + # 0x00400000 = CmdTypes: UpdateRegs + LoadConstantToReg (0x00C00000,r0) @ldr r0, = 0x00C00000 + str r0, [r1, #PL354_SMC_DIRECT_CMD_OFFSET] + +# +# Page mode setup for VRAM +# + #read current state + ldr r0, [r2, #0] + ldr r0, [r2, #0] + LoadConstantToReg (0x00000000,r0) @ldr r0, = 0x00000000 + str r0, [r2, #0] + ldr r0, [r2, #0] + + #enable page mode + ldr r0, [r2, #0] + ldr r0, [r2, #0] + LoadConstantToReg (0x00000000,r0) @ldr r0, = 0x00000000 + str r0, [r2, #0] + LoadConstantToReg (0x00900090,r0) @ldr r0, = 0x00900090 + str r0, [r2, #0] + + #confirm page mode enabled + ldr r0, [r2, #0] + ldr r0, [r2, #0] + LoadConstantToReg (0x00000000,r0) @ldr r0, = 0x00000000 + str r0, [r2, #0] + ldr r0, [r2, #0] + + bx lr + +ASM_FUNCTION_REMOVE_IF_UNREFERENCED \ No newline at end of file diff --git a/ArmPlatformPkg/Drivers/PL35xSmc/InitializeSMC.asm b/ArmPlatformPkg/Drivers/PL35xSmc/InitializeSMC.asm new file mode 100755 index 0000000000..732500e13a --- /dev/null +++ b/ArmPlatformPkg/Drivers/PL35xSmc/InitializeSMC.asm @@ -0,0 +1,153 @@ +// +// Copyright (c) 2011, ARM Limited. All rights reserved. +// +// This program and the accompanying materials +// are licensed and made available under the terms and conditions of the BSD License +// which accompanies this distribution. The full text of the license may be found at +// http://opensource.org/licenses/bsd-license.php +// +// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +// +// + +#include +#include +#include +#include + + INCLUDE AsmMacroIoLib.inc + + EXPORT SMCInitializeNOR + EXPORT SMCInitializeSRAM + EXPORT SMCInitializePeripherals + EXPORT SMCInitializeVRAM + + PRESERVE8 + AREA ModuleInitializeSMC, CODE, READONLY + +// CS0 CS0-Interf0 NOR1 flash on the motherboard +// CS1 CS1-Interf0 Reserved for the motherboard +// CS2 CS2-Interf0 SRAM on the motherboard +// CS3 CS3-Interf0 memory-mapped Ethernet and USB controllers on the motherboard +// CS4 CS0-Interf1 NOR2 flash on the motherboard +// CS5 CS1-Interf1 memory-mapped peripherals +// CS6 CS2-Interf1 memory-mapped peripherals +// CS7 CS3-Interf1 system memory-mapped peripherals on the motherboard. + +// IN r1 SmcBase +// IN r2 ChipSelect +// NOTE: This code is been called before any stack has been setup. It means some registers +// could be overwritten (case of 'r0') +SMCInitializeNOR + // Write to set_cycle register(holding register for NOR 1 cycle register or NAND cycle register) + // - Read cycle timeout = 0xA (0:3) + // - Write cycle timeout = 0x3(7:4) + // - OE Assertion Delay = 0x9(11:8) + // - WE Assertion delay = 0x3(15:12) + // - Page cycle timeout = 0x2(19:16) + ldr r0, = 0x0002393A + str r0, [r1, #PL354_SMC_SET_CYCLES_OFFSET] + + // Write to set_opmode register(holding register for NOR 1 opomode register or NAND opmode register) + ldr r0, = (PL354_SMC_SET_OPMODE_MEM_WIDTH_32 :OR: PL354_SMC_SET_OPMODE_SET_RD_BURST_LENGTH_CONT :OR: PL354_SMC_SET_OPMODE_SET_WR_BURST_LENGTH_CONT :OR: PL354_SMC_SET_OPMODE_SET_ADV) + str r0, [r1, #PL354_SMC_SET_OPMODE_OFFSET] + + // Write to direct_cmd register so that the NOR 1 registers(set-cycles and opmode) are updated with holding registers + ldr r0, =PL354_SMC_DIRECT_CMD_ADDR_CMD_UPDATE + orr r0, r0, r2 + str r0, [r1, #PL354_SMC_DIRECT_CMD_OFFSET] + + bx lr + + +// +// Setup SRAM (CS2-Interface0) +// +SMCInitializeSRAM + ldr r0, = 0x00027158 + str r0, [r1, #PL354_SMC_SET_CYCLES_OFFSET] + + ldr r0, =(PL354_SMC_SET_OPMODE_MEM_WIDTH_32 :OR: PL354_SMC_SET_OPMODE_SET_ADV) + str r0, [r1, #PL354_SMC_SET_OPMODE_OFFSET] + + ldr r0, =(PL354_SMC_DIRECT_CMD_ADDR_CMD_UPDATE :OR: PL354_SMC_DIRECT_CMD_ADDR_CS(0,2)) + str r0, [r1, #PL354_SMC_DIRECT_CMD_OFFSET] + + bx lr + +SMCInitializePeripherals +// +// USB/Eth/VRAM (CS3-Interface0) +// + ldr r0, = 0x000CD2AA + str r0, [r1, #PL354_SMC_SET_CYCLES_OFFSET] + + ldr r0, =(PL354_SMC_SET_OPMODE_MEM_WIDTH_32 :OR: PL354_SMC_SET_OPMODE_SET_RD_SYNC :OR: PL354_SMC_SET_OPMODE_SET_WR_SYNC) + str r0, [r1, #PL354_SMC_SET_OPMODE_OFFSET] + + ldr r0, =(PL354_SMC_DIRECT_CMD_ADDR_CMD_UPDATE :OR: PL354_SMC_DIRECT_CMD_ADDR_CS(0,3)) + str r0, [r1, #PL354_SMC_DIRECT_CMD_OFFSET] + + +// +// Setup Peripherals (CS3-Interface1) +// + ldr r0, = 0x00025156 + str r0, [r1, #PL354_SMC_SET_CYCLES_OFFSET] + + ldr r0, =(PL354_SMC_SET_OPMODE_MEM_WIDTH_32 :OR: PL354_SMC_SET_OPMODE_SET_RD_SYNC :OR: PL354_SMC_SET_OPMODE_SET_WR_SYNC) + str r0, [r1, #PL354_SMC_SET_OPMODE_OFFSET] + + ldr r0, =(PL354_SMC_DIRECT_CMD_ADDR_CMD_UPDATE :OR: PL354_SMC_DIRECT_CMD_ADDR_CS(1,3)) + str r0, [r1, #PL354_SMC_DIRECT_CMD_OFFSET] + + bx lr + + +// IN r1 SmcBase +// IN r2 VideoSRamBase +// NOTE: This code is been called before any stack has been setup. It means some registers +// could be overwritten (case of 'r0') +SMCInitializeVRAM + // + // Setup VRAM (CS1-Interface0) + // + ldr r0, = 0x00049249 + str r0, [r1, #PL354_SMC_SET_CYCLES_OFFSET] + + ldr r0, = (PL354_SMC_SET_OPMODE_MEM_WIDTH_32 :OR: PL354_SMC_SET_OPMODE_SET_RD_SYNC :OR: PL354_SMC_SET_OPMODE_SET_WR_SYNC) + str r0, [r1, #PL354_SMC_SET_OPMODE_OFFSET] + + ldr r0, = (PL354_SMC_DIRECT_CMD_ADDR_CMD_UPDATE :OR: PL354_SMC_DIRECT_CMD_ADDR_CS(0,1)) + str r0, [r1, #PL354_SMC_DIRECT_CMD_OFFSET] + + // + // Page mode setup for VRAM + // + + // Read current state + ldr r0, [r2, #0] + ldr r0, [r2, #0] + ldr r0, = 0x00000000 + str r0, [r2, #0] + ldr r0, [r2, #0] + + // Enable page mode + ldr r0, [r2, #0] + ldr r0, [r2, #0] + ldr r0, = 0x00000000 + str r0, [r2, #0] + ldr r0, = 0x00900090 + str r0, [r2, #0] + + // Confirm page mode enabled + ldr r0, [r2, #0] + ldr r0, [r2, #0] + ldr r0, = 0x00000000 + str r0, [r2, #0] + ldr r0, [r2, #0] + + bx lr + + END diff --git a/ArmPlatformPkg/Drivers/PL35xSmc/PL35xSmc.inf b/ArmPlatformPkg/Drivers/PL35xSmc/PL35xSmc.inf new file mode 100755 index 0000000000..3960d49756 --- /dev/null +++ b/ArmPlatformPkg/Drivers/PL35xSmc/PL35xSmc.inf @@ -0,0 +1,29 @@ +#/* @file +# Copyright (c) 2011, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#*/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = PL35xSmc + FILE_GUID = 10952220-aa32-11df-a438-0002a5d5c51b + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = PL35xSmcLib + +[Sources.common] + InitializeSMC.asm | RVCT + InitializeSMC.S | GCC + +[Packages] + ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec + MdePkg/MdePkg.dec diff --git a/ArmPlatformPkg/Library/L2X0CacheLibNull/L2X0Cache.c b/ArmPlatformPkg/Library/L2X0CacheLibNull/L2X0Cache.c new file mode 100644 index 0000000000..ec0a0dd464 --- /dev/null +++ b/ArmPlatformPkg/Library/L2X0CacheLibNull/L2X0Cache.c @@ -0,0 +1,30 @@ +/** @file +* +* Copyright (c) 2011, ARM Limited. All rights reserved. +* +* This program and the accompanying materials +* are licensed and made available under the terms and conditions of the BSD License +* which accompanies this distribution. The full text of the license may be found at +* http://opensource.org/licenses/bsd-license.php +* +* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +* +**/ + +#include +#include + +// Initialize L2X0 Cache Controller +VOID +L2x0CacheInit ( + IN UINTN L2x0Base, + IN UINT32 L2x0TagLatencies, + IN UINT32 L2x0DataLatencies, + IN UINT32 L2x0AuxValue, + IN UINT32 L2x0AuxMask, + IN BOOLEAN CacheEnabled + ) +{ + //No implementation +} diff --git a/ArmPlatformPkg/Library/L2X0CacheLibNull/L2X0CacheLibNull.inf b/ArmPlatformPkg/Library/L2X0CacheLibNull/L2X0CacheLibNull.inf new file mode 100755 index 0000000000..f0ebe17c41 --- /dev/null +++ b/ArmPlatformPkg/Library/L2X0CacheLibNull/L2X0CacheLibNull.inf @@ -0,0 +1,27 @@ +#/* @file +# Copyright (c) 2011, ARM Limited. All rights reserved. +# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#*/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = L2X0CacheLibNull + FILE_GUID = 9c76c900-1e8c-11e0-8766-0002a5d5c51b + MODULE_TYPE = SEC + VERSION_STRING = 1.0 + LIBRARY_CLASS = L2X0CacheLib + +[Sources] + L2X0Cache.c + +[Packages] + MdePkg/MdePkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec