Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/sdmmc sdhc(4), sdmmc(4): Added MMC HS DDR52 support.
details: https://anonhg.NetBSD.org/src/rev/04afe114d9a1
branches: trunk
changeset: 821799:04afe114d9a1
user: nonaka <nonaka%NetBSD.org@localhost>
date: Fri Feb 17 10:50:43 2017 +0000
description:
sdhc(4), sdmmc(4): Added MMC HS DDR52 support.
diffstat:
sys/dev/sdmmc/sdhc.c | 15 ++++++++++--
sys/dev/sdmmc/sdmmc_mem.c | 54 ++++++++++++++++++++++++++++++++++++++++++----
sys/dev/sdmmc/sdmmcchip.h | 4 +-
3 files changed, 63 insertions(+), 10 deletions(-)
diffs (161 lines):
diff -r 9c2ad85f5528 -r 04afe114d9a1 sys/dev/sdmmc/sdhc.c
--- a/sys/dev/sdmmc/sdhc.c Fri Feb 17 10:49:47 2017 +0000
+++ b/sys/dev/sdmmc/sdhc.c Fri Feb 17 10:50:43 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sdhc.c,v 1.97 2017/01/07 15:05:08 kiyohara Exp $ */
+/* $NetBSD: sdhc.c,v 1.98 2017/02/17 10:50:43 nonaka Exp $ */
/* $OpenBSD: sdhc.c,v 1.25 2009/01/13 19:44:20 grange Exp $ */
/*
@@ -23,7 +23,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.97 2017/01/07 15:05:08 kiyohara Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdhc.c,v 1.98 2017/02/17 10:50:43 nonaka Exp $");
#ifdef _KERNEL_OPT
#include "opt_sdmmc.h"
@@ -1107,7 +1107,13 @@
if (freq > 100000) {
HSET2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_SDR104);
} else if (freq > 50000) {
- HSET2(hp, SDHC_HOST_CTL2, SDHC_UHS_MODE_SELECT_SDR50);
+ if (ddr) {
+ HSET2(hp, SDHC_HOST_CTL2,
+ SDHC_UHS_MODE_SELECT_DDR50);
+ } else {
+ HSET2(hp, SDHC_HOST_CTL2,
+ SDHC_UHS_MODE_SELECT_SDR50);
+ }
} else if (freq > 25000) {
if (ddr) {
HSET2(hp, SDHC_HOST_CTL2,
@@ -1335,6 +1341,9 @@
{
struct sdhc_host *hp = (struct sdhc_host *)sch;
+ if (hp->specver < SDHC_SPEC_VERS_300)
+ return EINVAL;
+
mutex_enter(&hp->intr_lock);
switch (signal_voltage) {
case SDMMC_SIGNAL_VOLTAGE_180:
diff -r 9c2ad85f5528 -r 04afe114d9a1 sys/dev/sdmmc/sdmmc_mem.c
--- a/sys/dev/sdmmc/sdmmc_mem.c Fri Feb 17 10:49:47 2017 +0000
+++ b/sys/dev/sdmmc/sdmmc_mem.c Fri Feb 17 10:50:43 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sdmmc_mem.c,v 1.53 2017/02/17 10:48:19 nonaka Exp $ */
+/* $NetBSD: sdmmc_mem.c,v 1.54 2017/02/17 10:50:43 nonaka Exp $ */
/* $OpenBSD: sdmmc_mem.c,v 1.10 2009/01/09 10:55:22 jsg Exp $ */
/*
@@ -45,7 +45,7 @@
/* Routines for SD/MMC memory cards. */
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.53 2017/02/17 10:48:19 nonaka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.54 2017/02/17 10:50:43 nonaka Exp $");
#ifdef _KERNEL_OPT
#include "opt_sdmmc.h"
@@ -907,6 +907,7 @@
int width, value, hs_timing, bus_clock, error;
uint8_t ext_csd[512];
uint32_t sectors = 0;
+ bool ddr = false;
sc->sc_transfer_mode = NULL;
@@ -934,11 +935,15 @@
return ENOTSUP;
}
- sc->sc_transfer_mode = NULL;
if (ISSET(sc->sc_caps, SMC_CAPS_MMC_HS200) &&
ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_HS200_1_8V) {
sf->csd.tran_speed = 200000; /* 200MHz SDR */
hs_timing = EXT_CSD_HS_TIMING_HS200;
+ } else if (ISSET(sc->sc_caps, SMC_CAPS_MMC_DDR52) &&
+ ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_DDR52_1_8V) {
+ sf->csd.tran_speed = 52000; /* 52MHz */
+ hs_timing = EXT_CSD_HS_TIMING_HIGHSPEED;
+ ddr = true;
} else if (ext_csd[EXT_CSD_CARD_TYPE] & EXT_CSD_CARD_TYPE_F_52M) {
sf->csd.tran_speed = 52000; /* 52MHz */
hs_timing = EXT_CSD_HS_TIMING_HIGHSPEED;
@@ -1022,6 +1027,47 @@
}
}
+ /*
+ * HS_TIMING must be set to â??0x1â?? before setting BUS_WIDTH
+ * for dual data rate operation
+ */
+ if (ddr &&
+ hs_timing == EXT_CSD_HS_TIMING_HIGHSPEED &&
+ width > 1) {
+ error = sdmmc_mem_mmc_switch(sf,
+ EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BUS_WIDTH,
+ (width == 8) ? EXT_CSD_BUS_WIDTH_8_DDR :
+ EXT_CSD_BUS_WIDTH_4_DDR);
+ if (error) {
+ DPRINTF(("%s: can't switch to DDR"
+ " (%d bit)\n", SDMMCDEVNAME(sc), width));
+ return error;
+ }
+
+ delay(10000);
+
+ error = sdmmc_mem_signal_voltage(sc,
+ SDMMC_SIGNAL_VOLTAGE_180);
+ if (error) {
+ aprint_error_dev(sc->sc_dev,
+ "can't switch signaling voltage\n");
+ return error;
+ }
+
+ error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch,
+ sc->sc_busclk, ddr);
+ if (error) {
+ aprint_error_dev(sc->sc_dev,
+ "can't change bus clock\n");
+ return error;
+ }
+
+ delay(10000);
+
+ sc->sc_transfer_mode = "DDR52";
+ sc->sc_busddr = ddr;
+ }
+
sectors = ext_csd[EXT_CSD_SEC_COUNT + 0] << 0 |
ext_csd[EXT_CSD_SEC_COUNT + 1] << 8 |
ext_csd[EXT_CSD_SEC_COUNT + 2] << 16 |
@@ -1041,8 +1087,6 @@
"can't execute MMC tuning\n");
return error;
}
- } else {
- sc->sc_transfer_mode = NULL;
}
} else {
if (sc->sc_busclk > sf->csd.tran_speed)
diff -r 9c2ad85f5528 -r 04afe114d9a1 sys/dev/sdmmc/sdmmcchip.h
--- a/sys/dev/sdmmc/sdmmcchip.h Fri Feb 17 10:49:47 2017 +0000
+++ b/sys/dev/sdmmc/sdmmcchip.h Fri Feb 17 10:50:43 2017 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: sdmmcchip.h,v 1.7 2015/08/05 10:29:37 jmcneill Exp $ */
+/* $NetBSD: sdmmcchip.h,v 1.8 2017/02/17 10:50:43 nonaka Exp $ */
/* $OpenBSD: sdmmcchip.h,v 1.3 2007/05/31 10:09:01 uwe Exp $ */
/*
@@ -97,7 +97,7 @@
((tag)->card_intr_ack((handle)))
/* UHS functions */
#define sdmmc_chip_signal_voltage(tag, handle, voltage) \
- ((tag)->signal_voltage((handle), (voltage)))
+ ((tag)->signal_voltage ? (tag)->signal_voltage((handle), (voltage)) : EINVAL)
#define sdmmc_chip_execute_tuning(tag, handle, timing) \
((tag)->execute_tuning ? (tag)->execute_tuning((handle), (timing)) : EINVAL)
Home |
Main Index |
Thread Index |
Old Index