1 /* 2 * Copyright 2019 Emmanuel Vadot <manu@freebsd.org> 3 * Copyright (c) 2017 Ian Lepore <ian@freebsd.org> All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 22 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include <sys/param.h> 32 #include <sys/bus.h> 33 #include <sys/kernel.h> 34 #include <sys/gpio.h> 35 #include <sys/taskqueue.h> 36 37 #include <dev/mmc/bridge.h> 38 #include <dev/mmc/mmc_fdt_helpers.h> 39 40 #include <dev/gpio/gpiobusvar.h> 41 #include <dev/ofw/ofw_bus.h> 42 #include <dev/ofw/ofw_bus_subr.h> 43 44 #ifdef EXT_RESOURCES 45 #include <dev/extres/regulator/regulator.h> 46 #endif 47 48 #include "mmc_pwrseq_if.h" 49 50 static inline void 51 mmc_fdt_parse_sd_speed(phandle_t node, struct mmc_host *host) 52 { 53 bool no_18v = false; 54 55 /* 56 * Parse SD supported modes 57 * All UHS-I modes requires 1.8V signaling. 58 */ 59 if (OF_hasprop(node, "no-1-8-v")) 60 no_18v = true; 61 if (OF_hasprop(node, "cap-sd-highspeed")) 62 host->caps |= MMC_CAP_HSPEED; 63 if (OF_hasprop(node, "sd-uhs-sdr12") && no_18v == false) 64 host->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_SIGNALING_180; 65 if (OF_hasprop(node, "sd-uhs-sdr25") && no_18v == false) 66 host->caps |= MMC_CAP_UHS_SDR25 | MMC_CAP_SIGNALING_180; 67 if (OF_hasprop(node, "sd-uhs-sdr50") && no_18v == false) 68 host->caps |= MMC_CAP_UHS_SDR50 | MMC_CAP_SIGNALING_180; 69 if (OF_hasprop(node, "sd-uhs-sdr104") && no_18v == false) 70 host->caps |= MMC_CAP_UHS_SDR104 | MMC_CAP_SIGNALING_180; 71 if (OF_hasprop(node, "sd-uhs-ddr50") && no_18v == false) 72 host->caps |= MMC_CAP_UHS_DDR50 | MMC_CAP_SIGNALING_180; 73 } 74 75 static inline void 76 mmc_fdt_parse_mmc_speed(phandle_t node, struct mmc_host *host) 77 { 78 79 /* Parse eMMC supported modes */ 80 if (OF_hasprop(node, "cap-mmc-highspeed")) 81 host->caps |= MMC_CAP_HSPEED; 82 if (OF_hasprop(node, "mmc-ddr-1_2v")) 83 host->caps |= MMC_CAP_MMC_DDR52_120 | MMC_CAP_SIGNALING_120; 84 if (OF_hasprop(node, "mmc-ddr-1_8v")) 85 host->caps |= MMC_CAP_MMC_DDR52_180 | MMC_CAP_SIGNALING_180; 86 if (OF_hasprop(node, "mmc-ddr-3_3v")) 87 host->caps |= MMC_CAP_SIGNALING_330; 88 if (OF_hasprop(node, "mmc-hs200-1_2v")) 89 host->caps |= MMC_CAP_MMC_HS200_120 | MMC_CAP_SIGNALING_120; 90 if (OF_hasprop(node, "mmc-hs200-1_8v")) 91 host->caps |= MMC_CAP_MMC_HS200_180 | MMC_CAP_SIGNALING_180; 92 if (OF_hasprop(node, "mmc-hs400-1_2v")) 93 host->caps |= MMC_CAP_MMC_HS400_120 | MMC_CAP_SIGNALING_120; 94 if (OF_hasprop(node, "mmc-hs400-1_8v")) 95 host->caps |= MMC_CAP_MMC_HS400_180 | MMC_CAP_SIGNALING_180; 96 if (OF_hasprop(node, "mmc-hs400-enhanced-strobe")) 97 host->caps |= MMC_CAP_MMC_ENH_STROBE; 98 } 99 100 int 101 mmc_fdt_parse(device_t dev, phandle_t node, struct mmc_fdt_helper *helper, 102 struct mmc_host *host) 103 { 104 uint32_t bus_width; 105 phandle_t pwrseq_xref; 106 107 if (node <= 0) 108 node = ofw_bus_get_node(dev); 109 if (node <= 0) 110 return (ENXIO); 111 112 if (OF_getencprop(node, "bus-width", &bus_width, sizeof(uint32_t)) <= 0) 113 bus_width = 1; 114 115 if (bus_width >= 4) 116 host->caps |= MMC_CAP_4_BIT_DATA; 117 if (bus_width >= 8) 118 host->caps |= MMC_CAP_8_BIT_DATA; 119 120 /* 121 * max-frequency is optional, drivers should tweak this value 122 * if it's not present based on the clock that the mmc controller 123 * operates on 124 */ 125 OF_getencprop(node, "max-frequency", &host->f_max, sizeof(uint32_t)); 126 127 if (OF_hasprop(node, "broken-cd")) 128 helper->props |= MMC_PROP_BROKEN_CD; 129 if (OF_hasprop(node, "non-removable")) 130 helper->props |= MMC_PROP_NON_REMOVABLE; 131 if (OF_hasprop(node, "wp-inverted")) 132 helper->props |= MMC_PROP_WP_INVERTED; 133 if (OF_hasprop(node, "cd-inverted")) 134 helper->props |= MMC_PROP_CD_INVERTED; 135 if (OF_hasprop(node, "no-sdio")) 136 helper->props |= MMC_PROP_NO_SDIO; 137 if (OF_hasprop(node, "no-sd")) 138 helper->props |= MMC_PROP_NO_SD; 139 if (OF_hasprop(node, "no-mmc")) 140 helper->props |= MMC_PROP_NO_MMC; 141 142 if (!(helper->props & MMC_PROP_NO_SD)) 143 mmc_fdt_parse_sd_speed(node, host); 144 145 if (!(helper->props & MMC_PROP_NO_MMC)) 146 mmc_fdt_parse_mmc_speed(node, host); 147 148 #ifdef EXT_RESOURCES 149 /* 150 * Get the regulators if they are supported and 151 * clean the non supported modes based on the available voltages. 152 */ 153 if (regulator_get_by_ofw_property(dev, 0, "vmmc-supply", 154 &helper->vmmc_supply) == 0) { 155 if (bootverbose) 156 device_printf(dev, "vmmc-supply regulator found\n"); 157 } 158 if (regulator_get_by_ofw_property(dev, 0, "vqmmc-supply", 159 &helper->vqmmc_supply) == 0 && bootverbose) { 160 if (bootverbose) 161 device_printf(dev, "vqmmc-supply regulator found\n"); 162 } 163 164 if (helper->vqmmc_supply != NULL) { 165 if (regulator_check_voltage(helper->vqmmc_supply, 1200000) == 0) 166 host->caps |= MMC_CAP_SIGNALING_120; 167 else 168 host->caps &= ~( MMC_CAP_MMC_HS400_120 | 169 MMC_CAP_MMC_HS200_120 | 170 MMC_CAP_MMC_DDR52_120); 171 if (regulator_check_voltage(helper->vqmmc_supply, 1800000) == 0) 172 host->caps |= MMC_CAP_SIGNALING_180; 173 else 174 host->caps &= ~(MMC_CAP_MMC_HS400_180 | 175 MMC_CAP_MMC_HS200_180 | 176 MMC_CAP_MMC_DDR52_180 | 177 MMC_CAP_UHS_DDR50 | 178 MMC_CAP_UHS_SDR104 | 179 MMC_CAP_UHS_SDR50 | 180 MMC_CAP_UHS_SDR25); 181 if (regulator_check_voltage(helper->vqmmc_supply, 3300000) == 0) 182 host->caps |= MMC_CAP_SIGNALING_330; 183 } else 184 host->caps |= MMC_CAP_SIGNALING_330; 185 #endif 186 187 if (OF_hasprop(node, "mmc-pwrseq")) { 188 if (OF_getencprop(node, "mmc-pwrseq", &pwrseq_xref, sizeof(pwrseq_xref)) == -1) { 189 device_printf(dev, "Cannot get the pwrseq_xref property\n"); 190 return (ENXIO); 191 } 192 helper->mmc_pwrseq = OF_device_from_xref(pwrseq_xref); 193 } 194 return (0); 195 } 196 197 /* 198 * Card detect interrupt handler. 199 */ 200 static void 201 cd_intr(void *arg) 202 { 203 struct mmc_fdt_helper *helper = arg; 204 205 taskqueue_enqueue_timeout(taskqueue_swi_giant, 206 &helper->cd_delayed_task, -(hz / 2)); 207 } 208 209 static void 210 cd_card_task(void *arg, int pending __unused) 211 { 212 struct mmc_fdt_helper *helper = arg; 213 bool cd_present; 214 215 cd_present = mmc_fdt_gpio_get_present(helper); 216 if(helper->cd_handler && cd_present != helper->cd_present) 217 helper->cd_handler(helper->dev, 218 cd_present); 219 helper->cd_present = cd_present; 220 221 /* If we're polling re-schedule the task */ 222 if (helper->cd_ihandler == NULL) 223 taskqueue_enqueue_timeout_sbt(taskqueue_swi_giant, 224 &helper->cd_delayed_task, mstosbt(500), 0, C_PREL(2)); 225 } 226 227 /* 228 * Card detect setup. 229 */ 230 static void 231 cd_setup(struct mmc_fdt_helper *helper, phandle_t node) 232 { 233 int pincaps; 234 device_t dev; 235 const char *cd_mode_str; 236 237 dev = helper->dev; 238 239 TIMEOUT_TASK_INIT(taskqueue_swi_giant, &helper->cd_delayed_task, 0, 240 cd_card_task, helper); 241 242 /* 243 * If the device is flagged as non-removable, set that slot option, and 244 * set a flag to make sdhci_fdt_gpio_get_present() always return true. 245 */ 246 if (helper->props & MMC_PROP_NON_REMOVABLE) { 247 helper->cd_disabled = true; 248 if (bootverbose) 249 device_printf(dev, "Non-removable media\n"); 250 return; 251 } 252 253 /* 254 * If there is no cd-gpios property, then presumably the hardware 255 * PRESENT_STATE register and interrupts will reflect card state 256 * properly, and there's nothing more for us to do. Our get_present() 257 * will return sdhci_generic_get_card_present() because cd_pin is NULL. 258 * 259 * If there is a property, make sure we can read the pin. 260 */ 261 if (gpio_pin_get_by_ofw_property(dev, node, "cd-gpios", 262 &helper->cd_pin)) 263 return; 264 265 if (gpio_pin_getcaps(helper->cd_pin, &pincaps) != 0 || 266 !(pincaps & GPIO_PIN_INPUT)) { 267 device_printf(dev, "Cannot read card-detect gpio pin; " 268 "setting card-always-present flag.\n"); 269 helper->cd_disabled = true; 270 return; 271 } 272 273 /* 274 * If the pin can trigger an interrupt on both rising and falling edges, 275 * we can use it to detect card presence changes. If not, we'll request 276 * card presence polling instead of using interrupts. 277 */ 278 if (!(pincaps & GPIO_INTR_EDGE_BOTH)) { 279 if (bootverbose) 280 device_printf(dev, "Cannot configure " 281 "GPIO_INTR_EDGE_BOTH for card detect\n"); 282 goto without_interrupts; 283 } 284 285 if (helper->cd_handler == NULL) { 286 if (bootverbose) 287 device_printf(dev, "Cannot configure " 288 "interrupts as no cd_handler is set\n"); 289 goto without_interrupts; 290 } 291 292 /* 293 * Create an interrupt resource from the pin and set up the interrupt. 294 */ 295 if ((helper->cd_ires = gpio_alloc_intr_resource(dev, &helper->cd_irid, 296 RF_ACTIVE, helper->cd_pin, GPIO_INTR_EDGE_BOTH)) == NULL) { 297 if (bootverbose) 298 device_printf(dev, "Cannot allocate an IRQ for card " 299 "detect GPIO\n"); 300 goto without_interrupts; 301 } 302 303 if (bus_setup_intr(dev, helper->cd_ires, INTR_TYPE_BIO | INTR_MPSAFE, 304 NULL, cd_intr, helper, &helper->cd_ihandler) != 0) { 305 device_printf(dev, "Unable to setup card-detect irq handler\n"); 306 helper->cd_ihandler = NULL; 307 goto without_interrupts; 308 } 309 310 without_interrupts: 311 /* 312 * If we have a readable gpio pin, but didn't successfully configure 313 * gpio interrupts, setup a timeout task to poll the pin 314 */ 315 if (helper->cd_ihandler == NULL) { 316 cd_mode_str = "polling"; 317 } else { 318 cd_mode_str = "interrupts"; 319 } 320 321 if (bootverbose) { 322 device_printf(dev, "Card presence detect on %s pin %u, " 323 "configured for %s.\n", 324 device_get_nameunit(helper->cd_pin->dev), helper->cd_pin->pin, 325 cd_mode_str); 326 } 327 } 328 329 /* 330 * Write protect setup. 331 */ 332 static void 333 wp_setup(struct mmc_fdt_helper *helper, phandle_t node) 334 { 335 device_t dev; 336 337 dev = helper->dev; 338 339 if (OF_hasprop(node, "disable-wp")) { 340 helper->wp_disabled = true; 341 if (bootverbose) 342 device_printf(dev, "Write protect disabled\n"); 343 return; 344 } 345 346 if (gpio_pin_get_by_ofw_property(dev, node, "wp-gpios", &helper->wp_pin)) 347 return; 348 349 if (bootverbose) 350 device_printf(dev, "Write protect switch on %s pin %u\n", 351 device_get_nameunit(helper->wp_pin->dev), helper->wp_pin->pin); 352 } 353 354 int 355 mmc_fdt_gpio_setup(device_t dev, phandle_t node, struct mmc_fdt_helper *helper, 356 mmc_fdt_cd_handler handler) 357 { 358 359 if (node <= 0) 360 node = ofw_bus_get_node(dev); 361 if (node <= 0) { 362 device_printf(dev, "Cannot get node for device\n"); 363 return (ENXIO); 364 } 365 366 helper->dev = dev; 367 helper->cd_handler = handler; 368 cd_setup(helper, node); 369 wp_setup(helper, node); 370 371 /* 372 * Schedule a card detection 373 */ 374 taskqueue_enqueue_timeout_sbt(taskqueue_swi_giant, 375 &helper->cd_delayed_task, mstosbt(500), 0, C_PREL(2)); 376 return (0); 377 } 378 379 void 380 mmc_fdt_gpio_teardown(struct mmc_fdt_helper *helper) 381 { 382 383 if (helper == NULL) 384 return; 385 386 if (helper->cd_ihandler != NULL) 387 bus_teardown_intr(helper->dev, helper->cd_ires, helper->cd_ihandler); 388 if (helper->wp_pin != NULL) 389 gpio_pin_release(helper->wp_pin); 390 if (helper->cd_pin != NULL) 391 gpio_pin_release(helper->cd_pin); 392 if (helper->cd_ires != NULL) 393 bus_release_resource(helper->dev, SYS_RES_IRQ, 0, helper->cd_ires); 394 395 taskqueue_drain_timeout(taskqueue_swi_giant, &helper->cd_delayed_task); 396 } 397 398 bool 399 mmc_fdt_gpio_get_present(struct mmc_fdt_helper *helper) 400 { 401 bool pinstate; 402 403 if (helper->cd_disabled) 404 return (true); 405 if (helper->cd_pin == NULL) 406 return (false); 407 408 gpio_pin_is_active(helper->cd_pin, &pinstate); 409 410 return (pinstate ^ (bool)(helper->props & MMC_PROP_CD_INVERTED)); 411 } 412 413 bool 414 mmc_fdt_gpio_get_readonly(struct mmc_fdt_helper *helper) 415 { 416 bool pinstate; 417 418 if (helper->wp_disabled) 419 return (false); 420 421 if (helper->wp_pin == NULL) 422 return (false); 423 424 gpio_pin_is_active(helper->wp_pin, &pinstate); 425 426 return (pinstate ^ (bool)(helper->props & MMC_PROP_WP_INVERTED)); 427 } 428 429 void 430 mmc_fdt_set_power(struct mmc_fdt_helper *helper, enum mmc_power_mode power_mode) 431 { 432 int reg_status; 433 int rv; 434 435 switch (power_mode) { 436 case power_on: 437 break; 438 case power_off: 439 if (helper->vmmc_supply) { 440 rv = regulator_status(helper->vmmc_supply, ®_status); 441 if (rv == 0 && reg_status == REGULATOR_STATUS_ENABLED) 442 regulator_disable(helper->vmmc_supply); 443 } 444 if (helper->vqmmc_supply) { 445 rv = regulator_status(helper->vqmmc_supply, ®_status); 446 if (rv == 0 && reg_status == REGULATOR_STATUS_ENABLED) 447 regulator_disable(helper->vqmmc_supply); 448 } 449 if (helper->mmc_pwrseq) 450 MMC_PWRSEQ_SET_POWER(helper->mmc_pwrseq, false); 451 break; 452 case power_up: 453 if (helper->vmmc_supply) { 454 rv = regulator_status(helper->vmmc_supply, ®_status); 455 if (rv == 0 && reg_status != REGULATOR_STATUS_ENABLED) 456 regulator_enable(helper->vmmc_supply); 457 } 458 if (helper->vqmmc_supply) { 459 rv = regulator_status(helper->vqmmc_supply, ®_status); 460 if (rv == 0 && reg_status != REGULATOR_STATUS_ENABLED) 461 regulator_enable(helper->vqmmc_supply); 462 } 463 if (helper->mmc_pwrseq) 464 MMC_PWRSEQ_SET_POWER(helper->mmc_pwrseq, true); 465 break; 466 } 467 } 468