1 1.1 skrll /* $NetBSD: siop_sgc.c,v 1.1 2014/02/24 07:23:42 skrll Exp $ */ 2 1.1 skrll 3 1.1 skrll /* $OpenBSD: siop_sgc.c,v 1.1 2007/08/05 19:09:52 kettenis Exp $ */ 4 1.1 skrll 5 1.1 skrll /* 6 1.1 skrll * Copyright (c) 2007 Mark Kettenis 7 1.1 skrll * 8 1.1 skrll * Permission to use, copy, modify, and distribute this software for any 9 1.1 skrll * purpose with or without fee is hereby granted, provided that the above 10 1.1 skrll * copyright notice and this permission notice appear in all copies. 11 1.1 skrll * 12 1.1 skrll * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 1.1 skrll * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 1.1 skrll * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 1.1 skrll * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 1.1 skrll * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 1.1 skrll * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 1.1 skrll * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 1.1 skrll */ 20 1.1 skrll 21 1.1 skrll #include <sys/cdefs.h> 22 1.1 skrll __KERNEL_RCSID(0, "$NetBSD: siop_sgc.c,v 1.1 2014/02/24 07:23:42 skrll Exp $"); 23 1.1 skrll 24 1.1 skrll #include <sys/param.h> 25 1.1 skrll #include <sys/device.h> 26 1.1 skrll #include <sys/systm.h> 27 1.1 skrll 28 1.1 skrll #include <uvm/uvm_extern.h> 29 1.1 skrll 30 1.1 skrll #include <machine/autoconf.h> 31 1.1 skrll #include <sys/bus.h> 32 1.1 skrll #include <machine/iomod.h> 33 1.1 skrll 34 1.1 skrll #include <dev/scsipi/scsi_all.h> 35 1.1 skrll #include <dev/scsipi/scsipi_all.h> 36 1.1 skrll #include <dev/scsipi/scsiconf.h> 37 1.1 skrll 38 1.1 skrll #include <dev/ic/siopreg.h> 39 1.1 skrll #include <dev/ic/siopvar_common.h> 40 1.1 skrll #include <dev/ic/siopvar.h> 41 1.1 skrll 42 1.1 skrll #include <hppa/dev/cpudevs.h> 43 1.1 skrll 44 1.1 skrll #define IO_II_INTEN 0x20000000 45 1.1 skrll #define IO_II_PACKEN 0x10000000 46 1.1 skrll #define IO_II_PREFETCHEN 0x08000000 47 1.1 skrll 48 1.1 skrll int siop_sgc_match(device_t, cfdata_t, void *); 49 1.1 skrll void siop_sgc_attach(device_t, device_t, void *); 50 1.1 skrll int siop_sgc_intr(void *); 51 1.1 skrll void siop_sgc_reset(struct siop_common_softc *); 52 1.1 skrll 53 1.1 skrll uint8_t siop_sgc_r1(void *, bus_space_handle_t, bus_size_t); 54 1.1 skrll uint16_t siop_sgc_r2(void *, bus_space_handle_t, bus_size_t); 55 1.1 skrll void siop_sgc_w1(void *, bus_space_handle_t, bus_size_t, uint8_t); 56 1.1 skrll void siop_sgc_w2(void *, bus_space_handle_t, bus_size_t, uint16_t); 57 1.1 skrll 58 1.1 skrll struct siop_sgc_softc { 59 1.1 skrll struct siop_softc sc_siop; 60 1.1 skrll bus_space_tag_t sc_iot; 61 1.1 skrll bus_space_handle_t sc_ioh; 62 1.1 skrll struct hppa_bus_space_tag sc_bustag; 63 1.1 skrll }; 64 1.1 skrll 65 1.1 skrll CFATTACH_DECL_NEW(siop_gedoens, sizeof(struct siop_sgc_softc), 66 1.1 skrll siop_sgc_match, siop_sgc_attach, NULL, NULL); 67 1.1 skrll 68 1.1 skrll int 69 1.1 skrll siop_sgc_match(device_t parent, cfdata_t match, void *aux) 70 1.1 skrll { 71 1.1 skrll struct confargs *ca = aux; 72 1.1 skrll 73 1.1 skrll if (ca->ca_type.iodc_type != HPPA_TYPE_ADMA || 74 1.1 skrll ca->ca_type.iodc_sv_model != HPPA_ADMA_FWSCSI) 75 1.1 skrll return 0; 76 1.1 skrll 77 1.1 skrll return 1; 78 1.1 skrll } 79 1.1 skrll 80 1.1 skrll void 81 1.1 skrll siop_sgc_attach(device_t parent, device_t self, void *aux) 82 1.1 skrll { 83 1.1 skrll struct siop_sgc_softc *sgc = device_private(self); 84 1.1 skrll struct siop_softc *sc = &sgc->sc_siop; 85 1.1 skrll struct confargs *ca = aux; 86 1.1 skrll struct cpu_info *ci = &cpus[0]; 87 1.1 skrll volatile struct iomod *regs; 88 1.1 skrll 89 1.1 skrll sc->sc_c.sc_dev = self; 90 1.1 skrll sgc->sc_iot = ca->ca_iot; 91 1.1 skrll if (bus_space_map(sgc->sc_iot, ca->ca_hpa, 92 1.1 skrll IOMOD_HPASIZE, 0, &sgc->sc_ioh)) { 93 1.1 skrll aprint_error(": can't map io space\n"); 94 1.1 skrll return; 95 1.1 skrll } 96 1.1 skrll 97 1.1 skrll ca->ca_irq = hppa_intr_allocate_bit(&ci->ci_ir, ca->ca_irq); 98 1.1 skrll if (ca->ca_irq == HPPACF_IRQ_UNDEF) { 99 1.1 skrll aprint_error(": can't allocate interrupt\n"); 100 1.1 skrll return; 101 1.1 skrll } 102 1.1 skrll 103 1.1 skrll sgc->sc_bustag = *sgc->sc_iot; 104 1.1 skrll sgc->sc_bustag.hbt_r1 = siop_sgc_r1; 105 1.1 skrll sgc->sc_bustag.hbt_r2 = siop_sgc_r2; 106 1.1 skrll sgc->sc_bustag.hbt_w1 = siop_sgc_w1; 107 1.1 skrll sgc->sc_bustag.hbt_w2 = siop_sgc_w2; 108 1.1 skrll 109 1.1 skrll sc->sc_c.features = SF_CHIP_PF | SF_CHIP_BE | SF_BUS_WIDE; 110 1.1 skrll sc->sc_c.maxburst = 4; 111 1.1 skrll sc->sc_c.maxoff = 8; 112 1.1 skrll sc->sc_c.clock_div = 3; 113 1.1 skrll sc->sc_c.clock_period = 250; 114 1.1 skrll sc->sc_c.ram_size = 0; 115 1.1 skrll 116 1.1 skrll sc->sc_c.sc_reset = siop_sgc_reset; 117 1.1 skrll sc->sc_c.sc_dmat = ca->ca_dmatag; 118 1.1 skrll 119 1.1 skrll sc->sc_c.sc_rt = &sgc->sc_bustag; 120 1.1 skrll bus_space_subregion(sgc->sc_iot, sgc->sc_ioh, IOMOD_DEVOFFSET, 121 1.1 skrll IOMOD_HPASIZE - IOMOD_DEVOFFSET, &sc->sc_c.sc_rh); 122 1.1 skrll 123 1.1 skrll regs = bus_space_vaddr(sgc->sc_iot, sgc->sc_ioh); 124 1.1 skrll regs->io_command = CMD_RESET; 125 1.1 skrll while ((regs->io_status & IO_ERR_MEM_RY) == 0) 126 1.1 skrll delay(100); 127 1.1 skrll regs->io_ii_rw = IO_II_PACKEN | IO_II_PREFETCHEN; 128 1.1 skrll 129 1.1 skrll siop_sgc_reset(&sc->sc_c); 130 1.1 skrll 131 1.1 skrll regs->io_eim = ci->ci_hpa | (31 - ca->ca_irq); 132 1.1 skrll regs->io_ii_rw |= IO_II_INTEN; 133 1.1 skrll 134 1.1 skrll aprint_normal(": NCR53C720 rev %d\n", bus_space_read_1(sc->sc_c.sc_rt, 135 1.1 skrll sc->sc_c.sc_rh, SIOP_CTEST3) >> 4); 136 1.1 skrll 137 1.1 skrll siop_attach(&sgc->sc_siop); 138 1.1 skrll 139 1.1 skrll (void)hppa_intr_establish(IPL_BIO, siop_intr, sc, &ci->ci_ir, 140 1.1 skrll ca->ca_irq); 141 1.1 skrll } 142 1.1 skrll 143 1.1 skrll void 144 1.1 skrll siop_sgc_reset(struct siop_common_softc *sc) 145 1.1 skrll { 146 1.1 skrll bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_DCNTL, DCNTL_EA); 147 1.1 skrll bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST0, CTEST0_EHP); 148 1.1 skrll bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_CTEST4, CTEST4_MUX); 149 1.1 skrll 150 1.1 skrll bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_STIME0, 151 1.1 skrll (0xc << STIME0_SEL_SHIFT)); 152 1.1 skrll } 153 1.1 skrll 154 1.1 skrll uint8_t 155 1.1 skrll siop_sgc_r1(void *v, bus_space_handle_t h, bus_size_t o) 156 1.1 skrll { 157 1.1 skrll return *(volatile uint8_t *)(h + (o ^ 3)); 158 1.1 skrll } 159 1.1 skrll 160 1.1 skrll uint16_t 161 1.1 skrll siop_sgc_r2(void *v, bus_space_handle_t h, bus_size_t o) 162 1.1 skrll { 163 1.1 skrll if (o == SIOP_SIST0) { 164 1.1 skrll uint16_t reg; 165 1.1 skrll 166 1.1 skrll reg = siop_sgc_r1(v, h, SIOP_SIST0); 167 1.1 skrll reg |= siop_sgc_r1(v, h, SIOP_SIST1) << 8; 168 1.1 skrll return reg; 169 1.1 skrll } 170 1.1 skrll return *(volatile uint16_t *)(h + (o ^ 2)); 171 1.1 skrll } 172 1.1 skrll 173 1.1 skrll void 174 1.1 skrll siop_sgc_w1(void *v, bus_space_handle_t h, bus_size_t o, uint8_t vv) 175 1.1 skrll { 176 1.1 skrll *(volatile uint8_t *)(h + (o ^ 3)) = vv; 177 1.1 skrll } 178 1.1 skrll 179 1.1 skrll void 180 1.1 skrll siop_sgc_w2(void *v, bus_space_handle_t h, bus_size_t o, uint16_t vv) 181 1.1 skrll { 182 1.1 skrll *(volatile uint16_t *)(h + (o ^ 2)) = vv; 183 1.1 skrll } 184