mirror of https://github.com/acidanthera/audk.git
127 lines
3.6 KiB
C
127 lines
3.6 KiB
C
/** @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 <Library/IoLib.h>
|
|
#include <Library/DebugLib.h>
|
|
#include <Library/ArmLib.h>
|
|
#include <Drivers/PL310L2Cache.h>
|
|
#include <Library/PcdLib.h>
|
|
|
|
#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);
|
|
}
|
|
}
|