| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: hpc.c,v 1.64 2011/01/25 12:21:04 tsutsui Exp $ */ | | 1 | /* $NetBSD: hpc.c,v 1.65 2011/01/25 13:22:05 tsutsui Exp $ */ |
2 | | | 2 | |
3 | /* | | 3 | /* |
4 | * Copyright (c) 2000 Soren S. Jorvang | | 4 | * Copyright (c) 2000 Soren S. Jorvang |
5 | * Copyright (c) 2001 Rafal K. Boni | | 5 | * Copyright (c) 2001 Rafal K. Boni |
6 | * Copyright (c) 2001 Jason R. Thorpe | | 6 | * Copyright (c) 2001 Jason R. Thorpe |
7 | * All rights reserved. | | 7 | * All rights reserved. |
8 | * | | 8 | * |
9 | * Redistribution and use in source and binary forms, with or without | | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | | 10 | * modification, are permitted provided that the following conditions |
11 | * are met: | | 11 | * are met: |
12 | * 1. Redistributions of source code must retain the above copyright | | 12 | * 1. Redistributions of source code must retain the above copyright |
13 | * notice, this list of conditions and the following disclaimer. | | 13 | * notice, this list of conditions and the following disclaimer. |
14 | * 2. Redistributions in binary form must reproduce the above copyright | | 14 | * 2. Redistributions in binary form must reproduce the above copyright |
| @@ -25,27 +25,27 @@ | | | @@ -25,27 +25,27 @@ |
25 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | | 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 | | 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
27 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | | 27 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
28 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | | 28 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
29 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | | 29 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
30 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | | 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 | | 31 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
32 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | | 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 | | 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. | | 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | */ | | 35 | */ |
36 | | | 36 | |
37 | #include <sys/cdefs.h> | | 37 | #include <sys/cdefs.h> |
38 | __KERNEL_RCSID(0, "$NetBSD: hpc.c,v 1.64 2011/01/25 12:21:04 tsutsui Exp $"); | | 38 | __KERNEL_RCSID(0, "$NetBSD: hpc.c,v 1.65 2011/01/25 13:22:05 tsutsui Exp $"); |
39 | | | 39 | |
40 | #include <sys/param.h> | | 40 | #include <sys/param.h> |
41 | #include <sys/systm.h> | | 41 | #include <sys/systm.h> |
42 | #include <sys/kernel.h> | | 42 | #include <sys/kernel.h> |
43 | #include <sys/device.h> | | 43 | #include <sys/device.h> |
44 | #include <sys/reboot.h> | | 44 | #include <sys/reboot.h> |
45 | #include <sys/callout.h> | | 45 | #include <sys/callout.h> |
46 | | | 46 | |
47 | #define _SGIMIPS_BUS_DMA_PRIVATE | | 47 | #define _SGIMIPS_BUS_DMA_PRIVATE |
48 | #include <machine/bus.h> | | 48 | #include <machine/bus.h> |
49 | #include <machine/machtype.h> | | 49 | #include <machine/machtype.h> |
50 | #include <machine/sysconf.h> | | 50 | #include <machine/sysconf.h> |
51 | | | 51 | |
| @@ -207,27 +207,27 @@ static const struct hpc_device hpc3_devi | | | @@ -207,27 +207,27 @@ static const struct hpc_device hpc3_devi |
207 | HPC3_PBUS_CH6_DEVREGS + IOC_PANEL, 0, | | 207 | HPC3_PBUS_CH6_DEVREGS + IOC_PANEL, 0, |
208 | 9, | | 208 | 9, |
209 | HPCDEV_IP24 }, | | 209 | HPCDEV_IP24 }, |
210 | | | 210 | |
211 | { NULL, | | 211 | { NULL, |
212 | 0, | | 212 | 0, |
213 | 0, 0, | | 213 | 0, 0, |
214 | 0, | | 214 | 0, |
215 | 0 | | 215 | 0 |
216 | } | | 216 | } |
217 | }; | | 217 | }; |
218 | | | 218 | |
219 | struct hpc_softc { | | 219 | struct hpc_softc { |
220 | struct device sc_dev; | | 220 | device_t sc_dev; |
221 | | | 221 | |
222 | bus_addr_t sc_base; | | 222 | bus_addr_t sc_base; |
223 | | | 223 | |
224 | bus_space_tag_t sc_ct; | | 224 | bus_space_tag_t sc_ct; |
225 | bus_space_handle_t sc_ch; | | 225 | bus_space_handle_t sc_ch; |
226 | }; | | 226 | }; |
227 | | | 227 | |
228 | static struct hpc_values hpc1_values = { | | 228 | static struct hpc_values hpc1_values = { |
229 | .revision = 1, | | 229 | .revision = 1, |
230 | .scsi0_regs = HPC1_SCSI0_REGS, | | 230 | .scsi0_regs = HPC1_SCSI0_REGS, |
231 | .scsi0_regs_size = HPC1_SCSI0_REGS_SIZE, | | 231 | .scsi0_regs_size = HPC1_SCSI0_REGS_SIZE, |
232 | .scsi0_cbp = HPC1_SCSI0_CBP, | | 232 | .scsi0_cbp = HPC1_SCSI0_CBP, |
233 | .scsi0_ndbp = HPC1_SCSI0_NDBP, | | 233 | .scsi0_ndbp = HPC1_SCSI0_NDBP, |
| @@ -341,76 +341,77 @@ static struct hpc_values hpc3_values = { | | | @@ -341,76 +341,77 @@ static struct hpc_values hpc3_values = { |
341 | .scsi_max_xfer = MAX_SCSI_XFER, | | 341 | .scsi_max_xfer = MAX_SCSI_XFER, |
342 | .scsi_dma_segs = (MAX_SCSI_XFER / 8192), | | 342 | .scsi_dma_segs = (MAX_SCSI_XFER / 8192), |
343 | .scsi_dma_segs_size = 8192, | | 343 | .scsi_dma_segs_size = 8192, |
344 | .scsi_dma_datain_cmd = HPC3_SCSI_DMACTL_ACTIVE, | | 344 | .scsi_dma_datain_cmd = HPC3_SCSI_DMACTL_ACTIVE, |
345 | .scsi_dma_dataout_cmd =(HPC3_SCSI_DMACTL_ACTIVE | HPC3_SCSI_DMACTL_DIR), | | 345 | .scsi_dma_dataout_cmd =(HPC3_SCSI_DMACTL_ACTIVE | HPC3_SCSI_DMACTL_DIR), |
346 | .scsi_dmactl_flush = HPC3_SCSI_DMACTL_FLUSH, | | 346 | .scsi_dmactl_flush = HPC3_SCSI_DMACTL_FLUSH, |
347 | .scsi_dmactl_active = HPC3_SCSI_DMACTL_ACTIVE, | | 347 | .scsi_dmactl_active = HPC3_SCSI_DMACTL_ACTIVE, |
348 | .scsi_dmactl_reset = HPC3_SCSI_DMACTL_RESET | | 348 | .scsi_dmactl_reset = HPC3_SCSI_DMACTL_RESET |
349 | }; | | 349 | }; |
350 | | | 350 | |
351 | | | 351 | |
352 | static int powerintr_established; | | 352 | static int powerintr_established; |
353 | | | 353 | |
354 | static int hpc_match(struct device *, struct cfdata *, void *); | | 354 | static int hpc_match(device_t, cfdata_t, void *); |
355 | static void hpc_attach(struct device *, struct device *, void *); | | 355 | static void hpc_attach(device_t, device_t, void *); |
356 | static int hpc_print(void *, const char *); | | 356 | static int hpc_print(void *, const char *); |
357 | | | 357 | |
358 | static int hpc_revision(struct hpc_softc *, struct gio_attach_args *); | | 358 | static int hpc_revision(struct hpc_softc *, struct gio_attach_args *); |
359 | | | 359 | |
360 | static int hpc_submatch(struct device *, struct cfdata *, | | 360 | static int hpc_submatch(device_t, cfdata_t, const int *, void *); |
361 | const int *, void *); | | | |
362 | | | 361 | |
363 | //static int hpc_power_intr(void *); | | 362 | //static int hpc_power_intr(void *); |
364 | | | 363 | |
365 | #if defined(BLINK) | | 364 | #if defined(BLINK) |
366 | static callout_t hpc_blink_ch; | | 365 | static callout_t hpc_blink_ch; |
367 | static void hpc_blink(void *); | | 366 | static void hpc_blink(void *); |
368 | #endif | | 367 | #endif |
369 | | | 368 | |
370 | static int hpc_read_eeprom(int, bus_space_tag_t, bus_space_handle_t, | | 369 | static int hpc_read_eeprom(int, bus_space_tag_t, bus_space_handle_t, |
371 | uint8_t *, size_t); | | 370 | uint8_t *, size_t); |
372 | | | 371 | |
373 | CFATTACH_DECL(hpc, sizeof(struct hpc_softc), | | 372 | CFATTACH_DECL_NEW(hpc, sizeof(struct hpc_softc), |
374 | hpc_match, hpc_attach, NULL, NULL); | | 373 | hpc_match, hpc_attach, NULL, NULL); |
375 | | | 374 | |
376 | static int | | 375 | static int |
377 | hpc_match(struct device *parent, struct cfdata *cf, void *aux) | | 376 | hpc_match(device_t parent, cfdata_t cf, void *aux) |
378 | { | | 377 | { |
379 | struct gio_attach_args* ga = aux; | | 378 | struct gio_attach_args* ga = aux; |
380 | | | 379 | |
381 | if (mach_type == MACH_SGI_IP12 || mach_type == MACH_SGI_IP20 || | | 380 | if (mach_type == MACH_SGI_IP12 || mach_type == MACH_SGI_IP20 || |
382 | mach_type == MACH_SGI_IP22) { | | 381 | mach_type == MACH_SGI_IP22) { |
383 | /* Make sure it's actually there and readable */ | | 382 | /* Make sure it's actually there and readable */ |
384 | if (!platform.badaddr((void*)MIPS_PHYS_TO_KSEG1(ga->ga_addr), | | 383 | if (!platform.badaddr((void*)MIPS_PHYS_TO_KSEG1(ga->ga_addr), |
385 | sizeof(uint32_t))) | | 384 | sizeof(uint32_t))) |
386 | return 1; | | 385 | return 1; |
387 | } | | 386 | } |
388 | | | 387 | |
389 | return 0; | | 388 | return 0; |
390 | } | | 389 | } |
391 | | | 390 | |
392 | static void | | 391 | static void |
393 | hpc_attach(struct device *parent, struct device *self, void *aux) | | 392 | hpc_attach(device_t parent, device_t self, void *aux) |
394 | { | | 393 | { |
395 | struct hpc_softc *sc = (struct hpc_softc *)self; | | 394 | struct hpc_softc *sc = device_private(self); |
396 | struct gio_attach_args* ga = aux; | | 395 | struct gio_attach_args* ga = aux; |
397 | struct hpc_attach_args ha; | | 396 | struct hpc_attach_args ha; |
398 | const struct hpc_device *hd; | | 397 | const struct hpc_device *hd; |
399 | uint32_t hpctype; | | 398 | uint32_t hpctype; |
400 | int isonboard; | | 399 | int isonboard; |
401 | int isioplus; | | 400 | int isioplus; |
402 | int sysmask; | | 401 | int sysmask; |
403 | | | 402 | |
| | | 403 | sc->sc_dev = self; |
| | | 404 | |
404 | #ifdef BLINK | | 405 | #ifdef BLINK |
405 | callout_init(&hpc_blink_ch, 0); | | 406 | callout_init(&hpc_blink_ch, 0); |
406 | #endif | | 407 | #endif |
407 | | | 408 | |
408 | switch (mach_type) { | | 409 | switch (mach_type) { |
409 | case MACH_SGI_IP12: | | 410 | case MACH_SGI_IP12: |
410 | sysmask = HPCDEV_IP12; | | 411 | sysmask = HPCDEV_IP12; |
411 | break; | | 412 | break; |
412 | | | 413 | |
413 | case MACH_SGI_IP20: | | 414 | case MACH_SGI_IP20: |
414 | sysmask = HPCDEV_IP20; | | 415 | sysmask = HPCDEV_IP20; |
415 | break; | | 416 | break; |
416 | | | 417 | |
| @@ -457,51 +458,52 @@ hpc_attach(struct device *parent, struct | | | @@ -457,51 +458,52 @@ hpc_attach(struct device *parent, struct |
457 | */ | | 458 | */ |
458 | if (isioplus) { | | 459 | if (isioplus) { |
459 | int arb_slot; | | 460 | int arb_slot; |
460 | | | 461 | |
461 | if (platform.badaddr( | | 462 | if (platform.badaddr( |
462 | (void *)MIPS_PHYS_TO_KSEG1(HPC_BASE_ADDRESS_2), 4)) | | 463 | (void *)MIPS_PHYS_TO_KSEG1(HPC_BASE_ADDRESS_2), 4)) |
463 | arb_slot = GIO_SLOT_EXP1; | | 464 | arb_slot = GIO_SLOT_EXP1; |
464 | else | | 465 | else |
465 | arb_slot = GIO_SLOT_EXP0; | | 466 | arb_slot = GIO_SLOT_EXP0; |
466 | | | 467 | |
467 | if (gio_arb_config(arb_slot, GIO_ARB_LB | GIO_ARB_MST | | | 468 | if (gio_arb_config(arb_slot, GIO_ARB_LB | GIO_ARB_MST | |
468 | GIO_ARB_64BIT | GIO_ARB_HPC2_64BIT)) { | | 469 | GIO_ARB_64BIT | GIO_ARB_HPC2_64BIT)) { |
469 | printf("%s: failed to configure GIO bus arbiter\n", | | 470 | printf("%s: failed to configure GIO bus arbiter\n", |
470 | sc->sc_dev.dv_xname); | | 471 | device_xname(sc->sc_dev)); |
471 | return; | | 472 | return; |
472 | } | | 473 | } |
473 | | | 474 | |
474 | printf("%s: using EXP%d's DMA channel\n", sc->sc_dev.dv_xname, | | 475 | printf("%s: using EXP%d's DMA channel\n", |
| | | 476 | device_xname(sc->sc_dev), |
475 | (arb_slot == GIO_SLOT_EXP0) ? 0 : 1); | | 477 | (arb_slot == GIO_SLOT_EXP0) ? 0 : 1); |
476 | | | 478 | |
477 | bus_space_write_4(ga->ga_iot, ga->ga_ioh, | | 479 | bus_space_write_4(ga->ga_iot, ga->ga_ioh, |
478 | HPC3_PBUS_CFGPIO_REGS, 0x0003ffff); | | 480 | HPC3_PBUS_CFGPIO_REGS, 0x0003ffff); |
479 | | | 481 | |
480 | if (arb_slot == GIO_SLOT_EXP0) | | 482 | if (arb_slot == GIO_SLOT_EXP0) |
481 | bus_space_write_4(ga->ga_iot, ga->ga_ioh, | | 483 | bus_space_write_4(ga->ga_iot, ga->ga_ioh, |
482 | HPC3_PBUS_CH0_DEVREGS, 0x20202020); | | 484 | HPC3_PBUS_CH0_DEVREGS, 0x20202020); |
483 | else | | 485 | else |
484 | bus_space_write_4(ga->ga_iot, ga->ga_ioh, | | 486 | bus_space_write_4(ga->ga_iot, ga->ga_ioh, |
485 | HPC3_PBUS_CH0_DEVREGS, 0x30303030); | | 487 | HPC3_PBUS_CH0_DEVREGS, 0x30303030); |
486 | } else if (!isonboard) { | | 488 | } else if (!isonboard) { |
487 | int arb_slot; | | 489 | int arb_slot; |
488 | | | 490 | |
489 | arb_slot = (ga->ga_addr == HPC_BASE_ADDRESS_1) ? | | 491 | arb_slot = (ga->ga_addr == HPC_BASE_ADDRESS_1) ? |
490 | GIO_SLOT_EXP0 : GIO_SLOT_EXP1; | | 492 | GIO_SLOT_EXP0 : GIO_SLOT_EXP1; |
491 | | | 493 | |
492 | if (gio_arb_config(arb_slot, GIO_ARB_RT | GIO_ARB_MST)) { | | 494 | if (gio_arb_config(arb_slot, GIO_ARB_RT | GIO_ARB_MST)) { |
493 | printf("%s: failed to configure GIO bus arbiter\n", | | 495 | printf("%s: failed to configure GIO bus arbiter\n", |
494 | sc->sc_dev.dv_xname); | | 496 | device_xname(sc->sc_dev)); |
495 | return; | | 497 | return; |
496 | } | | 498 | } |
497 | } | | 499 | } |
498 | | | 500 | |
499 | sc->sc_ct = SGIMIPS_BUS_SPACE_HPC; | | 501 | sc->sc_ct = SGIMIPS_BUS_SPACE_HPC; |
500 | sc->sc_ch = ga->ga_ioh; | | 502 | sc->sc_ch = ga->ga_ioh; |
501 | | | 503 | |
502 | sc->sc_base = ga->ga_addr; | | 504 | sc->sc_base = ga->ga_addr; |
503 | | | 505 | |
504 | hpc_read_eeprom(hpctype, SGIMIPS_BUS_SPACE_HPC, | | 506 | hpc_read_eeprom(hpctype, SGIMIPS_BUS_SPACE_HPC, |
505 | MIPS_PHYS_TO_KSEG1(sc->sc_base), ha.hpc_eeprom, | | 507 | MIPS_PHYS_TO_KSEG1(sc->sc_base), ha.hpc_eeprom, |
506 | sizeof(ha.hpc_eeprom)); | | 508 | sizeof(ha.hpc_eeprom)); |
507 | | | 509 | |
| @@ -671,29 +673,29 @@ hpc_power_intr(void *arg) | | | @@ -671,29 +673,29 @@ hpc_power_intr(void *arg) |
671 | *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd9850)) = pwr_reg; | | 673 | *((volatile uint32_t *)MIPS_PHYS_TO_KSEG1(0x1fbd9850)) = pwr_reg; |
672 | | | 674 | |
673 | printf("hpc_power_intr: panel reg = %08x\n", pwr_reg); | | 675 | printf("hpc_power_intr: panel reg = %08x\n", pwr_reg); |
674 | | | 676 | |
675 | if (pwr_reg & 2) | | 677 | if (pwr_reg & 2) |
676 | cpu_reboot(RB_HALT, NULL); | | 678 | cpu_reboot(RB_HALT, NULL); |
677 | | | 679 | |
678 | return 1; | | 680 | return 1; |
679 | } | | 681 | } |
680 | #endif | | 682 | #endif |
681 | | | 683 | |
682 | #if defined(BLINK) | | 684 | #if defined(BLINK) |
683 | static void | | 685 | static void |
684 | hpc_blink(void *self) | | 686 | hpc_blink(void *arg) |
685 | { | | 687 | { |
686 | struct hpc_softc *sc = (struct hpc_softc *) self; | | 688 | struct hpc_softc *sc = arg; |
687 | register int s; | | 689 | register int s; |
688 | int value; | | 690 | int value; |
689 | | | 691 | |
690 | s = splhigh(); | | 692 | s = splhigh(); |
691 | | | 693 | |
692 | value = *(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(HPC_BASE_ADDRESS_0 + | | 694 | value = *(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(HPC_BASE_ADDRESS_0 + |
693 | HPC1_AUX_REGS); | | 695 | HPC1_AUX_REGS); |
694 | value ^= HPC1_AUX_CONSLED; | | 696 | value ^= HPC1_AUX_CONSLED; |
695 | *(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(HPC_BASE_ADDRESS_0 + | | 697 | *(volatile uint8_t *)MIPS_PHYS_TO_KSEG1(HPC_BASE_ADDRESS_0 + |
696 | HPC1_AUX_REGS) = value; | | 698 | HPC1_AUX_REGS) = value; |
697 | splx(s); | | 699 | splx(s); |
698 | | | 700 | |
699 | /* | | 701 | /* |