// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2025 Yao Zi */ #include #include #include #include #include #include #include DECLARE_GLOBAL_DATA_PTR; #define TH1520_SUBSYS_CLK (void __iomem *)(0xffff011000 + 0x220) #define TH1520_SUBSYS_CLK_VO_EN BIT(2) #define TH1520_SUBSYS_CLK_VI_EN BIT(1) #define TH1520_SUBSYS_CLK_DSP_EN BIT(0) #define TH1520_SUBSYS_RST (void __iomem *)(0xffff015000 + 0x220) #define TH1520_SUBSYS_RST_VP_N BIT(3) #define TH1520_SUBSYS_RST_VO_N BIT(2) #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; struct udevice *dev; ret = fdtdec_setup_mem_size_base(); if (ret) { printf("failed to setup memory size and base: %d\n", ret); return ret; } /* DDR init */ ret = uclass_get_device(UCLASS_RAM, 0, &dev); if (ret) { printf("DRAM init failed: %d\n", ret); return ret; } return 0; } static void __iomem *th1520_iopmp_regs[] = { TH1520_IOPMP_EMMC, TH1520_IOPMP_SDIO0, TH1520_IOPMP_SDIO1, TH1520_IOPMP_USB0, TH1520_IOPMP_AO, TH1520_IOPMP_AUD, TH1520_IOPMP_CHIP_DBG, TH1520_IOPMP_EIP120I, TH1520_IOPMP_EIP120II, TH1520_IOPMP_EIP120III, TH1520_IOPMP_ISP0, TH1520_IOPMP_ISP1, TH1520_IOPMP_DW200, TH1520_IOPMP_VIPRE, TH1520_IOPMP_VENC, TH1520_IOPMP_VDEC, TH1520_IOPMP_G2D, TH1520_IOPMP_FCE, TH1520_IOPMP_NPU, TH1520_IOPMP_DPU0, TH1520_IOPMP_DPU1, TH1520_IOPMP_GPU, TH1520_IOPMP_GMAC1, TH1520_IOPMP_GMAC2, TH1520_IOPMP_DMAC, TH1520_IOPMP_TEE_DMAC, TH1520_IOPMP_DSP0, TH1520_IOPMP_DSP1, }; 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 * enabled and resets should be deasserted ahead of time, or the HART * will hang when configuring corresponding IOPMP entries. */ setbits_le32(TH1520_SUBSYS_CLK, TH1520_SUBSYS_CLK_VO_EN | TH1520_SUBSYS_CLK_VI_EN | TH1520_SUBSYS_CLK_DSP_EN); setbits_le32(TH1520_SUBSYS_RST, TH1520_SUBSYS_RST_VP_N | TH1520_SUBSYS_RST_VO_N | TH1520_SUBSYS_RST_VI_N | TH1520_SUBSYS_RST_DSP_N); for (i = 0; i < ARRAY_SIZE(th1520_iopmp_regs); i++) writel(TH1520_IOPMP_DEFAULT_ATTR, th1520_iopmp_regs[i]); }