]> git.proxmox.com Git - mirror_edk2.git/blob - ArmPkg/Drivers/PL310L2Cache/PL310L2Cache.c
Sync up ArmPkg with patch from mailing list. Changed name of BdsLib.h to BdsUnixLib...
[mirror_edk2.git] / ArmPkg / Drivers / PL310L2Cache / PL310L2Cache.c
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 <Library/L2X0CacheLib.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 L2x0CacheInit(UINTN L2x0Base, BOOLEAN CacheEnabled) {
26 UINT32 Data;
27 UINT32 Revision;
28 UINT32 Aux;
29 UINT32 PfCtl;
30 UINT32 PwrCtl;
31
32 // Check if L2x0 is present and is an ARM implementation
33 Data = L2x0ReadReg(L2X0_CACHEID);
34 if ((Data >> 24) != L2X0_CACHEID_IMPLEMENTER_ARM) {
35 ASSERT(0);
36 return;
37 }
38
39 // Check if L2x0 is PL310
40 if (((Data >> 6) & 0xF) != L2X0_CACHEID_PARTNUM_PL310) {
41 ASSERT(0);
42 return;
43 }
44
45 // RTL release
46 Revision = Data & 0x3F;
47
48 // Check if L2x0 is already enabled then we disable it
49 Data = L2x0ReadReg(L2X0_CTRL);
50 if (Data & L2X0_CTRL_ENABLED) {
51 L2x0WriteReg(L2X0_CTRL, L2X0_CTRL_DISABLED);
52 }
53
54 //
55 // Set up global configurations
56 //
57
58 // Auxiliary register: Non-secure interrupt access Control + Event monitor bus enable + SBO
59 Aux = L2X0_AUXCTRL_NSAC | L2X0_AUXCTRL_EM | L2X0_AUXCTRL_SBO;
60 // Use AWCACHE attributes for WA
61 Aux |= L2x0_AUXCTRL_AW_AWCACHE;
62 // Use default Size
63 Data = L2x0ReadReg(L2X0_AUXCTRL);
64 Aux |= Data & (0x7 << 17);
65 // Use default associativity
66 Aux |= Data & (0x1 << 16);
67 // Enabled I & D Prefetch
68 Aux |= L2x0_AUXCTRL_IPREFETCH | L2x0_AUXCTRL_DPREFETCH;
69
70 if (Revision >= 5) {
71 // Prefetch Offset Register
72 PfCtl = L2x0ReadReg(L2X0_PFCTRL);
73 // - Prefetch increment set to 0
74 // - Prefetch dropping off
75 // - Double linefills off
76 L2x0WriteReg(L2X0_PFCTRL, PfCtl);
77
78 // Power Control Register - L2X0_PWRCTRL
79 PwrCtl = L2x0ReadReg(L2X0_PWRCTRL);
80 // - Standby when idle off
81 // - Dynamic clock gating off
82 // - Nc,NC-shared dropping off
83 L2x0WriteReg(L2X0_PWRCTRL, PwrCtl);
84 }
85
86 if (Revision >= 4) {
87 // Tag RAM Latency register
88 // - Use default latency
89
90 // Data RAM Latency Control register
91 // - Use default latency
92 } else if (Revision >= 2) {
93 L2x0WriteReg(L230_TAG_LATENCY,
94 (L2_TAG_ACCESS_LATENCY << 8)
95 | (L2_TAG_ACCESS_LATENCY << 4)
96 | L2_TAG_SETUP_LATENCY
97 );
98
99 L2x0WriteReg(L230_DATA_LATENCY,
100 (L2_DATA_ACCESS_LATENCY << 8)
101 | (L2_DATA_ACCESS_LATENCY << 4)
102 | L2_DATA_SETUP_LATENCY
103 );
104 } else {
105 Aux |= (L2_TAG_ACCESS_LATENCY << 6)
106 | (L2_DATA_ACCESS_LATENCY << 3)
107 | L2_DATA_ACCESS_LATENCY;
108 }
109
110 // Write Auxiliary value
111 L2x0WriteReg(L2X0_AUXCTRL, Aux);
112
113 //
114 // Invalidate all entries in cache
115 //
116 L2x0WriteReg(L2X0_INVWAY, 0xffff);
117 // Poll cache maintenance register until invalidate operation is complete
118 while(L2x0ReadReg(L2X0_INVWAY) & 0xffff);
119
120 // Write to the Lockdown D and Lockdown I Register 9 if required
121 // - Not required
122
123 // Clear any residual raw interrupts
124 L2x0WriteReg(L2X0_INTCLEAR, 0x1FF);
125
126 // Enable the cache
127 if (CacheEnabled) {
128 L2x0WriteReg(L2X0_CTRL, L2X0_CTRL_ENABLED);
129 }
130 }