1 1.16 thorpej /* $NetBSD: siisata_cardbus.c,v 1.16 2022/09/25 17:33:19 thorpej Exp $ */ 2 1.1 kiyohara /* Id: siisata_pci.c,v 1.11 2008/05/21 16:20:11 jakllsch Exp */ 3 1.1 kiyohara 4 1.1 kiyohara /* 5 1.1 kiyohara * Copyright (c) 2006 Manuel Bouyer. 6 1.1 kiyohara * 7 1.1 kiyohara * Redistribution and use in source and binary forms, with or without 8 1.1 kiyohara * modification, are permitted provided that the following conditions 9 1.1 kiyohara * are met: 10 1.1 kiyohara * 1. Redistributions of source code must retain the above copyright 11 1.1 kiyohara * notice, this list of conditions and the following disclaimer. 12 1.1 kiyohara * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 kiyohara * notice, this list of conditions and the following disclaimer in the 14 1.1 kiyohara * documentation and/or other materials provided with the distribution. 15 1.1 kiyohara * 16 1.1 kiyohara * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 1.1 kiyohara * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 1.1 kiyohara * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 1.1 kiyohara * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 1.1 kiyohara * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 1.1 kiyohara * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 1.1 kiyohara * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 1.1 kiyohara * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 1.1 kiyohara * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 1.1 kiyohara * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 1.1 kiyohara * 27 1.1 kiyohara */ 28 1.1 kiyohara 29 1.4 jakllsch /* 30 1.1 kiyohara * Copyright (c) 2007, 2008 Jonathan A. Kollasch. 31 1.1 kiyohara * All rights reserved. 32 1.1 kiyohara * 33 1.1 kiyohara * Redistribution and use in source and binary forms, with or without 34 1.1 kiyohara * modification, are permitted provided that the following conditions 35 1.1 kiyohara * are met: 36 1.1 kiyohara * 1. Redistributions of source code must retain the above copyright 37 1.1 kiyohara * notice, this list of conditions and the following disclaimer. 38 1.1 kiyohara * 2. Redistributions in binary form must reproduce the above copyright 39 1.1 kiyohara * notice, this list of conditions and the following disclaimer in the 40 1.1 kiyohara * documentation and/or other materials provided with the distribution. 41 1.1 kiyohara * 42 1.1 kiyohara * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 43 1.1 kiyohara * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 44 1.1 kiyohara * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 45 1.1 kiyohara * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 46 1.1 kiyohara * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 47 1.1 kiyohara * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 48 1.1 kiyohara * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 49 1.1 kiyohara * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 50 1.1 kiyohara * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 51 1.1 kiyohara * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 52 1.1 kiyohara */ 53 1.1 kiyohara 54 1.1 kiyohara #include <sys/cdefs.h> 55 1.16 thorpej __KERNEL_RCSID(0, "$NetBSD: siisata_cardbus.c,v 1.16 2022/09/25 17:33:19 thorpej Exp $"); 56 1.1 kiyohara 57 1.1 kiyohara #include <sys/types.h> 58 1.1 kiyohara #include <sys/param.h> 59 1.1 kiyohara #include <sys/kernel.h> 60 1.1 kiyohara #include <sys/systm.h> 61 1.1 kiyohara 62 1.1 kiyohara #include <dev/cardbus/cardbusvar.h> 63 1.1 kiyohara #include <dev/pci/pcidevs.h> 64 1.1 kiyohara #include <dev/ic/siisatavar.h> 65 1.1 kiyohara 66 1.1 kiyohara struct siisata_cardbus_softc { 67 1.1 kiyohara struct siisata_softc si_sc; 68 1.1 kiyohara cardbus_chipset_tag_t sc_cc; 69 1.1 kiyohara cardbus_function_tag_t sc_cf; 70 1.1 kiyohara cardbus_devfunc_t sc_ct; 71 1.7 dyoung pcitag_t sc_tag; 72 1.9 dyoung bus_space_tag_t sc_iot; /* CardBus I/O space tag */ 73 1.9 dyoung bus_space_tag_t sc_memt; /* CardBus MEM space tag */ 74 1.9 dyoung rbus_tag_t sc_rbus_iot; /* CardBus i/o rbus tag */ 75 1.9 dyoung rbus_tag_t sc_rbus_memt; /* CardBus mem rbus tag */ 76 1.1 kiyohara 77 1.1 kiyohara bus_size_t sc_grsize; 78 1.1 kiyohara bus_size_t sc_prsize; 79 1.1 kiyohara void *sc_ih; 80 1.1 kiyohara }; 81 1.1 kiyohara 82 1.1 kiyohara static int siisata_cardbus_match(device_t, cfdata_t, void *); 83 1.1 kiyohara static void siisata_cardbus_attach(device_t, device_t, void *); 84 1.1 kiyohara static int siisata_cardbus_detach(device_t, int); 85 1.5 dyoung static bool siisata_cardbus_resume(device_t, const pmf_qual_t *); 86 1.1 kiyohara 87 1.1 kiyohara static const struct siisata_cardbus_product { 88 1.8 dyoung pci_vendor_id_t scp_vendor; 89 1.8 dyoung pci_product_id_t scp_product; 90 1.1 kiyohara int scp_ports; 91 1.1 kiyohara int scp_chip; 92 1.1 kiyohara 93 1.1 kiyohara } siisata_cardbus_products[] = { 94 1.1 kiyohara { 95 1.1 kiyohara PCI_VENDOR_CMDTECH, PCI_PRODUCT_CMDTECH_3124, 96 1.1 kiyohara 4, 3124 97 1.1 kiyohara }, 98 1.1 kiyohara { 99 1.1 kiyohara 0, 0, 100 1.1 kiyohara 0, 0 101 1.1 kiyohara }, 102 1.1 kiyohara }; 103 1.1 kiyohara 104 1.1 kiyohara CFATTACH_DECL_NEW(siisata_cardbus, sizeof(struct siisata_cardbus_softc), 105 1.1 kiyohara siisata_cardbus_match, siisata_cardbus_attach, siisata_cardbus_detach, 106 1.1 kiyohara NULL); 107 1.1 kiyohara 108 1.1 kiyohara static const struct siisata_cardbus_product * 109 1.1 kiyohara siisata_cardbus_lookup(const struct cardbus_attach_args *ca) 110 1.1 kiyohara { 111 1.1 kiyohara const struct siisata_cardbus_product *scp; 112 1.1 kiyohara 113 1.1 kiyohara for (scp = siisata_cardbus_products; scp->scp_ports > 0; scp++) { 114 1.10 dyoung if (PCI_VENDOR(ca->ca_id) == scp->scp_vendor && 115 1.10 dyoung PCI_PRODUCT(ca->ca_id) == scp->scp_product) 116 1.1 kiyohara return scp; 117 1.1 kiyohara } 118 1.1 kiyohara return NULL; 119 1.1 kiyohara } 120 1.1 kiyohara 121 1.1 kiyohara static int 122 1.1 kiyohara siisata_cardbus_match(device_t parent, cfdata_t match, void *aux) 123 1.1 kiyohara { 124 1.1 kiyohara struct cardbus_attach_args *ca = aux; 125 1.1 kiyohara 126 1.1 kiyohara if (siisata_cardbus_lookup(ca) != NULL) 127 1.1 kiyohara return 3; 128 1.1 kiyohara 129 1.1 kiyohara return 0; 130 1.1 kiyohara } 131 1.1 kiyohara 132 1.1 kiyohara static void 133 1.1 kiyohara siisata_cardbus_attach(device_t parent, device_t self, void *aux) 134 1.1 kiyohara { 135 1.1 kiyohara struct cardbus_attach_args *ca = aux; 136 1.1 kiyohara struct siisata_cardbus_softc *csc = device_private(self); 137 1.1 kiyohara struct siisata_softc *sc = &csc->si_sc; 138 1.1 kiyohara cardbus_devfunc_t ct = ca->ca_ct; 139 1.1 kiyohara cardbus_chipset_tag_t cc = ct->ct_cc; 140 1.1 kiyohara cardbus_function_tag_t cf = ct->ct_cf; 141 1.5 dyoung pcireg_t csr; 142 1.1 kiyohara const struct siisata_cardbus_product *scp; 143 1.1 kiyohara bus_space_tag_t memt; 144 1.1 kiyohara bus_space_handle_t memh; 145 1.1 kiyohara bus_addr_t base; 146 1.1 kiyohara bus_size_t grsize, prsize; 147 1.1 kiyohara uint32_t gcreg; 148 1.1 kiyohara char devinfo[256]; 149 1.1 kiyohara 150 1.1 kiyohara sc->sc_atac.atac_dev = self; 151 1.1 kiyohara 152 1.1 kiyohara csc->sc_cc = cc; 153 1.1 kiyohara csc->sc_cf = cf; 154 1.1 kiyohara csc->sc_ct = ct; 155 1.7 dyoung csc->sc_tag = ca->ca_tag; 156 1.1 kiyohara 157 1.9 dyoung csc->sc_iot = ca->ca_iot; 158 1.9 dyoung csc->sc_memt = ca->ca_memt; 159 1.9 dyoung csc->sc_rbus_iot = ca->ca_rbus_iot; 160 1.9 dyoung csc->sc_rbus_memt = ca->ca_rbus_memt; 161 1.9 dyoung 162 1.10 dyoung pci_devinfo(ca->ca_id, ca->ca_class, 0, devinfo, sizeof(devinfo)); 163 1.1 kiyohara aprint_naive(": SATA-II HBA\n"); 164 1.1 kiyohara aprint_normal(": %s\n", devinfo); 165 1.1 kiyohara 166 1.1 kiyohara /* 167 1.1 kiyohara * XXXX 168 1.1 kiyohara * Our BAR0/BAR1 type is 64bit Memory. Cardbus_mapreg_map() don't 169 1.1 kiyohara * support 64bit Memory. We map ourself... 170 1.1 kiyohara */ 171 1.1 kiyohara /* map bar0 */ 172 1.1 kiyohara { 173 1.1 kiyohara #define SIISATA_BAR0_SIZE 128 174 1.1 kiyohara grsize = SIISATA_BAR0_SIZE; 175 1.13 dyoung base = PCI_MAPREG_MEM_ADDR(Cardbus_conf_read(ct, ca->ca_tag, SIISATA_CARDBUS_BAR0)); 176 1.9 dyoung memt = csc->sc_memt; 177 1.9 dyoung if ((*cf->cardbus_space_alloc)(cc, csc->sc_rbus_memt, base, 178 1.1 kiyohara grsize, grsize - 1, grsize, 0, &base, &memh)) { 179 1.1 kiyohara aprint_error( 180 1.1 kiyohara "%s: unable to map device global registers\n", 181 1.1 kiyohara SIISATANAME(sc)); 182 1.1 kiyohara return; 183 1.1 kiyohara } 184 1.13 dyoung Cardbus_conf_write(ct, ca->ca_tag, SIISATA_CARDBUS_BAR0, base); 185 1.1 kiyohara } 186 1.1 kiyohara sc->sc_grt = memt; 187 1.1 kiyohara sc->sc_grh = memh; 188 1.1 kiyohara csc->sc_grsize = grsize; 189 1.1 kiyohara 190 1.1 kiyohara /* map bar1 */ 191 1.1 kiyohara { 192 1.1 kiyohara #define SIISATA_BAR1_SIZE (32 * 1024) 193 1.1 kiyohara prsize = SIISATA_BAR1_SIZE; 194 1.10 dyoung base = PCI_MAPREG_MEM_ADDR(Cardbus_conf_read(ct, ca->ca_tag, 195 1.1 kiyohara SIISATA_CARDBUS_BAR1)); 196 1.9 dyoung memt = csc->sc_memt; 197 1.9 dyoung if ((*cf->cardbus_space_alloc)(cc, csc->sc_rbus_memt, base, 198 1.1 kiyohara prsize, prsize - 1, prsize, 0, &base, &memh)) { 199 1.10 dyoung Cardbus_conf_write(ct, ca->ca_tag, 200 1.1 kiyohara SIISATA_CARDBUS_BAR0, 0); 201 1.9 dyoung (*cf->cardbus_space_free)(cc, csc->sc_rbus_memt, 202 1.1 kiyohara sc->sc_grh, grsize); 203 1.1 kiyohara aprint_error( 204 1.1 kiyohara "%s: unable to map device port registers\n", 205 1.1 kiyohara SIISATANAME(sc)); 206 1.1 kiyohara return; 207 1.1 kiyohara } 208 1.13 dyoung Cardbus_conf_write(ct, ca->ca_tag, SIISATA_CARDBUS_BAR1, base); 209 1.1 kiyohara } 210 1.1 kiyohara sc->sc_prt = memt; 211 1.1 kiyohara sc->sc_prh = memh; 212 1.1 kiyohara csc->sc_prsize = prsize; 213 1.1 kiyohara 214 1.1 kiyohara sc->sc_dmat = ca->ca_dmat; 215 1.1 kiyohara 216 1.1 kiyohara /* map interrupt */ 217 1.15 drochner csc->sc_ih = Cardbus_intr_establish(ct, IPL_BIO, siisata_intr, sc); 218 1.1 kiyohara if (csc->sc_ih == NULL) { 219 1.10 dyoung Cardbus_conf_write(ct, ca->ca_tag, SIISATA_CARDBUS_BAR0, 0); 220 1.9 dyoung (*cf->cardbus_space_free)(cc, csc->sc_rbus_memt, sc->sc_grh, 221 1.1 kiyohara grsize); 222 1.10 dyoung Cardbus_conf_write(ct, ca->ca_tag, SIISATA_CARDBUS_BAR1, 0); 223 1.9 dyoung (*cf->cardbus_space_free)(cc, csc->sc_rbus_memt, sc->sc_prh, 224 1.1 kiyohara prsize); 225 1.1 kiyohara aprint_error("%s: couldn't establish interrupt\n", 226 1.1 kiyohara SIISATANAME(sc)); 227 1.1 kiyohara return; 228 1.1 kiyohara } 229 1.1 kiyohara 230 1.1 kiyohara /* fill in number of ports on this device */ 231 1.1 kiyohara scp = siisata_cardbus_lookup(ca); 232 1.1 kiyohara if (scp != NULL) 233 1.1 kiyohara sc->sc_atac.atac_nchannels = scp->scp_ports; 234 1.1 kiyohara else 235 1.1 kiyohara /* _match() should prevent us from getting here */ 236 1.1 kiyohara panic("siisata: the universe might be falling apart!\n"); 237 1.1 kiyohara 238 1.1 kiyohara /* enable bus mastering in case the firmware didn't */ 239 1.10 dyoung csr = Cardbus_conf_read(ct, ca->ca_tag, PCI_COMMAND_STATUS_REG); 240 1.10 dyoung csr |= PCI_COMMAND_MASTER_ENABLE; 241 1.10 dyoung csr |= PCI_COMMAND_MEM_ENABLE; 242 1.10 dyoung Cardbus_conf_write(ct, ca->ca_tag, PCI_COMMAND_STATUS_REG, csr); 243 1.1 kiyohara 244 1.1 kiyohara gcreg = GRREAD(sc, GR_GC); 245 1.1 kiyohara 246 1.1 kiyohara /* CardBus supports only 32-bit 33MHz */ 247 1.1 kiyohara KASSERT(!(gcreg & 248 1.1 kiyohara (GR_GC_REQ64|GR_GC_DEVSEL|GR_GC_STOP|GR_GC_TRDY|GR_GC_M66EN))); 249 1.1 kiyohara 250 1.1 kiyohara aprint_normal("%s: SiI%d on 32-bit, 33MHz PCI (CardBus).", 251 1.1 kiyohara SIISATANAME(sc), scp->scp_chip); 252 1.1 kiyohara if (gcreg & GR_GC_3GBPS) 253 1.1 kiyohara aprint_normal(" 3.0Gb/s capable.\n"); 254 1.1 kiyohara else 255 1.1 kiyohara aprint_normal("\n"); 256 1.1 kiyohara 257 1.1 kiyohara siisata_attach(sc); 258 1.1 kiyohara 259 1.1 kiyohara if (!pmf_device_register(self, NULL, siisata_cardbus_resume)) 260 1.1 kiyohara aprint_error_dev(self, "couldn't establish power handler\n"); 261 1.1 kiyohara } 262 1.1 kiyohara 263 1.1 kiyohara static int 264 1.1 kiyohara siisata_cardbus_detach(device_t self, int flags) 265 1.1 kiyohara { 266 1.1 kiyohara struct siisata_cardbus_softc *csc = device_private(self); 267 1.1 kiyohara struct siisata_softc *sc = &csc->si_sc; 268 1.1 kiyohara struct cardbus_devfunc *ct = csc->sc_ct; 269 1.1 kiyohara cardbus_chipset_tag_t cc = ct->ct_cc; 270 1.1 kiyohara cardbus_function_tag_t cf = ct->ct_cf; 271 1.7 dyoung pcitag_t ctag = csc->sc_tag; 272 1.1 kiyohara int rv; 273 1.1 kiyohara 274 1.1 kiyohara rv = siisata_detach(sc, flags); 275 1.1 kiyohara if (rv) 276 1.1 kiyohara return (rv); 277 1.1 kiyohara if (csc->sc_ih != NULL) { 278 1.11 dyoung Cardbus_intr_disestablish(ct, csc->sc_ih); 279 1.1 kiyohara csc->sc_ih = NULL; 280 1.1 kiyohara } 281 1.1 kiyohara if (csc->sc_grsize) { 282 1.10 dyoung Cardbus_conf_write(ct, ctag, SIISATA_CARDBUS_BAR0, 0); 283 1.9 dyoung (*cf->cardbus_space_free)(cc, csc->sc_rbus_memt, sc->sc_grh, 284 1.1 kiyohara csc->sc_grsize); 285 1.1 kiyohara csc->sc_grsize = 0; 286 1.1 kiyohara } 287 1.1 kiyohara if (csc->sc_prsize) { 288 1.10 dyoung Cardbus_conf_write(ct, ctag, SIISATA_CARDBUS_BAR1, 0); 289 1.9 dyoung (*cf->cardbus_space_free)(cc, csc->sc_rbus_memt, sc->sc_prh, 290 1.1 kiyohara csc->sc_prsize); 291 1.1 kiyohara csc->sc_prsize = 0; 292 1.1 kiyohara } 293 1.1 kiyohara return 0; 294 1.1 kiyohara } 295 1.1 kiyohara 296 1.1 kiyohara static bool 297 1.5 dyoung siisata_cardbus_resume(device_t dv, const pmf_qual_t *qual) 298 1.1 kiyohara { 299 1.1 kiyohara struct siisata_cardbus_softc *csc = device_private(dv); 300 1.1 kiyohara struct siisata_softc *sc = &csc->si_sc; 301 1.1 kiyohara int s; 302 1.1 kiyohara 303 1.1 kiyohara s = splbio(); 304 1.1 kiyohara siisata_resume(sc); 305 1.1 kiyohara splx(s); 306 1.1 kiyohara 307 1.1 kiyohara return true; 308 1.1 kiyohara } 309