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