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 <[email protected]>
@@ -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 <[email protected]>
@@ -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;