1 /* $NetBSD: armadaxp.c,v 1.26 2022/06/25 12:41:56 jmcneill 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.26 2022/06/25 12:41:56 jmcneill 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) le32toh(*(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
armadaxp_bootstrap(vaddr_t vbase,bus_addr_t pbase)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
armadaxp_intr_init(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
armadaxp_pic_unblock_irqs(struct pic_softc * pic,size_t irqbase,uint32_t irq_mask)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
armadaxp_pic_block_irqs(struct pic_softc * pic,size_t irqbase,uint32_t irq_mask)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
armadaxp_pic_establish_irq(struct pic_softc * pic,struct intrsource * is)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
armadaxp_pic_set_priority(struct pic_softc * pic,int ipl)655 armadaxp_pic_set_priority(struct pic_softc *pic, int ipl)
656 {
657 int ctp;
658
659 register_t psw = DISABLE_INTERRUPT_SAVE();
660
661 ctp = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_CTP);
662 ctp &= ~(0xf << MPIC_CTP_SHIFT);
663 ctp |= (ipl << MPIC_CTP_SHIFT);
664 MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_CTP, ctp);
665
666 curcpu()->ci_cpl = ipl;
667
668 if ((psw & I32_bit) == 0) {
669 ENABLE_INTERRUPT();
670 }
671 }
672
673 static void
armadaxp_pic_source_name(struct pic_softc * pic,int irq,char * buf,size_t len)674 armadaxp_pic_source_name(struct pic_softc *pic, int irq, char *buf, size_t len)
675 {
676 if (irq >= __arraycount(armadaxp_pic_source_names)) {
677 snprintf(buf, len, "Unknown IRQ %d", irq);
678 return;
679 }
680 strlcpy(buf, armadaxp_pic_source_names[irq], len);
681 }
682
683 static int
armadaxp_find_pending_irqs(void)684 armadaxp_find_pending_irqs(void)
685 {
686 struct intrsource *is;
687 int irq;
688
689 irq = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_IIACK) & 0x3ff;
690
691 /* Is it a spurious interrupt ?*/
692 if (irq == 0x3ff)
693 return 0;
694 is = armadaxp_pic.pic_sources[irq];
695 if (is == NULL) {
696 printf("stray interrupt: %d\n", irq);
697 return 0;
698 }
699
700 armadaxp_pic_block_irq(&armadaxp_pic, irq);
701 pic_mark_pending(&armadaxp_pic, irq);
702
703 return is->is_ipl;
704 }
705
706 static void
armadaxp_pic_block_irq(struct pic_softc * pic,size_t irq)707 armadaxp_pic_block_irq(struct pic_softc *pic, size_t irq)
708 {
709
710 KASSERT(pic->pic_maxsources >= irq);
711 MPIC_WRITE(ARMADAXP_MLMB_MPIC_ICE, irq);
712 MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ISM, irq);
713 }
714
715 static void
armadaxp_err_pic_source_name(struct pic_softc * pic,int irq,char * buf,size_t len)716 armadaxp_err_pic_source_name(struct pic_softc *pic, int irq,
717 char *buf, size_t len)
718 {
719 if (irq >= __arraycount(armadaxp_err_pic_source_names)) {
720 snprintf(buf, len, "Unknown IRQ %d", irq);
721 return;
722 }
723 strlcpy(buf, armadaxp_err_pic_source_names[irq], len);
724 }
725
726
727 /*
728 * ARMADAXP_MLMB_MPIC_ERR_CAUSE
729 */
730 static void
armadaxp_err_pic_unblock_irqs(struct pic_softc * pic,size_t irqbase,uint32_t irq_mask)731 armadaxp_err_pic_unblock_irqs(struct pic_softc *pic, size_t irqbase,
732 uint32_t irq_mask)
733 {
734 uint32_t reg;
735
736 KASSERT(irqbase == 0); /* XXX: support offset */
737
738 reg = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_ERR_MASK);
739 reg |= irq_mask;
740 MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ERR_MASK, reg);
741 }
742
743 static void
armadaxp_err_pic_block_irqs(struct pic_softc * pic,size_t irqbase,uint32_t irq_mask)744 armadaxp_err_pic_block_irqs(struct pic_softc *pic, size_t irqbase,
745 uint32_t irq_mask)
746 {
747 uint32_t reg;
748
749 KASSERT(irqbase == 0); /* XXX: support offset */
750
751 reg = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_ERR_MASK);
752 reg &= ~irq_mask;
753 MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ERR_MASK, reg);
754 }
755
756 static void
armadaxp_err_pic_establish_irq(struct pic_softc * pic,struct intrsource * is)757 armadaxp_err_pic_establish_irq(struct pic_softc *pic, struct intrsource *is)
758 {
759 uint32_t reg;
760
761 KASSERT(pic->pic_maxsources >= is->is_irq);
762
763 reg = MPIC_CPU_READ(ARMADAXP_MLMB_MPIC_ERR_MASK);
764 reg |= ARMADAXP_IRQ_ERROR_BIT(is->is_irq);
765 MPIC_CPU_WRITE(ARMADAXP_MLMB_MPIC_ERR_MASK, reg);
766 }
767
768 static int
armadaxp_err_pic_pending_irqs(struct pic_softc * pic)769 armadaxp_err_pic_pending_irqs(struct pic_softc *pic)
770 {
771 struct intrsource *is;
772 uint32_t reg;
773 int irq;
774
775 reg = MPIC_READ(ARMADAXP_MLMB_MPIC_ERR_CAUSE);
776 irq = ffs(reg);
777 if (irq == 0)
778 return 0;
779 irq--; /* bit number to index */
780
781 is = pic->pic_sources[irq];
782 if (is == NULL) {
783 printf("stray interrupt: %d\n", irq);
784 return 0;
785 }
786 return pic_mark_pending_sources(pic, 0, irq);
787 }
788
789
790 /*
791 * Clock functions
792 */
793
794 static void
armadaxp_getclks(void)795 armadaxp_getclks(void)
796 {
797 uint64_t sar_reg;
798 uint8_t sar_cpu_freq, sar_fab_freq;
799
800 if (cputype == CPU_ID_MV88SV584X_V7)
801 mvTclk = 250000000; /* 250 MHz */
802 else
803 mvTclk = 200000000; /* 200 MHz */
804
805 sar_reg = (read_miscreg(ARMADAXP_MISC_SAR_HI) << 31) |
806 read_miscreg(ARMADAXP_MISC_SAR_LO);
807
808 sar_cpu_freq = EXTRACT_XP_CPU_FREQ_FIELD(sar_reg);
809 sar_fab_freq = EXTRACT_XP_FAB_FREQ_FIELD(sar_reg);
810
811 /* Check if CPU frequency field has correct value */
812 if (sar_cpu_freq >= __arraycount(clock_table_xp))
813 panic("Reserved value in cpu frequency configuration field: "
814 "%d", sar_cpu_freq);
815
816 /* Check if fabric frequency field has correct value */
817 if (sar_fab_freq >= __arraycount(freq_conf_table))
818 panic("Reserved value in fabric frequency configuration field: "
819 "%d", sar_fab_freq);
820
821 /* Get CPU clock frequency */
822 mvPclk = clock_table_xp[sar_cpu_freq] *
823 freq_conf_table[sar_fab_freq].vco_cpu;
824
825 /* Get L2CLK clock frequency and use as system clock (mvSysclk) */
826 mvSysclk = mvPclk / freq_conf_table[sar_fab_freq].vco_l2c;
827
828 /* Round mvSysclk value to integer MHz */
829 if (((mvPclk % freq_conf_table[sar_fab_freq].vco_l2c) * 10 /
830 freq_conf_table[sar_fab_freq].vco_l2c) >= 5)
831 mvSysclk++;
832
833 mvPclk *= 1000000;
834 mvSysclk *= 1000000;
835
836 curcpu()->ci_data.cpu_cc_freq = mvPclk;
837 }
838
839 static void
armada370_getclks(void)840 armada370_getclks(void)
841 {
842 uint32_t sar;
843 uint8_t cpu_freq, fab_freq;
844
845 sar = read_miscreg(ARMADAXP_MISC_SAR_LO);
846 if (sar & 0x00100000)
847 mvTclk = 200000000; /* 200 MHz */
848 else
849 mvTclk = 166666667; /* 166 MHz */
850
851 cpu_freq = EXTRACT_370_CPU_FREQ_FIELD(sar);
852 fab_freq = EXTRACT_370_FAB_FREQ_FIELD(sar);
853
854 /* Check if CPU frequency field has correct value */
855 if (cpu_freq >= __arraycount(clock_table_370))
856 panic("Reserved value in cpu frequency configuration field: "
857 "%d", cpu_freq);
858
859 /* Check if fabric frequency field has correct value */
860 if (fab_freq >= __arraycount(freq_conf_table))
861 panic("Reserved value in fabric frequency configuration field: "
862 "%d", fab_freq);
863
864 /* Get CPU clock frequency */
865 mvPclk = clock_table_370[cpu_freq] *
866 freq_conf_table[fab_freq].vco_cpu;
867
868 /* Get L2CLK clock frequency and use as system clock (mvSysclk) */
869 mvSysclk = mvPclk / freq_conf_table[fab_freq].vco_l2c;
870
871 /* Round mvSysclk value to integer MHz */
872 if (((mvPclk % freq_conf_table[fab_freq].vco_l2c) * 10 /
873 freq_conf_table[fab_freq].vco_l2c) >= 5)
874 mvSysclk++;
875
876 mvPclk *= 1000000;
877 mvSysclk *= 1000000;
878 }
879
880 /*
881 * L2 Cache initialization
882 */
883
884 static int
armadaxp_l2_init(bus_addr_t pbase)885 armadaxp_l2_init(bus_addr_t pbase)
886 {
887 u_int32_t reg;
888 int ret;
889
890 /* Map L2 space */
891 ret = bus_space_map(&mvsoc_bs_tag, pbase + ARMADAXP_L2_BASE,
892 0x1000, 0, &l2_handle);
893 if (ret) {
894 printf("%s: Cannot map L2 register space, ret:%d\n",
895 __func__, ret);
896 return (-1);
897 }
898
899 /* Variables for cpufunc_asm_pj4b.S */
900 /* XXX: per cpu register. need to support SMP */
901 armadaxp_l2_barrier_reg = mlmb_base + MVSOC_MLMB_CIB_BARRIER(0);
902
903 /* Set L2 policy */
904 reg = L2_READ(ARMADAXP_L2_AUX_CTRL);
905 reg &= ~(L2_AUX_WBWT_MODE_MASK);
906 reg &= ~(L2_AUX_REP_STRAT_MASK);
907 reg |= L2_AUX_ECC_ENABLE;
908 reg |= L2_AUX_PARITY_ENABLE;
909 reg |= L2_AUX_WBWT_MODE_BY_ATTR;
910 reg |= L2_AUX_FORCE_WA_BY_ATTR;
911 reg |= L2_AUX_REP_STRAT_SEMIPLRU;
912 L2_WRITE(ARMADAXP_L2_AUX_CTRL, reg);
913
914 /* Invalidate L2 cache */
915 L2_WRITE(ARMADAXP_L2_INV_WAY, L2_ALL_WAYS);
916
917 /* Clear pending L2 interrupts */
918 L2_WRITE(ARMADAXP_L2_INT_CAUSE, 0x1ff);
919
920 /* Enable Cache and TLB maintenance broadcast */
921 __asm__ __volatile__ ("mrc p15, 1, %0, c15, c2, 0" : "=r"(reg));
922 reg |= (1 << 8);
923 __asm__ __volatile__ ("mcr p15, 1, %0, c15, c2, 0" : :"r"(reg));
924
925 /*
926 * Set the Point of Coherency and Point of Unification to DRAM.
927 * This is a reset value but anyway, configure this just in case.
928 */
929 reg = read_mlmbreg(ARMADAXP_L2_CFU);
930 reg |= (1 << 17) | (1 << 18);
931 write_mlmbreg(ARMADAXP_L2_CFU, reg);
932
933 /* Enable L2 cache */
934 reg = L2_READ(ARMADAXP_L2_CTRL);
935 L2_WRITE(ARMADAXP_L2_CTRL, reg | L2_CTRL_ENABLE);
936
937 /* Mark as enabled */
938 l2cache_state = 1;
939
940 #ifdef DEBUG
941 /* Configure and enable counter */
942 L2_WRITE(ARMADAXP_L2_CNTR_CONF(0), 0xf0000 | (4 << 2));
943 L2_WRITE(ARMADAXP_L2_CNTR_CONF(1), 0xf0000 | (2 << 2));
944 L2_WRITE(ARMADAXP_L2_CNTR_CTRL, 0x303);
945 #endif
946
947 return (0);
948 }
949
950 void
armadaxp_sdcache_inv_all(void)951 armadaxp_sdcache_inv_all(void)
952 {
953 L2_WRITE(ARMADAXP_L2_INV_WAY, L2_ALL_WAYS);
954 }
955
956 void
armadaxp_sdcache_wb_all(void)957 armadaxp_sdcache_wb_all(void)
958 {
959 L2_WRITE(ARMADAXP_L2_WB_WAY, L2_ALL_WAYS);
960 L2_WRITE(ARMADAXP_L2_SYNC, 0);
961 dsb(sy);
962 }
963
964 void
armadaxp_sdcache_wbinv_all(void)965 armadaxp_sdcache_wbinv_all(void)
966 {
967 L2_WRITE(ARMADAXP_L2_WBINV_WAY, L2_ALL_WAYS);
968 L2_WRITE(ARMADAXP_L2_SYNC, 0);
969 dsb(sy);
970 }
971
972 static paddr_t
armadaxp_sdcache_wbalign_base(vaddr_t va,paddr_t pa,psize_t sz)973 armadaxp_sdcache_wbalign_base(vaddr_t va, paddr_t pa, psize_t sz)
974 {
975 paddr_t line_start = pa & ~ARMADAXP_L2_ALIGN;
976 vaddr_t save_start;
977 uint8_t save_buf[ARMADAXP_L2_LINE_SIZE];
978 size_t unalign;
979
980 unalign = va & ARMADAXP_L2_ALIGN;
981 if (unalign == 0)
982 return line_start; /* request is aligned to cache line size */
983
984 /* save data that is not intended to invalidate */
985 save_start = va & ~ARMADAXP_L2_ALIGN;
986 memcpy(save_buf, (void *)save_start, unalign);
987
988 /* invalidate include saved data */
989 L2_WRITE(ARMADAXP_L2_INV_PHYS, line_start);
990
991 /* write back saved data */
992 memcpy((void *)save_start, save_buf, unalign);
993 L2_WRITE(ARMADAXP_L2_WB_PHYS, line_start);
994 L2_WRITE(ARMADAXP_L2_SYNC, 0);
995 dsb(sy);
996
997 return line_start;
998 }
999
1000 static paddr_t
armadaxp_sdcache_wbalign_end(vaddr_t va,paddr_t pa,psize_t sz)1001 armadaxp_sdcache_wbalign_end(vaddr_t va, paddr_t pa, psize_t sz)
1002 {
1003 paddr_t line_start = (pa + sz - 1) & ~ARMADAXP_L2_ALIGN;
1004 vaddr_t save_start = va + sz;
1005 uint8_t save_buf[ARMADAXP_L2_LINE_SIZE];
1006 size_t save_len;
1007 size_t unalign;
1008
1009 unalign = save_start & ARMADAXP_L2_ALIGN;
1010 if (unalign == 0)
1011 return line_start; /* request is aligned to cache line size */
1012
1013 /* save data that is not intended to invalidate */
1014 save_len = ARMADAXP_L2_LINE_SIZE - unalign;
1015 memcpy(save_buf, (void *)save_start, save_len);
1016
1017 /* invalidate include saved data */
1018 L2_WRITE(ARMADAXP_L2_INV_PHYS, line_start);
1019
1020 /* write back saved data */
1021 memcpy((void *)save_start, save_buf, save_len);
1022 L2_WRITE(ARMADAXP_L2_WB_PHYS, line_start);
1023 dsb(sy);
1024
1025 return line_start;
1026 }
1027
1028 void
armadaxp_sdcache_inv_range(vaddr_t va,paddr_t pa,psize_t sz)1029 armadaxp_sdcache_inv_range(vaddr_t va, paddr_t pa, psize_t sz)
1030 {
1031 paddr_t pa_base;
1032 paddr_t pa_end;
1033
1034 /* align and write-back the boundary */
1035 pa_base = armadaxp_sdcache_wbalign_base(va, pa, sz);
1036 pa_end = armadaxp_sdcache_wbalign_end(va, pa, sz);
1037
1038 /* invalidate other cache */
1039 if (pa_base == pa_end) {
1040 L2_WRITE(ARMADAXP_L2_INV_PHYS, pa_base);
1041 return;
1042 }
1043
1044 L2_WRITE(ARMADAXP_L2_RANGE_BASE, pa_base);
1045 L2_WRITE(ARMADAXP_L2_INV_RANGE, pa_end);
1046 }
1047
1048 void
armadaxp_sdcache_wb_range(vaddr_t va,paddr_t pa,psize_t sz)1049 armadaxp_sdcache_wb_range(vaddr_t va, paddr_t pa, psize_t sz)
1050 {
1051 paddr_t pa_base = pa & ~ARMADAXP_L2_ALIGN;
1052 paddr_t pa_end = (pa + sz - 1) & ~ARMADAXP_L2_ALIGN;
1053
1054 if (pa_base == pa_end)
1055 L2_WRITE(ARMADAXP_L2_WB_PHYS, pa_base);
1056 else {
1057 L2_WRITE(ARMADAXP_L2_RANGE_BASE, pa_base);
1058 L2_WRITE(ARMADAXP_L2_WB_RANGE, pa_end);
1059 }
1060 L2_WRITE(ARMADAXP_L2_SYNC, 0);
1061 dsb(sy);
1062 }
1063
1064 void
armadaxp_sdcache_wbinv_range(vaddr_t va,paddr_t pa,psize_t sz)1065 armadaxp_sdcache_wbinv_range(vaddr_t va, paddr_t pa, psize_t sz)
1066 {
1067 paddr_t pa_base = pa & ~ARMADAXP_L2_ALIGN;
1068 paddr_t pa_end = (pa + sz - 1) & ~ARMADAXP_L2_ALIGN;
1069
1070 if (pa_base == pa_end)
1071 L2_WRITE(ARMADAXP_L2_WBINV_PHYS, pa_base);
1072 else {
1073 L2_WRITE(ARMADAXP_L2_RANGE_BASE, pa_base);
1074 L2_WRITE(ARMADAXP_L2_WBINV_RANGE, pa_end);
1075 }
1076 L2_WRITE(ARMADAXP_L2_SYNC, 0);
1077 dsb(sy);
1078 }
1079
1080 #ifdef AURORA_IO_CACHE_COHERENCY
1081 static void
armadaxp_io_coherency_init(void)1082 armadaxp_io_coherency_init(void)
1083 {
1084 uint32_t reg;
1085
1086 /* set CIB read snoop command to ReadUnique */
1087 reg = read_mlmbreg(MVSOC_MLMB_CIB_CTRL_CFG);
1088 reg |= MVSOC_MLMB_CIB_CTRL_CFG_WB_EN;
1089 write_mlmbreg(MVSOC_MLMB_CIB_CTRL_CFG, reg);
1090
1091 /* enable CPUs in SMP group on Fabric coherency */
1092 reg = read_mlmbreg(MVSOC_MLMB_CFU_FAB_CTRL);
1093 reg |= MVSOC_MLMB_CFU_FAB_CTRL_SNOOP_CPU0;
1094 write_mlmbreg(MVSOC_MLMB_CFU_FAB_CTRL, reg);
1095
1096 /* send all snoop request to L2 cache */
1097 reg = read_mlmbreg(MVSOC_MLMB_CFU_CFG);
1098 #ifdef L2CACHE_ENABLE
1099 reg |= MVSOC_MLMB_CFU_CFG_L2_NOTIFY;
1100 #else
1101 reg &= ~MVSOC_MLMB_CFU_CFG_L2_NOTIFY;
1102 #endif
1103 write_mlmbreg(MVSOC_MLMB_CFU_CFG, reg);
1104
1105 /* Mark as enabled */
1106 iocc_state = 1;
1107 }
1108 #endif
1109
1110 static int
armadaxp_clkgating(struct marvell_attach_args * mva)1111 armadaxp_clkgating(struct marvell_attach_args *mva)
1112 {
1113 uint32_t val;
1114 int i;
1115
1116 for (i = 0; i < __arraycount(clkgatings); i++) {
1117 if (clkgatings[i].offset == mva->mva_offset) {
1118 val = read_miscreg(ARMADAXP_MISC_PMCGC);
1119 if ((val & clkgatings[i].bits) == clkgatings[i].bits)
1120 /* Clock enabled */
1121 return 0;
1122 return 1;
1123 }
1124 }
1125 /* Clock Gating not support */
1126 return 0;
1127 }
1128
1129 int
armadaxp_init_mbus(void)1130 armadaxp_init_mbus(void)
1131 {
1132 struct mbus_table_def *def;
1133 uint32_t reg;
1134 int i;
1135
1136 for (i = 0; i < nwindow; i++) {
1137 /* disable all windows */
1138 reg = read_mlmbreg(MVSOC_MLMB_WCR(i));
1139 reg &= ~MVSOC_MLMB_WCR_WINEN;
1140 write_mlmbreg(MVSOC_MLMB_WCR(i), reg);
1141 write_mlmbreg(MVSOC_MLMB_WBR(i), 0);
1142 }
1143
1144 for (i = 0; i < __arraycount(mbus_table); i++) {
1145 def = &mbus_table[i];
1146 if (def->window >= nwindow)
1147 continue;
1148 if (def->size == 0)
1149 continue;
1150
1151 /* restore window base */
1152 reg = def->base & MVSOC_MLMB_WBR_BASE_MASK;
1153 write_mlmbreg(MVSOC_MLMB_WBR(def->window), reg);
1154
1155 /* restore window configuration */
1156 reg = MVSOC_MLMB_WCR_SIZE(def->size);
1157 reg |= MVSOC_MLMB_WCR_TARGET(def->target);
1158 reg |= MVSOC_MLMB_WCR_ATTR(def->attr);
1159 #ifdef AURORA_IO_CACHE_COHERENCY
1160 reg |= MVSOC_MLMB_WCR_SYNC; /* enable I/O coherency barrier */
1161 #endif
1162 reg |= MVSOC_MLMB_WCR_WINEN;
1163 write_mlmbreg(MVSOC_MLMB_WCR(def->window), reg);
1164 }
1165
1166 return 0;
1167 }
1168
1169 int
armadaxp_attr_dump(struct mvsoc_softc * sc,uint32_t target,uint32_t attr)1170 armadaxp_attr_dump(struct mvsoc_softc *sc, uint32_t target, uint32_t attr)
1171 {
1172 struct mbus_description *desc;
1173 int i;
1174
1175 for (i = 0; i < __arraycount(mbus_desc); i++) {
1176 desc = &mbus_desc[i];
1177 if (desc->target != target)
1178 continue;
1179 if (desc->attr != attr)
1180 continue;
1181 aprint_verbose_dev(sc->sc_dev, "%s", desc->string);
1182 return 0;
1183 }
1184
1185 /* unknown decoding target/attribute pair */
1186 aprint_verbose_dev(sc->sc_dev, "target 0x%x(attr 0x%x)", target, attr);
1187 return -1;
1188 }
1189