1 /* $NetBSD: sdhc_pci.c,v 1.17 2020/01/01 23:28:31 mlelstv Exp $ */ 2 /* $OpenBSD: sdhc_pci.c,v 1.7 2007/10/30 18:13:45 chl Exp $ */ 3 4 /* 5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> 6 * 7 * Permission to use, copy, modify, and distribute this software for any 8 * purpose with or without fee is hereby granted, provided that the above 9 * copyright notice and this permission notice appear in all copies. 10 * 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18 */ 19 20 #include <sys/cdefs.h> 21 __KERNEL_RCSID(0, "$NetBSD: sdhc_pci.c,v 1.17 2020/01/01 23:28:31 mlelstv Exp $"); 22 23 #ifdef _KERNEL_OPT 24 #include "opt_sdmmc.h" 25 #endif 26 27 #include <sys/param.h> 28 #include <sys/device.h> 29 #include <sys/systm.h> 30 #include <sys/malloc.h> 31 #include <sys/pmf.h> 32 33 #include <dev/pci/pcivar.h> 34 #include <dev/pci/pcidevs.h> 35 36 #include <dev/sdmmc/sdhcreg.h> 37 #include <dev/sdmmc/sdhcvar.h> 38 #include <dev/sdmmc/sdmmcvar.h> 39 40 /* PCI base address registers */ 41 #define SDHC_PCI_BAR_START PCI_MAPREG_START 42 #define SDHC_PCI_BAR_END PCI_MAPREG_END 43 44 /* PCI interface classes */ 45 #define SDHC_PCI_INTERFACE_NO_DMA 0x00 46 #define SDHC_PCI_INTERFACE_DMA 0x01 47 #define SDHC_PCI_INTERFACE_VENDOR 0x02 48 49 /* 50 * 8-bit PCI configuration register that tells us how many slots there 51 * are and which BAR entry corresponds to the first slot. 52 */ 53 #define SDHC_PCI_CONF_SLOT_INFO 0x40 54 #define SDHC_PCI_NUM_SLOTS(info) ((((info) >> 4) & 0x7) + 1) 55 #define SDHC_PCI_FIRST_BAR(info) ((info) & 0x7) 56 57 struct sdhc_pci_softc { 58 struct sdhc_softc sc; 59 pci_chipset_tag_t sc_pc; 60 void *sc_ih; 61 }; 62 63 static int sdhc_pci_match(device_t, cfdata_t, void *); 64 static void sdhc_pci_attach(device_t, device_t, void *); 65 static int sdhc_pci_detach(device_t, int); 66 67 CFATTACH_DECL_NEW(sdhc_pci, sizeof(struct sdhc_pci_softc), 68 sdhc_pci_match, sdhc_pci_attach, sdhc_pci_detach, NULL); 69 70 #ifdef SDHC_DEBUG 71 #define DPRINTF(s) printf s 72 #else 73 #define DPRINTF(s) /**/ 74 #endif 75 76 static const struct sdhc_pci_quirk { 77 pci_vendor_id_t vendor; 78 pci_product_id_t product; 79 pci_vendor_id_t subvendor; 80 pci_product_id_t subproduct; 81 u_int function; 82 83 uint32_t flags; 84 #define SDHC_PCI_QUIRK_FORCE_DMA __BIT(0) 85 #define SDHC_PCI_QUIRK_TI_HACK __BIT(1) 86 #define SDHC_PCI_QUIRK_NO_PWR0 __BIT(2) 87 #define SDHC_PCI_QUIRK_RICOH_LOWER_FREQ_HACK __BIT(3) 88 #define SDHC_PCI_QUIRK_RICOH_SLOW_SDR50_HACK __BIT(4) 89 #define SDHC_PCI_QUIRK_INTEL_EMMC_HW_RESET __BIT(5) 90 #define SDHC_PCI_QUIRK_SINGLE_POWER_WRITE __BIT(6) 91 } sdhc_pci_quirk_table[] = { 92 { 93 PCI_VENDOR_TI, 94 PCI_PRODUCT_TI_PCI72111SD, 95 0xffff, 96 0xffff, 97 4, 98 SDHC_PCI_QUIRK_TI_HACK 99 }, 100 101 { 102 PCI_VENDOR_TI, 103 PCI_PRODUCT_TI_PCIXX12SD, 104 0xffff, 105 0xffff, 106 3, 107 SDHC_PCI_QUIRK_TI_HACK 108 }, 109 110 { 111 PCI_VENDOR_ENE, 112 PCI_PRODUCT_ENE_CB712, 113 0xffff, 114 0xffff, 115 0, 116 SDHC_PCI_QUIRK_NO_PWR0 117 }, 118 { 119 PCI_VENDOR_RICOH, 120 PCI_PRODUCT_RICOH_Rx5U823, 121 0xffff, 122 0xffff, 123 0, 124 SDHC_PCI_QUIRK_RICOH_SLOW_SDR50_HACK 125 | SDHC_PCI_QUIRK_SINGLE_POWER_WRITE 126 }, 127 { 128 PCI_VENDOR_RICOH, 129 PCI_PRODUCT_RICOH_Rx5C822, 130 0xffff, 131 0xffff, 132 ~0, 133 SDHC_PCI_QUIRK_FORCE_DMA 134 }, 135 136 { 137 PCI_VENDOR_RICOH, 138 PCI_PRODUCT_RICOH_Rx5U822, 139 0xffff, 140 0xffff, 141 ~0, 142 SDHC_PCI_QUIRK_FORCE_DMA 143 }, 144 145 { 146 PCI_VENDOR_INTEL, 147 PCI_PRODUCT_INTEL_BAYTRAIL_SCC_MMC, 148 0xffff, 149 0xffff, 150 ~0, 151 SDHC_PCI_QUIRK_INTEL_EMMC_HW_RESET 152 }, 153 154 { 155 PCI_VENDOR_INTEL, 156 PCI_PRODUCT_INTEL_BSW_SSC_MMC, 157 0xffff, 158 0xffff, 159 ~0, 160 SDHC_PCI_QUIRK_INTEL_EMMC_HW_RESET 161 }, 162 163 { 164 PCI_VENDOR_INTEL, 165 PCI_PRODUCT_INTEL_100SERIES_LP_EMMC, 166 0xffff, 167 0xffff, 168 ~0, 169 SDHC_PCI_QUIRK_INTEL_EMMC_HW_RESET 170 }, 171 }; 172 173 static void sdhc_pci_quirk_ti_hack(struct pci_attach_args *); 174 static void sdhc_pci_quirk_ricoh_lower_freq_hack(struct pci_attach_args *); 175 static void sdhc_pci_intel_emmc_hw_reset(struct sdhc_softc *, 176 struct sdhc_host *); 177 178 static uint32_t 179 sdhc_pci_lookup_quirk_flags(struct pci_attach_args *pa) 180 { 181 const struct sdhc_pci_quirk *q; 182 pcireg_t id; 183 pci_vendor_id_t vendor; 184 pci_product_id_t product; 185 int i; 186 187 for (i = 0; i < __arraycount(sdhc_pci_quirk_table); i++) { 188 q = &sdhc_pci_quirk_table[i]; 189 190 if ((PCI_VENDOR(pa->pa_id) == q->vendor) 191 && (PCI_PRODUCT(pa->pa_id) == q->product)) { 192 if ((q->function != ~0) 193 && (pa->pa_function != q->function)) 194 continue; 195 196 if ((q->subvendor == 0xffff) 197 && (q->subproduct == 0xffff)) 198 return (q->flags); 199 200 id = pci_conf_read(pa->pa_pc, pa->pa_tag, 201 PCI_SUBSYS_ID_REG); 202 vendor = PCI_VENDOR(id); 203 product = PCI_PRODUCT(id); 204 205 if ((q->subvendor != 0xffff) 206 && (q->subproduct != 0xffff)) { 207 if ((vendor == q->subvendor) 208 && (product == q->subproduct)) 209 return (q->flags); 210 } else if (q->subvendor != 0xffff) { 211 if (product == q->subproduct) 212 return (q->flags); 213 } else { 214 if (vendor == q->subvendor) 215 return (q->flags); 216 } 217 } 218 } 219 return (0); 220 } 221 222 static int 223 sdhc_pci_match(device_t parent, cfdata_t cf, void *aux) 224 { 225 struct pci_attach_args *pa = aux; 226 227 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_SYSTEM && 228 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_SYSTEM_SDHC) 229 return (1); 230 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_RICOH && 231 (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_RICOH_Rx5U822 || 232 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_RICOH_Rx5U823)) 233 return (1); 234 return (0); 235 } 236 237 static void 238 sdhc_pci_attach(device_t parent, device_t self, void *aux) 239 { 240 struct sdhc_pci_softc *sc = device_private(self); 241 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 242 pci_chipset_tag_t pc = pa->pa_pc; 243 pcitag_t tag = pa->pa_tag; 244 pci_intr_handle_t ih; 245 pcireg_t csr; 246 pcireg_t slotinfo; 247 char const *intrstr; 248 int nslots; 249 int reg; 250 int cnt; 251 bus_space_tag_t iot; 252 bus_space_handle_t ioh; 253 bus_size_t size; 254 uint32_t flags; 255 char intrbuf[PCI_INTRSTR_LEN]; 256 257 sc->sc.sc_dev = self; 258 sc->sc.sc_dmat = pa->pa_dmat; 259 sc->sc.sc_host = NULL; 260 261 sc->sc_pc = pc; 262 263 pci_aprint_devinfo(pa, NULL); 264 265 /* Some controllers needs special treatment. */ 266 flags = sdhc_pci_lookup_quirk_flags(pa); 267 if (ISSET(flags, SDHC_PCI_QUIRK_TI_HACK)) 268 sdhc_pci_quirk_ti_hack(pa); 269 if (ISSET(flags, SDHC_PCI_QUIRK_FORCE_DMA)) 270 SET(sc->sc.sc_flags, SDHC_FLAG_FORCE_DMA); 271 if (ISSET(flags, SDHC_PCI_QUIRK_SINGLE_POWER_WRITE)) 272 SET(sc->sc.sc_flags, SDHC_FLAG_SINGLE_POWER_WRITE); 273 if (ISSET(flags, SDHC_PCI_QUIRK_NO_PWR0)) 274 SET(sc->sc.sc_flags, SDHC_FLAG_NO_PWR0); 275 if (ISSET(flags, SDHC_PCI_QUIRK_RICOH_LOWER_FREQ_HACK)) 276 sdhc_pci_quirk_ricoh_lower_freq_hack(pa); 277 if (ISSET(flags, SDHC_PCI_QUIRK_RICOH_SLOW_SDR50_HACK)) 278 SET(sc->sc.sc_flags, SDHC_FLAG_SLOW_SDR50); 279 if (ISSET(flags, SDHC_PCI_QUIRK_INTEL_EMMC_HW_RESET)) 280 sc->sc.sc_vendor_hw_reset = sdhc_pci_intel_emmc_hw_reset; 281 282 /* 283 * Map and attach all hosts supported by the host controller. 284 */ 285 slotinfo = pci_conf_read(pc, tag, SDHC_PCI_CONF_SLOT_INFO); 286 nslots = SDHC_PCI_NUM_SLOTS(slotinfo); 287 288 /* Allocate an array big enough to hold all the possible hosts */ 289 sc->sc.sc_host = malloc(sizeof(struct sdhc_host *) * nslots, 290 M_DEVBUF, M_WAITOK | M_ZERO); 291 292 /* Enable the device. */ 293 csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 294 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, 295 csr | PCI_COMMAND_MASTER_ENABLE); 296 297 /* Map and establish the interrupt. */ 298 if (pci_intr_map(pa, &ih)) { 299 aprint_error_dev(self, "couldn't map interrupt\n"); 300 goto err; 301 } 302 303 intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf)); 304 sc->sc_ih = pci_intr_establish_xname(pc, ih, IPL_SDMMC, sdhc_intr, 305 &sc->sc, device_xname(self)); 306 if (sc->sc_ih == NULL) { 307 aprint_error_dev(self, "couldn't establish interrupt\n"); 308 goto err; 309 } 310 aprint_normal_dev(self, "interrupting at %s\n", intrstr); 311 312 /* Enable use of DMA if supported by the interface. */ 313 if ((PCI_INTERFACE(pa->pa_class) == SDHC_PCI_INTERFACE_DMA)) 314 SET(sc->sc.sc_flags, SDHC_FLAG_USE_DMA); 315 316 /* XXX: handle 64-bit BARs */ 317 cnt = 0; 318 for (reg = SDHC_PCI_BAR_START + SDHC_PCI_FIRST_BAR(slotinfo) * 319 sizeof(uint32_t); 320 reg < SDHC_PCI_BAR_END && nslots > 0; 321 reg += sizeof(uint32_t), nslots--) { 322 if (pci_mapreg_map(pa, reg, PCI_MAPREG_TYPE_MEM, 0, 323 &iot, &ioh, NULL, &size)) { 324 continue; 325 } 326 327 cnt++; 328 if (sdhc_host_found(&sc->sc, iot, ioh, size) != 0) { 329 /* XXX: sc->sc_host leak */ 330 aprint_error_dev(self, 331 "couldn't initialize host (0x%x)\n", reg); 332 } 333 } 334 if (cnt == 0) { 335 aprint_error_dev(self, "couldn't map register\n"); 336 goto err; 337 } 338 339 if (!pmf_device_register1(self, sdhc_suspend, sdhc_resume, 340 sdhc_shutdown)) { 341 aprint_error_dev(self, "couldn't establish powerhook\n"); 342 } 343 344 return; 345 346 err: 347 if (sc->sc.sc_host != NULL) { 348 free(sc->sc.sc_host, M_DEVBUF); 349 sc->sc.sc_host = NULL; 350 } 351 } 352 353 static int 354 sdhc_pci_detach(device_t self, int flags) 355 { 356 struct sdhc_pci_softc * const sc = device_private(self); 357 int rv; 358 359 rv = sdhc_detach(&sc->sc, flags); 360 if (rv) 361 return rv; 362 363 if (sc->sc_ih != NULL) { 364 pci_intr_disestablish(sc->sc_pc, sc->sc_ih); 365 sc->sc_ih = NULL; 366 } 367 368 if (sc->sc.sc_host != NULL) { 369 free(sc->sc.sc_host, M_DEVBUF); 370 sc->sc.sc_host = NULL; 371 } 372 373 return rv; 374 } 375 376 static void 377 sdhc_pci_conf_write(struct pci_attach_args *pa, int reg, uint8_t val) 378 { 379 pcireg_t r; 380 381 r = pci_conf_read(pa->pa_pc, pa->pa_tag, reg & ~0x3); 382 r &= ~(0xff << ((reg & 0x3) * 8)); 383 r |= (val << ((reg & 0x3) * 8)); 384 pci_conf_write(pa->pa_pc, pa->pa_tag, reg & ~0x3, r); 385 } 386 387 /* TI specific register */ 388 #define SDHC_PCI_GENERAL_CTL 0x4c 389 #define MMC_SD_DIS 0x02 390 391 static void 392 sdhc_pci_quirk_ti_hack(struct pci_attach_args *pa) 393 { 394 pci_chipset_tag_t pc = pa->pa_pc; 395 pcitag_t tag; 396 pcireg_t id, reg; 397 398 /* Look at func - 1 for the flash device */ 399 tag = pci_make_tag(pc, pa->pa_bus, pa->pa_device, pa->pa_function - 1); 400 id = pci_conf_read(pc, tag, PCI_ID_REG); 401 if (PCI_VENDOR(id) != PCI_VENDOR_TI) { 402 return; 403 } 404 switch (PCI_PRODUCT(id)) { 405 case PCI_PRODUCT_TI_PCI72111FM: 406 case PCI_PRODUCT_TI_PCIXX12FM: 407 break; 408 default: 409 return; 410 } 411 412 /* 413 * Disable MMC/SD on the flash media controller so the 414 * SD host takes over. 415 */ 416 reg = pci_conf_read(pc, tag, SDHC_PCI_GENERAL_CTL); 417 reg |= MMC_SD_DIS; 418 pci_conf_write(pc, tag, SDHC_PCI_GENERAL_CTL, reg); 419 } 420 421 /* Ricoh specific register */ 422 #define SDHC_PCI_MODE_KEY 0xf9 423 #define SDHC_PCI_MODE 0x150 424 #define SDHC_PCI_MODE_SD20 0x10 425 #define SDHC_PCI_BASE_FREQ_KEY 0xfc 426 #define SDHC_PCI_BASE_FREQ 0xe1 427 428 /* Some RICOH controllers need to be bumped into the right mode. */ 429 static void 430 sdhc_pci_quirk_ricoh_lower_freq_hack(struct pci_attach_args *pa) 431 { 432 /* Enable SD2.0 mode. */ 433 sdhc_pci_conf_write(pa, SDHC_PCI_MODE_KEY, 0xfc); 434 sdhc_pci_conf_write(pa, SDHC_PCI_MODE, SDHC_PCI_MODE_SD20); 435 sdhc_pci_conf_write(pa, SDHC_PCI_MODE_KEY, 0x00); 436 437 /* 438 * Some SD/MMC cards don't work with the default base 439 * clock frequency of 200MHz. Lower it to 50MHz. 440 */ 441 sdhc_pci_conf_write(pa, SDHC_PCI_BASE_FREQ_KEY, 0x01); 442 sdhc_pci_conf_write(pa, SDHC_PCI_BASE_FREQ, 50); 443 sdhc_pci_conf_write(pa, SDHC_PCI_BASE_FREQ_KEY, 0x00); 444 } 445 446 static void 447 sdhc_pci_intel_emmc_hw_reset(struct sdhc_softc *sc, struct sdhc_host *hp) 448 { 449 kmutex_t *plock = sdhc_host_lock(hp); 450 uint8_t reg; 451 452 mutex_enter(plock); 453 454 reg = sdhc_host_read_1(hp, SDHC_POWER_CTL); 455 reg |= 0x10; 456 sdhc_host_write_1(hp, SDHC_POWER_CTL, reg); 457 458 sdmmc_delay(10); 459 460 reg &= ~0x10; 461 sdhc_host_write_1(hp, SDHC_POWER_CTL, reg); 462 463 sdmmc_delay(1000); 464 465 mutex_exit(plock); 466 } 467