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