xref: /netbsd-src/sys/arch/arm/marvell/armadaxp.c (revision bdc22b2e01993381dcefeff2bc9b56ca75a4235c)
1 /*	$NetBSD: armadaxp.c,v 1.21 2017/02/26 09:33:27 skrll Exp $	*/
2 /*******************************************************************************
3 Copyright (C) Marvell International Ltd. and its affiliates
4 
5 Developed by Semihalf
6 
7 ********************************************************************************
8 Marvell BSD License
9 
10 If you received this File from Marvell, you may opt to use, redistribute and/or
11 modify this File under the following licensing terms.
12 Redistribution and use in source and binary forms, with or without modification,
13 are permitted provided that the following conditions are met:
14 
15     *   Redistributions of source code must retain the above copyright notice,
16             this list of conditions and the following disclaimer.
17 
18     *   Redistributions in binary form must reproduce the above copyright
19         notice, this list of conditions and the following disclaimer in the
20         documentation and/or other materials provided with the distribution.
21 
22     *   Neither the name of Marvell nor the names of its contributors may be
23         used to endorse or promote products derived from this software without
24         specific prior written permission.
25 
26 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
30 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
33 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 
37 *******************************************************************************/
38 
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: armadaxp.c,v 1.21 2017/02/26 09:33:27 skrll Exp $");
41 
42 #define _INTR_PRIVATE
43 
44 #include "opt_mvsoc.h"
45 
46 #include <sys/param.h>
47 #include <sys/bus.h>
48 
49 #include <machine/intr.h>
50 
51 #include <arm/pic/picvar.h>
52 
53 #include <arm/armreg.h>
54 #include <arm/cpu.h>
55 #include <arm/cpufunc.h>
56 
57 #include <arm/marvell/mvsocreg.h>
58 #include <arm/marvell/mvsocvar.h>
59 #include <arm/marvell/armadaxpreg.h>
60 #include <arm/marvell/armadaxpvar.h>
61 
62 #include <dev/marvell/marvellreg.h>
63 
64 #define EXTRACT_XP_CPU_FREQ_FIELD(sar)	(((0x01 & (sar >> 52)) << 3) | \
65 					    (0x07 & (sar >> 21)))
66 #define EXTRACT_XP_FAB_FREQ_FIELD(sar)	(((0x01 & (sar >> 51)) << 4) | \
67 					    (0x0F & (sar >> 24)))
68 #define EXTRACT_370_CPU_FREQ_FIELD(sar)	((sar >> 11) & 0xf)
69 #define EXTRACT_370_FAB_FREQ_FIELD(sar)	((sar >> 15) & 0x1f)
70 
71 #define	MPIC_WRITE(reg, val)		(bus_space_write_4(&mvsoc_bs_tag, \
72 					    mpic_handle, reg, val))
73 #define	MPIC_CPU_WRITE(reg, val)	(bus_space_write_4(&mvsoc_bs_tag, \
74 					    mpic_cpu_handle, reg, val))
75 
76 #define	MPIC_READ(reg)			(bus_space_read_4(&mvsoc_bs_tag, \
77 					    mpic_handle, reg))
78 #define	MPIC_CPU_READ(reg)		(bus_space_read_4(&mvsoc_bs_tag, \
79 					    mpic_cpu_handle, reg))
80 
81 #define	L2_WRITE(reg, val)		(bus_space_write_4(&mvsoc_bs_tag, \
82 					    l2_handle, reg, val))
83 #define	L2_READ(reg)			(bus_space_read_4(&mvsoc_bs_tag, \
84 					    l2_handle, reg))
85 bus_space_handle_t mpic_cpu_handle;
86 static bus_space_handle_t mpic_handle, l2_handle;
87 int l2cache_state = 0;
88 int iocc_state = 0;
89 #define read_miscreg(r)		(*(volatile uint32_t *)(misc_base + (r)))
90 vaddr_t misc_base;
91 vaddr_t armadaxp_l2_barrier_reg;
92 
93 static void armadaxp_intr_init(void);
94 
95 static void armadaxp_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
96 static void armadaxp_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
97 static void armadaxp_pic_establish_irq(struct pic_softc *, struct intrsource *);
98 static void armadaxp_pic_set_priority(struct pic_softc *, int);
99 static void armadaxp_pic_source_name(struct pic_softc *, int, char*, size_t);
100 
101 static int armadaxp_find_pending_irqs(void);
102 static void armadaxp_pic_block_irq(struct pic_softc *, size_t);
103 
104 /* handle error cause */
105 static void armadaxp_err_pic_unblock_irqs(struct pic_softc *, size_t, uint32_t);
106 static void armadaxp_err_pic_block_irqs(struct pic_softc *, size_t, uint32_t);
107 static void armadaxp_err_pic_establish_irq(struct pic_softc *,
108     struct intrsource *);
109 static void armadaxp_err_pic_source_name(struct pic_softc *,
110     int, char*, size_t);
111 static int armadaxp_err_pic_pending_irqs(struct pic_softc *);
112 
113 static void armadaxp_getclks(void);
114 static void armada370_getclks(void);
115 static int armadaxp_clkgating(struct marvell_attach_args *);
116 
117 static int armadaxp_l2_init(bus_addr_t);
118 static paddr_t armadaxp_sdcache_wbalign_base(vaddr_t, paddr_t, psize_t);
119 static paddr_t armadaxp_sdcache_wbalign_end(vaddr_t, paddr_t, psize_t);
120 #ifdef AURORA_IO_CACHE_COHERENCY
121 static void armadaxp_io_coherency_init(void);
122 #endif
123 
124 struct vco_freq_ratio {
125 	uint8_t	vco_cpu;	/* VCO to CLK0(CPU) clock ratio */
126 	uint8_t	vco_l2c;	/* VCO to NB(L2 cache) clock ratio */
127 	uint8_t	vco_hcl;	/* VCO to HCLK(DDR controller) clock ratio */
128 	uint8_t	vco_ddr;	/* VCO to DR(DDR memory) clock ratio */
129 };
130 
131 /*
132  * Interrupt names for ARMADA XP
133  */
134 static const char * const armadaxp_pic_source_names[] = {
135 	/* Main Interrupt Cause Per-CPU (IRQ 0-29) */
136 	"InDBLowSum", "InDBHighSum", "OutDBSum", "CFU_LocalSum",
137 	"SoC_ErrorSum", "LTimer0", "LTimer1", "LWDT", "GbE0_TH_RxTx",
138 	"GbE0_RxTx", "GbE1_RxTxTh", "GbE1_RxTx", "GbE2_RxTxTh", "GbE2_RxTx",
139 	"GbE3_RxTxTh", "GbE3_RxTx", "GPIO0_7", "GPIO8_15", "GPIO16_23",
140 	"GPIO24_31", "GPIO32_39", "GPIO40_47", "GPIO48_55", "GPIO56_63",
141 	"GPIO64_66", "SCNT", "PCNT", "Reserved27", "VCNT", "Reserved29",
142 	/* Main Interrupt Cause Global-Shared (IRQ 30-115) */
143 	"SPI0", "I2C0", "I2C1", "IDMA0", "IDMA1", "IDMA2", "IDMA3", "GTimer0",
144 	"GTimer1", "GTimer2", "GTimer3", "UART0", "UART1", "UART2", "UART3",
145 	"USB0", "USB1", "USB2", "CESA0", "CESA1", "RTC", "XOR0_Ch0",
146 	"XOR0_Ch1", "BM", "SDIO", "SATA0", "TDM", "SATA1", "PEX0_0", "PEX0_1",
147 	"PEX0_2", "PEX0_3", "PEX1_0", "PEX1_1", "PEX1_2", "PEX1_3",
148 	"GbE0_Sum", "GbE0_Rx", "GbE0_Tx", "GbE0_Misc", "GbE1_Sum", "GbE1_Rx",
149 	"GbE1_Tx", "GbE1_Misc", "GbE2_Sum", "GbE2_Rx", "GbE2_Tx", "GbE2_Misc",
150 	"GbE3_Sum", "GbE3_Rx", "GbE3_Tx", "GbE3_Misc", "GPIO0_7", "GPIO8_15",
151 	"GPIO16_23", "GPIO24_31", "Reserved86", "GPIO32_39", "GPIO40_47",
152 	"GPIO48_55", "GPIO56_63", "GPIO64_66", "SPI1", "WDT", "XOR1_Ch2",
153 	"XOR1_Ch3", "SharedDB1Sum", "SharedDB2Sum", "SharedDB3Sum", "PEX2_0",
154 	"Reserved100", "Reserved101", "Reserved102", "PEX3_0", "Reserved104",
155 	"Reserved105", "Reserved106", "PMU", "DRAM", "GbE0_Wakeup",
156 	"GbE1_Wakeup", "GbE2_Wakeup", "GbE3_Wakeup", "NAND", "Reserved114",
157 	"Reserved115"
158 };
159 static const char * const armadaxp_err_pic_source_names[] = {
160 	/*
161 	 * IRQ 120-151 (bit 0-31 in SoC Error Interrupt Cause register)
162 	 * connected to SoC_ErrorSum in Main Interrupt Cause
163 	 */
164 	"ERR_CESA0", "ERR_DevBus", "ERR_IDMA", "ERR_XOR1",
165 	"ERR_PEX0", "ERR_PEX1", "ERR_GbE", "ERR_CESA1",
166 	"ERR_USB", "ERR_DRAM", "ERR_XOR0", "ERR_Reserved11",
167 	"ERR_BM", "ERR_CIB", "ERR_Reserved14", "ERR_PEX2",
168 	"ERR_PEX3", "ERR_SATA0", "ERR_SATA1", "ERR_Reserved19",
169 	"ERR_TDM", "ERR_NAND", "ERR_Reserved22",
170 	"ERR_Reserved23", "ERR_Reserved24", "ERR_Reserved25",
171 	"ERR_Reserved26", "ERR_Reserved27", "ERR_Reserved28",
172 	"ERR_Reserved29", "ERR_Reserved30", "ERR_Reserved31",
173 };
174 
175 /*
176  * Mbus Target and Attribute bindings for ARMADA XP
177  */
178 static struct mbus_description {
179 	uint8_t target;
180 	uint8_t attr;
181 	const char *string;
182 } mbus_desc[] = {
183 	/* DDR */
184 	{ ARMADAXP_UNITID_DDR, ARMADAXP_ATTR_DDR_CS0,
185 	       	"DDR(M_CS[0])" },
186 	{ ARMADAXP_UNITID_DDR, ARMADAXP_ATTR_DDR_CS1,
187 	       	"DDR(M_CS[1])" },
188 	{ ARMADAXP_UNITID_DDR, ARMADAXP_ATTR_DDR_CS2,
189 	       	"DDR(M_CS[2])" },
190 	{ ARMADAXP_UNITID_DDR, ARMADAXP_ATTR_DDR_CS3,
191 	       	"DDR(M_CS[3])" },
192 
193 	/* DEVBUS */
194 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS0,
195 	       	"DEVBUS(SPI0 CS0)" },
196 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS1,
197 	       	"DEVBUS(SPI0 CS1)" },
198 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS2,
199 	       	"DEVBUS(SPI0 CS2)" },
200 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS3,
201 	       	"DEVBUS(SPI0 CS3)" },
202 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS4,
203 	       	"DEVBUS(SPI0 CS4)" },
204 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS5,
205 	       	"DEVBUS(SPI0 CS5)" },
206 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS6,
207 	       	"DEVBUS(SPI0 CS6)" },
208 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS7,
209 	       	"DEVBUS(SPI0 CS7)" },
210 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS0,
211 	       	"DEVBUS(SPI1 CS0)" },
212 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS1,
213 	       	"DEVBUS(SPI1 CS1)" },
214 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS2,
215 	       	"DEVBUS(SPI1 CS2)" },
216 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS3,
217 	       	"DEVBUS(SPI1 CS3)" },
218 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS4,
219 	       	"DEVBUS(SPI1 CS4)" },
220 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS5,
221 	       	"DEVBUS(SPI1 CS5)" },
222 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS6,
223 	       	"DEVBUS(SPI1 CS6)" },
224 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI1_CS7,
225 	       	"DEVBUS(SPI1 CS7)" },
226 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS0,
227 	       	"DEVBUS(DevCS[0])" },
228 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS1,
229 	       	"DEVBUS(DevCS[1])" },
230 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS2,
231 	       	"DEVBUS(DevCS[2])" },
232 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS3,
233 	       	"DEVBUS(DevCS[3])" },
234 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_BOOT_CS,
235 	       	"DEVBUS(BootCS)" },
236 	{ ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_BOOT_ROM,
237 	       	"DEVBUS(BootROM)" },
238 
239 	/* GbE */
240 	{ ARMADAXP_UNITID_GBE0, ARMADAXP_ATTR_GBE_RESERVED,
241 	       	"GBE0 GBE1" },
242 	{ ARMADAXP_UNITID_GBE2, ARMADAXP_ATTR_GBE_RESERVED,
243 	       	"GBE2 GBE3" },
244 
245 	/* PEX(PCIe) */
246 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx0_MEM,
247 	       	"PEX0(Lane0, Memory)" },
248 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx1_MEM,
249 	       	"PEX0(Lane1, Memory)" },
250 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx2_MEM,
251 	       	"PEX0(Lane2, Memory)" },
252 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx3_MEM,
253 	       	"PEX0(Lane3, Memory)" },
254 	{ ARMADAXP_UNITID_PEX2, ARMADAXP_ATTR_PEX2_MEM,
255 	       	"PEX2(Lane0, Memory)" },
256 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx0_MEM,
257 	       	"PEX1(Lane0, Memory)" },
258 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx1_MEM,
259 	       	"PEX1(Lane1, Memory)" },
260 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx2_MEM,
261 	       	"PEX1(Lane2, Memory)" },
262 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx3_MEM,
263 	       	"PEX1(Lane3, Memory)" },
264 	{ ARMADAXP_UNITID_PEX3, ARMADAXP_ATTR_PEX3_MEM,
265 	       	"PEX3(Lane0, Memory)" },
266 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx0_IO,
267 	       	"PEX0(Lane0, I/O)" },
268 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx1_IO,
269 	       	"PEX0(Lane1, I/O)" },
270 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx2_IO,
271 	       	"PEX0(Lane2, I/O)" },
272 	{ ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx3_IO,
273 	       	"PEX0(Lane3, I/O)" },
274 	{ ARMADAXP_UNITID_PEX2, ARMADAXP_ATTR_PEX2_IO,
275 	       	"PEX2(Lane0, I/O)" },
276 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx0_IO,
277 	       	"PEX1(Lane0, I/O)" },
278 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx1_IO,
279 	       	"PEX1(Lane1, I/O)" },
280 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx2_IO,
281 	       	"PEX1(Lane2, I/O)" },
282 	{ ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx3_IO,
283 	       	"PEX1(Lane3, I/O)" },
284 	{ ARMADAXP_UNITID_PEX3, ARMADAXP_ATTR_PEX3_IO,
285 	       	"PEX3(Lane0, I/O)" },
286 
287 	/* CRYPT */
288 	{ ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT0_NOSWAP,
289 	       	"CESA0(No swap)" },
290 	{ ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT0_SWAP_BYTE,
291 	       	"CESA0(Byte swap)" },
292 	{ ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT0_SWAP_BYTE_WORD,
293 	       	"CESA0(Byte and word swap)" },
294 	{ ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT0_SWAP_WORD,
295 	       	"CESA0(Word swap)" },
296 	{ ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT1_NOSWAP,
297 	       	"CESA1(No swap)" },
298 	{ ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT1_SWAP_BYTE,
299 	       	"CESA1(Byte swap)" },
300 	{ ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT1_SWAP_BYTE_WORD,
301 	       	"CESA1(Byte and word swap)" },
302 	{ ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT1_SWAP_WORD,
303 	       	"CESA1(Word swap)" },
304 
305 	/* BM */
306 	{ ARMADAXP_UNITID_BM, ARMADAXP_ATTR_BM_RESERVED,
307 		"BM" },
308 
309 	/* NAND */
310 	{ ARMADAXP_UNITID_NAND, ARMADAXP_ATTR_NAND_RESERVED,
311 		"NAND" },
312 };
313 
314 /*
315  * Default Mbus address decoding table for ARMADA XP
316  * this table may changed by device drivers.
317  *
318  * NOTE: some version of u-boot is broken. it writes old decoding table.
319  *       probably, it's designed for Kirkwood SoC or older. we need to restore
320  *       ARMADA XP's parameter set.
321  */
322 static struct mbus_table_def {
323 	int window;	/* index of address decoding window registers */
324 	uint32_t base;	/* base address of the window */
325 	uint32_t size;	/* size of the window */
326 	uint8_t target;	/* target unit of the window */
327 	uint8_t attr;	/* target attribute of the window */
328 } mbus_table[] = {
329 	/*
330 	 * based on 'default address mapping' described in Marvell's document
331 	 * 'ARMADA XP Functional Specifications.'
332 	 *
333 	 * some windows are modified to get compatibility with old codes.
334 	 */
335 	{
336 		/* PCIe 0 lane0 MEM */
337 		/* MODIFIED (moved to MARVELL_PEXMEM_PBASE) */
338 		 0, 0xe0000000, 0x01000000,
339 		 ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx0_MEM
340 	},
341 	{
342 		/* PCIe 0 lane1 MEM */
343 		 1, 0x88000000, 0x08000000,
344 		 ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx1_MEM
345 	},
346 	{
347 		/* PCIe 0 lane2 MEM */
348 		 2, 0x90000000, 0x08000000,
349 		 ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx2_MEM
350 	},
351 	{
352 		/* PCIe 0 lane3 MEM */
353 		 3, 0x98000000, 0x08000000,
354 		 ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx3_MEM
355 	},
356 	{
357 		/* PCIe 1 lane0 MEM */
358 		 4, 0xa0000000, 0x08000000,
359 		 ARMADAXP_UNITID_PEX1, ARMADAXP_ATTR_PEXx0_MEM
360 	},
361 	{	5, 0, 0, 0, 0 /* disabled */ },
362 	{	6, 0, 0, 0, 0 /* disabled */ },
363 	{	7, 0, 0, 0, 0 /* disabled */ },
364 	{
365 		/* Security Accelerator SRAM, Engine 0, no data swap */
366 		 8, 0xc8010000, 0x00010000,
367 		 ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT0_NOSWAP,
368 	},
369 	{
370 		/* Device bus, BOOT_CS */
371 		 9, 0xd8000000, 0x08000000,
372 		 ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_BOOT_CS,
373 	},
374 	{
375 		/* Device bus, DEV_CS[0] */
376 		/* MODIFIED (moved, conflict to MARVELL_PEXMEM_PBASE here.) */
377 		10, 0x80000000, 0x08000000,
378 		ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS0
379 	},
380 	{
381 		/* Device bus, DEV_CS[1] */
382 		11, 0xe8000000, 0x08000000,
383 		ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS1
384 	},
385 	{
386 		/* Device bus, DEV_CS[2] */
387 		/* MODIFIED: (disabled, conflict to MARVELL_PEXIO_PBASE) */
388 		12, 0xf0000000, 0x00000000,
389 		ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_DEV_CS2
390 	},
391 	{
392 		/* Device bus, BOOT_ROM */
393 		13, 0xf8000000, 0x08000000,
394 		ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_BOOT_ROM
395 	},
396 	{
397 		/* Device bus, SPI0_CS[0] */
398 		14, 0xd4000000, 0x04000000,
399 		ARMADAXP_UNITID_DEVBUS, ARMADAXP_ATTR_DEVBUS_SPI0_CS0
400 	},
401 	{
402 		/* Security Accelerator SRAM, Engine 1, no data swap */
403 		/* MODIFIED (added, 0xd0300000-0xd030ffff) */
404 		15, 0xd0300000, 0x00010000,
405 	       	ARMADAXP_UNITID_CRYPT, ARMADAXP_ATTR_CRYPT1_NOSWAP
406 	},
407 	{
408 		/* PCIe 0 lane 0 I/O */
409 		/* MODIFIED (added, MARVELL_PEXIO_PBASE) */
410 		16, 0xf2000000, 0x00100000,
411 	       	ARMADAXP_UNITID_PEX0, ARMADAXP_ATTR_PEXx0_IO
412        	},
413 	{	17, 0xd0320000, 0, 0, 0 /* disabled */ },
414 	{
415 		/* Buffer Manamgement unit */
416 		18, 0xd3800000, 0x00800000,
417 		ARMADAXP_UNITID_BM, ARMADAXP_ATTR_BM_RESERVED
418 	},
419 	{
420 		/* DDR */
421 		/* MODIFIED (up to 2GB memory space) */
422 		19, 0x00000000, 0x80000000,
423 		ARMADAXP_UNITID_DDR, ARMADAXP_ATTR_DDR_CS0
424 	},
425 
426 };
427 
428 static struct vco_freq_ratio freq_conf_table[] = {
429 /*00*/	{ 1, 1,	 4,  2 },
430 /*01*/	{ 1, 2,	 2,  2 },
431 /*02*/	{ 2, 2,	 6,  3 },
432 /*03*/	{ 2, 2,	 3,  3 },
433 /*04*/	{ 1, 2,	 3,  3 },
434 /*05*/	{ 1, 2,	 4,  2 },
435 /*06*/	{ 1, 1,	 2,  2 },
436 /*07*/	{ 2, 3,	 6,  6 },
437 /*08*/	{ 2, 3,	 5,  5 },
438 /*09*/	{ 1, 2,	 6,  3 },
439 /*10*/	{ 2, 4,	10,  5 },
440 /*11*/	{ 1, 3,	 6,  6 },
441 /*12*/	{ 1, 2,	 5,  5 },
442 /*13*/	{ 1, 3,	 6,  3 },
443 /*14*/	{ 1, 2,	 5,  5 },
444 /*15*/	{ 2, 2,	 5,  5 },
445 /*16*/	{ 1, 1,	 3,  3 },
446 /*17*/	{ 2, 5,	10, 10 },
447 /*18*/	{ 1, 3,	 8,  4 },
448 /*19*/	{ 1, 1,	 2,  1 },
449 /*20*/	{ 2, 3,	 6,  3 },
450 /*21*/	{ 1, 2,	 8,  4 },
451 /*22*/	{ 2, 5,	10,  5 }
452 };
453 
454 static uint16_t clock_table_xp[] = {
455 	1000, 1066, 1200, 1333, 1500, 1666, 1800, 2000,
456 	 600,  667,  800, 1600, 2133, 2200, 2400
457 };
458 static uint16_t clock_table_370[] = {
459 	 400,  533,  667,  800, 1000, 1067, 1200, 1333,
460 	1500, 1600, 1667, 1800, 2000,  333,  600,  900,
461 	   0
462 };
463 
464 static struct pic_ops armadaxp_picops = {
465 	.pic_unblock_irqs = armadaxp_pic_unblock_irqs,
466 	.pic_block_irqs = armadaxp_pic_block_irqs,
467 	.pic_establish_irq = armadaxp_pic_establish_irq,
468 	.pic_set_priority = armadaxp_pic_set_priority,
469 	.pic_source_name = armadaxp_pic_source_name,
470 };
471 
472 static struct pic_softc armadaxp_pic = {
473 	.pic_ops = &armadaxp_picops,
474 	.pic_name = "armadaxp",
475 };
476 
477 static struct pic_ops armadaxp_err_picops = {
478 	.pic_unblock_irqs = armadaxp_err_pic_unblock_irqs,
479 	.pic_block_irqs = armadaxp_err_pic_block_irqs,
480 	.pic_establish_irq = armadaxp_err_pic_establish_irq,
481 	.pic_find_pending_irqs = armadaxp_err_pic_pending_irqs,
482 	.pic_source_name = armadaxp_err_pic_source_name,
483 };
484 
485 static struct pic_softc armadaxp_err_pic = {
486 	.pic_ops = &armadaxp_err_picops,
487 	.pic_name = "armadaxp_err",
488 };
489 
490 static struct {
491 	bus_size_t offset;
492 	uint32_t bits;
493 } clkgatings[]= {
494 	{ ARMADAXP_GBE3_BASE,	(1 << 1) },
495 	{ ARMADAXP_GBE2_BASE,	(1 << 2) },
496 	{ ARMADAXP_GBE1_BASE,	(1 << 3) },
497 	{ ARMADAXP_GBE0_BASE,	(1 << 4) },
498 	{ MVSOC_PEX_BASE,	(1 << 5) },
499 	{ ARMADAXP_PEX01_BASE,	(1 << 6) },
500 	{ ARMADAXP_PEX02_BASE,	(1 << 7) },
501 	{ ARMADAXP_PEX03_BASE,	(1 << 8) },
502 	{ ARMADAXP_PEX10_BASE,	(1 << 9) },
503 	{ ARMADAXP_PEX11_BASE,	(1 << 10) },
504 	{ ARMADAXP_PEX12_BASE,	(1 << 11) },
505 	{ ARMADAXP_PEX13_BASE,	(1 << 12) },
506 #if 0
507 	{ NetA, (1 << 13) },
508 #endif
509 	{ ARMADAXP_SATAHC_BASE,	(1 << 14) | (1 << 15) | (1 << 29) | (1 << 30) },
510 	{ ARMADAXP_LCD_BASE,	(1 << 16) },
511 	{ ARMADAXP_SDIO_BASE,	(1 << 17) },
512 	{ ARMADAXP_USB1_BASE,	(1 << 19) },
513 	{ ARMADAXP_USB2_BASE,	(1 << 20) },
514 	{ ARMADAXP_CESA0_BASE,	(1 << 23) },
515 	{ ARMADAXP_CESA1_BASE,	(1 << 23) },
516 	{ ARMADAXP_PEX2_BASE,	(1 << 26) },
517 	{ ARMADAXP_PEX3_BASE,	(1 << 27) },
518 #if 0
519 	{ DDR, (1 << 28) },
520 #endif
521 };
522 
523 /*
524  * armadaxp_bootstrap:
525  *
526  *	Initialize the rest of the Armada XP dependencies, making it
527  *	ready to handle interrupts from devices.
528  */
529 void
530 armadaxp_bootstrap(vaddr_t vbase, bus_addr_t pbase)
531 {
532 	int i;
533 
534 	/* Map MPIC base and MPIC percpu base registers */
535 	if (bus_space_map(&mvsoc_bs_tag, pbase + ARMADAXP_MLMB_MPIC_BASE,
536 	    0x500, 0, &mpic_handle) != 0)
537 		panic("%s: Could not map MPIC registers", __func__);
538 	if (bus_space_map(&mvsoc_bs_tag, pbase + ARMADAXP_MLMB_MPIC_CPU_BASE,
539 	    0x800, 0, &mpic_cpu_handle) != 0)
540 		panic("%s: Could not map MPIC percpu registers", __func__);
541 
542 	/* Disable all interrupts */
543 	for (i = 0; i < ARMADAXP_IRQ_SOURCES; i++)
544 		MPIC_WRITE(ARMADAXP_MLMB_MPIC_ICE, i);
545 
546 	mvsoc_intr_init = armadaxp_intr_init;
547 
548 	mvsoc_clkgating = armadaxp_clkgating;
549 
550 	misc_base = vbase + ARMADAXP_MISC_BASE;
551 	switch (mvsoc_model()) {
552 	case MARVELL_ARMADAXP_MV78130:
553 	case MARVELL_ARMADAXP_MV78160:
554 	case MARVELL_ARMADAXP_MV78230:
555 	case MARVELL_ARMADAXP_MV78260:
556 	case MARVELL_ARMADAXP_MV78460:
557 		armadaxp_getclks();
558 		break;
559 
560 	case MARVELL_ARMADA370_MV6707:
561 	case MARVELL_ARMADA370_MV6710:
562 	case MARVELL_ARMADA370_MV6W11:
563 		armada370_getclks();
564 		break;
565 	}
566 
567 #ifdef L2CACHE_ENABLE
568 	/* Initialize L2 Cache */
569 	armadaxp_l2_init(pbase);
570 #endif
571 
572 #ifdef AURORA_IO_CACHE_COHERENCY
573 	/* Initialize cache coherency */
574 	armadaxp_io_coherency_init();
575 #endif
576 }
577 
578 static void
579 armadaxp_intr_init(void)
580 {
581 	int ctrl;
582 	void *ih __diagused;
583 
584 	/* Get max interrupts */
585 	armadaxp_pic.pic_maxsources =
586 	    ((MPIC_READ(ARMADAXP_MLMB_MPIC_CTRL) >> 2) & 0x7FF);
587 
588 	if (!armadaxp_pic.pic_maxsources)
589 		armadaxp_pic.pic_maxsources = ARMADAXP_IRQ_SOURCES;
590 
591 	pic_add(&armadaxp_pic, 0);
592 
593 	/* Chain error interrupts controller */
594 	MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ERR_MASK, 0);
595 	armadaxp_err_pic.pic_maxsources = ARMADAXP_IRQ_ERROR_SOURCES;
596 	pic_add(&armadaxp_err_pic, ARMADAXP_IRQ_ERROR_BASE);
597 	ih = intr_establish(ARMADAXP_IRQ_ERR_SUMMARY, IPL_HIGH, IST_LEVEL_HIGH,
598 	    pic_handle_intr, &armadaxp_err_pic);
599 	KASSERT(ih != NULL);
600 
601 	ctrl = MPIC_READ(ARMADAXP_MLMB_MPIC_CTRL);
602 	/* Enable IRQ prioritization */
603 	ctrl |= (1 << 0);
604 	MPIC_WRITE(ARMADAXP_MLMB_MPIC_CTRL, ctrl);
605 
606 	find_pending_irqs = armadaxp_find_pending_irqs;
607 }
608 
609 static void
610 armadaxp_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase,
611     uint32_t irq_mask)
612 {
613 	int n;
614 
615 	while (irq_mask != 0) {
616 		n = ffs(irq_mask) - 1;
617 		KASSERT(pic->pic_maxsources >= n + irqbase);
618 		MPIC_WRITE(ARMADAXP_MLMB_MPIC_ISE, n + irqbase);
619 		MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ICM, n + irqbase);
620 		if ((n + irqbase) == 0)
621 			MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_DOORBELL_MASK,
622 			    0xffffffff);
623 		irq_mask &= ~__BIT(n);
624 	}
625 }
626 
627 static void
628 armadaxp_pic_block_irqs(struct pic_softc *pic, size_t irqbase,
629     uint32_t irq_mask)
630 {
631 	int n;
632 
633 	while (irq_mask != 0) {
634 		n = ffs(irq_mask) - 1;
635 		KASSERT(pic->pic_maxsources >= n + irqbase);
636 		MPIC_WRITE(ARMADAXP_MLMB_MPIC_ICE, n + irqbase);
637 		MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ISM, n + irqbase);
638 		irq_mask &= ~__BIT(n);
639 	}
640 }
641 
642 static void
643 armadaxp_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
644 {
645 	int tmp;
646 	KASSERT(pic->pic_maxsources >= is->is_irq);
647 	tmp = MPIC_READ(ARMADAXP_MLMB_MPIC_ISCR_BASE + is->is_irq * 4);
648 	/* Clear previous priority */
649 	tmp &= ~(0xf << MPIC_ISCR_SHIFT);
650 	MPIC_WRITE(ARMADAXP_MLMB_MPIC_ISCR_BASE + is->is_irq * 4,
651 	    tmp | (is->is_ipl << MPIC_ISCR_SHIFT));
652 }
653 
654 static void
655 armadaxp_pic_set_priority(struct pic_softc *pic, int ipl)
656 {
657 	int ctp;
658 
659 	ctp = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_CTP);
660 	ctp &= ~(0xf << MPIC_CTP_SHIFT);
661 	ctp |= (ipl << MPIC_CTP_SHIFT);
662 	MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_CTP, ctp);
663 }
664 
665 static void
666 armadaxp_pic_source_name(struct pic_softc *pic, int irq, char *buf, size_t len)
667 {
668 	if (irq >= __arraycount(armadaxp_pic_source_names)) {
669 		snprintf(buf, len, "Unknown IRQ %d", irq);
670 		return;
671 	}
672 	strlcpy(buf, armadaxp_pic_source_names[irq], len);
673 }
674 
675 static int
676 armadaxp_find_pending_irqs(void)
677 {
678 	struct intrsource *is;
679 	int irq;
680 
681 	irq = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_IIACK) & 0x3ff;
682 
683 	/* Is it a spurious interrupt ?*/
684 	if (irq == 0x3ff)
685 		return 0;
686 	is = armadaxp_pic.pic_sources[irq];
687 	if (is == NULL) {
688 		printf("stray interrupt: %d\n", irq);
689 		return 0;
690 	}
691 
692 	armadaxp_pic_block_irq(&armadaxp_pic, irq);
693 	pic_mark_pending(&armadaxp_pic, irq);
694 
695 	return is->is_ipl;
696 }
697 
698 static void
699 armadaxp_pic_block_irq(struct pic_softc *pic, size_t irq)
700 {
701 
702 	KASSERT(pic->pic_maxsources >= irq);
703 	MPIC_WRITE(ARMADAXP_MLMB_MPIC_ICE, irq);
704 	MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ISM, irq);
705 }
706 
707 static void
708 armadaxp_err_pic_source_name(struct pic_softc *pic, int irq,
709     char *buf, size_t len)
710 {
711 	if (irq >= __arraycount(armadaxp_err_pic_source_names)) {
712 		snprintf(buf, len, "Unknown IRQ %d", irq);
713 		return;
714 	}
715 	strlcpy(buf, armadaxp_err_pic_source_names[irq], len);
716 }
717 
718 
719 /*
720  * ARMADAXP_MLMB_MPIC_ERR_CAUSE
721  */
722 static void
723 armadaxp_err_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase,
724     uint32_t irq_mask)
725 {
726 	uint32_t reg;
727 
728 	KASSERT(irqbase == 0); /* XXX: support offset */
729 
730 	reg = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_ERR_MASK);
731 	reg |= irq_mask;
732 	MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ERR_MASK, reg);
733 }
734 
735 static void
736 armadaxp_err_pic_block_irqs(struct pic_softc *pic, size_t irqbase,
737     uint32_t irq_mask)
738 {
739 	uint32_t reg;
740 
741 	KASSERT(irqbase == 0); /* XXX: support offset */
742 
743 	reg = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_ERR_MASK);
744 	reg &= ~irq_mask;
745 	MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ERR_MASK, reg);
746 }
747 
748 static void
749 armadaxp_err_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
750 {
751 	uint32_t reg;
752 
753 	KASSERT(pic->pic_maxsources >= is->is_irq);
754 
755 	reg = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_ERR_MASK);
756 	reg |= ARMADAXP_IRQ_ERROR_BIT(is->is_irq);
757 	MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ERR_MASK, reg);
758 }
759 
760 static int
761 armadaxp_err_pic_pending_irqs(struct pic_softc *pic)
762 {
763 	struct intrsource *is;
764 	uint32_t reg;
765 	int irq;
766 
767 	reg = MPIC_READ(ARMADAXP_MLMB_MPIC_ERR_CAUSE);
768 	irq = ffs(reg);
769 	if (irq == 0)
770 		return 0;
771 	irq--; /* bit number to index */
772 
773 	is = pic->pic_sources[irq];
774 	if (is == NULL) {
775 		printf("stray interrupt: %d\n", irq);
776 		return 0;
777 	}
778 	return pic_mark_pending_sources(pic, 0, irq);
779 }
780 
781 
782 /*
783  * Clock functions
784  */
785 
786 static void
787 armadaxp_getclks(void)
788 {
789 	uint64_t sar_reg;
790 	uint8_t  sar_cpu_freq, sar_fab_freq;
791 
792 	if (cputype == CPU_ID_MV88SV584X_V7)
793 		mvTclk = 250000000; /* 250 MHz */
794 	else
795 		mvTclk = 200000000; /* 200 MHz */
796 
797 	sar_reg = (read_miscreg(ARMADAXP_MISC_SAR_HI) << 31) |
798 	    read_miscreg(ARMADAXP_MISC_SAR_LO);
799 
800 	sar_cpu_freq = EXTRACT_XP_CPU_FREQ_FIELD(sar_reg);
801 	sar_fab_freq = EXTRACT_XP_FAB_FREQ_FIELD(sar_reg);
802 
803 	/* Check if CPU frequency field has correct value */
804 	if (sar_cpu_freq >= __arraycount(clock_table_xp))
805 		panic("Reserved value in cpu frequency configuration field: "
806 		    "%d", sar_cpu_freq);
807 
808 	/* Check if fabric frequency field has correct value */
809 	if (sar_fab_freq >= __arraycount(freq_conf_table))
810 		panic("Reserved value in fabric frequency configuration field: "
811 		    "%d", sar_fab_freq);
812 
813 	/* Get CPU clock frequency */
814 	mvPclk = clock_table_xp[sar_cpu_freq] *
815 	    freq_conf_table[sar_fab_freq].vco_cpu;
816 
817 	/* Get L2CLK clock frequency and use as system clock (mvSysclk) */
818 	mvSysclk = mvPclk / freq_conf_table[sar_fab_freq].vco_l2c;
819 
820 	/* Round mvSysclk value to integer MHz */
821 	if (((mvPclk % freq_conf_table[sar_fab_freq].vco_l2c) * 10 /
822 	    freq_conf_table[sar_fab_freq].vco_l2c) >= 5)
823 		mvSysclk++;
824 
825 	mvPclk *= 1000000;
826 	mvSysclk *= 1000000;
827 
828 	curcpu()->ci_data.cpu_cc_freq = mvPclk;
829 }
830 
831 static void
832 armada370_getclks(void)
833 {
834 	uint32_t sar;
835 	uint8_t  cpu_freq, fab_freq;
836 
837 	sar = read_miscreg(ARMADAXP_MISC_SAR_LO);
838 	if (sar & 0x00100000)
839 		mvTclk = 200000000; /* 200 MHz */
840 	else
841 		mvTclk = 166666667; /* 166 MHz */
842 
843 	cpu_freq = EXTRACT_370_CPU_FREQ_FIELD(sar);
844 	fab_freq = EXTRACT_370_FAB_FREQ_FIELD(sar);
845 
846 	/* Check if CPU frequency field has correct value */
847 	if (cpu_freq >= __arraycount(clock_table_370))
848 		panic("Reserved value in cpu frequency configuration field: "
849 		    "%d", cpu_freq);
850 
851 	/* Check if fabric frequency field has correct value */
852 	if (fab_freq >= __arraycount(freq_conf_table))
853 		panic("Reserved value in fabric frequency configuration field: "
854 		    "%d", fab_freq);
855 
856 	/* Get CPU clock frequency */
857 	mvPclk = clock_table_370[cpu_freq] *
858 	    freq_conf_table[fab_freq].vco_cpu;
859 
860 	/* Get L2CLK clock frequency and use as system clock (mvSysclk) */
861 	mvSysclk = mvPclk / freq_conf_table[fab_freq].vco_l2c;
862 
863 	/* Round mvSysclk value to integer MHz */
864 	if (((mvPclk % freq_conf_table[fab_freq].vco_l2c) * 10 /
865 	    freq_conf_table[fab_freq].vco_l2c) >= 5)
866 		mvSysclk++;
867 
868 	mvPclk *= 1000000;
869 	mvSysclk *= 1000000;
870 }
871 
872 /*
873  * L2 Cache initialization
874  */
875 
876 static int
877 armadaxp_l2_init(bus_addr_t pbase)
878 {
879 	u_int32_t reg;
880 	int ret;
881 
882 	/* Map L2 space */
883 	ret = bus_space_map(&mvsoc_bs_tag, pbase + ARMADAXP_L2_BASE,
884 	    0x1000, 0, &l2_handle);
885 	if (ret) {
886 		printf("%s: Cannot map L2 register space, ret:%d\n",
887 		    __func__, ret);
888 		return (-1);
889 	}
890 
891 	/* Variables for cpufunc_asm_pj4b.S */
892 	/* XXX: per cpu register. need to support SMP */
893 	armadaxp_l2_barrier_reg = mlmb_base + MVSOC_MLMB_CIB_BARRIER(0);
894 
895 	/* Set L2 policy */
896 	reg = L2_READ(ARMADAXP_L2_AUX_CTRL);
897 	reg &= ~(L2_AUX_WBWT_MODE_MASK);
898 	reg &= ~(L2_AUX_REP_STRAT_MASK);
899 	reg |= L2_AUX_ECC_ENABLE;
900 	reg |= L2_AUX_PARITY_ENABLE;
901 	reg |= L2_AUX_WBWT_MODE_BY_ATTR;
902 	reg |= L2_AUX_FORCE_WA_BY_ATTR;
903 	reg |= L2_AUX_REP_STRAT_SEMIPLRU;
904 	L2_WRITE(ARMADAXP_L2_AUX_CTRL, reg);
905 
906 	/* Invalidate L2 cache */
907 	L2_WRITE(ARMADAXP_L2_INV_WAY, L2_ALL_WAYS);
908 
909 	/* Clear pending L2 interrupts */
910 	L2_WRITE(ARMADAXP_L2_INT_CAUSE, 0x1ff);
911 
912 	/* Enable Cache and TLB maintenance broadcast */
913 	__asm__ __volatile__ ("mrc p15, 1, %0, c15, c2, 0" : "=r"(reg));
914 	reg |= (1 << 8);
915 	__asm__ __volatile__ ("mcr p15, 1, %0, c15, c2, 0" : :"r"(reg));
916 
917 	/*
918 	 * Set the Point of Coherency and Point of Unification to DRAM.
919 	 * This is a reset value but anyway, configure this just in case.
920 	 */
921 	reg = read_mlmbreg(ARMADAXP_L2_CFU);
922 	reg |= (1 << 17) | (1 << 18);
923 	write_mlmbreg(ARMADAXP_L2_CFU, reg);
924 
925 	/* Enable L2 cache */
926 	reg = L2_READ(ARMADAXP_L2_CTRL);
927 	L2_WRITE(ARMADAXP_L2_CTRL, reg | L2_CTRL_ENABLE);
928 
929 	/* Mark as enabled */
930 	l2cache_state = 1;
931 
932 #ifdef DEBUG
933 	/* Configure and enable counter */
934 	L2_WRITE(ARMADAXP_L2_CNTR_CONF(0), 0xf0000 | (4 << 2));
935 	L2_WRITE(ARMADAXP_L2_CNTR_CONF(1), 0xf0000 | (2 << 2));
936 	L2_WRITE(ARMADAXP_L2_CNTR_CTRL, 0x303);
937 #endif
938 
939 	return (0);
940 }
941 
942 void
943 armadaxp_sdcache_inv_all(void)
944 {
945 	L2_WRITE(ARMADAXP_L2_INV_WAY, L2_ALL_WAYS);
946 }
947 
948 void
949 armadaxp_sdcache_wb_all(void)
950 {
951 	L2_WRITE(ARMADAXP_L2_WB_WAY, L2_ALL_WAYS);
952 	L2_WRITE(ARMADAXP_L2_SYNC, 0);
953 	__asm__ __volatile__("dsb");
954 }
955 
956 void
957 armadaxp_sdcache_wbinv_all(void)
958 {
959 	L2_WRITE(ARMADAXP_L2_WBINV_WAY, L2_ALL_WAYS);
960 	L2_WRITE(ARMADAXP_L2_SYNC, 0);
961 	__asm__ __volatile__("dsb");
962 }
963 
964 static paddr_t
965 armadaxp_sdcache_wbalign_base(vaddr_t va, paddr_t pa, psize_t sz)
966 {
967 	paddr_t line_start = pa & ~ARMADAXP_L2_ALIGN;
968 	vaddr_t save_start;
969 	uint8_t save_buf[ARMADAXP_L2_LINE_SIZE];
970 	size_t unalign;
971 
972 	unalign = va & ARMADAXP_L2_ALIGN;
973 	if (unalign == 0)
974 		return line_start;  /* request is aligned to cache line size */
975 
976 	/* save data that is not intended to invalidate */
977 	save_start = va & ~ARMADAXP_L2_ALIGN;
978 	memcpy(save_buf, (void *)save_start, unalign);
979 
980 	/* invalidate include saved data */
981 	L2_WRITE(ARMADAXP_L2_INV_PHYS, line_start);
982 
983 	/* write back saved data */
984 	memcpy((void *)save_start, save_buf, unalign);
985 	L2_WRITE(ARMADAXP_L2_WB_PHYS, line_start);
986 	L2_WRITE(ARMADAXP_L2_SYNC, 0);
987 	__asm__ __volatile__("dsb");
988 
989 	return line_start;
990 }
991 
992 static paddr_t
993 armadaxp_sdcache_wbalign_end(vaddr_t va, paddr_t pa, psize_t sz)
994 {
995 	paddr_t line_start = (pa + sz - 1) & ~ARMADAXP_L2_ALIGN;
996 	vaddr_t save_start = va + sz;
997 	uint8_t save_buf[ARMADAXP_L2_LINE_SIZE];
998 	size_t save_len;
999 	size_t unalign;
1000 
1001 	unalign = save_start & ARMADAXP_L2_ALIGN;
1002 	if (unalign == 0)
1003 		return line_start; /* request is aligned to cache line size */
1004 
1005 	/* save data that is not intended to invalidate */
1006 	save_len = ARMADAXP_L2_LINE_SIZE - unalign;
1007 	memcpy(save_buf, (void *)save_start, save_len);
1008 
1009 	/* invalidate include saved data */
1010 	L2_WRITE(ARMADAXP_L2_INV_PHYS, line_start);
1011 
1012 	/* write back saved data */
1013 	memcpy((void *)save_start, save_buf, save_len);
1014 	L2_WRITE(ARMADAXP_L2_WB_PHYS, line_start);
1015 	__asm__ __volatile__("dsb");
1016 
1017 	return line_start;
1018 }
1019 
1020 void
1021 armadaxp_sdcache_inv_range(vaddr_t va, paddr_t pa, psize_t sz)
1022 {
1023 	paddr_t pa_base;
1024 	paddr_t pa_end;
1025 
1026 	/* align and write-back the boundary */
1027 	pa_base = armadaxp_sdcache_wbalign_base(va, pa, sz);
1028 	pa_end = armadaxp_sdcache_wbalign_end(va, pa, sz);
1029 
1030 	/* invalidate other cache */
1031 	if (pa_base == pa_end) {
1032 		L2_WRITE(ARMADAXP_L2_INV_PHYS, pa_base);
1033 		return;
1034 	}
1035 
1036 	L2_WRITE(ARMADAXP_L2_RANGE_BASE, pa_base);
1037 	L2_WRITE(ARMADAXP_L2_INV_RANGE, pa_end);
1038 }
1039 
1040 void
1041 armadaxp_sdcache_wb_range(vaddr_t va, paddr_t pa, psize_t sz)
1042 {
1043 	paddr_t pa_base = pa & ~ARMADAXP_L2_ALIGN;
1044 	paddr_t pa_end  = (pa + sz - 1) & ~ARMADAXP_L2_ALIGN;
1045 
1046 	if (pa_base == pa_end)
1047 		L2_WRITE(ARMADAXP_L2_WB_PHYS, pa_base);
1048 	else {
1049 		L2_WRITE(ARMADAXP_L2_RANGE_BASE, pa_base);
1050 		L2_WRITE(ARMADAXP_L2_WB_RANGE, pa_end);
1051 	}
1052 	L2_WRITE(ARMADAXP_L2_SYNC, 0);
1053 	__asm__ __volatile__("dsb");
1054 }
1055 
1056 void
1057 armadaxp_sdcache_wbinv_range(vaddr_t va, paddr_t pa, psize_t sz)
1058 {
1059 	paddr_t pa_base = pa & ~ARMADAXP_L2_ALIGN;;
1060 	paddr_t pa_end  = (pa + sz - 1) & ~ARMADAXP_L2_ALIGN;
1061 
1062 	if (pa_base == pa_end)
1063 		L2_WRITE(ARMADAXP_L2_WBINV_PHYS, pa_base);
1064 	else {
1065 		L2_WRITE(ARMADAXP_L2_RANGE_BASE, pa_base);
1066 		L2_WRITE(ARMADAXP_L2_WBINV_RANGE, pa_end);
1067 	}
1068 	L2_WRITE(ARMADAXP_L2_SYNC, 0);
1069 	__asm__ __volatile__("dsb");
1070 }
1071 
1072 #ifdef AURORA_IO_CACHE_COHERENCY
1073 static void
1074 armadaxp_io_coherency_init(void)
1075 {
1076 	uint32_t reg;
1077 
1078 	/* set CIB read snoop command to ReadUnique */
1079 	reg = read_mlmbreg(MVSOC_MLMB_CIB_CTRL_CFG);
1080 	reg |= MVSOC_MLMB_CIB_CTRL_CFG_WB_EN;
1081 	write_mlmbreg(MVSOC_MLMB_CIB_CTRL_CFG, reg);
1082 
1083 	/* enable CPUs in SMP group on Fabric coherency */
1084 	reg = read_mlmbreg(MVSOC_MLMB_CFU_FAB_CTRL);
1085 	reg |= MVSOC_MLMB_CFU_FAB_CTRL_SNOOP_CPU0;
1086 	write_mlmbreg(MVSOC_MLMB_CFU_FAB_CTRL, reg);
1087 
1088 	/* send all snoop request to L2 cache */
1089 	reg = read_mlmbreg(MVSOC_MLMB_CFU_CFG);
1090 #ifdef L2CACHE_ENABLE
1091 	reg |= MVSOC_MLMB_CFU_CFG_L2_NOTIFY;
1092 #else
1093 	reg &= ~MVSOC_MLMB_CFU_CFG_L2_NOTIFY;
1094 #endif
1095 	write_mlmbreg(MVSOC_MLMB_CFU_CFG, reg);
1096 
1097 	/* Mark as enabled */
1098 	iocc_state = 1;
1099 }
1100 #endif
1101 
1102 static int
1103 armadaxp_clkgating(struct marvell_attach_args *mva)
1104 {
1105 	uint32_t val;
1106 	int i;
1107 
1108 	for (i = 0; i < __arraycount(clkgatings); i++) {
1109 		if (clkgatings[i].offset == mva->mva_offset) {
1110 			val = read_miscreg(ARMADAXP_MISC_PMCGC);
1111 			if ((val & clkgatings[i].bits) == clkgatings[i].bits)
1112 				/* Clock enabled */
1113 				return 0;
1114 			return 1;
1115 		}
1116 	}
1117 	/* Clock Gating not support */
1118 	return 0;
1119 }
1120 
1121 int
1122 armadaxp_init_mbus(void)
1123 {
1124 	struct mbus_table_def *def;
1125 	uint32_t reg;
1126 	int i;
1127 
1128 	for (i = 0; i < nwindow; i++) {
1129 		/* disable all windows */
1130 		reg = read_mlmbreg(MVSOC_MLMB_WCR(i));
1131 		reg &= ~MVSOC_MLMB_WCR_WINEN;
1132 		write_mlmbreg(MVSOC_MLMB_WCR(i), reg);
1133 		write_mlmbreg(MVSOC_MLMB_WBR(i), 0);
1134 	}
1135 
1136 	for (i = 0; i < __arraycount(mbus_table); i++) {
1137 		def = &mbus_table[i];
1138 		if (def->window >= nwindow)
1139 			continue;
1140 		if (def->size == 0)
1141 			continue;
1142 
1143 		/* restore window base */
1144 		reg = def->base & MVSOC_MLMB_WBR_BASE_MASK;
1145 		write_mlmbreg(MVSOC_MLMB_WBR(def->window), reg);
1146 
1147 		/* restore window configuration */
1148 		reg  = MVSOC_MLMB_WCR_SIZE(def->size);
1149 		reg |= MVSOC_MLMB_WCR_TARGET(def->target);
1150 		reg |= MVSOC_MLMB_WCR_ATTR(def->attr);
1151 #ifdef AURORA_IO_CACHE_COHERENCY
1152 		reg |= MVSOC_MLMB_WCR_SYNC; /* enbale I/O coherency barrior */
1153 #endif
1154 		reg |= MVSOC_MLMB_WCR_WINEN;
1155 		write_mlmbreg(MVSOC_MLMB_WCR(def->window), reg);
1156 	}
1157 
1158 	return 0;
1159 }
1160 
1161 int
1162 armadaxp_attr_dump(struct mvsoc_softc *sc, uint32_t target, uint32_t attr)
1163 {
1164 	struct mbus_description *desc;
1165 	int i;
1166 
1167 	for (i = 0; i < __arraycount(mbus_desc); i++) {
1168 		desc = &mbus_desc[i];
1169 		if (desc->target != target)
1170 			continue;
1171 		if (desc->attr != attr)
1172 			continue;
1173 		aprint_verbose_dev(sc->sc_dev, "%s", desc->string);
1174 		return 0;
1175 	}
1176 
1177 	/* unknown decoding target/attribute pair */
1178 	aprint_verbose_dev(sc->sc_dev, "target 0x%x(attr 0x%x)", target, attr);
1179 	return -1;
1180 }
1181