diff --git a/soc/riscv/riscv-privilege/andes_v5/CMakeLists.txt b/soc/riscv/riscv-privilege/andes_v5/CMakeLists.txt index de945fa8cb7..b117c3c4401 100644 --- a/soc/riscv/riscv-privilege/andes_v5/CMakeLists.txt +++ b/soc/riscv/riscv-privilege/andes_v5/CMakeLists.txt @@ -8,6 +8,7 @@ zephyr_sources( ) zephyr_sources_ifdef(CONFIG_SOC_ANDES_V5_PMA pma.c) +zephyr_sources_ifdef(CONFIG_SOC_ANDES_V5_L2_CACHE l2_cache.c) # Note: AndeStar V5 DSP needs custom Andes V5 toolchain if(CONFIG_SOC_ANDES_V5_HWDSP) diff --git a/soc/riscv/riscv-privilege/andes_v5/Kconfig.soc b/soc/riscv/riscv-privilege/andes_v5/Kconfig.soc index bfe601ac89a..1bd10402540 100644 --- a/soc/riscv/riscv-privilege/andes_v5/Kconfig.soc +++ b/soc/riscv/riscv-privilege/andes_v5/Kconfig.soc @@ -47,6 +47,11 @@ config CACHE_ENABLE bool "Enable cache" default n +config SOC_ANDES_V5_L2_CACHE + bool "Enable Andes V5 L2 cache controller" + depends on CACHE_ENABLE + default y + config SOC_ANDES_V5_HWDSP bool "Enable AndeStar V5 DSP ISA" select RISCV_SOC_CONTEXT_SAVE diff --git a/soc/riscv/riscv-privilege/andes_v5/l2_cache.c b/soc/riscv/riscv-privilege/andes_v5/l2_cache.c new file mode 100644 index 00000000000..50e8e974a53 --- /dev/null +++ b/soc/riscv/riscv-privilege/andes_v5/l2_cache.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2021 Andes Technology Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT andestech_l2c + +/** + * @brief Andes V5 L2 Cache Controller driver + */ + +#include +#include +#include +#include + +/* + * L2C Register Base Address + */ + +#define AMDES_V5_L2C_BASE DT_INST_REG_ADDR(0) + +/* + * L2C Register Offset + */ + +#define L2C_CTRL 0x08 + +/* + * L2C Helper Constant + */ + +/* enable L2C */ +#define L2C_CTRL_CEN BIT(0) + +/* instruction prefetch depth */ +#define IPFDPT_FIELD(x) (x << 3) +#define L2C_CTRL_IPFDPT_0 IPFDPT_FIELD(0) +#define L2C_CTRL_IPFDPT_1 IPFDPT_FIELD(1) +#define L2C_CTRL_IPFDPT_2 IPFDPT_FIELD(2) +#define L2C_CTRL_IPFDPT_3 IPFDPT_FIELD(3) + +/* data prefetch depth */ +#define DPFDPT_FIELD(x) (x << 5) +#define L2C_CTRL_DPFDPT_0 DPFDPT_FIELD(0) +#define L2C_CTRL_DPFDPT_2 DPFDPT_FIELD(1) +#define L2C_CTRL_DPFDPT_4 DPFDPT_FIELD(2) +#define L2C_CTRL_DPFDPT_8 DPFDPT_FIELD(3) + +static void andes_v5_l2c_enable(void) +{ + volatile uint64_t *l2c_ctrl = + INT_TO_POINTER(AMDES_V5_L2C_BASE + L2C_CTRL); + + /* Use largest instr/data prefetch depth by default */ + uint64_t l2c_config = L2C_CTRL_IPFDPT_3 | L2C_CTRL_DPFDPT_8; + + /* Configure L2 cache */ + *l2c_ctrl = l2c_config; + + /* Enable L2 cache */ + *l2c_ctrl = (l2c_config | L2C_CTRL_CEN); +} + +static int andes_v5_l2c_init(const struct device *dev) +{ + ARG_UNUSED(dev); + +#ifdef SMU_BASE + volatile uint32_t *system_cfg = INT_TO_POINTER(SMU_BASE + SMU_SYSTEMCFG); + + if (!(*system_cfg & SMU_SYSTEMCFG_L2C)) { + /* This SoC doesn't have L2 cache */ + return -1; + } +#endif /* SMU_BASE */ + + andes_v5_l2c_enable(); + return 0; +} + +SYS_INIT(andes_v5_l2c_init, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);