1 /* $OpenBSD: sdhc_fdt.c,v 1.21 2024/10/09 00:38:26 jsg Exp $ */ 2 /* 3 * Copyright (c) 2017 Mark Kettenis 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include <sys/param.h> 19 #include <sys/malloc.h> 20 #include <sys/systm.h> 21 22 #include <machine/bus.h> 23 #include <machine/fdt.h> 24 #include <machine/intr.h> 25 26 #include <dev/ofw/openfirm.h> 27 #include <dev/ofw/ofw_clock.h> 28 #include <dev/ofw/ofw_gpio.h> 29 #include <dev/ofw/ofw_misc.h> 30 #include <dev/ofw/ofw_pinctrl.h> 31 #include <dev/ofw/ofw_regulator.h> 32 #include <dev/ofw/fdt.h> 33 34 #include <dev/sdmmc/sdhcreg.h> 35 #include <dev/sdmmc/sdhcvar.h> 36 #include <dev/sdmmc/sdmmcvar.h> 37 38 /* RK3399 */ 39 #define GRF_EMMCCORE_CON0_BASECLOCK 0xf000 40 #define GRF_EMMCCORE_CON0_BASECLOCK_CLR (0xff << 24) 41 #define GRF_EMMCCORE_CON0_BASECLOCK_VAL(x) (((x) & 0xff) << 8) 42 #define GRF_EMMCCORE_CON11 0xf02c 43 #define GRF_EMMCCORE_CON11_CLOCKMULT_CLR (0xff << 16) 44 #define GRF_EMMCCORE_CON11_CLOCKMULT_VAL(x) (((x) & 0xff) << 0) 45 46 /* Marvell Xenon */ 47 #define XENON_SYS_OP_CTRL 0x108 48 #define XENON_SYS_OP_CTRL_SLOT_ENABLE(x) (1 << (x)) 49 #define XENON_SYS_OP_CTRL_SDCLK_IDLEOFF_ENABLE(x) (1 << ((x) + 8)) 50 #define XENON_SYS_OP_CTRL_AUTO_CLKGATE_DISABLE (1 << 20) 51 #define XENON_SYS_EXT_OP_CTRL 0x10c 52 #define XENON_SYS_EXT_OP_CTRL_PARALLEL_TRAN(x) (1 << (x)) 53 #define XENON_SYS_EXT_OP_CTRL_MASK_CMD_CONFLICT_ERR (1 << 8) 54 #define XENON_SLOT_EMMC_CTRL 0x130 55 #define XENON_SLOT_EMMC_CTRL_ENABLE_DATA_STROBE (1 << 24) 56 #define XENON_SLOT_EMMC_CTRL_ENABLE_RESP_STROBE (1 << 25) 57 #define XENON_EMMC_PHY_TIMING_ADJUST 0x170 58 #define XENON_EMMC_PHY_TIMING_ADJUST_SAMPL_INV_QSP_PHASE_SELECT (1 << 18) 59 #define XENON_EMMC_PHY_TIMING_ADJUST_SDIO_MODE (1 << 28) 60 #define XENON_EMMC_PHY_TIMING_ADJUST_SLOW_MODE (1 << 29) 61 #define XENON_EMMC_PHY_TIMING_ADJUST_INIT (1U << 31) 62 #define XENON_EMMC_PHY_FUNC_CONTROL 0x174 63 #define XENON_EMMC_PHY_FUNC_CONTROL_DQ_ASYNC_MODE (1 << 4) 64 #define XENON_EMMC_PHY_FUNC_CONTROL_DQ_DDR_MODE (0xff << 8) 65 #define XENON_EMMC_PHY_FUNC_CONTROL_CMD_DDR_MODE (1 << 16) 66 #define XENON_EMMC_PHY_PAD_CONTROL 0x178 67 #define XENON_EMMC_PHY_PAD_CONTROL_FC_DQ_RECEN (1 << 24) 68 #define XENON_EMMC_PHY_PAD_CONTROL_FC_CMD_RECEN (1 << 25) 69 #define XENON_EMMC_PHY_PAD_CONTROL_FC_QSP_RECEN (1 << 26) 70 #define XENON_EMMC_PHY_PAD_CONTROL_FC_QSN_RECEN (1 << 27) 71 #define XENON_EMMC_PHY_PAD_CONTROL_FC_ALL_CMOS_RECVR 0xf000 72 #define XENON_EMMC_PHY_PAD_CONTROL1 0x17c 73 #define XENON_EMMC_PHY_PAD_CONTROL1_FC_CMD_PD (1 << 8) 74 #define XENON_EMMC_PHY_PAD_CONTROL1_FC_QSP_PD (1 << 9) 75 #define XENON_EMMC_PHY_PAD_CONTROL1_FC_CMD_PU (1 << 24) 76 #define XENON_EMMC_PHY_PAD_CONTROL1_FC_QSP_PU (1 << 25) 77 #define XENON_EMMC_PHY_PAD_CONTROL1_FC_DQ_PD 0xff 78 #define XENON_EMMC_PHY_PAD_CONTROL1_FC_DQ_PU (0xff << 16) 79 #define XENON_EMMC_PHY_PAD_CONTROL2 0x180 80 #define XENON_EMMC_PHY_PAD_CONTROL2_ZPR_SHIFT 0 81 #define XENON_EMMC_PHY_PAD_CONTROL2_ZPR_MASK 0x1f 82 #define XENON_EMMC_PHY_PAD_CONTROL2_ZNR_SHIFT 8 83 #define XENON_EMMC_PHY_PAD_CONTROL2_ZNR_MASK 0x1f 84 85 #define ARMADA_3700_SOC_PAD_CTL 0 86 #define ARMADA_3700_SOC_PAD_CTL_3_3V 0 87 #define ARMADA_3700_SOC_PAD_CTL_1_8V 1 88 89 struct sdhc_fdt_softc { 90 struct sdhc_softc sc; 91 bus_space_tag_t sc_iot; 92 bus_space_handle_t sc_ioh; 93 bus_space_handle_t sc_pad_ioh; 94 bus_size_t sc_size; 95 void *sc_ih; 96 int sc_node; 97 uint32_t sc_gpio[3]; 98 uint32_t sc_vqmmc; 99 100 /* Marvell Xenon */ 101 int sc_sdhc_id; 102 int sc_slow_mode; 103 uint32_t sc_znr; 104 uint32_t sc_zpr; 105 106 struct sdhc_host *sc_host; 107 struct clock_device sc_cd; 108 }; 109 110 int sdhc_fdt_match(struct device *, void *, void *); 111 void sdhc_fdt_attach(struct device *, struct device *, void *); 112 113 const struct cfattach sdhc_fdt_ca = { 114 sizeof(struct sdhc_fdt_softc), sdhc_fdt_match, sdhc_fdt_attach, 115 NULL, sdhc_activate 116 }; 117 118 int sdhc_fdt_card_detect(struct sdhc_softc *); 119 int sdhc_fdt_signal_voltage(struct sdhc_softc *, int); 120 uint32_t sdhc_fdt_get_frequency(void *, uint32_t *); 121 122 void sdhc_fdt_xenon_bus_clock_post(struct sdhc_softc *, int, int); 123 124 int 125 sdhc_fdt_match(struct device *parent, void *match, void *aux) 126 { 127 struct fdt_attach_args *faa = aux; 128 129 return (OF_is_compatible(faa->fa_node, "arasan,sdhci-5.1") || 130 OF_is_compatible(faa->fa_node, "arasan,sdhci-8.9a") || 131 OF_is_compatible(faa->fa_node, "brcm,bcm2711-emmc2") || 132 OF_is_compatible(faa->fa_node, "brcm,bcm2835-sdhci") || 133 OF_is_compatible(faa->fa_node, "marvell,armada-3700-sdhci") || 134 OF_is_compatible(faa->fa_node, "marvell,armada-ap806-sdhci") || 135 OF_is_compatible(faa->fa_node, "marvell,armada-cp110-sdhci")); 136 } 137 138 void 139 sdhc_fdt_attach(struct device *parent, struct device *self, void *aux) 140 { 141 struct sdhc_fdt_softc *sc = (struct sdhc_fdt_softc *)self; 142 struct fdt_attach_args *faa = aux; 143 struct regmap *rm = NULL; 144 uint64_t capmask = 0, capset = 0; 145 uint32_t reg, phandle, freq; 146 char pad_type[16] = { 0 }; 147 148 if (faa->fa_nreg < 1) { 149 printf(": no registers\n"); 150 return; 151 } 152 153 sc->sc_iot = faa->fa_iot; 154 sc->sc_size = faa->fa_reg[0].size; 155 sc->sc_node = faa->fa_node; 156 157 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 158 faa->fa_reg[0].size, 0, &sc->sc_ioh)) { 159 printf(": can't map registers\n"); 160 return; 161 } 162 163 pinctrl_byname(faa->fa_node, "default"); 164 165 clock_set_assigned(faa->fa_node); 166 clock_enable_all(faa->fa_node); 167 reset_deassert_all(faa->fa_node); 168 169 sc->sc_ih = fdt_intr_establish(faa->fa_node, IPL_BIO, 170 sdhc_intr, sc, sc->sc.sc_dev.dv_xname); 171 if (sc->sc_ih == NULL) { 172 printf(": can't establish interrupt\n"); 173 goto unmap; 174 } 175 176 if (OF_getproplen(faa->fa_node, "cd-gpios") > 0 || 177 OF_getproplen(faa->fa_node, "non-removable") == 0) { 178 OF_getpropintarray(faa->fa_node, "cd-gpios", sc->sc_gpio, 179 sizeof(sc->sc_gpio)); 180 gpio_controller_config_pin(sc->sc_gpio, GPIO_CONFIG_INPUT); 181 sc->sc.sc_card_detect = sdhc_fdt_card_detect; 182 } 183 184 sc->sc_vqmmc = OF_getpropint(sc->sc_node, "vqmmc-supply", 0); 185 186 printf("\n"); 187 188 sc->sc.sc_host = &sc->sc_host; 189 sc->sc.sc_dmat = faa->fa_dmat; 190 191 /* 192 * Arasan controller always uses 1.8V and doesn't like an 193 * explicit switch. 194 */ 195 if (OF_is_compatible(faa->fa_node, "arasan,sdhci-5.1")) 196 sc->sc.sc_signal_voltage = sdhc_fdt_signal_voltage; 197 198 /* 199 * Rockchip RK3399 PHY doesn't like being powered down at low 200 * clock speeds and needs to be powered up explicitly. 201 */ 202 if (OF_is_compatible(faa->fa_node, "rockchip,rk3399-sdhci-5.1")) { 203 /* 204 * The eMMC core's clock multiplier is of no use, so we just 205 * clear it. Also make sure to set the base clock frequency. 206 */ 207 freq = clock_get_frequency(faa->fa_node, "clk_xin"); 208 freq /= 1000 * 1000; /* in MHz */ 209 phandle = OF_getpropint(faa->fa_node, 210 "arasan,soc-ctl-syscon", 0); 211 if (phandle) 212 rm = regmap_byphandle(phandle); 213 if (rm) { 214 regmap_write_4(rm, GRF_EMMCCORE_CON11, 215 GRF_EMMCCORE_CON11_CLOCKMULT_CLR | 216 GRF_EMMCCORE_CON11_CLOCKMULT_VAL(0)); 217 regmap_write_4(rm, GRF_EMMCCORE_CON0_BASECLOCK, 218 GRF_EMMCCORE_CON0_BASECLOCK_CLR | 219 GRF_EMMCCORE_CON0_BASECLOCK_VAL(freq)); 220 } 221 /* Provide base clock frequency for the PHY driver. */ 222 sc->sc_cd.cd_node = faa->fa_node; 223 sc->sc_cd.cd_cookie = sc; 224 sc->sc_cd.cd_get_frequency = sdhc_fdt_get_frequency; 225 clock_register(&sc->sc_cd); 226 /* 227 * Enable the PHY. The PHY should be powered on/off in 228 * the bus_clock function, but it's good enough to just 229 * enable it here right away and to keep it powered on. 230 */ 231 phy_enable(faa->fa_node, "phy_arasan"); 232 sc->sc.sc_flags |= SDHC_F_NOPWR0; 233 234 /* XXX Doesn't work on Rockchip RK3399. */ 235 capmask |= (uint64_t)SDHC_DDR50_SUPP << 32; 236 } 237 238 if (OF_is_compatible(faa->fa_node, "arasan,sdhci-8.9a")) { 239 freq = clock_get_frequency(faa->fa_node, "clk_xin"); 240 sc->sc.sc_clkbase = freq / 1000; 241 } 242 243 if (OF_is_compatible(faa->fa_node, "brcm,bcm2711-emmc2")) 244 sc->sc.sc_flags |= SDHC_F_NOPWR0; 245 246 if (OF_is_compatible(faa->fa_node, "brcm,bcm2835-sdhci")) { 247 capmask = 0xffffffff; 248 capset = SDHC_VOLTAGE_SUPP_3_3V | SDHC_HIGH_SPEED_SUPP; 249 capset |= SDHC_MAX_BLK_LEN_1024 << SDHC_MAX_BLK_LEN_SHIFT; 250 251 freq = clock_get_frequency(faa->fa_node, NULL); 252 sc->sc.sc_clkbase = freq / 1000; 253 254 sc->sc.sc_flags |= SDHC_F_32BIT_ACCESS; 255 sc->sc.sc_flags |= SDHC_F_NO_HS_BIT; 256 } 257 258 if (OF_is_compatible(faa->fa_node, "marvell,armada-3700-sdhci") || 259 OF_is_compatible(faa->fa_node, "marvell,armada-ap806-sdhci") || 260 OF_is_compatible(faa->fa_node, "marvell,armada-cp110-sdhci")) { 261 if (OF_is_compatible(faa->fa_node, 262 "marvell,armada-3700-sdhci")) { 263 KASSERT(faa->fa_nreg > 1); 264 if (bus_space_map(sc->sc_iot, faa->fa_reg[1].addr, 265 faa->fa_reg[1].size, 0, &sc->sc_pad_ioh)) { 266 printf("%s: can't map registers\n", 267 sc->sc.sc_dev.dv_xname); 268 return; 269 } 270 OF_getprop(faa->fa_node, "marvell,pad-type", 271 pad_type, sizeof(pad_type)); 272 if (!strcmp(pad_type, "fixed-1-8v")) { 273 bus_space_write_4(sc->sc_iot, sc->sc_pad_ioh, 274 ARMADA_3700_SOC_PAD_CTL, 275 ARMADA_3700_SOC_PAD_CTL_1_8V); 276 } else { 277 bus_space_write_4(sc->sc_iot, sc->sc_pad_ioh, 278 ARMADA_3700_SOC_PAD_CTL, 279 ARMADA_3700_SOC_PAD_CTL_3_3V); 280 regulator_set_voltage(sc->sc_vqmmc, 3300000); 281 } 282 } 283 284 if (OF_getpropint(faa->fa_node, "bus-width", 1) != 8) 285 capmask |= SDHC_8BIT_MODE_SUPP; 286 if (OF_getproplen(faa->fa_node, "no-1-8-v") == 0) { 287 capmask |= SDHC_VOLTAGE_SUPP_1_8V; 288 capmask |= (uint64_t)SDHC_DDR50_SUPP << 32; 289 } 290 if (OF_getproplen(faa->fa_node, 291 "marvell,xenon-phy-slow-mode") == 0) 292 sc->sc_slow_mode = 1; 293 294 sc->sc_znr = OF_getpropint(faa->fa_node, 295 "marvell,xenon-phy-znr", 0xf); 296 sc->sc_znr &= XENON_EMMC_PHY_PAD_CONTROL2_ZNR_MASK; 297 sc->sc_zpr = OF_getpropint(faa->fa_node, 298 "marvell,xenon-phy-zpr", 0xf); 299 sc->sc_zpr &= XENON_EMMC_PHY_PAD_CONTROL2_ZPR_MASK; 300 sc->sc_sdhc_id = OF_getpropint(faa->fa_node, 301 "marvell,xenon-sdhc-id", 0); 302 303 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 304 XENON_SYS_OP_CTRL); 305 reg |= XENON_SYS_OP_CTRL_SLOT_ENABLE(sc->sc_sdhc_id); 306 reg &= ~XENON_SYS_OP_CTRL_SDCLK_IDLEOFF_ENABLE(sc->sc_sdhc_id); 307 reg &= ~XENON_SYS_OP_CTRL_AUTO_CLKGATE_DISABLE; 308 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 309 XENON_SYS_OP_CTRL, reg); 310 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 311 XENON_SYS_EXT_OP_CTRL); 312 reg |= XENON_SYS_EXT_OP_CTRL_PARALLEL_TRAN(sc->sc_sdhc_id); 313 reg |= XENON_SYS_EXT_OP_CTRL_MASK_CMD_CONFLICT_ERR; 314 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 315 XENON_SYS_EXT_OP_CTRL, reg); 316 317 freq = clock_get_frequency(faa->fa_node, NULL); 318 sc->sc.sc_clkbase = freq / 1000; 319 sc->sc.sc_bus_clock_post = sdhc_fdt_xenon_bus_clock_post; 320 } 321 322 sdhc_host_found(&sc->sc, sc->sc_iot, sc->sc_ioh, sc->sc_size, 1, 323 capmask, capset); 324 return; 325 326 unmap: 327 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size); 328 } 329 330 int 331 sdhc_fdt_card_detect(struct sdhc_softc *ssc) 332 { 333 struct sdhc_fdt_softc *sc = (struct sdhc_fdt_softc *)ssc; 334 335 if (OF_getproplen(sc->sc_node, "non-removable") == 0) 336 return 1; 337 338 return gpio_controller_get_pin(sc->sc_gpio); 339 } 340 341 int 342 sdhc_fdt_signal_voltage(struct sdhc_softc *sc, int signal_voltage) 343 { 344 switch (signal_voltage) { 345 case SDMMC_SIGNAL_VOLTAGE_180: 346 return 0; 347 default: 348 return EINVAL; 349 } 350 } 351 352 uint32_t 353 sdhc_fdt_get_frequency(void *cookie, uint32_t *cells) 354 { 355 struct sdhc_fdt_softc *sc = cookie; 356 return clock_get_frequency(sc->sc_cd.cd_node, "clk_xin"); 357 } 358 359 /* Marvell Xenon */ 360 void 361 sdhc_fdt_xenon_bus_clock_post(struct sdhc_softc *ssc, int freq, int timing) 362 { 363 struct sdhc_fdt_softc *sc = (struct sdhc_fdt_softc *)ssc; 364 uint32_t reg; 365 int i; 366 367 if (freq == 0) 368 return; 369 370 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 371 XENON_EMMC_PHY_PAD_CONTROL); 372 reg |= (XENON_EMMC_PHY_PAD_CONTROL_FC_DQ_RECEN | 373 XENON_EMMC_PHY_PAD_CONTROL_FC_CMD_RECEN | 374 XENON_EMMC_PHY_PAD_CONTROL_FC_QSP_RECEN | 375 XENON_EMMC_PHY_PAD_CONTROL_FC_QSN_RECEN | 376 XENON_EMMC_PHY_PAD_CONTROL_FC_ALL_CMOS_RECVR); 377 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 378 XENON_EMMC_PHY_PAD_CONTROL, reg); 379 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 380 XENON_EMMC_PHY_PAD_CONTROL1); 381 reg &= ~(XENON_EMMC_PHY_PAD_CONTROL1_FC_CMD_PD | 382 XENON_EMMC_PHY_PAD_CONTROL1_FC_DQ_PD); 383 reg |= (XENON_EMMC_PHY_PAD_CONTROL1_FC_CMD_PU | 384 XENON_EMMC_PHY_PAD_CONTROL1_FC_DQ_PU); 385 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 386 XENON_EMMC_PHY_PAD_CONTROL1, reg); 387 388 if (timing == SDMMC_TIMING_LEGACY) 389 goto phy_init; 390 391 /* TODO: check for SMF_IO_MODE and set flag */ 392 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 393 XENON_EMMC_PHY_TIMING_ADJUST); 394 reg &= ~XENON_EMMC_PHY_TIMING_ADJUST_SDIO_MODE; 395 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 396 XENON_EMMC_PHY_TIMING_ADJUST, reg); 397 398 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 399 XENON_EMMC_PHY_PAD_CONTROL2); 400 reg &= ~(XENON_EMMC_PHY_PAD_CONTROL2_ZPR_MASK << 401 XENON_EMMC_PHY_PAD_CONTROL2_ZPR_SHIFT | 402 XENON_EMMC_PHY_PAD_CONTROL2_ZNR_MASK << 403 XENON_EMMC_PHY_PAD_CONTROL2_ZNR_SHIFT); 404 reg |= sc->sc_zpr << XENON_EMMC_PHY_PAD_CONTROL2_ZPR_SHIFT | 405 sc->sc_znr << XENON_EMMC_PHY_PAD_CONTROL2_ZNR_SHIFT; 406 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 407 XENON_EMMC_PHY_PAD_CONTROL2, reg); 408 409 reg = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SDHC_CLOCK_CTL); 410 reg &= ~SDHC_SDCLK_ENABLE; 411 bus_space_write_2(sc->sc_iot, sc->sc_ioh, SDHC_CLOCK_CTL, reg); 412 413 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 414 XENON_EMMC_PHY_FUNC_CONTROL); 415 reg &= ~(XENON_EMMC_PHY_FUNC_CONTROL_DQ_DDR_MODE | 416 XENON_EMMC_PHY_FUNC_CONTROL_CMD_DDR_MODE); 417 reg |= XENON_EMMC_PHY_FUNC_CONTROL_DQ_ASYNC_MODE; 418 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 419 XENON_EMMC_PHY_FUNC_CONTROL, reg); 420 421 reg = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SDHC_CLOCK_CTL); 422 reg |= SDHC_SDCLK_ENABLE; 423 bus_space_write_2(sc->sc_iot, sc->sc_ioh, SDHC_CLOCK_CTL, reg); 424 425 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 426 XENON_SLOT_EMMC_CTRL); 427 reg &= ~(XENON_SLOT_EMMC_CTRL_ENABLE_DATA_STROBE | 428 XENON_SLOT_EMMC_CTRL_ENABLE_RESP_STROBE); 429 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 430 XENON_SLOT_EMMC_CTRL, reg); 431 432 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 433 XENON_EMMC_PHY_PAD_CONTROL1); 434 reg &= ~(XENON_EMMC_PHY_PAD_CONTROL1_FC_QSP_PD | 435 XENON_EMMC_PHY_PAD_CONTROL1_FC_QSP_PU); 436 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 437 XENON_EMMC_PHY_PAD_CONTROL1, reg); 438 439 phy_init: 440 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 441 XENON_EMMC_PHY_TIMING_ADJUST); 442 reg |= XENON_EMMC_PHY_TIMING_ADJUST_SAMPL_INV_QSP_PHASE_SELECT; 443 reg &= ~XENON_EMMC_PHY_TIMING_ADJUST_SLOW_MODE; 444 if (timing == SDMMC_TIMING_LEGACY || 445 timing == SDMMC_TIMING_HIGHSPEED || sc->sc_slow_mode) 446 reg |= XENON_EMMC_PHY_TIMING_ADJUST_SLOW_MODE; 447 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 448 XENON_EMMC_PHY_TIMING_ADJUST, reg); 449 450 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 451 XENON_EMMC_PHY_TIMING_ADJUST); 452 reg |= XENON_EMMC_PHY_TIMING_ADJUST_INIT; 453 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 454 XENON_EMMC_PHY_TIMING_ADJUST, reg); 455 456 for (i = 1000; i > 0; i--) { 457 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 458 XENON_EMMC_PHY_TIMING_ADJUST); 459 if (!(reg & XENON_EMMC_PHY_TIMING_ADJUST_INIT)) 460 break; 461 delay(10); 462 } 463 if (i == 0) 464 printf("%s: phy initialization timeout\n", 465 sc->sc.sc_dev.dv_xname); 466 467 if (freq > SDMMC_SDCLK_400KHZ) { 468 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 469 XENON_SYS_OP_CTRL); 470 reg |= XENON_SYS_OP_CTRL_SDCLK_IDLEOFF_ENABLE(sc->sc_sdhc_id); 471 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 472 XENON_SYS_OP_CTRL, reg); 473 } 474 } 475