1 /* $NetBSD: sdhc_pci.c,v 1.19 2022/10/14 07:54:49 jmcneill 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.19 2022/10/14 07:54:49 jmcneill 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 #define SDHC_PCI_QUIRK_BROKEN_ADMA __BIT(7) 92 } sdhc_pci_quirk_table[] = { 93 { 94 PCI_VENDOR_TI, 95 PCI_PRODUCT_TI_PCI72111SD, 96 0xffff, 97 0xffff, 98 4, 99 SDHC_PCI_QUIRK_TI_HACK 100 }, 101 102 { 103 PCI_VENDOR_TI, 104 PCI_PRODUCT_TI_PCIXX12SD, 105 0xffff, 106 0xffff, 107 3, 108 SDHC_PCI_QUIRK_TI_HACK 109 }, 110 111 { 112 PCI_VENDOR_ENE, 113 PCI_PRODUCT_ENE_CB712, 114 0xffff, 115 0xffff, 116 0, 117 SDHC_PCI_QUIRK_NO_PWR0 118 }, 119 { 120 PCI_VENDOR_RICOH, 121 PCI_PRODUCT_RICOH_Rx5U823, 122 0xffff, 123 0xffff, 124 0, 125 SDHC_PCI_QUIRK_RICOH_SLOW_SDR50_HACK 126 | SDHC_PCI_QUIRK_SINGLE_POWER_WRITE 127 | SDHC_PCI_QUIRK_BROKEN_ADMA 128 }, 129 { 130 PCI_VENDOR_RICOH, 131 PCI_PRODUCT_RICOH_Rx5C822, 132 0xffff, 133 0xffff, 134 ~0, 135 SDHC_PCI_QUIRK_FORCE_DMA 136 | SDHC_PCI_QUIRK_BROKEN_ADMA 137 }, 138 139 { 140 PCI_VENDOR_RICOH, 141 PCI_PRODUCT_RICOH_Rx5U822, 142 0xffff, 143 0xffff, 144 ~0, 145 SDHC_PCI_QUIRK_FORCE_DMA 146 | SDHC_PCI_QUIRK_BROKEN_ADMA 147 }, 148 149 { 150 PCI_VENDOR_INTEL, 151 PCI_PRODUCT_INTEL_BAYTRAIL_SCC_MMC, 152 0xffff, 153 0xffff, 154 ~0, 155 SDHC_PCI_QUIRK_INTEL_EMMC_HW_RESET 156 }, 157 158 { 159 PCI_VENDOR_INTEL, 160 PCI_PRODUCT_INTEL_BSW_SSC_MMC, 161 0xffff, 162 0xffff, 163 ~0, 164 SDHC_PCI_QUIRK_INTEL_EMMC_HW_RESET 165 }, 166 167 { 168 PCI_VENDOR_INTEL, 169 PCI_PRODUCT_INTEL_100SERIES_LP_EMMC, 170 0xffff, 171 0xffff, 172 ~0, 173 SDHC_PCI_QUIRK_INTEL_EMMC_HW_RESET 174 }, 175 }; 176 177 static void sdhc_pci_quirk_ti_hack(struct pci_attach_args *); 178 static void sdhc_pci_quirk_ricoh_lower_freq_hack(struct pci_attach_args *); 179 static void sdhc_pci_intel_emmc_hw_reset(struct sdhc_softc *, 180 struct sdhc_host *); 181 182 static uint32_t 183 sdhc_pci_lookup_quirk_flags(struct pci_attach_args *pa) 184 { 185 const struct sdhc_pci_quirk *q; 186 pcireg_t id; 187 pci_vendor_id_t vendor; 188 pci_product_id_t product; 189 int i; 190 191 for (i = 0; i < __arraycount(sdhc_pci_quirk_table); i++) { 192 q = &sdhc_pci_quirk_table[i]; 193 194 if ((PCI_VENDOR(pa->pa_id) == q->vendor) 195 && (PCI_PRODUCT(pa->pa_id) == q->product)) { 196 if ((q->function != ~0) 197 && (pa->pa_function != q->function)) 198 continue; 199 200 if ((q->subvendor == 0xffff) 201 && (q->subproduct == 0xffff)) 202 return (q->flags); 203 204 id = pci_conf_read(pa->pa_pc, pa->pa_tag, 205 PCI_SUBSYS_ID_REG); 206 vendor = PCI_VENDOR(id); 207 product = PCI_PRODUCT(id); 208 209 if ((q->subvendor != 0xffff) 210 && (q->subproduct != 0xffff)) { 211 if ((vendor == q->subvendor) 212 && (product == q->subproduct)) 213 return (q->flags); 214 } else if (q->subvendor != 0xffff) { 215 if (product == q->subproduct) 216 return (q->flags); 217 } else { 218 if (vendor == q->subvendor) 219 return (q->flags); 220 } 221 } 222 } 223 return (0); 224 } 225 226 static int 227 sdhc_pci_match(device_t parent, cfdata_t cf, void *aux) 228 { 229 struct pci_attach_args *pa = aux; 230 231 if (PCI_CLASS(pa->pa_class) == PCI_CLASS_SYSTEM && 232 PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_SYSTEM_SDHC) 233 return (1); 234 if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_RICOH && 235 (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_RICOH_Rx5U822 || 236 PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_RICOH_Rx5U823)) 237 return (1); 238 return (0); 239 } 240 241 static void 242 sdhc_pci_attach(device_t parent, device_t self, void *aux) 243 { 244 struct sdhc_pci_softc *sc = device_private(self); 245 struct pci_attach_args *pa = (struct pci_attach_args *)aux; 246 pci_chipset_tag_t pc = pa->pa_pc; 247 pcitag_t tag = pa->pa_tag; 248 pci_intr_handle_t ih; 249 pcireg_t csr; 250 pcireg_t slotinfo; 251 char const *intrstr; 252 int nslots; 253 int reg; 254 int cnt; 255 bus_space_tag_t iot; 256 bus_space_handle_t ioh; 257 bus_size_t size; 258 uint32_t flags; 259 int width; 260 char intrbuf[PCI_INTRSTR_LEN]; 261 262 sc->sc.sc_dev = self; 263 sc->sc.sc_dmat = pa->pa_dmat; 264 sc->sc.sc_host = NULL; 265 266 sc->sc_pc = pc; 267 268 pci_aprint_devinfo(pa, NULL); 269 270 /* Some controllers needs special treatment. */ 271 flags = sdhc_pci_lookup_quirk_flags(pa); 272 if (ISSET(flags, SDHC_PCI_QUIRK_TI_HACK)) 273 sdhc_pci_quirk_ti_hack(pa); 274 if (ISSET(flags, SDHC_PCI_QUIRK_FORCE_DMA)) 275 SET(sc->sc.sc_flags, SDHC_FLAG_FORCE_DMA); 276 if (ISSET(flags, SDHC_PCI_QUIRK_SINGLE_POWER_WRITE)) 277 SET(sc->sc.sc_flags, SDHC_FLAG_SINGLE_POWER_WRITE); 278 if (ISSET(flags, SDHC_PCI_QUIRK_NO_PWR0)) 279 SET(sc->sc.sc_flags, SDHC_FLAG_NO_PWR0); 280 if (ISSET(flags, SDHC_PCI_QUIRK_BROKEN_ADMA)) 281 SET(sc->sc.sc_flags, SDHC_FLAG_BROKEN_ADMA); 282 if (ISSET(flags, SDHC_PCI_QUIRK_RICOH_LOWER_FREQ_HACK)) 283 sdhc_pci_quirk_ricoh_lower_freq_hack(pa); 284 if (ISSET(flags, SDHC_PCI_QUIRK_RICOH_SLOW_SDR50_HACK)) 285 SET(sc->sc.sc_flags, SDHC_FLAG_SLOW_SDR50); 286 if (ISSET(flags, SDHC_PCI_QUIRK_INTEL_EMMC_HW_RESET)) 287 sc->sc.sc_vendor_hw_reset = sdhc_pci_intel_emmc_hw_reset; 288 289 /* 290 * Map and attach all hosts supported by the host controller. 291 */ 292 slotinfo = pci_conf_read(pc, tag, SDHC_PCI_CONF_SLOT_INFO); 293 nslots = SDHC_PCI_NUM_SLOTS(slotinfo); 294 295 /* Allocate an array big enough to hold all the possible hosts */ 296 sc->sc.sc_host = malloc(sizeof(struct sdhc_host *) * nslots, 297 M_DEVBUF, M_WAITOK | M_ZERO); 298 299 /* Enable the device. */ 300 csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 301 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, 302 csr | PCI_COMMAND_MASTER_ENABLE); 303 304 /* Map and establish the interrupt. */ 305 if (pci_intr_map(pa, &ih)) { 306 aprint_error_dev(self, "couldn't map interrupt\n"); 307 goto err; 308 } 309 310 intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf)); 311 sc->sc_ih = pci_intr_establish_xname(pc, ih, IPL_SDMMC, sdhc_intr, 312 &sc->sc, device_xname(self)); 313 if (sc->sc_ih == NULL) { 314 aprint_error_dev(self, "couldn't establish interrupt\n"); 315 goto err; 316 } 317 aprint_normal_dev(self, "interrupting at %s\n", intrstr); 318 319 /* Enable use of DMA if supported by the interface. */ 320 if ((PCI_INTERFACE(pa->pa_class) == SDHC_PCI_INTERFACE_DMA)) 321 SET(sc->sc.sc_flags, SDHC_FLAG_USE_DMA); 322 323 cnt = 0; 324 for (reg = SDHC_PCI_BAR_START + SDHC_PCI_FIRST_BAR(slotinfo) * 325 sizeof(uint32_t); 326 reg < SDHC_PCI_BAR_END && nslots > 0; 327 reg += width, nslots--) { 328 pcireg_t type; 329 330 type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, reg); 331 if (type == PCI_MAPREG_TYPE_IO) 332 break; 333 else if (PCI_MAPREG_MEM_TYPE(type) 334 == PCI_MAPREG_MEM_TYPE_64BIT) 335 width = 8; 336 else 337 width = 4; 338 339 if (pci_mapreg_map(pa, reg, type, 0, 340 &iot, &ioh, NULL, &size)) { 341 continue; 342 } 343 344 cnt++; 345 if (sdhc_host_found(&sc->sc, iot, ioh, size) != 0) { 346 /* XXX: sc->sc_host leak */ 347 aprint_error_dev(self, 348 "couldn't initialize host (0x%x)\n", reg); 349 } 350 } 351 if (cnt == 0) { 352 aprint_error_dev(self, "couldn't map register\n"); 353 goto err; 354 } 355 356 if (!pmf_device_register1(self, sdhc_suspend, sdhc_resume, 357 sdhc_shutdown)) { 358 aprint_error_dev(self, "couldn't establish powerhook\n"); 359 } 360 361 return; 362 363 err: 364 if (sc->sc.sc_host != NULL) { 365 free(sc->sc.sc_host, M_DEVBUF); 366 sc->sc.sc_host = NULL; 367 } 368 } 369 370 static int 371 sdhc_pci_detach(device_t self, int flags) 372 { 373 struct sdhc_pci_softc * const sc = device_private(self); 374 int rv; 375 376 rv = sdhc_detach(&sc->sc, flags); 377 if (rv) 378 return rv; 379 380 if (sc->sc_ih != NULL) { 381 pci_intr_disestablish(sc->sc_pc, sc->sc_ih); 382 sc->sc_ih = NULL; 383 } 384 385 if (sc->sc.sc_host != NULL) { 386 free(sc->sc.sc_host, M_DEVBUF); 387 sc->sc.sc_host = NULL; 388 } 389 390 return rv; 391 } 392 393 static void 394 sdhc_pci_conf_write(struct pci_attach_args *pa, int reg, uint8_t val) 395 { 396 pcireg_t r; 397 398 r = pci_conf_read(pa->pa_pc, pa->pa_tag, reg & ~0x3); 399 r &= ~(0xff << ((reg & 0x3) * 8)); 400 r |= (val << ((reg & 0x3) * 8)); 401 pci_conf_write(pa->pa_pc, pa->pa_tag, reg & ~0x3, r); 402 } 403 404 /* TI specific register */ 405 #define SDHC_PCI_GENERAL_CTL 0x4c 406 #define MMC_SD_DIS 0x02 407 408 static void 409 sdhc_pci_quirk_ti_hack(struct pci_attach_args *pa) 410 { 411 pci_chipset_tag_t pc = pa->pa_pc; 412 pcitag_t tag; 413 pcireg_t id, reg; 414 415 /* Look at func - 1 for the flash device */ 416 tag = pci_make_tag(pc, pa->pa_bus, pa->pa_device, pa->pa_function - 1); 417 id = pci_conf_read(pc, tag, PCI_ID_REG); 418 if (PCI_VENDOR(id) != PCI_VENDOR_TI) { 419 return; 420 } 421 switch (PCI_PRODUCT(id)) { 422 case PCI_PRODUCT_TI_PCI72111FM: 423 case PCI_PRODUCT_TI_PCIXX12FM: 424 break; 425 default: 426 return; 427 } 428 429 /* 430 * Disable MMC/SD on the flash media controller so the 431 * SD host takes over. 432 */ 433 reg = pci_conf_read(pc, tag, SDHC_PCI_GENERAL_CTL); 434 reg |= MMC_SD_DIS; 435 pci_conf_write(pc, tag, SDHC_PCI_GENERAL_CTL, reg); 436 } 437 438 /* Ricoh specific register */ 439 #define SDHC_PCI_MODE_KEY 0xf9 440 #define SDHC_PCI_MODE 0x150 441 #define SDHC_PCI_MODE_SD20 0x10 442 #define SDHC_PCI_BASE_FREQ_KEY 0xfc 443 #define SDHC_PCI_BASE_FREQ 0xe1 444 445 /* Some RICOH controllers need to be bumped into the right mode. */ 446 static void 447 sdhc_pci_quirk_ricoh_lower_freq_hack(struct pci_attach_args *pa) 448 { 449 /* Enable SD2.0 mode. */ 450 sdhc_pci_conf_write(pa, SDHC_PCI_MODE_KEY, 0xfc); 451 sdhc_pci_conf_write(pa, SDHC_PCI_MODE, SDHC_PCI_MODE_SD20); 452 sdhc_pci_conf_write(pa, SDHC_PCI_MODE_KEY, 0x00); 453 454 /* 455 * Some SD/MMC cards don't work with the default base 456 * clock frequency of 200MHz. Lower it to 50MHz. 457 */ 458 sdhc_pci_conf_write(pa, SDHC_PCI_BASE_FREQ_KEY, 0x01); 459 sdhc_pci_conf_write(pa, SDHC_PCI_BASE_FREQ, 50); 460 sdhc_pci_conf_write(pa, SDHC_PCI_BASE_FREQ_KEY, 0x00); 461 } 462 463 static void 464 sdhc_pci_intel_emmc_hw_reset(struct sdhc_softc *sc, struct sdhc_host *hp) 465 { 466 kmutex_t *plock = sdhc_host_lock(hp); 467 uint8_t reg; 468 469 mutex_enter(plock); 470 471 reg = sdhc_host_read_1(hp, SDHC_POWER_CTL); 472 reg |= 0x10; 473 sdhc_host_write_1(hp, SDHC_POWER_CTL, reg); 474 475 sdmmc_delay(10); 476 477 reg &= ~0x10; 478 sdhc_host_write_1(hp, SDHC_POWER_CTL, reg); 479 480 sdmmc_delay(1000); 481 482 mutex_exit(plock); 483 } 484