diff options
Diffstat (limited to 'arch/riscv/cpu/andesv5')
-rw-r--r-- | arch/riscv/cpu/andesv5/Kconfig | 15 | ||||
-rw-r--r-- | arch/riscv/cpu/andesv5/Makefile | 8 | ||||
-rw-r--r-- | arch/riscv/cpu/andesv5/cache.c | 130 | ||||
-rw-r--r-- | arch/riscv/cpu/andesv5/cpu.c | 50 | ||||
-rw-r--r-- | arch/riscv/cpu/andesv5/spl.c | 27 |
5 files changed, 230 insertions, 0 deletions
diff --git a/arch/riscv/cpu/andesv5/Kconfig b/arch/riscv/cpu/andesv5/Kconfig new file mode 100644 index 0000000000..82bb5a2a53 --- /dev/null +++ b/arch/riscv/cpu/andesv5/Kconfig @@ -0,0 +1,15 @@ +config RISCV_NDS + bool + select ARCH_EARLY_INIT_R + imply CPU + imply CPU_RISCV + imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE) + imply ANDES_PLICSW if (RISCV_MMODE || SPL_RISCV_MMODE) + imply ANDES_PLMT_TIMER if (RISCV_MMODE || SPL_RISCV_MMODE) + imply V5L2_CACHE + imply SPL_CPU + imply SPL_OPENSBI + imply SPL_LOAD_FIT + help + Run U-Boot on AndeStar V5 platforms and use some specific features + which are provided by Andes Technology AndeStar V5 families. diff --git a/arch/riscv/cpu/andesv5/Makefile b/arch/riscv/cpu/andesv5/Makefile new file mode 100644 index 0000000000..35a1a2fb83 --- /dev/null +++ b/arch/riscv/cpu/andesv5/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (C) 2017 Andes Technology Corporation +# Rick Chen, Andes Technology Corporation <rick@andestech.com> + +obj-y := cpu.o +obj-y += cache.o +obj-y += spl.o diff --git a/arch/riscv/cpu/andesv5/cache.c b/arch/riscv/cpu/andesv5/cache.c new file mode 100644 index 0000000000..40d77f671c --- /dev/null +++ b/arch/riscv/cpu/andesv5/cache.c @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2023 Andes Technology Corporation + * Rick Chen, Andes Technology Corporation <rick@andestech.com> + */ + +#include <asm/csr.h> +#include <asm/asm.h> +#include <common.h> +#include <cache.h> +#include <cpu_func.h> +#include <dm.h> +#include <dm/uclass-internal.h> +#include <asm/arch-andes/csr.h> + +#ifdef CONFIG_V5L2_CACHE +void enable_caches(void) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_driver(UCLASS_CACHE, + DM_DRIVER_GET(v5l2_cache), + &dev); + if (ret) { + log_debug("Cannot enable v5l2 cache\n"); + } else { + ret = cache_enable(dev); + if (ret) + log_debug("v5l2 cache enable failed\n"); + } +} + +static void cache_ops(int (*ops)(struct udevice *dev)) +{ + struct udevice *dev = NULL; + + uclass_find_first_device(UCLASS_CACHE, &dev); + + if (dev) + ops(dev); +} +#endif + +void flush_dcache_all(void) +{ +#if CONFIG_IS_ENABLED(RISCV_MMODE) + csr_write(CSR_MCCTLCOMMAND, CCTL_L1D_WBINVAL_ALL); +#endif +} + +void flush_dcache_range(unsigned long start, unsigned long end) +{ + flush_dcache_all(); +} + +void invalidate_dcache_range(unsigned long start, unsigned long end) +{ + flush_dcache_all(); +} + +void icache_enable(void) +{ +#if CONFIG_IS_ENABLED(RISCV_MMODE) + asm volatile("csrsi %0, 0x1" :: "i"(CSR_MCACHE_CTL)); +#endif +} + +void icache_disable(void) +{ +#if CONFIG_IS_ENABLED(RISCV_MMODE) + asm volatile("csrci %0, 0x1" :: "i"(CSR_MCACHE_CTL)); +#endif +} + +void dcache_enable(void) +{ +#if CONFIG_IS_ENABLED(RISCV_MMODE) + asm volatile("csrsi %0, 0x2" :: "i"(CSR_MCACHE_CTL)); +#endif + +#ifdef CONFIG_V5L2_CACHE + cache_ops(cache_enable); +#endif +} + +void dcache_disable(void) +{ +#if CONFIG_IS_ENABLED(RISCV_MMODE) + asm volatile("csrci %0, 0x2" :: "i"(CSR_MCACHE_CTL)); +#endif + +#ifdef CONFIG_V5L2_CACHE + cache_ops(cache_disable); +#endif +} + +int icache_status(void) +{ + int ret = 0; + +#if CONFIG_IS_ENABLED(RISCV_MMODE) + asm volatile ( + "csrr t1, %1\n\t" + "andi %0, t1, 0x01\n\t" + : "=r" (ret) + : "i"(CSR_MCACHE_CTL) + : "memory" + ); +#endif + + return !!ret; +} + +int dcache_status(void) +{ + int ret = 0; + +#if CONFIG_IS_ENABLED(RISCV_MMODE) + asm volatile ( + "csrr t1, %1\n\t" + "andi %0, t1, 0x02\n\t" + : "=r" (ret) + : "i" (CSR_MCACHE_CTL) + : "memory" + ); +#endif + + return !!ret; +} diff --git a/arch/riscv/cpu/andesv5/cpu.c b/arch/riscv/cpu/andesv5/cpu.c new file mode 100644 index 0000000000..06e379bcb1 --- /dev/null +++ b/arch/riscv/cpu/andesv5/cpu.c @@ -0,0 +1,50 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2023 Andes Technology Corporation + * Rick Chen, Andes Technology Corporation <rick@andestech.com> + */ + +/* CPU specific code */ +#include <common.h> +#include <cpu_func.h> +#include <irq_func.h> +#include <asm/cache.h> +#include <asm/csr.h> +#include <asm/arch-andes/csr.h> + +/* + * cleanup_before_linux() is called just before we call linux + * it prepares the processor for linux + * + * we disable interrupt and caches. + */ +int cleanup_before_linux(void) +{ + disable_interrupts(); + + cache_flush(); + + return 0; +} + +void harts_early_init(void) +{ + /* Enable I/D-cache in SPL */ + if (CONFIG_IS_ENABLED(RISCV_MMODE)) { + unsigned long mcache_ctl_val = csr_read(CSR_MCACHE_CTL); + + mcache_ctl_val |= (MCACHE_CTL_DC_COHEN | MCACHE_CTL_IC_EN | + MCACHE_CTL_DC_EN | MCACHE_CTL_CCTL_SUEN); + + csr_write(CSR_MCACHE_CTL, mcache_ctl_val); + + /* + * Check mcache_ctl.DC_COHEN, we assume this platform does + * not support CM if the bit is hard-wired to 0. + */ + if (csr_read(CSR_MCACHE_CTL) & MCACHE_CTL_DC_COHEN) { + /* Wait for DC_COHSTA bit to be set */ + while (!(csr_read(CSR_MCACHE_CTL) & MCACHE_CTL_DC_COHSTA)); + } + } +} diff --git a/arch/riscv/cpu/andesv5/spl.c b/arch/riscv/cpu/andesv5/spl.c new file mode 100644 index 0000000000..413849043b --- /dev/null +++ b/arch/riscv/cpu/andesv5/spl.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2023 Andes Technology Corporation + * Rick Chen, Andes Technology Corporation <rick@andestech.com> + */ +#include <common.h> +#include <cpu_func.h> +#include <hang.h> +#include <init.h> +#include <log.h> +#include <spl.h> +#include <asm/global_data.h> +#include <asm/system.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if CONFIG_IS_ENABLED(RAM_SUPPORT) +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) +{ + return (void *)(CONFIG_SPL_LOAD_FIT_ADDRESS + offset); +} + +void *board_spl_fit_buffer_addr(ulong fit_size, int sectors, int bl_len) +{ + return spl_get_load_buffer(0, sectors * bl_len); +} +#endif |