xref: /rk3399_ARM-atf/drivers/marvell/mochi/apn806_setup.c (revision 015240d9d35c88d4f5c2845e8b8bfceb6d25dd9d)
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 <mvebu_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 enum axi_attr {
71 	AXI_SDIO_ATTR = 0,
72 	AXI_DFX_ATTR,
73 	AXI_MAX_ATTR,
74 };
75 
76 static void apn_sec_masters_access_en(uint32_t enable)
77 {
78 	/* Open/Close incoming access for all masters.
79 	 * The access is disabled in trusted boot mode
80 	 * Could only be done in EL3
81 	 */
82 	if (enable != 0) {
83 		mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG, 0x0U, /* no clear */
84 			      SEC_IN_ACCESS_ENA_ALL_MASTERS);
85 #if LLC_SRAM
86 		/* Do not change access security level
87 		 * for PIDI masters
88 		 */
89 		mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG,
90 				   SEC_MOCHI_IN_ACC_PIDI_LEVEL(
91 					  MOCHI_IN_ACC_LEVEL_MASK_ALL),
92 				   SEC_MOCHI_IN_ACC_PIDI_LEVEL(
93 					  MOCHI_IN_ACC_LEVEL_LEAVE_ORIG));
94 #endif
95 	} else {
96 		mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG,
97 				   SEC_IN_ACCESS_ENA_ALL_MASTERS,
98 				   0x0U /* no set */);
99 #if LLC_SRAM
100 		/* Return PIDI access level to the default */
101 		mmio_clrsetbits_32(SEC_MOCHI_IN_ACC_REG,
102 				   SEC_MOCHI_IN_ACC_PIDI_LEVEL(
103 					  MOCHI_IN_ACC_LEVEL_MASK_ALL),
104 				   SEC_MOCHI_IN_ACC_PIDI_LEVEL(
105 					  MOCHI_IN_ACC_LEVEL_FORCE_NONSEC));
106 #endif
107 	}
108 }
109 
110 static void setup_smmu(void)
111 {
112 	uint32_t reg;
113 
114 	/* Set the SMMU page size to 64 KB */
115 	reg = mmio_read_32(SMMU_sACR);
116 	reg |= SMMU_sACR_PG_64K;
117 	mmio_write_32(SMMU_sACR, reg);
118 }
119 
120 static void init_aurora2(void)
121 {
122 	uint32_t reg;
123 
124 	/* Enable GSPMU control by CPU */
125 	reg = mmio_read_32(CCU_GSPMU_CR);
126 	reg |= GSPMU_CPU_CONTROL;
127 	mmio_write_32(CCU_GSPMU_CR, reg);
128 
129 #if LLC_ENABLE
130 	/* Enable LLC for AP806 in exclusive mode */
131 	llc_enable(0, 1);
132 
133 	/* Set point of coherency to DDR.
134 	 * This is required by units which have
135 	 * SW cache coherency
136 	 */
137 	reg = mmio_read_32(CCU_HTC_CR);
138 	reg |= (0x1 << CCU_SET_POC_OFFSET);
139 	mmio_write_32(CCU_HTC_CR, reg);
140 #endif /* LLC_ENABLE */
141 
142 	errata_wa_init();
143 }
144 
145 
146 /* MCIx indirect access register are based by default at 0xf4000000/0xf6000000
147  * to avoid conflict of internal registers of units connected via MCIx, which
148  * can be based on the same address (i.e CP1 base is also 0xf4000000),
149  * the following routines remaps the MCIx indirect bases to another domain
150  */
151 static void mci_remap_indirect_access_base(void)
152 {
153 	uint32_t mci;
154 
155 	for (mci = 0; mci < MCI_MAX_UNIT_ID; mci++)
156 		mmio_write_32(MCIX4_REG_START_ADDRESS_REG(mci),
157 			      MVEBU_MCI_REG_BASE_REMAP(mci) >>
158 			      MCI_REMAP_OFF_SHIFT);
159 }
160 
161 static void apn806_axi_attr_init(void)
162 {
163 	uint32_t index, data;
164 
165 	/* Initialize AXI attributes for APN806 */
166 
167 	/* Go over the AXI attributes and set Ax-Cache and Ax-Domain */
168 	for (index = 0; index < AXI_MAX_ATTR; index++) {
169 		switch (index) {
170 		/* DFX works with no coherent only -
171 		 * there's no option to configure the Ax-Cache and Ax-Domain
172 		 */
173 		case AXI_DFX_ATTR:
174 			continue;
175 		default:
176 			/* Set Ax-Cache as cacheable, no allocate, modifiable,
177 			 * bufferable
178 			 * The values are different because Read & Write
179 			 * definition is different in Ax-Cache
180 			 */
181 			data = mmio_read_32(MVEBU_AXI_ATTR_REG(index));
182 			data &= ~MVEBU_AXI_ATTR_ARCACHE_MASK;
183 			data |= (CACHE_ATTR_WRITE_ALLOC |
184 				 CACHE_ATTR_CACHEABLE   |
185 				 CACHE_ATTR_BUFFERABLE) <<
186 				 MVEBU_AXI_ATTR_ARCACHE_OFFSET;
187 			data &= ~MVEBU_AXI_ATTR_AWCACHE_MASK;
188 			data |= (CACHE_ATTR_READ_ALLOC |
189 				 CACHE_ATTR_CACHEABLE  |
190 				 CACHE_ATTR_BUFFERABLE) <<
191 				 MVEBU_AXI_ATTR_AWCACHE_OFFSET;
192 			/* Set Ax-Domain as Outer domain */
193 			data &= ~MVEBU_AXI_ATTR_ARDOMAIN_MASK;
194 			data |= DOMAIN_OUTER_SHAREABLE <<
195 				MVEBU_AXI_ATTR_ARDOMAIN_OFFSET;
196 			data &= ~MVEBU_AXI_ATTR_AWDOMAIN_MASK;
197 			data |= DOMAIN_OUTER_SHAREABLE <<
198 				MVEBU_AXI_ATTR_AWDOMAIN_OFFSET;
199 			mmio_write_32(MVEBU_AXI_ATTR_REG(index), data);
200 		}
201 	}
202 }
203 
204 static void dss_setup(void)
205 {
206 	/* Enable 48-bit VA */
207 	mmio_setbits_32(DSS_CR0, DVM_48BIT_VA_ENABLE);
208 }
209 
210 void misc_soc_configurations(void)
211 {
212 	uint32_t reg;
213 
214 	/* Un-mask Watchdog reset from influencing the SYSRST_OUTn.
215 	 * Otherwise, upon WD timeout, the WD reset signal won't trigger reset
216 	 */
217 	reg = mmio_read_32(MVEBU_SYSRST_OUT_CONFIG_REG);
218 	reg &= ~(WD_MASK_SYS_RST_OUT);
219 	mmio_write_32(MVEBU_SYSRST_OUT_CONFIG_REG, reg);
220 }
221 
222 void ap_init(void)
223 {
224 	/* Setup Aurora2. */
225 	init_aurora2();
226 
227 	/* configure MCI mapping */
228 	mci_remap_indirect_access_base();
229 
230 	/* configure IO_WIN windows */
231 	init_io_win(MVEBU_AP0);
232 
233 	/* configure CCU windows */
234 	init_ccu(MVEBU_AP0);
235 
236 	/* configure DSS */
237 	dss_setup();
238 
239 	/* configure the SMMU */
240 	setup_smmu();
241 
242 	/* Open APN incoming access for all masters */
243 	apn_sec_masters_access_en(1);
244 
245 	/* configure axi for APN*/
246 	apn806_axi_attr_init();
247 
248 	/* misc configuration of the SoC */
249 	misc_soc_configurations();
250 }
251 
252 void ap_ble_init(void)
253 {
254 }
255 
256 int ap_get_count(void)
257 {
258 	return 1;
259 }
260 
261 void update_cp110_default_win(int cp_id)
262 {
263 }
264