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