Module Name: src Committed By: jmcneill Date: Fri Oct 3 11:23:29 UTC 2014
Modified Files: src/sys/arch/arm/allwinner: awin_mmc.c Log Message: Use SDn_CLK_REG instead of MMC_CLKCR to setup bus clock; gives a nearly 2x boost in performance in HS mode. Also, make sure to setup PLL6 before probing clocks. To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.11 src/sys/arch/arm/allwinner/awin_mmc.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/allwinner/awin_mmc.c diff -u src/sys/arch/arm/allwinner/awin_mmc.c:1.10 src/sys/arch/arm/allwinner/awin_mmc.c:1.11 --- src/sys/arch/arm/allwinner/awin_mmc.c:1.10 Thu Sep 11 08:20:52 2014 +++ src/sys/arch/arm/allwinner/awin_mmc.c Fri Oct 3 11:23:29 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: awin_mmc.c,v 1.10 2014/09/11 08:20:52 matt Exp $ */ +/* $NetBSD: awin_mmc.c,v 1.11 2014/10/03 11:23:29 jmcneill Exp $ */ /*- * Copyright (c) 2014 Jared D. McNeill <jmcne...@invisible.ca> @@ -29,7 +29,7 @@ #include "locators.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: awin_mmc.c,v 1.10 2014/09/11 08:20:52 matt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: awin_mmc.c,v 1.11 2014/10/03 11:23:29 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -87,6 +87,7 @@ struct awin_mmc_softc { device_t sc_dev; bus_space_tag_t sc_bst; bus_space_handle_t sc_bsh; + bus_space_handle_t sc_clk_bsh; bus_dma_tag_t sc_dmat; bool sc_use_dma; @@ -237,6 +238,8 @@ awin_mmc_attach(device_t parent, device_ cv_init(&sc->sc_idst_cv, "awinmmcdma"); bus_space_subregion(sc->sc_bst, aio->aio_core_bsh, loc->loc_offset, loc->loc_size, &sc->sc_bsh); + bus_space_subregion(sc->sc_bst, aio->aio_ccm_bsh, + AWIN_SD0_CLK_REG + (loc->loc_port * 8), 0, &sc->sc_clk_bsh); sc->sc_use_dma = true; prop_dictionary_get_bool(cfg, "dma", &sc->sc_use_dma); @@ -244,6 +247,7 @@ awin_mmc_attach(device_t parent, device_ aprint_naive("\n"); aprint_normal(": SD3.0 (%s)\n", sc->sc_use_dma ? "DMA" : "PIO"); + awin_pll6_enable(); awin_mmc_probe_clocks(sc, aio); if (prop_dictionary_get_cstring_nocopy(cfg, "detect-gpio", &pin_name)) { @@ -494,13 +498,26 @@ static int awin_mmc_bus_clock(sdmmc_chipset_handle_t sch, int freq) { struct awin_mmc_softc *sc = sch; - unsigned int div, freq_hz; - uint32_t clkcr; + uint32_t odly, sdly, clkcr; #ifdef AWIN_MMC_DEBUG aprint_normal_dev(sc->sc_dev, "freq = %d\n", freq); #endif + if (freq <= 400) { + odly = 0; + sdly = 7; + } else if (freq <= 25000) { + odly = 0; + sdly = 5; + } else if (freq <= 50000) { + odly = 3; + sdly = 5; + } else { + /* UHS speeds not implemented yet */ + return 1; + } + clkcr = MMC_READ(sc, AWIN_MMC_CLKCR); clkcr &= ~AWIN_MMC_CLKCR_CARDCLKON; MMC_WRITE(sc, AWIN_MMC_CLKCR, clkcr); @@ -508,15 +525,19 @@ awin_mmc_bus_clock(sdmmc_chipset_handle_ return 1; if (freq) { - freq_hz = freq * 1000; - div = (sc->sc_mod_clk + (freq_hz >> 1)) / freq_hz / 2; clkcr &= ~AWIN_MMC_CLKCR_DIV; - clkcr |= div; MMC_WRITE(sc, AWIN_MMC_CLKCR, clkcr); if (awin_mmc_update_clock(sc) != 0) return 1; + uint32_t clk = bus_space_read_4(sc->sc_bst, sc->sc_clk_bsh, 0); + clk &= ~AWIN_SD_CLK_OUTPUT_PHASE_CTR; + clk |= __SHIFTIN(odly, AWIN_SD_CLK_OUTPUT_PHASE_CTR); + clk &= ~AWIN_SD_CLK_PHASE_CTR; + clk |= __SHIFTIN(sdly, AWIN_SD_CLK_PHASE_CTR); + bus_space_write_4(sc->sc_bst, sc->sc_clk_bsh, 0, clk); + clkcr |= AWIN_MMC_CLKCR_CARDCLKON; MMC_WRITE(sc, AWIN_MMC_CLKCR, clkcr); if (awin_mmc_update_clock(sc) != 0)