Mon Aug 3 10:08:51 2015 UTC ()
Add support for DDR50 transfer modes.


(jmcneill)
diff -r1.75 -r1.76 src/sys/dev/sdmmc/sdhc.c
diff -r1.28 -r1.29 src/sys/dev/sdmmc/sdmmc.c
diff -r1.9 -r1.10 src/sys/dev/sdmmc/sdmmc_io.c
diff -r1.38 -r1.39 src/sys/dev/sdmmc/sdmmc_mem.c
diff -r1.5 -r1.6 src/sys/dev/sdmmc/sdmmcchip.h
diff -r1.17 -r1.18 src/sys/dev/sdmmc/sdmmcreg.h
diff -r1.17 -r1.18 src/sys/dev/sdmmc/sdmmcvar.h

cvs diff -r1.75 -r1.76 src/sys/dev/sdmmc/sdhc.c (expand / switch to unified diff)

--- src/sys/dev/sdmmc/sdhc.c 2015/08/03 05:24:37 1.75
+++ src/sys/dev/sdmmc/sdhc.c 2015/08/03 10:08:51 1.76
@@ -1,39 +1,39 @@ @@ -1,39 +1,39 @@
1/* $NetBSD: sdhc.c,v 1.75 2015/08/03 05:24:37 mlelstv Exp $ */ 1/* $NetBSD: sdhc.c,v 1.76 2015/08/03 10:08:51 jmcneill Exp $ */
2/* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */ 2/* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> 5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 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 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 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 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */ 18 */
19 19
20/* 20/*
21 * SD Host Controller driver based on the SD Host Controller Standard 21 * SD Host Controller driver based on the SD Host Controller Standard
22 * Simplified Specification Version 1.00 (www.sdcard.com). 22 * Simplified Specification Version 1.00 (www.sdcard.com).
23 */ 23 */
24 24
25#include <sys/cdefs.h> 25#include <sys/cdefs.h>
26__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.75 2015/08/03 05:24:37 mlelstv Exp $"); 26__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.76 2015/08/03 10:08:51 jmcneill Exp $");
27 27
28#ifdef _KERNEL_OPT 28#ifdef _KERNEL_OPT
29#include "opt_sdmmc.h" 29#include "opt_sdmmc.h"
30#endif 30#endif
31 31
32#include <sys/param.h> 32#include <sys/param.h>
33#include <sys/device.h> 33#include <sys/device.h>
34#include <sys/kernel.h> 34#include <sys/kernel.h>
35#include <sys/malloc.h> 35#include <sys/malloc.h>
36#include <sys/systm.h> 36#include <sys/systm.h>
37#include <sys/mutex.h> 37#include <sys/mutex.h>
38#include <sys/condvar.h> 38#include <sys/condvar.h>
39 39
@@ -164,27 +164,27 @@ hwrite2(struct sdhc_host *hp, bus_size_t @@ -164,27 +164,27 @@ hwrite2(struct sdhc_host *hp, bus_size_t
164 do if (bits) HWRITE1((hp), (reg), HREAD1((hp), (reg)) | (bits)); while (0) 164 do if (bits) HWRITE1((hp), (reg), HREAD1((hp), (reg)) | (bits)); while (0)
165#define HSET2(hp, reg, bits) \ 165#define HSET2(hp, reg, bits) \
166 do if (bits) HWRITE2((hp), (reg), HREAD2((hp), (reg)) | (bits)); while (0) 166 do if (bits) HWRITE2((hp), (reg), HREAD2((hp), (reg)) | (bits)); while (0)
167#define HSET4(hp, reg, bits) \ 167#define HSET4(hp, reg, bits) \
168 do if (bits) HWRITE4((hp), (reg), HREAD4((hp), (reg)) | (bits)); while (0) 168 do if (bits) HWRITE4((hp), (reg), HREAD4((hp), (reg)) | (bits)); while (0)
169 169
170static int sdhc_host_reset(sdmmc_chipset_handle_t); 170static int sdhc_host_reset(sdmmc_chipset_handle_t);
171static int sdhc_host_reset1(sdmmc_chipset_handle_t); 171static int sdhc_host_reset1(sdmmc_chipset_handle_t);
172static uint32_t sdhc_host_ocr(sdmmc_chipset_handle_t); 172static uint32_t sdhc_host_ocr(sdmmc_chipset_handle_t);
173static int sdhc_host_maxblklen(sdmmc_chipset_handle_t); 173static int sdhc_host_maxblklen(sdmmc_chipset_handle_t);
174static int sdhc_card_detect(sdmmc_chipset_handle_t); 174static int sdhc_card_detect(sdmmc_chipset_handle_t);
175static int sdhc_write_protect(sdmmc_chipset_handle_t); 175static int sdhc_write_protect(sdmmc_chipset_handle_t);
176static int sdhc_bus_power(sdmmc_chipset_handle_t, uint32_t); 176static int sdhc_bus_power(sdmmc_chipset_handle_t, uint32_t);
177static int sdhc_bus_clock(sdmmc_chipset_handle_t, int); 177static int sdhc_bus_clock_ddr(sdmmc_chipset_handle_t, int, bool);
178static int sdhc_bus_width(sdmmc_chipset_handle_t, int); 178static int sdhc_bus_width(sdmmc_chipset_handle_t, int);
179static int sdhc_bus_rod(sdmmc_chipset_handle_t, int); 179static int sdhc_bus_rod(sdmmc_chipset_handle_t, int);
180static void sdhc_card_enable_intr(sdmmc_chipset_handle_t, int); 180static void sdhc_card_enable_intr(sdmmc_chipset_handle_t, int);
181static void sdhc_card_intr_ack(sdmmc_chipset_handle_t); 181static void sdhc_card_intr_ack(sdmmc_chipset_handle_t);
182static void sdhc_exec_command(sdmmc_chipset_handle_t, 182static void sdhc_exec_command(sdmmc_chipset_handle_t,
183 struct sdmmc_command *); 183 struct sdmmc_command *);
184static int sdhc_signal_voltage(sdmmc_chipset_handle_t, int); 184static int sdhc_signal_voltage(sdmmc_chipset_handle_t, int);
185static int sdhc_start_command(struct sdhc_host *, struct sdmmc_command *); 185static int sdhc_start_command(struct sdhc_host *, struct sdmmc_command *);
186static int sdhc_wait_state(struct sdhc_host *, uint32_t, uint32_t); 186static int sdhc_wait_state(struct sdhc_host *, uint32_t, uint32_t);
187static int sdhc_soft_reset(struct sdhc_host *, int); 187static int sdhc_soft_reset(struct sdhc_host *, int);
188static int sdhc_wait_intr(struct sdhc_host *, int, int); 188static int sdhc_wait_intr(struct sdhc_host *, int, int);
189static void sdhc_transfer_data(struct sdhc_host *, struct sdmmc_command *); 189static void sdhc_transfer_data(struct sdhc_host *, struct sdmmc_command *);
190static int sdhc_transfer_data_dma(struct sdhc_host *, struct sdmmc_command *); 190static int sdhc_transfer_data_dma(struct sdhc_host *, struct sdmmc_command *);
@@ -200,39 +200,40 @@ static struct sdmmc_chip_functions sdhc_ @@ -200,39 +200,40 @@ static struct sdmmc_chip_functions sdhc_
200 200
201 /* host controller capabilities */ 201 /* host controller capabilities */
202 .host_ocr = sdhc_host_ocr, 202 .host_ocr = sdhc_host_ocr,
203 .host_maxblklen = sdhc_host_maxblklen, 203 .host_maxblklen = sdhc_host_maxblklen,
204 204
205 /* card detection */ 205 /* card detection */
206 .card_detect = sdhc_card_detect, 206 .card_detect = sdhc_card_detect,
207 207
208 /* write protect */ 208 /* write protect */
209 .write_protect = sdhc_write_protect, 209 .write_protect = sdhc_write_protect,
210 210
211 /* bus power, clock frequency, width and ROD(OpenDrain/PushPull) */ 211 /* bus power, clock frequency, width and ROD(OpenDrain/PushPull) */
212 .bus_power = sdhc_bus_power, 212 .bus_power = sdhc_bus_power,
213 .bus_clock = sdhc_bus_clock, 213 .bus_clock = NULL, /* see sdhc_bus_clock_ddr */
214 .bus_width = sdhc_bus_width, 214 .bus_width = sdhc_bus_width,
215 .bus_rod = sdhc_bus_rod, 215 .bus_rod = sdhc_bus_rod,
216 216
217 /* command execution */ 217 /* command execution */
218 .exec_command = sdhc_exec_command, 218 .exec_command = sdhc_exec_command,
219 219
220 /* card interrupt */ 220 /* card interrupt */
221 .card_enable_intr = sdhc_card_enable_intr, 221 .card_enable_intr = sdhc_card_enable_intr,
222 .card_intr_ack = sdhc_card_intr_ack, 222 .card_intr_ack = sdhc_card_intr_ack,
223 223
224 /* UHS functions */ 224 /* UHS functions */
225 .signal_voltage = sdhc_signal_voltage, 225 .signal_voltage = sdhc_signal_voltage,
 226 .bus_clock_ddr = sdhc_bus_clock_ddr,
226}; 227};
227 228
228static int 229static int
229sdhc_cfprint(void *aux, const char *pnp) 230sdhc_cfprint(void *aux, const char *pnp)
230{ 231{
231 const struct sdmmcbus_attach_args * const saa = aux; 232 const struct sdmmcbus_attach_args * const saa = aux;
232 const struct sdhc_host * const hp = saa->saa_sch; 233 const struct sdhc_host * const hp = saa->saa_sch;
233 234
234 if (pnp) { 235 if (pnp) {
235 aprint_normal("sdmmc at %s", pnp); 236 aprint_normal("sdmmc at %s", pnp);
236 } 237 }
237 for (size_t host = 0; host < hp->sc->sc_nhosts; host++) { 238 for (size_t host = 0; host < hp->sc->sc_nhosts; host++) {
238 if (hp->sc->sc_host[host] == hp) { 239 if (hp->sc->sc_host[host] == hp) {
@@ -408,34 +409,34 @@ sdhc_host_found(struct sdhc_softc *sc, b @@ -408,34 +409,34 @@ sdhc_host_found(struct sdhc_softc *sc, b
408 409
409 /* 410 /*
410 * Determine SD bus voltage levels supported by the controller. 411 * Determine SD bus voltage levels supported by the controller.
411 */ 412 */
412 aprint_normal(","); 413 aprint_normal(",");
413 if (ISSET(caps, SDHC_HIGH_SPEED_SUPP)) { 414 if (ISSET(caps, SDHC_HIGH_SPEED_SUPP)) {
414 SET(hp->ocr, MMC_OCR_HCS); 415 SET(hp->ocr, MMC_OCR_HCS);
415 aprint_normal(" HS"); 416 aprint_normal(" HS");
416 } 417 }
417 if (ISSET(caps2, SDHC_SDR50_SUPP)) { 418 if (ISSET(caps2, SDHC_SDR50_SUPP)) {
418 SET(hp->ocr, MMC_OCR_S18A); 419 SET(hp->ocr, MMC_OCR_S18A);
419 aprint_normal(" SDR50"); 420 aprint_normal(" SDR50");
420 } 421 }
421 if (ISSET(caps2, SDHC_SDR104_SUPP)) { 
422 SET(hp->ocr, MMC_OCR_S18A); 
423 aprint_normal(" SDR104"); 
424 } 
425 if (ISSET(caps2, SDHC_DDR50_SUPP)) { 422 if (ISSET(caps2, SDHC_DDR50_SUPP)) {
426 SET(hp->ocr, MMC_OCR_S18A); 423 SET(hp->ocr, MMC_OCR_S18A);
427 aprint_normal(" DDR50"); 424 aprint_normal(" DDR50");
428 } 425 }
 426 if (ISSET(caps2, SDHC_SDR104_SUPP)) {
 427 SET(hp->ocr, MMC_OCR_S18A);
 428 aprint_normal(" SDR104 HS200");
 429 }
429 if (ISSET(caps, SDHC_VOLTAGE_SUPP_1_8V)) { 430 if (ISSET(caps, SDHC_VOLTAGE_SUPP_1_8V)) {
430 SET(hp->ocr, MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V); 431 SET(hp->ocr, MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V);
431 aprint_normal(" 1.8V"); 432 aprint_normal(" 1.8V");
432 } 433 }
433 if (ISSET(caps, SDHC_VOLTAGE_SUPP_3_0V)) { 434 if (ISSET(caps, SDHC_VOLTAGE_SUPP_3_0V)) {
434 SET(hp->ocr, MMC_OCR_2_9V_3_0V | MMC_OCR_3_0V_3_1V); 435 SET(hp->ocr, MMC_OCR_2_9V_3_0V | MMC_OCR_3_0V_3_1V);
435 aprint_normal(" 3.0V"); 436 aprint_normal(" 3.0V");
436 } 437 }
437 if (ISSET(caps, SDHC_VOLTAGE_SUPP_3_3V)) { 438 if (ISSET(caps, SDHC_VOLTAGE_SUPP_3_3V)) {
438 SET(hp->ocr, MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V); 439 SET(hp->ocr, MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V);
439 aprint_normal(" 3.3V"); 440 aprint_normal(" 3.3V");
440 } 441 }
441 442
@@ -524,26 +525,34 @@ adma_done: @@ -524,26 +525,34 @@ adma_done:
524 saa.saa_clkmin = hp->clkbase / 256 / 16; 525 saa.saa_clkmin = hp->clkbase / 256 / 16;
525 else if (hp->sc->sc_clkmsk != 0) 526 else if (hp->sc->sc_clkmsk != 0)
526 saa.saa_clkmin = hp->clkbase / (hp->sc->sc_clkmsk >> 527 saa.saa_clkmin = hp->clkbase / (hp->sc->sc_clkmsk >>
527 (ffs(hp->sc->sc_clkmsk) - 1)); 528 (ffs(hp->sc->sc_clkmsk) - 1));
528 else if (hp->specver >= SDHC_SPEC_VERS_300) 529 else if (hp->specver >= SDHC_SPEC_VERS_300)
529 saa.saa_clkmin = hp->clkbase / 0x3ff; 530 saa.saa_clkmin = hp->clkbase / 0x3ff;
530 else 531 else
531 saa.saa_clkmin = hp->clkbase / 256; 532 saa.saa_clkmin = hp->clkbase / 256;
532 saa.saa_caps = SMC_CAPS_4BIT_MODE|SMC_CAPS_AUTO_STOP; 533 saa.saa_caps = SMC_CAPS_4BIT_MODE|SMC_CAPS_AUTO_STOP;
533 if (ISSET(sc->sc_flags, SDHC_FLAG_8BIT_MODE)) 534 if (ISSET(sc->sc_flags, SDHC_FLAG_8BIT_MODE))
534 saa.saa_caps |= SMC_CAPS_8BIT_MODE; 535 saa.saa_caps |= SMC_CAPS_8BIT_MODE;
535 if (ISSET(caps, SDHC_HIGH_SPEED_SUPP)) 536 if (ISSET(caps, SDHC_HIGH_SPEED_SUPP))
536 saa.saa_caps |= SMC_CAPS_SD_HIGHSPEED; 537 saa.saa_caps |= SMC_CAPS_SD_HIGHSPEED;
 538 if (ISSET(caps2, SDHC_SDR104_SUPP))
 539 saa.saa_caps |= SMC_CAPS_UHS_SDR104 |
 540 SMC_CAPS_UHS_SDR50 |
 541 SMC_CAPS_MMC_HS200;
 542 if (ISSET(caps2, SDHC_SDR50_SUPP))
 543 saa.saa_caps |= SMC_CAPS_UHS_SDR50;
 544 if (ISSET(caps2, SDHC_DDR50_SUPP))
 545 saa.saa_caps |= SMC_CAPS_UHS_DDR50;
537 if (ISSET(hp->flags, SHF_USE_DMA)) { 546 if (ISSET(hp->flags, SHF_USE_DMA)) {
538 saa.saa_caps |= SMC_CAPS_DMA; 547 saa.saa_caps |= SMC_CAPS_DMA;
539 if (!ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED)) 548 if (!ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED))
540 saa.saa_caps |= SMC_CAPS_MULTI_SEG_DMA; 549 saa.saa_caps |= SMC_CAPS_MULTI_SEG_DMA;
541 } 550 }
542 if (ISSET(sc->sc_flags, SDHC_FLAG_SINGLE_ONLY)) 551 if (ISSET(sc->sc_flags, SDHC_FLAG_SINGLE_ONLY))
543 saa.saa_caps |= SMC_CAPS_SINGLE_ONLY; 552 saa.saa_caps |= SMC_CAPS_SINGLE_ONLY;
544 hp->sdmmc = config_found(sc->sc_dev, &saa, sdhc_cfprint); 553 hp->sdmmc = config_found(sc->sc_dev, &saa, sdhc_cfprint);
545 554
546 return 0; 555 return 0;
547 556
548err: 557err:
549 cv_destroy(&hp->intr_cv); 558 cv_destroy(&hp->intr_cv);
@@ -954,27 +963,27 @@ sdhc_clock_divisor(struct sdhc_host *hp, @@ -954,27 +963,27 @@ sdhc_clock_divisor(struct sdhc_host *hp,
954 } 963 }
955 /* No divisor found. */ 964 /* No divisor found. */
956 return false; 965 return false;
957 } 966 }
958 /* No divisor found. */ 967 /* No divisor found. */
959 return false; 968 return false;
960} 969}
961 970
962/* 971/*
963 * Set or change SDCLK frequency or disable the SD clock. 972 * Set or change SDCLK frequency or disable the SD clock.
964 * Return zero on success. 973 * Return zero on success.
965 */ 974 */
966static int 975static int
967sdhc_bus_clock(sdmmc_chipset_handle_t sch, int freq) 976sdhc_bus_clock_ddr(sdmmc_chipset_handle_t sch, int freq, bool ddr)
968{ 977{
969 struct sdhc_host *hp = (struct sdhc_host *)sch; 978 struct sdhc_host *hp = (struct sdhc_host *)sch;
970 u_int div; 979 u_int div;
971 u_int timo; 980 u_int timo;
972 int16_t reg; 981 int16_t reg;
973 int error = 0; 982 int error = 0;
974 bool present __diagused; 983 bool present __diagused;
975 984
976 mutex_enter(&hp->intr_lock); 985 mutex_enter(&hp->intr_lock);
977 986
978#ifdef DIAGNOSTIC 987#ifdef DIAGNOSTIC
979 present = ISSET(HREAD4(hp, SDHC_PRESENT_STATE), SDHC_CMD_INHIBIT_MASK); 988 present = ISSET(HREAD4(hp, SDHC_PRESENT_STATE), SDHC_CMD_INHIBIT_MASK);
980 989
@@ -997,34 +1006,39 @@ sdhc_bus_clock(sdmmc_chipset_handle_t sc @@ -997,34 +1006,39 @@ sdhc_bus_clock(sdmmc_chipset_handle_t sc
997 if (ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED)) { 1006 if (ISSET(hp->sc->sc_flags, SDHC_FLAG_ENHANCED)) {
998 HCLR4(hp, SDHC_CLOCK_CTL, 0xfff8); 1007 HCLR4(hp, SDHC_CLOCK_CTL, 0xfff8);
999 if (freq == SDMMC_SDCLK_OFF) { 1008 if (freq == SDMMC_SDCLK_OFF) {
1000 HSET4(hp, SDHC_CLOCK_CTL, 0x80f0); 1009 HSET4(hp, SDHC_CLOCK_CTL, 0x80f0);
1001 goto out; 1010 goto out;
1002 } 1011 }
1003 } else { 1012 } else {
1004 HCLR2(hp, SDHC_CLOCK_CTL, SDHC_SDCLK_ENABLE); 1013 HCLR2(hp, SDHC_CLOCK_CTL, SDHC_SDCLK_ENABLE);
1005 if (freq == SDMMC_SDCLK_OFF) 1014 if (freq == SDMMC_SDCLK_OFF)
1006 goto out; 1015 goto out;
1007 } 1016 }
1008 1017
1009 if (hp->specver >= SDHC_SPEC_VERS_300) { 1018 if (hp->specver >= SDHC_SPEC_VERS_300) {
1010 /* XXX DDR */ 
1011 HCLR2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_MASK); 1019 HCLR2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_MASK);
1012 if (freq > 100000) { 1020 if (freq > 100000) {
1013 HSET2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_SDR104); 1021 HSET2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_SDR104);
1014 } else if (freq > 50000) { 1022 } else if (freq > 50000) {
1015 HSET2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_SDR50); 1023 HSET2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_SDR50);
1016 } else if (freq > 25000) { 1024 } else if (freq > 25000) {
1017 HSET2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_SDR25); 1025 if (ddr) {
 1026 HSET2(hp, SDHC_HOST_CTL2,
 1027 SDHC_UHS_MODE_SELECT_DDR50);
 1028 } else {
 1029 HSET2(hp, SDHC_HOST_CTL2,
 1030 SDHC_UHS_MODE_SELECT_SDR25);
 1031 }
1018 } else if (freq > 400) { 1032 } else if (freq > 400) {
1019 HSET2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_SDR12); 1033 HSET2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_SDR12);
1020 } 1034 }
1021 } 1035 }
1022 1036
1023 /* 1037 /*
1024 * Set the minimum base clock frequency divisor. 1038 * Set the minimum base clock frequency divisor.
1025 */ 1039 */
1026 if (!sdhc_clock_divisor(hp, freq, &div)) { 1040 if (!sdhc_clock_divisor(hp, freq, &div)) {
1027 /* Invalid base clock frequency or `freq' value. */ 1041 /* Invalid base clock frequency or `freq' value. */
1028 aprint_error_dev(hp->sc->sc_dev, 1042 aprint_error_dev(hp->sc->sc_dev,
1029 "Invalid bus clock %d kHz\n", freq); 1043 "Invalid bus clock %d kHz\n", freq);
1030 error = EINVAL; 1044 error = EINVAL;

cvs diff -r1.28 -r1.29 src/sys/dev/sdmmc/sdmmc.c (expand / switch to unified diff)

--- src/sys/dev/sdmmc/sdmmc.c 2015/08/03 05:32:50 1.28
+++ src/sys/dev/sdmmc/sdmmc.c 2015/08/03 10:08:51 1.29
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sdmmc.c,v 1.28 2015/08/03 05:32:50 mlelstv Exp $ */ 1/* $NetBSD: sdmmc.c,v 1.29 2015/08/03 10:08:51 jmcneill Exp $ */
2/* $OpenBSD: sdmmc.c,v 1.18 2009/01/09 10:58:38 jsg Exp $ */ 2/* $OpenBSD: sdmmc.c,v 1.18 2009/01/09 10:58:38 jsg Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> 5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 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 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
@@ -39,27 +39,27 @@ @@ -39,27 +39,27 @@
39 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 39 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
40 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 40 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 41 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
42 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 */ 43 */
44 44
45/* 45/*
46 * Host controller independent SD/MMC bus driver based on information 46 * Host controller independent SD/MMC bus driver based on information
47 * from SanDisk SD Card Product Manual Revision 2.2 (SanDisk), SDIO 47 * from SanDisk SD Card Product Manual Revision 2.2 (SanDisk), SDIO
48 * Simple Specification Version 1.0 (SDIO) and the Linux "mmc" driver. 48 * Simple Specification Version 1.0 (SDIO) and the Linux "mmc" driver.
49 */ 49 */
50 50
51#include <sys/cdefs.h> 51#include <sys/cdefs.h>
52__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.28 2015/08/03 05:32:50 mlelstv Exp $"); 52__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.29 2015/08/03 10:08:51 jmcneill Exp $");
53 53
54#ifdef _KERNEL_OPT 54#ifdef _KERNEL_OPT
55#include "opt_sdmmc.h" 55#include "opt_sdmmc.h"
56#endif 56#endif
57 57
58#include <sys/param.h> 58#include <sys/param.h>
59#include <sys/device.h> 59#include <sys/device.h>
60#include <sys/kernel.h> 60#include <sys/kernel.h>
61#include <sys/kthread.h> 61#include <sys/kthread.h>
62#include <sys/malloc.h> 62#include <sys/malloc.h>
63#include <sys/proc.h> 63#include <sys/proc.h>
64#include <sys/systm.h> 64#include <sys/systm.h>
65#include <sys/callout.h> 65#include <sys/callout.h>
@@ -513,27 +513,28 @@ sdmmc_enable(struct sdmmc_softc *sc) @@ -513,27 +513,28 @@ sdmmc_enable(struct sdmmc_softc *sc)
513 * Calculate the equivalent of the card OCR from the host 513 * Calculate the equivalent of the card OCR from the host
514 * capabilities and select the maximum supported bus voltage. 514 * capabilities and select the maximum supported bus voltage.
515 */ 515 */
516 error = sdmmc_chip_bus_power(sc->sc_sct, sc->sc_sch, 516 error = sdmmc_chip_bus_power(sc->sc_sct, sc->sc_sch,
517 sdmmc_chip_host_ocr(sc->sc_sct, sc->sc_sch)); 517 sdmmc_chip_host_ocr(sc->sc_sct, sc->sc_sch));
518 if (error) { 518 if (error) {
519 aprint_error_dev(sc->sc_dev, "couldn't supply bus power\n"); 519 aprint_error_dev(sc->sc_dev, "couldn't supply bus power\n");
520 goto out; 520 goto out;
521 } 521 }
522 522
523 /* 523 /*
524 * Select the minimum clock frequency. 524 * Select the minimum clock frequency.
525 */ 525 */
526 error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, SDMMC_SDCLK_400K); 526 error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, SDMMC_SDCLK_400K,
 527 false);
