- Don't switch MMC high-speed timing, if host controller isn't supported.

- Only check EXT_CSD STRUCTURE version when CSD version is 3.
- initialize width at sdmmc_function_alloc().
This commit is contained in:
nonaka 2011-02-13 06:43:51 +00:00
parent 3e0d3a901e
commit 833f453410
6 changed files with 40 additions and 30 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: mvsdio.c,v 1.3 2011/02/05 15:45:21 nonaka Exp $ */
/* $NetBSD: mvsdio.c,v 1.4 2011/02/13 06:43:51 nonaka Exp $ */
/*
* Copyright (c) 2010 KIYOHARA Takashi
* All rights reserved.
@ -25,7 +25,7 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mvsdio.c,v 1.3 2011/02/05 15:45:21 nonaka Exp $");
__KERNEL_RCSID(0, "$NetBSD: mvsdio.c,v 1.4 2011/02/13 06:43:51 nonaka Exp $");
#include "opt_mvsdio.h"
@ -239,7 +239,7 @@ mvsdio_attach(device_t parent, device_t self, void *aux)
saa.saa_clkmin = 100; /* XXXX: 100 kHz from SheevaPlug LSP */
saa.saa_clkmax = MVSDIO_MAX_CLOCK;
saa.saa_caps = SMC_CAPS_AUTO_STOP | SMC_CAPS_4BIT_MODE | SMC_CAPS_DMA |
SMC_CAPS_SD_HIGHSPEED;
SMC_CAPS_SD_HIGHSPEED | SMC_CAPS_MMC_HIGHSPEED;
#ifndef MVSDIO_CARD_DETECT
saa.saa_caps |= SMC_CAPS_POLL_CARD_DET;
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: sdmmc.c,v 1.7 2011/02/05 15:45:21 nonaka Exp $ */
/* $NetBSD: sdmmc.c,v 1.8 2011/02/13 06:43:51 nonaka Exp $ */
/* $OpenBSD: sdmmc.c,v 1.18 2009/01/09 10:58:38 jsg Exp $ */
/*
@ -50,7 +50,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.7 2011/02/05 15:45:21 nonaka Exp $");
__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.8 2011/02/13 06:43:51 nonaka Exp $");
#include <sys/param.h>
#include <sys/device.h>
@ -576,6 +576,7 @@ sdmmc_function_alloc(struct sdmmc_softc *sc)
sf->cis.manufacturer = SDMMC_VENDOR_INVALID;
sf->cis.product = SDMMC_PRODUCT_INVALID;
sf->cis.function = SDMMC_FUNCTION_INVALID;
sf->width = 1;
if (ISSET(sc->sc_flags, SMF_MEM_MODE) &&
ISSET(sc->sc_caps, SMC_CAPS_DMA) &&

View File

@ -1,4 +1,4 @@
/* $NetBSD: sdmmc_io.c,v 1.5 2010/10/07 12:40:34 kiyohara Exp $ */
/* $NetBSD: sdmmc_io.c,v 1.6 2011/02/13 06:43:52 nonaka Exp $ */
/* $OpenBSD: sdmmc_io.c,v 1.10 2007/09/17 01:33:33 krw Exp $ */
/*
@ -20,7 +20,7 @@
/* Routines for SD I/O cards. */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sdmmc_io.c,v 1.5 2010/10/07 12:40:34 kiyohara Exp $");
__KERNEL_RCSID(0, "$NetBSD: sdmmc_io.c,v 1.6 2011/02/13 06:43:52 nonaka Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@ -194,7 +194,6 @@ sdmmc_io_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
SDMMC_LOCK(sc);
if (sf->number == 0) {
sf->width = 1;
reg = sdmmc_io_read_1(sf, SD_IO_CCCR_CAPABILITY);
if (!(reg & CCCR_CAPS_LSC) || (reg & CCCR_CAPS_4BLS)) {
sdmmc_io_write_1(sf, SD_IO_CCCR_BUS_WIDTH,

View File

@ -1,4 +1,4 @@
/* $NetBSD: sdmmc_mem.c,v 1.15 2011/02/05 15:45:21 nonaka Exp $ */
/* $NetBSD: sdmmc_mem.c,v 1.16 2011/02/13 06:43:52 nonaka Exp $ */
/* $OpenBSD: sdmmc_mem.c,v 1.10 2009/01/09 10:55:22 jsg Exp $ */
/*
@ -46,7 +46,7 @@
/* Routines for SD/MMC memory cards. */
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.15 2011/02/05 15:45:21 nonaka Exp $");
__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.16 2011/02/13 06:43:52 nonaka Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@ -342,8 +342,7 @@ sdmmc_decode_csd(struct sdmmc_softc *sc, sdmmc_response resp,
csd->tran_speed = speed_exponent[e] * speed_mantissa[m] / 10;
} else {
csd->csdver = MMC_CSD_CSDVER(resp);
if (csd->csdver != MMC_CSD_CSDVER_1_0 &&
csd->csdver != MMC_CSD_CSDVER_2_0) {
if (csd->csdver == MMC_CSD_CSDVER_1_0) {
aprint_error_dev(sc->sc_dev,
"unknown MMC CSD structure version 0x%x\n",
csd->csdver);
@ -618,8 +617,6 @@ sdmmc_mem_sd_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
return error;
}
sf->width = 4;
} else {
sf->width = 1;
}
if (sf->scr.sd_spec >= SCR_SD_SPEC_VER_1_10 &&
@ -688,9 +685,11 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
aprint_error_dev(sc->sc_dev, "can't read EXT_CSD\n");
return error;
}
if (ext_csd[EXT_CSD_STRUCTURE] > EXT_CSD_STRUCTURE_VER_1_2) {
if ((sf->csd.csdver == 3) &&
(ext_csd[EXT_CSD_STRUCTURE] > EXT_CSD_STRUCTURE_VER_1_2)) {
aprint_error_dev(sc->sc_dev,
"unrecognised future version\n");
"unrecognised future version (%d)\n",
ext_csd[EXT_CSD_STRUCTURE]);
return error;
}
hs_timing = 0;
@ -702,14 +701,6 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
case EXT_CSD_CARD_TYPE_52M | EXT_CSD_CARD_TYPE_26M:
sf->csd.tran_speed = 52000; /* 52MHz */
hs_timing = 1;
error = sdmmc_mem_mmc_switch(sf, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_HS_TIMING, hs_timing);
if (error) {
aprint_error_dev(sc->sc_dev,
"can't change high speed\n");
return error;
}
break;
default:
@ -718,6 +709,20 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
ext_csd[EXT_CSD_CARD_TYPE]);
return error;
}
if (!ISSET(sc->sc_caps, SMC_CAPS_MMC_HIGHSPEED)) {
hs_timing = 0;
}
if (hs_timing) {
error = sdmmc_mem_mmc_switch(sf, EXT_CSD_CMD_SET_NORMAL,
EXT_CSD_HS_TIMING, hs_timing);
if (error) {
aprint_error_dev(sc->sc_dev,
"can't change high speed\n");
return error;
}
}
if (sc->sc_busclk > sf->csd.tran_speed)
sc->sc_busclk = sf->csd.tran_speed;
error =
@ -727,6 +732,7 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
"can't change bus clock\n");
return error;
}
if (hs_timing) {
error = sdmmc_mem_send_cxd_data(sc,
MMC_SEND_EXT_CSD, ext_csd, sizeof(ext_csd));
@ -778,7 +784,6 @@ sdmmc_mem_mmc_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
"can't change bus clock\n");
return error;
}
sf->width = 1;
}
return 0;
@ -993,6 +998,9 @@ sdmmc_mem_send_cxd_data(struct sdmmc_softc *sc, int opcode, void *data,
BUS_DMASYNC_POSTREAD);
}
memcpy(data, ptr, datalen);
#ifdef SDMMC_DEBUG
sdmmc_dump_data("CXD", data, datalen);
#endif
}
out:

