1 /** @file 2 * 3 * Copyright (c) 2011, ARM Limited. All rights reserved. 4 * 5 * This program and the accompanying materials 6 * are licensed and made available under the terms and conditions of the BSD License 7 * which accompanies this distribution. The full text of the license may be found at 8 * http://opensource.org/licenses/bsd-license.php 9 * 10 * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12 * 13 **/ 14 15 #include <Library/IoLib.h> 16 #include <Library/DebugLib.h> 17 #include <Library/ArmLib.h> 18 #include <Drivers/PL310L2Cache.h> 19 #include <Library/PcdLib.h> 20 21 #define L2x0WriteReg(reg,val) MmioWrite32(PcdGet32(PcdL2x0ControllerBase) + reg, val) 22 #define L2x0ReadReg(reg) MmioRead32(PcdGet32(PcdL2x0ControllerBase) + reg) 23 24 // Initialize PL320 L2 Cache Controller 25 VOID 26 L2x0CacheInit ( 27 IN UINTN L2x0Base, 28 IN UINT32 L2x0TagLatencies, 29 IN UINT32 L2x0DataLatencies, 30 IN UINT32 L2x0AuxValue, 31 IN UINT32 L2x0AuxMask, 32 IN BOOLEAN CacheEnabled 33 ) 34 { 35 UINT32 Data; 36 UINT32 Revision; 37 UINT32 Aux; 38 UINT32 PfCtl; 39 UINT32 PwrCtl; 40 41 // Check if L2x0 is present and is an ARM implementation 42 Data = L2x0ReadReg(L2X0_CACHEID); 43 if ((Data >> 24) != L2X0_CACHEID_IMPLEMENTER_ARM) { 44 ASSERT(0); 45 return; 46 } 47 48 // Check if L2x0 is PL310 49 if (((Data >> 6) & 0xF) != L2X0_CACHEID_PARTNUM_PL310) { 50 ASSERT(0); 51 return; 52 } 53 54 // RTL release 55 Revision = Data & 0x3F; 56 57 // Check if L2x0 is already enabled then we disable it 58 Data = L2x0ReadReg(L2X0_CTRL); 59 if (Data & L2X0_CTRL_ENABLED) { 60 L2x0WriteReg(L2X0_CTRL, L2X0_CTRL_DISABLED); 61 } 62 63 // 64 // Set up global configurations 65 // 66 67 // Auxiliary register: Non-secure interrupt access Control + Event monitor bus enable + SBO 68 Aux = L2X0_AUXCTRL_NSAC | L2X0_AUXCTRL_EM | L2X0_AUXCTRL_SBO; 69 // Use AWCACHE attributes for WA 70 Aux |= L2x0_AUXCTRL_AW_AWCACHE; 71 // Use default Size 72 Data = L2x0ReadReg(L2X0_AUXCTRL); 73 Aux |= Data & L2X0_AUXCTRL_WAYSIZE_MASK; 74 // Use default associativity 75 Aux |= Data & L2X0_AUXCTRL_ASSOCIATIVITY; 76 // Enabled I & D Prefetch 77 Aux |= L2x0_AUXCTRL_IPREFETCH | L2x0_AUXCTRL_DPREFETCH; 78 79 if (Revision >= 5) { 80 // Prefetch Offset Register 81 PfCtl = L2x0ReadReg(L2X0_PFCTRL); 82 // - Prefetch increment set to 0 83 // - Prefetch dropping off 84 // - Double linefills off 85 L2x0WriteReg(L2X0_PFCTRL, PfCtl); 86 87 // Power Control Register - L2X0_PWRCTRL 88 PwrCtl = L2x0ReadReg(L2X0_PWRCTRL); 89 // - Standby when idle off 90 // - Dynamic clock gating off 91 // - Nc,NC-shared dropping off 92 L2x0WriteReg(L2X0_PWRCTRL, PwrCtl); 93 } 94 95 if (Revision >= 2) { 96 L2x0WriteReg(L230_TAG_LATENCY, L2x0TagLatencies); 97 L2x0WriteReg(L230_DATA_LATENCY, L2x0DataLatencies); 98 } else { 99 // PL310 old style latency is not supported yet 100 ASSERT(0); 101 } 102 103 // Set the platform specific values 104 Aux = (Aux & L2x0AuxMask) | L2x0AuxValue; 105 106 // Write Auxiliary value 107 L2x0WriteReg(L2X0_AUXCTRL, Aux); 108 109 // 110 // Invalidate all entries in cache 111 // 112 L2x0WriteReg(L2X0_INVWAY, 0xffff); 113 // Poll cache maintenance register until invalidate operation is complete 114 while(L2x0ReadReg(L2X0_INVWAY) & 0xffff); 115 116 // Write to the Lockdown D and Lockdown I Register 9 if required 117 // - Not required 118 119 // Clear any residual raw interrupts 120 L2x0WriteReg(L2X0_INTCLEAR, 0x1FF); 121 122 // Enable the cache 123 if (CacheEnabled) { 124 L2x0WriteReg(L2X0_CTRL, L2X0_CTRL_ENABLED); 125 } 126 } 127