527 if (error) { 528 if (error) {
528 aprint_error_dev(sc->sc_dev, "couldn't supply clock\n"); 529 aprint_error_dev(sc->sc_dev, "couldn't supply clock\n");
529 goto out; 530 goto out;
530 } 531 }
531 532
532 /* XXX wait for card to power up */ 533 /* XXX wait for card to power up */
533 sdmmc_delay(100000); 534 sdmmc_delay(100000);
534 535
535 if (!ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) { 536 if (!ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) {
536 /* Initialize SD I/O card function(s). */ 537 /* Initialize SD I/O card function(s). */
537 error = sdmmc_io_enable(sc); 538 error = sdmmc_io_enable(sc);
538 if (error) { 539 if (error) {
539 DPRINTF(1, ("%s: sdmmc_io_enable failed %d\n", DEVNAME(sc), error)); 540 DPRINTF(1, ("%s: sdmmc_io_enable failed %d\n", DEVNAME(sc), error));
@@ -559,27 +560,28 @@ out: @@ -559,27 +560,28 @@ out:
559 560
560static void 561static void
561sdmmc_disable(struct sdmmc_softc *sc) 562sdmmc_disable(struct sdmmc_softc *sc)
562{ 563{
563 /* XXX complete commands if card is still present. */ 564 /* XXX complete commands if card is still present. */
564 565
565 if (!ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) { 566 if (!ISSET(sc->sc_caps, SMC_CAPS_SPI_MODE)) {
566 /* Make sure no card is still selected. */ 567 /* Make sure no card is still selected. */
567 (void)sdmmc_select_card(sc, NULL); 568 (void)sdmmc_select_card(sc, NULL);
568 } 569 }
569 570
570 /* Turn off bus power and clock. */ 571 /* Turn off bus power and clock. */
571 (void)sdmmc_chip_bus_width(sc->sc_sct, sc->sc_sch, 1); 572 (void)sdmmc_chip_bus_width(sc->sc_sct, sc->sc_sch, 1);
572 (void)sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, SDMMC_SDCLK_OFF); 573 (void)sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, SDMMC_SDCLK_OFF,
 574 false);
573 (void)sdmmc_chip_bus_power(sc->sc_sct, sc->sc_sch, 0); 575 (void)sdmmc_chip_bus_power(sc->sc_sct, sc->sc_sch, 0);
574 sc->sc_busclk = sc->sc_clkmax; 576 sc->sc_busclk = sc->sc_clkmax;
575} 577}
576 578
577/* 579/*
578 * Set the lowest bus voltage supported by the card and the host. 580 * Set the lowest bus voltage supported by the card and the host.
579 */ 581 */
580int 582int
581sdmmc_set_bus_power(struct sdmmc_softc *sc, uint32_t host_ocr, 583sdmmc_set_bus_power(struct sdmmc_softc *sc, uint32_t host_ocr,
582 uint32_t card_ocr) 584 uint32_t card_ocr)
583{ 585{
584 uint32_t bit; 586 uint32_t bit;
585 587

cvs diff -r1.9 -r1.10 src/sys/dev/sdmmc/sdmmc_io.c (expand / switch to unified diff)

--- src/sys/dev/sdmmc/sdmmc_io.c 2015/08/03 05:32:50 1.9
+++ src/sys/dev/sdmmc/sdmmc_io.c 2015/08/03 10:08:51 1.10
@@ -1,36 +1,36 @@ @@ -1,36 +1,36 @@
1/* $NetBSD: sdmmc_io.c,v 1.9 2015/08/03 05:32:50 mlelstv Exp $ */ 1/* $NetBSD: sdmmc_io.c,v 1.10 2015/08/03 10:08:51 jmcneill Exp $ */
2/* $OpenBSD: sdmmc_io.c,v 1.10 2007/09/17 01:33:33 krw Exp $ */ 2/* $OpenBSD: sdmmc_io.c,v 1.10 2007/09/17 01:33:33 krw Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> 5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 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 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 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 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */ 18 */
19 19
20/* Routines for SD I/O cards. */ 20/* Routines for SD I/O cards. */
21 21
22#include <sys/cdefs.h> 22#include <sys/cdefs.h>
23__KERNEL_RCSID(0, "$NetBSD: sdmmc_io.c,v 1.9 2015/08/03 05:32:50 mlelstv Exp $"); 23__KERNEL_RCSID(0, "$NetBSD: sdmmc_io.c,v 1.10 2015/08/03 10:08:51 jmcneill Exp $");
24 24
25#ifdef _KERNEL_OPT 25#ifdef _KERNEL_OPT
26#include "opt_sdmmc.h" 26#include "opt_sdmmc.h"
27#endif 27#endif
28 28
29#include <sys/param.h> 29#include <sys/param.h>
30#include <sys/kernel.h> 30#include <sys/kernel.h>
31#include <sys/malloc.h> 31#include <sys/malloc.h>
32#include <sys/proc.h> 32#include <sys/proc.h>
33#include <sys/systm.h> 33#include <sys/systm.h>
34 34
35#include <dev/sdmmc/sdmmc_ioreg.h> 35#include <dev/sdmmc/sdmmc_ioreg.h>
36#include <dev/sdmmc/sdmmcchip.h> 36#include <dev/sdmmc/sdmmcchip.h>
@@ -221,27 +221,28 @@ sdmmc_io_init(struct sdmmc_softc *sc, st @@ -221,27 +221,28 @@ sdmmc_io_init(struct sdmmc_softc *sc, st
221 221
222 reg = sdmmc_io_read_1(sf, SD_IO_CCCR_HIGH_SPEED); 222 reg = sdmmc_io_read_1(sf, SD_IO_CCCR_HIGH_SPEED);
223 if (reg & CCCR_HIGH_SPEED_SHS) { 223 if (reg & CCCR_HIGH_SPEED_SHS) {
224 reg |= CCCR_HIGH_SPEED_EHS; 224 reg |= CCCR_HIGH_SPEED_EHS;
225 sdmmc_io_write_1(sf, SD_IO_CCCR_HIGH_SPEED, reg); 225 sdmmc_io_write_1(sf, SD_IO_CCCR_HIGH_SPEED, reg);
226 sf->csd.tran_speed = 50000; /* 50MHz */ 226 sf->csd.tran_speed = 50000; /* 50MHz */
227 227
228 /* Wait 400KHz x 8 clock */ 228 /* Wait 400KHz x 8 clock */
229 delay(1); 229 delay(1);
230 } 230 }
231 if (sc->sc_busclk > sf->csd.tran_speed) 231 if (sc->sc_busclk > sf->csd.tran_speed)
232 sc->sc_busclk = sf->csd.tran_speed; 232 sc->sc_busclk = sf->csd.tran_speed;
233 error = 233 error =
234 sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, sc->sc_busclk); 234 sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, sc->sc_busclk,
 235 false);
235 if (error) 236 if (error)
236 aprint_error_dev(sc->sc_dev, 237 aprint_error_dev(sc->sc_dev,
237 "can't change bus clock\n"); 238 "can't change bus clock\n");
238 } else { 239 } else {
239 reg = sdmmc_io_read_1(sf0, SD_IO_FBR(sf->number) + 0x000); 240 reg = sdmmc_io_read_1(sf0, SD_IO_FBR(sf->number) + 0x000);
240 sf->interface = FBR_STD_FUNC_IF_CODE(reg); 241 sf->interface = FBR_STD_FUNC_IF_CODE(reg);
241 if (sf->interface == 0x0f) 242 if (sf->interface == 0x0f)
242 sf->interface = 243 sf->interface =
243 sdmmc_io_read_1(sf0, SD_IO_FBR(sf->number) + 0x001); 244 sdmmc_io_read_1(sf0, SD_IO_FBR(sf->number) + 0x001);
244 error = sdmmc_read_cis(sf, &sf->cis); 245 error = sdmmc_read_cis(sf, &sf->cis);
245 if (error) { 246 if (error) {
246 aprint_error_dev(sc->sc_dev, "couldn't read CIS\n"); 247 aprint_error_dev(sc->sc_dev, "couldn't read CIS\n");
247 SET(sf->flags, SFF_ERROR); 248 SET(sf->flags, SFF_ERROR);

cvs diff -r1.38 -r1.39 src/sys/dev/sdmmc/sdmmc_mem.c (expand / switch to unified diff)

--- src/sys/dev/sdmmc/sdmmc_mem.c 2015/08/03 05:32:50 1.38
+++ src/sys/dev/sdmmc/sdmmc_mem.c 2015/08/03 10:08:51 1.39
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sdmmc_mem.c,v 1.38 2015/08/03 05:32:50 mlelstv Exp $ */ 1/* $NetBSD: sdmmc_mem.c,v 1.39 2015/08/03 10:08:51 jmcneill Exp $ */
2/* $OpenBSD: sdmmc_mem.c,v 1.10 2009/01/09 10:55:22 jsg Exp $ */ 2/* $OpenBSD: sdmmc_mem.c,v 1.10 2009/01/09 10:55:22 jsg Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> 5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 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 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
@@ -35,27 +35,27 @@ @@ -35,27 +35,27 @@
35 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 35 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
36 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 36 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
37 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 37 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
38 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 38 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
39 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 39 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
40 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 40 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 41 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
42 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43 */ 43 */
44 44
45/* Routines for SD/MMC memory cards. */ 45/* Routines for SD/MMC memory cards. */
46 46
47#include <sys/cdefs.h> 47#include <sys/cdefs.h>
48__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.38 2015/08/03 05:32:50 mlelstv Exp $"); 48__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.39 2015/08/03 10:08:51 jmcneill Exp $");
49 49
50#ifdef _KERNEL_OPT 50#ifdef _KERNEL_OPT
51#include "opt_sdmmc.h" 51#include "opt_sdmmc.h"
52#endif 52#endif
53 53
54#include <sys/param.h> 54#include <sys/param.h>
55#include <sys/kernel.h> 55#include <sys/kernel.h>
56#include <sys/malloc.h> 56#include <sys/malloc.h>
57#include <sys/systm.h> 57#include <sys/systm.h>
58#include <sys/device.h> 58#include <sys/device.h>
59 59
60#include <dev/sdmmc/sdmmcchip.h> 60#include <dev/sdmmc/sdmmcchip.h>
61#include <dev/sdmmc/sdmmcreg.h> 61#include <dev/sdmmc/sdmmcreg.h>
@@ -86,26 +86,47 @@ static int sdmmc_mem_spi_read_ocr(struct @@ -86,26 +86,47 @@ static int sdmmc_mem_spi_read_ocr(struct
86static int sdmmc_mem_single_read_block(struct sdmmc_function *, uint32_t, 86static int sdmmc_mem_single_read_block(struct sdmmc_function *, uint32_t,
87 u_char *, size_t); 87 u_char *, size_t);
88static int sdmmc_mem_single_write_block(struct sdmmc_function *, uint32_t, 88static int sdmmc_mem_single_write_block(struct sdmmc_function *, uint32_t,
89 u_char *, size_t); 89 u_char *, size_t);
90static int sdmmc_mem_single_segment_dma_read_block(struct sdmmc_function *, 90static int sdmmc_mem_single_segment_dma_read_block(struct sdmmc_function *,
91 uint32_t, u_char *, size_t); 91 uint32_t, u_char *, size_t);
92static int sdmmc_mem_single_segment_dma_write_block(struct sdmmc_function *, 92static int sdmmc_mem_single_segment_dma_write_block(struct sdmmc_function *,
93 uint32_t, u_char *, size_t); 93 uint32_t, u_char *, size_t);
94static int sdmmc_mem_read_block_subr(struct sdmmc_function *, bus_dmamap_t, 94static int sdmmc_mem_read_block_subr(struct sdmmc_function *, bus_dmamap_t,
95 uint32_t, u_char *, size_t); 95 uint32_t, u_char *, size_t);
96static int sdmmc_mem_write_block_subr(struct sdmmc_function *, bus_dmamap_t, 96static int sdmmc_mem_write_block_subr(struct sdmmc_function *, bus_dmamap_t,
97 uint32_t, u_char *, size_t); 97 uint32_t, u_char *, size_t);
98 98
 99static const struct {
 100 const char *name;
 101 int v;
 102 int freq;
 103} switch_group0_functions[] = {
 104 /* Default/SDR12 */
 105 { "Default/SDR12", 0, 25000 },
 106
 107 /* High-Speed/SDR25 */
 108 { "High-Speed/SDR25", SMC_CAPS_SD_HIGHSPEED, 50000 },
 109
 110 /* SDR50 */
 111 { "SDR50", SMC_CAPS_UHS_SDR50, 100000 },
 112
 113 /* SDR104 */
 114 { "SDR104", SMC_CAPS_UHS_SDR104, 208000 },
 115
 116 /* DDR50 */
 117 { "DDR50", SMC_CAPS_UHS_DDR50, 50000 },
 118};
 119
99/* 120/*
100 * Initialize SD/MMC memory cards and memory in SDIO "combo" cards. 121 * Initialize SD/MMC memory cards and memory in SDIO "combo" cards.
101 */ 122 */
102int 123int
103sdmmc_mem_enable(struct sdmmc_softc *sc) 124sdmmc_mem_enable(struct sdmmc_softc *sc)
104{ 125{
105 uint32_t host_ocr; 126 uint32_t host_ocr;
106 uint32_t card_ocr; 127 uint32_t card_ocr;
107 uint32_t new_ocr; 128 uint32_t new_ocr;
108 uint32_t ocr = 0; 129 uint32_t ocr = 0;
109 int error; 130 int error;
110 131
111 SDMMC_LOCK(sc); 132 SDMMC_LOCK(sc);
@@ -211,47 +232,48 @@ mmc_mode: @@ -211,47 +232,48 @@ mmc_mode:
211 error = sdmmc_mmc_command(sc, &cmd); 232 error = sdmmc_mmc_command(sc, &cmd);
212 if (error) { 233 if (error) {
213 DPRINTF(("%s: voltage switch command failed\n", 234 DPRINTF(("%s: voltage switch command failed\n",
214 SDMMCDEVNAME(sc))); 235 SDMMCDEVNAME(sc)));
215 goto out; 236 goto out;
216 } 237 }
217 238
218 delay(1000); 239 delay(1000);
219 240
220 /* 241 /*
221 * Stop the clock 242 * Stop the clock
222 */ 243 */
223 error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, 244 error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch,
224 SDMMC_SDCLK_OFF); 245 SDMMC_SDCLK_OFF, false);
225 if (error) 246 if (error)
226 goto out; 247 goto out;
227 248
228 delay(1000); 249 delay(1000);
229 250
230 /* 251 /*
231 * Card switch command was successful, update host controller 252 * Card switch command was successful, update host controller
232 * signal voltage setting. 253 * signal voltage setting.
233 */ 254 */
234 error = sdmmc_chip_signal_voltage(sc->sc_sct, 255 error = sdmmc_chip_signal_voltage(sc->sc_sct,
235 sc->sc_sch, SDMMC_SIGNAL_VOLTAGE_180); 256 sc->sc_sch, SDMMC_SIGNAL_VOLTAGE_180);
236 if (error) 257 if (error)
237 goto out; 258 goto out;
238 259
239 delay(5000); 260 delay(5000);
240 261
241 /* 262 /*
242 * Switch to SDR12 timing 263 * Switch to SDR12 timing
243 */ 264 */
244 error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, 25000); 265 error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, 25000,
 266 false);
245 if (error) 267 if (error)
246 goto out; 268 goto out;
247 269
248 delay(1000); 270 delay(1000);
249 271
250 SET(sc->sc_flags, SMF_UHS_MODE); 272 SET(sc->sc_flags, SMF_UHS_MODE);
251 } 273 }
252 274
253out: 275out:
254 SDMMC_UNLOCK(sc); 276 SDMMC_UNLOCK(sc);
255 277
256 if (error) 278 if (error)
257 printf("%s: %s failed with error %d\n", SDMMCDEVNAME(sc), 279 printf("%s: %s failed with error %d\n", SDMMCDEVNAME(sc),
@@ -662,214 +684,258 @@ static void @@ -662,214 +684,258 @@ static void
662sdmmc_be512_to_bitfield512(sdmmc_bitfield512_t *buf) { 684sdmmc_be512_to_bitfield512(sdmmc_bitfield512_t *buf) {
663 size_t i; 685 size_t i;
664 uint32_t tmp0, tmp1; 686 uint32_t tmp0, tmp1;
665 const size_t bitswords = __arraycount(buf->_bits); 687 const size_t bitswords = __arraycount(buf->_bits);
666 for (i = 0; i < bitswords/2; i++) { 688 for (i = 0; i < bitswords/2; i++) {
667 tmp0 = buf->_bits[i]; 689 tmp0 = buf->_bits[i];
668 tmp1 = buf->_bits[bitswords - 1 - i]; 690 tmp1 = buf->_bits[bitswords - 1 - i];
669 buf->_bits[i] = be32toh(tmp1); 691 buf->_bits[i] = be32toh(tmp1);
670 buf->_bits[bitswords - 1 - i] = be32toh(tmp0); 692 buf->_bits[bitswords - 1 - i] = be32toh(tmp0);
671 } 693 }
672} 694}
673 695
674static int 696static int
 697sdmmc_mem_select_transfer_mode(struct sdmmc_softc *sc, int support_func)
 698{
 699 if (ISSET(sc->sc_flags, SMF_UHS_MODE)) {
 700 if (ISSET(sc->sc_caps, SMC_CAPS_UHS_SDR104) &&
 701 ISSET(support_func, SD_ACCESS_MODE_SDR104)) {
 702 return SD_ACCESS_MODE_SDR104;
 703 }
 704 if (ISSET(sc->sc_caps, SMC_CAPS_UHS_DDR50) &&
 705 ISSET(support_func, SD_ACCESS_MODE_DDR50)) {
 706 return SD_ACCESS_MODE_DDR50;
 707 }
 708 if (ISSET(sc->sc_caps, SMC_CAPS_UHS_SDR50) &&
 709 ISSET(support_func, SD_ACCESS_MODE_SDR50)) {
 710 return SD_ACCESS_MODE_SDR50;
 711 }
 712 }
 713 if (ISSET(sc->sc_caps, SMC_CAPS_SD_HIGHSPEED) &&
 714 ISSET(support_func, SD_ACCESS_MODE_SDR25)) {
 715 return SD_ACCESS_MODE_SDR25;
 716 }
 717 return SD_ACCESS_MODE_SDR12;
 718}
 719
 720static int
675sdmmc_mem_sd_init(struct sdmmc_softc *sc, struct sdmmc_function *sf) 721sdmmc_mem_sd_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
676{ 722{
677 static const struct { 723 int support_func, best_func, bus_clock, error, i;
678 int v; 
679 int freq; 
680 int uhs; 
681 } switch_group0_functions[] = { 
682 /* Default/SDR12 */ 
683 { MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V | 
684 MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V, 25000, 0 }, 
685 
686 /* High-Speed/SDR25 */ 
687 { MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V | 
688 MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V, 50000, 0 }, 
689 
690 /* SDR50 */ 
691 { MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V, 100000, 1 }, 
692 
693 /* SDR104 */ 
694 { MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V, 208000, 1 }, 
695 
696#if notyet 
697 /* DDR50 */ 
698 { MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V, 50000, 1 }, 
699#endif 
700 }; 
701 int host_ocr, support_func, best_func, bus_clock, error, g, i; 
702 sdmmc_bitfield512_t status; /* Switch Function Status */ 724 sdmmc_bitfield512_t status; /* Switch Function Status */
 725 bool ddr = false;
703 726
704 /* change bus clock */ 727 /* change bus clock */
705 bus_clock = min(sc->sc_busclk, sf->csd.tran_speed); 728 bus_clock = min(sc->sc_busclk, sf->csd.tran_speed);
706 error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, bus_clock); 729 error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, bus_clock, false);
707 if (error) { 730 if (error) {
708 aprint_error_dev(sc->sc_dev, "can't change bus clock\n"); 731 aprint_error_dev(sc->sc_dev, "can't change bus clock\n");
709 return error; 732 return error;
710 } 733 }
711 734
712 error = sdmmc_mem_send_scr(sc, sf, sf->raw_scr); 735 error = sdmmc_mem_send_scr(sc, sf, sf->raw_scr);
713 if (error) { 736 if (error) {
714 aprint_error_dev(sc->sc_dev, "SD_SEND_SCR send failed.\n"); 737 aprint_error_dev(sc->sc_dev, "SD_SEND_SCR send failed.\n");
715 return error; 738 return error;
716 } 739 }
717 error = sdmmc_mem_decode_scr(sc, sf); 740 error = sdmmc_mem_decode_scr(sc, sf);
718 if (error) 741 if (error)
719 return error; 742 return error;
720 743
721 if (ISSET(sc->sc_caps, SMC_CAPS_4BIT_MODE) && 744 if (ISSET(sc->sc_caps, SMC_CAPS_4BIT_MODE) &&
722 ISSET(sf->scr.bus_width, SCR_SD_BUS_WIDTHS_4BIT)) { 745 ISSET(sf->scr.bus_width, SCR_SD_BUS_WIDTHS_4BIT)) {
723 DPRINTF(("%s: change bus width\n", SDMMCDEVNAME(sc))); 746 DPRINTF(("%s: change bus width\n", SDMMCDEVNAME(sc)));
724 error = sdmmc_set_bus_width(sf, 4); 747 error = sdmmc_set_bus_width(sf, 4);
725 if (error) { 748 if (error) {
726 aprint_error_dev(sc->sc_dev, 749 aprint_error_dev(sc->sc_dev,
727 "can't change bus width (%d bit)\n", 4); 750 "can't change bus width (%d bit)\n", 4);
728 return error; 751 return error;
729 } 752 }
730 sf->width = 4; 753 sf->width = 4;
731 } 754 }
732 755
 756 best_func = 0;
733 if (sf->scr.sd_spec >= SCR_SD_SPEC_VER_1_10 && 757 if (sf->scr.sd_spec >= SCR_SD_SPEC_VER_1_10 &&
734 ISSET(sf->csd.ccc, SD_CSD_CCC_SWITCH)) { 758 ISSET(sf->csd.ccc, SD_CSD_CCC_SWITCH)) {
735 DPRINTF(("%s: switch func mode 0\n", SDMMCDEVNAME(sc))); 759 DPRINTF(("%s: switch func mode 0\n", SDMMCDEVNAME(sc)));
736 error = sdmmc_mem_sd_switch(sf, 0, 1, 0, &status); 760 error = sdmmc_mem_sd_switch(sf, 0, 1, 0, &status);
737 if (error) { 761 if (error) {
738 aprint_error_dev(sc->sc_dev, 762 aprint_error_dev(sc->sc_dev,
739 "switch func mode 0 failed\n"); 763 "switch func mode 0 failed\n");
740 return error; 764 return error;
741 } 765 }
742 766
743 host_ocr = sdmmc_chip_host_ocr(sc->sc_sct, sc->sc_sch); 
744 support_func = SFUNC_STATUS_GROUP(&status, 1); 767 support_func = SFUNC_STATUS_GROUP(&status, 1);
745 DPRINTF(("%s: support_func %#x\n", SDMMCDEVNAME(sc), support_func)); 768
746 best_func = 0; 769 for (i = 0; i < __arraycount(switch_group0_functions); i++) {
747 for (i = 0, g = 1; 770 if (!(support_func & (1 << i)))
748 i < __arraycount(switch_group0_functions); i++, g <<= 1) { 
749 if (!(switch_group0_functions[i].v & host_ocr)) 
750 continue; 771 continue;
751 if (switch_group0_functions[i].uhs && 772 DPRINTF(("%s: card supports mode %s\n",
752 !ISSET(sc->sc_flags, SMF_UHS_MODE)) 773 SDMMCDEVNAME(sc),
753 break; 774 switch_group0_functions[i].name));
754 if (g & support_func) 
755 best_func = i; 
756 } 775 }
757 if (ISSET(sc->sc_caps, SMC_CAPS_SD_HIGHSPEED) && 776
758 best_func != 0) { 777 best_func = sdmmc_mem_select_transfer_mode(sc, support_func);
 778
 779 DPRINTF(("%s: using mode %s\n", SDMMCDEVNAME(sc),
 780 switch_group0_functions[best_func].name));
 781
 782 if (best_func != 0) {
759 DPRINTF(("%s: switch func mode 1(func=%d)\n", 783 DPRINTF(("%s: switch func mode 1(func=%d)\n",
760 SDMMCDEVNAME(sc), best_func)); 784 SDMMCDEVNAME(sc), best_func));
761 error = 785 error =
762 sdmmc_mem_sd_switch(sf, 1, 1, best_func, &status); 786 sdmmc_mem_sd_switch(sf, 1, 1, best_func, &status);
763 if (error) { 787 if (error) {
764 aprint_error_dev(sc->sc_dev, 788 aprint_error_dev(sc->sc_dev,
765 "switch func mode 1 failed:" 789 "switch func mode 1 failed:"
766 " group 1 function %d(0x%2x)\n", 790 " group 1 function %d(0x%2x)\n",
767 best_func, support_func); 791 best_func, support_func);
768 return error; 792 return error;
769 } 793 }
770 sf->csd.tran_speed = 794 sf->csd.tran_speed =
771 switch_group0_functions[best_func].freq; 795 switch_group0_functions[best_func].freq;
772 796
 797 if (best_func == SD_ACCESS_MODE_DDR50)
 798 ddr = true;
 799
773 /* Wait 400KHz x 8 clock (2.5us * 8 + slop) */ 800 /* Wait 400KHz x 8 clock (2.5us * 8 + slop) */
774 delay(25); 801 delay(25);
775 } 802 }
776 } 803 }
777 804
778 /* update bus clock */ 805 /* update bus clock */
779 if (sc->sc_busclk > sf->csd.tran_speed) 806 if (sc->sc_busclk > sf->csd.tran_speed)
780 sc->sc_busclk = sf->csd.tran_speed; 807 sc->sc_busclk = sf->csd.tran_speed;
781 if (sc->sc_busclk == bus_clock) 808 if (sc->sc_busclk == bus_clock && sc->sc_busddr == ddr)
782 return 0; 809 return 0;
783 810
784 /* change bus clock */ 811 /* change bus clock */
785 error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, sc->sc_busclk); 812 error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, sc->sc_busclk,
 813 ddr);
786 if (error) { 814 if (error) {
787 aprint_error_dev(sc->sc_dev, "can't change bus clock\n"); 815 aprint_error_dev(sc->sc_dev, "can't change bus clock\n");
788 return error; 816 return error;
789 } 817 }
790 818
 819 sc->sc_transfer_mode = switch_group0_functions[best_func].name;
 820 sc->sc_busddr = ddr;
 821
791 return 0; 822 return 0;
792} 823}
793 824
794static int 825static int
795sdmmc_mem_mmc_init(struct sdmmc_softc *sc, struct sdmmc_function *sf) 826sdmmc_mem_mmc_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
796{ 827{
797 int width, value, hs_timing, bus_clock, error; 828 int width, value, hs_timing, bus_clock, error;
798 char ext_csd[512]; 829 char ext_csd[512];
799 uint32_t sectors = 0; 830 uint32_t sectors = 0;
800 int host_ocr; 831
 832 sc->sc_transfer_mode = NULL;
801 833
802 /* change bus clock */ 834 /* change bus clock */
803 bus_clock = min(sc->sc_busclk, sf->csd.tran_speed); 835 bus_clock = min(sc->sc_busclk, sf->csd.tran_speed);
804 error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, bus_clock); 836 error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, bus_clock, false);
805 if (error) { 837 if (error) {
806 aprint_error_dev(sc->sc_dev, "can't change bus clock\n"); 838 aprint_error_dev(sc->sc_dev, "can't change bus clock\n");
807 return error; 839 return error;
808 } 840 }
809 841
810 host_ocr = sdmmc_chip_host_ocr(sc->sc_sct, sc->sc_sch); 
811 
812 if (sf->csd.mmcver >= MMC_CSD_MMCVER_4_0) { 842 if (sf->csd.mmcver >= MMC_CSD_MMCVER_4_0) {
813 error = sdmmc_mem_send_cxd_data(sc, 843 error = sdmmc_mem_send_cxd_data(sc,
814 MMC_SEND_EXT_CSD, ext_csd, sizeof(ext_csd)); 844 MMC_SEND_EXT_CSD, ext_csd, sizeof(ext_csd));
815 if (error) { 845 if (error) {
816 aprint_error_dev(sc->sc_dev, 846 aprint_error_dev(sc->sc_dev,
817 "can't read EXT_CSD (error=%d)\n", error); 847 "can't read EXT_CSD (error=%d)\n", error);
818 return error; 848 return error;
819 } 849 }
820 if ((sf->csd.csdver == MMC_CSD_CSDVER_EXT_CSD) && 850 if ((sf->csd.csdver == MMC_CSD_CSDVER_EXT_CSD) &&
821 (ext_csd[EXT_CSD_STRUCTURE] > EXT_CSD_STRUCTURE_VER_1_2)) { 851 (ext_csd[EXT_CSD_STRUCTURE] > EXT_CSD_STRUCTURE_VER_1_2)) {
822 aprint_error_dev(sc->sc_dev, 852 aprint_error_dev(sc->sc_dev,
823 "unrecognised future version (%d)\n", 853 "unrecognised future version (%d)\n",
824 ext_csd[EXT_CSD_STRUCTURE]); 854 ext_csd[EXT_CSD_STRUCTURE]);
825 return ENOTSUP; 855 return ENOTSUP;
826 } 856 }
827 857
828 if (ISSET(host_ocr, MMC_OCR_1_7V_1_8V|MMC_OCR_1_8V_1_9V) && 858 sc->sc_transfer_mode = NULL;
 859 if (ISSET(sc->sc_caps, SMC_CAPS_MMC_HS200) &&
829 ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_HS200_1_8V) { 860 ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_HS200_1_8V) {
830 sf->csd.tran_speed = 200000; /* 200MHz SDR */ 861 sf->csd.tran_speed = 200000; /* 200MHz SDR */
831 hs_timing = 2; 862 hs_timing = 2;
832 } else if (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_52M) { 863 } else if (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_52M) {
833 sf->csd.tran_speed = 52000; /* 52MHz */ 864 sf->csd.tran_speed = 52000; /* 52MHz */
834 hs_timing = 1; 865 hs_timing = 1;
835 } else if (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_26M) { 866 } else if (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_26M) {
836 sf->csd.tran_speed = 26000; /* 26MHz */ 867 sf->csd.tran_speed = 26000; /* 26MHz */
837 hs_timing = 0; 868 hs_timing = 0;
838 } else { 869 } else {
839 aprint_error_dev(sc->sc_dev, 870 aprint_error_dev(sc->sc_dev,
840 "unknown CARD_TYPE: 0x%x\n", 871 "unknown CARD_TYPE: 0x%x\n",
841 ext_csd[EXT_CSD_CARD_TYPE]); 872 ext_csd[EXT_CSD_CARD_TYPE]);
842 return ENOTSUP; 873 return ENOTSUP;
843 } 874 }
844 875
845 if (!ISSET(sc->sc_caps, SMC_CAPS_MMC_HIGHSPEED)) { 876 if (hs_timing == 2) {
 877 error = sdmmc_chip_signal_voltage(sc->sc_sct,
 878 sc->sc_sch, SDMMC_SIGNAL_VOLTAGE_180);
 879 if (error)
 880 hs_timing = 1;
 881 }
 882
 883 if (ISSET(sc->sc_caps, SMC_CAPS_8BIT_MODE)) {
 884 width = 8;
 885 value = EXT_CSD_BUS_WIDTH_8;
 886 } else if (ISSET(sc->sc_caps, SMC_CAPS_4BIT_MODE)) {
 887 width = 4;
 888 value = EXT_CSD_BUS_WIDTH_4;
 889 } else {
 890 width = 1;
 891 value = EXT_CSD_BUS_WIDTH_1;
 892 }
 893
 894 if (width != 1) {
 895 error = sdmmc_mem_mmc_switch(sf, EXT_CSD_CMD_SET_NORMAL,
 896 EXT_CSD_BUS_WIDTH, value);
 897 if (error == 0)
 898 error = sdmmc_chip_bus_width(sc->sc_sct,
 899 sc->sc_sch, width);
 900 else {
 901 DPRINTF(("%s: can't change bus width"
 902 " (%d bit)\n", SDMMCDEVNAME(sc), width));
 903 return error;
 904 }
 905
 906 /* XXXX: need bus test? (using by CMD14 & CMD19) */
 907 }
 908 sf->width = width;
 909
 910 if (hs_timing == 1 &&
 911 !ISSET(sc->sc_caps, SMC_CAPS_MMC_HIGHSPEED)) {
846 hs_timing = 0; 912 hs_timing = 0;
847 } 913 }
848 if (hs_timing) { 914 if (hs_timing) {
849 error = sdmmc_mem_mmc_switch(sf, EXT_CSD_CMD_SET_NORMAL, 915 error = sdmmc_mem_mmc_switch(sf, EXT_CSD_CMD_SET_NORMAL,
850 EXT_CSD_HS_TIMING, hs_timing); 916 EXT_CSD_HS_TIMING, hs_timing);
851 if (error) { 917 if (error) {
852 aprint_error_dev(sc->sc_dev, 918 aprint_error_dev(sc->sc_dev,
853 "can't change high speed\n"); 919 "can't change high speed\n");
854 return error; 920 return error;
855 } 921 }
856 } 922 }
857 923
858 if (sc->sc_busclk > sf->csd.tran_speed) 924 if (sc->sc_busclk > sf->csd.tran_speed)
859 sc->sc_busclk = sf->csd.tran_speed; 925 sc->sc_busclk = sf->csd.tran_speed;
860 if (sc->sc_busclk != bus_clock) { 926 if (sc->sc_busclk != bus_clock) {
861 error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, 927 error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch,
862 sc->sc_busclk); 928 sc->sc_busclk, false);
863 if (error) { 929 if (error) {
864 aprint_error_dev(sc->sc_dev, 930 aprint_error_dev(sc->sc_dev,
865 "can't change bus clock\n"); 931 "can't change bus clock\n");
866 return error; 932 return error;
867 } 933 }
868 } 934 }
869 935
870 if (hs_timing) { 936 if (hs_timing) {
871 error = sdmmc_mem_send_cxd_data(sc, 937 error = sdmmc_mem_send_cxd_data(sc,
872 MMC_SEND_EXT_CSD, ext_csd, sizeof(ext_csd)); 938 MMC_SEND_EXT_CSD, ext_csd, sizeof(ext_csd));
873 if (error) { 939 if (error) {
874 aprint_error_dev(sc->sc_dev, 940 aprint_error_dev(sc->sc_dev,
875 "can't re-read EXT_CSD\n"); 941 "can't re-read EXT_CSD\n");
@@ -881,58 +947,37 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s @@ -881,58 +947,37 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *s
881 return EINVAL; 947 return EINVAL;
882 } 948 }
883 } 949 }
884 950
885 sectors = ext_csd[EXT_CSD_SEC_COUNT + 0] << 0 | 951 sectors = ext_csd[EXT_CSD_SEC_COUNT + 0] << 0 |
886 ext_csd[EXT_CSD_SEC_COUNT + 1] << 8 | 952 ext_csd[EXT_CSD_SEC_COUNT + 1] << 8 |
887 ext_csd[EXT_CSD_SEC_COUNT + 2] << 16 | 953 ext_csd[EXT_CSD_SEC_COUNT + 2] << 16 |
888 ext_csd[EXT_CSD_SEC_COUNT + 3] << 24; 954 ext_csd[EXT_CSD_SEC_COUNT + 3] << 24;
889 if (sectors > (2u * 1024 * 1024 * 1024) / 512) { 955 if (sectors > (2u * 1024 * 1024 * 1024) / 512) {
890 SET(sf->flags, SFF_SDHC); 956 SET(sf->flags, SFF_SDHC);
891 sf->csd.capacity = sectors; 957 sf->csd.capacity = sectors;
892 } 958 }
893 959
894 if (ISSET(sc->sc_caps, SMC_CAPS_8BIT_MODE)) { 960 if (hs_timing == 2) {
895 width = 8; 961 sc->sc_transfer_mode = "HS200";
896 value = EXT_CSD_BUS_WIDTH_8; 
897 } else if (ISSET(sc->sc_caps, SMC_CAPS_4BIT_MODE)) { 
898 width = 4; 
899 value = EXT_CSD_BUS_WIDTH_4; 
900 } else { 962 } else {
901 width = 1; 963 sc->sc_transfer_mode = NULL;
902 value = EXT_CSD_BUS_WIDTH_1; 
903 } 964 }
904 
905 if (width != 1) { 
906 error = sdmmc_mem_mmc_switch(sf, EXT_CSD_CMD_SET_NORMAL, 
907 EXT_CSD_BUS_WIDTH, value); 
908 if (error == 0) 
909 error = sdmmc_chip_bus_width(sc->sc_sct, 
910 sc->sc_sch, width); 
911 else { 
912 DPRINTF(("%s: can't change bus width" 
913 " (%d bit)\n", SDMMCDEVNAME(sc), width)); 
914 return error; 
915 } 
916 
917 /* XXXX: need bus test? (using by CMD14 & CMD19) */ 
918 } 
919 sf->width = width; 
920 } else { 965 } else {
921 if (sc->sc_busclk > sf->csd.tran_speed) 966 if (sc->sc_busclk > sf->csd.tran_speed)
922 sc->sc_busclk = sf->csd.tran_speed; 967 sc->sc_busclk = sf->csd.tran_speed;
923 if (sc->sc_busclk != bus_clock) { 968 if (sc->sc_busclk != bus_clock) {
924 error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, 969 error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch,
925 sc->sc_busclk); 970 sc->sc_busclk, false);
926 if (error) { 971 if (error) {
927 aprint_error_dev(sc->sc_dev, 972 aprint_error_dev(sc->sc_dev,
928 "can't change bus clock\n"); 973 "can't change bus clock\n");
929 return error; 974 return error;
930 } 975 }
931 } 976 }
932 } 977 }
933 978
934 return 0; 979 return 0;
935} 980}
936 981
937static int 982static int
938sdmmc_mem_send_cid(struct sdmmc_softc *sc, sdmmc_response *resp) 983sdmmc_mem_send_cid(struct sdmmc_softc *sc, sdmmc_response *resp)
@@ -1073,31 +1118,31 @@ sdmmc_mem_decode_scr(struct sdmmc_softc  @@ -1073,31 +1118,31 @@ sdmmc_mem_decode_scr(struct sdmmc_softc
1073 memset(resp, 0, sizeof(resp)); 1118 memset(resp, 0, sizeof(resp));
1074 /* 1119 /*
1075 * Change the raw-scr received from the DMA stream to resp. 1120 * Change the raw-scr received from the DMA stream to resp.
1076 */ 1121 */
1077 resp[0] = be32toh(sf->raw_scr[1]) >> 8; // LSW 1122 resp[0] = be32toh(sf->raw_scr[1]) >> 8; // LSW
1078 resp[1] = be32toh(sf->raw_scr[0]); // MSW 1123 resp[1] = be32toh(sf->raw_scr[0]); // MSW
1079 resp[0] |= (resp[1] & 0xff) << 24; 1124 resp[0] |= (resp[1] & 0xff) << 24;
1080 resp[1] >>= 8; 1125 resp[1] >>= 8;
1081 1126
1082 ver = SCR_STRUCTURE(resp); 1127 ver = SCR_STRUCTURE(resp);
1083 sf->scr.sd_spec = SCR_SD_SPEC(resp); 1128 sf->scr.sd_spec = SCR_SD_SPEC(resp);
1084 sf->scr.bus_width = SCR_SD_BUS_WIDTHS(resp); 1129 sf->scr.bus_width = SCR_SD_BUS_WIDTHS(resp);
1085 1130
1086 DPRINTF(("%s: sdmmc_mem_decode_scr: %08x%08x spec=%d, bus width=%d\n", 1131 DPRINTF(("%s: sdmmc_mem_decode_scr: %08x%08x ver=%d, spec=%d, bus width=%d, spec3=%d\n",
1087 SDMMCDEVNAME(sc), resp[1], resp[0], 1132 SDMMCDEVNAME(sc), resp[1], resp[0],
1088 sf->scr.sd_spec, sf->scr.bus_width)); 1133 ver, sf->scr.sd_spec, sf->scr.bus_width, sf->scr.sd_spec3));
1089 1134
1090 if (ver != 0) { 1135 if (ver != 0 && ver != 1) {
1091 DPRINTF(("%s: unknown structure version: %d\n", 1136 DPRINTF(("%s: unknown structure version: %d\n",
1092 SDMMCDEVNAME(sc), ver)); 1137 SDMMCDEVNAME(sc), ver));
1093 return EINVAL; 1138 return EINVAL;
1094 } 1139 }
1095 return 0; 1140 return 0;
1096} 1141}
1097 1142
1098static int 1143static int
1099sdmmc_mem_send_cxd_data(struct sdmmc_softc *sc, int opcode, void *data, 1144sdmmc_mem_send_cxd_data(struct sdmmc_softc *sc, int opcode, void *data,
1100 size_t datalen) 1145 size_t datalen)
1101{ 1146{
1102 struct sdmmc_command cmd; 1147 struct sdmmc_command cmd;
1103 bus_dma_segment_t ds[1]; 1148 bus_dma_segment_t ds[1];

cvs diff -r1.5 -r1.6 src/sys/dev/sdmmc/sdmmcchip.h (expand / switch to unified diff)

--- src/sys/dev/sdmmc/sdmmcchip.h 2015/08/02 21:44:36 1.5
+++ src/sys/dev/sdmmc/sdmmcchip.h 2015/08/03 10:08:51 1.6
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sdmmcchip.h,v 1.5 2015/08/02 21:44:36 jmcneill Exp $ */ 1/* $NetBSD: sdmmcchip.h,v 1.6 2015/08/03 10:08:51 jmcneill Exp $ */
2/* $OpenBSD: sdmmcchip.h,v 1.3 2007/05/31 10:09:01 uwe Exp $ */ 2/* $OpenBSD: sdmmcchip.h,v 1.3 2007/05/31 10:09:01 uwe Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> 5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 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 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
@@ -50,47 +50,48 @@ struct sdmmc_chip_functions { @@ -50,47 +50,48 @@ struct sdmmc_chip_functions {
50 int (*bus_width)(sdmmc_chipset_handle_t, int); 50 int (*bus_width)(sdmmc_chipset_handle_t, int);
51 int (*bus_rod)(sdmmc_chipset_handle_t, int); 51 int (*bus_rod)(sdmmc_chipset_handle_t, int);
52 52
53 /* command execution */ 53 /* command execution */
54 void (*exec_command)(sdmmc_chipset_handle_t, 54 void (*exec_command)(sdmmc_chipset_handle_t,
55 struct sdmmc_command *); 55 struct sdmmc_command *);
56 56
57 /* card interrupt */ 57 /* card interrupt */
58 void (*card_enable_intr)(sdmmc_chipset_handle_t, int); 58 void (*card_enable_intr)(sdmmc_chipset_handle_t, int);
59 void (*card_intr_ack)(sdmmc_chipset_handle_t); 59 void (*card_intr_ack)(sdmmc_chipset_handle_t);
60 60
61 /* UHS functions */ 61 /* UHS functions */
62 int (*signal_voltage)(sdmmc_chipset_handle_t, int); 62 int (*signal_voltage)(sdmmc_chipset_handle_t, int);
 63 int (*bus_clock_ddr)(sdmmc_chipset_handle_t, int, bool);
63}; 64};
64 65
65/* host controller reset */ 66/* host controller reset */
66#define sdmmc_chip_host_reset(tag, handle) \ 67#define sdmmc_chip_host_reset(tag, handle) \
67 ((tag)->host_reset((handle))) 68 ((tag)->host_reset((handle)))
68/* host capabilities */ 69/* host capabilities */
69#define sdmmc_chip_host_ocr(tag, handle) \ 70#define sdmmc_chip_host_ocr(tag, handle) \
70 ((tag)->host_ocr((handle))) 71 ((tag)->host_ocr((handle)))
71#define sdmmc_chip_host_maxblklen(tag, handle) \ 72#define sdmmc_chip_host_maxblklen(tag, handle) \
72 ((tag)->host_maxblklen((handle))) 73 ((tag)->host_maxblklen((handle)))
73/* card detection */ 74/* card detection */
74#define sdmmc_chip_card_detect(tag, handle) \ 75#define sdmmc_chip_card_detect(tag, handle) \
75 ((tag)->card_detect((handle))) 76 ((tag)->card_detect((handle)))
76/* write protect */ 77/* write protect */
77#define sdmmc_chip_write_protect(tag, handle) \ 78#define sdmmc_chip_write_protect(tag, handle) \
78 ((tag)->write_protect((handle))) 79 ((tag)->write_protect((handle)))
79/* bus power, clock frequency, width and rod */ 80/* bus power, clock frequency, width and rod */
80#define sdmmc_chip_bus_power(tag, handle, ocr) \ 81#define sdmmc_chip_bus_power(tag, handle, ocr) \
81 ((tag)->bus_power((handle), (ocr))) 82 ((tag)->bus_power((handle), (ocr)))
82#define sdmmc_chip_bus_clock(tag, handle, freq) \ 83#define sdmmc_chip_bus_clock(tag, handle, freq, ddr) \
83 ((tag)->bus_clock((handle), (freq))) 84 ((tag)->bus_clock_ddr ? (tag)->bus_clock_ddr((handle), (freq), (ddr)) : ((ddr) ? EINVAL : ((tag)->bus_clock((handle), (freq)))))
84#define sdmmc_chip_bus_width(tag, handle, width) \ 85#define sdmmc_chip_bus_width(tag, handle, width) \
85 ((tag)->bus_width((handle), (width))) 86 ((tag)->bus_width((handle), (width)))
86#define sdmmc_chip_bus_rod(tag, handle, width) \ 87#define sdmmc_chip_bus_rod(tag, handle, width) \
87 ((tag)->bus_rod((handle), (width))) 88 ((tag)->bus_rod((handle), (width)))
88/* command execution */ 89/* command execution */
89#define sdmmc_chip_exec_command(tag, handle, cmdp) \ 90#define sdmmc_chip_exec_command(tag, handle, cmdp) \
90 ((tag)->exec_command((handle), (cmdp))) 91 ((tag)->exec_command((handle), (cmdp)))
91/* card interrupt */ 92/* card interrupt */
92#define sdmmc_chip_card_enable_intr(tag, handle, enable) \ 93#define sdmmc_chip_card_enable_intr(tag, handle, enable) \
93 ((tag)->card_enable_intr((handle), (enable))) 94 ((tag)->card_enable_intr((handle), (enable)))
94#define sdmmc_chip_card_intr_ack(tag, handle) \ 95#define sdmmc_chip_card_intr_ack(tag, handle) \
95 ((tag)->card_intr_ack((handle))) 96 ((tag)->card_intr_ack((handle)))
96/* UHS functions */ 97/* UHS functions */

