1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
|
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2025 Yao Zi <ziyao@disroot.org>
*/
#include <asm/arch/iopmp.h>
#include <asm/io.h>
#include <cpu_func.h>
#include <dm.h>
#include <linux/sizes.h>
#include <log.h>
#include <init.h>
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]);
}
|