1 /*
2 * Copyright (C) 2018 Marvell International Ltd.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 * https://spdx.org/licenses
6 */
7
8 /* AP806 Marvell SoC driver */
9
10 #include <common/debug.h>
11 #include <drivers/marvell/ccu.h>
12 #include <drivers/marvell/cache_llc.h>
13 #include <drivers/marvell/io_win.h>
14 #include <drivers/marvell/mci.h>
15 #include <drivers/marvell/mochi/ap_setup.h>
16 #include <lib/mmio.h>
17
18 #include <a8k_plat_def.h>
19
20 #define SMMU_sACR (MVEBU_SMMU_BASE + 0x10)
21 #define SMMU_sACR_PG_64K (1 << 16)
22
23 #define CCU_GSPMU_CR (MVEBU_CCU_BASE(MVEBU_AP0) + \
24 0x3F0)
25 #define GSPMU_CPU_CONTROL (0x1 << 0)
26
27 #define CCU_HTC_CR (MVEBU_CCU_BASE(MVEBU_AP0) + \
28 0x200)
29 #define CCU_SET_POC_OFFSET 5
30
31 #define DSS_CR0 (MVEBU_RFU_BASE + 0x100)
32 #define DVM_48BIT_VA_ENABLE (1 << 21)
33
34 /* Secure MoChi incoming access */
35 #define SEC_MOCHI_IN_ACC_REG (MVEBU_RFU_BASE + 0x4738)
36 #define SEC_MOCHI_IN_ACC_IHB0_EN (1)
37 #define SEC_MOCHI_IN_ACC_IHB1_EN (1 << 3)
38 #define SEC_MOCHI_IN_ACC_IHB2_EN (1 << 6)
39 #define SEC_MOCHI_IN_ACC_PIDI_EN (1 << 9)
40 #define SEC_IN_ACCESS_ENA_ALL_MASTERS (SEC_MOCHI_IN_ACC_IHB0_EN | \
41 SEC_MOCHI_IN_ACC_IHB1_EN | \
42 SEC_MOCHI_IN_ACC_IHB2_EN | \
43 SEC_MOCHI_IN_ACC_PIDI_EN)
44 #define MOCHI_IN_ACC_LEVEL_FORCE_NONSEC (0)
45 #define MOCHI_IN_ACC_LEVEL_FORCE_SEC (1)
46 #define MOCHI_IN_ACC_LEVEL_LEAVE_ORIG (2)
47 #define MOCHI_IN_ACC_LEVEL_MASK_ALL (3)
48 #define SEC_MOCHI_IN_ACC_IHB0_LEVEL(l) ((l) << 1)
49 #define SEC_MOCHI_IN_ACC_IHB1_LEVEL(l) ((l) << 4)
50 #define SEC_MOCHI_IN_ACC_PIDI_LEVEL(l) ((l) << 10)
51
52
53 /* SYSRST_OUTn Config definitions */
54 #define MVEBU_SYSRST_OUT_CONFIG_REG (MVEBU_MISC_SOC_BASE + 0x4)
55 #define WD_MASK_SYS_RST_OUT (1 << 2)
56
57 /* Generic Timer System Controller */
58 #define MVEBU_MSS_GTCR_REG (MVEBU_REGS_BASE + 0x581000)
59 #define MVEBU_MSS_GTCR_ENABLE_BIT 0x1
60
61 /*
62 * AXI Configuration.
63 */
64
65 /* Used for Units of AP-806 (e.g. SDIO and etc) */
66 #define MVEBU_AXI_ATTR_BASE (MVEBU_REGS_BASE + 0x6F4580)
67 #define MVEBU_AXI_ATTR_REG(index) (MVEBU_AXI_ATTR_BASE + \
68 0x4 * index)
69
70 #define XOR_STREAM_ID_REG(ch) (MVEBU_REGS_BASE + 0x410010 + (ch) * 0x20000)
71 #define XOR_STREAM_ID_MASK 0xFFFF
72 #define SDIO_STREAM_ID_REG (MVEBU_RFU_BASE + 0x4600)
73 #define SDIO_STREAM_ID_MASK 0xFF
74
75 /* Do not use the default Stream ID 0 */
76 #define A806_STREAM_ID_BASE (0x1)
77
78 static uintptr_t stream_id_reg[] = {
79 XOR_STREAM_ID_REG(0),
80 XOR_STREAM_ID_REG(1),
81 XOR_STREAM_ID_REG(2),
82 XOR_STREAM_ID_REG(3),
83 SDIO_STREAM_ID_REG,
84 0
85 };
86
87 enum axi_attr {
88 AXI_SDIO_ATTR = 0,
89 AXI_DFX_ATTR,
90 AXI_MAX_ATTR,
91 };
92
apn_sec_masters_access_en(uint32_t enable)93 static void apn_sec_masters_access_en(uint32_t enable)
94 {
95 /* Open/Close incoming access for all masters.
96 * The access is disabled in trusted boot mode
97 * Could only be done in EL3
98 */
99 if (enable != 0) {
100 mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, 0x0U, /* no clear */
101 SEC_IN_ACCESS_ENA_ALL_MASTERS);
102 #if LLC_SRAM
103 /* Do not change access security level
104 * for PIDI masters
105 */
106 mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG,
107 SEC_MOCHI_IN_ACC_PIDI_LEVEL(
108 MOCHI_IN_ACC_LEVEL_MASK_ALL),
109 SEC_MOCHI_IN_ACC_PIDI_LEVEL(
110 MOCHI_IN_ACC_LEVEL_LEAVE_ORIG));
111 #endif
112 } else {
113 mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG,
114 SEC_IN_ACCESS_ENA_ALL_MASTERS,
115 0x0U /* no set */);
116 #if LLC_SRAM
117 /* Return PIDI access level to the default */
118 mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG,
119 SEC_MOCHI_IN_ACC_PIDI_LEVEL(
120 MOCHI_IN_ACC_LEVEL_MASK_ALL),
121 SEC_MOCHI_IN_ACC_PIDI_LEVEL(
122 MOCHI_IN_ACC_LEVEL_FORCE_NONSEC));
123 #endif
124 }
125 }
126
setup_smmu(void)127 static void setup_smmu(void)
128 {
129 uint32_t reg;
130
131 /* Set the SMMU page size to 64 KB */
132 reg = mmio_read_32(SMMU_sACR);
133 reg |= SMMU_sACR_PG_64K;
134 mmio_write_32(SMMU_sACR, reg);
135 }
136
init_aurora2(void)137 static void init_aurora2(void)
138 {
139 uint32_t reg;
140
141 /* Enable GSPMU control by CPU */
142 reg = mmio_read_32(CCU_GSPMU_CR);
143 reg |= GSPMU_CPU_CONTROL;
144 mmio_write_32(CCU_GSPMU_CR, reg);
145
146 #if LLC_ENABLE
147 /* Enable LLC for AP806 in exclusive mode */
148 llc_enable(0, 1);
149
150 /* Set point of coherency to DDR.
151 * This is required by units which have
152 * SW cache coherency
153 */
154 reg = mmio_read_32(CCU_HTC_CR);
155 reg |= (0x1 << CCU_SET_POC_OFFSET);
156 mmio_write_32(CCU_HTC_CR, reg);
157 #endif /* LLC_ENABLE */
158
159 errata_wa_init();
160 }
161
162
163 /* MCIx indirect access register are based by default at 0xf4000000/0xf6000000
164 * to avoid conflict of internal registers of units connected via MCIx, which
165 * can be based on the same address (i.e CP1 base is also 0xf4000000),
166 * the following routines remaps the MCIx indirect bases to another domain
167 */
mci_remap_indirect_access_base(void)168 static void mci_remap_indirect_access_base(void)
169 {
170 uint32_t mci;
171
172 for (mci = 0; mci < MCI_MAX_UNIT_ID; mci++)
173 mmio_write_32(MCIX4_REG_START_ADDRESS_REG(mci),
174 MVEBU_MCI_REG_BASE_REMAP(mci) >>
175 MCI_REMAP_OFF_SHIFT);
176 }
177
178 /* Set a unique stream id for all DMA capable devices */
ap806_stream_id_init(void)179 static void ap806_stream_id_init(void)
180 {
181 int i;
182
183 for (i = 0; stream_id_reg[i] != 0; i++) {
184 uint32_t mask = stream_id_reg[i] == SDIO_STREAM_ID_REG ?
185 SDIO_STREAM_ID_MASK : XOR_STREAM_ID_MASK;
186
187 mmio_clrsetbits_32(stream_id_reg[i], mask,
188 i + A806_STREAM_ID_BASE);
189 }
190 }
191
apn806_axi_attr_init(void)192 static void apn806_axi_attr_init(void)
193 {
194 uint32_t index, data;
195
196 /* Initialize AXI attributes for APN806 */
197
198 /* Go over the AXI attributes and set Ax-Cache and Ax-Domain */
199 for (index = 0; index < AXI_MAX_ATTR; index++) {
200 switch (index) {
201 /* DFX works with no coherent only -
202 * there's no option to configure the Ax-Cache and Ax-Domain
203 */
204 case AXI_DFX_ATTR:
205 continue;
206 default:
207 /* Set Ax-Cache as cacheable, no allocate, modifiable,
208 * bufferable
209 * The values are different because Read & Write
210 * definition is different in Ax-Cache
211 */
212 data = mmio_read_32(MVEBU_AXI_ATTR_REG(index));
213 data &= ~MVEBU_AXI_ATTR_ARCACHE_MASK;
214 data |= (CACHE_ATTR_WRITE_ALLOC |
215 CACHE_ATTR_CACHEABLE |
216 CACHE_ATTR_BUFFERABLE) <<
217 MVEBU_AXI_ATTR_ARCACHE_OFFSET;
218 data &= ~MVEBU_AXI_ATTR_AWCACHE_MASK;
219 data |= (CACHE_ATTR_READ_ALLOC |
220 CACHE_ATTR_CACHEABLE |
221 CACHE_ATTR_BUFFERABLE) <<
222 MVEBU_AXI_ATTR_AWCACHE_OFFSET;
223 /* Set Ax-Domain as Outer domain */
224 data &= ~MVEBU_AXI_ATTR_ARDOMAIN_MASK;
225 data |= DOMAIN_OUTER_SHAREABLE <<
226 MVEBU_AXI_ATTR_ARDOMAIN_OFFSET;
227 data &= ~MVEBU_AXI_ATTR_AWDOMAIN_MASK;
228 data |= DOMAIN_OUTER_SHAREABLE <<
229 MVEBU_AXI_ATTR_AWDOMAIN_OFFSET;
230 mmio_write_32(MVEBU_AXI_ATTR_REG(index), data);
231 }
232 }
233 }
234
dss_setup(void)235 static void dss_setup(void)
236 {
237 /* Enable 48-bit VA */
238 mmio_setbits_32(DSS_CR0, DVM_48BIT_VA_ENABLE);
239 }
240
misc_soc_configurations(void)241 void misc_soc_configurations(void)
242 {
243 uint32_t reg;
244
245 /* Un-mask Watchdog reset from influencing the SYSRST_OUTn.
246 * Otherwise, upon WD timeout, the WD reset signal won't trigger reset
247 */
248 reg = mmio_read_32(MVEBU_SYSRST_OUT_CONFIG_REG);
249 reg &= ~(WD_MASK_SYS_RST_OUT);
250 mmio_write_32(MVEBU_SYSRST_OUT_CONFIG_REG, reg);
251 }
252
ap_init(void)253 void ap_init(void)
254 {
255 /* Setup Aurora2. */
256 init_aurora2();
257
258 /* configure MCI mapping */
259 mci_remap_indirect_access_base();
260
261 /* configure IO_WIN windows */
262 init_io_win(MVEBU_AP0);
263
264 /* configure CCU windows */
265 init_ccu(MVEBU_AP0);
266
267 /* configure DSS */
268 dss_setup();
269
270 /* Set the stream IDs for DMA masters */
271 ap806_stream_id_init();
272
273 /* configure the SMMU */
274 setup_smmu();
275
276 /* Open APN incoming access for all masters */
277 apn_sec_masters_access_en(1);
278
279 /* configure axi for APN*/
280 apn806_axi_attr_init();
281
282 /* misc configuration of the SoC */
283 misc_soc_configurations();
284 }
285
ap_ble_init(void)286 void ap_ble_init(void)
287 {
288 }
289
ap_get_count(void)290 int ap_get_count(void)
291 {
292 return 1;
293 }
294
update_cp110_default_win(int cp_id)295 void update_cp110_default_win(int cp_id)
296 {
297 }
298