1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2012 Thomas Skibo 5 * Copyright (c) 2008 Alexander Motin <mav@FreeBSD.org> 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 /* Generic driver to attach sdhci controllers on simplebus. 30 * Derived mainly from sdhci_pci.c 31 */ 32 33 #include <sys/cdefs.h> 34 __FBSDID("$FreeBSD$"); 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/bus.h> 39 #include <sys/kernel.h> 40 #include <sys/lock.h> 41 #include <sys/module.h> 42 #include <sys/mutex.h> 43 #include <sys/resource.h> 44 #include <sys/rman.h> 45 #include <sys/sysctl.h> 46 #include <sys/taskqueue.h> 47 48 #include <machine/bus.h> 49 #include <machine/resource.h> 50 51 #include <dev/fdt/fdt_common.h> 52 #include <dev/ofw/ofw_bus.h> 53 #include <dev/ofw/ofw_bus_subr.h> 54 55 #include <dev/ofw/ofw_subr.h> 56 #include <dev/extres/clk/clk.h> 57 #include <dev/extres/clk/clk_fixed.h> 58 #include <dev/extres/syscon/syscon.h> 59 #include <dev/extres/phy/phy.h> 60 61 #include <dev/mmc/bridge.h> 62 63 #include <dev/sdhci/sdhci.h> 64 65 #include "mmcbr_if.h" 66 #include "sdhci_if.h" 67 68 #include "opt_mmccam.h" 69 70 #include "clkdev_if.h" 71 #include "syscon_if.h" 72 73 #define MAX_SLOTS 6 74 #define SDHCI_FDT_ARMADA38X 1 75 #define SDHCI_FDT_GENERIC 2 76 #define SDHCI_FDT_XLNX_ZY7 3 77 #define SDHCI_FDT_QUALCOMM 4 78 #define SDHCI_FDT_RK3399 5 79 #define SDHCI_FDT_RK3568 6 80 #define SDHCI_FDT_XLNX_ZMP 7 81 82 #define RK3399_GRF_EMMCCORE_CON0 0xf000 83 #define RK3399_CORECFG_BASECLKFREQ 0xff00 84 #define RK3399_CORECFG_TIMEOUTCLKUNIT (1 << 7) 85 #define RK3399_CORECFG_TUNINGCOUNT 0x3f 86 #define RK3399_GRF_EMMCCORE_CON11 0xf02c 87 #define RK3399_CORECFG_CLOCKMULTIPLIER 0xff 88 89 #define RK3568_EMMC_HOST_CTRL 0x0508 90 #define RK3568_EMMC_EMMC_CTRL 0x052c 91 #define RK3568_EMMC_ATCTRL 0x0540 92 #define RK3568_EMMC_DLL_CTRL 0x0800 93 #define DLL_CTRL_SRST 0x00000001 94 #define DLL_CTRL_START 0x00000002 95 #define DLL_CTRL_START_POINT_DEFAULT 0x00050000 96 #define DLL_CTRL_INCREMENT_DEFAULT 0x00000200 97 98 #define RK3568_EMMC_DLL_RXCLK 0x0804 99 #define DLL_RXCLK_DELAY_ENABLE 0x08000000 100 #define DLL_RXCLK_NO_INV 0x20000000 101 102 #define RK3568_EMMC_DLL_TXCLK 0x0808 103 #define DLL_TXCLK_DELAY_ENABLE 0x08000000 104 #define DLL_TXCLK_TAPNUM_DEFAULT 0x00000008 105 #define DLL_TXCLK_TAPNUM_FROM_SW 0x01000000 106 107 #define RK3568_EMMC_DLL_STRBIN 0x080c 108 #define DLL_STRBIN_DELAY_ENABLE 0x08000000 109 #define DLL_STRBIN_TAPNUM_DEFAULT 0x00000008 110 #define DLL_STRBIN_TAPNUM_FROM_SW 0x01000000 111 112 #define RK3568_EMMC_DLL_STATUS0 0x0840 113 #define DLL_STATUS0_DLL_LOCK 0x00000100 114 #define DLL_STATUS0_DLL_TIMEOUT 0x00000200 115 116 #define LOWEST_SET_BIT(mask) ((((mask) - 1) & (mask)) ^ (mask)) 117 #define SHIFTIN(x, mask) ((x) * LOWEST_SET_BIT(mask)) 118 119 #define EMMCCARDCLK_ID 1000 120 121 static struct ofw_compat_data compat_data[] = { 122 { "marvell,armada-380-sdhci", SDHCI_FDT_ARMADA38X }, 123 { "sdhci_generic", SDHCI_FDT_GENERIC }, 124 { "qcom,sdhci-msm-v4", SDHCI_FDT_QUALCOMM }, 125 { "rockchip,rk3399-sdhci-5.1", SDHCI_FDT_RK3399 }, 126 { "xlnx,zy7_sdhci", SDHCI_FDT_XLNX_ZY7 }, 127 { "rockchip,rk3568-dwcmshc", SDHCI_FDT_RK3568 }, 128 { "xlnx,zynqmp-8.9a", SDHCI_FDT_XLNX_ZMP }, 129 { NULL, 0 } 130 }; 131 132 struct sdhci_fdt_softc { 133 device_t dev; /* Controller device */ 134 u_int quirks; /* Chip specific quirks */ 135 u_int caps; /* If we override SDHCI_CAPABILITIES */ 136 uint32_t max_clk; /* Max possible freq */ 137 uint8_t sdma_boundary; /* If we override the SDMA boundary */ 138 struct resource *irq_res; /* IRQ resource */ 139 void *intrhand; /* Interrupt handle */ 140 141 int num_slots; /* Number of slots on this controller*/ 142 struct sdhci_slot slots[MAX_SLOTS]; 143 struct resource *mem_res[MAX_SLOTS]; /* Memory resource */ 144 145 bool wp_inverted; /* WP pin is inverted */ 146 bool wp_disabled; /* WP pin is not supported */ 147 bool no_18v; /* No 1.8V support */ 148 149 clk_t clk_xin; /* xin24m fixed clock */ 150 clk_t clk_ahb; /* ahb clock */ 151 clk_t clk_core; /* core clock */ 152 phy_t phy; /* phy to be used */ 153 }; 154 155 struct rk3399_emmccardclk_sc { 156 device_t clkdev; 157 bus_addr_t reg; 158 }; 159 160 static int 161 rk3399_emmccardclk_init(struct clknode *clk, device_t dev) 162 { 163 164 clknode_init_parent_idx(clk, 0); 165 return (0); 166 } 167 168 static clknode_method_t rk3399_emmccardclk_clknode_methods[] = { 169 /* Device interface */ 170 CLKNODEMETHOD(clknode_init, rk3399_emmccardclk_init), 171 CLKNODEMETHOD_END 172 }; 173 DEFINE_CLASS_1(rk3399_emmccardclk_clknode, rk3399_emmccardclk_clknode_class, 174 rk3399_emmccardclk_clknode_methods, sizeof(struct rk3399_emmccardclk_sc), 175 clknode_class); 176 177 static int 178 rk3399_ofw_map(struct clkdom *clkdom, uint32_t ncells, 179 phandle_t *cells, struct clknode **clk) 180 { 181 182 if (ncells == 0) 183 *clk = clknode_find_by_id(clkdom, EMMCCARDCLK_ID); 184 else 185 return (ERANGE); 186 187 if (*clk == NULL) 188 return (ENXIO); 189 return (0); 190 } 191 192 static void 193 sdhci_init_rk3399_emmccardclk(device_t dev) 194 { 195 struct clknode_init_def def; 196 struct rk3399_emmccardclk_sc *sc; 197 struct clkdom *clkdom; 198 struct clknode *clk; 199 clk_t clk_parent; 200 bus_addr_t paddr; 201 bus_size_t psize; 202 const char **clknames; 203 phandle_t node; 204 int i, nclocks, ncells, error; 205 206 node = ofw_bus_get_node(dev); 207 208 if (ofw_reg_to_paddr(node, 0, &paddr, &psize, NULL) != 0) { 209 device_printf(dev, "cannot parse 'reg' property\n"); 210 return; 211 } 212 213 error = ofw_bus_parse_xref_list_get_length(node, "clocks", 214 "#clock-cells", &ncells); 215 if (error != 0 || ncells != 2) { 216 device_printf(dev, "couldn't find parent clocks\n"); 217 return; 218 } 219 220 nclocks = ofw_bus_string_list_to_array(node, "clock-output-names", 221 &clknames); 222 /* No clocks to export */ 223 if (nclocks <= 0) 224 return; 225 226 if (nclocks != 1) { 227 device_printf(dev, "Having %d clock instead of 1, aborting\n", 228 nclocks); 229 return; 230 } 231 232 clkdom = clkdom_create(dev); 233 clkdom_set_ofw_mapper(clkdom, rk3399_ofw_map); 234 235 memset(&def, 0, sizeof(def)); 236 def.id = EMMCCARDCLK_ID; 237 def.name = clknames[0]; 238 def.parent_names = malloc(sizeof(char *) * ncells, M_OFWPROP, M_WAITOK); 239 for (i = 0; i < ncells; i++) { 240 error = clk_get_by_ofw_index(dev, 0, i, &clk_parent); 241 if (error != 0) { 242 device_printf(dev, "cannot get clock %d\n", error); 243 return; 244 } 245 def.parent_names[i] = clk_get_name(clk_parent); 246 if (bootverbose) 247 device_printf(dev, "clk parent: %s\n", 248 def.parent_names[i]); 249 clk_release(clk_parent); 250 } 251 def.parent_cnt = ncells; 252 253 clk = clknode_create(clkdom, &rk3399_emmccardclk_clknode_class, &def); 254 if (clk == NULL) { 255 device_printf(dev, "cannot create clknode\n"); 256 return; 257 } 258 259 sc = clknode_get_softc(clk); 260 sc->reg = paddr; 261 sc->clkdev = device_get_parent(dev); 262 263 clknode_register(clkdom, clk); 264 265 if (clkdom_finit(clkdom) != 0) { 266 device_printf(dev, "cannot finalize clkdom initialization\n"); 267 return; 268 } 269 270 if (bootverbose) 271 clkdom_dump(clkdom); 272 } 273 274 static int 275 sdhci_init_rk3399(device_t dev) 276 { 277 struct sdhci_fdt_softc *sc = device_get_softc(dev); 278 struct syscon *grf = NULL; 279 phandle_t node; 280 uint64_t freq; 281 uint32_t mask, val; 282 int error; 283 284 /* Get and activate clocks */ 285 error = clk_get_by_ofw_name(dev, 0, "clk_xin", &sc->clk_xin); 286 if (error != 0) { 287 device_printf(dev, "cannot get xin clock\n"); 288 return (ENXIO); 289 } 290 error = clk_enable(sc->clk_xin); 291 if (error != 0) { 292 device_printf(dev, "cannot enable xin clock\n"); 293 return (ENXIO); 294 } 295 error = clk_get_freq(sc->clk_xin, &freq); 296 if (error != 0) { 297 device_printf(dev, "cannot get xin clock frequency\n"); 298 return (ENXIO); 299 } 300 error = clk_get_by_ofw_name(dev, 0, "clk_ahb", &sc->clk_ahb); 301 if (error != 0) { 302 device_printf(dev, "cannot get ahb clock\n"); 303 return (ENXIO); 304 } 305 error = clk_enable(sc->clk_ahb); 306 if (error != 0) { 307 device_printf(dev, "cannot enable ahb clock\n"); 308 return (ENXIO); 309 } 310 311 /* Register clock */ 312 sdhci_init_rk3399_emmccardclk(dev); 313 314 /* Enable PHY */ 315 error = phy_get_by_ofw_name(dev, 0, "phy_arasan", &sc->phy); 316 if (error != 0) { 317 device_printf(dev, "Could not get phy\n"); 318 return (ENXIO); 319 } 320 error = phy_enable(sc->phy); 321 if (error != 0) { 322 device_printf(dev, "Could not enable phy\n"); 323 return (ENXIO); 324 } 325 /* Get syscon */ 326 node = ofw_bus_get_node(dev); 327 if (OF_hasprop(node, "arasan,soc-ctl-syscon") && 328 syscon_get_by_ofw_property(dev, node, 329 "arasan,soc-ctl-syscon", &grf) != 0) { 330 device_printf(dev, "cannot get grf driver handle\n"); 331 return (ENXIO); 332 } 333 334 /* Disable clock multiplier */ 335 mask = RK3399_CORECFG_CLOCKMULTIPLIER; 336 val = 0; 337 SYSCON_WRITE_4(grf, RK3399_GRF_EMMCCORE_CON11, (mask << 16) | val); 338 339 /* Set base clock frequency */ 340 mask = RK3399_CORECFG_BASECLKFREQ; 341 val = SHIFTIN((freq + (1000000 / 2)) / 1000000, 342 RK3399_CORECFG_BASECLKFREQ); 343 SYSCON_WRITE_4(grf, RK3399_GRF_EMMCCORE_CON0, (mask << 16) | val); 344 345 return (0); 346 } 347 348 static uint8_t 349 sdhci_fdt_read_1(device_t dev, struct sdhci_slot *slot, bus_size_t off) 350 { 351 struct sdhci_fdt_softc *sc = device_get_softc(dev); 352 353 return (bus_read_1(sc->mem_res[slot->num], off)); 354 } 355 356 static void 357 sdhci_fdt_write_1(device_t dev, struct sdhci_slot *slot, bus_size_t off, 358 uint8_t val) 359 { 360 struct sdhci_fdt_softc *sc = device_get_softc(dev); 361 362 bus_write_1(sc->mem_res[slot->num], off, val); 363 } 364 365 static uint16_t 366 sdhci_fdt_read_2(device_t dev, struct sdhci_slot *slot, bus_size_t off) 367 { 368 struct sdhci_fdt_softc *sc = device_get_softc(dev); 369 370 return (bus_read_2(sc->mem_res[slot->num], off)); 371 } 372 373 static void 374 sdhci_fdt_write_2(device_t dev, struct sdhci_slot *slot, bus_size_t off, 375 uint16_t val) 376 { 377 struct sdhci_fdt_softc *sc = device_get_softc(dev); 378 379 bus_write_2(sc->mem_res[slot->num], off, val); 380 } 381 382 static uint32_t 383 sdhci_fdt_read_4(device_t dev, struct sdhci_slot *slot, bus_size_t off) 384 { 385 struct sdhci_fdt_softc *sc = device_get_softc(dev); 386 uint32_t val32; 387 388 val32 = bus_read_4(sc->mem_res[slot->num], off); 389 if (off == SDHCI_CAPABILITIES && sc->no_18v) 390 val32 &= ~SDHCI_CAN_VDD_180; 391 392 return (val32); 393 } 394 395 static void 396 sdhci_fdt_write_4(device_t dev, struct sdhci_slot *slot, bus_size_t off, 397 uint32_t val) 398 { 399 struct sdhci_fdt_softc *sc = device_get_softc(dev); 400 401 bus_write_4(sc->mem_res[slot->num], off, val); 402 } 403 404 static void 405 sdhci_fdt_read_multi_4(device_t dev, struct sdhci_slot *slot, 406 bus_size_t off, uint32_t *data, bus_size_t count) 407 { 408 struct sdhci_fdt_softc *sc = device_get_softc(dev); 409 410 bus_read_multi_4(sc->mem_res[slot->num], off, data, count); 411 } 412 413 static void 414 sdhci_fdt_write_multi_4(device_t dev, struct sdhci_slot *slot, 415 bus_size_t off, uint32_t *data, bus_size_t count) 416 { 417 struct sdhci_fdt_softc *sc = device_get_softc(dev); 418 419 bus_write_multi_4(sc->mem_res[slot->num], off, data, count); 420 } 421 422 static void 423 sdhci_fdt_intr(void *arg) 424 { 425 struct sdhci_fdt_softc *sc = (struct sdhci_fdt_softc *)arg; 426 int i; 427 428 for (i = 0; i < sc->num_slots; i++) 429 sdhci_generic_intr(&sc->slots[i]); 430 } 431 432 static int 433 sdhci_fdt_get_ro(device_t bus, device_t dev) 434 { 435 struct sdhci_fdt_softc *sc = device_get_softc(bus); 436 437 if (sc->wp_disabled) 438 return (false); 439 return (sdhci_generic_get_ro(bus, dev) ^ sc->wp_inverted); 440 } 441 442 static int 443 sdhci_fdt_set_clock(device_t dev, struct sdhci_slot *slot, int clock) 444 { 445 struct sdhci_fdt_softc *sc = device_get_softc(dev); 446 int32_t val; 447 int i; 448 449 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 450 SDHCI_FDT_RK3568) { 451 if (clock == 400000) 452 clock = 375000; 453 454 if (clock) { 455 clk_set_freq(sc->clk_core, clock, 0); 456 457 if (clock <= 52000000) { 458 bus_write_4(sc->mem_res[slot->num], 459 RK3568_EMMC_DLL_CTRL, 0x0); 460 bus_write_4(sc->mem_res[slot->num], 461 RK3568_EMMC_DLL_RXCLK, DLL_RXCLK_NO_INV); 462 bus_write_4(sc->mem_res[slot->num], 463 RK3568_EMMC_DLL_TXCLK, 0x0); 464 bus_write_4(sc->mem_res[slot->num], 465 RK3568_EMMC_DLL_STRBIN, 0x0); 466 return (clock); 467 } 468 469 bus_write_4(sc->mem_res[slot->num], 470 RK3568_EMMC_DLL_CTRL, DLL_CTRL_START); 471 DELAY(1000); 472 bus_write_4(sc->mem_res[slot->num], 473 RK3568_EMMC_DLL_CTRL, 0); 474 bus_write_4(sc->mem_res[slot->num], 475 RK3568_EMMC_DLL_CTRL, DLL_CTRL_START_POINT_DEFAULT | 476 DLL_CTRL_INCREMENT_DEFAULT | DLL_CTRL_START); 477 for (i = 0; i < 500; i++) { 478 val = bus_read_4(sc->mem_res[slot->num], 479 RK3568_EMMC_DLL_STATUS0); 480 if (val & DLL_STATUS0_DLL_LOCK && 481 !(val & DLL_STATUS0_DLL_TIMEOUT)) 482 break; 483 DELAY(1000); 484 } 485 bus_write_4(sc->mem_res[slot->num], RK3568_EMMC_ATCTRL, 486 (0x1 << 16 | 0x2 << 17 | 0x3 << 19)); 487 bus_write_4(sc->mem_res[slot->num], 488 RK3568_EMMC_DLL_RXCLK, 489 DLL_RXCLK_DELAY_ENABLE | DLL_RXCLK_NO_INV); 490 bus_write_4(sc->mem_res[slot->num], 491 RK3568_EMMC_DLL_TXCLK, DLL_TXCLK_DELAY_ENABLE | 492 DLL_TXCLK_TAPNUM_DEFAULT|DLL_TXCLK_TAPNUM_FROM_SW); 493 bus_write_4(sc->mem_res[slot->num], 494 RK3568_EMMC_DLL_STRBIN, DLL_STRBIN_DELAY_ENABLE | 495 DLL_STRBIN_TAPNUM_DEFAULT | 496 DLL_STRBIN_TAPNUM_FROM_SW); 497 } 498 } 499 return (clock); 500 } 501 502 static int 503 sdhci_fdt_probe(device_t dev) 504 { 505 struct sdhci_fdt_softc *sc = device_get_softc(dev); 506 phandle_t node; 507 pcell_t cid; 508 509 sc->quirks = 0; 510 sc->num_slots = 1; 511 sc->max_clk = 0; 512 513 if (!ofw_bus_status_okay(dev)) 514 return (ENXIO); 515 516 switch (ofw_bus_search_compatible(dev, compat_data)->ocd_data) { 517 case SDHCI_FDT_ARMADA38X: 518 sc->quirks = SDHCI_QUIRK_BROKEN_AUTO_STOP; 519 device_set_desc(dev, "ARMADA38X SDHCI controller"); 520 break; 521 case SDHCI_FDT_GENERIC: 522 device_set_desc(dev, "generic fdt SDHCI controller"); 523 break; 524 case SDHCI_FDT_QUALCOMM: 525 sc->quirks = SDHCI_QUIRK_ALL_SLOTS_NON_REMOVABLE | 526 SDHCI_QUIRK_BROKEN_SDMA_BOUNDARY; 527 sc->sdma_boundary = SDHCI_BLKSZ_SDMA_BNDRY_4K; 528 device_set_desc(dev, "Qualcomm FDT SDHCI controller"); 529 break; 530 case SDHCI_FDT_RK3399: 531 device_set_desc(dev, "Rockchip RK3399 fdt SDHCI controller"); 532 break; 533 case SDHCI_FDT_XLNX_ZY7: 534 sc->quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK; 535 device_set_desc(dev, "Zynq-7000 generic fdt SDHCI controller"); 536 break; 537 case SDHCI_FDT_RK3568: 538 device_set_desc(dev, "Rockchip RK3568 fdt SDHCI controller"); 539 break; 540 case SDHCI_FDT_XLNX_ZMP: 541 device_set_desc(dev, "ZynqMP generic fdt SDHCI controller"); 542 break; 543 default: 544 return (ENXIO); 545 } 546 547 node = ofw_bus_get_node(dev); 548 549 /* Allow dts to patch quirks, slots, and max-frequency. */ 550 if ((OF_getencprop(node, "quirks", &cid, sizeof(cid))) > 0) 551 sc->quirks = cid; 552 if ((OF_getencprop(node, "num-slots", &cid, sizeof(cid))) > 0) 553 sc->num_slots = cid; 554 if ((OF_getencprop(node, "max-frequency", &cid, sizeof(cid))) > 0) 555 sc->max_clk = cid; 556 if (OF_hasprop(node, "no-1-8-v")) 557 sc->no_18v = true; 558 if (OF_hasprop(node, "wp-inverted")) 559 sc->wp_inverted = true; 560 if (OF_hasprop(node, "disable-wp")) 561 sc->wp_disabled = true; 562 563 return (0); 564 } 565 566 static int 567 sdhci_fdt_attach(device_t dev) 568 { 569 struct sdhci_fdt_softc *sc = device_get_softc(dev); 570 struct sdhci_slot *slot; 571 int err, slots, rid, i; 572 573 sc->dev = dev; 574 575 /* Allocate IRQ. */ 576 rid = 0; 577 sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, 578 RF_ACTIVE); 579 if (sc->irq_res == NULL) { 580 device_printf(dev, "Can't allocate IRQ\n"); 581 return (ENOMEM); 582 } 583 584 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 585 SDHCI_FDT_RK3399) { 586 /* Initialize SDHCI */ 587 err = sdhci_init_rk3399(dev); 588 if (err != 0) { 589 device_printf(dev, "Cannot init RK3399 SDHCI\n"); 590 return (err); 591 } 592 } 593 594 if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 595 SDHCI_FDT_RK3568) { 596 /* setup & enable clocks */ 597 if (clk_get_by_ofw_name(dev, 0, "core", &sc->clk_core)) { 598 device_printf(dev, "cannot get core clock\n"); 599 return (ENXIO); 600 } 601 clk_enable(sc->clk_core); 602 } 603 604 /* Scan all slots. */ 605 slots = sc->num_slots; /* number of slots determined in probe(). */ 606 sc->num_slots = 0; 607 for (i = 0; i < slots; i++) { 608 slot = &sc->slots[sc->num_slots]; 609 610 /* Allocate memory. */ 611 rid = 0; 612 sc->mem_res[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY, 613 &rid, RF_ACTIVE); 614 if (sc->mem_res[i] == NULL) { 615 device_printf(dev, 616 "Can't allocate memory for slot %d\n", i); 617 continue; 618 } 619 620 slot->quirks = sc->quirks; 621 slot->caps = sc->caps; 622 slot->max_clk = sc->max_clk; 623 slot->sdma_boundary = sc->sdma_boundary; 624 625 if (sdhci_init_slot(dev, slot, i) != 0) 626 continue; 627 628 sc->num_slots++; 629 } 630 device_printf(dev, "%d slot(s) allocated\n", sc->num_slots); 631 632 /* Activate the interrupt */ 633 err = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE, 634 NULL, sdhci_fdt_intr, sc, &sc->intrhand); 635 if (err) { 636 device_printf(dev, "Cannot setup IRQ\n"); 637 return (err); 638 } 639 640 /* Process cards detection. */ 641 for (i = 0; i < sc->num_slots; i++) 642 sdhci_start_slot(&sc->slots[i]); 643 644 return (0); 645 } 646 647 static int 648 sdhci_fdt_detach(device_t dev) 649 { 650 struct sdhci_fdt_softc *sc = device_get_softc(dev); 651 int i; 652 653 bus_generic_detach(dev); 654 bus_teardown_intr(dev, sc->irq_res, sc->intrhand); 655 bus_release_resource(dev, SYS_RES_IRQ, rman_get_rid(sc->irq_res), 656 sc->irq_res); 657 658 for (i = 0; i < sc->num_slots; i++) { 659 sdhci_cleanup_slot(&sc->slots[i]); 660 bus_release_resource(dev, SYS_RES_MEMORY, 661 rman_get_rid(sc->mem_res[i]), sc->mem_res[i]); 662 } 663 664 return (0); 665 } 666 667 static device_method_t sdhci_fdt_methods[] = { 668 /* device_if */ 669 DEVMETHOD(device_probe, sdhci_fdt_probe), 670 DEVMETHOD(device_attach, sdhci_fdt_attach), 671 DEVMETHOD(device_detach, sdhci_fdt_detach), 672 673 /* Bus interface */ 674 DEVMETHOD(bus_read_ivar, sdhci_generic_read_ivar), 675 DEVMETHOD(bus_write_ivar, sdhci_generic_write_ivar), 676 677 /* mmcbr_if */ 678 DEVMETHOD(mmcbr_update_ios, sdhci_generic_update_ios), 679 DEVMETHOD(mmcbr_request, sdhci_generic_request), 680 DEVMETHOD(mmcbr_get_ro, sdhci_fdt_get_ro), 681 DEVMETHOD(mmcbr_acquire_host, sdhci_generic_acquire_host), 682 DEVMETHOD(mmcbr_release_host, sdhci_generic_release_host), 683 684 /* SDHCI registers accessors */ 685 DEVMETHOD(sdhci_read_1, sdhci_fdt_read_1), 686 DEVMETHOD(sdhci_read_2, sdhci_fdt_read_2), 687 DEVMETHOD(sdhci_read_4, sdhci_fdt_read_4), 688 DEVMETHOD(sdhci_read_multi_4, sdhci_fdt_read_multi_4), 689 DEVMETHOD(sdhci_write_1, sdhci_fdt_write_1), 690 DEVMETHOD(sdhci_write_2, sdhci_fdt_write_2), 691 DEVMETHOD(sdhci_write_4, sdhci_fdt_write_4), 692 DEVMETHOD(sdhci_write_multi_4, sdhci_fdt_write_multi_4), 693 DEVMETHOD(sdhci_set_clock, sdhci_fdt_set_clock), 694 695 DEVMETHOD_END 696 }; 697 698 static driver_t sdhci_fdt_driver = { 699 "sdhci_fdt", 700 sdhci_fdt_methods, 701 sizeof(struct sdhci_fdt_softc), 702 }; 703 704 DRIVER_MODULE(sdhci_fdt, simplebus, sdhci_fdt_driver, NULL, NULL); 705 SDHCI_DEPEND(sdhci_fdt); 706 #ifndef MMCCAM 707 MMC_DECLARE_BRIDGE(sdhci_fdt); 708 #endif 709