diff --git a/drivers/arm/scu/scu.c b/drivers/arm/scu/scu.c new file mode 100644 index 0000000..aceac92 --- /dev/null +++ b/drivers/arm/scu/scu.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include + +/******************************************************************************* + * Turn ON snoop control unit. This is needed to synchronize the data between + * CPU's. + ******************************************************************************/ +void enable_snoop_ctrl_unit(uintptr_t base) +{ + uint32_t scu_ctrl; + + INFO("[SCU]: enabling snoop control unit ... \n"); + + assert(base != 0U); + scu_ctrl = mmio_read_32(base + SCU_CTRL_REG); + + /* already enabled? */ + if ((scu_ctrl & SCU_ENABLE_BIT) != 0) { + return; + } + + scu_ctrl |= SCU_ENABLE_BIT; + mmio_write_32(base + SCU_CTRL_REG, scu_ctrl); +} + +/******************************************************************************* + * Snoop Control Unit configuration register. This is read-only register and + * contains information such as + * - number of CPUs present + * - is a particular CPU operating in SMP mode or AMP mode + * - data cache size of a particular CPU + * - does SCU has ACP port + * - is L2CPRESENT + * NOTE: user of this API should interpert the bits in this register according + * to the TRM + ******************************************************************************/ +uint32_t read_snoop_ctrl_unit_cfg(uintptr_t base) +{ + assert(base != 0U); + + return mmio_read_32(base + SCU_CFG_REG); +} diff --git a/include/drivers/arm/scu.h b/include/drivers/arm/scu.h new file mode 100644 index 0000000..992539f --- /dev/null +++ b/include/drivers/arm/scu.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2019, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SCU_H +#define SCU_H + +#include + +#define SCU_CTRL_REG 0x00 +#define SCU_CFG_REG 0x04 + +#define SCU_ENABLE_BIT (1 << 0) + +void enable_snoop_ctrl_unit(uintptr_t base); +uint32_t read_snoop_ctrl_unit_cfg(uintptr_t base); + +#endif /* SCU_H */ diff --git a/plat/arm/board/a5ds/a5ds_pm.c b/plat/arm/board/a5ds/a5ds_pm.c index cc734b0..7774002 100644 --- a/plat/arm/board/a5ds/a5ds_pm.c +++ b/plat/arm/board/a5ds/a5ds_pm.c @@ -4,11 +4,10 @@ * SPDX-License-Identifier: BSD-3-Clause */ #include - +#include #include #include #include -#include /******************************************************************************* * Platform handler called when a power domain is about to be turned on. The diff --git a/plat/arm/board/a5ds/include/platform_def.h b/plat/arm/board/a5ds/include/platform_def.h index e9e4b9a..d200af6 100644 --- a/plat/arm/board/a5ds/include/platform_def.h +++ b/plat/arm/board/a5ds/include/platform_def.h @@ -334,6 +334,9 @@ #define A5DS_HOLD_STATE_WAIT 0 #define A5DS_HOLD_STATE_GO 1 +/* Snoop Control Unit base address */ +#define A5DS_SCU_BASE 0x1C000000 + /* * GIC related constants to cater for GICv2 */ diff --git a/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c b/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c index 8b45af8..a951dc7 100644 --- a/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c +++ b/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c @@ -4,12 +4,17 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include #include + void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { arm_sp_min_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); + + /* enable snoop control unit */ + enable_snoop_ctrl_unit(A5DS_SCU_BASE); } /* diff --git a/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk b/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk index da1d785..4b0c97d 100644 --- a/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk +++ b/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk @@ -5,7 +5,8 @@ # # SP_MIN source files specific to A5DS platform -BL32_SOURCES += drivers/cfi/v2m/v2m_flash.c \ +BL32_SOURCES += drivers/arm/scu/scu.c \ + drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ lib/aarch32/arm32_aeabi_divmod.c \ lib/aarch32/arm32_aeabi_divmod_a32.S \