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