Module Name: src Committed By: jmcneill Date: Mon Dec 29 23:58:25 UTC 2014
Modified Files: src/sys/dev/ic: dwc_mmc.c dwc_mmc_var.h Log Message: - Simplify clock setup - Add DWC_MMC_F_FORCE_CLK flag, which forces updating clock for each command (apparently required by Rockchip) - Let bus glue limit the max clk speed used To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/sys/dev/ic/dwc_mmc.c \ 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.2 src/sys/dev/ic/dwc_mmc.c:1.3 --- src/sys/dev/ic/dwc_mmc.c:1.2 Sat Dec 27 19:18:04 2014 +++ src/sys/dev/ic/dwc_mmc.c Mon Dec 29 23:58:25 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_mmc.c,v 1.2 2014/12/27 19:18:04 jmcneill Exp $ */ +/* $NetBSD: dwc_mmc.c,v 1.3 2014/12/29 23:58:25 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.2 2014/12/27 19:18:04 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: dwc_mmc.c,v 1.3 2014/12/29 23:58:25 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -105,15 +105,19 @@ dwc_mmc_init(struct dwc_mmc_softc *sc) saa.saa_sct = &dwc_mmc_chip_functions; saa.saa_sch = sc; saa.saa_clkmin = 400; - saa.saa_clkmax = sc->sc_clock_freq / 1000; + if (sc->sc_clock_max) { + saa.saa_clkmax = sc->sc_clock_max; + } else { + saa.saa_clkmax = sc->sc_clock_freq / 1000; + } saa.saa_caps = SMC_CAPS_4BIT_MODE| SMC_CAPS_8BIT_MODE| SMC_CAPS_SD_HIGHSPEED| SMC_CAPS_MMC_HIGHSPEED| SMC_CAPS_AUTO_STOP; - saa.saa_dmat = sc->sc_dmat; #if notyet + saa.saa_dmat = sc->sc_dmat; saa.saa_caps |= SMC_CAPS_DMA| SMC_CAPS_MULTI_SEG_DMA; #endif @@ -161,25 +165,16 @@ dwc_mmc_intr(void *priv) static int dwc_mmc_set_clock(struct dwc_mmc_softc *sc, u_int freq) { - u_int pll_freq = sc->sc_clock_freq / 1000; - u_int clk_div, mmc_div; + u_int pll_freq, clk_div; - mmc_div = min(howmany(pll_freq, freq), 0x3c); - clk_div = howmany(pll_freq / mmc_div, freq); - if (clk_div > 1 && (clk_div & 1) != 0) + pll_freq = sc->sc_clock_freq / 1000; + clk_div = (pll_freq / freq) >> 1; + if (pll_freq % freq) clk_div++; -#ifdef DWC_MMC_DEBUG - device_printf(sc->sc_dev, "%s: mmc_div=%u clk_div=%u freq=%u\n", - __func__, mmc_div, clk_div, pll_freq / mmc_div / clk_div); -#endif - MMC_WRITE(sc, DWC_MMC_CLKDIV_REG, - __SHIFTIN(clk_div >> 1, DWC_MMC_CLKDIV_CLK_DIVIDER0)); - if (dwc_mmc_update_clock(sc)) - return ETIMEDOUT; - - return sc->sc_set_clkdiv(sc, mmc_div); + __SHIFTIN(clk_div, DWC_MMC_CLKDIV_CLK_DIVIDER0)); + return dwc_mmc_update_clock(sc); } static int @@ -389,6 +384,8 @@ dwc_mmc_bus_clock(sdmmc_chipset_handle_t delay(1000); + sc->sc_cur_freq = freq; + return 0; } @@ -435,6 +432,12 @@ dwc_mmc_exec_command(sdmmc_chipset_handl cmd->c_opcode, cmd->c_flags); #endif + if (sc->sc_flags & DWC_MMC_F_FORCE_CLK) { + cmd->c_error = dwc_mmc_bus_clock(sc, sc->sc_cur_freq); + if (cmd->c_error) + return; + } + if (sc->sc_flags & DWC_MMC_F_USE_HOLD_REG) cmdval |= DWC_MMC_CMD_USE_HOLD_REG; Index: src/sys/dev/ic/dwc_mmc_var.h diff -u src/sys/dev/ic/dwc_mmc_var.h:1.2 src/sys/dev/ic/dwc_mmc_var.h:1.3 --- src/sys/dev/ic/dwc_mmc_var.h:1.2 Sat Dec 27 19:18:04 2014 +++ src/sys/dev/ic/dwc_mmc_var.h Mon Dec 29 23:58:25 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: dwc_mmc_var.h,v 1.2 2014/12/27 19:18:04 jmcneill Exp $ */ +/* $NetBSD: dwc_mmc_var.h,v 1.3 2014/12/29 23:58:25 jmcneill Exp $ */ /*- * Copyright (c) 2014 Jared D. McNeill <jmcne...@invisible.ca> @@ -36,10 +36,12 @@ struct dwc_mmc_softc { bus_dma_tag_t sc_dmat; void *sc_ih; unsigned int sc_clock_freq; + unsigned int sc_bus_freq; unsigned int sc_fifo_depth; uint32_t sc_flags; #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 */ int (*sc_set_clkdiv)(struct dwc_mmc_softc *, int); device_t sc_sdmmc_dev; @@ -47,6 +49,7 @@ struct dwc_mmc_softc { kcondvar_t sc_intr_cv; uint32_t sc_intr_rint; + u_int sc_cur_freq; }; void dwc_mmc_init(struct dwc_mmc_softc *);