From nobody Tue Mar 29 22:59:55 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4A9BC1A3474E; Tue, 29 Mar 2022 22:59:56 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4KSlQ40b4Vz4Tb4; Tue, 29 Mar 2022 22:59:56 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1648594796; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=XSi+F9J8GvlNLCMWfbJy8soSB0YfeTXUTkmagcE2wGY=; b=e1sPD132EHgNXyTYxQL/L+MtkH2KR+4rkZ6c1ResUCom+9X9hQtAm2ZZ1RLk8fYGkTSOM4 9ydRZoKBwp+1b6Q81YVi1qwo1fiM1M8GcXrhP7e5JtgynDR1Qg8XoSz/ROUd9zTL7/tHKl KlQIw/GUFsZ5oNpQUdexQC23HDLisCBhtm7G6EgmzfnBSRI4/CdqaGoyMX0vjijJPX5CAs wQC88GeJvndqEHXUh8cGPqiaG8i+AfkS2Xg2VkgKxr0aZl5yqYUd/vy64SdDN/NFL4YvW/ QfJi8ifNiFckagycZuLawMZDQgan2qpvtiWrGheLztU3hyOU2g4g9CJwljBdbw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id CCA1527887; Tue, 29 Mar 2022 22:59:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 22TMxtkm049894; Tue, 29 Mar 2022 22:59:55 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 22TMxtWh049893; Tue, 29 Mar 2022 22:59:55 GMT (envelope-from git) Date: Tue, 29 Mar 2022 22:59:55 GMT Message-Id: <202203292259.22TMxtWh049893@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Marcin Wojtas Subject: git: 2f9a9149e526 - stable/13 - mmc: switch mmc_helper to device_ api List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: mw X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 2f9a9149e5262720d3d9d44fabfad542700cbae4 Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1648594796; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=XSi+F9J8GvlNLCMWfbJy8soSB0YfeTXUTkmagcE2wGY=; b=dEB+fVjHxT1joCUdHPJBxe/UErN9zp2BZdNUdemjmzKamFfLYAcV1JRHWrkzp9qMwwwwz9 2c0cwpZdBonDzh4OZwleV7Nw+ivMGCyuoevvCLYZFGNRe8fn42XQ+ID+bQMCCTnz9hQFnu KFI+BbimbjYIubvGkLQJOJC3/ZzPIveFssJmMkKg90Gz8+g03rFfWMbdz8PESHPCAz4BCe cy5hX2gH+W1GbQIHXf5xkNNJlfAvinol3bVedg7LCYSuLP1HFfaybFyO+G05b8LxDabDxJ azurCX+vdGyA5KpuAn2fQqoCeT075ePOXiu0c5MHkTNgfJOJckYMIl1nVpaCUA== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1648594796; a=rsa-sha256; cv=none; b=bOcnvuRBMe4mb3bIcMYV8aMaIzSgRrqONBNw0K34bze4+ymswRadQkNPPupEgJEke9wxm5 H9ocaGwk5WA4o5CbThGRa6GGuhDIPxUHUcvc8i/YSI0RxDan8oA2TQmJc1xQqpSXcILRNb 2uX48yIdLEm7mHpc9+Gfj0OYIjdI/ixKTiyR++cs3FGv4SXrrNA5TF9c3qxXih8nnxAhr9 +k8O484auuw0NIlQ5Pl9Be0S/vB6d12zQ4U+G9203owb30NzNTl/NoUecMtPM8HH+gVEYp SoD2S+SY+M9gLpNiuM3OMOu3aLo/Y9olsvS72TqLmq/97l+v5YmqTAI8UUL2+w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by mw: URL: https://cgit.FreeBSD.org/src/commit/?id=2f9a9149e5262720d3d9d44fabfad542700cbae4 commit 2f9a9149e5262720d3d9d44fabfad542700cbae4 Author: Bartlomiej Grzesik AuthorDate: 2021-08-02 14:27:23 +0000 Commit: Marcin Wojtas CommitDate: 2022-03-29 22:24:26 +0000 mmc: switch mmc_helper to device_ api Add generic mmc_helper which uses newly introduced device_*_property api. Thanks to this change the sd/mmc drivers will be capable of parsing both DT and ACPI description. Ensure backward compatibility for all mmc_fdt_helper users. Reviewed by: manu, mw Sponsored by: Semihalf Differential revision: https://reviews.freebsd.org/D31598 (cherry picked from commit 8a8166e5bcfb50e2b7280581b600d098fa6c9fc7) mmc: Fix regression in 8a8166e5bcfb breaking Stratix 10 boot The refactoring in 8a8166e5bcfb introduced a functional change that breaks booting on the Stratix 10, hanging when it should be attaching da0. Previously OF_getencprop was called with a pointer to host->f_max, so if it wasn't present then the existing value was left untouched, but after that commit it will instead clobber the value with 0. The dwmmc driver, as used on the Stratix 10, sets a default value before calling mmc_fdt_parse and so was broken by this functional change. It appears that aw_mmc also does the same thing, so was presumably also broken on some boards. Fixes: 8a8166e5bcfb ("mmc: switch mmc_helper to device_ api") Reviewed by: manu, mw Differential Revision: https://reviews.freebsd.org/D32209 (cherry picked from commit 4a331971d2f1083f35b87197da0614fa3e0e53cb) --- sys/arm/allwinner/aw_mmc.c | 2 +- sys/arm/broadcom/bcm2835/bcm2835_sdhci.c | 2 +- sys/conf/files | 1 + sys/dev/mmc/host/dwmmc_var.h | 2 +- sys/dev/mmc/mmc_fdt_helpers.c | 116 ++++---------------------- sys/dev/mmc/mmc_fdt_helpers.h | 42 ++-------- sys/dev/mmc/mmc_helpers.c | 134 +++++++++++++++++++++++++++++++ sys/dev/mmc/mmc_helpers.h | 70 ++++++++++++++++ sys/dev/sdhci/sdhci_xenon.c | 2 +- 9 files changed, 233 insertions(+), 138 deletions(-) diff --git a/sys/arm/allwinner/aw_mmc.c b/sys/arm/allwinner/aw_mmc.c index 9f215399e62b..3271090f19e3 100644 --- a/sys/arm/allwinner/aw_mmc.c +++ b/sys/arm/allwinner/aw_mmc.c @@ -130,7 +130,7 @@ struct aw_mmc_softc { 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 index 9d8be703983d..c8725b6067f6 100644 --- a/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c +++ b/sys/arm/broadcom/bcm2835/bcm2835_sdhci.c @@ -157,7 +157,7 @@ struct bcm_sdhci_softc { 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 index 3e727f952ac2..b9f0c225afe8 100644 --- a/sys/conf/files +++ b/sys/conf/files @@ -2492,6 +2492,7 @@ dev/mmc/mmcbr_if.m standard 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 index ef7c91fa628e..a3f20278ad2a 100644 --- a/sys/dev/mmc/host/dwmmc_var.h +++ b/sys/dev/mmc/host/dwmmc_var.h @@ -56,7 +56,7 @@ struct dwmmc_softc { 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.c b/sys/dev/mmc/mmc_fdt_helpers.c index 9ec4e1a8d213..534f21247506 100644 --- a/sys/dev/mmc/mmc_fdt_helpers.c +++ b/sys/dev/mmc/mmc_fdt_helpers.c @@ -45,105 +45,21 @@ __FBSDID("$FreeBSD$"); #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 @@ mmc_fdt_parse(device_t dev, phandle_t node, struct mmc_fdt_helper *helper, 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 @@ cd_intr(void *arg) 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 @@ cd_card_task(void *arg, int pending __unused) * 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 @@ without_interrupts: * 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 @@ wp_setup(struct mmc_fdt_helper *helper, phandle_t node) } 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 @@ mmc_fdt_gpio_setup(device_t dev, phandle_t node, struct mmc_fdt_helper *helper, } 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 @@ mmc_fdt_gpio_teardown(struct mmc_fdt_helper *helper) } 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 @@ mmc_fdt_gpio_get_present(struct mmc_fdt_helper *helper) } 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 @@ 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) +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_fdt_helpers.h index e6d6f3fbfd84..f07ca1684440 100644 --- 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_helpers.c b/sys/dev/mmc/mmc_helpers.c new file mode 100644 index 000000000000..1a90f291fc47 --- /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 + */ + if (device_get_property(dev, "max-frequency", &max_freq, + sizeof(uint64_t)) > 0) + 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/mmc/mmc_helpers.h b/sys/dev/mmc/mmc_helpers.h new file mode 100644 index 000000000000..e402e587a159 --- /dev/null +++ b/sys/dev/mmc/mmc_helpers.h @@ -0,0 +1,70 @@ +/* + * 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. + */ + +#ifndef _MMC_HELPERS_H_ +#define _MMC_HELPERS_H_ + +#include + +#ifdef EXT_RESOURCES +#include +#endif + +struct mmc_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) + +#ifdef EXT_RESOURCES + regulator_t vmmc_supply; + regulator_t vqmmc_supply; +#endif + + device_t mmc_pwrseq; +}; + +int mmc_parse(device_t dev, struct mmc_helper *helper, + struct mmc_host *host); + +#endif diff --git a/sys/dev/sdhci/sdhci_xenon.c b/sys/dev/sdhci/sdhci_xenon.c index b6f7513245eb..d88514d8fd8f 100644 --- a/sys/dev/sdhci/sdhci_xenon.c +++ b/sys/dev/sdhci/sdhci_xenon.c @@ -94,7 +94,7 @@ struct sdhci_xenon_softc { 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