diff --git a/sys/arm/allwinner/aw_mmc.c b/sys/arm/allwinner/aw_mmc.c --- a/sys/arm/allwinner/aw_mmc.c +++ b/sys/arm/allwinner/aw_mmc.c @@ -130,7 +130,7 @@ int aw_timeout; struct callout aw_timeoutc; struct mmc_host aw_host; - struct mmc_fdt_helper mmc_helper; + struct mmc_helper mmc_helper; #ifdef MMCCAM union ccb * ccb; struct mmc_sim mmc_sim; diff --git a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c --- a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c @@ -156,7 +156,7 @@ void * sc_intrhand; struct mmc_request * sc_req; struct sdhci_slot sc_slot; - struct mmc_fdt_helper sc_mmc_helper; + struct mmc_helper sc_mmc_helper; int sc_dma_ch; bus_dma_tag_t sc_dma_tag; bus_dmamap_t sc_dma_map; diff --git a/sys/conf/files b/sys/conf/files --- a/sys/conf/files +++ b/sys/conf/files @@ -2483,6 +2483,7 @@ dev/mmc/mmcbus_if.m standard dev/mmc/mmcsd.c optional mmcsd !mmccam dev/mmc/mmc_fdt_helpers.c optional ext_resources mmc fdt | ext_resources mmccam fdt +dev/mmc/mmc_helpers.c optional ext_resources mmc | ext_resources mmccam dev/mmc/mmc_pwrseq.c optional ext_resources mmc fdt | ext_resources mmccam fdt dev/mmc/mmc_pwrseq_if.m optional ext_resources mmc fdt | ext_resources mmccam fdt dev/mmcnull/mmcnull.c optional mmcnull diff --git a/sys/dev/mmc/host/dwmmc_var.h b/sys/dev/mmc/host/dwmmc_var.h --- a/sys/dev/mmc/host/dwmmc_var.h +++ b/sys/dev/mmc/host/dwmmc_var.h @@ -56,7 +56,7 @@ device_t dev; void *intr_cookie; struct mmc_host host; - struct mmc_fdt_helper mmc_helper; + struct mmc_helper mmc_helper; struct mtx sc_mtx; #ifdef MMCCAM union ccb * ccb; diff --git a/sys/dev/mmc/mmc_fdt_helpers.h b/sys/dev/mmc/mmc_fdt_helpers.h --- a/sys/dev/mmc/mmc_fdt_helpers.h +++ b/sys/dev/mmc/mmc_fdt_helpers.h @@ -37,43 +37,17 @@ #include #endif -struct mmc_fdt_helper { - device_t dev; - gpio_pin_t wp_pin; - gpio_pin_t cd_pin; - void * cd_ihandler; - struct resource * cd_ires; - int cd_irid; - void (*cd_handler)(device_t, bool); - struct timeout_task cd_delayed_task; - bool cd_disabled; - bool wp_disabled; - bool cd_present; - uint32_t props; -#define MMC_PROP_BROKEN_CD (1 << 0) -#define MMC_PROP_NON_REMOVABLE (1 << 1) -#define MMC_PROP_WP_INVERTED (1 << 2) -#define MMC_PROP_CD_INVERTED (1 << 3) -#define MMC_PROP_DISABLE_WP (1 << 4) -#define MMC_PROP_NO_SDIO (1 << 5) -#define MMC_PROP_NO_SD (1 << 6) -#define MMC_PROP_NO_MMC (1 << 7) +#include -#ifdef EXT_RESOURCES - regulator_t vmmc_supply; - regulator_t vqmmc_supply; -#endif - - device_t mmc_pwrseq; -}; +#define mmc_fdt_helper mmc_helper /* For backwards compatibility */ typedef void (*mmc_fdt_cd_handler)(device_t dev, bool present); -int mmc_fdt_parse(device_t dev, phandle_t node, struct mmc_fdt_helper *helper, struct mmc_host *host); -int mmc_fdt_gpio_setup(device_t dev, phandle_t node, struct mmc_fdt_helper *helper, mmc_fdt_cd_handler handler); -void mmc_fdt_gpio_teardown(struct mmc_fdt_helper *helper); -bool mmc_fdt_gpio_get_present(struct mmc_fdt_helper *helper); -bool mmc_fdt_gpio_get_readonly(struct mmc_fdt_helper *helper); -void mmc_fdt_set_power(struct mmc_fdt_helper *helper, enum mmc_power_mode power_mode); +int mmc_fdt_parse(device_t dev, phandle_t node, struct mmc_helper *helper, struct mmc_host *host); +int mmc_fdt_gpio_setup(device_t dev, phandle_t node, struct mmc_helper *helper, mmc_fdt_cd_handler handler); +void mmc_fdt_gpio_teardown(struct mmc_helper *helper); +bool mmc_fdt_gpio_get_present(struct mmc_helper *helper); +bool mmc_fdt_gpio_get_readonly(struct mmc_helper *helper); +void mmc_fdt_set_power(struct mmc_helper *helper, enum mmc_power_mode power_mode); #endif diff --git a/sys/dev/mmc/mmc_fdt_helpers.c b/sys/dev/mmc/mmc_fdt_helpers.c --- a/sys/dev/mmc/mmc_fdt_helpers.c +++ b/sys/dev/mmc/mmc_fdt_helpers.c @@ -45,105 +45,21 @@ #include #endif -#include "mmc_pwrseq_if.h" - -static inline void -mmc_fdt_parse_sd_speed(phandle_t node, struct mmc_host *host) -{ - bool no_18v = false; - - /* - * Parse SD supported modes - * All UHS-I modes requires 1.8V signaling. - */ - if (OF_hasprop(node, "no-1-8-v")) - no_18v = true; - if (OF_hasprop(node, "cap-sd-highspeed")) - host->caps |= MMC_CAP_HSPEED; - if (OF_hasprop(node, "sd-uhs-sdr12") && no_18v == false) - host->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_SIGNALING_180; - if (OF_hasprop(node, "sd-uhs-sdr25") && no_18v == false) - host->caps |= MMC_CAP_UHS_SDR25 | MMC_CAP_SIGNALING_180; - if (OF_hasprop(node, "sd-uhs-sdr50") && no_18v == false) - host->caps |= MMC_CAP_UHS_SDR50 | MMC_CAP_SIGNALING_180; - if (OF_hasprop(node, "sd-uhs-sdr104") && no_18v == false) - host->caps |= MMC_CAP_UHS_SDR104 | MMC_CAP_SIGNALING_180; - if (OF_hasprop(node, "sd-uhs-ddr50") && no_18v == false) - host->caps |= MMC_CAP_UHS_DDR50 | MMC_CAP_SIGNALING_180; -} +#include -static inline void -mmc_fdt_parse_mmc_speed(phandle_t node, struct mmc_host *host) -{ - - /* Parse eMMC supported modes */ - if (OF_hasprop(node, "cap-mmc-highspeed")) - host->caps |= MMC_CAP_HSPEED; - if (OF_hasprop(node, "mmc-ddr-1_2v")) - host->caps |= MMC_CAP_MMC_DDR52_120 | MMC_CAP_SIGNALING_120; - if (OF_hasprop(node, "mmc-ddr-1_8v")) - host->caps |= MMC_CAP_MMC_DDR52_180 | MMC_CAP_SIGNALING_180; - if (OF_hasprop(node, "mmc-ddr-3_3v")) - host->caps |= MMC_CAP_SIGNALING_330; - if (OF_hasprop(node, "mmc-hs200-1_2v")) - host->caps |= MMC_CAP_MMC_HS200_120 | MMC_CAP_SIGNALING_120; - if (OF_hasprop(node, "mmc-hs200-1_8v")) - host->caps |= MMC_CAP_MMC_HS200_180 | MMC_CAP_SIGNALING_180; - if (OF_hasprop(node, "mmc-hs400-1_2v")) - host->caps |= MMC_CAP_MMC_HS400_120 | MMC_CAP_SIGNALING_120; - if (OF_hasprop(node, "mmc-hs400-1_8v")) - host->caps |= MMC_CAP_MMC_HS400_180 | MMC_CAP_SIGNALING_180; - if (OF_hasprop(node, "mmc-hs400-enhanced-strobe")) - host->caps |= MMC_CAP_MMC_ENH_STROBE; -} +#include "mmc_pwrseq_if.h" int -mmc_fdt_parse(device_t dev, phandle_t node, struct mmc_fdt_helper *helper, +mmc_fdt_parse(device_t dev, phandle_t node, struct mmc_helper *helper, struct mmc_host *host) { - uint32_t bus_width; + struct mmc_helper mmc_helper; phandle_t pwrseq_xref; - if (node <= 0) - node = ofw_bus_get_node(dev); - if (node <= 0) - return (ENXIO); - - if (OF_getencprop(node, "bus-width", &bus_width, sizeof(uint32_t)) <= 0) - bus_width = 1; - - if (bus_width >= 4) - host->caps |= MMC_CAP_4_BIT_DATA; - if (bus_width >= 8) - host->caps |= MMC_CAP_8_BIT_DATA; + memset(&mmc_helper, 0, sizeof(mmc_helper)); + mmc_parse(dev, &mmc_helper, host); - /* - * max-frequency is optional, drivers should tweak this value - * if it's not present based on the clock that the mmc controller - * operates on - */ - OF_getencprop(node, "max-frequency", &host->f_max, sizeof(uint32_t)); - - if (OF_hasprop(node, "broken-cd")) - helper->props |= MMC_PROP_BROKEN_CD; - if (OF_hasprop(node, "non-removable")) - helper->props |= MMC_PROP_NON_REMOVABLE; - if (OF_hasprop(node, "wp-inverted")) - helper->props |= MMC_PROP_WP_INVERTED; - if (OF_hasprop(node, "cd-inverted")) - helper->props |= MMC_PROP_CD_INVERTED; - if (OF_hasprop(node, "no-sdio")) - helper->props |= MMC_PROP_NO_SDIO; - if (OF_hasprop(node, "no-sd")) - helper->props |= MMC_PROP_NO_SD; - if (OF_hasprop(node, "no-mmc")) - helper->props |= MMC_PROP_NO_MMC; - - if (!(helper->props & MMC_PROP_NO_SD)) - mmc_fdt_parse_sd_speed(node, host); - - if (!(helper->props & MMC_PROP_NO_MMC)) - mmc_fdt_parse_mmc_speed(node, host); + helper->props = mmc_helper.props; #ifdef EXT_RESOURCES /* @@ -200,7 +116,7 @@ static void cd_intr(void *arg) { - struct mmc_fdt_helper *helper = arg; + struct mmc_helper *helper = arg; taskqueue_enqueue_timeout(taskqueue_swi_giant, &helper->cd_delayed_task, -(hz / 2)); @@ -209,7 +125,7 @@ static void cd_card_task(void *arg, int pending __unused) { - struct mmc_fdt_helper *helper = arg; + struct mmc_helper *helper = arg; bool cd_present; cd_present = mmc_fdt_gpio_get_present(helper); @@ -228,7 +144,7 @@ * Card detect setup. */ static void -cd_setup(struct mmc_fdt_helper *helper, phandle_t node) +cd_setup(struct mmc_helper *helper, phandle_t node) { int pincaps; device_t dev; @@ -330,7 +246,7 @@ * Write protect setup. */ static void -wp_setup(struct mmc_fdt_helper *helper, phandle_t node) +wp_setup(struct mmc_helper *helper, phandle_t node) { device_t dev; @@ -352,7 +268,7 @@ } int -mmc_fdt_gpio_setup(device_t dev, phandle_t node, struct mmc_fdt_helper *helper, +mmc_fdt_gpio_setup(device_t dev, phandle_t node, struct mmc_helper *helper, mmc_fdt_cd_handler handler) { @@ -377,7 +293,7 @@ } void -mmc_fdt_gpio_teardown(struct mmc_fdt_helper *helper) +mmc_fdt_gpio_teardown(struct mmc_helper *helper) { if (helper == NULL) @@ -396,7 +312,7 @@ } bool -mmc_fdt_gpio_get_present(struct mmc_fdt_helper *helper) +mmc_fdt_gpio_get_present(struct mmc_helper *helper) { bool pinstate; @@ -411,7 +327,7 @@ } bool -mmc_fdt_gpio_get_readonly(struct mmc_fdt_helper *helper) +mmc_fdt_gpio_get_readonly(struct mmc_helper *helper) { bool pinstate; @@ -427,7 +343,7 @@ } void -mmc_fdt_set_power(struct mmc_fdt_helper *helper, enum mmc_power_mode power_mode) +mmc_fdt_set_power(struct mmc_helper *helper, enum mmc_power_mode power_mode) { int reg_status; int rv; diff --git a/sys/dev/mmc/mmc_fdt_helpers.h b/sys/dev/mmc/mmc_helpers.h copy from sys/dev/mmc/mmc_fdt_helpers.h copy to sys/dev/mmc/mmc_helpers.h --- a/sys/dev/mmc/mmc_fdt_helpers.h +++ b/sys/dev/mmc/mmc_helpers.h @@ -23,21 +23,18 @@ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * $FreeBSD$ */ -#ifndef _MMC_FDT_HELPERS_H_ -#define _MMC_FDT_HELPERS_H_ +#ifndef _MMC_HELPERS_H_ +#define _MMC_HELPERS_H_ #include -#include #ifdef EXT_RESOURCES #include #endif -struct mmc_fdt_helper { +struct mmc_helper { device_t dev; gpio_pin_t wp_pin; gpio_pin_t cd_pin; @@ -67,13 +64,7 @@ device_t mmc_pwrseq; }; -typedef void (*mmc_fdt_cd_handler)(device_t dev, bool present); - -int mmc_fdt_parse(device_t dev, phandle_t node, struct mmc_fdt_helper *helper, struct mmc_host *host); -int mmc_fdt_gpio_setup(device_t dev, phandle_t node, struct mmc_fdt_helper *helper, mmc_fdt_cd_handler handler); -void mmc_fdt_gpio_teardown(struct mmc_fdt_helper *helper); -bool mmc_fdt_gpio_get_present(struct mmc_fdt_helper *helper); -bool mmc_fdt_gpio_get_readonly(struct mmc_fdt_helper *helper); -void mmc_fdt_set_power(struct mmc_fdt_helper *helper, enum mmc_power_mode power_mode); +int mmc_parse(device_t dev, struct mmc_helper *helper, + struct mmc_host *host); #endif diff --git a/sys/dev/mmc/mmc_helpers.c b/sys/dev/mmc/mmc_helpers.c new file mode 100644 --- /dev/null +++ b/sys/dev/mmc/mmc_helpers.c @@ -0,0 +1,134 @@ +/* + * Copyright 2019 Emmanuel Vadot + * Copyright (c) 2017 Ian Lepore All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include +#include + +static inline void +mmc_parse_sd_speed(device_t dev, struct mmc_host *host) +{ + bool no_18v = false; + + /* + * Parse SD supported modes + * All UHS-I modes requires 1.8V signaling. + */ + if (device_has_property(dev, "no-1-8-v")) + no_18v = true; + if (device_has_property(dev, "cap-sd-highspeed")) + host->caps |= MMC_CAP_HSPEED; + if (device_has_property(dev, "sd-uhs-sdr12") && !no_18v) + host->caps |= MMC_CAP_UHS_SDR12 | MMC_CAP_SIGNALING_180; + if (device_has_property(dev, "sd-uhs-sdr25") && !no_18v) + host->caps |= MMC_CAP_UHS_SDR25 | MMC_CAP_SIGNALING_180; + if (device_has_property(dev, "sd-uhs-sdr50") && !no_18v) + host->caps |= MMC_CAP_UHS_SDR50 | MMC_CAP_SIGNALING_180; + if (device_has_property(dev, "sd-uhs-sdr104") && !no_18v) + host->caps |= MMC_CAP_UHS_SDR104 | MMC_CAP_SIGNALING_180; + if (device_has_property(dev, "sd-uhs-ddr50") && !no_18v) + host->caps |= MMC_CAP_UHS_DDR50 | MMC_CAP_SIGNALING_180; +} + +static inline void +mmc_parse_mmc_speed(device_t dev, struct mmc_host *host) +{ + /* Parse eMMC supported modes */ + if (device_has_property(dev, "cap-mmc-highspeed")) + host->caps |= MMC_CAP_HSPEED; + if (device_has_property(dev, "mmc-ddr-1_2v")) + host->caps |= MMC_CAP_MMC_DDR52_120 | MMC_CAP_SIGNALING_120; + if (device_has_property(dev, "mmc-ddr-1_8v")) + host->caps |= MMC_CAP_MMC_DDR52_180 | MMC_CAP_SIGNALING_180; + if (device_has_property(dev, "mmc-ddr-3_3v")) + host->caps |= MMC_CAP_SIGNALING_330; + if (device_has_property(dev, "mmc-hs200-1_2v")) + host->caps |= MMC_CAP_MMC_HS200_120 | MMC_CAP_SIGNALING_120; + if (device_has_property(dev, "mmc-hs200-1_8v")) + host->caps |= MMC_CAP_MMC_HS200_180 | MMC_CAP_SIGNALING_180; + if (device_has_property(dev, "mmc-hs400-1_2v")) + host->caps |= MMC_CAP_MMC_HS400_120 | MMC_CAP_SIGNALING_120; + if (device_has_property(dev, "mmc-hs400-1_8v")) + host->caps |= MMC_CAP_MMC_HS400_180 | MMC_CAP_SIGNALING_180; + if (device_has_property(dev, "mmc-hs400-enhanced-strobe")) + host->caps |= MMC_CAP_MMC_ENH_STROBE; +} + +int +mmc_parse(device_t dev, struct mmc_helper *helper, struct mmc_host *host) +{ + uint64_t bus_width, max_freq; + + bus_width = 0; + if (device_get_property(dev, "bus-width", &bus_width, sizeof(uint64_t)) <= 0) + bus_width = 1; + + if (bus_width >= 4) + host->caps |= MMC_CAP_4_BIT_DATA; + if (bus_width >= 8) + host->caps |= MMC_CAP_8_BIT_DATA; + + /* + * max-frequency is optional, drivers should tweak this value + * if it's not present based on the clock that the mmc controller + * operates on + */ + max_freq = 0; + device_get_property(dev, "max-frequency", &max_freq, sizeof(uint64_t)); + host->f_max = max_freq; + + if (device_has_property(dev, "broken-cd")) + helper->props |= MMC_PROP_BROKEN_CD; + if (device_has_property(dev, "non-removable")) + helper->props |= MMC_PROP_NON_REMOVABLE; + if (device_has_property(dev, "wp-inverted")) + helper->props |= MMC_PROP_WP_INVERTED; + if (device_has_property(dev, "cd-inverted")) + helper->props |= MMC_PROP_CD_INVERTED; + if (device_has_property(dev, "no-sdio")) + helper->props |= MMC_PROP_NO_SDIO; + if (device_has_property(dev, "no-sd")) + helper->props |= MMC_PROP_NO_SD; + if (device_has_property(dev, "no-mmc")) + helper->props |= MMC_PROP_NO_MMC; + + if (!(helper->props & MMC_PROP_NO_SD)) + mmc_parse_sd_speed(dev, host); + + if (!(helper->props & MMC_PROP_NO_MMC)) + mmc_parse_mmc_speed(dev, host); + + return (0); +} diff --git a/sys/dev/sdhci/sdhci_fsl_fdt.c b/sys/dev/sdhci/sdhci_fsl_fdt.c --- a/sys/dev/sdhci/sdhci_fsl_fdt.c +++ b/sys/dev/sdhci/sdhci_fsl_fdt.c @@ -106,7 +106,7 @@ bool slot_init_done; uint32_t cmd_and_mode; uint16_t sdclk_bits; - struct mmc_fdt_helper fdt_helper; + struct mmc_helper fdt_helper; uint32_t (* read)(struct sdhci_fsl_fdt_softc *, bus_size_t); void (* write)(struct sdhci_fsl_fdt_softc *, bus_size_t, uint32_t); diff --git a/sys/dev/sdhci/sdhci_xenon.c b/sys/dev/sdhci/sdhci_xenon.c --- a/sys/dev/sdhci/sdhci_xenon.c +++ b/sys/dev/sdhci/sdhci_xenon.c @@ -94,7 +94,7 @@ uint8_t zpr; /* PHY ZPR */ bool slow_mode; /* PHY slow mode */ - struct mmc_fdt_helper mmc_helper; /* MMC helper for parsing FDT */ + struct mmc_helper mmc_helper; /* MMC helper for parsing FDT */ }; static uint8_t