1 /* $OpenBSD: sdhc_fdt.c,v 1.18 2021/10/24 17:52:27 mpi 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 }; 116 117 int sdhc_fdt_card_detect(struct sdhc_softc *); 118 int sdhc_fdt_signal_voltage(struct sdhc_softc *, int); 119 uint32_t sdhc_fdt_get_frequency(void *, uint32_t *); 120 121 void sdhc_fdt_xenon_bus_clock_post(struct sdhc_softc *, int, int); 122 123 int 124 sdhc_fdt_match(struct device *parent, void *match, void *aux) 125 { 126 struct fdt_attach_args *faa = aux; 127 128 return (OF_is_compatible(faa->fa_node, "arasan,sdhci-5.1") || 129 OF_is_compatible(faa->fa_node, "arasan,sdhci-8.9a") || 130 OF_is_compatible(faa->fa_node, "brcm,bcm2711-emmc2") || 131 OF_is_compatible(faa->fa_node, "brcm,bcm2835-sdhci") || 132 OF_is_compatible(faa->fa_node, "marvell,armada-3700-sdhci") || 133 OF_is_compatible(faa->fa_node, "marvell,armada-ap806-sdhci") || 134 OF_is_compatible(faa->fa_node, "marvell,armada-cp110-sdhci")); 135 } 136 137 void 138 sdhc_fdt_attach(struct device *parent, struct device *self, void *aux) 139 { 140 struct sdhc_fdt_softc *sc = (struct sdhc_fdt_softc *)self; 141 struct fdt_attach_args *faa = aux; 142 struct regmap *rm = NULL; 143 uint32_t reg, phandle, freq, cap = 0; 144 char pad_type[16] = { 0 }; 145 146 if (faa->fa_nreg < 1) { 147 printf(": no registers\n"); 148 return; 149 } 150 151 sc->sc_iot = faa->fa_iot; 152 sc->sc_size = faa->fa_reg[0].size; 153 sc->sc_node = faa->fa_node; 154 155 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 156 faa->fa_reg[0].size, 0, &sc->sc_ioh)) { 157 printf(": can't map registers\n"); 158 return; 159 } 160 161 pinctrl_byname(faa->fa_node, "default"); 162 163 clock_set_assigned(faa->fa_node); 164 clock_enable_all(faa->fa_node); 165 reset_deassert_all(faa->fa_node); 166 167 sc->sc_ih = fdt_intr_establish(faa->fa_node, IPL_BIO, 168 sdhc_intr, sc, sc->sc.sc_dev.dv_xname); 169 if (sc->sc_ih == NULL) { 170 printf(": can't establish interrupt\n"); 171 goto unmap; 172 } 173 174 if (OF_getproplen(faa->fa_node, "cd-gpios") > 0 || 175 OF_getproplen(faa->fa_node, "non-removable") == 0) { 176 OF_getpropintarray(faa->fa_node, "cd-gpios", sc->sc_gpio, 177 sizeof(sc->sc_gpio)); 178 gpio_controller_config_pin(sc->sc_gpio, GPIO_CONFIG_INPUT); 179 sc->sc.sc_card_detect = sdhc_fdt_card_detect; 180 } 181 182 sc->sc_vqmmc = OF_getpropint(sc->sc_node, "vqmmc-supply", 0); 183 184 printf("\n"); 185 186 sc->sc.sc_host = &sc->sc_host; 187 sc->sc.sc_dmat = faa->fa_dmat; 188 189 /* 190 * Arasan controller always uses 1.8V and doesn't like an 191 * explicit switch. 192 */ 193 if (OF_is_compatible(faa->fa_node, "arasan,sdhci-5.1")) 194 sc->sc.sc_signal_voltage = sdhc_fdt_signal_voltage; 195 196 /* 197 * Rockchip RK3399 PHY doesn't like being powered down at low 198 * clock speeds and needs to be powered up explicitly. 199 */ 200 if (OF_is_compatible(faa->fa_node, "rockchip,rk3399-sdhci-5.1")) { 201 /* 202 * The eMMC core's clock multiplier is of no use, so we just 203 * clear it. Also make sure to set the base clock frequency. 204 */ 205 freq = clock_get_frequency(faa->fa_node, "clk_xin"); 206 freq /= 1000 * 1000; /* in MHz */ 207 phandle = OF_getpropint(faa->fa_node, 208 "arasan,soc-ctl-syscon", 0); 209 if (phandle) 210 rm = regmap_byphandle(phandle); 211 if (rm) { 212 regmap_write_4(rm, GRF_EMMCCORE_CON11, 213 GRF_EMMCCORE_CON11_CLOCKMULT_CLR | 214 GRF_EMMCCORE_CON11_CLOCKMULT_VAL(0)); 215 regmap_write_4(rm, GRF_EMMCCORE_CON0_BASECLOCK, 216 GRF_EMMCCORE_CON0_BASECLOCK_CLR | 217 GRF_EMMCCORE_CON0_BASECLOCK_VAL(freq)); 218 } 219 /* Provide base clock frequency for the PHY driver. */ 220 sc->sc_cd.cd_node = faa->fa_node; 221 sc->sc_cd.cd_cookie = sc; 222 sc->sc_cd.cd_get_frequency = sdhc_fdt_get_frequency; 223 clock_register(&sc->sc_cd); 224 /* 225 * Enable the PHY. The PHY should be powered on/off in 226 * the bus_clock function, but it's good enough to just 227 * enable it here right away and to keep it powered on. 228 */ 229 phy_enable(faa->fa_node, "phy_arasan"); 230 sc->sc.sc_flags |= SDHC_F_NOPWR0; 231 232 /* XXX Doesn't work on Rockchip RK3399. */ 233 sc->sc.sc_flags |= SDHC_F_NODDR50; 234 } 235 236 if (OF_is_compatible(faa->fa_node, "arasan,sdhci-8.9a")) { 237 freq = clock_get_frequency(faa->fa_node, "clk_xin"); 238 sc->sc.sc_clkbase = freq / 1000; 239 } 240 241 if (OF_is_compatible(faa->fa_node, "brcm,bcm2711-emmc2")) 242 sc->sc.sc_flags |= SDHC_F_NOPWR0; 243 244 if (OF_is_compatible(faa->fa_node, "brcm,bcm2835-sdhci")) { 245 cap = SDHC_VOLTAGE_SUPP_3_3V | SDHC_HIGH_SPEED_SUPP; 246 cap |= SDHC_MAX_BLK_LEN_1024 << SDHC_MAX_BLK_LEN_SHIFT; 247 248 freq = clock_get_frequency(faa->fa_node, NULL); 249 sc->sc.sc_clkbase = freq / 1000; 250 251 sc->sc.sc_flags |= SDHC_F_32BIT_ACCESS; 252 sc->sc.sc_flags |= SDHC_F_NO_HS_BIT; 253 } 254 255 if (OF_is_compatible(faa->fa_node, "marvell,armada-3700-sdhci") || 256 OF_is_compatible(faa->fa_node, "marvell,armada-ap806-sdhci") || 257 OF_is_compatible(faa->fa_node, "marvell,armada-cp110-sdhci")) { 258 if (OF_is_compatible(faa->fa_node, 259 "marvell,armada-3700-sdhci")) { 260 KASSERT(faa->fa_nreg > 1); 261 if (bus_space_map(sc->sc_iot, faa->fa_reg[1].addr, 262 faa->fa_reg[1].size, 0, &sc->sc_pad_ioh)) { 263 printf("%s: can't map registers\n", 264 sc->sc.sc_dev.dv_xname); 265 return; 266 } 267 OF_getprop(faa->fa_node, "marvell,pad-type", 268 pad_type, sizeof(pad_type)); 269 if (!strcmp(pad_type, "fixed-1-8v")) { 270 bus_space_write_4(sc->sc_iot, sc->sc_pad_ioh, 271 ARMADA_3700_SOC_PAD_CTL, 272 ARMADA_3700_SOC_PAD_CTL_1_8V); 273 } else { 274 bus_space_write_4(sc->sc_iot, sc->sc_pad_ioh, 275 ARMADA_3700_SOC_PAD_CTL, 276 ARMADA_3700_SOC_PAD_CTL_3_3V); 277 regulator_set_voltage(sc->sc_vqmmc, 3300000); 278 } 279 } 280 281 cap = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 282 SDHC_CAPABILITIES); 283 if (OF_getpropint(faa->fa_node, "bus-width", 1) != 8) 284 cap &= ~SDHC_8BIT_MODE_SUPP; 285 if (OF_getproplen(faa->fa_node, "no-1-8-v") == 0) { 286 cap &= ~SDHC_VOLTAGE_SUPP_1_8V; 287 sc->sc.sc_flags |= SDHC_F_NODDR50; 288 } 289 if (OF_getproplen(faa->fa_node, 290 "marvell,xenon-phy-slow-mode") == 0) 291 sc->sc_slow_mode = 1; 292 293 sc->sc_znr = OF_getpropint(faa->fa_node, 294 "marvell,xenon-phy-znr", 0xf); 295 sc->sc_znr &= XENON_EMMC_PHY_PAD_CONTROL2_ZNR_MASK; 296 sc->sc_zpr = OF_getpropint(faa->fa_node, 297 "marvell,xenon-phy-zpr", 0xf); 298 sc->sc_zpr &= XENON_EMMC_PHY_PAD_CONTROL2_ZPR_MASK; 299 sc->sc_sdhc_id = OF_getpropint(faa->fa_node, 300 "marvell,xenon-sdhc-id", 0); 301 302 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 303 XENON_SYS_OP_CTRL); 304 reg |= XENON_SYS_OP_CTRL_SLOT_ENABLE(sc->sc_sdhc_id); 305 reg &= ~XENON_SYS_OP_CTRL_SDCLK_IDLEOFF_ENABLE(sc->sc_sdhc_id); 306 reg &= ~XENON_SYS_OP_CTRL_AUTO_CLKGATE_DISABLE; 307 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 308 XENON_SYS_OP_CTRL, reg); 309 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 310 XENON_SYS_EXT_OP_CTRL); 311 reg |= XENON_SYS_EXT_OP_CTRL_PARALLEL_TRAN(sc->sc_sdhc_id); 312 reg |= XENON_SYS_EXT_OP_CTRL_MASK_CMD_CONFLICT_ERR; 313 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 314 XENON_SYS_EXT_OP_CTRL, reg); 315 316 freq = clock_get_frequency(faa->fa_node, NULL); 317 sc->sc.sc_clkbase = freq / 1000; 318 sc->sc.sc_bus_clock_post = sdhc_fdt_xenon_bus_clock_post; 319 } 320 321 sdhc_host_found(&sc->sc, sc->sc_iot, sc->sc_ioh, sc->sc_size, 1, cap); 322 return; 323 324 unmap: 325 bus_space_unmap(sc->sc_iot, sc->sc_ioh, sc->sc_size); 326 } 327 328 int 329 sdhc_fdt_card_detect(struct sdhc_softc *ssc) 330 { 331 struct sdhc_fdt_softc *sc = (struct sdhc_fdt_softc *)ssc; 332 333 if (OF_getproplen(sc->sc_node, "non-removable") == 0) 334 return 1; 335 336 return gpio_controller_get_pin(sc->sc_gpio); 337 } 338 339 int 340 sdhc_fdt_signal_voltage(struct sdhc_softc *sc, int signal_voltage) 341 { 342 switch (signal_voltage) { 343 case SDMMC_SIGNAL_VOLTAGE_180: 344 return 0; 345 default: 346 return EINVAL; 347 } 348 } 349 350 uint32_t 351 sdhc_fdt_get_frequency(void *cookie, uint32_t *cells) 352 { 353 struct sdhc_fdt_softc *sc = cookie; 354 return clock_get_frequency(sc->sc_cd.cd_node, "clk_xin"); 355 } 356 357 /* Marvell Xenon */ 358 void 359 sdhc_fdt_xenon_bus_clock_post(struct sdhc_softc *ssc, int freq, int timing) 360 { 361 struct sdhc_fdt_softc *sc = (struct sdhc_fdt_softc *)ssc; 362 uint32_t reg; 363 int i; 364 365 if (freq == 0) 366 return; 367 368 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 369 XENON_EMMC_PHY_PAD_CONTROL); 370 reg |= (XENON_EMMC_PHY_PAD_CONTROL_FC_DQ_RECEN | 371 XENON_EMMC_PHY_PAD_CONTROL_FC_CMD_RECEN | 372 XENON_EMMC_PHY_PAD_CONTROL_FC_QSP_RECEN | 373 XENON_EMMC_PHY_PAD_CONTROL_FC_QSN_RECEN | 374 XENON_EMMC_PHY_PAD_CONTROL_FC_ALL_CMOS_RECVR); 375 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 376 XENON_EMMC_PHY_PAD_CONTROL, reg); 377 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 378 XENON_EMMC_PHY_PAD_CONTROL1); 379 reg &= ~(XENON_EMMC_PHY_PAD_CONTROL1_FC_CMD_PD | 380 XENON_EMMC_PHY_PAD_CONTROL1_FC_DQ_PD); 381 reg |= (XENON_EMMC_PHY_PAD_CONTROL1_FC_CMD_PU | 382 XENON_EMMC_PHY_PAD_CONTROL1_FC_DQ_PU); 383 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 384 XENON_EMMC_PHY_PAD_CONTROL1, reg); 385 386 if (timing == SDMMC_TIMING_LEGACY) 387 goto phy_init; 388 389 /* TODO: check for SMF_IO_MODE and set flag */ 390 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 391 XENON_EMMC_PHY_TIMING_ADJUST); 392 reg &= ~XENON_EMMC_PHY_TIMING_ADJUST_SDIO_MODE; 393 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 394 XENON_EMMC_PHY_TIMING_ADJUST, reg); 395 396 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 397 XENON_EMMC_PHY_PAD_CONTROL2); 398 reg &= ~(XENON_EMMC_PHY_PAD_CONTROL2_ZPR_MASK << 399 XENON_EMMC_PHY_PAD_CONTROL2_ZPR_SHIFT | 400 XENON_EMMC_PHY_PAD_CONTROL2_ZNR_MASK << 401 XENON_EMMC_PHY_PAD_CONTROL2_ZNR_SHIFT); 402 reg |= sc->sc_zpr << XENON_EMMC_PHY_PAD_CONTROL2_ZPR_SHIFT | 403 sc->sc_znr << XENON_EMMC_PHY_PAD_CONTROL2_ZNR_SHIFT; 404 405 reg = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SDHC_CLOCK_CTL); 406 reg &= ~SDHC_SDCLK_ENABLE; 407 bus_space_write_2(sc->sc_iot, sc->sc_ioh, SDHC_CLOCK_CTL, reg); 408 409 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 410 XENON_EMMC_PHY_FUNC_CONTROL); 411 reg &= ~(XENON_EMMC_PHY_FUNC_CONTROL_DQ_DDR_MODE | 412 XENON_EMMC_PHY_FUNC_CONTROL_CMD_DDR_MODE); 413 reg |= XENON_EMMC_PHY_FUNC_CONTROL_DQ_ASYNC_MODE; 414 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 415 XENON_EMMC_PHY_FUNC_CONTROL, reg); 416 417 reg = bus_space_read_2(sc->sc_iot, sc->sc_ioh, SDHC_CLOCK_CTL); 418 reg |= SDHC_SDCLK_ENABLE; 419 bus_space_write_2(sc->sc_iot, sc->sc_ioh, SDHC_CLOCK_CTL, reg); 420 421 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 422 XENON_SLOT_EMMC_CTRL); 423 reg &= ~(XENON_SLOT_EMMC_CTRL_ENABLE_DATA_STROBE | 424 XENON_SLOT_EMMC_CTRL_ENABLE_RESP_STROBE); 425 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 426 XENON_SLOT_EMMC_CTRL, reg); 427 428 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 429 XENON_EMMC_PHY_PAD_CONTROL1); 430 reg &= ~(XENON_EMMC_PHY_PAD_CONTROL1_FC_QSP_PD | 431 XENON_EMMC_PHY_PAD_CONTROL1_FC_QSP_PU); 432 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 433 XENON_EMMC_PHY_PAD_CONTROL1, reg); 434 435 phy_init: 436 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 437 XENON_EMMC_PHY_TIMING_ADJUST); 438 reg |= XENON_EMMC_PHY_TIMING_ADJUST_SAMPL_INV_QSP_PHASE_SELECT; 439 reg &= ~XENON_EMMC_PHY_TIMING_ADJUST_SLOW_MODE; 440 if (timing == SDMMC_TIMING_LEGACY || 441 timing == SDMMC_TIMING_HIGHSPEED || sc->sc_slow_mode) 442 reg |= XENON_EMMC_PHY_TIMING_ADJUST_SLOW_MODE; 443 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 444 XENON_EMMC_PHY_TIMING_ADJUST, reg); 445 446 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 447 XENON_EMMC_PHY_TIMING_ADJUST); 448 reg |= XENON_EMMC_PHY_TIMING_ADJUST_INIT; 449 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 450 XENON_EMMC_PHY_TIMING_ADJUST, reg); 451 452 for (i = 1000; i > 0; i--) { 453 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 454 XENON_EMMC_PHY_TIMING_ADJUST); 455 if (!(reg & XENON_EMMC_PHY_TIMING_ADJUST_INIT)) 456 break; 457 delay(10); 458 } 459 if (i == 0) 460 printf("%s: phy initialization timeout\n", 461 sc->sc.sc_dev.dv_xname); 462 463 if (freq > SDMMC_SDCLK_400KHZ) { 464 reg = bus_space_read_4(sc->sc_iot, sc->sc_ioh, 465 XENON_SYS_OP_CTRL); 466 reg |= XENON_SYS_OP_CTRL_SDCLK_IDLEOFF_ENABLE(sc->sc_sdhc_id); 467 bus_space_write_4(sc->sc_iot, sc->sc_ioh, 468 XENON_SYS_OP_CTRL, reg); 469 } 470 } 471