Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ic Dump registers on timeout and allow bus glue to o...



details:   https://anonhg.NetBSD.org/src/rev/93f7bc1ccdb1
branches:  trunk
changeset: 812670:93f7bc1ccdb1
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Sat Dec 26 23:13:10 2015 +0000

description:
Dump registers on timeout and allow bus glue to override card detect func

diffstat:

 sys/dev/ic/dwc_mmc.c     |  42 ++++++++++++++++++++++++++++++++----------
 sys/dev/ic/dwc_mmc_var.h |   4 +++-
 2 files changed, 35 insertions(+), 11 deletions(-)

diffs (128 lines):

diff -r 32700acad5b7 -r 93f7bc1ccdb1 sys/dev/ic/dwc_mmc.c
--- a/sys/dev/ic/dwc_mmc.c      Sat Dec 26 22:57:09 2015 +0000
+++ b/sys/dev/ic/dwc_mmc.c      Sat Dec 26 23:13:10 2015 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -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 @@
                                   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 @@
        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 @@
        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 @@
        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 @@
        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 @@
 #endif
 
 void
-dwc_mmc_dump_regs(void)
+dwc_mmc_dump_regs(int unit)
 {
        static const struct {
                const char *name;
@@ -595,14 +616,15 @@
                { "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));
        }
 }
diff -r 32700acad5b7 -r 93f7bc1ccdb1 sys/dev/ic/dwc_mmc_var.h
--- a/sys/dev/ic/dwc_mmc_var.h  Sat Dec 26 22:57:09 2015 +0000
+++ b/sys/dev/ic/dwc_mmc_var.h  Sat Dec 26 23:13:10 2015 +0000
@@ -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 <jmcneill%invisible.ca@localhost>
@@ -42,7 +42,9 @@
 #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;



Home | Main Index | Thread Index | Old Index