1 /* $NetBSD: sdhc_pci.c,v 1.18 2021/11/10 14:36:28 msaitoh 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.18 2021/11/10 14:36:28 msaitoh 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 int width; 256 char intrbuf[PCI_INTRSTR_LEN]; 257 258 sc->sc.sc_dev = self; 259 sc->sc.sc_dmat = pa->pa_dmat; 260 sc->sc.sc_host = NULL; 261 262 sc->sc_pc = pc; 263 264 pci_aprint_devinfo(pa, NULL); 265 266 /* Some controllers needs special treatment. */ 267 flags = sdhc_pci_lookup_quirk_flags(pa); 268 if (ISSET(flags, SDHC_PCI_QUIRK_TI_HACK)) 269 sdhc_pci_quirk_ti_hack(pa); 270 if (ISSET(flags, SDHC_PCI_QUIRK_FORCE_DMA)) 271 SET(sc->sc.sc_flags, SDHC_FLAG_FORCE_DMA); 272 if (ISSET(flags, SDHC_PCI_QUIRK_SINGLE_POWER_WRITE)) 273 SET(sc->sc.sc_flags, SDHC_FLAG_SINGLE_POWER_WRITE); 274 if (ISSET(flags, SDHC_PCI_QUIRK_NO_PWR0)) 275 SET(sc->sc.sc_flags, SDHC_FLAG_NO_PWR0); 276 if (ISSET(flags, SDHC_PCI_QUIRK_RICOH_LOWER_FREQ_HACK)) 277 sdhc_pci_quirk_ricoh_lower_freq_hack(pa); 278 if (ISSET(flags, SDHC_PCI_QUIRK_RICOH_SLOW_SDR50_HACK)) 279 SET(sc->sc.sc_flags, SDHC_FLAG_SLOW_SDR50); 280 if (ISSET(flags, SDHC_PCI_QUIRK_INTEL_EMMC_HW_RESET)) 281 sc->sc.sc_vendor_hw_reset = sdhc_pci_intel_emmc_hw_reset; 282 283 /* 284 * Map and attach all hosts supported by the host controller. 285 */ 286 slotinfo = pci_conf_read(pc, tag, SDHC_PCI_CONF_SLOT_INFO); 287 nslots = SDHC_PCI_NUM_SLOTS(slotinfo); 288 289 /* Allocate an array big enough to hold all the possible hosts */ 290 sc->sc.sc_host = malloc(sizeof(struct sdhc_host *) * nslots, 291 M_DEVBUF, M_WAITOK | M_ZERO); 292 293 /* Enable the device. */ 294 csr = pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG); 295 pci_conf_write(pc, tag, PCI_COMMAND_STATUS_REG, 296 csr | PCI_COMMAND_MASTER_ENABLE); 297 298 /* Map and establish the interrupt. */ 299 if (pci_intr_map(pa, &ih)) { 300 aprint_error_dev(self, "couldn't map interrupt\n"); 301 goto err; 302 } 303 304 intrstr = pci_intr_string(pc, ih, intrbuf, sizeof(intrbuf)); 305 sc->sc_ih = pci_intr_establish_xname(pc, ih, IPL_SDMMC, sdhc_intr, 306 &sc->sc, device_xname(self)); 307 if (sc->sc_ih == NULL) { 308 aprint_error_dev(self, "couldn't establish interrupt\n"); 309 goto err; 310 } 311 aprint_normal_dev(self, "interrupting at %s\n", intrstr); 312 313 /* Enable use of DMA if supported by the interface. */ 314 if ((PCI_INTERFACE(pa->pa_class) == SDHC_PCI_INTERFACE_DMA)) 315 SET(sc->sc.sc_flags, SDHC_FLAG_USE_DMA); 316 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 += width, nslots--) { 322 pcireg_t type; 323 324 type = pci_mapreg_type(pa->pa_pc, pa->pa_tag, reg); 325 if (type == PCI_MAPREG_TYPE_IO) 326 break; 327 else if (PCI_MAPREG_MEM_TYPE(type) 328 == PCI_MAPREG_MEM_TYPE_64BIT) 329 width = 8; 330 else 331 width = 4; 332 333 if (pci_mapreg_map(pa, reg, type, 0, 334 &iot, &ioh, NULL, &size)) { 335 continue; 336 } 337 338 cnt++; 339 if (sdhc_host_found(&sc->sc, iot, ioh, size) != 0) { 340 /* XXX: sc->sc_host leak */ 341 aprint_error_dev(self, 342 "couldn't initialize host (0x%x)\n", reg); 343 } 344 } 345 if (cnt == 0) { 346 aprint_error_dev(self, "couldn't map register\n"); 347 goto err; 348 } 349 350 if (!pmf_device_register1(self, sdhc_suspend, sdhc_resume, 351 sdhc_shutdown)) { 352 aprint_error_dev(self, "couldn't establish powerhook\n"); 353 } 354 355 return; 356 357 err: 358 if (sc->sc.sc_host != NULL) { 359 free(sc->sc.sc_host, M_DEVBUF); 360 sc->sc.sc_host = NULL; 361 } 362 } 363 364 static int 365 sdhc_pci_detach(device_t self, int flags) 366 { 367 struct sdhc_pci_softc * const sc = device_private(self); 368 int rv; 369 370 rv = sdhc_detach(&sc->sc, flags); 371 if (rv) 372 return rv; 373 374 if (sc->sc_ih != NULL) { 375 pci_intr_disestablish(sc->sc_pc, sc->sc_ih); 376 sc->sc_ih = NULL; 377 } 378 379 if (sc->sc.sc_host != NULL) { 380 free(sc->sc.sc_host, M_DEVBUF); 381 sc->sc.sc_host = NULL; 382 } 383 384 return rv; 385 } 386 387 static void 388 sdhc_pci_conf_write(struct pci_attach_args *pa, int reg, uint8_t val) 389 { 390 pcireg_t r; 391 392 r = pci_conf_read(pa->pa_pc, pa->pa_tag, reg & ~0x3); 393 r &= ~(0xff << ((reg & 0x3) * 8)); 394 r |= (val << ((reg & 0x3) * 8)); 395 pci_conf_write(pa->pa_pc, pa->pa_tag, reg & ~0x3, r); 396 } 397 398 /* TI specific register */ 399 #define SDHC_PCI_GENERAL_CTL 0x4c 400 #define MMC_SD_DIS 0x02 401 402 static void 403 sdhc_pci_quirk_ti_hack(struct pci_attach_args *pa) 404 { 405 pci_chipset_tag_t pc = pa->pa_pc; 406 pcitag_t tag; 407 pcireg_t id, reg; 408 409 /* Look at func - 1 for the flash device */ 410 tag = pci_make_tag(pc, pa->pa_bus, pa->pa_device, pa->pa_function - 1); 411 id = pci_conf_read(pc, tag, PCI_ID_REG); 412 if (PCI_VENDOR(id) != PCI_VENDOR_TI) { 413 return; 414 } 415 switch (PCI_PRODUCT(id)) { 416 case PCI_PRODUCT_TI_PCI72111FM: 417 case PCI_PRODUCT_TI_PCIXX12FM: 418 break; 419 default: 420 return; 421 } 422 423 /* 424 * Disable MMC/SD on the flash media controller so the 425 * SD host takes over. 426 */ 427 reg = pci_conf_read(pc, tag, SDHC_PCI_GENERAL_CTL); 428 reg |= MMC_SD_DIS; 429 pci_conf_write(pc, tag, SDHC_PCI_GENERAL_CTL, reg); 430 } 431 432 /* Ricoh specific register */ 433 #define SDHC_PCI_MODE_KEY 0xf9 434 #define SDHC_PCI_MODE 0x150 435 #define SDHC_PCI_MODE_SD20 0x10 436 #define SDHC_PCI_BASE_FREQ_KEY 0xfc 437 #define SDHC_PCI_BASE_FREQ 0xe1 438 439 /* Some RICOH controllers need to be bumped into the right mode. */ 440 static void 441 sdhc_pci_quirk_ricoh_lower_freq_hack(struct pci_attach_args *pa) 442 { 443 /* Enable SD2.0 mode. */ 444 sdhc_pci_conf_write(pa, SDHC_PCI_MODE_KEY, 0xfc); 445 sdhc_pci_conf_write(pa, SDHC_PCI_MODE, SDHC_PCI_MODE_SD20); 446 sdhc_pci_conf_write(pa, SDHC_PCI_MODE_KEY, 0x00); 447 448 /* 449 * Some SD/MMC cards don't work with the default base 450 * clock frequency of 200MHz. Lower it to 50MHz. 451 */ 452 sdhc_pci_conf_write(pa, SDHC_PCI_BASE_FREQ_KEY, 0x01); 453 sdhc_pci_conf_write(pa, SDHC_PCI_BASE_FREQ, 50); 454 sdhc_pci_conf_write(pa, SDHC_PCI_BASE_FREQ_KEY, 0x00); 455 } 456 457 static void 458 sdhc_pci_intel_emmc_hw_reset(struct sdhc_softc *sc, struct sdhc_host *hp) 459 { 460 kmutex_t *plock = sdhc_host_lock(hp); 461 uint8_t reg; 462 463 mutex_enter(plock); 464 465 reg = sdhc_host_read_1(hp, SDHC_POWER_CTL); 466 reg |= 0x10; 467 sdhc_host_write_1(hp, SDHC_POWER_CTL, reg); 468 469 sdmmc_delay(10); 470 471 reg &= ~0x10; 472 sdhc_host_write_1(hp, SDHC_POWER_CTL, reg); 473 474 sdmmc_delay(1000); 475 476 mutex_exit(plock); 477 } 478