cvs diff -r1.17 -r1.18 src/sys/dev/sdmmc/sdmmcreg.h (expand / switch to unified diff)

--- src/sys/dev/sdmmc/sdmmcreg.h 2015/08/02 22:47:05 1.17
+++ src/sys/dev/sdmmc/sdmmcreg.h 2015/08/03 10:08:51 1.18
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sdmmcreg.h,v 1.17 2015/08/02 22:47:05 jmcneill Exp $ */ 1/* $NetBSD: sdmmcreg.h,v 1.18 2015/08/03 10:08:51 jmcneill Exp $ */
2/* $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $ */ 2/* $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> 5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 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 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
@@ -324,26 +324,32 @@ @@ -324,26 +324,32 @@
324#define SCR_SD_BUS_WIDTHS_1BIT (1 << 0) /* 1bit (DAT0) */ 324#define SCR_SD_BUS_WIDTHS_1BIT (1 << 0) /* 1bit (DAT0) */
325#define SCR_SD_BUS_WIDTHS_4BIT (1 << 2) /* 4bit (DAT0-3) */ 325#define SCR_SD_BUS_WIDTHS_4BIT (1 << 2) /* 4bit (DAT0-3) */
326#define SCR_SD_SPEC3(scr) MMC_RSP_BITS((scr), 47, 1) 326#define SCR_SD_SPEC3(scr) MMC_RSP_BITS((scr), 47, 1)
327#define SCR_EX_SECURITY(scr) MMC_RSP_BITS((scr), 43, 4) 327#define SCR_EX_SECURITY(scr) MMC_RSP_BITS((scr), 43, 4)
328#define SCR_RESERVED(scr) MMC_RSP_BITS((scr), 34, 9) 328#define SCR_RESERVED(scr) MMC_RSP_BITS((scr), 34, 9)
329#define SCR_CMD_SUPPORT_CMD23(scr) MMC_RSP_BITS((scr), 33, 1) 329#define SCR_CMD_SUPPORT_CMD23(scr) MMC_RSP_BITS((scr), 33, 1)
330#define SCR_CMD_SUPPORT_CMD20(scr) MMC_RSP_BITS((scr), 32, 1) 330#define SCR_CMD_SUPPORT_CMD20(scr) MMC_RSP_BITS((scr), 32, 1)
331#define SCR_RESERVED2(scr) MMC_RSP_BITS((scr), 0, 32) 331#define SCR_RESERVED2(scr) MMC_RSP_BITS((scr), 0, 32)
332 332
333/* Status of Switch Function */ 333/* Status of Switch Function */
334#define SFUNC_STATUS_GROUP(status, group) \ 334#define SFUNC_STATUS_GROUP(status, group) \
335 (__bitfield((uint32_t *)(status), 400 + (group - 1) * 16, 16)) 335 (__bitfield((uint32_t *)(status), 400 + (group - 1) * 16, 16))
336 336
 337#define SD_ACCESS_MODE_SDR12 0
 338#define SD_ACCESS_MODE_SDR25 1
 339#define SD_ACCESS_MODE_SDR50 2
 340#define SD_ACCESS_MODE_SDR104 3
 341#define SD_ACCESS_MODE_DDR50 4
 342
