--- /dev/null
+/** @file\r
+*\r
+* Copyright (c) 2011, ARM Limited. All rights reserved.\r
+* \r
+* This program and the accompanying materials \r
+* are licensed and made available under the terms and conditions of the BSD License \r
+* which accompanies this distribution. The full text of the license may be found at \r
+* http://opensource.org/licenses/bsd-license.php \r
+*\r
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+*\r
+**/\r
+\r
+#include <Library/IoLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/ArmLib.h>\r
+#include <Library/L2X0CacheLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+#define L2x0WriteReg(reg,val) MmioWrite32(PcdGet32(PcdL2x0ControllerBase) + reg, val)\r
+#define L2x0ReadReg(reg) MmioRead32(PcdGet32(PcdL2x0ControllerBase) + reg)\r
+\r
+// Initialize PL320 L2 Cache Controller\r
+VOID L2x0CacheInit(UINTN L2x0Base, BOOLEAN CacheEnabled) {\r
+ UINT32 Data;\r
+ UINT32 Revision;\r
+ UINT32 Aux;\r
+ UINT32 PfCtl;\r
+ UINT32 PwrCtl;\r
+\r
+ // Check if L2x0 is present and is an ARM implementation\r
+ Data = L2x0ReadReg(L2X0_CACHEID);\r
+ if ((Data >> 24) != L2X0_CACHEID_IMPLEMENTER_ARM) {\r
+ ASSERT(0);\r
+ return;\r
+ }\r
+\r
+ // Check if L2x0 is PL310\r
+ if (((Data >> 6) & 0xF) != L2X0_CACHEID_PARTNUM_PL310) {\r
+ ASSERT(0);\r
+ return;\r
+ }\r
+\r
+ // RTL release\r
+ Revision = Data & 0x3F;\r
+\r
+ // Check if L2x0 is already enabled then we disable it\r
+ Data = L2x0ReadReg(L2X0_CTRL);\r
+ if (Data & L2X0_CTRL_ENABLED) {\r
+ L2x0WriteReg(L2X0_CTRL, L2X0_CTRL_DISABLED);\r
+ }\r
+\r
+ //\r
+ // Set up global configurations\r
+ //\r
+\r
+ // Auxiliary register: Non-secure interrupt access Control + Event monitor bus enable + SBO\r
+ Aux = L2X0_AUXCTRL_NSAC | L2X0_AUXCTRL_EM | L2X0_AUXCTRL_SBO;\r
+ // Use AWCACHE attributes for WA\r
+ Aux |= L2x0_AUXCTRL_AW_AWCACHE;\r
+ // Use default Size\r
+ Data = L2x0ReadReg(L2X0_AUXCTRL);\r
+ Aux |= Data & (0x7 << 17);\r
+ // Use default associativity\r
+ Aux |= Data & (0x1 << 16);\r
+ // Enabled I & D Prefetch\r
+ Aux |= L2x0_AUXCTRL_IPREFETCH | L2x0_AUXCTRL_DPREFETCH;\r
+ \r
+ if (Revision >= 5) {\r
+ // Prefetch Offset Register\r
+ PfCtl = L2x0ReadReg(L2X0_PFCTRL);\r
+ // - Prefetch increment set to 0\r
+ // - Prefetch dropping off\r
+ // - Double linefills off\r
+ L2x0WriteReg(L2X0_PFCTRL, PfCtl);\r
+\r
+ // Power Control Register - L2X0_PWRCTRL\r
+ PwrCtl = L2x0ReadReg(L2X0_PWRCTRL);\r
+ // - Standby when idle off\r
+ // - Dynamic clock gating off\r
+ // - Nc,NC-shared dropping off\r
+ L2x0WriteReg(L2X0_PWRCTRL, PwrCtl);\r
+ }\r
+\r
+ if (Revision >= 4) {\r
+ // Tag RAM Latency register\r
+ // - Use default latency\r
+ \r
+ // Data RAM Latency Control register\r
+ // - Use default latency\r
+ } else if (Revision >= 2) {\r
+ L2x0WriteReg(L230_TAG_LATENCY,\r
+ (L2_TAG_ACCESS_LATENCY << 8)\r
+ | (L2_TAG_ACCESS_LATENCY << 4)\r
+ | L2_TAG_SETUP_LATENCY\r
+ );\r
+ \r
+ L2x0WriteReg(L230_DATA_LATENCY,\r
+ (L2_DATA_ACCESS_LATENCY << 8)\r
+ | (L2_DATA_ACCESS_LATENCY << 4)\r
+ | L2_DATA_SETUP_LATENCY\r
+ );\r
+ } else {\r
+ Aux |= (L2_TAG_ACCESS_LATENCY << 6)\r
+ | (L2_DATA_ACCESS_LATENCY << 3)\r
+ | L2_DATA_ACCESS_LATENCY;\r
+ }\r
+\r
+ // Write Auxiliary value\r
+ L2x0WriteReg(L2X0_AUXCTRL, Aux);\r
+\r
+ //\r
+ // Invalidate all entries in cache\r
+ //\r
+ L2x0WriteReg(L2X0_INVWAY, 0xffff);\r
+ // Poll cache maintenance register until invalidate operation is complete\r
+ while(L2x0ReadReg(L2X0_INVWAY) & 0xffff);\r
+\r
+ // Write to the Lockdown D and Lockdown I Register 9 if required\r
+ // - Not required\r
+\r
+ // Clear any residual raw interrupts\r
+ L2x0WriteReg(L2X0_INTCLEAR, 0x1FF);\r
+\r
+ // Enable the cache\r
+ if (CacheEnabled) {\r
+ L2x0WriteReg(L2X0_CTRL, L2X0_CTRL_ENABLED);\r
+ }\r
+}\r