View File

@ -1,4 +1,4 @@
/* $NetBSD: sdmmcreg.h,v 1.5 2010/10/07 12:24:23 kiyohara Exp $ */
/* $NetBSD: sdmmcreg.h,v 1.6 2011/02/13 06:43:52 nonaka Exp $ */
/* $OpenBSD: sdmmcreg.h,v 1.4 2009/01/09 10:55:22 jsg Exp $ */
/*
@ -162,14 +162,15 @@
/* MMC R2 response (CSD) */
#define MMC_CSD_CSDVER(resp) MMC_RSP_BITS((resp), 126, 2)
#define MMC_CSD_CSDVER_1_0 1
#define MMC_CSD_CSDVER_2_0 2
#define MMC_CSD_CSDVER_1_0 0
#define MMC_CSD_CSDVER_1_1 1
#define MMC_CSD_CSDVER_1_2 2 /* MMC 4.1 - 4.2 - 4.3 */
#define MMC_CSD_MMCVER(resp) MMC_RSP_BITS((resp), 122, 4)
#define MMC_CSD_MMCVER_1_0 0 /* MMC 1.0 - 1.2 */
#define MMC_CSD_MMCVER_1_4 1 /* MMC 1.4 */
#define MMC_CSD_MMCVER_2_0 2 /* MMC 2.0 - 2.2 */
#define MMC_CSD_MMCVER_3_1 3 /* MMC 3.1 - 3.3 */
#define MMC_CSD_MMCVER_4_0 4 /* MMC 4 */
#define MMC_CSD_MMCVER_4_0 4 /* MMC 4.1 - 4.2 - 4.3 */
#define MMC_CSD_TAAC(resp) MMC_RSP_BITS((resp), 112, 8)
#define MMC_CSD_TAAC_MANT(resp) MMC_RSP_BITS((resp), 115, 4)
#define MMC_CSD_TAAC_EXP(resp) MMC_RSP_BITS((resp), 112, 3)

View File

@ -1,4 +1,4 @@
/* $NetBSD: sdmmcvar.h,v 1.9 2011/02/05 15:45:21 nonaka Exp $ */
/* $NetBSD: sdmmcvar.h,v 1.10 2011/02/13 06:43:52 nonaka Exp $ */
/* $OpenBSD: sdmmcvar.h,v 1.13 2009/01/09 10:55:22 jsg Exp $ */
/*
@ -220,6 +220,7 @@ struct sdmmc_softc {
#define SMC_CAPS_8BIT_MODE 0x0040 /* 8-bits data bus width */
#define SMC_CAPS_MULTI_SEG_DMA 0x0080 /* multiple segment DMA transfer */
#define SMC_CAPS_SD_HIGHSPEED 0x0100 /* SD high-speed timing */
#define SMC_CAPS_MMC_HIGHSPEED 0x0200 /* MMC high-speed timing */
/* function */
int sc_function_count; /* number of I/O functions (SDIO) */