mirror of
https://github.com/ARM-software/arm-trusted-firmware.git
synced 2025-04-17 01:54:22 +00:00
feat(s32g274a): add ncore support
Ncore is a cache-coherent interconnect module. It enables the integration of heterogenous coherent agents and non-coherent agents in a chip. TF-A boots with the first core in isolation to avoid crashes due to cache invalidation operations. Later, it will disable the isolation and reconfigure the module every time a new core is added or removed through PSCI. Change-Id: Ida42db91b10be1e66c3b9b73674d1e37a61844dd Signed-off-by: Dan Nica <dan.nica@nxp.com> Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com> Signed-off-by: Ghennadi Procopciuc <ghennadi.procopciuc@nxp.com>
This commit is contained in:
parent
5765e0c95a
commit
5071f7c7ee
5 changed files with 216 additions and 8 deletions
102
plat/nxp/s32/s32g274ardb2/include/s32cc-ncore.h
Normal file
102
plat/nxp/s32/s32g274ardb2/include/s32cc-ncore.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright 2019-2021, 2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef S32G2_NCORE_H
|
||||
#define S32G2_NCORE_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#define NCORE_BASE_ADDR UL(0x50400000)
|
||||
|
||||
#define A53_CLUSTER0_CAIU U(0)
|
||||
#define A53_CLUSTER1_CAIU U(1)
|
||||
|
||||
/**
|
||||
* Directory Unit Registers
|
||||
*
|
||||
* The directory provides a point of serialization for establishing transaction
|
||||
* ordering and sequences coherence operations and memory accesses.
|
||||
*/
|
||||
#define NCORE_DIRU(N) (NCORE_BASE_ADDR + UL(0x80000) + ((N) * UL(0x1000)))
|
||||
|
||||
/* DIRU Snoop Filtering Enable */
|
||||
#define NCORE_DIRUSFE(N) (NCORE_DIRU(N) + UL(0x10))
|
||||
#define NCORE_DIRUSFE_SFEN(SF) BIT_32(SF)
|
||||
|
||||
/* DIRU Caching Agent Snoop Enable */
|
||||
#define NCORE_DIRUCASE(N) (NCORE_DIRU(N) + UL(0x40))
|
||||
#define NCORE_DIRUCASE_CASNPEN(CAIU) BIT_32(CAIU)
|
||||
|
||||
/* DIRU Snoop Filter Maintenance Control */
|
||||
#define NCORE_DIRUSFMC(N) (NCORE_DIRU(N) + UL(0x80))
|
||||
#define NCORE_DIRUSFMC_SFID(SF) ((SF) << 16U)
|
||||
#define NCORE_DIRUSFMC_SFMNTOP_ALL U(0x0)
|
||||
|
||||
/* DIRU Snoop Filter Maintenance Activity */
|
||||
#define NCORE_DIRUSFMA(N) (NCORE_DIRU(N) + UL(0x84))
|
||||
#define NCORE_DIRUSFMA_MNTOPACTV BIT_32(0)
|
||||
|
||||
/**
|
||||
* Coherent Agent Interface Unit Registers
|
||||
*
|
||||
* CAI provides a means for a fully-coherent agent to be connected to the Ncore.
|
||||
* The CAI behaves as a fully-coherent slave.
|
||||
*/
|
||||
#define NCORE_CAIU(N) (NCORE_BASE_ADDR + ((N) * UL(0x1000)))
|
||||
#define NCORE_CAIU0_BASE_ADDR NCORE_BASE_ADDR
|
||||
|
||||
/* CAIU Transaction Control */
|
||||
#define NCORE_CAIUTC_OFF UL(0x0)
|
||||
#define NCORE_CAIUTC_ISOLEN_SHIFT U(1)
|
||||
#define NCORE_CAIUTC_ISOLEN_MASK BIT_32(NCORE_CAIUTC_ISOLEN_SHIFT)
|
||||
|
||||
#define NCORE_CAIUTC(N) (NCORE_CAIU(N) + NCORE_CAIUTC_OFF)
|
||||
|
||||
/* CAIU Identification */
|
||||
#define NCORE_CAIUID(n) (NCORE_CAIU(n) + UL(0xFFC))
|
||||
#define NCORE_CAIUID_TYPE GENMASK_32(U(19), U(16))
|
||||
#define NCORE_CAIUID_TYPE_ACE_DVM U(0x0)
|
||||
|
||||
/**
|
||||
* Coherent Subsystem Registers
|
||||
*/
|
||||
#define NCORE_CSR (NCORE_BASE_ADDR + UL(0xFF000))
|
||||
|
||||
/* Coherent Subsystem ACE DVM Snoop Enable */
|
||||
#define NCORE_CSADSE (NCORE_CSR + UL(0x40))
|
||||
#define NCORE_CSADSE_DVMSNPEN(CAIU) BIT_32(CAIU)
|
||||
|
||||
/* Coherent Subsystem Identification */
|
||||
#define NCORE_CSID (NCORE_CSR + UL(0xFFC))
|
||||
#define NCORE_CSID_NUMSFS_SHIFT U(18)
|
||||
#define NCORE_CSID_NUMSFS_MASK GENMASK_32(U(22), NCORE_CSID_NUMSFS_SHIFT)
|
||||
#define NCORE_CSID_NUMSFS(CSIDR) (((CSIDR) & NCORE_CSID_NUMSFS_MASK) \
|
||||
>> NCORE_CSID_NUMSFS_SHIFT)
|
||||
|
||||
/* Coherent Subsystem Unit Identification */
|
||||
#define NCORE_CSUID (NCORE_CSR + UL(0xFF8))
|
||||
#define NCORE_CSUID_NUMCMIUS_SHIFT U(24)
|
||||
#define NCORE_CSUID_NUMCMIUS_MASK GENMASK_32(U(29), NCORE_CSUID_NUMCMIUS_SHIFT)
|
||||
#define NCORE_CSUID_NUMCMIUS(CSUIDR) (((CSUIDR) & NCORE_CSUID_NUMCMIUS_MASK) \
|
||||
>> NCORE_CSUID_NUMCMIUS_SHIFT)
|
||||
#define NCORE_CSUID_NUMDIRUS_SHIFT U(16)
|
||||
#define NCORE_CSUID_NUMDIRUS_MASK GENMASK_32(U(21), NCORE_CSUID_NUMDIRUS_SHIFT)
|
||||
#define NCORE_CSUID_NUMDIRUS(CSUIDR) (((CSUIDR) & NCORE_CSUID_NUMDIRUS_MASK) \
|
||||
>> NCORE_CSUID_NUMDIRUS_SHIFT)
|
||||
#define NCORE_CSUID_NUMNCBUS_SHIFT U(8)
|
||||
#define NCORE_CSUID_NUMNCBUS_MASK GENMASK_32(U(13), NCORE_CSUID_NUMNCBUS_SHIFT)
|
||||
#define NCORE_CSUID_NUMNCBUS(CSUIDR) (((CSUIDR) & NCORE_CSUID_NUMNCBUS_MASK) \
|
||||
>> NCORE_CSUID_NUMNCBUS_SHIFT)
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
void ncore_caiu_online(uint32_t caiu);
|
||||
void ncore_caiu_offline(uint32_t caiu);
|
||||
void ncore_init(void);
|
||||
bool ncore_is_caiu_online(uint32_t caiu);
|
||||
void ncore_disable_caiu_isolation(uint32_t caiu);
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
||||
#endif /* S32G2_NCORE_H */
|
|
@ -11,6 +11,7 @@
|
|||
#include <plat_console.h>
|
||||
#include <s32cc-clk-drv.h>
|
||||
#include <plat_io_storage.h>
|
||||
#include <s32cc-ncore.h>
|
||||
|
||||
#define SIUL2_PC09_MSCR UL(0x4009C2E4)
|
||||
#define SIUL2_PC10_MSCR UL(0x4009C2E8)
|
||||
|
@ -62,6 +63,14 @@ void bl2_el3_early_platform_setup(u_register_t arg0, u_register_t arg1,
|
|||
linflex_config_pinctrl();
|
||||
console_s32g2_register();
|
||||
|
||||
/* Restore (clear) the CAIUTC[IsolEn] bit for the primary cluster, which
|
||||
* we have manually set during early BL2 boot.
|
||||
*/
|
||||
ncore_disable_caiu_isolation(A53_CLUSTER0_CAIU);
|
||||
|
||||
ncore_init();
|
||||
ncore_caiu_online(A53_CLUSTER0_CAIU);
|
||||
|
||||
plat_s32g2_io_setup();
|
||||
}
|
||||
|
||||
|
|
|
@ -6,10 +6,7 @@
|
|||
|
||||
#include <asm_macros.S>
|
||||
#include <platform_def.h>
|
||||
|
||||
#define S32G_NCORE_CAIU0_BASE_ADDR UL(0x50400000)
|
||||
#define S32G_NCORE_CAIUTC_OFF U(0x0)
|
||||
#define S32G_NCORE_CAIUTC_ISOLEN_SHIFT U(1)
|
||||
#include <s32cc-ncore.h>
|
||||
|
||||
.globl plat_crash_console_flush
|
||||
.globl plat_crash_console_init
|
||||
|
@ -104,12 +101,12 @@ endfunc plat_secondary_cold_boot_setup
|
|||
* Clobber list: x0, x1, x2
|
||||
*/
|
||||
func plat_reset_handler
|
||||
mov x0, #S32G_NCORE_CAIU0_BASE_ADDR
|
||||
ldr w1, [x0, #S32G_NCORE_CAIUTC_OFF]
|
||||
mov x0, #NCORE_CAIU0_BASE_ADDR
|
||||
ldr w1, [x0, #NCORE_CAIUTC_OFF]
|
||||
movz w2, #1
|
||||
lsl w2, w2, #S32G_NCORE_CAIUTC_ISOLEN_SHIFT
|
||||
lsl w2, w2, #NCORE_CAIUTC_ISOLEN_SHIFT
|
||||
orr w1, w1, w2
|
||||
str w1, [x0, #S32G_NCORE_CAIUTC_OFF]
|
||||
str w1, [x0, #NCORE_CAIUTC_OFF]
|
||||
ret
|
||||
endfunc plat_reset_handler
|
||||
|
||||
|
|
|
@ -53,6 +53,7 @@ BL2_SOURCES += \
|
|||
${PLAT_S32G274ARDB2}/plat_bl2_el3_setup.c \
|
||||
${PLAT_S32G274ARDB2}/plat_bl2_image_desc.c \
|
||||
${PLAT_S32G274ARDB2}/plat_io_storage.c \
|
||||
${PLAT_S32G274ARDB2}/s32cc_ncore.c \
|
||||
common/desc_image_load.c \
|
||||
drivers/io/io_fip.c \
|
||||
drivers/io/io_memmap.c \
|
||||
|
|
99
plat/nxp/s32/s32g274ardb2/s32cc_ncore.c
Normal file
99
plat/nxp/s32/s32g274ardb2/s32cc_ncore.c
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* Copyright 2019-2021, 2024 NXP
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
#include <lib/mmio.h>
|
||||
#include <platform_def.h>
|
||||
|
||||
#include <s32cc-ncore.h>
|
||||
|
||||
static void ncore_diru_online(uint32_t diru)
|
||||
{
|
||||
uint32_t numsfs, sf;
|
||||
|
||||
numsfs = NCORE_CSID_NUMSFS(mmio_read_32(NCORE_CSID)) + 1U;
|
||||
|
||||
/* Initialize all entries maintenance operation for each snoop filter */
|
||||
for (sf = 0U; sf < numsfs; sf++) {
|
||||
mmio_write_32(NCORE_DIRUSFMC(diru), NCORE_DIRUSFMC_SFID(sf) |
|
||||
NCORE_DIRUSFMC_SFMNTOP_ALL);
|
||||
|
||||
while ((mmio_read_32(NCORE_DIRUSFMA(diru)) & NCORE_DIRUSFMA_MNTOPACTV) != 0U) {
|
||||
}
|
||||
|
||||
mmio_setbits_32(NCORE_DIRUSFE(diru), NCORE_DIRUSFE_SFEN(sf));
|
||||
}
|
||||
}
|
||||
|
||||
void ncore_disable_caiu_isolation(uint32_t caiu)
|
||||
{
|
||||
/* Exit from low-power state */
|
||||
mmio_clrbits_32(NCORE_CAIUTC(caiu), NCORE_CAIUTC_ISOLEN_MASK);
|
||||
}
|
||||
|
||||
static void set_caiu(uint32_t caiu, bool on)
|
||||
{
|
||||
uint32_t dirucase, csadser, caiuidr;
|
||||
uint32_t numdirus, diru;
|
||||
|
||||
/* Enable or disable snoop messages to the CAI for each DIRU */
|
||||
numdirus = NCORE_CSUID_NUMDIRUS(mmio_read_32(NCORE_CSUID));
|
||||
for (diru = 0; diru < numdirus; diru++) {
|
||||
dirucase = mmio_read_32(NCORE_DIRUCASE(diru));
|
||||
|
||||
if (on) {
|
||||
dirucase |= NCORE_DIRUCASE_CASNPEN(caiu);
|
||||
} else {
|
||||
dirucase &= ~NCORE_DIRUCASE_CASNPEN(caiu);
|
||||
}
|
||||
|
||||
mmio_write_32(NCORE_DIRUCASE(diru), dirucase);
|
||||
}
|
||||
|
||||
/* Enable or disable DVM messages to the CAI */
|
||||
caiuidr = mmio_read_32(NCORE_CAIUID(caiu));
|
||||
if ((caiuidr & NCORE_CAIUID_TYPE) == NCORE_CAIUID_TYPE_ACE_DVM) {
|
||||
csadser = mmio_read_32(NCORE_CSADSE);
|
||||
|
||||
if (on) {
|
||||
csadser |= NCORE_CSADSE_DVMSNPEN(caiu);
|
||||
} else {
|
||||
csadser &= ~NCORE_CSADSE_DVMSNPEN(caiu);
|
||||
}
|
||||
|
||||
mmio_write_32(NCORE_CSADSE, csadser);
|
||||
}
|
||||
}
|
||||
|
||||
void ncore_caiu_online(uint32_t caiu)
|
||||
{
|
||||
set_caiu(caiu, true);
|
||||
}
|
||||
|
||||
void ncore_caiu_offline(uint32_t caiu)
|
||||
{
|
||||
set_caiu(caiu, false);
|
||||
}
|
||||
|
||||
bool ncore_is_caiu_online(uint32_t caiu)
|
||||
{
|
||||
uint32_t stat = mmio_read_32(NCORE_CSADSE);
|
||||
|
||||
return ((stat & NCORE_CSADSE_DVMSNPEN(caiu)) != 0U);
|
||||
}
|
||||
|
||||
void ncore_init(void)
|
||||
{
|
||||
uint32_t csuidr = mmio_read_32(NCORE_CSUID);
|
||||
uint32_t numdirus, diru;
|
||||
|
||||
numdirus = NCORE_CSUID_NUMDIRUS(csuidr);
|
||||
for (diru = 0U; diru < numdirus; diru++) {
|
||||
/**
|
||||
* Transition the directory to an online state by ensuring that
|
||||
* all DIRUs within the interface are operational.
|
||||
*/
|
||||
ncore_diru_online(diru);
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue