1 /* $NetBSD: hpc.c,v 1.73 2021/08/07 16:19:04 thorpej Exp $ */
2
3 /*
4 * Copyright (c) 2000 Soren S. Jorvang
5 * Copyright (c) 2001 Rafal K. Boni
6 * Copyright (c) 2001 Jason R. Thorpe
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed for the
20 * NetBSD Project. See http://www.NetBSD.org/ for
21 * information about NetBSD.
22 * 4. The name of the author may not be used to endorse or promote products
23 * derived from this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
26 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
27 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
28 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
29 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
30 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37 #include <sys/cdefs.h>
38 __KERNEL_RCSID(0, "$NetBSD: hpc.c,v 1.73 2021/08/07 16:19:04 thorpej Exp $");
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/kernel.h>
43 #include <sys/device.h>
44 #include <sys/reboot.h>
45 #include <sys/callout.h>
46
47 #include <sys/bus.h>
48 #include <machine/machtype.h>
49 #include <machine/sysconf.h>
50
51 #include <sgimips/gio/gioreg.h>
52 #include <sgimips/gio/giovar.h>
53
54 #include <sgimips/hpc/hpcvar.h>
55 #include <sgimips/hpc/hpcreg.h>
56 #include <sgimips/ioc/iocreg.h>
57
58 #include <dev/ic/smc93cx6var.h>
59
60 #include "locators.h"
61
62 struct hpc_device {
63 const char *hd_name;
64 bus_addr_t hd_base;
65 bus_addr_t hd_devoff;
66 bus_addr_t hd_dmaoff;
67 int hd_irq;
68 int hd_sysmask;
69 };
70
71 static const struct hpc_device hpc1_devices[] = {
72 /* probe order is important for IP20 zsc */
73
74 { "zsc", /* Personal Iris/Indigo serial 0/1 duart 1 */
75 HPC_BASE_ADDRESS_0,
76 0x0d10, 0,
77 5,
78 HPCDEV_IP12 | HPCDEV_IP20 },
79
80 { "zsc", /* Personal Iris/Indigo kbd/ms duart 0 */
81 HPC_BASE_ADDRESS_0,
82 0x0d00, 0,
83 5,
84 HPCDEV_IP12 | HPCDEV_IP20 },
85
86 { "sq", /* Personal Iris/Indigo onboard ethernet */
87 HPC_BASE_ADDRESS_0,
88 HPC1_ENET_DEVREGS, HPC1_ENET_REGS,
89 3,
90 HPCDEV_IP12 | HPCDEV_IP20 },
91
92 { "sq", /* E++ GIO adapter slot 0 (Indigo) */
93 HPC_BASE_ADDRESS_1,
94 HPC1_ENET_DEVREGS, HPC1_ENET_REGS,
95 6,
96 HPCDEV_IP12 | HPCDEV_IP20 },
97
98 { "sq", /* E++ GIO adapter slot 0 (Indy) */
99 HPC_BASE_ADDRESS_1,
100 HPC1_ENET_DEVREGS, HPC1_ENET_REGS,
101 22,
102 HPCDEV_IP24 },
103
104 { "sq", /* E++ GIO adapter slot 1 (Indigo) */
105 HPC_BASE_ADDRESS_2,
106 HPC1_ENET_DEVREGS, HPC1_ENET_REGS,
107 6,
108 HPCDEV_IP12 | HPCDEV_IP20 },
109
110 { "sq", /* E++ GIO adapter slot 1 (Indy/Challenge S) */
111 HPC_BASE_ADDRESS_2,
112 HPC1_ENET_DEVREGS, HPC1_ENET_REGS,
113 23,
114 HPCDEV_IP24 },
115
116 { "wdsc", /* Personal Iris/Indigo onboard SCSI */
117 HPC_BASE_ADDRESS_0,
118 HPC1_SCSI0_DEVREGS, HPC1_SCSI0_REGS,
119 2, /* XXX 1 = IRQ_LOCAL0 + 2 */
120 HPCDEV_IP12 | HPCDEV_IP20 },
121
122 { "wdsc", /* GIO32 SCSI adapter slot 0 (Indigo) */
123 HPC_BASE_ADDRESS_1,
124 HPC1_SCSI0_DEVREGS, HPC1_SCSI0_REGS,
125 6,
126 HPCDEV_IP12 | HPCDEV_IP20 },
127
128 { "wdsc", /* GIO32 SCSI adapter slot 0 (Indy) */
129 HPC_BASE_ADDRESS_1,
130 HPC1_SCSI0_DEVREGS, HPC1_SCSI0_REGS,
131 22,
132 HPCDEV_IP24 },
133
134 { "wdsc", /* GIO32 SCSI adapter slot 1 (Indigo) */
135 HPC_BASE_ADDRESS_2,
136 HPC1_SCSI0_DEVREGS, HPC1_SCSI0_REGS,
137 6,
138 HPCDEV_IP12 | HPCDEV_IP20 },
139
140 { "wdsc", /* GIO32 SCSI adapter slot 1 (Indy/Challenge S) */
141 HPC_BASE_ADDRESS_2,
142 HPC1_SCSI0_DEVREGS, HPC1_SCSI0_REGS,
143 23,
144 HPCDEV_IP24 },
145
146 { NULL,
147 0,
148 0, 0,
149 0,
150 0
151 }
152 };
153
154 static const struct hpc_device hpc3_devices[] = {
155 { "zsc", /* serial 0/1 duart 0 */
156 HPC_BASE_ADDRESS_0,
157 /* XXX Magic numbers */
158 HPC3_PBUS_CH6_DEVREGS + IOC_SERIAL_REGS, 0,
159 29,
160 HPCDEV_IP22 | HPCDEV_IP24 },
161
162 { "pckbc", /* Indigo2/Indy ps2 keyboard/mouse controller */
163 HPC_BASE_ADDRESS_0,
164 HPC3_PBUS_CH6_DEVREGS + IOC_KB_REGS, 0,
165 28,
166 HPCDEV_IP22 | HPCDEV_IP24 },
167
168 { "sq", /* Indigo2/Indy/Challenge S/Challenge M onboard enet */
169 HPC_BASE_ADDRESS_0,
170 HPC3_ENET_DEVREGS, HPC3_ENET_REGS,
171 3,
172 HPCDEV_IP22 | HPCDEV_IP24 },
173
174 { "sq", /* Challenge S IOPLUS secondary ethernet */
175 HPC_BASE_ADDRESS_1,
176 HPC3_ENET_DEVREGS, HPC3_ENET_REGS,
177 0,
178 HPCDEV_IP24 },
179
180 { "wdsc", /* Indigo2/Indy/Challenge S/Challenge M onboard SCSI */
181 HPC_BASE_ADDRESS_0,
182 HPC3_SCSI0_DEVREGS, HPC3_SCSI0_REGS,
183 1, /* XXX 1 = IRQ_LOCAL0 + 1 */
184 HPCDEV_IP22 | HPCDEV_IP24 },
185
186 { "wdsc", /* Indigo2/Challenge M secondary onboard SCSI */
187 HPC_BASE_ADDRESS_0,
188 HPC3_SCSI1_DEVREGS, HPC3_SCSI1_REGS,
189 2, /* XXX 2 = IRQ_LOCAL0 + 2 */
190 HPCDEV_IP22 },
191
192 { "haltwo", /* Indigo2/Indy onboard audio */
193 HPC_BASE_ADDRESS_0,
194 HPC3_PBUS_CH0_DEVREGS, HPC3_PBUS_DMAREGS,
195 8 + 4, /* XXX IRQ_LOCAL1 + 4 */
196 HPCDEV_IP22 | HPCDEV_IP24 },
197
198 { "pi1ppc", /* Indigo2/Indy/Challenge S/Challenge M onboard pport */
199 HPC_BASE_ADDRESS_0,
200 HPC3_PBUS_CH6_DEVREGS + IOC_PLP_REGS, 0,
201 -1,
202 HPCDEV_IP22 | HPCDEV_IP24 },
203
204 { "button", /* Indy front panel */
205 HPC_BASE_ADDRESS_0,
206 HPC3_PBUS_CH6_DEVREGS + IOC_PANEL, 0,
207 9,
208 HPCDEV_IP24 },
209
210 { NULL,
211 0,
212 0, 0,
213 0,
214 0
215 }
216 };
217
218 struct hpc_softc {
219 device_t sc_dev;
220
221 bus_addr_t sc_base;
222
223 bus_space_tag_t sc_ct;
224 bus_space_handle_t sc_ch;
225 };
226
227 static struct hpc_values hpc1_values = {
228 .revision = 1,
229 .scsi0_regs = HPC1_SCSI0_REGS,
230 .scsi0_regs_size = HPC1_SCSI0_REGS_SIZE,
231 .scsi0_cbp = HPC1_SCSI0_CBP,
232 .scsi0_ndbp = HPC1_SCSI0_NDBP,
233 .scsi0_bc = HPC1_SCSI0_BC,
234 .scsi0_ctl = HPC1_SCSI0_CTL,
235 .scsi0_gio = HPC1_SCSI0_GIO,
236 .scsi0_dev = HPC1_SCSI0_DEV,
237 .scsi0_dmacfg = HPC1_SCSI0_DMACFG,
238 .scsi0_piocfg = HPC1_SCSI0_PIOCFG,
239 .scsi1_regs = 0,
240 .scsi1_regs_size = 0,
241 .scsi1_cbp = 0,
242 .scsi1_ndbp = 0,
243 .scsi1_bc = 0,
244 .scsi1_ctl = 0,
245 .scsi1_gio = 0,
246 .scsi1_dev = 0,
247 .scsi1_dmacfg = 0,
248 .scsi1_piocfg = 0,
249 .enet_regs = HPC1_ENET_REGS,
250 .enet_regs_size = HPC1_ENET_REGS_SIZE,
251 .enet_intdelay = HPC1_ENET_INTDELAY,
252 .enet_intdelayval = HPC1_ENET_INTDELAY_OFF,
253 .enetr_cbp = HPC1_ENETR_CBP,
254 .enetr_ndbp = HPC1_ENETR_NDBP,
255 .enetr_bc = HPC1_ENETR_BC,
256 .enetr_ctl = HPC1_ENETR_CTL,
257 .enetr_ctl_active = HPC1_ENETR_CTL_ACTIVE,
258 .enetr_reset = HPC1_ENETR_RESET,
259 .enetr_dmacfg = 0,
260 .enetr_piocfg = 0,
261 .enetx_cbp = HPC1_ENETX_CBP,
262 .enetx_ndbp = HPC1_ENETX_NDBP,
263 .enetx_bc = HPC1_ENETX_BC,
264 .enetx_ctl = HPC1_ENETX_CTL,
265 .enetx_ctl_active = HPC1_ENETX_CTL_ACTIVE,
266 .enetx_dev = 0,
267 .enetr_fifo = HPC1_ENETR_FIFO,
268 .enetr_fifo_size = HPC1_ENETR_FIFO_SIZE,
269 .enetx_fifo = HPC1_ENETX_FIFO,
270 .enetx_fifo_size = HPC1_ENETX_FIFO_SIZE,
271 .scsi0_devregs_size = HPC1_SCSI0_DEVREGS_SIZE,
272 .scsi1_devregs_size = 0,
273 .enet_devregs = HPC1_ENET_DEVREGS,
274 .enet_devregs_size = HPC1_ENET_DEVREGS_SIZE,
275 .pbus_fifo = 0,
276 .pbus_fifo_size = 0,
277 .pbus_bbram = 0,
278 #define MAX_SCSI_XFER (512*1024)
279 .scsi_max_xfer = MAX_SCSI_XFER,
280 .scsi_dma_segs = (MAX_SCSI_XFER / 4096),
281 .scsi_dma_segs_size = 4096,
282 .scsi_dma_datain_cmd = (HPC1_SCSI_DMACTL_ACTIVE | HPC1_SCSI_DMACTL_DIR),
283 .scsi_dma_dataout_cmd = HPC1_SCSI_DMACTL_ACTIVE,
284 .scsi_dmactl_flush = HPC1_SCSI_DMACTL_FLUSH,
285 .scsi_dmactl_active = HPC1_SCSI_DMACTL_ACTIVE,
286 .scsi_dmactl_reset = HPC1_SCSI_DMACTL_RESET
287 };
288
289 static struct hpc_values hpc3_values = {
290 .revision = 3,
291 .scsi0_regs = HPC3_SCSI0_REGS,
292 .scsi0_regs_size = HPC3_SCSI0_REGS_SIZE,
293 .scsi0_cbp = HPC3_SCSI0_CBP,
294 .scsi0_ndbp = HPC3_SCSI0_NDBP,
295 .scsi0_bc = HPC3_SCSI0_BC,
296 .scsi0_ctl = HPC3_SCSI0_CTL,
297 .scsi0_gio = HPC3_SCSI0_GIO,
298 .scsi0_dev = HPC3_SCSI0_DEV,
299 .scsi0_dmacfg = HPC3_SCSI0_DMACFG,
300 .scsi0_piocfg = HPC3_SCSI0_PIOCFG,
301 .scsi1_regs = HPC3_SCSI1_REGS,
302 .scsi1_regs_size = HPC3_SCSI1_REGS_SIZE,
303 .scsi1_cbp = HPC3_SCSI1_CBP,
304 .scsi1_ndbp = HPC3_SCSI1_NDBP,
305 .scsi1_bc = HPC3_SCSI1_BC,
306 .scsi1_ctl = HPC3_SCSI1_CTL,
307 .scsi1_gio = HPC3_SCSI1_GIO,
308 .scsi1_dev = HPC3_SCSI1_DEV,
309 .scsi1_dmacfg = HPC3_SCSI1_DMACFG,
310 .scsi1_piocfg = HPC3_SCSI1_PIOCFG,
311 .enet_regs = HPC3_ENET_REGS,
312 .enet_regs_size = HPC3_ENET_REGS_SIZE,
313 .enet_intdelay = 0,
314 .enet_intdelayval = 0,
315 .enetr_cbp = HPC3_ENETR_CBP,
316 .enetr_ndbp = HPC3_ENETR_NDBP,
317 .enetr_bc = HPC3_ENETR_BC,
318 .enetr_ctl = HPC3_ENETR_CTL,
319 .enetr_ctl_active = HPC3_ENETR_CTL_ACTIVE,
320 .enetr_reset = HPC3_ENETR_RESET,
321 .enetr_dmacfg = HPC3_ENETR_DMACFG,
322 .enetr_piocfg = HPC3_ENETR_PIOCFG,
323 .enetx_cbp = HPC3_ENETX_CBP,
324 .enetx_ndbp = HPC3_ENETX_NDBP,
325 .enetx_bc = HPC3_ENETX_BC,
326 .enetx_ctl = HPC3_ENETX_CTL,
327 .enetx_ctl_active = HPC3_ENETX_CTL_ACTIVE,
328 .enetx_dev = HPC3_ENETX_DEV,
329 .enetr_fifo = HPC3_ENETR_FIFO,
330 .enetr_fifo_size = HPC3_ENETR_FIFO_SIZE,
331 .enetx_fifo = HPC3_ENETX_FIFO,
332 .enetx_fifo_size = HPC3_ENETX_FIFO_SIZE,
333 .scsi0_devregs_size = HPC3_SCSI0_DEVREGS_SIZE,
334 .scsi1_devregs_size = HPC3_SCSI1_DEVREGS_SIZE,
335 .enet_devregs = HPC3_ENET_DEVREGS,
336 .enet_devregs_size = HPC3_ENET_DEVREGS_SIZE,
337 .pbus_fifo = HPC3_PBUS_FIFO,
338 .pbus_fifo_size = HPC3_PBUS_FIFO_SIZE,
339 .pbus_bbram = HPC3_PBUS_BBRAM,
340 .scsi_max_xfer = MAX_SCSI_XFER,
341 .scsi_dma_segs = (MAX_SCSI_XFER / 8192),
342 .scsi_dma_segs_size = 8192,
343 .scsi_dma_datain_cmd = HPC3_SCSI_DMACTL_ACTIVE,
344 .scsi_dma_dataout_cmd =(HPC3_SCSI_DMACTL_ACTIVE | HPC3_SCSI_DMACTL_DIR),
345 .scsi_dmactl_flush = HPC3_SCSI_DMACTL_FLUSH,
346 .scsi_dmactl_active = HPC3_SCSI_DMACTL_ACTIVE,
347 .scsi_dmactl_reset = HPC3_SCSI_DMACTL_RESET
348 };
349
350 static int hpc_match(device_t, cfdata_t, void *);
351 static void hpc_attach(device_t, device_t, void *);
352 static int hpc_print(void *, const char *);
353
354 static int hpc_revision(struct hpc_softc *, struct gio_attach_args *);
355
356 static int hpc_submatch(device_t, cfdata_t, const int *, void *);
357
358 //static int hpc_power_intr(void *);
359
360 #if defined(BLINK)
361 static callout_t hpc_blink_ch;
362 static void hpc_blink(void *);
363 #endif
364
365 static int hpc_read_eeprom(int, bus_space_tag_t, bus_space_handle_t,
366 uint8_t *, size_t);
367
368 CFATTACH_DECL_NEW(hpc, sizeof(struct hpc_softc),
369 hpc_match, hpc_attach, NULL, NULL);
370
371 static void hpc_bus_mem_init(bus_space_tag_t, void *);
372
373 static struct mips_bus_space hpc_mbst;
374 bus_space_tag_t hpc_memt = NULL;
375
376
377 static int
hpc_match(device_t parent,cfdata_t cf,void * aux)378 hpc_match(device_t parent, cfdata_t cf, void *aux)
379 {
380 struct gio_attach_args* ga = aux;
381
382 if (mach_type == MACH_SGI_IP12 || mach_type == MACH_SGI_IP20 ||
383 mach_type == MACH_SGI_IP22) {
384 /* Make sure it's actually there and readable */
385 if (!platform.badaddr((void*)MIPS_PHYS_TO_KSEG1(ga->ga_addr),
386 sizeof(uint32_t)))
387 return 1;
388 }
389
390 return 0;
391 }
392
393 static void
hpc_attach(device_t parent,device_t self,void * aux)394 hpc_attach(device_t parent, device_t self, void *aux)
395 {
396 struct hpc_softc *sc = device_private(self);
397 struct gio_attach_args* ga = aux;
398 struct hpc_attach_args ha;
399 const struct hpc_device *hd;
400 uint32_t hpctype;
401 int isonboard;
402 int isioplus;
403 int sysmask;
404
405 sc->sc_dev = self;
406
407 #ifdef BLINK
408 callout_init(&hpc_blink_ch, 0);
409 #endif
410
411 switch (mach_type) {
412 case MACH_SGI_IP12:
413 sysmask = HPCDEV_IP12;
414 break;
415
416 case MACH_SGI_IP20:
417 sysmask = HPCDEV_IP20;
418 break;
419
420 case MACH_SGI_IP22:
421 if (mach_subtype == MACH_SGI_IP22_FULLHOUSE)
422 sysmask = HPCDEV_IP22;
423 else
424 sysmask = HPCDEV_IP24;
425 break;
426
427 default:
428 panic("hpc_attach: can't handle HPC on an IP%d", mach_type);
429 };
430
431 if ((hpctype = hpc_revision(sc, ga)) == 0)
432 panic("hpc_attach: could not identify HPC revision\n");
433
434 /* force big-endian mode */
435 if (hpctype == 15)
436 *(uint32_t *)MIPS_PHYS_TO_KSEG1(ga->ga_addr+HPC1_BIGENDIAN) = 0;
437
438 /*
439 * All machines have only one HPC on the mainboard itself. ''Extra''
440 * HPCs require bus arbiter and other magic to run happily.
441 */
442 isonboard = (ga->ga_addr == HPC_BASE_ADDRESS_0);
443 isioplus = (ga->ga_addr == HPC_BASE_ADDRESS_1 && hpctype == 3 &&
444 sysmask == HPCDEV_IP24);
445
446 printf(": SGI HPC%d%s (%s)\n", (hpctype == 3) ? 3 : 1,
447 (hpctype == 15) ? ".5" : "", (isonboard) ? "onboard" :
448 (isioplus) ? "IOPLUS mezzanine" : "GIO slot");
449
450 /*
451 * Configure the bus arbiter appropriately.
452 *
453 * In the case of Challenge S, we must tell the IOPLUS board which
454 * DMA channel to use (we steal it from one of the slots). SGI permits
455 * an HPC1.5 in slot 1, in which case IOPLUS must use EXP0, or any
456 * other DMA-capable board in slot 0, which leaves us to use EXP1. Of
457 * course, this means that only one GIO board may use DMA.
458 *
459 * Note that this never happens on Indigo2.
460 */
461 if (isioplus) {
462 int arb_slot;
463
464 if (platform.badaddr(
465 (void *)MIPS_PHYS_TO_KSEG1(HPC_BASE_ADDRESS_2), 4))
466 arb_slot = GIO_SLOT_EXP1;
467 else
468 arb_slot = GIO_SLOT_EXP0;
469
470 if (gio_arb_config(arb_slot, GIO_ARB_LB | GIO_ARB_MST |
471 GIO_ARB_64BIT | GIO_ARB_HPC2_64BIT)) {
472 printf("%s: failed to configure GIO bus arbiter\n",
473 device_xname(sc->sc_dev));
474 return;
475 }
476
477 printf("%s: using EXP%d's DMA channel\n",
478 device_xname(sc->sc_dev),
479 (arb_slot == GIO_SLOT_EXP0) ? 0 : 1);
480
481 bus_space_write_4(ga->ga_iot, ga->ga_ioh,
482 HPC3_PBUS_CFGPIO_REGS, 0x0003ffff);
483
484 if (arb_slot == GIO_SLOT_EXP0)
485 bus_space_write_4(ga->ga_iot, ga->ga_ioh,
486 HPC3_PBUS_CH0_DEVREGS, 0x20202020);
487 else
488 bus_space_write_4(ga->ga_iot, ga->ga_ioh,
489 HPC3_PBUS_CH0_DEVREGS, 0x30303030);
490 } else if (!isonboard) {
491 int arb_slot;
492
493 arb_slot = (ga->ga_addr == HPC_BASE_ADDRESS_1) ?
494 GIO_SLOT_EXP0 : GIO_SLOT_EXP1;
495
496 if (gio_arb_config(arb_slot, GIO_ARB_RT | GIO_ARB_MST)) {
497 printf("%s: failed to configure GIO bus arbiter\n",
498 device_xname(sc->sc_dev));
499 return;
500 }
501 }
502
503 hpc_bus_mem_init(&hpc_mbst, NULL);
504 hpc_memt = &hpc_mbst;
505
506 sc->sc_ct = normal_memt;
507 sc->sc_ch = ga->ga_ioh;
508
509 sc->sc_base = ga->ga_addr;
510
511 hpc_read_eeprom(hpctype, normal_memt,
512 MIPS_PHYS_TO_KSEG1(sc->sc_base), ha.hpc_eeprom,
513 sizeof(ha.hpc_eeprom));
514
515 hd = (hpctype == 3) ? hpc3_devices : hpc1_devices;
516 for (; hd->hd_name != NULL; hd++) {
517 if (!(hd->hd_sysmask & sysmask) || hd->hd_base != sc->sc_base)
518 continue;
519
520 ha.ha_name = hd->hd_name;
521 ha.ha_devoff = hd->hd_devoff;
522 ha.ha_dmaoff = hd->hd_dmaoff;
523 ha.ha_irq = hd->hd_irq;
524
525 /* XXX This is disgusting. */
526 ha.ha_st = normal_memt;
527 if (bus_space_map(normal_memt, sc->sc_base, 0,
528 BUS_SPACE_MAP_LINEAR, &ha.ha_sh) != 0)
529 continue;
530 ha.ha_dmat = &sgimips_default_bus_dma_tag;
531 if (hpctype == 3)
532 ha.hpc_regs = &hpc3_values;
533 else
534 ha.hpc_regs = &hpc1_values;
535 ha.hpc_regs->revision = hpctype;
536
537 /* XXXgross! avoid complaining in E++ and GIO32 SCSI cases */
538 if (hpctype != 3 && sc->sc_base != HPC_BASE_ADDRESS_0) {
539 config_found(self, &ha, NULL,
540 CFARGS(.submatch = hpc_submatch));
541 } else {
542 config_found(self, &ha, hpc_print,
543 CFARGS(.submatch = hpc_submatch));
544 }
545 }
546
547 #if defined(BLINK)
548 if (mach_type == MACH_SGI_IP12 || mach_type == MACH_SGI_IP20)
549 hpc_blink(sc);
550 #endif
551 }
552
553 /*
554 * HPC revision detection isn't as simple as it should be. Devices probe
555 * differently depending on their slots, but luckily there is only one
556 * instance in which we have to decide the major revision (HPC1 vs HPC3).
557 *
558 * The HPC is found in the following configurations:
559 * o Personal Iris 4D/3x:
560 * One on-board HPC1 or HPC1.5.
561 *
562 * o Indigo R3k/R4k:
563 * One on-board HPC1 or HPC1.5.
564 * Up to two additional HPC1.5's in GIO slots 0 and 1.
565 *
566 * o Indy:
567 * One on-board HPC3.
568 * Up to two additional HPC1.5's in GIO slots 0 and 1.
569 *
570 * o Challenge S
571 * One on-board HPC3.
572 * Up to one additional HPC3 on the IOPLUS board (if installed).
573 * Up to one additional HPC1.5 in slot 1 of the IOPLUS board.
574 *
575 * o Indigo2, Challenge M
576 * One on-board HPC3.
577 *
578 * All we really have to worry about is the IP22 case.
579 */
580 static int
hpc_revision(struct hpc_softc * sc,struct gio_attach_args * ga)581 hpc_revision(struct hpc_softc *sc, struct gio_attach_args *ga)
582 {
583
584 /* No hardware ever supported the last hpc base address. */
585 if (ga->ga_addr == HPC_BASE_ADDRESS_3)
586 return (0);
587
588 if (mach_type == MACH_SGI_IP12 || mach_type == MACH_SGI_IP20) {
589 uint32_t reg;
590
591 if (!platform.badaddr((void *)MIPS_PHYS_TO_KSEG1(ga->ga_addr +
592 HPC1_BIGENDIAN), 4)) {
593 reg = *(uint32_t *)MIPS_PHYS_TO_KSEG1(ga->ga_addr +
594 HPC1_BIGENDIAN);
595
596 if (((reg >> HPC1_REVSHIFT) & HPC1_REVMASK) ==
597 HPC1_REV15)
598 return (15);
599 else
600 return (1);
601 }
602
603 return (1);
604 }
605
606 /*
607 * If IP22, probe slot 0 to determine if HPC1.5 or HPC3. Slot 1 must
608 * be HPC1.5.
609 */
610 if (mach_type == MACH_SGI_IP22) {
611 if (ga->ga_addr == HPC_BASE_ADDRESS_0)
612 return (3);
613
614 if (ga->ga_addr == HPC_BASE_ADDRESS_2)
615 return (15);
616
617 /*
618 * Probe for it. We use one of the PBUS registers. Note
619 * that this probe succeeds with my E++ adapter in slot 1
620 * (bad), but it appears to always do the right thing in
621 * slot 0 (good!) and we're only worried about that one
622 * anyhow.
623 */
624 if (platform.badaddr((void *)MIPS_PHYS_TO_KSEG1(ga->ga_addr +
625 HPC3_PBUS_CH7_BP), 4))
626 return (15);
627 else
628 return (3);
629 }
630
631 return (0);
632 }
633
634 static int
hpc_submatch(device_t parent,cfdata_t cf,const int * ldesc,void * aux)635 hpc_submatch(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
636 {
637 struct hpc_attach_args *ha = aux;
638
639 if (cf->cf_loc[HPCCF_OFFSET] != HPCCF_OFFSET_DEFAULT &&
640 (bus_addr_t) cf->cf_loc[HPCCF_OFFSET] != ha->ha_devoff)
641 return (0);
642
643 return (config_match(parent, cf, aux));
644 }
645
646 static int
hpc_print(void * aux,const char * pnp)647 hpc_print(void *aux, const char *pnp)
648 {
649 struct hpc_attach_args *ha = aux;
650
651 if (pnp)
652 printf("%s at %s", ha->ha_name, pnp);
653
654 printf(" offset %#" PRIxVADDR, (vaddr_t)ha->ha_devoff);
655
656 return (UNCONF);
657 }
658
659 #if defined(BLINK)
660 static void
hpc_blink(void * arg)661 hpc_blink(void *arg)
662 {
663 struct hpc_softc *sc = arg;
664 register int s;
665 int value;
666
667 s = splhigh();
668
669 value = *(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(HPC_BASE_ADDRESS_0 +
670 HPC1_AUX_REGS);
671 value ^= HPC1_AUX_CONSLED;
672 *(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(HPC_BASE_ADDRESS_0 +
673 HPC1_AUX_REGS) = value;
674 splx(s);
675
676 /*
677 * Blink rate is:
678 * full cycle every second if completely idle (loadav = 0)
679 * full cycle every 2 seconds if loadav = 1
680 * full cycle every 3 seconds if loadav = 2
681 * etc.
682 */
683 s = (((averunnable.ldavg[0] + FSCALE) * hz) >> (FSHIFT + 1));
684 callout_reset(&hpc_blink_ch, s, hpc_blink, sc);
685 }
686 #endif
687
688 /*
689 * Read the eeprom associated with one of the HPC's.
690 *
691 * NB: An eeprom is not always present, but the HPC should be able to
692 * handle this gracefully. Any consumers should validate the data to
693 * ensure it's reasonable.
694 */
695 static int
hpc_read_eeprom(int hpctype,bus_space_tag_t t,bus_space_handle_t h,uint8_t * buf,size_t len)696 hpc_read_eeprom(int hpctype, bus_space_tag_t t, bus_space_handle_t h,
697 uint8_t *buf, size_t len)
698 {
699 struct seeprom_descriptor sd;
700 bus_space_handle_t bsh;
701 bus_space_tag_t tag;
702 bus_size_t offset;
703
704 if (!len || len & 0x1)
705 return (1);
706
707 offset = (hpctype == 3) ? HPC3_EEPROM_DATA : HPC1_AUX_REGS;
708
709 tag = normal_memt;
710 if (bus_space_subregion(t, h, offset, 1, &bsh) != 0)
711 return (1);
712
713 sd.sd_chip = C56_66;
714 sd.sd_tag = tag;
715 sd.sd_bsh = bsh;
716 sd.sd_regsize = 1;
717 sd.sd_control_offset = 0;
718 sd.sd_status_offset = 0;
719 sd.sd_dataout_offset = 0;
720 sd.sd_DI = 0x10; /* EEPROM -> CPU */
721 sd.sd_DO = 0x08; /* CPU -> EEPROM */
722 sd.sd_CK = 0x04;
723 sd.sd_CS = 0x02;
724 sd.sd_MS = 0;
725 sd.sd_RDY = 0;
726
727 if (read_seeprom(&sd, (uint16_t *)buf, 0, len / 2) != 1)
728 return (1);
729
730 bus_space_unmap(t, bsh, 1);
731
732 return (0);
733 }
734
735 #define CHIP hpc
736 #define CHIP_MEM /* defined */
737 #define CHIP_ALIGN_STRIDE 2
738 #define CHIP_ACCESS_SIZE 4
739 #define CHIP_W1_BUS_START(v) 0x00000000UL
740 #define CHIP_W1_BUS_END(v) 0xffffffffUL
741 #define CHIP_W1_SYS_START(v) 0x00000000UL
742 #define CHIP_W1_SYS_END(v) 0xffffffffUL
743
744 #include <mips/mips/bus_space_alignstride_chipdep.c>
745