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