Module Name: src Committed By: jmcneill Date: Sat Dec 26 23:13:10 UTC 2015
Modified Files: src/sys/dev/ic: dwc_mmc.c dwc_mmc_var.h Log Message: Dump registers on timeout and allow bus glue to override card detect func To generate a diff of this commit: cvs rdiff -u -r1.7 -r1.8 src/sys/dev/ic/dwc_mmc.c cvs rdiff -u -r1.4 -r1.5 src/sys/dev/ic/dwc_mmc_var.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/ic/dwc_mmc.c diff -u src/sys/dev/ic/dwc_mmc.c:1.7 src/sys/dev/ic/dwc_mmc.c:1.8 --- src/sys/dev/ic/dwc_mmc.c:1.7 Sun Aug 9 13:01:21 2015 +++ src/sys/dev/ic/dwc_mmc.c Sat Dec 26 23:13:10 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_mmc.c,v 1.7 2015/08/09 13:01:21 jmcneill Exp $ */ +/* $NetBSD: dwc_mmc.c,v 1.8 2015/12/26 23:13:10 jmcneill Exp $ */ /*- * Copyright (c) 2014 Jared D. McNeill <jmcne...@invisible.ca> @@ -29,7 +29,7 @@ #include "opt_dwc_mmc.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: dwc_mmc.c,v 1.7 2015/08/09 13:01:21 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dwc_mmc.c,v 1.8 2015/12/26 23:13:10 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -72,7 +72,7 @@ static void dwc_mmc_print_rint(struct dw uint32_t); #endif -void dwc_mmc_dump_regs(void); +void dwc_mmc_dump_regs(int); static struct sdmmc_chip_functions dwc_mmc_chip_functions = { .host_reset = dwc_mmc_host_reset, @@ -102,6 +102,11 @@ dwc_mmc_init(struct dwc_mmc_softc *sc) mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_BIO); cv_init(&sc->sc_intr_cv, "dwcmmcirq"); +#ifdef DWC_MMC_DEBUG + const uint32_t verid = MMC_READ(sc, DWC_MMC_VERID_REG); + aprint_normal_dev(sc->sc_dev, "version 0x%04x\n", verid & 0xffff); +#endif + dwc_mmc_host_reset(sc); dwc_mmc_bus_width(sc, 1); @@ -177,6 +182,11 @@ dwc_mmc_set_clock(struct dwc_mmc_softc * if (pll_freq % freq) clk_div++; +#ifdef DWC_MMC_DEBUG + printf("%s: using clk_div %d for freq %d (act %u)\n", + __func__, clk_div, freq, pll_freq / (clk_div * 2)); +#endif + MMC_WRITE(sc, DWC_MMC_CLKDIV_REG, __SHIFTIN(clk_div, DWC_MMC_CLKDIV_CLK_DIVIDER0)); return dwc_mmc_update_clock(sc); @@ -341,8 +351,14 @@ dwc_mmc_card_detect(sdmmc_chipset_handle struct dwc_mmc_softc *sc = sch; uint32_t cdetect; - cdetect = MMC_READ(sc, DWC_MMC_CDETECT_REG); - return !(cdetect & DWC_MMC_CDETECT_CARD_DETECT_N); + if (sc->sc_flags & DWC_MMC_F_BROKEN_CD) { + return 1; + } else if (sc->sc_card_detect) { + return sc->sc_card_detect(sc); + } else { + cdetect = MMC_READ(sc, DWC_MMC_CDETECT_REG); + return !(cdetect & DWC_MMC_CDETECT_CARD_DETECT_N); + } } static int @@ -544,6 +560,11 @@ done: cmd->c_flags |= SCF_ITSDONE; mutex_exit(&sc->sc_intr_lock); + if (cmd->c_error == ETIMEDOUT && !ISSET(cmd->c_flags, SCF_TOUT_OK)) { + device_printf(sc->sc_dev, "Device timeout!\n"); + dwc_mmc_dump_regs(device_unit(sc->sc_dev)); + } + ctrl = MMC_READ(sc, DWC_MMC_CTRL_REG); ctrl |= DWC_MMC_CTRL_FIFO_RESET; MMC_WRITE(sc, DWC_MMC_CTRL_REG, ctrl); @@ -570,7 +591,7 @@ dwc_mmc_print_rint(struct dwc_mmc_softc #endif void -dwc_mmc_dump_regs(void) +dwc_mmc_dump_regs(int unit) { static const struct { const char *name; @@ -595,14 +616,15 @@ dwc_mmc_dump_regs(void) { "RST", DWC_MMC_RST_REG }, { "BACK_END_POWER", DWC_MMC_BACK_END_POWER_REG }, }; - device_t self = device_find_by_driver_unit("dwcmmc", 0); + device_t self = device_find_by_driver_unit("dwcmmc", unit); if (self == NULL) return; struct dwc_mmc_softc *sc = device_private(self); int i; - for (i = 0; i < __arraycount(regs); i++) { - device_printf(sc->sc_dev, "%s: %#x\n", regs[i].name, - MMC_READ(sc, regs[i].reg)); + for (i = 0; i < __arraycount(regs); i += 2) { + device_printf(sc->sc_dev, " %s: 0x%08x\t%s: 0x%08x\n", + regs[i+0].name, MMC_READ(sc, regs[i+0].reg), + regs[i+1].name, MMC_READ(sc, regs[i+1].reg)); } } Index: src/sys/dev/ic/dwc_mmc_var.h diff -u src/sys/dev/ic/dwc_mmc_var.h:1.4 src/sys/dev/ic/dwc_mmc_var.h:1.5 --- src/sys/dev/ic/dwc_mmc_var.h:1.4 Tue Dec 30 00:19:50 2014 +++ src/sys/dev/ic/dwc_mmc_var.h Sat Dec 26 23:13:10 2015 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_mmc_var.h,v 1.4 2014/12/30 00:19:50 jmcneill Exp $ */ +/* $NetBSD: dwc_mmc_var.h,v 1.5 2015/12/26 23:13:10 jmcneill Exp $ */ /*- * Copyright (c) 2014 Jared D. McNeill <jmcne...@invisible.ca> @@ -42,7 +42,9 @@ struct dwc_mmc_softc { #define DWC_MMC_F_USE_HOLD_REG 0x0001 /* set USE_HOLD_REG with every cmd */ #define DWC_MMC_F_PWREN_CLEAR 0x0002 /* clear POWER_ENABLE bit to enable */ #define DWC_MMC_F_FORCE_CLK 0x0004 /* update clk div with every cmd */ +#define DWC_MMC_F_BROKEN_CD 0x0008 /* card detect doesn't work */ int (*sc_set_clkdiv)(struct dwc_mmc_softc *, int); + int (*sc_card_detect)(struct dwc_mmc_softc *); device_t sc_sdmmc_dev; kmutex_t sc_intr_lock;