diff options
Diffstat (limited to 'arch/riscv/cpu')
-rw-r--r-- | arch/riscv/cpu/th1520/Kconfig | 1 | ||||
-rw-r--r-- | arch/riscv/cpu/th1520/Makefile | 2 | ||||
-rw-r--r-- | arch/riscv/cpu/th1520/cache.c | 2 | ||||
-rw-r--r-- | arch/riscv/cpu/th1520/cpu.c | 29 | ||||
-rw-r--r-- | arch/riscv/cpu/th1520/spl.c | 83 |
5 files changed, 115 insertions, 2 deletions
diff --git a/arch/riscv/cpu/th1520/Kconfig b/arch/riscv/cpu/th1520/Kconfig index 4d44191bd22..c73462c04b8 100644 --- a/arch/riscv/cpu/th1520/Kconfig +++ b/arch/riscv/cpu/th1520/Kconfig @@ -11,6 +11,7 @@ config THEAD_TH1520 select BINMAN if SPL select SYS_CACHE_THEAD_CMO select CLK_THEAD + select PINCTRL_TH1520 imply CPU imply CPU_RISCV imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE) diff --git a/arch/riscv/cpu/th1520/Makefile b/arch/riscv/cpu/th1520/Makefile index 5d806c06e2e..d971ea7390d 100644 --- a/arch/riscv/cpu/th1520/Makefile +++ b/arch/riscv/cpu/th1520/Makefile @@ -5,4 +5,4 @@ obj-y += cache.o obj-y += cpu.o obj-y += dram.o -obj-y += spl.o +obj-$(CONFIG_SPL_BUILD) += spl.o diff --git a/arch/riscv/cpu/th1520/cache.c b/arch/riscv/cpu/th1520/cache.c index 08aa1f789fd..b2fec229363 100644 --- a/arch/riscv/cpu/th1520/cache.c +++ b/arch/riscv/cpu/th1520/cache.c @@ -11,6 +11,7 @@ #define CSR_MHCR_IE BIT(0) #define CSR_MHCR_DE BIT(1) +#if CONFIG_IS_ENABLED(RISCV_MMODE) void icache_enable(void) { csr_write(CSR_MHCR, csr_read(CSR_MHCR) | CSR_MHCR_IE); @@ -30,3 +31,4 @@ int dcache_status(void) { return (csr_read(CSR_MHCR) & CSR_MHCR_DE) != 0; } +#endif /* CONFIG_IS_ENABLED(RISCV_MMODE) */ diff --git a/arch/riscv/cpu/th1520/cpu.c b/arch/riscv/cpu/th1520/cpu.c index b83f1272c67..f60446fd772 100644 --- a/arch/riscv/cpu/th1520/cpu.c +++ b/arch/riscv/cpu/th1520/cpu.c @@ -9,8 +9,35 @@ #include <asm/io.h> #include <cpu_func.h> +#include <linux/bitops.h> -#define TH1520_PMP_BASE (void *)0xffdc020000 +#define TH1520_C910_RST (void __iomem *)(0xffef014000 + 0x004) +#define TH1520_C910_CORE_RST_N(n) BIT((n) + 1) +#define TH1520_SYSCFG_AP_BASE (void __iomem *)(0xffef018000) +#define TH1520_SYSCFG_CORE_START_L(n) (TH1520_SYSCFG_AP_BASE + 0x50 + 8 * (n)) +#define TH1520_SYSCFG_CORE_START_H(n) (TH1520_SYSCFG_AP_BASE + 0x54 + 8 * (n)) +#define TH1520_PMP_BASE (void *)0xffdc020000 + +void th1520_kick_secondary_cores(void) +{ + int i; + + /* + * On coldboot, only HART 0 is brought up by hardware, and resets for + * secondary cores are asserted. Set reset address of secondary cores + * to the entry of SPL, then deassert the resets to bring them up. + */ + for (i = 1; i < 4; i++) { + writel(CONFIG_SPL_TEXT_BASE & 0xffffffff, + TH1520_SYSCFG_CORE_START_L(i)); + writel(CONFIG_SPL_TEXT_BASE >> 32, + TH1520_SYSCFG_CORE_START_H(i)); + } + + setbits_le32(TH1520_C910_RST, TH1520_C910_CORE_RST_N(1) | + TH1520_C910_CORE_RST_N(2) | + TH1520_C910_CORE_RST_N(3)); +} void th1520_invalidate_pmp(void) { diff --git a/arch/riscv/cpu/th1520/spl.c b/arch/riscv/cpu/th1520/spl.c index 362fe895f86..b95470485f6 100644 --- a/arch/riscv/cpu/th1520/spl.c +++ b/arch/riscv/cpu/th1520/spl.c @@ -4,6 +4,7 @@ */ #include <asm/arch/iopmp.h> #include <asm/io.h> +#include <cpu_func.h> #include <dm.h> #include <linux/sizes.h> #include <log.h> @@ -21,6 +22,52 @@ DECLARE_GLOBAL_DATA_PTR; #define TH1520_SUBSYS_RST_VI_N BIT(1) #define TH1520_SUBSYS_RST_DSP_N BIT(0) +#define CSR_MXSTATUS 0x7c0 +#define CSR_MXSTATUS_THEADISAEE BIT(22) +#define CSR_MXSTATUS_MAEE BIT(21) +#define CSR_MXSTATUS_CLINTEE BIT(17) +#define CSR_MXSTATUS_UCME BIT(16) +#define CSR_MXSTATUS_MM BIT(15) +#define CSR_MHCR 0x7c1 +#define CSR_MHCR_WBR BIT(8) +#define CSR_MHCR_BTB BIT(6) +#define CSR_MHCR_BPE BIT(5) +#define CSR_MHCR_RS BIT(4) +#define CSR_MHCR_WB BIT(3) +#define CSR_MHCR_WA BIT(2) +#define CSR_MHCR_DE BIT(1) +#define CSR_MHCR_IE BIT(0) +#define CSR_MCOR 0x7c2 +#define CSR_MCOR_IBP_INV BIT(18) +#define CSR_MCOR_BTB_INV BIT(17) +#define CSR_MCOR_BHT_INV BIT(16) +#define CSR_MCOR_CACHE_INV BIT(4) +#define CSR_MCCR2 0x7c3 +#define CSR_MCCR2_TPRF BIT(31) +#define CSR_MCCR2_IPRF(n) ((n) << 29) +#define CSR_MCCR2_TSETUP BIT(25) +#define CSR_MCCR2_TLNTCY(n) ((n) << 22) +#define CSR_MCCR2_DSETUP BIT(19) +#define CSR_MCCR2_DLNTCY(n) ((n) << 16) +#define CSR_MCCR2_L2EN BIT(3) +#define CSR_MCCR2_RFE BIT(0) +#define CSR_MHINT 0x7c5 +#define CSR_MHINT_FENCERW_BROAD_DIS BIT(22) +#define CSR_MHINT_TLB_BRAOD_DIS BIT(21) +#define CSR_MHINT_NSFE BIT(18) +#define CSR_MHINT_L2_PREF_DIST(n) ((n) << 16) +#define CSR_MHINT_L2PLD BIT(15) +#define CSR_MHINT_DCACHE_PREF_DIST(n) ((n) << 13) +#define CSR_MHINT_LPE BIT(9) +#define CSR_MHINT_ICACHE_PREF BIT(8) +#define CSR_MHINT_AMR BIT(3) +#define CSR_MHINT_DCACHE_PREF BIT(2) +#define CSR_MHINT2 0x7cc +#define CSR_MHINT2_LOCAL_ICG_EN(n) BIT((n) + 14) +#define CSR_MHINT4 0x7ce +#define CSR_MSMPR 0x7f3 +#define CSR_MSMPR_SMPEN BIT(0) + int spl_dram_init(void) { int ret; @@ -77,6 +124,42 @@ void harts_early_init(void) { int i; + /* Invalidate cache and buffer entries */ + csr_write(CSR_MCOR, CSR_MCOR_IBP_INV | CSR_MCOR_BTB_INV | + CSR_MCOR_BHT_INV | CSR_MCOR_CACHE_INV | 0x3); + + /* Enable cache snooping */ + csr_write(CSR_MSMPR, CSR_MSMPR_SMPEN); + + /* + * Configure and enable L2 cache, + * Enable tag/data RAM prefetch, both cost 2 cycles + * Prefetch 3 cache lines of instructions + * Enable read allocation + */ + csr_write(CSR_MCCR2, CSR_MCCR2_TPRF | CSR_MCCR2_IPRF(3) | + CSR_MCCR2_TSETUP | CSR_MCCR2_TLNTCY(1) | + CSR_MCCR2_DSETUP | CSR_MCCR2_DLNTCY(1) | + CSR_MCCR2_L2EN | CSR_MCCR2_RFE); + csr_write(CSR_MXSTATUS, CSR_MXSTATUS_THEADISAEE | CSR_MXSTATUS_MAEE | + CSR_MXSTATUS_CLINTEE | CSR_MXSTATUS_UCME | + CSR_MXSTATUS_MM); + csr_write(CSR_MHINT, CSR_MHINT_FENCERW_BROAD_DIS | + CSR_MHINT_TLB_BRAOD_DIS | + CSR_MHINT_NSFE | + CSR_MHINT_L2_PREF_DIST(2) | + CSR_MHINT_L2PLD | + CSR_MHINT_DCACHE_PREF_DIST(3) | + CSR_MHINT_LPE | + CSR_MHINT_ICACHE_PREF | + CSR_MHINT_AMR | + CSR_MHINT_DCACHE_PREF); + csr_write(CSR_MHCR, CSR_MHCR_WBR | CSR_MHCR_BTB | CSR_MHCR_BPE | + CSR_MHCR_RS | CSR_MHCR_WB | CSR_MHCR_WA | 0x3); + csr_write(CSR_MHINT2, CSR_MHINT2_LOCAL_ICG_EN(8) | + CSR_MHINT2_LOCAL_ICG_EN(3)); + csr_write(CSR_MHINT4, 0x410); + /* * Set IOPMPs to the default attribute, allowing the application * processor to access various peripherals. Subsystem clocks should be |