1 /* $NetBSD: siop_sgc.c,v 1.4 2009/05/15 17:55:44 tsutsui Exp $ */
3 /* $OpenBSD: siop_sgc.c,v 1.1 2007/08/05 19:09:52 kettenis Exp $ */
6 * Copyright (c) 2007 Mark Kettenis
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 #include <sys/cdefs.h>
22 __KERNEL_RCSID(0, "$NetBSD: siop_sgc.c,v 1.4 2009/05/15 17:55:44 tsutsui Exp $");
24 #include <sys/param.h>
25 #include <sys/device.h>
26 #include <sys/systm.h>
28 #include <uvm/uvm_extern.h>
30 #include <machine/autoconf.h>
31 #include <machine/bus.h>
32 #include <machine/iomod.h>
34 #include <dev/scsipi/scsi_all.h>
35 #include <dev/scsipi/scsipi_all.h>
36 #include <dev/scsipi/scsiconf.h>
38 #include <dev/ic/siopreg.h>
39 #include <dev/ic/siopvar_common.h>
40 #include <dev/ic/siopvar.h>
42 #include <hp700/dev/cpudevs.h>
43 #include <hp700/hp700/intr.h>
45 #define IO_II_INTEN 0x20000000
46 #define IO_II_PACKEN 0x10000000
47 #define IO_II_PREFETCHEN 0x08000000
49 int siop_sgc_match(device_t
, cfdata_t
, void *);
50 void siop_sgc_attach(device_t
, device_t
, void *);
51 int siop_sgc_intr(void *);
52 void siop_sgc_reset(struct siop_common_softc
*);
54 uint8_t siop_sgc_r1(void *, bus_space_handle_t
, bus_size_t
);
55 uint16_t siop_sgc_r2(void *, bus_space_handle_t
, bus_size_t
);
56 void siop_sgc_w1(void *, bus_space_handle_t
, bus_size_t
, uint8_t);
57 void siop_sgc_w2(void *, bus_space_handle_t
, bus_size_t
, uint16_t);
59 struct siop_sgc_softc
{
60 struct siop_softc sc_siop
;
61 bus_space_tag_t sc_iot
;
62 bus_space_handle_t sc_ioh
;
63 struct hppa_bus_space_tag sc_bustag
;
66 CFATTACH_DECL_NEW(siop_gedoens
, sizeof(struct siop_sgc_softc
),
67 siop_sgc_match
, siop_sgc_attach
, NULL
, NULL
);
70 siop_sgc_match(device_t parent
, cfdata_t match
, void *aux
)
72 struct confargs
*ca
= aux
;
74 if (ca
->ca_type
.iodc_type
!= HPPA_TYPE_ADMA
||
75 ca
->ca_type
.iodc_sv_model
!= HPPA_ADMA_FWSCSI
)
78 /* Make sure we have an IRQ. */
79 if (ca
->ca_irq
== HP700CF_IRQ_UNDEF
)
80 ca
->ca_irq
= hp700_intr_allocate_bit(&int_reg_cpu
);
86 siop_sgc_attach(device_t parent
, device_t self
, void *aux
)
88 struct siop_sgc_softc
*sgc
= device_private(self
);
89 struct siop_softc
*sc
= &sgc
->sc_siop
;
90 struct confargs
*ca
= aux
;
91 volatile struct iomod
*regs
;
93 sc
->sc_c
.sc_dev
= self
;
94 sgc
->sc_iot
= ca
->ca_iot
;
95 if (bus_space_map(sgc
->sc_iot
, ca
->ca_hpa
,
96 IOMOD_HPASIZE
, 0, &sgc
->sc_ioh
)) {
97 aprint_error(": can't map io space\n");
101 sgc
->sc_bustag
= *sgc
->sc_iot
;
102 sgc
->sc_bustag
.hbt_r1
= siop_sgc_r1
;
103 sgc
->sc_bustag
.hbt_r2
= siop_sgc_r2
;
104 sgc
->sc_bustag
.hbt_w1
= siop_sgc_w1
;
105 sgc
->sc_bustag
.hbt_w2
= siop_sgc_w2
;
107 sc
->sc_c
.features
= SF_CHIP_PF
| SF_CHIP_BE
| SF_BUS_WIDE
;
108 sc
->sc_c
.maxburst
= 4;
110 sc
->sc_c
.clock_div
= 3;
111 sc
->sc_c
.clock_period
= 250;
112 sc
->sc_c
.ram_size
= 0;
114 sc
->sc_c
.sc_reset
= siop_sgc_reset
;
115 sc
->sc_c
.sc_dmat
= ca
->ca_dmatag
;
117 sc
->sc_c
.sc_rt
= &sgc
->sc_bustag
;
118 bus_space_subregion(sgc
->sc_iot
, sgc
->sc_ioh
, IOMOD_DEVOFFSET
,
119 IOMOD_HPASIZE
- IOMOD_DEVOFFSET
, &sc
->sc_c
.sc_rh
);
121 regs
= bus_space_vaddr(sgc
->sc_iot
, sgc
->sc_ioh
);
122 regs
->io_command
= CMD_RESET
;
123 while ((regs
->io_status
& IO_ERR_MEM_RY
) == 0)
125 regs
->io_ii_rw
= IO_II_PACKEN
| IO_II_PREFETCHEN
;
127 siop_sgc_reset(&sc
->sc_c
);
129 regs
->io_eim
= cpu_gethpa(0) | (31 - ca
->ca_irq
);
130 regs
->io_ii_rw
|= IO_II_INTEN
;
132 aprint_normal(": NCR53C720 rev %d\n", bus_space_read_1(sc
->sc_c
.sc_rt
,
133 sc
->sc_c
.sc_rh
, SIOP_CTEST3
) >> 4);
135 siop_attach(&sgc
->sc_siop
);
137 (void)hp700_intr_establish(self
, IPL_BIO
,
138 siop_intr
, sc
, &int_reg_cpu
, ca
->ca_irq
);
142 siop_sgc_reset(struct siop_common_softc
*sc
)
144 bus_space_write_1(sc
->sc_rt
, sc
->sc_rh
, SIOP_DCNTL
, DCNTL_EA
);
145 bus_space_write_1(sc
->sc_rt
, sc
->sc_rh
, SIOP_CTEST0
, CTEST0_EHP
);
146 bus_space_write_1(sc
->sc_rt
, sc
->sc_rh
, SIOP_CTEST4
, CTEST4_MUX
);
148 bus_space_write_1(sc
->sc_rt
, sc
->sc_rh
, SIOP_STIME0
,
149 (0xc << STIME0_SEL_SHIFT
));
153 siop_sgc_r1(void *v
, bus_space_handle_t h
, bus_size_t o
)
155 return *(volatile uint8_t *)(h
+ (o
^ 3));
159 siop_sgc_r2(void *v
, bus_space_handle_t h
, bus_size_t o
)
161 if (o
== SIOP_SIST0
) {
164 reg
= siop_sgc_r1(v
, h
, SIOP_SIST0
);
165 reg
|= siop_sgc_r1(v
, h
, SIOP_SIST1
) << 8;
168 return *(volatile uint16_t *)(h
+ (o
^ 2));
172 siop_sgc_w1(void *v
, bus_space_handle_t h
, bus_size_t o
, uint8_t vv
)
174 *(volatile uint8_t *)(h
+ (o
^ 3)) = vv
;
178 siop_sgc_w2(void *v
, bus_space_handle_t h
, bus_size_t o
, uint16_t vv
)
180 *(volatile uint16_t *)(h
+ (o
^ 2)) = vv
;