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

This commit is contained in:
nonaka 2011-02-05 15:45:21 +00:00
parent bb3b6ddc45
commit 2431d55e10
4 changed files with 32 additions and 25 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: mvsdio.c,v 1.2 2010/10/08 11:20:22 kiyohara Exp $ */
/* $NetBSD: mvsdio.c,v 1.3 2011/02/05 15:45:21 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.2 2010/10/08 11:20:22 kiyohara Exp $");
__KERNEL_RCSID(0, "$NetBSD: mvsdio.c,v 1.3 2011/02/05 15:45:21 nonaka Exp $");
#include "opt_mvsdio.h"
@ -238,7 +238,8 @@ mvsdio_attach(device_t parent, device_t self, void *aux)
saa.saa_dmat = sc->sc_dmat;
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;
saa.saa_caps = SMC_CAPS_AUTO_STOP | SMC_CAPS_4BIT_MODE | SMC_CAPS_DMA |
SMC_CAPS_SD_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.6 2010/10/07 12:40:34 kiyohara Exp $ */
/* $NetBSD: sdmmc.c,v 1.7 2011/02/05 15:45:21 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.6 2010/10/07 12:40:34 kiyohara Exp $");
__KERNEL_RCSID(0, "$NetBSD: sdmmc.c,v 1.7 2011/02/05 15:45:21 nonaka Exp $");
#include <sys/param.h>
#include <sys/device.h>
@ -530,6 +530,7 @@ sdmmc_disable(struct sdmmc_softc *sc)
(void)sdmmc_chip_bus_width(sc->sc_sct, sc->sc_sch, 1);
(void)sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, SDMMC_SDCLK_OFF);
(void)sdmmc_chip_bus_power(sc->sc_sct, sc->sc_sch, 0);
sc->sc_busclk = sc->sc_clkmax;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: sdmmc_mem.c,v 1.14 2010/11/13 13:52:11 uebayasi Exp $ */
/* $NetBSD: sdmmc_mem.c,v 1.15 2011/02/05 15:45:21 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.14 2010/11/13 13:52:11 uebayasi Exp $");
__KERNEL_RCSID(0, "$NetBSD: sdmmc_mem.c,v 1.15 2011/02/05 15:45:21 nonaka Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@ -425,11 +425,12 @@ sdmmc_print_csd(sdmmc_response resp, struct sdmmc_csd *csd)
printf("csdver = %d\n", csd->csdver);
printf("mmcver = %d\n", csd->mmcver);
printf("capacity = %08x\n", csd->capacity);
printf("capacity = 0x%08x\n", csd->capacity);
printf("read_bl_len = %d\n", csd->read_bl_len);
printf("write_cl_len = %d\n", csd->write_bl_len);
printf("r2w_factor = %d\n", csd->r2w_factor);
printf("tran_speed = %d\n", csd->tran_speed);
printf("ccc = 0x%x\n", csd->ccc);
}
#endif
@ -574,10 +575,10 @@ sdmmc_mem_set_blocklen(struct sdmmc_softc *sc, struct sdmmc_function *sf)
static int
sdmmc_mem_sd_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
{
struct {
static const struct {
int v;
int freq;
} switch_group0_functions [] = {
} switch_group0_functions[] = {
/* Default/SDR12 */
{ MMC_OCR_1_7V_1_8V | MMC_OCR_1_8V_1_9V |
MMC_OCR_3_2V_3_3V | MMC_OCR_3_3V_3_4V, 25000 },
@ -609,6 +610,7 @@ sdmmc_mem_sd_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
if (ISSET(sc->sc_caps, SMC_CAPS_4BIT_MODE) &&
ISSET(sf->scr.bus_width, SCR_SD_BUS_WIDTHS_4BIT)) {
DPRINTF(("%s: change bus width\n", SDMMCDEVNAME(sc)));
error = sdmmc_set_bus_width(sf, 4);
if (error) {
aprint_error_dev(sc->sc_dev,
@ -616,11 +618,13 @@ sdmmc_mem_sd_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
return error;
}
sf->width = 4;
} else
} else {
sf->width = 1;
}
if (sf->scr.sd_spec >= SCR_SD_SPEC_VER_1_10 &&
ISSET(sf->csd.ccc, SD_CSD_CCC_SWITCH)) {
DPRINTF(("%s: switch func mode 0\n", SDMMCDEVNAME(sc)));
error = sdmmc_mem_sd_switch(sf, 0, 1, 0, status);
if (error) {
aprint_error_dev(sc->sc_dev,
@ -638,7 +642,10 @@ sdmmc_mem_sd_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
if (g & support_func)
best_func = i;
}
if (best_func != 0) {
if (ISSET(sc->sc_caps, SMC_CAPS_SD_HIGHSPEED) &&
best_func != 0) {
DPRINTF(("%s: switch func mode 1(func=%d)\n",
SDMMCDEVNAME(sc), best_func));
error =
sdmmc_mem_sd_switch(sf, 1, 1, best_func, status);
if (error) {
@ -653,19 +660,16 @@ sdmmc_mem_sd_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
/* Wait 400KHz x 8 clock */
delay(1);
if (sc->sc_busclk > sf->csd.tran_speed)
sc->sc_busclk = sf->csd.tran_speed;
}
}
error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch,
sc->sc_busclk);
if (error) {
aprint_error_dev(sc->sc_dev,
"can't change bus clock\n");
return error;
}
} else
if (sc->sc_busclk > sf->csd.tran_speed)
sc->sc_busclk = sf->csd.tran_speed;
/* change bus clock */
if (sc->sc_busclk > sf->csd.tran_speed)
sc->sc_busclk = sf->csd.tran_speed;
error = sdmmc_chip_bus_clock(sc->sc_sct, sc->sc_sch, sc->sc_busclk);
if (error) {
aprint_error_dev(sc->sc_dev, "can't change bus clock\n");
return error;
}
return 0;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sdmmcvar.h,v 1.8 2010/10/07 12:24:23 kiyohara Exp $ */
/* $NetBSD: sdmmcvar.h,v 1.9 2011/02/05 15:45:21 nonaka Exp $ */
/* $OpenBSD: sdmmcvar.h,v 1.13 2009/01/09 10:55:22 jsg Exp $ */
/*
@ -219,6 +219,7 @@ struct sdmmc_softc {
#define SMC_CAPS_SINGLE_ONLY 0x0020 /* only single read/write */
#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 */
/* function */
int sc_function_count; /* number of I/O functions (SDIO) */