gt.c revision 1.21.2.2 1 1.21.2.1 uebayasi /* $NetBSD: gt.c,v 1.21.2.2 2010/08/17 06:46:16 uebayasi Exp $ */
2 1.1 matt
3 1.1 matt /*
4 1.1 matt * Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
5 1.1 matt * All rights reserved.
6 1.1 matt *
7 1.1 matt * Redistribution and use in source and binary forms, with or without
8 1.1 matt * modification, are permitted provided that the following conditions
9 1.1 matt * are met:
10 1.1 matt * 1. Redistributions of source code must retain the above copyright
11 1.1 matt * notice, this list of conditions and the following disclaimer.
12 1.1 matt * 2. Redistributions in binary form must reproduce the above copyright
13 1.1 matt * notice, this list of conditions and the following disclaimer in the
14 1.1 matt * documentation and/or other materials provided with the distribution.
15 1.1 matt * 3. All advertising materials mentioning features or use of this software
16 1.1 matt * must display the following acknowledgement:
17 1.1 matt * This product includes software developed for the NetBSD Project by
18 1.1 matt * Allegro Networks, Inc., and Wasabi Systems, Inc.
19 1.1 matt * 4. The name of Allegro Networks, Inc. may not be used to endorse
20 1.1 matt * or promote products derived from this software without specific prior
21 1.1 matt * written permission.
22 1.1 matt * 5. The name of Wasabi Systems, Inc. may not be used to endorse
23 1.1 matt * or promote products derived from this software without specific prior
24 1.1 matt * written permission.
25 1.1 matt *
26 1.1 matt * THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
27 1.1 matt * WASABI SYSTEMS, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
28 1.1 matt * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
29 1.1 matt * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30 1.1 matt * IN NO EVENT SHALL EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
31 1.1 matt * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 1.1 matt * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 1.1 matt * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 1.1 matt * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 1.1 matt * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 1.1 matt * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 1.1 matt * POSSIBILITY OF SUCH DAMAGE.
38 1.1 matt */
39 1.1 matt
40 1.1 matt /*
41 1.1 matt * gt.c -- GT system controller driver
42 1.1 matt */
43 1.5 lukem
44 1.5 lukem #include <sys/cdefs.h>
45 1.21.2.1 uebayasi __KERNEL_RCSID(0, "$NetBSD: gt.c,v 1.21.2.2 2010/08/17 06:46:16 uebayasi Exp $");
46 1.1 matt
47 1.1 matt #include "opt_marvell.h"
48 1.21.2.1 uebayasi #include "gtmpsc.h"
49 1.21.2.2 uebayasi #include "opt_multiprocessor.h"
50 1.8 jmc #include "locators.h"
51 1.1 matt
52 1.1 matt #include <sys/param.h>
53 1.21.2.1 uebayasi #include <sys/bus.h>
54 1.1 matt #include <sys/device.h>
55 1.1 matt #include <sys/kernel.h>
56 1.21.2.1 uebayasi #include <sys/types.h>
57 1.1 matt
58 1.1 matt #include <dev/marvell/gtintrreg.h>
59 1.21.2.1 uebayasi #include <dev/marvell/gtsdmareg.h>
60 1.21.2.1 uebayasi #if NGTMPSC > 0
61 1.21.2.1 uebayasi #include <dev/marvell/gtmpscreg.h>
62 1.21.2.1 uebayasi #include <dev/marvell/gtmpscvar.h>
63 1.21.2.1 uebayasi #endif
64 1.21.2.1 uebayasi #include <dev/marvell/gtpcireg.h>
65 1.21.2.1 uebayasi #include <dev/marvell/gtreg.h>
66 1.1 matt #include <dev/marvell/gtvar.h>
67 1.21.2.1 uebayasi #include <dev/marvell/marvellreg.h>
68 1.21.2.1 uebayasi #include <dev/marvell/marvellvar.h>
69 1.21.2.1 uebayasi
70 1.21.2.1 uebayasi #include <dev/pci/pcireg.h>
71 1.1 matt
72 1.1 matt #if ((GT_MPP_WATCHDOG & 0xf0f0f0f0) != 0)
73 1.1 matt # error /* unqualified: configuration botch! */
74 1.1 matt #endif
75 1.1 matt
76 1.21.2.1 uebayasi #define gt_read(sc,r) bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (r))
77 1.21.2.1 uebayasi #define gt_write(sc,r,v) bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (r), (v))
78 1.21.2.1 uebayasi
79 1.21.2.1 uebayasi
80 1.21.2.1 uebayasi static int gt_cfprint(void *, const char *);
81 1.21.2.1 uebayasi static int gt_cfsearch(device_t, cfdata_t, const int *, void *);
82 1.21.2.1 uebayasi static void gt_attach_peripherals(struct gt_softc *);
83 1.21.2.1 uebayasi
84 1.21.2.1 uebayasi #ifdef GT_DEVBUS
85 1.21.2.1 uebayasi static int gt_devbus_intr(void *);
86 1.3 matt static void gt_devbus_intr_enb(struct gt_softc *);
87 1.21.2.1 uebayasi #endif
88 1.1 matt #ifdef GT_ECC
89 1.21.2.1 uebayasi static int gt_ecc_intr(void *);
90 1.3 matt static void gt_ecc_intr_enb(struct gt_softc *);
91 1.1 matt #endif
92 1.21.2.1 uebayasi #if NGTMPSC > 0
93 1.21.2.1 uebayasi static void gt_sdma_intr_enb(struct gt_softc *);
94 1.21.2.1 uebayasi #endif
95 1.21.2.1 uebayasi #ifdef GT_COMM
96 1.21.2.1 uebayasi static int gt_comm_intr(void *);
97 1.21.2.1 uebayasi static void gt_comm_intr_enb(struct gt_softc *);
98 1.21.2.1 uebayasi #endif
99 1.21.2.1 uebayasi
100 1.1 matt
101 1.21.2.1 uebayasi #ifdef GT_WATCHDOG
102 1.21.2.1 uebayasi static void gt_watchdog_init(struct gt_softc *);
103 1.21.2.1 uebayasi static void gt_watchdog_enable(struct gt_softc *);
104 1.21.2.1 uebayasi #ifndef GT_MPP_WATCHDOG
105 1.21.2.1 uebayasi static void gt_watchdog_disable(struct gt_softc *);
106 1.21.2.1 uebayasi #endif
107 1.6 matt
108 1.21.2.1 uebayasi static struct gt_softc *gt_watchdog_sc = NULL;
109 1.21.2.1 uebayasi static int gt_watchdog_state = 0;
110 1.21.2.1 uebayasi #endif
111 1.1 matt
112 1.1 matt
113 1.21.2.2 uebayasi #define OFFSET_DEFAULT MVA_OFFSET_DEFAULT
114 1.21.2.2 uebayasi #define IRQ_DEFAULT MVA_IRQ_DEFAULT
115 1.21.2.1 uebayasi static const struct gt_dev {
116 1.21.2.1 uebayasi int model;
117 1.21.2.1 uebayasi const char *name;
118 1.21.2.1 uebayasi int unit;
119 1.21.2.1 uebayasi bus_size_t offset;
120 1.21.2.1 uebayasi int irq;
121 1.21.2.1 uebayasi } gt_devs[] = {
122 1.21.2.1 uebayasi { MARVELL_DISCOVERY, "gfec", 0, 0x0000, IRQ_DEFAULT },
123 1.21.2.1 uebayasi { MARVELL_DISCOVERY, "gtidmac", 0, 0x0000, 4 /*...7 */ },
124 1.21.2.1 uebayasi { MARVELL_DISCOVERY, "gtmpsc", 0, 0x8000, 40 },
125 1.21.2.1 uebayasi { MARVELL_DISCOVERY, "gtmpsc", 1, 0x9000, 42 },
126 1.21.2.1 uebayasi { MARVELL_DISCOVERY, "gtpci", 0, OFFSET_DEFAULT, IRQ_DEFAULT },
127 1.21.2.1 uebayasi { MARVELL_DISCOVERY, "gtpci", 1, OFFSET_DEFAULT, IRQ_DEFAULT },
128 1.21.2.1 uebayasi { MARVELL_DISCOVERY, "gttwsi", 0, 0xc000, 37 },
129 1.21.2.1 uebayasi { MARVELL_DISCOVERY, "obio", 0, OFFSET_DEFAULT, IRQ_DEFAULT },
130 1.21.2.1 uebayasi { MARVELL_DISCOVERY, "obio", 1, OFFSET_DEFAULT, IRQ_DEFAULT },
131 1.21.2.1 uebayasi { MARVELL_DISCOVERY, "obio", 2, OFFSET_DEFAULT, IRQ_DEFAULT },
132 1.21.2.1 uebayasi { MARVELL_DISCOVERY, "obio", 3, OFFSET_DEFAULT, IRQ_DEFAULT },
133 1.21.2.1 uebayasi { MARVELL_DISCOVERY, "obio", 4, OFFSET_DEFAULT, IRQ_DEFAULT },
134 1.21.2.1 uebayasi
135 1.21.2.1 uebayasi { MARVELL_DISCOVERY_II, "gtidmac", 0, 0x0000, 4 /*...7 */ },
136 1.21.2.1 uebayasi { MARVELL_DISCOVERY_II, "gtmpsc", 0, 0x8000, 40 },
137 1.21.2.1 uebayasi { MARVELL_DISCOVERY_II, "gtmpsc", 1, 0x9000, 42 },
138 1.21.2.1 uebayasi { MARVELL_DISCOVERY_II, "gtpci", 0, OFFSET_DEFAULT, IRQ_DEFAULT },
139 1.21.2.1 uebayasi { MARVELL_DISCOVERY_II, "gtpci", 1, OFFSET_DEFAULT, IRQ_DEFAULT },
140 1.21.2.1 uebayasi { MARVELL_DISCOVERY_II, "gttwsi", 0, 0xc000, 37 },
141 1.21.2.1 uebayasi { MARVELL_DISCOVERY_II, "mvgbec", 0, 0x0000, IRQ_DEFAULT },
142 1.1 matt
143 1.21.2.1 uebayasi { MARVELL_DISCOVERY_III,"gtidmac", 0, 0x0000, 4 /*...7 */ },
144 1.21.2.1 uebayasi { MARVELL_DISCOVERY_III,"gtmpsc", 0, 0x8000, 40 },
145 1.21.2.1 uebayasi { MARVELL_DISCOVERY_III,"gtmpsc", 1, 0x9000, 42 },
146 1.21.2.1 uebayasi { MARVELL_DISCOVERY_III,"gtpci", 0, OFFSET_DEFAULT, IRQ_DEFAULT },
147 1.21.2.1 uebayasi { MARVELL_DISCOVERY_III,"gtpci", 1, OFFSET_DEFAULT, IRQ_DEFAULT },
148 1.21.2.1 uebayasi { MARVELL_DISCOVERY_III,"gttwsi", 0, 0xc000, 37 },
149 1.21.2.1 uebayasi { MARVELL_DISCOVERY_III,"mvgbec", 0, 0x0000, IRQ_DEFAULT },
150 1.21.2.2 uebayasi
151 1.21.2.2 uebayasi #if 0 /* XXXXXX: from www.marvell.com */
152 1.21.2.2 uebayasi /* Discovery LT (Discovery Light) MV644[23]0 */
153 1.21.2.2 uebayasi { MARVELL_DISCOVERY_LT, "gtidmac", 0, 0x?000, ? /*...? */ },
154 1.21.2.2 uebayasi { MARVELL_DISCOVERY_LT, "gtmpsc", 0, 0x?000, ? },
155 1.21.2.2 uebayasi { MARVELL_DISCOVERY_LT, "gtmpsc", 1, 0x?000, ? },
156 1.21.2.2 uebayasi { MARVELL_DISCOVERY_LT, "gtpci", 0, OFFSET_DEFAULT, IRQ_DEFAULT },
157 1.21.2.2 uebayasi { MARVELL_DISCOVERY_LT, "gtpci", 1, OFFSET_DEFAULT, IRQ_DEFAULT },
158 1.21.2.2 uebayasi { MARVELL_DISCOVERY_LT, "gttwsi", 0, 0x?000, ? },
159 1.21.2.2 uebayasi { MARVELL_DISCOVERY_LT, "mvgbec", 0, 0x?000, IRQ_DEFAULT },
160 1.21.2.2 uebayasi
161 1.21.2.2 uebayasi /* Discovery V MV64560 */
162 1.21.2.2 uebayasi { MARVELL_DISCOVERY_V, "com", ?, 0x?0000, ? },
163 1.21.2.2 uebayasi { MARVELL_DISCOVERY_V, "ehci", 0, 0x?0000, ? },
164 1.21.2.2 uebayasi { MARVELL_DISCOVERY_V, "ehci", 1, 0x?0000, ? },
165 1.21.2.2 uebayasi { MARVELL_DISCOVERY_V, "gtidmac", 0, 0x?0000, ? /*...? */ },
166 1.21.2.2 uebayasi { MARVELL_DISCOVERY_V, "gtpci", 0, 0x?0000, IRQ_DEFAULT },
167 1.21.2.2 uebayasi { MARVELL_DISCOVERY_V, "gttwsi", 0, 0x?0000, ? },
168 1.21.2.2 uebayasi { MARVELL_DISCOVERY_V, "mvgbec", 0, 0x?0000, IRQ_DEFAULT },
169 1.21.2.2 uebayasi { MARVELL_DISCOVERY_V, "mvpex or gtpci?", 0, 0x?0000, IRQ_DEFAULT },
170 1.21.2.2 uebayasi { MARVELL_DISCOVERY_V, "obio", 0, OFFSET_DEFAULT, IRQ_DEFAULT },
171 1.21.2.2 uebayasi
172 1.21.2.2 uebayasi /* Discovery VI MV64660 */
173 1.21.2.2 uebayasi /* MV64560 + SATA? */
174 1.21.2.2 uebayasi { MARVELL_DISCOVERY_VI, "mvsata", 0, 0x?0000, ? },
175 1.21.2.1 uebayasi #endif
176 1.21.2.1 uebayasi };
177 1.1 matt
178 1.1 matt
179 1.21.2.1 uebayasi static int
180 1.21.2.1 uebayasi gt_cfprint(void *aux, const char *pnp)
181 1.1 matt {
182 1.21.2.1 uebayasi struct marvell_attach_args *mva = aux;
183 1.1 matt
184 1.21.2.1 uebayasi if (pnp)
185 1.21.2.1 uebayasi aprint_normal("%s at %s unit %d",
186 1.21.2.1 uebayasi mva->mva_name, pnp, mva->mva_unit);
187 1.21.2.1 uebayasi else {
188 1.21.2.2 uebayasi if (mva->mva_unit != MVA_UNIT_DEFAULT)
189 1.21.2.1 uebayasi aprint_normal(" unit %d", mva->mva_unit);
190 1.21.2.2 uebayasi if (mva->mva_offset != MVA_OFFSET_DEFAULT) {
191 1.21.2.1 uebayasi aprint_normal(" offset 0x%04x", mva->mva_offset);
192 1.21.2.1 uebayasi if (mva->mva_size > 0)
193 1.21.2.1 uebayasi aprint_normal("-0x%04x",
194 1.21.2.1 uebayasi mva->mva_offset + mva->mva_size - 1);
195 1.21.2.1 uebayasi }
196 1.21.2.2 uebayasi if (mva->mva_irq != MVA_IRQ_DEFAULT)
197 1.21.2.1 uebayasi aprint_normal(" irq %d", mva->mva_irq);
198 1.1 matt }
199 1.1 matt
200 1.21.2.1 uebayasi return UNCONF;
201 1.1 matt }
202 1.1 matt
203 1.1 matt
204 1.21.2.1 uebayasi /* ARGSUSED */
205 1.1 matt static int
206 1.21.2.1 uebayasi gt_cfsearch(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
207 1.1 matt {
208 1.21.2.1 uebayasi struct marvell_attach_args *mva = aux;
209 1.21.2.1 uebayasi
210 1.21.2.2 uebayasi if (cf->cf_loc[GTCF_IRQ] != MVA_IRQ_DEFAULT)
211 1.21.2.1 uebayasi mva->mva_irq = cf->cf_loc[GTCF_IRQ];
212 1.1 matt
213 1.21.2.1 uebayasi return config_match(parent, cf, aux);
214 1.21.2.1 uebayasi }
215 1.21.2.1 uebayasi
216 1.21.2.1 uebayasi static void
217 1.21.2.1 uebayasi gt_attach_peripherals(struct gt_softc *sc)
218 1.21.2.1 uebayasi {
219 1.21.2.1 uebayasi struct marvell_attach_args mva;
220 1.21.2.1 uebayasi int i;
221 1.1 matt
222 1.21.2.1 uebayasi for (i = 0; i < __arraycount(gt_devs); i++) {
223 1.21.2.1 uebayasi if (gt_devs[i].model != sc->sc_model)
224 1.21.2.1 uebayasi continue;
225 1.21.2.1 uebayasi
226 1.21.2.1 uebayasi mva.mva_name = gt_devs[i].name;
227 1.21.2.1 uebayasi mva.mva_model = sc->sc_model;
228 1.21.2.1 uebayasi mva.mva_revision = sc->sc_rev;
229 1.21.2.1 uebayasi mva.mva_iot = sc->sc_iot;
230 1.21.2.1 uebayasi mva.mva_ioh = sc->sc_ioh;
231 1.21.2.1 uebayasi mva.mva_unit = gt_devs[i].unit;
232 1.21.2.1 uebayasi mva.mva_addr = sc->sc_addr;
233 1.21.2.1 uebayasi mva.mva_offset = gt_devs[i].offset;
234 1.21.2.1 uebayasi mva.mva_size = 0;
235 1.21.2.1 uebayasi mva.mva_dmat = sc->sc_dmat;
236 1.21.2.1 uebayasi mva.mva_irq = gt_devs[i].irq;
237 1.1 matt
238 1.21.2.1 uebayasi config_found_sm_loc(sc->sc_dev, "gt", NULL, &mva,
239 1.21.2.1 uebayasi gt_cfprint, gt_cfsearch);
240 1.21.2.1 uebayasi }
241 1.1 matt }
242 1.1 matt
243 1.1 matt void
244 1.1 matt gt_attach_common(struct gt_softc *gt)
245 1.1 matt {
246 1.1 matt uint32_t cpucfg, cpumode, cpumstr;
247 1.21.2.2 uebayasi #ifdef GT_DEBUG
248 1.1 matt uint32_t loaddr, hiaddr;
249 1.1 matt #endif
250 1.1 matt
251 1.21.2.1 uebayasi gt_write(gt, GTPCI_CA(0), PCI_ID_REG);
252 1.21.2.1 uebayasi gt->sc_model = PCI_PRODUCT(gt_read(gt, GTPCI_CD(0)));
253 1.21.2.1 uebayasi gt_write(gt, GTPCI_CA(0), PCI_CLASS_REG);
254 1.21.2.1 uebayasi gt->sc_rev = PCI_REVISION(gt_read(gt, GTPCI_CD(0)));
255 1.21.2.1 uebayasi
256 1.21.2.1 uebayasi aprint_naive("\n");
257 1.21.2.1 uebayasi switch (gt->sc_model) {
258 1.21.2.1 uebayasi case MARVELL_DISCOVERY:
259 1.21.2.1 uebayasi aprint_normal(": GT-6426x%c Discovery\n",
260 1.21.2.1 uebayasi (gt->sc_rev == MARVELL_DISCOVERY_REVA) ? 'A' : 'B');
261 1.21.2.1 uebayasi break;
262 1.21.2.1 uebayasi case MARVELL_DISCOVERY_II:
263 1.21.2.1 uebayasi aprint_normal(": MV6436x Discovery II\n");
264 1.21.2.1 uebayasi break;
265 1.21.2.1 uebayasi
266 1.21.2.1 uebayasi case MARVELL_DISCOVERY_III:
267 1.21.2.2 uebayasi aprint_normal(": MV6446x Discovery III\n");
268 1.21.2.2 uebayasi break;
269 1.21.2.2 uebayasi #if 0
270 1.21.2.1 uebayasi case MARVELL_DISCOVERY_LT:
271 1.21.2.1 uebayasi case MARVELL_DISCOVERY_V:
272 1.21.2.1 uebayasi case MARVELL_DISCOVERY_VI:
273 1.21.2.1 uebayasi #endif
274 1.21.2.1 uebayasi
275 1.21.2.1 uebayasi default:
276 1.21.2.1 uebayasi aprint_normal(": type unknown\n"); break;
277 1.21.2.1 uebayasi }
278 1.1 matt
279 1.3 matt cpumode = gt_read(gt, GT_CPU_Mode);
280 1.21.2.1 uebayasi aprint_normal_dev(gt->sc_dev,
281 1.21.2.1 uebayasi "id %d", GT_CPUMode_MultiGTID_GET(cpumode));
282 1.1 matt if (cpumode & GT_CPUMode_MultiGT)
283 1.3 matt aprint_normal (" (multi)");
284 1.1 matt switch (GT_CPUMode_CPUType_GET(cpumode)) {
285 1.3 matt case 4: aprint_normal(", 60x bus"); break;
286 1.3 matt case 5: aprint_normal(", MPX bus"); break;
287 1.21.2.1 uebayasi
288 1.21.2.1 uebayasi default:
289 1.21.2.1 uebayasi aprint_normal(", %#x(?) bus", GT_CPUMode_CPUType_GET(cpumode));
290 1.21.2.1 uebayasi break;
291 1.1 matt }
292 1.1 matt
293 1.3 matt cpumstr = gt_read(gt, GT_CPU_Master_Ctl);
294 1.1 matt switch (cpumstr & (GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock)) {
295 1.1 matt case 0: break;
296 1.3 matt case GT_CPUMstrCtl_CleanBlock: aprint_normal(", snoop=clean"); break;
297 1.3 matt case GT_CPUMstrCtl_FlushBlock: aprint_normal(", snoop=flush"); break;
298 1.1 matt case GT_CPUMstrCtl_CleanBlock|GT_CPUMstrCtl_FlushBlock:
299 1.3 matt aprint_normal(", snoop=clean&flush"); break;
300 1.1 matt }
301 1.3 matt aprint_normal(" wdog=%#x,%#x\n",
302 1.21.2.2 uebayasi gt_read(gt, GT_WDOG_Config), gt_read(gt, GT_WDOG_Value));
303 1.1 matt
304 1.21.2.2 uebayasi #ifdef GT_DEBUG
305 1.21.2.2 uebayasi loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS0_Low_Decode), gt->sc_model);
306 1.21.2.2 uebayasi hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS0_High_Decode), gt->sc_model);
307 1.21.2.1 uebayasi aprint_normal_dev(gt->sc_dev, " scs[0]=%#10x-%#10x\n",
308 1.21.2.1 uebayasi loaddr, hiaddr);
309 1.3 matt
310 1.21.2.2 uebayasi loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS1_Low_Decode), gt->sc_model);
311 1.21.2.2 uebayasi hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS1_High_Decode), gt->sc_model);
312 1.21.2.1 uebayasi aprint_normal_dev(gt->sc_dev, " scs[1]=%#10x-%#10x\n",
313 1.21.2.1 uebayasi loaddr, hiaddr);
314 1.3 matt
315 1.21.2.2 uebayasi loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS2_Low_Decode), gt->sc_model);
316 1.21.2.2 uebayasi hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS2_High_Decode), gt->sc_model);
317 1.21.2.1 uebayasi aprint_normal_dev(gt->sc_dev, " scs[2]=%#10x-%#10x\n",
318 1.21.2.1 uebayasi loaddr, hiaddr);
319 1.3 matt
320 1.21.2.2 uebayasi loaddr = GT_LADDR_GET(gt_read(gt, GT_SCS3_Low_Decode), gt->sc_model);
321 1.21.2.2 uebayasi hiaddr = GT_HADDR_GET(gt_read(gt, GT_SCS3_High_Decode), gt->sc_model);
322 1.21.2.1 uebayasi aprint_normal_dev(gt->sc_dev, " scs[3]=%#10x-%#10x\n",
323 1.21.2.1 uebayasi loaddr, hiaddr);
324 1.3 matt
325 1.21.2.2 uebayasi loaddr = GT_LADDR_GET(gt_read(gt, GT_CS0_Low_Decode), gt->sc_model);
326 1.21.2.2 uebayasi hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS0_High_Decode), gt->sc_model);
327 1.21.2.1 uebayasi aprint_normal_dev(gt->sc_dev, " cs[0]=%#10x-%#10x\n",
328 1.21.2.1 uebayasi loaddr, hiaddr);
329 1.3 matt
330 1.21.2.2 uebayasi loaddr = GT_LADDR_GET(gt_read(gt, GT_CS1_Low_Decode), gt->sc_model);
331 1.21.2.2 uebayasi hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS1_High_Decode), gt->sc_model);
332 1.21.2.1 uebayasi aprint_normal_dev(gt->sc_dev, " cs[1]=%#10x-%#10x\n",
333 1.21.2.1 uebayasi loaddr, hiaddr);
334 1.3 matt
335 1.21.2.2 uebayasi loaddr = GT_LADDR_GET(gt_read(gt, GT_CS2_Low_Decode), gt->sc_model);
336 1.21.2.2 uebayasi hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS2_High_Decode), gt->sc_model);
337 1.21.2.1 uebayasi aprint_normal_dev(gt->sc_dev, " cs[2]=%#10x-%#10x\n",
338 1.21.2.1 uebayasi loaddr, hiaddr);
339 1.3 matt
340 1.21.2.2 uebayasi loaddr = GT_LADDR_GET(gt_read(gt, GT_CS3_Low_Decode), gt->sc_model);
341 1.21.2.2 uebayasi hiaddr = GT_HADDR_GET(gt_read(gt, GT_CS3_High_Decode), gt->sc_model);
342 1.21.2.1 uebayasi aprint_normal_dev(gt->sc_dev, " cs[3]=%#10x-%#10x\n",
343 1.21.2.1 uebayasi loaddr, hiaddr);
344 1.3 matt
345 1.21.2.2 uebayasi loaddr = GT_LADDR_GET(gt_read(gt, GT_BootCS_Low_Decode), gt->sc_model);
346 1.21.2.2 uebayasi hiaddr = GT_HADDR_GET(gt_read(gt, GT_BootCS_High_Decode), gt->sc_model);
347 1.21.2.2 uebayasi aprint_normal_dev(gt->sc_dev, " bootcs=%#10x-%#10x\n",
348 1.21.2.1 uebayasi loaddr, hiaddr);
349 1.3 matt
350 1.21.2.2 uebayasi loaddr = GT_LADDR_GET(gt_read(gt, GT_PCI0_IO_Low_Decode), gt->sc_model);
351 1.21.2.2 uebayasi hiaddr =
352 1.21.2.2 uebayasi GT_HADDR_GET(gt_read(gt, GT_PCI0_IO_High_Decode), gt->sc_model);
353 1.21.2.2 uebayasi aprint_normal_dev(gt->sc_dev, " pci0io=%#10x-%#10x ",
354 1.21.2.1 uebayasi loaddr, hiaddr);
355 1.3 matt
356 1.3 matt loaddr = gt_read(gt, GT_PCI0_IO_Remap);
357 1.3 matt aprint_normal("remap=%#010x\n", loaddr);
358 1.3 matt
359 1.21.2.2 uebayasi loaddr =
360 1.21.2.2 uebayasi GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem0_Low_Decode), gt->sc_model);
361 1.21.2.2 uebayasi hiaddr =
362 1.21.2.2 uebayasi GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem0_High_Decode), gt->sc_model);
363 1.21.2.2 uebayasi aprint_normal_dev(gt->sc_dev, " pci0mem[0]=%#10x-%#10x ",
364 1.21.2.1 uebayasi loaddr, hiaddr);
365 1.3 matt
366 1.3 matt loaddr = gt_read(gt, GT_PCI0_Mem0_Remap_Low);
367 1.3 matt hiaddr = gt_read(gt, GT_PCI0_Mem0_Remap_High);
368 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
369 1.3 matt
370 1.21.2.2 uebayasi loaddr =
371 1.21.2.2 uebayasi GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem1_Low_Decode), gt->sc_model);
372 1.21.2.2 uebayasi hiaddr =
373 1.21.2.2 uebayasi GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem1_High_Decode), gt->sc_model);
374 1.21.2.2 uebayasi aprint_normal_dev(gt->sc_dev, " pci0mem[1]=%#10x-%#10x ",
375 1.21.2.1 uebayasi loaddr, hiaddr);
376 1.3 matt
377 1.3 matt loaddr = gt_read(gt, GT_PCI0_Mem1_Remap_Low);
378 1.3 matt hiaddr = gt_read(gt, GT_PCI0_Mem1_Remap_High);
379 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
380 1.3 matt
381 1.21.2.2 uebayasi loaddr =
382 1.21.2.2 uebayasi GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem2_Low_Decode), gt->sc_model);
383 1.21.2.2 uebayasi hiaddr =
384 1.21.2.2 uebayasi GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem2_High_Decode), gt->sc_model);
385 1.21.2.2 uebayasi aprint_normal_dev(gt->sc_dev, " pci0mem[2]=%#10x-%#10x ",
386 1.21.2.1 uebayasi loaddr, hiaddr);
387 1.3 matt
388 1.3 matt loaddr = gt_read(gt, GT_PCI0_Mem2_Remap_Low);
389 1.3 matt hiaddr = gt_read(gt, GT_PCI0_Mem2_Remap_High);
390 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
391 1.3 matt
392 1.21.2.2 uebayasi loaddr =
393 1.21.2.2 uebayasi GT_LADDR_GET(gt_read(gt, GT_PCI0_Mem3_Low_Decode), gt->sc_model);
394 1.21.2.2 uebayasi hiaddr =
395 1.21.2.2 uebayasi GT_HADDR_GET(gt_read(gt, GT_PCI0_Mem3_High_Decode), gt->sc_model);
396 1.21.2.2 uebayasi aprint_normal_dev(gt->sc_dev, " pci0mem[3]=%#10x-%#10x ",
397 1.21.2.1 uebayasi loaddr, hiaddr);
398 1.3 matt
399 1.3 matt loaddr = gt_read(gt, GT_PCI0_Mem3_Remap_Low);
400 1.3 matt hiaddr = gt_read(gt, GT_PCI0_Mem3_Remap_High);
401 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
402 1.3 matt
403 1.21.2.2 uebayasi loaddr = GT_LADDR_GET(gt_read(gt, GT_PCI1_IO_Low_Decode), gt->sc_model);
404 1.21.2.2 uebayasi hiaddr =
405 1.21.2.2 uebayasi GT_HADDR_GET(gt_read(gt, GT_PCI1_IO_High_Decode), gt->sc_model);
406 1.21.2.2 uebayasi aprint_normal_dev(gt->sc_dev, " pci1io=%#10x-%#10x ",
407 1.21.2.1 uebayasi loaddr, hiaddr);
408 1.3 matt
409 1.3 matt loaddr = gt_read(gt, GT_PCI1_IO_Remap);
410 1.3 matt aprint_normal("remap=%#010x\n", loaddr);
411 1.3 matt
412 1.21.2.2 uebayasi loaddr =
413 1.21.2.2 uebayasi GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem0_Low_Decode), gt->sc_model);
414 1.21.2.2 uebayasi hiaddr =
415 1.21.2.2 uebayasi GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem0_High_Decode), gt->sc_model);
416 1.21.2.2 uebayasi aprint_normal_dev(gt->sc_dev, " pci1mem[0]=%#10x-%#10x ",
417 1.21.2.1 uebayasi loaddr, hiaddr);
418 1.3 matt
419 1.3 matt loaddr = gt_read(gt, GT_PCI1_Mem0_Remap_Low);
420 1.3 matt hiaddr = gt_read(gt, GT_PCI1_Mem0_Remap_High);
421 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
422 1.3 matt
423 1.21.2.2 uebayasi loaddr =
424 1.21.2.2 uebayasi GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem1_Low_Decode), gt->sc_model);
425 1.21.2.2 uebayasi hiaddr =
426 1.21.2.2 uebayasi GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem1_High_Decode), gt->sc_model);
427 1.21.2.2 uebayasi aprint_normal_dev(gt->sc_dev, " pci1mem[1]=%#10x-%#10x ",
428 1.21.2.1 uebayasi loaddr, hiaddr);
429 1.3 matt
430 1.3 matt loaddr = gt_read(gt, GT_PCI1_Mem1_Remap_Low);
431 1.3 matt hiaddr = gt_read(gt, GT_PCI1_Mem1_Remap_High);
432 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
433 1.3 matt
434 1.21.2.2 uebayasi loaddr =
435 1.21.2.2 uebayasi GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem2_Low_Decode), gt->sc_model);
436 1.21.2.2 uebayasi hiaddr =
437 1.21.2.2 uebayasi GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem2_High_Decode), gt->sc_model);
438 1.21.2.2 uebayasi aprint_normal_dev(gt->sc_dev, " pci1mem[2]=%#10x-%#10x ",
439 1.21.2.1 uebayasi loaddr, hiaddr);
440 1.3 matt
441 1.3 matt loaddr = gt_read(gt, GT_PCI1_Mem2_Remap_Low);
442 1.3 matt hiaddr = gt_read(gt, GT_PCI1_Mem2_Remap_High);
443 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
444 1.3 matt
445 1.21.2.2 uebayasi loaddr =
446 1.21.2.2 uebayasi GT_LADDR_GET(gt_read(gt, GT_PCI1_Mem3_Low_Decode), gt->sc_model);
447 1.21.2.2 uebayasi hiaddr =
448 1.21.2.2 uebayasi GT_HADDR_GET(gt_read(gt, GT_PCI1_Mem3_High_Decode), gt->sc_model);
449 1.21.2.2 uebayasi aprint_normal_dev(gt->sc_dev, " pci1mem[3]=%#10x-%#10x ",
450 1.21.2.1 uebayasi loaddr, hiaddr);
451 1.3 matt
452 1.3 matt loaddr = gt_read(gt, GT_PCI1_Mem3_Remap_Low);
453 1.3 matt hiaddr = gt_read(gt, GT_PCI1_Mem3_Remap_High);
454 1.3 matt aprint_normal("remap=%#010x.%#010x\n", hiaddr, loaddr);
455 1.1 matt
456 1.21.2.2 uebayasi loaddr = GT_LADDR_GET(gt_read(gt, GT_Internal_Decode), gt->sc_model);
457 1.21.2.2 uebayasi aprint_normal_dev(gt->sc_dev, " internal=%#10x-%#10x\n",
458 1.21.2.1 uebayasi loaddr, loaddr + 256 * 1024);
459 1.1 matt
460 1.21.2.2 uebayasi loaddr = GT_LADDR_GET(gt_read(gt, GT_CPU0_Low_Decode), gt->sc_model);
461 1.21.2.2 uebayasi hiaddr = GT_HADDR_GET(gt_read(gt, GT_CPU0_High_Decode), gt->sc_model);
462 1.21.2.2 uebayasi aprint_normal_dev(gt->sc_dev, " cpu0=%#10x-%#10x\n",
463 1.21.2.1 uebayasi loaddr, hiaddr);
464 1.1 matt
465 1.21.2.2 uebayasi #ifdef MULTIPROCESSOR
466 1.21.2.2 uebayasi loaddr = GT_LADDR_GET(gt_read(gt, GT_CPU1_Low_Decode), gt->sc_model);
467 1.21.2.2 uebayasi hiaddr = GT_HADDR_GET(gt_read(gt, GT_CPU1_High_Decode), gt->sc_model);
468 1.21.2.1 uebayasi aprint_normal_dev(gt->sc_dev, " cpu1=%#10x-%#10x",
469 1.21.2.1 uebayasi loaddr, hiaddr);
470 1.1 matt #endif
471 1.21.2.2 uebayasi #endif
472 1.1 matt
473 1.21.2.1 uebayasi aprint_normal("%s:", device_xname(gt->sc_dev));
474 1.1 matt
475 1.3 matt cpucfg = gt_read(gt, GT_CPU_Cfg);
476 1.1 matt cpucfg |= GT_CPUCfg_ConfSBDis; /* per errata #46 */
477 1.1 matt cpucfg |= GT_CPUCfg_AACKDelay; /* per restriction #18 */
478 1.3 matt gt_write(gt, GT_CPU_Cfg, cpucfg);
479 1.1 matt if (cpucfg & GT_CPUCfg_Pipeline)
480 1.3 matt aprint_normal(" pipeline");
481 1.1 matt if (cpucfg & GT_CPUCfg_AACKDelay)
482 1.3 matt aprint_normal(" aack-delay");
483 1.1 matt if (cpucfg & GT_CPUCfg_RdOOO)
484 1.3 matt aprint_normal(" read-ooo");
485 1.1 matt if (cpucfg & GT_CPUCfg_IOSBDis)
486 1.3 matt aprint_normal(" io-sb-dis");
487 1.1 matt if (cpucfg & GT_CPUCfg_ConfSBDis)
488 1.3 matt aprint_normal(" conf-sb-dis");
489 1.1 matt if (cpucfg & GT_CPUCfg_ClkSync)
490 1.3 matt aprint_normal(" clk-sync");
491 1.3 matt aprint_normal("\n");
492 1.1 matt
493 1.21.2.1 uebayasi #ifdef GT_WATCHDOG
494 1.1 matt gt_watchdog_init(gt);
495 1.21.2.1 uebayasi #endif
496 1.1 matt
497 1.21.2.1 uebayasi #ifdef GT_DEVBUS
498 1.21.2.1 uebayasi gt_devbus_intr_enb(gt);
499 1.21.2.1 uebayasi #endif
500 1.1 matt #ifdef GT_ECC
501 1.1 matt gt_ecc_intr_enb(gt);
502 1.1 matt #endif
503 1.21.2.1 uebayasi #if NGTMPSC > 0
504 1.21.2.1 uebayasi gt_sdma_intr_enb(gt);
505 1.21.2.1 uebayasi #endif
506 1.21.2.1 uebayasi #ifdef GT_COMM
507 1.1 matt gt_comm_intr_enb(gt);
508 1.21.2.1 uebayasi #endif
509 1.21.2.1 uebayasi
510 1.21.2.1 uebayasi gt_attach_peripherals(gt);
511 1.1 matt
512 1.21.2.1 uebayasi #ifdef GT_WATCHDOG
513 1.1 matt gt_watchdog_service();
514 1.21.2.1 uebayasi gt_watchdog_enable(gt);
515 1.21.2.1 uebayasi #endif
516 1.1 matt }
517 1.1 matt
518 1.21.2.1 uebayasi
519 1.21.2.1 uebayasi #ifdef GT_DEVBUS
520 1.21.2.1 uebayasi static int
521 1.21.2.1 uebayasi gt_devbus_intr(void *arg)
522 1.1 matt {
523 1.21.2.1 uebayasi struct gt_softc *gt = (struct gt_softc *)arg;
524 1.21.2.1 uebayasi u_int32_t cause;
525 1.21.2.1 uebayasi u_int32_t addr;
526 1.1 matt
527 1.21.2.1 uebayasi cause = gt_read(gt, GT_DEVBUS_ICAUSE);
528 1.21.2.1 uebayasi addr = gt_read(gt, GT_DEVBUS_ERR_ADDR);
529 1.21.2.1 uebayasi gt_write(gt, GT_DEVBUS_ICAUSE, 0); /* clear intr */
530 1.21.2.1 uebayasi
531 1.21.2.1 uebayasi if (cause & GT_DEVBUS_DBurstErr) {
532 1.21.2.1 uebayasi aprint_error_dev(gt->sc_dev,
533 1.21.2.1 uebayasi "Device Bus error: burst violation");
534 1.21.2.1 uebayasi if ((cause & GT_DEVBUS_Sel) == 0)
535 1.21.2.1 uebayasi aprint_error(", addr %#x", addr);
536 1.21.2.1 uebayasi aprint_error("\n");
537 1.21.2.1 uebayasi }
538 1.21.2.1 uebayasi if (cause & GT_DEVBUS_DRdyErr) {
539 1.21.2.1 uebayasi aprint_error_dev(gt->sc_dev,
540 1.21.2.1 uebayasi "Device Bus error: ready timer expired");
541 1.21.2.1 uebayasi if ((cause & GT_DEVBUS_Sel) != 0)
542 1.21.2.1 uebayasi aprint_error(", addr %#x\n", addr);
543 1.21.2.1 uebayasi aprint_error("\n");
544 1.21.2.1 uebayasi }
545 1.21.2.1 uebayasi
546 1.21.2.1 uebayasi return cause != 0;
547 1.1 matt }
548 1.1 matt
549 1.21.2.1 uebayasi /*
550 1.21.2.1 uebayasi * gt_devbus_intr_enb - enable GT-64260 Device Bus interrupts
551 1.21.2.1 uebayasi */
552 1.21.2.1 uebayasi static void
553 1.21.2.1 uebayasi gt_devbus_intr_enb(struct gt_softc *gt)
554 1.1 matt {
555 1.21.2.1 uebayasi gt_write(gt, GT_DEVBUS_IMASK,
556 1.21.2.1 uebayasi GT_DEVBUS_DBurstErr|GT_DEVBUS_DRdyErr);
557 1.21.2.1 uebayasi (void)gt_read(gt, GT_DEVBUS_ERR_ADDR); /* clear addr */
558 1.21.2.1 uebayasi gt_write(gt, GT_DEVBUS_ICAUSE, 0); /* clear intr */
559 1.1 matt
560 1.21.2.1 uebayasi (void)marvell_intr_establish(IRQ_DEV, IPL_VM, gt_devbus_intr, gt);
561 1.21.2.1 uebayasi }
562 1.21.2.1 uebayasi #endif /* GT_DEVBUS */
563 1.1 matt
564 1.21.2.1 uebayasi #ifdef GT_ECC
565 1.21.2.1 uebayasi const static char *gt_ecc_intr_str[4] = {
566 1.21.2.1 uebayasi "(none)",
567 1.21.2.1 uebayasi "single bit",
568 1.21.2.1 uebayasi "double bit",
569 1.21.2.1 uebayasi "(reserved)"
570 1.21.2.1 uebayasi };
571 1.21.2.1 uebayasi
572 1.21.2.1 uebayasi static int
573 1.21.2.1 uebayasi gt_ecc_intr(void *arg)
574 1.21.2.1 uebayasi {
575 1.21.2.1 uebayasi struct gt_softc *gt = (struct gt_softc *)arg;
576 1.21.2.1 uebayasi uint32_t addr, dlo, dhi, rec, calc, count;
577 1.21.2.1 uebayasi int err;
578 1.21.2.1 uebayasi
579 1.21.2.1 uebayasi count = gt_read(gt, GT_ECC_Count);
580 1.21.2.1 uebayasi dlo = gt_read(gt, GT_ECC_Data_Lo);
581 1.21.2.1 uebayasi dhi = gt_read(gt, GT_ECC_Data_Hi);
582 1.21.2.1 uebayasi rec = gt_read(gt, GT_ECC_Rec);
583 1.21.2.1 uebayasi calc = gt_read(gt, GT_ECC_Calc);
584 1.21.2.1 uebayasi addr = gt_read(gt, GT_ECC_Addr); /* read last! */
585 1.21.2.1 uebayasi gt_write(gt, GT_ECC_Addr, 0); /* clear intr */
586 1.21.2.1 uebayasi
587 1.21.2.1 uebayasi err = addr & 0x3;
588 1.21.2.1 uebayasi
589 1.21.2.1 uebayasi aprint_error_dev(gt->sc_dev,
590 1.21.2.1 uebayasi "ECC error: %s: addr %#x data %#x.%#x rec %#x calc %#x cnt %#x\n",
591 1.21.2.1 uebayasi gt_ecc_intr_str[err], addr, dhi, dlo, rec, calc, count);
592 1.21.2.1 uebayasi
593 1.21.2.1 uebayasi if (err == 2)
594 1.21.2.1 uebayasi panic("ecc");
595 1.1 matt
596 1.21.2.1 uebayasi return err == 1;
597 1.1 matt }
598 1.1 matt
599 1.21.2.1 uebayasi /*
600 1.21.2.1 uebayasi * gt_ecc_intr_enb - enable GT-64260 ECC interrupts
601 1.21.2.1 uebayasi */
602 1.21.2.1 uebayasi static void
603 1.21.2.1 uebayasi gt_ecc_intr_enb(struct gt_softc *gt)
604 1.1 matt {
605 1.21.2.1 uebayasi uint32_t ctl;
606 1.21.2.1 uebayasi
607 1.21.2.1 uebayasi ctl = gt_read(gt, GT_ECC_Ctl);
608 1.21.2.1 uebayasi ctl |= 1 << 16; /* XXX 1-bit threshold == 1 */
609 1.21.2.1 uebayasi gt_write(gt, GT_ECC_Ctl, ctl);
610 1.21.2.1 uebayasi (void)gt_read(gt, GT_ECC_Data_Lo);
611 1.21.2.1 uebayasi (void)gt_read(gt, GT_ECC_Data_Hi);
612 1.21.2.1 uebayasi (void)gt_read(gt, GT_ECC_Rec);
613 1.21.2.1 uebayasi (void)gt_read(gt, GT_ECC_Calc);
614 1.21.2.1 uebayasi (void)gt_read(gt, GT_ECC_Addr); /* read last! */
615 1.21.2.1 uebayasi gt_write(gt, GT_ECC_Addr, 0); /* clear intr */
616 1.21.2.1 uebayasi
617 1.21.2.1 uebayasi (void)marvell_intr_establish(IRQ_ECC, IPL_VM, gt_ecc_intr, gt);
618 1.1 matt }
619 1.21.2.1 uebayasi #endif /* GT_ECC */
620 1.1 matt
621 1.21.2.1 uebayasi #if NGTMPSC > 0
622 1.21.2.1 uebayasi /*
623 1.21.2.1 uebayasi * gt_sdma_intr_enb - enable GT-64260 SDMA interrupts
624 1.21.2.1 uebayasi */
625 1.21.2.1 uebayasi static void
626 1.21.2.1 uebayasi gt_sdma_intr_enb(struct gt_softc *gt)
627 1.1 matt {
628 1.1 matt
629 1.21.2.1 uebayasi (void)marvell_intr_establish(IRQ_SDMA, IPL_SERIAL, gtmpsc_intr, gt);
630 1.1 matt }
631 1.1 matt #endif
632 1.1 matt
633 1.21.2.1 uebayasi #ifdef GT_COMM
634 1.1 matt /*
635 1.1 matt * unknown board, enable everything
636 1.1 matt */
637 1.21.2.1 uebayasi # define GT_CommUnitIntr_DFLT \
638 1.21.2.1 uebayasi GT_CommUnitIntr_S0 |\
639 1.21.2.1 uebayasi GT_CommUnitIntr_S1 |\
640 1.21.2.1 uebayasi GT_CommUnitIntr_E0 |\
641 1.21.2.1 uebayasi GT_CommUnitIntr_E1 |\
642 1.21.2.1 uebayasi GT_CommUnitIntr_E2
643 1.1 matt
644 1.1 matt static const char * const gt_comm_subunit_name[8] = {
645 1.1 matt "ethernet 0",
646 1.1 matt "ethernet 1",
647 1.1 matt "ethernet 2",
648 1.1 matt "(reserved)",
649 1.1 matt "MPSC 0",
650 1.1 matt "MPSC 1",
651 1.1 matt "(reserved)",
652 1.1 matt "(sel)",
653 1.1 matt };
654 1.1 matt
655 1.1 matt static int
656 1.1 matt gt_comm_intr(void *arg)
657 1.1 matt {
658 1.1 matt struct gt_softc *gt = (struct gt_softc *)arg;
659 1.21.2.1 uebayasi uint32_t cause, addr;
660 1.1 matt unsigned int mask;
661 1.1 matt int i;
662 1.1 matt
663 1.3 matt cause = gt_read(gt, GT_CommUnitIntr_Cause);
664 1.3 matt gt_write(gt, GT_CommUnitIntr_Cause, ~cause);
665 1.3 matt addr = gt_read(gt, GT_CommUnitIntr_ErrAddr);
666 1.1 matt
667 1.21.2.1 uebayasi aprint_error_dev(gt->sc_dev,
668 1.21.2.1 uebayasi "Communications Unit Controller interrupt, cause %#x addr %#x\n",
669 1.21.2.1 uebayasi cause, addr);
670 1.1 matt
671 1.1 matt cause &= GT_CommUnitIntr_DFLT;
672 1.1 matt if (cause == 0)
673 1.1 matt return 0;
674 1.3 matt
675 1.1 matt mask = 0x7;
676 1.1 matt for (i=0; i<7; i++) {
677 1.1 matt if (cause & mask) {
678 1.21.2.1 uebayasi printf("%s: Comm Unit %s:", device_xname(gt->sc_dev),
679 1.1 matt gt_comm_subunit_name[i]);
680 1.9 perry if (cause & 1)
681 1.1 matt printf(" AddrMiss");
682 1.9 perry if (cause & 2)
683 1.1 matt printf(" AccProt");
684 1.9 perry if (cause & 4)
685 1.1 matt printf(" WrProt");
686 1.1 matt printf("\n");
687 1.1 matt }
688 1.1 matt cause >>= 4;
689 1.1 matt }
690 1.1 matt return 1;
691 1.1 matt }
692 1.1 matt
693 1.1 matt /*
694 1.1 matt * gt_comm_intr_init - enable GT-64260 Comm Unit interrupts
695 1.1 matt */
696 1.1 matt static void
697 1.1 matt gt_comm_intr_enb(struct gt_softc *gt)
698 1.1 matt {
699 1.21.2.1 uebayasi uint32_t cause;
700 1.1 matt
701 1.3 matt cause = gt_read(gt, GT_CommUnitIntr_Cause);
702 1.1 matt if (cause)
703 1.3 matt gt_write(gt, GT_CommUnitIntr_Cause, ~cause);
704 1.3 matt gt_write(gt, GT_CommUnitIntr_Mask, GT_CommUnitIntr_DFLT);
705 1.3 matt (void)gt_read(gt, GT_CommUnitIntr_ErrAddr);
706 1.1 matt
707 1.21.2.1 uebayasi (void)marvell_intr_establish(IRQ_COMM, IPL_VM, gt_comm_intr, gt);
708 1.1 matt }
709 1.21.2.1 uebayasi #endif /* GT_COMM */
710 1.1 matt
711 1.1 matt
712 1.21.2.1 uebayasi #ifdef GT_WATCHDOG
713 1.1 matt #ifndef GT_MPP_WATCHDOG
714 1.21.2.1 uebayasi static void
715 1.3 matt gt_watchdog_init(struct gt_softc *gt)
716 1.1 matt {
717 1.1 matt u_int32_t r;
718 1.1 matt
719 1.21.2.1 uebayasi aprint_normal_dev(gt->sc_dev, "watchdog");
720 1.1 matt
721 1.1 matt /*
722 1.1 matt * handle case where firmware started watchdog
723 1.1 matt */
724 1.3 matt r = gt_read(gt, GT_WDOG_Config);
725 1.21.2.1 uebayasi aprint_normal(" status %#x,%#x:", r, gt_read(gt, GT_WDOG_Value));
726 1.1 matt if ((r & 0x80000000) != 0) {
727 1.3 matt gt_watchdog_sc = gt; /* enabled */
728 1.1 matt gt_watchdog_state = 1;
729 1.21.2.1 uebayasi aprint_normal(" firmware-enabled\n");
730 1.21.2.1 uebayasi gt_watchdog_disable(gt);
731 1.21.2.1 uebayasi } else
732 1.21.2.1 uebayasi aprint_normal(" firmware-disabled\n");
733 1.1 matt }
734 1.1 matt
735 1.21.2.1 uebayasi #elif GT_MPP_WATCHDOG == 0
736 1.1 matt
737 1.21.2.1 uebayasi static void
738 1.3 matt gt_watchdog_init(struct gt_softc *gt)
739 1.1 matt {
740 1.1 matt
741 1.21.2.1 uebayasi aprint_normal_dev(gt->sc_dev, "watchdog not configured\n");
742 1.21.2.1 uebayasi return;
743 1.21.2.1 uebayasi }
744 1.1 matt
745 1.21.2.1 uebayasi #else /* GT_MPP_WATCHDOG > 0 */
746 1.1 matt
747 1.21.2.1 uebayasi static void
748 1.21.2.1 uebayasi gt_watchdog_init(struct gt_softc *gt)
749 1.21.2.1 uebayasi {
750 1.21.2.1 uebayasi u_int32_t mpp_watchdog = GT_MPP_WATCHDOG; /* from config */
751 1.21.2.1 uebayasi u_int32_t cfgbits, mppbits, mppmask, regoff, r;
752 1.1 matt
753 1.21.2.1 uebayasi mppmask = 0;
754 1.21.2.1 uebayasi
755 1.21.2.1 uebayasi aprint_normal_dev(gt->sc_dev, "watchdog");
756 1.1 matt
757 1.1 matt /*
758 1.1 matt * if firmware started watchdog, we disable and start
759 1.1 matt * from scratch to get it in a known state.
760 1.1 matt *
761 1.1 matt * on GT-64260A we always see 0xffffffff
762 1.1 matt * in both the GT_WDOG_Config_Enb and GT_WDOG_Value regsiters.
763 1.1 matt */
764 1.3 matt r = gt_read(gt, GT_WDOG_Config);
765 1.1 matt if (r != ~0) {
766 1.1 matt if ((r & GT_WDOG_Config_Enb) != 0) {
767 1.3 matt gt_write(gt, GT_WDOG_Config,
768 1.21.2.1 uebayasi GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT);
769 1.3 matt gt_write(gt, GT_WDOG_Config,
770 1.21.2.1 uebayasi GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT);
771 1.1 matt }
772 1.1 matt }
773 1.1 matt
774 1.1 matt /*
775 1.1 matt * "the watchdog timer can be activated only after
776 1.1 matt * configuring two MPP pins to act as WDE and WDNMI"
777 1.1 matt */
778 1.1 matt mppbits = 0;
779 1.1 matt cfgbits = 0x3;
780 1.1 matt for (regoff = GT_MPP_Control0; regoff <= GT_MPP_Control3; regoff += 4) {
781 1.1 matt if ((mpp_watchdog & cfgbits) == cfgbits) {
782 1.1 matt mppbits = 0x99;
783 1.1 matt mppmask = 0xff;
784 1.1 matt break;
785 1.1 matt }
786 1.1 matt cfgbits <<= 2;
787 1.1 matt if ((mpp_watchdog & cfgbits) == cfgbits) {
788 1.1 matt mppbits = 0x9900;
789 1.1 matt mppmask = 0xff00;
790 1.1 matt break;
791 1.1 matt }
792 1.1 matt cfgbits <<= 6; /* skip unqualified bits */
793 1.1 matt }
794 1.1 matt if (mppbits == 0) {
795 1.21.2.1 uebayasi aprint_error(" config error\n");
796 1.1 matt return;
797 1.1 matt }
798 1.1 matt
799 1.3 matt r = gt_read(gt, regoff);
800 1.1 matt r &= ~mppmask;
801 1.1 matt r |= mppbits;
802 1.3 matt gt_write(gt, regoff, r);
803 1.21.2.1 uebayasi aprint_normal(" mpp %#x %#x", regoff, mppbits);
804 1.1 matt
805 1.3 matt gt_write(gt, GT_WDOG_Value, GT_WDOG_NMI_DFLT);
806 1.1 matt
807 1.21.2.1 uebayasi gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1a|GT_WDOG_Preset_DFLT);
808 1.21.2.1 uebayasi gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1b|GT_WDOG_Preset_DFLT);
809 1.1 matt
810 1.3 matt r = gt_read(gt, GT_WDOG_Config),
811 1.21.2.1 uebayasi aprint_normal(" status %#x,%#x: %s\n",
812 1.21.2.1 uebayasi r, gt_read(gt, GT_WDOG_Value),
813 1.21.2.1 uebayasi ((r & GT_WDOG_Config_Enb) != 0) ? "enabled" : "botch");
814 1.1 matt }
815 1.1 matt #endif /* GT_MPP_WATCHDOG */
816 1.1 matt
817 1.21.2.1 uebayasi static void
818 1.21.2.1 uebayasi gt_watchdog_enable(struct gt_softc *gt)
819 1.1 matt {
820 1.1 matt
821 1.21.2.1 uebayasi if (gt_watchdog_state == 0) {
822 1.1 matt gt_watchdog_state = 1;
823 1.1 matt
824 1.3 matt gt_write(gt, GT_WDOG_Config,
825 1.21.2.1 uebayasi GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT);
826 1.3 matt gt_write(gt, GT_WDOG_Config,
827 1.21.2.1 uebayasi GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT);
828 1.1 matt }
829 1.1 matt }
830 1.1 matt
831 1.21.2.1 uebayasi #ifndef GT_MPP_WATCHDOG
832 1.21.2.1 uebayasi static void
833 1.21.2.1 uebayasi gt_watchdog_disable(struct gt_softc *gt)
834 1.1 matt {
835 1.1 matt
836 1.21.2.1 uebayasi if (gt_watchdog_state != 0) {
837 1.1 matt gt_watchdog_state = 0;
838 1.1 matt
839 1.3 matt gt_write(gt, GT_WDOG_Config,
840 1.21.2.1 uebayasi GT_WDOG_Config_Ctl1a | GT_WDOG_Preset_DFLT);
841 1.3 matt gt_write(gt, GT_WDOG_Config,
842 1.21.2.1 uebayasi GT_WDOG_Config_Ctl1b | GT_WDOG_Preset_DFLT);
843 1.1 matt }
844 1.1 matt }
845 1.21.2.1 uebayasi #endif
846 1.21.2.1 uebayasi
847 1.21.2.1 uebayasi /*
848 1.21.2.1 uebayasi * XXXX: gt_watchdog_service/reset functions need mutex lock...
849 1.21.2.1 uebayasi */
850 1.1 matt
851 1.21.2.2 uebayasi #ifdef GT_DEBUG
852 1.1 matt int inhibit_watchdog_service = 0;
853 1.1 matt #endif
854 1.1 matt void
855 1.1 matt gt_watchdog_service(void)
856 1.1 matt {
857 1.3 matt struct gt_softc *gt = gt_watchdog_sc;
858 1.1 matt
859 1.3 matt if ((gt == NULL) || (gt_watchdog_state == 0))
860 1.1 matt return; /* not enabled */
861 1.21.2.2 uebayasi #ifdef GT_DEBUG
862 1.1 matt if (inhibit_watchdog_service)
863 1.1 matt return;
864 1.1 matt #endif
865 1.9 perry
866 1.21.2.1 uebayasi gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl2a|GT_WDOG_Preset_DFLT);
867 1.21.2.1 uebayasi gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl2b|GT_WDOG_Preset_DFLT);
868 1.1 matt }
869 1.1 matt
870 1.1 matt /*
871 1.1 matt * gt_watchdog_reset - force a watchdog reset using Preset_VAL=0
872 1.1 matt */
873 1.1 matt void
874 1.19 cegger gt_watchdog_reset(void)
875 1.1 matt {
876 1.3 matt struct gt_softc *gt = gt_watchdog_sc;
877 1.1 matt u_int32_t r;
878 1.1 matt
879 1.3 matt r = gt_read(gt, GT_WDOG_Config);
880 1.21.2.1 uebayasi gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1a);
881 1.21.2.1 uebayasi gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1b);
882 1.1 matt if ((r & GT_WDOG_Config_Enb) != 0) {
883 1.1 matt /*
884 1.1 matt * was enabled, we just toggled it off, toggle on again
885 1.1 matt */
886 1.21.2.1 uebayasi gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1a);
887 1.21.2.1 uebayasi gt_write(gt, GT_WDOG_Config, GT_WDOG_Config_Ctl1b);
888 1.1 matt }
889 1.1 matt for(;;);
890 1.1 matt }
891 1.21.2.1 uebayasi #endif
892 1.1 matt
893 1.1 matt
894 1.1 matt int
895 1.21.2.1 uebayasi marvell_winparams_by_tag(device_t dev, int tag, int *target, int *attr,
896 1.21.2.1 uebayasi uint64_t *base, uint32_t *size)
897 1.1 matt {
898 1.21.2.1 uebayasi static const struct {
899 1.21.2.1 uebayasi int tag;
900 1.21.2.1 uebayasi uint32_t attribute;
901 1.21.2.1 uebayasi uint32_t basereg;
902 1.21.2.1 uebayasi uint32_t sizereg;
903 1.21.2.1 uebayasi } tagtbl[] = {
904 1.21.2.1 uebayasi { MARVELL_TAG_SDRAM_CS0, MARVELL_ATTR_SDRAM_CS0,
905 1.21.2.1 uebayasi GT_SCS0_Low_Decode, GT_SCS0_High_Decode },
906 1.21.2.1 uebayasi { MARVELL_TAG_SDRAM_CS1, MARVELL_ATTR_SDRAM_CS1,
907 1.21.2.1 uebayasi GT_SCS1_Low_Decode, GT_SCS1_High_Decode },
908 1.21.2.1 uebayasi { MARVELL_TAG_SDRAM_CS2, MARVELL_ATTR_SDRAM_CS2,
909 1.21.2.1 uebayasi GT_SCS2_Low_Decode, GT_SCS2_High_Decode },
910 1.21.2.1 uebayasi { MARVELL_TAG_SDRAM_CS3, MARVELL_ATTR_SDRAM_CS3,
911 1.21.2.1 uebayasi GT_SCS3_Low_Decode, GT_SCS3_High_Decode },
912 1.21.2.1 uebayasi
913 1.21.2.1 uebayasi { MARVELL_TAG_UNDEFINED, 0, 0 }
914 1.21.2.1 uebayasi };
915 1.21.2.1 uebayasi struct gt_softc *sc = device_private(dev);
916 1.21.2.1 uebayasi int i;
917 1.1 matt
918 1.21.2.1 uebayasi for (i = 0; tagtbl[i].tag != MARVELL_TAG_UNDEFINED; i++)
919 1.21.2.1 uebayasi if (tag == tagtbl[i].tag)
920 1.21.2.1 uebayasi break;
921 1.21.2.1 uebayasi if (tagtbl[i].tag == MARVELL_TAG_UNDEFINED)
922 1.21.2.1 uebayasi return -1;
923 1.1 matt
924 1.21.2.1 uebayasi if (target != NULL)
925 1.21.2.1 uebayasi *target = 0;
926 1.21.2.1 uebayasi if (attr != NULL)
927 1.21.2.1 uebayasi *attr = tagtbl[i].attribute;
928 1.21.2.1 uebayasi if (base != NULL)
929 1.21.2.1 uebayasi *base = gt_read(sc, tagtbl[i].basereg) <<
930 1.21.2.1 uebayasi (sc->sc_model == MARVELL_DISCOVERY ? 20 : 16);
931 1.21.2.1 uebayasi if (size != NULL) {
932 1.21.2.1 uebayasi const uint32_t s = gt_read(sc, tagtbl[i].sizereg);
933 1.21.2.1 uebayasi
934 1.21.2.1 uebayasi if (s != 0)
935 1.21.2.1 uebayasi *size = (s + 1) <<
936 1.21.2.1 uebayasi (sc->sc_model == MARVELL_DISCOVERY ? 20 : 16);
937 1.21.2.1 uebayasi else
938 1.21.2.1 uebayasi *size = 0;
939 1.1 matt }
940 1.1 matt
941 1.21.2.1 uebayasi return 0;
942 1.6 matt }
943