337/* This assumes the response fields are in host byte order in 32-bit units. */ 343/* This assumes the response fields are in host byte order in 32-bit units. */
338#define MMC_RSP_BITS(resp, start, len) __bitfield((resp), (start)-8, (len)) 344#define MMC_RSP_BITS(resp, start, len) __bitfield((resp), (start)-8, (len))
339static inline uint32_t 345static inline uint32_t
340__bitfield(const uint32_t *src, size_t start, size_t len) 346__bitfield(const uint32_t *src, size_t start, size_t len)
341{ 347{
342 if (start + len > 512 || len == 0 || len > 32) 348 if (start + len > 512 || len == 0 || len > 32)
343 return 0; 349 return 0;
344 350
345 src += start / 32; 351 src += start / 32;
346 start %= 32; 352 start %= 32;
347 353
348 uint32_t dst = src[0] >> start; 354 uint32_t dst = src[0] >> start;
349 355

cvs diff -r1.17 -r1.18 src/sys/dev/sdmmc/sdmmcvar.h (expand / switch to unified diff)

--- src/sys/dev/sdmmc/sdmmcvar.h 2015/08/02 21:44:36 1.17
+++ src/sys/dev/sdmmc/sdmmcvar.h 2015/08/03 10:08:51 1.18
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sdmmcvar.h,v 1.17 2015/08/02 21:44:36 jmcneill Exp $ */ 1/* $NetBSD: sdmmcvar.h,v 1.18 2015/08/03 10:08:51 jmcneill Exp $ */
2/* $OpenBSD: sdmmcvar.h,v 1.13 2009/01/09 10:55:22 jsg Exp $ */ 2/* $OpenBSD: sdmmcvar.h,v 1.13 2009/01/09 10:55:22 jsg Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org> 5 * Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 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 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
@@ -219,52 +219,59 @@ struct sdmmc_softc { @@ -219,52 +219,59 @@ struct sdmmc_softc {
219#define SMF_UHS_MODE 0x10000 /* host in UHS mode */ 219#define SMF_UHS_MODE 0x10000 /* host in UHS mode */
220 220
221 uint32_t sc_caps; /* host capability */ 221 uint32_t sc_caps; /* host capability */
222#define SMC_CAPS_AUTO_STOP 0x0001 /* send CMD12 automagically by host */ 222#define SMC_CAPS_AUTO_STOP 0x0001 /* send CMD12 automagically by host */
223#define SMC_CAPS_4BIT_MODE 0x0002 /* 4-bits data bus width */ 223#define SMC_CAPS_4BIT_MODE 0x0002 /* 4-bits data bus width */
224#define SMC_CAPS_DMA 0x0004 /* DMA transfer */ 224#define SMC_CAPS_DMA 0x0004 /* DMA transfer */
225#define SMC_CAPS_SPI_MODE 0x0008 /* SPI mode */ 225#define SMC_CAPS_SPI_MODE 0x0008 /* SPI mode */
226#define SMC_CAPS_POLL_CARD_DET 0x0010 /* Polling card detect */ 226#define SMC_CAPS_POLL_CARD_DET 0x0010 /* Polling card detect */
227#define SMC_CAPS_SINGLE_ONLY 0x0020 /* only single read/write */ 227#define SMC_CAPS_SINGLE_ONLY 0x0020 /* only single read/write */
228#define SMC_CAPS_8BIT_MODE 0x0040 /* 8-bits data bus width */ 228#define SMC_CAPS_8BIT_MODE 0x0040 /* 8-bits data bus width */
229#define SMC_CAPS_MULTI_SEG_DMA 0x0080 /* multiple segment DMA transfer */ 229#define SMC_CAPS_MULTI_SEG_DMA 0x0080 /* multiple segment DMA transfer */
230#define SMC_CAPS_SD_HIGHSPEED 0x0100 /* SD high-speed timing */ 230#define SMC_CAPS_SD_HIGHSPEED 0x0100 /* SD high-speed timing */
231#define SMC_CAPS_MMC_HIGHSPEED 0x0200 /* MMC high-speed timing */ 231#define SMC_CAPS_MMC_HIGHSPEED 0x0200 /* MMC high-speed timing */
 232#define SMC_CAPS_UHS_SDR50 0x1000 /* UHS SDR50 timing */
 233#define SMC_CAPS_UHS_SDR104 0x2000 /* UHS SDR104 timing */
 234#define SMC_CAPS_UHS_DDR50 0x4000 /* UHS DDR50 timing */
 235#define SMC_CAPS_UHS_MASK 0x7000
 236#define SMC_CAPS_MMC_HS200 0x8000 /* eMMC HS200 timing */
232 237
233 /* function */ 238 /* function */
234 int sc_function_count; /* number of I/O functions (SDIO) */ 239 int sc_function_count; /* number of I/O functions (SDIO) */
235 struct sdmmc_function *sc_card; /* selected card */ 240 struct sdmmc_function *sc_card; /* selected card */
236 struct sdmmc_function *sc_fn0; /* function 0, the card itself */ 241 struct sdmmc_function *sc_fn0; /* function 0, the card itself */
237 SIMPLEQ_HEAD(, sdmmc_function) sf_head; /* list of card functions */ 242 SIMPLEQ_HEAD(, sdmmc_function) sf_head; /* list of card functions */
238 243
239 /* task queue */ 244 /* task queue */
240 struct lwp *sc_tskq_lwp; /* asynchronous tasks */ 245 struct lwp *sc_tskq_lwp; /* asynchronous tasks */
241 TAILQ_HEAD(, sdmmc_task) sc_tskq; /* task thread work queue */ 246 TAILQ_HEAD(, sdmmc_task) sc_tskq; /* task thread work queue */
242 struct kmutex sc_tskq_mtx; 247 struct kmutex sc_tskq_mtx;
243 struct kcondvar sc_tskq_cv; 248 struct kcondvar sc_tskq_cv;
244 249
245 /* discover task */ 250 /* discover task */
246 struct sdmmc_task sc_discover_task; /* card attach/detach task */ 251 struct sdmmc_task sc_discover_task; /* card attach/detach task */
247 struct kmutex sc_discover_task_mtx; 252 struct kmutex sc_discover_task_mtx;
248 253
249 /* interrupt task */ 254 /* interrupt task */
250 struct sdmmc_task sc_intr_task; /* card interrupt task */ 255 struct sdmmc_task sc_intr_task; /* card interrupt task */
251 struct kmutex sc_intr_task_mtx; 256 struct kmutex sc_intr_task_mtx;
252 TAILQ_HEAD(, sdmmc_intr_handler) sc_intrq; /* interrupt handlers */ 257 TAILQ_HEAD(, sdmmc_intr_handler) sc_intrq; /* interrupt handlers */
253 258
254 u_int sc_clkmin; /* host min bus clock */ 259 u_int sc_clkmin; /* host min bus clock */
255 u_int sc_clkmax; /* host max bus clock */ 260 u_int sc_clkmax; /* host max bus clock */
256 u_int sc_busclk; /* host bus clock */ 261 u_int sc_busclk; /* host bus clock */
 262 bool sc_busddr; /* host bus clock is in DDR mode */
257 int sc_buswidth; /* host bus width */ 263 int sc_buswidth; /* host bus width */
 264 const char *sc_transfer_mode; /* current transfer mode */
258 265
259 callout_t sc_card_detect_ch; /* polling card insert/remove */ 266 callout_t sc_card_detect_ch; /* polling card insert/remove */
260}; 267};
261 268
262/* 269/*
263 * Attach devices at the sdmmc bus. 270 * Attach devices at the sdmmc bus.
264 */ 271 */
265struct sdmmc_attach_args { 272struct sdmmc_attach_args {
266 uint16_t manufacturer; 273 uint16_t manufacturer;
267 uint16_t product; 274 uint16_t product;
268 int interface; 275 int interface;
269 struct sdmmc_function *sf; 276 struct sdmmc_function *sf;
270}; 277};