Merge tag 'mmc-v5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 5 Mar 2019 03:07:02 +0000 (19:07 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 5 Mar 2019 03:07:02 +0000 (19:07 -0800)
Pull MMC updates from Ulf Hansson:
 "MMC core:
   - Fixup max_discard/trim calculations
   - Announce SD specs greater than 4.0
   - Add discard support for SD cards
   - Don't do retries for CMD6 (SWITCH command)
   - Various cleanups and re-structuring

  MMC host:
   - cqhci:
      * Add maintainers for eMMC CQHCI driver
   - sdhci:
      * Consolidate WP GPIO code
      * Add ADMA3 DMA support for V4 enabled host
      * Fixup card detect support in pci-o2micro driver
      * Add support for CMDQ and SDMMC pads auto-calibration in tegra
        driver
      * Add DCMD support and CMDQ support, support for i.MX6ULL variant,
        fixup HS400 timing issue and add HS400_ES support for i.MX8QXP
        to esdhc-imx driver
      * Avoid CRC errors by adjusting settings to speed mode and fixup
        card initialization for high speed mode in renesas_sdhi
      * Fixup timeout settings for omap
      * Enable 8 bits bus-width support in atmel-mci
      * Convert some legacy code in jz4740 driver to use modern APIs
      * Send a CMD12 to clear DPSM at errors for STM32 sdmmc mmci
        driver"

* tag 'mmc-v5.1' of git://git.kernel.org/pub/scm/linux/kernel/git/ulfh/mmc: (69 commits)
  mmc:fix a bug when max_discard is 0
  mmc: core: Add a debug print when the card may have been replaced
  mmc: core: Add sd discard timeout
  mmc: core: Add discard support to sd
  mmc: sdhci-esdhc-imx: clear the HALT bit when enable CQE
  mmc: core: do not retry CMD6 in __mmc_switch()
  mmc: core: Convert mmc_align_data_size() into an SDIO specific function
  mmc: core: Move mmc_of_parse_voltage() to host.c
  mmc: core: Convert mmc_regulator_get_ocrmask() to static
  mmc: core: Move regulator helpers to separate file
  mmc: of_mmc_spi: Convert to mmc_of_parse_voltage()
  mmc: core: Drop retries as in-parameter to mmc_wait_for_app_cmd()
  mmc: core: Convert mmc_wait_for_app_cmd() to static
  mmc: renesas_sdhi: Change HW adjustment register according to speed mode
  mmc: mmci: Send a CMD12 to clear the DPSM at errors
  mmc: sdhci-xenon: Fixup already marked switch fall-through
  mmc: sdhci-tegra: drop ->get_ro() implementation
  mmc: sdhci-omap: drop ->get_ro() implementation
  mmc: sdhci: use WP GPIO in sdhci_check_ro()
  mmc: wmt-sdmmc: Drop unused include
  ...

59 files changed:
Documentation/devicetree/bindings/mmc/fsl-imx-esdhc.txt
Documentation/devicetree/bindings/mmc/mmc.txt
Documentation/devicetree/bindings/mmc/nvidia,tegra20-sdhci.txt
Documentation/devicetree/bindings/mmc/ti-omap.txt
MAINTAINERS
drivers/mmc/core/Makefile
drivers/mmc/core/block.c
drivers/mmc/core/core.c
drivers/mmc/core/core.h
drivers/mmc/core/host.c
drivers/mmc/core/mmc.c
drivers/mmc/core/mmc_ops.c
drivers/mmc/core/regulator.c [new file with mode: 0644]
drivers/mmc/core/sd.c
drivers/mmc/core/sd_ops.c
drivers/mmc/core/sd_ops.h
drivers/mmc/core/sdio.c
drivers/mmc/core/sdio_bus.c
drivers/mmc/core/sdio_io.c
drivers/mmc/core/sdio_ops.h
drivers/mmc/core/slot-gpio.c
drivers/mmc/host/Kconfig
drivers/mmc/host/atmel-mci.c
drivers/mmc/host/bcm2835.c
drivers/mmc/host/cb710-mmc.c
drivers/mmc/host/davinci_mmc.c
drivers/mmc/host/jz4740_mmc.c
drivers/mmc/host/mmc_spi.c
drivers/mmc/host/mmci.c
drivers/mmc/host/mmci.h
drivers/mmc/host/mxcmmc.c
drivers/mmc/host/mxs-mmc.c
drivers/mmc/host/of_mmc_spi.c
drivers/mmc/host/omap.c
drivers/mmc/host/pxamci.c
drivers/mmc/host/renesas_sdhi.h
drivers/mmc/host/renesas_sdhi_core.c
drivers/mmc/host/renesas_sdhi_internal_dmac.c
drivers/mmc/host/s3cmci.c
drivers/mmc/host/sdhci-bcm-kona.c
drivers/mmc/host/sdhci-brcmstb.c
drivers/mmc/host/sdhci-esdhc-imx.c
drivers/mmc/host/sdhci-omap.c
drivers/mmc/host/sdhci-pci-core.c
drivers/mmc/host/sdhci-pci-o2micro.c
drivers/mmc/host/sdhci-pci.h
drivers/mmc/host/sdhci-pxav2.c
drivers/mmc/host/sdhci-tegra.c
drivers/mmc/host/sdhci-xenon-phy.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/sdhci.h
drivers/mmc/host/sdhci_am654.c
drivers/mmc/host/sunxi-mmc.c
drivers/mmc/host/tmio_mmc_core.c
drivers/mmc/host/wmt-sdmmc.c
include/linux/mmc/card.h
include/linux/mmc/host.h
include/linux/mmc/sd.h
include/linux/mmc/slot-gpio.h

index 9201a7d8d7b02e9fb98281a1edcae4e9859757db..540c65ed9cba1d70a1e4456e8c444c401b1ed4b7 100644 (file)
@@ -15,6 +15,7 @@ Required properties:
               "fsl,imx6q-usdhc"
               "fsl,imx6sl-usdhc"
               "fsl,imx6sx-usdhc"
+              "fsl,imx6ull-usdhc"
               "fsl,imx7d-usdhc"
               "fsl,imx8qxp-usdhc"
 
index f5a0923b34ca1e5dfd11f3c9ba03792a6963b5c7..cdbcfd3a4ff214b7a531269fa992cdb56d4105f6 100644 (file)
@@ -62,6 +62,8 @@ Optional properties:
   be referred to mmc-pwrseq-simple.txt. But now it's reused as a tunable delay
   waiting for I/O signalling and card power supply to be stable, regardless of
   whether pwrseq-simple is used. Default to 10ms if no available.
+- supports-cqe : The presence of this property indicates that the corresponding
+  MMC host controller supports HW command queue feature.
 
 *NOTE* on CD and WP polarity. To use common for all SD/MMC host controllers line
 polarity properties, we have to fix the meaning of the "normal" and "inverted"
index 32b4b4e41923516a6f5712f349c9519557664791..2cecdc71d94c5bdd409643f0ebc6bb56b03b59ac 100644 (file)
@@ -39,12 +39,16 @@ sdhci@c8000200 {
        bus-width = <8>;
 };
 
-Optional properties for Tegra210 and Tegra186:
+Optional properties for Tegra210, Tegra186 and Tegra194:
 - pinctrl-names, pinctrl-0, pinctrl-1 : Specify pad voltage
   configurations. Valid pinctrl-names are "sdmmc-3v3" and "sdmmc-1v8"
   for controllers supporting multiple voltage levels. The order of names
   should correspond to the pin configuration states in pinctrl-0 and
   pinctrl-1.
+- pinctrl-names : "sdmmc-3v3-drv" and "sdmmc-1v8-drv" are applicable for
+  Tegra210 where pad config registers are in the pinmux register domain
+  for pull-up-strength and pull-down-strength values configuration when
+  using pads at 3V3 and 1V8 levels.
 - nvidia,only-1-8-v : The presence of this property indicates that the
   controller operates at a 1.8 V fixed I/O voltage.
 - nvidia,pad-autocal-pull-up-offset-3v3,
index 8de57996976359d96cb1b2c3fa672d8843ac83fb..02fd31cf361d6ed893ec2f9eb8368b358ab2bae1 100644 (file)
@@ -24,31 +24,3 @@ Examples:
                dmas = <&sdma 61 &sdma 62>;
                dma-names = "tx", "rx";
        };
-
-* TI MMC host controller for OMAP1 and 2420
-
-The MMC Host Controller on TI OMAP1 and 2420 family provides
-an interface for MMC, SD, and SDIO types of memory cards.
-
-This file documents differences between the core properties described
-by mmc.txt and the properties used by the omap mmc driver.
-
-Note that this driver will not work with omap2430 or later omaps,
-please see the omap hsmmc driver for the current omaps.
-
-Required properties:
-- compatible: Must be "ti,omap2420-mmc", for OMAP2420 controllers
-- ti,hwmods: For 2420, must be "msdi<n>", where n is controller
-  instance starting 1
-
-Examples:
-
-       msdi1: mmc@4809c000 {
-               compatible = "ti,omap2420-mmc";
-               ti,hwmods = "msdi1";
-               reg = <0x4809c000 0x80>;
-               interrupts = <83>;
-               dmas = <&sdma 61 &sdma 62>;
-               dma-names = "tx", "rx";
-       };
-
index f1050734d909d08abd3fd227abd7abdf12c3e29b..84857bc78a61baeeec36fbb3e894216f958e3c84 100644 (file)
@@ -13616,11 +13616,18 @@ F:    drivers/mmc/host/sdhci-brcmstb*
 SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER
 M:     Adrian Hunter <adrian.hunter@intel.com>
 L:     linux-mmc@vger.kernel.org
-T:     git git://git.infradead.org/users/ahunter/linux-sdhci.git
 S:     Maintained
 F:     drivers/mmc/host/sdhci*
 F:     include/linux/mmc/sdhci*
 
+EMMC CMDQ HOST CONTROLLER INTERFACE (CQHCI) DRIVER
+M:     Adrian Hunter <adrian.hunter@intel.com>
+M:     Ritesh Harjani <riteshh@codeaurora.org>
+M:     Asutosh Das <asutoshd@codeaurora.org>
+L:     linux-mmc@vger.kernel.org
+S:     Maintained
+F:     drivers/mmc/host/cqhci*
+
 SYNOPSYS SDHCI COMPLIANT DWC MSHC DRIVER
 M:     Prabu Thangamuthu <prabu.t@synopsys.com>
 M:     Manjunath M B <manjumb@synopsys.com>
index abba078f7f4903eac35671aa3db54823362e86fb..95ffe008ebdf8e088379ca8491078df594d0c9c2 100644 (file)
@@ -8,7 +8,7 @@ mmc_core-y                      := core.o bus.o host.o \
                                   mmc.o mmc_ops.o sd.o sd_ops.o \
                                   sdio.o sdio_ops.o sdio_bus.o \
                                   sdio_cis.o sdio_io.o sdio_irq.o \
-                                  slot-gpio.o
+                                  slot-gpio.o regulator.o
 mmc_core-$(CONFIG_OF)          += pwrseq.o
 obj-$(CONFIG_PWRSEQ_SIMPLE)    += pwrseq_simple.o
 obj-$(CONFIG_PWRSEQ_SD8787)    += pwrseq_sd8787.o
index 9ce8eb51a60fd1d377107fc8264ca16e8b32e493..2c71a434c915e66d7eecaa501d91ef328fccb3c0 100644 (file)
@@ -1124,7 +1124,7 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
 {
        struct mmc_blk_data *md = mq->blkdata;
        struct mmc_card *card = md->queue.card;
-       unsigned int from, nr, arg;
+       unsigned int from, nr;
        int err = 0, type = MMC_BLK_DISCARD;
        blk_status_t status = BLK_STS_OK;
 
@@ -1136,24 +1136,18 @@ static void mmc_blk_issue_discard_rq(struct mmc_queue *mq, struct request *req)
        from = blk_rq_pos(req);
        nr = blk_rq_sectors(req);
 
-       if (mmc_can_discard(card))
-               arg = MMC_DISCARD_ARG;
-       else if (mmc_can_trim(card))
-               arg = MMC_TRIM_ARG;
-       else
-               arg = MMC_ERASE_ARG;
        do {
                err = 0;
                if (card->quirks & MMC_QUIRK_INAND_CMD38) {
                        err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL,
                                         INAND_CMD38_ARG_EXT_CSD,
-                                        arg == MMC_TRIM_ARG ?
+                                        card->erase_arg == MMC_TRIM_ARG ?
                                         INAND_CMD38_ARG_TRIM :
                                         INAND_CMD38_ARG_ERASE,
                                         0);
                }
                if (!err)
-                       err = mmc_erase(card, from, nr, arg);
+                       err = mmc_erase(card, from, nr, card->erase_arg);
        } while (err == -EIO && !mmc_blk_reset(md, card->host, type));
        if (err)
                status = BLK_STS_IOERR;
@@ -2768,8 +2762,8 @@ static int mmc_dbg_card_status_get(void *data, u64 *val)
 
        return ret;
 }
-DEFINE_SIMPLE_ATTRIBUTE(mmc_dbg_card_status_fops, mmc_dbg_card_status_get,
-               NULL, "%08llx\n");
+DEFINE_DEBUGFS_ATTRIBUTE(mmc_dbg_card_status_fops, mmc_dbg_card_status_get,
+                        NULL, "%08llx\n");
 
 /* That is two digits * 512 + 1 for newline */
 #define EXT_CSD_STR_LEN 1025
@@ -2857,8 +2851,9 @@ static int mmc_blk_add_debugfs(struct mmc_card *card, struct mmc_blk_data *md)
 
        if (mmc_card_mmc(card) || mmc_card_sd(card)) {
                md->status_dentry =
-                       debugfs_create_file("status", S_IRUSR, root, card,
-                                           &mmc_dbg_card_status_fops);
+                       debugfs_create_file_unsafe("status", 0400, root,
+                                                  card,
+                                                  &mmc_dbg_card_status_fops);
                if (!md->status_dentry)
                        return -EIO;
        }
index b27a1e6202331f3692db7db58f20e1f5bed04f29..6db36dc870b585d6ca19ed2e1710c34b73a59986 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/leds.h>
 #include <linux/scatterlist.h>
 #include <linux/log2.h>
-#include <linux/regulator/consumer.h>
 #include <linux/pm_runtime.h>
 #include <linux/pm_wakeup.h>
 #include <linux/suspend.h>
@@ -52,6 +51,7 @@
 
 /* The max erase timeout, used when host->max_busy_timeout isn't specified */
 #define MMC_ERASE_TIMEOUT_MS   (60 * 1000) /* 60 s */
+#define SD_DISCARD_TIMEOUT_MS  (250)
 
 static const unsigned freqs[] = { 400000, 300000, 200000, 100000 };
 
@@ -758,33 +758,6 @@ void mmc_set_data_timeout(struct mmc_data *data, const struct mmc_card *card)
 }
 EXPORT_SYMBOL(mmc_set_data_timeout);
 
-/**
- *     mmc_align_data_size - pads a transfer size to a more optimal value
- *     @card: the MMC card associated with the data transfer
- *     @sz: original transfer size
- *
- *     Pads the original data size with a number of extra bytes in
- *     order to avoid controller bugs and/or performance hits
- *     (e.g. some controllers revert to PIO for certain sizes).
- *
- *     Returns the improved size, which might be unmodified.
- *
- *     Note that this function is only relevant when issuing a
- *     single scatter gather entry.
- */
-unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz)
-{
-       /*
-        * FIXME: We don't have a system for the controller to tell
-        * the core about its problems yet, so for now we just 32-bit
-        * align the size.
-        */
-       sz = ((sz + 3) / 4) * 4;
-
-       return sz;
-}
-EXPORT_SYMBOL(mmc_align_data_size);
-
 /*
  * Allow claiming an already claimed host if the context is the same or there is
  * no context but the task is the same.
@@ -1112,55 +1085,6 @@ u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max)
 
        return mask;
 }
-EXPORT_SYMBOL(mmc_vddrange_to_ocrmask);
-
-#ifdef CONFIG_OF
-
-/**
- * mmc_of_parse_voltage - return mask of supported voltages
- * @np: The device node need to be parsed.
- * @mask: mask of voltages available for MMC/SD/SDIO
- *
- * Parse the "voltage-ranges" DT property, returning zero if it is not
- * found, negative errno if the voltage-range specification is invalid,
- * or one if the voltage-range is specified and successfully parsed.
- */
-int mmc_of_parse_voltage(struct device_node *np, u32 *mask)
-{
-       const u32 *voltage_ranges;
-       int num_ranges, i;
-
-       voltage_ranges = of_get_property(np, "voltage-ranges", &num_ranges);
-       num_ranges = num_ranges / sizeof(*voltage_ranges) / 2;
-       if (!voltage_ranges) {
-               pr_debug("%pOF: voltage-ranges unspecified\n", np);
-               return 0;
-       }
-       if (!num_ranges) {
-               pr_err("%pOF: voltage-ranges empty\n", np);
-               return -EINVAL;
-       }
-
-       for (i = 0; i < num_ranges; i++) {
-               const int j = i * 2;
-               u32 ocr_mask;
-
-               ocr_mask = mmc_vddrange_to_ocrmask(
-                               be32_to_cpu(voltage_ranges[j]),
-                               be32_to_cpu(voltage_ranges[j + 1]));
-               if (!ocr_mask) {
-                       pr_err("%pOF: voltage-range #%d is invalid\n",
-                               np, i);
-                       return -EINVAL;
-               }
-               *mask |= ocr_mask;
-       }
-
-       return 1;
-}
-EXPORT_SYMBOL(mmc_of_parse_voltage);
-
-#endif /* CONFIG_OF */
 
 static int mmc_of_get_func_num(struct device_node *node)
 {
@@ -1190,246 +1114,6 @@ struct device_node *mmc_of_find_child_device(struct mmc_host *host,
        return NULL;
 }
 
-#ifdef CONFIG_REGULATOR
-
-/**
- * mmc_ocrbitnum_to_vdd - Convert a OCR bit number to its voltage
- * @vdd_bit:   OCR bit number
- * @min_uV:    minimum voltage value (mV)
- * @max_uV:    maximum voltage value (mV)
- *
- * This function returns the voltage range according to the provided OCR
- * bit number. If conversion is not possible a negative errno value returned.
- */
-static int mmc_ocrbitnum_to_vdd(int vdd_bit, int *min_uV, int *max_uV)
-{
-       int             tmp;
-
-       if (!vdd_bit)
-               return -EINVAL;
-
-       /*
-        * REVISIT mmc_vddrange_to_ocrmask() may have set some
-        * bits this regulator doesn't quite support ... don't
-        * be too picky, most cards and regulators are OK with
-        * a 0.1V range goof (it's a small error percentage).
-        */
-       tmp = vdd_bit - ilog2(MMC_VDD_165_195);
-       if (tmp == 0) {
-               *min_uV = 1650 * 1000;
-               *max_uV = 1950 * 1000;
-       } else {
-               *min_uV = 1900 * 1000 + tmp * 100 * 1000;
-               *max_uV = *min_uV + 100 * 1000;
-       }
-
-       return 0;
-}
-
-/**
- * mmc_regulator_get_ocrmask - return mask of supported voltages
- * @supply: regulator to use
- *
- * This returns either a negative errno, or a mask of voltages that
- * can be provided to MMC/SD/SDIO devices using the specified voltage
- * regulator.  This would normally be called before registering the
- * MMC host adapter.
- */
-int mmc_regulator_get_ocrmask(struct regulator *supply)
-{
-       int                     result = 0;
-       int                     count;
-       int                     i;
-       int                     vdd_uV;
-       int                     vdd_mV;
-
-       count = regulator_count_voltages(supply);
-       if (count < 0)
-               return count;
-
-       for (i = 0; i < count; i++) {
-               vdd_uV = regulator_list_voltage(supply, i);
-               if (vdd_uV <= 0)
-                       continue;
-
-               vdd_mV = vdd_uV / 1000;
-               result |= mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV);
-       }
-
-       if (!result) {
-               vdd_uV = regulator_get_voltage(supply);
-               if (vdd_uV <= 0)
-                       return vdd_uV;
-
-               vdd_mV = vdd_uV / 1000;
-               result = mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV);
-       }
-
-       return result;
-}
-EXPORT_SYMBOL_GPL(mmc_regulator_get_ocrmask);
-
-/**
- * mmc_regulator_set_ocr - set regulator to match host->ios voltage
- * @mmc: the host to regulate
- * @supply: regulator to use
- * @vdd_bit: zero for power off, else a bit number (host->ios.vdd)
- *
- * Returns zero on success, else negative errno.
- *
- * MMC host drivers may use this to enable or disable a regulator using
- * a particular supply voltage.  This would normally be called from the
- * set_ios() method.
- */
-int mmc_regulator_set_ocr(struct mmc_host *mmc,
-                       struct regulator *supply,
-                       unsigned short vdd_bit)
-{
-       int                     result = 0;
-       int                     min_uV, max_uV;
-
-       if (vdd_bit) {
-               mmc_ocrbitnum_to_vdd(vdd_bit, &min_uV, &max_uV);
-
-               result = regulator_set_voltage(supply, min_uV, max_uV);
-               if (result == 0 && !mmc->regulator_enabled) {
-                       result = regulator_enable(supply);
-                       if (!result)
-                               mmc->regulator_enabled = true;
-               }
-       } else if (mmc->regulator_enabled) {
-               result = regulator_disable(supply);
-               if (result == 0)
-                       mmc->regulator_enabled = false;
-       }
-
-       if (result)
-               dev_err(mmc_dev(mmc),
-                       "could not set regulator OCR (%d)\n", result);
-       return result;
-}
-EXPORT_SYMBOL_GPL(mmc_regulator_set_ocr);
-
-static int mmc_regulator_set_voltage_if_supported(struct regulator *regulator,
-                                                 int min_uV, int target_uV,
-                                                 int max_uV)
-{
-       /*
-        * Check if supported first to avoid errors since we may try several
-        * signal levels during power up and don't want to show errors.
-        */
-       if (!regulator_is_supported_voltage(regulator, min_uV, max_uV))
-               return -EINVAL;
-
-       return regulator_set_voltage_triplet(regulator, min_uV, target_uV,
-                                            max_uV);
-}
-
-/**
- * mmc_regulator_set_vqmmc - Set VQMMC as per the ios
- *
- * For 3.3V signaling, we try to match VQMMC to VMMC as closely as possible.
- * That will match the behavior of old boards where VQMMC and VMMC were supplied
- * by the same supply.  The Bus Operating conditions for 3.3V signaling in the
- * SD card spec also define VQMMC in terms of VMMC.
- * If this is not possible we'll try the full 2.7-3.6V of the spec.
- *
- * For 1.2V and 1.8V signaling we'll try to get as close as possible to the
- * requested voltage.  This is definitely a good idea for UHS where there's a
- * separate regulator on the card that's trying to make 1.8V and it's best if
- * we match.
- *
- * This function is expected to be used by a controller's
- * start_signal_voltage_switch() function.
- */
-int mmc_regulator_set_vqmmc(struct mmc_host *mmc, struct mmc_ios *ios)
-{
-       struct device *dev = mmc_dev(mmc);
-       int ret, volt, min_uV, max_uV;
-
-       /* If no vqmmc supply then we can't change the voltage */
-       if (IS_ERR(mmc->supply.vqmmc))
-               return -EINVAL;
-
-       switch (ios->signal_voltage) {
-       case MMC_SIGNAL_VOLTAGE_120:
-               return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
-                                               1100000, 1200000, 1300000);
-       case MMC_SIGNAL_VOLTAGE_180:
-               return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
-                                               1700000, 1800000, 1950000);
-       case MMC_SIGNAL_VOLTAGE_330:
-               ret = mmc_ocrbitnum_to_vdd(mmc->ios.vdd, &volt, &max_uV);
-               if (ret < 0)
-                       return ret;
-
-               dev_dbg(dev, "%s: found vmmc voltage range of %d-%duV\n",
-                       __func__, volt, max_uV);
-
-               min_uV = max(volt - 300000, 2700000);
-               max_uV = min(max_uV + 200000, 3600000);
-
-               /*
-                * Due to a limitation in the current implementation of
-                * regulator_set_voltage_triplet() which is taking the lowest
-                * voltage possible if below the target, search for a suitable
-                * voltage in two steps and try to stay close to vmmc
-                * with a 0.3V tolerance at first.
-                */
-               if (!mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
-                                               min_uV, volt, max_uV))
-                       return 0;
-
-               return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
-                                               2700000, volt, 3600000);
-       default:
-               return -EINVAL;
-       }
-}
-EXPORT_SYMBOL_GPL(mmc_regulator_set_vqmmc);
-
-#endif /* CONFIG_REGULATOR */
-
-/**
- * mmc_regulator_get_supply - try to get VMMC and VQMMC regulators for a host
- * @mmc: the host to regulate
- *
- * Returns 0 or errno. errno should be handled, it is either a critical error
- * or -EPROBE_DEFER. 0 means no critical error but it does not mean all
- * regulators have been found because they all are optional. If you require
- * certain regulators, you need to check separately in your driver if they got
- * populated after calling this function.
- */
-int mmc_regulator_get_supply(struct mmc_host *mmc)
-{
-       struct device *dev = mmc_dev(mmc);
-       int ret;
-
-       mmc->supply.vmmc = devm_regulator_get_optional(dev, "vmmc");
-       mmc->supply.vqmmc = devm_regulator_get_optional(dev, "vqmmc");
-
-       if (IS_ERR(mmc->supply.vmmc)) {
-               if (PTR_ERR(mmc->supply.vmmc) == -EPROBE_DEFER)
-                       return -EPROBE_DEFER;
-               dev_dbg(dev, "No vmmc regulator found\n");
-       } else {
-               ret = mmc_regulator_get_ocrmask(mmc->supply.vmmc);
-               if (ret > 0)
-                       mmc->ocr_avail = ret;
-               else
-                       dev_warn(dev, "Failed getting OCR mask: %d\n", ret);
-       }
-
-       if (IS_ERR(mmc->supply.vqmmc)) {
-               if (PTR_ERR(mmc->supply.vqmmc) == -EPROBE_DEFER)
-                       return -EPROBE_DEFER;
-               dev_dbg(dev, "No vqmmc regulator found\n");
-       }
-
-       return 0;
-}
-EXPORT_SYMBOL_GPL(mmc_regulator_get_supply);
-
 /*
  * Mask off any voltages we don't support and select
  * the lowest voltage
@@ -1936,6 +1620,12 @@ static unsigned int mmc_sd_erase_timeout(struct mmc_card *card,
 {
        unsigned int erase_timeout;
 
+       /* for DISCARD none of the below calculation applies.
+        * the busy timeout is 250msec per discard command.
+        */
+       if (arg == SD_DISCARD_ARG)
+               return SD_DISCARD_TIMEOUT_MS;
+
        if (card->ssr.erase_timeout) {
                /* Erase timeout specified in SD Status Register (SSR) */
                erase_timeout = card->ssr.erase_timeout * qty +
@@ -2164,7 +1854,7 @@ static unsigned int mmc_align_erase_size(struct mmc_card *card,
  * @card: card to erase
  * @from: first sector to erase
  * @nr: number of sectors to erase
- * @arg: erase command argument (SD supports only %MMC_ERASE_ARG)
+ * @arg: erase command argument
  *
  * Caller must claim host before calling this function.
  */
@@ -2181,14 +1871,14 @@ int mmc_erase(struct mmc_card *card, unsigned int from, unsigned int nr,
        if (!card->erase_size)
                return -EOPNOTSUPP;
 
-       if (mmc_card_sd(card) && arg != MMC_ERASE_ARG)
+       if (mmc_card_sd(card) && arg != SD_ERASE_ARG && arg != SD_DISCARD_ARG)
                return -EOPNOTSUPP;
 
-       if ((arg & MMC_SECURE_ARGS) &&
+       if (mmc_card_mmc(card) && (arg & MMC_SECURE_ARGS) &&
            !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_ER_EN))
                return -EOPNOTSUPP;
 
-       if ((arg & MMC_TRIM_ARGS) &&
+       if (mmc_card_mmc(card) && (arg & MMC_TRIM_ARGS) &&
            !(card->ext_csd.sec_feature_support & EXT_CSD_SEC_GB_CL_EN))
                return -EOPNOTSUPP;
 
@@ -2381,9 +2071,9 @@ unsigned int mmc_calc_max_discard(struct mmc_card *card)
                return card->pref_erase;
 
        max_discard = mmc_do_calc_max_discard(card, MMC_ERASE_ARG);
-       if (max_discard && mmc_can_trim(card)) {
+       if (mmc_can_trim(card)) {
                max_trim = mmc_do_calc_max_discard(card, MMC_TRIM_ARG);
-               if (max_trim < max_discard)
+               if (max_trim < max_discard || max_discard == 0)
                        max_discard = max_trim;
        } else if (max_discard < card->erase_size) {
                max_discard = 0;
index 8fb6bc37f8081638f453386c282d55ae17de4c43..b5083b13d5944e0f2079bbde23d410c02b2ad37c 100644 (file)
@@ -59,6 +59,7 @@ void mmc_power_up(struct mmc_host *host, u32 ocr);
 void mmc_power_off(struct mmc_host *host);
 void mmc_power_cycle(struct mmc_host *host, u32 ocr);
 void mmc_set_initial_state(struct mmc_host *host);
+u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max);
 
 static inline void mmc_delay(unsigned int ms)
 {
index cf58ccaf22d50f742e72b76876ad58eb0f966233..3a4402a79904065a4f4be8c31ee918dc2c143a86 100644 (file)
@@ -194,7 +194,7 @@ int mmc_of_parse(struct mmc_host *host)
        switch (bus_width) {
        case 8:
                host->caps |= MMC_CAP_8_BIT_DATA;
-               /* Hosts capable of 8-bit transfers can also do 4 bits */
+               /* fall through - Hosts capable of 8-bit can also do 4 bits */
        case 4:
                host->caps |= MMC_CAP_4_BIT_DATA;
                break;
@@ -260,7 +260,7 @@ int mmc_of_parse(struct mmc_host *host)
        /* Parse Write Protection */
        ro_cap_invert = device_property_read_bool(dev, "wp-inverted");
 
-       ret = mmc_gpiod_request_ro(host, "wp", 0, false, 0, &ro_gpio_invert);
+       ret = mmc_gpiod_request_ro(host, "wp", 0, 0, &ro_gpio_invert);
        if (!ret)
                dev_info(host->parent, "Got WP GPIO\n");
        else if (ret != -ENOENT && ret != -ENOSYS)
@@ -348,6 +348,50 @@ int mmc_of_parse(struct mmc_host *host)
 
 EXPORT_SYMBOL(mmc_of_parse);
 
+/**
+ * mmc_of_parse_voltage - return mask of supported voltages
+ * @np: The device node need to be parsed.
+ * @mask: mask of voltages available for MMC/SD/SDIO
+ *
+ * Parse the "voltage-ranges" DT property, returning zero if it is not
+ * found, negative errno if the voltage-range specification is invalid,
+ * or one if the voltage-range is specified and successfully parsed.
+ */
+int mmc_of_parse_voltage(struct device_node *np, u32 *mask)
+{
+       const u32 *voltage_ranges;
+       int num_ranges, i;
+
+       voltage_ranges = of_get_property(np, "voltage-ranges", &num_ranges);
+       num_ranges = num_ranges / sizeof(*voltage_ranges) / 2;
+       if (!voltage_ranges) {
+               pr_debug("%pOF: voltage-ranges unspecified\n", np);
+               return 0;
+       }
+       if (!num_ranges) {
+               pr_err("%pOF: voltage-ranges empty\n", np);
+               return -EINVAL;
+       }
+
+       for (i = 0; i < num_ranges; i++) {
+               const int j = i * 2;
+               u32 ocr_mask;
+
+               ocr_mask = mmc_vddrange_to_ocrmask(
+                               be32_to_cpu(voltage_ranges[j]),
+                               be32_to_cpu(voltage_ranges[j + 1]));
+               if (!ocr_mask) {
+                       pr_err("%pOF: voltage-range #%d is invalid\n",
+                               np, i);
+                       return -EINVAL;
+               }
+               *mask |= ocr_mask;
+       }
+
+       return 1;
+}
+EXPORT_SYMBOL(mmc_of_parse_voltage);
+
 /**
  *     mmc_alloc_host - initialise the per-host structure.
  *     @extra: sizeof private data structure
index da892a599524b9727a3ac1d679333ac36d33c492..3e786ba204c3fd63a4f6b10b9f7acefb41276a88 100644 (file)
@@ -1594,6 +1594,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
 
        if (oldcard) {
                if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) {
+                       pr_debug("%s: Perhaps the card was replaced\n",
+                               mmc_hostname(host));
                        err = -ENOENT;
                        goto err;
                }
@@ -1743,6 +1745,14 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr,
                        card->ext_csd.power_off_notification = EXT_CSD_POWER_ON;
        }
 
+       /* set erase_arg */
+       if (mmc_can_discard(card))
+               card->erase_arg = MMC_DISCARD_ARG;
+       else if (mmc_can_trim(card))
+               card->erase_arg = MMC_TRIM_ARG;
+       else
+               card->erase_arg = MMC_ERASE_ARG;
+
        /*
         * Select timing interface
         */
index 9054329fe903e83e95699d8702b91d09eaeceacf..c5208fb312ae825c78954ebca912c32ddbe81e79 100644 (file)
@@ -562,7 +562,7 @@ int __mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
        if (index == EXT_CSD_SANITIZE_START)
                cmd.sanitize_busy = true;
 
-       err = mmc_wait_for_cmd(host, &cmd, MMC_CMD_RETRIES);
+       err = mmc_wait_for_cmd(host, &cmd, 0);
        if (err)
                goto out;
 
diff --git a/drivers/mmc/core/regulator.c b/drivers/mmc/core/regulator.c
new file mode 100644 (file)
index 0000000..b6febbc
--- /dev/null
@@ -0,0 +1,260 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Helper functions for MMC regulators.
+ */
+
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/log2.h>
+#include <linux/regulator/consumer.h>
+
+#include <linux/mmc/host.h>
+
+#include "core.h"
+#include "host.h"
+
+#ifdef CONFIG_REGULATOR
+
+/**
+ * mmc_ocrbitnum_to_vdd - Convert a OCR bit number to its voltage
+ * @vdd_bit:   OCR bit number
+ * @min_uV:    minimum voltage value (mV)
+ * @max_uV:    maximum voltage value (mV)
+ *
+ * This function returns the voltage range according to the provided OCR
+ * bit number. If conversion is not possible a negative errno value returned.
+ */
+static int mmc_ocrbitnum_to_vdd(int vdd_bit, int *min_uV, int *max_uV)
+{
+       int             tmp;
+
+       if (!vdd_bit)
+               return -EINVAL;
+
+       /*
+        * REVISIT mmc_vddrange_to_ocrmask() may have set some
+        * bits this regulator doesn't quite support ... don't
+        * be too picky, most cards and regulators are OK with
+        * a 0.1V range goof (it's a small error percentage).
+        */
+       tmp = vdd_bit - ilog2(MMC_VDD_165_195);
+       if (tmp == 0) {
+               *min_uV = 1650 * 1000;
+               *max_uV = 1950 * 1000;
+       } else {
+               *min_uV = 1900 * 1000 + tmp * 100 * 1000;
+               *max_uV = *min_uV + 100 * 1000;
+       }
+
+       return 0;
+}
+
+/**
+ * mmc_regulator_get_ocrmask - return mask of supported voltages
+ * @supply: regulator to use
+ *
+ * This returns either a negative errno, or a mask of voltages that
+ * can be provided to MMC/SD/SDIO devices using the specified voltage
+ * regulator.  This would normally be called before registering the
+ * MMC host adapter.
+ */
+static int mmc_regulator_get_ocrmask(struct regulator *supply)
+{
+       int                     result = 0;
+       int                     count;
+       int                     i;
+       int                     vdd_uV;
+       int                     vdd_mV;
+
+       count = regulator_count_voltages(supply);
+       if (count < 0)
+               return count;
+
+       for (i = 0; i < count; i++) {
+               vdd_uV = regulator_list_voltage(supply, i);
+               if (vdd_uV <= 0)
+                       continue;
+
+               vdd_mV = vdd_uV / 1000;
+               result |= mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV);
+       }
+
+       if (!result) {
+               vdd_uV = regulator_get_voltage(supply);
+               if (vdd_uV <= 0)
+                       return vdd_uV;
+
+               vdd_mV = vdd_uV / 1000;
+               result = mmc_vddrange_to_ocrmask(vdd_mV, vdd_mV);
+       }
+
+       return result;
+}
+
+/**
+ * mmc_regulator_set_ocr - set regulator to match host->ios voltage
+ * @mmc: the host to regulate
+ * @supply: regulator to use
+ * @vdd_bit: zero for power off, else a bit number (host->ios.vdd)
+ *
+ * Returns zero on success, else negative errno.
+ *
+ * MMC host drivers may use this to enable or disable a regulator using
+ * a particular supply voltage.  This would normally be called from the
+ * set_ios() method.
+ */
+int mmc_regulator_set_ocr(struct mmc_host *mmc,
+                       struct regulator *supply,
+                       unsigned short vdd_bit)
+{
+       int                     result = 0;
+       int                     min_uV, max_uV;
+
+       if (vdd_bit) {
+               mmc_ocrbitnum_to_vdd(vdd_bit, &min_uV, &max_uV);
+
+               result = regulator_set_voltage(supply, min_uV, max_uV);
+               if (result == 0 && !mmc->regulator_enabled) {
+                       result = regulator_enable(supply);
+                       if (!result)
+                               mmc->regulator_enabled = true;
+               }
+       } else if (mmc->regulator_enabled) {
+               result = regulator_disable(supply);
+               if (result == 0)
+                       mmc->regulator_enabled = false;
+       }
+
+       if (result)
+               dev_err(mmc_dev(mmc),
+                       "could not set regulator OCR (%d)\n", result);
+       return result;
+}
+EXPORT_SYMBOL_GPL(mmc_regulator_set_ocr);
+
+static int mmc_regulator_set_voltage_if_supported(struct regulator *regulator,
+                                                 int min_uV, int target_uV,
+                                                 int max_uV)
+{
+       /*
+        * Check if supported first to avoid errors since we may try several
+        * signal levels during power up and don't want to show errors.
+        */
+       if (!regulator_is_supported_voltage(regulator, min_uV, max_uV))
+               return -EINVAL;
+
+       return regulator_set_voltage_triplet(regulator, min_uV, target_uV,
+                                            max_uV);
+}
+
+/**
+ * mmc_regulator_set_vqmmc - Set VQMMC as per the ios
+ *
+ * For 3.3V signaling, we try to match VQMMC to VMMC as closely as possible.
+ * That will match the behavior of old boards where VQMMC and VMMC were supplied
+ * by the same supply.  The Bus Operating conditions for 3.3V signaling in the
+ * SD card spec also define VQMMC in terms of VMMC.
+ * If this is not possible we'll try the full 2.7-3.6V of the spec.
+ *
+ * For 1.2V and 1.8V signaling we'll try to get as close as possible to the
+ * requested voltage.  This is definitely a good idea for UHS where there's a
+ * separate regulator on the card that's trying to make 1.8V and it's best if
+ * we match.
+ *
+ * This function is expected to be used by a controller's
+ * start_signal_voltage_switch() function.
+ */
+int mmc_regulator_set_vqmmc(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+       struct device *dev = mmc_dev(mmc);
+       int ret, volt, min_uV, max_uV;
+
+       /* If no vqmmc supply then we can't change the voltage */
+       if (IS_ERR(mmc->supply.vqmmc))
+               return -EINVAL;
+
+       switch (ios->signal_voltage) {
+       case MMC_SIGNAL_VOLTAGE_120:
+               return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
+                                               1100000, 1200000, 1300000);
+       case MMC_SIGNAL_VOLTAGE_180:
+               return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
+                                               1700000, 1800000, 1950000);
+       case MMC_SIGNAL_VOLTAGE_330:
+               ret = mmc_ocrbitnum_to_vdd(mmc->ios.vdd, &volt, &max_uV);
+               if (ret < 0)
+                       return ret;
+
+               dev_dbg(dev, "%s: found vmmc voltage range of %d-%duV\n",
+                       __func__, volt, max_uV);
+
+               min_uV = max(volt - 300000, 2700000);
+               max_uV = min(max_uV + 200000, 3600000);
+
+               /*
+                * Due to a limitation in the current implementation of
+                * regulator_set_voltage_triplet() which is taking the lowest
+                * voltage possible if below the target, search for a suitable
+                * voltage in two steps and try to stay close to vmmc
+                * with a 0.3V tolerance at first.
+                */
+               if (!mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
+                                               min_uV, volt, max_uV))
+                       return 0;
+
+               return mmc_regulator_set_voltage_if_supported(mmc->supply.vqmmc,
+                                               2700000, volt, 3600000);
+       default:
+               return -EINVAL;
+       }
+}
+EXPORT_SYMBOL_GPL(mmc_regulator_set_vqmmc);
+
+#else
+
+static inline int mmc_regulator_get_ocrmask(struct regulator *supply)
+{
+       return 0;
+}
+
+#endif /* CONFIG_REGULATOR */
+
+/**
+ * mmc_regulator_get_supply - try to get VMMC and VQMMC regulators for a host
+ * @mmc: the host to regulate
+ *
+ * Returns 0 or errno. errno should be handled, it is either a critical error
+ * or -EPROBE_DEFER. 0 means no critical error but it does not mean all
+ * regulators have been found because they all are optional. If you require
+ * certain regulators, you need to check separately in your driver if they got
+ * populated after calling this function.
+ */
+int mmc_regulator_get_supply(struct mmc_host *mmc)
+{
+       struct device *dev = mmc_dev(mmc);
+       int ret;
+
+       mmc->supply.vmmc = devm_regulator_get_optional(dev, "vmmc");
+       mmc->supply.vqmmc = devm_regulator_get_optional(dev, "vqmmc");
+
+       if (IS_ERR(mmc->supply.vmmc)) {
+               if (PTR_ERR(mmc->supply.vmmc) == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+               dev_dbg(dev, "No vmmc regulator found\n");
+       } else {
+               ret = mmc_regulator_get_ocrmask(mmc->supply.vmmc);
+               if (ret > 0)
+                       mmc->ocr_avail = ret;
+               else
+                       dev_warn(dev, "Failed getting OCR mask: %d\n", ret);
+       }
+
+       if (IS_ERR(mmc->supply.vqmmc)) {
+               if (PTR_ERR(mmc->supply.vqmmc) == -EPROBE_DEFER)
+                       return -EPROBE_DEFER;
+               dev_dbg(dev, "No vqmmc regulator found\n");
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(mmc_regulator_get_supply);
index d0d9f90e7cdfb7453adc31f6cb5cd458989e8ceb..265e1aeeb9d889c0cdfb33c0524d8504c085c2ef 100644 (file)
@@ -209,6 +209,11 @@ static int mmc_decode_scr(struct mmc_card *card)
                /* Check if Physical Layer Spec v3.0 is supported */
                scr->sda_spec3 = UNSTUFF_BITS(resp, 47, 1);
 
+       if (scr->sda_spec3) {
+               scr->sda_spec4 = UNSTUFF_BITS(resp, 42, 1);
+               scr->sda_specx = UNSTUFF_BITS(resp, 38, 4);
+       }
+
        if (UNSTUFF_BITS(resp, 55, 1))
                card->erased_byte = 0xFF;
        else
@@ -226,6 +231,8 @@ static int mmc_read_ssr(struct mmc_card *card)
 {
        unsigned int au, es, et, eo;
        __be32 *raw_ssr;
+       u32 resp[4] = {};
+       u8 discard_support;
        int i;
 
        if (!(card->csd.cmdclass & CCC_APP_SPEC)) {
@@ -271,6 +278,14 @@ static int mmc_read_ssr(struct mmc_card *card)
                }
        }
 
+       /*
+        * starting SD5.1 discard is supported if DISCARD_SUPPORT (b313) is set
+        */
+       resp[3] = card->raw_ssr[6];
+       discard_support = UNSTUFF_BITS(resp, 313 - 288, 1);
+       card->erase_arg = (card->scr.sda_specx && discard_support) ?
+                           SD_DISCARD_ARG : SD_ERASE_ARG;
+
        return 0;
 }
 
@@ -936,8 +951,11 @@ retry:
                return err;
 
        if (oldcard) {
-               if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0)
+               if (memcmp(cid, oldcard->raw_cid, sizeof(cid)) != 0) {
+                       pr_debug("%s: Perhaps the card was replaced\n",
+                               mmc_hostname(host));
                        return -ENOENT;
+               }
 
                card = oldcard;
        } else {
index 47056d8d1bac370886eb8daf285b3656c570bb16..0bb0b841901631cc9b45b7f1e146484463236f83 100644 (file)
@@ -52,36 +52,17 @@ int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card)
 }
 EXPORT_SYMBOL_GPL(mmc_app_cmd);
 
-/**
- *     mmc_wait_for_app_cmd - start an application command and wait for
-                              completion
- *     @host: MMC host to start command
- *     @card: Card to send MMC_APP_CMD to
- *     @cmd: MMC command to start
- *     @retries: maximum number of retries
- *
- *     Sends a MMC_APP_CMD, checks the card response, sends the command
- *     in the parameter and waits for it to complete. Return any error
- *     that occurred while the command was executing.  Do not attempt to
- *     parse the response.
- */
-int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card,
-       struct mmc_command *cmd, int retries)
+static int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card,
+                               struct mmc_command *cmd)
 {
        struct mmc_request mrq = {};
-
-       int i, err;
-
-       if (retries < 0)
-               retries = MMC_CMD_RETRIES;
-
-       err = -EIO;
+       int i, err = -EIO;
 
        /*
         * We have to resend MMC_APP_CMD for each attempt so
         * we cannot use the retries field in mmc_command.
         */
-       for (i = 0;i <= retries;i++) {
+       for (i = 0; i <= MMC_CMD_RETRIES; i++) {
                err = mmc_app_cmd(host, card);
                if (err) {
                        /* no point in retrying; no APP commands allowed */
@@ -116,8 +97,6 @@ int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card,
        return err;
 }
 
-EXPORT_SYMBOL(mmc_wait_for_app_cmd);
-
 int mmc_app_set_bus_width(struct mmc_card *card, int width)
 {
        struct mmc_command cmd = {};
@@ -136,7 +115,7 @@ int mmc_app_set_bus_width(struct mmc_card *card, int width)
                return -EINVAL;
        }
 
-       return mmc_wait_for_app_cmd(card->host, card, &cmd, MMC_CMD_RETRIES);
+       return mmc_wait_for_app_cmd(card->host, card, &cmd);
 }
 
 int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
@@ -152,7 +131,7 @@ int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr)
        cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R3 | MMC_CMD_BCR;
 
        for (i = 100; i; i--) {
-               err = mmc_wait_for_app_cmd(host, NULL, &cmd, MMC_CMD_RETRIES);
+               err = mmc_wait_for_app_cmd(host, NULL, &cmd);
                if (err)
                        break;
 
index 0e6c3d51e66dedc7ca2fe07a65f346505565dc5d..ffaed5cacc88a2df9c58f9648090dab37a946cf5 100644 (file)
@@ -16,7 +16,6 @@
 
 struct mmc_card;
 struct mmc_host;
-struct mmc_command;
 
 int mmc_app_set_bus_width(struct mmc_card *card, int width);
 int mmc_send_app_op_cond(struct mmc_host *host, u32 ocr, u32 *rocr);
@@ -27,8 +26,6 @@ int mmc_sd_switch(struct mmc_card *card, int mode, int group,
        u8 value, u8 *resp);
 int mmc_app_sd_status(struct mmc_card *card, void *ssr);
 int mmc_app_cmd(struct mmc_host *host, struct mmc_card *card);
-int mmc_wait_for_app_cmd(struct mmc_host *host, struct mmc_card *card,
-       struct mmc_command *cmd, int retries);
 
 #endif
 
index d8e17ea6126de8339beddd776702e5aa3c0691d5..6718fc8bb40fdccb197b057440c37f6981161dea 100644 (file)
@@ -617,6 +617,8 @@ try_again:
                if (oldcard && (oldcard->type != MMC_TYPE_SD_COMBO ||
                    memcmp(card->raw_cid, oldcard->raw_cid, sizeof(card->raw_cid)) != 0)) {
                        mmc_remove_card(card);
+                       pr_debug("%s: Perhaps the card was replaced\n",
+                               mmc_hostname(host));
                        return -ENOENT;
                }
        } else {
@@ -624,6 +626,8 @@ try_again:
 
                if (oldcard && oldcard->type != MMC_TYPE_SDIO) {
                        mmc_remove_card(card);
+                       pr_debug("%s: Perhaps the card was replaced\n",
+                               mmc_hostname(host));
                        return -ENOENT;
                }
        }
@@ -736,8 +740,11 @@ try_again:
                int same = (card->cis.vendor == oldcard->cis.vendor &&
                            card->cis.device == oldcard->cis.device);
                mmc_remove_card(card);
-               if (!same)
+               if (!same) {
+                       pr_debug("%s: Perhaps the card was replaced\n",
+                               mmc_hostname(host));
                        return -ENOENT;
+               }
 
                card = oldcard;
        }
index b6d8203e46ebe177de629694f2a15406a6b262eb..62b0f5ecc7f7e4aaf59bc423f8c7ea0e20351581 100644 (file)
@@ -179,7 +179,6 @@ static int sdio_bus_remove(struct device *dev)
 {
        struct sdio_driver *drv = to_sdio_driver(dev->driver);
        struct sdio_func *func = dev_to_sdio_func(dev);
-       int ret = 0;
 
        /* Make sure card is powered before invoking ->remove() */
        if (func->card->host->caps & MMC_CAP_POWER_OFF_CARD)
@@ -205,7 +204,7 @@ static int sdio_bus_remove(struct device *dev)
 
        dev_pm_domain_detach(dev, false);
 
-       return ret;
+       return 0;
 }
 
 static const struct dev_pm_ops sdio_bus_pm_ops = {
index d40744bbafa9a95e7a36bd8efb980ac9a78c2f1e..3f67fbbe0d754c7fe24b68cc3d1eac40a354094e 100644 (file)
@@ -10,6 +10,7 @@
  */
 
 #include <linux/export.h>
+#include <linux/kernel.h>
 #include <linux/mmc/host.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/sdio.h>
@@ -203,6 +204,21 @@ static inline unsigned int sdio_max_byte_size(struct sdio_func *func)
        return min(mval, 512u); /* maximum size for byte mode */
 }
 
+/*
+ * This is legacy code, which needs to be re-worked some day. Basically we need
+ * to take into account the properties of the host, as to enable the SDIO func
+ * driver layer to allocate optimal buffers.
+ */
+static inline unsigned int _sdio_align_size(unsigned int sz)
+{
+       /*
+        * FIXME: We don't have a system for the controller to tell
+        * the core about its problems yet, so for now we just 32-bit
+        * align the size.
+        */
+       return ALIGN(sz, 4);
+}
+
 /**
  *     sdio_align_size - pads a transfer size to a more optimal value
  *     @func: SDIO function
@@ -230,7 +246,7 @@ unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
         * wants to increase the size up to a point where it
         * might need more than one block.
         */
-       sz = mmc_align_data_size(func->card, sz);
+       sz = _sdio_align_size(sz);
 
        /*
         * If we can still do this with just a byte transfer, then
@@ -252,7 +268,7 @@ unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
                 */
                blk_sz = ((sz + func->cur_blksize - 1) /
                        func->cur_blksize) * func->cur_blksize;
-               blk_sz = mmc_align_data_size(func->card, blk_sz);
+               blk_sz = _sdio_align_size(blk_sz);
 
                /*
                 * This value is only good if it is still just
@@ -265,8 +281,7 @@ unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
                 * We failed to do one request, but at least try to
                 * pad the remainder properly.
                 */
-               byte_sz = mmc_align_data_size(func->card,
-                               sz % func->cur_blksize);
+               byte_sz = _sdio_align_size(sz % func->cur_blksize);
                if (byte_sz <= sdio_max_byte_size(func)) {
                        blk_sz = sz / func->cur_blksize;
                        return blk_sz * func->cur_blksize + byte_sz;
@@ -276,16 +291,14 @@ unsigned int sdio_align_size(struct sdio_func *func, unsigned int sz)
                 * We need multiple requests, so first check that the
                 * controller can handle the chunk size;
                 */
-               chunk_sz = mmc_align_data_size(func->card,
-                               sdio_max_byte_size(func));
+               chunk_sz = _sdio_align_size(sdio_max_byte_size(func));
                if (chunk_sz == sdio_max_byte_size(func)) {
                        /*
                         * Fix up the size of the remainder (if any)
                         */
                        byte_sz = orig_sz % chunk_sz;
                        if (byte_sz) {
-                               byte_sz = mmc_align_data_size(func->card,
-                                               byte_sz);
+                               byte_sz = _sdio_align_size(byte_sz);
                        }
 
                        return (orig_sz / chunk_sz) * chunk_sz + byte_sz;
index 96945cafbf0be3b3175b2ae8f9f38bb6e9a3509f..1f6d0447ea0f9475f97715f1c9232359b4c64207 100644 (file)
@@ -25,7 +25,6 @@ int mmc_io_rw_direct(struct mmc_card *card, int write, unsigned fn,
 int mmc_io_rw_extended(struct mmc_card *card, int write, unsigned fn,
        unsigned addr, int incr_addr, u8 *buf, unsigned blocks, unsigned blksz);
 int sdio_reset(struct mmc_host *host);
-unsigned int mmc_align_data_size(struct mmc_card *card, unsigned int sz);
 void sdio_irq_work(struct work_struct *work);
 
 static inline bool sdio_is_io_busy(u32 opcode, u32 arg)
index 319ccd93383d25759d9104d3fd4eaae20745fc67..4afc6b87b4659fbfeca69264ae5b39b8a100fc6f 100644 (file)
@@ -22,7 +22,6 @@
 struct mmc_gpio {
        struct gpio_desc *ro_gpio;
        struct gpio_desc *cd_gpio;
-       bool override_ro_active_level;
        bool override_cd_active_level;
        irqreturn_t (*cd_gpio_isr)(int irq, void *dev_id);
        char *ro_label;
@@ -71,10 +70,6 @@ int mmc_gpio_get_ro(struct mmc_host *host)
        if (!ctx || !ctx->ro_gpio)
                return -ENOSYS;
 
-       if (ctx->override_ro_active_level)
-               return !gpiod_get_raw_value_cansleep(ctx->ro_gpio) ^
-                       !!(host->caps2 & MMC_CAP2_RO_ACTIVE_HIGH);
-
        return gpiod_get_value_cansleep(ctx->ro_gpio);
 }
 EXPORT_SYMBOL(mmc_gpio_get_ro);
@@ -225,7 +220,6 @@ EXPORT_SYMBOL(mmc_can_gpio_cd);
  * @host: mmc host
  * @con_id: function within the GPIO consumer
  * @idx: index of the GPIO to obtain in the consumer
- * @override_active_level: ignore %GPIO_ACTIVE_LOW flag
  * @debounce: debounce time in microseconds
  * @gpio_invert: will return whether the GPIO line is inverted or not,
  * set to NULL to ignore
@@ -233,7 +227,7 @@ EXPORT_SYMBOL(mmc_can_gpio_cd);
  * Returns zero on success, else an error.
  */
 int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id,
-                        unsigned int idx, bool override_active_level,
+                        unsigned int idx,
                         unsigned int debounce, bool *gpio_invert)
 {
        struct mmc_gpio *ctx = host->slot.handler_priv;
@@ -253,7 +247,6 @@ int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id,
        if (gpio_invert)
                *gpio_invert = !gpiod_is_active_low(desc);
 
-       ctx->override_ro_active_level = override_active_level;
        ctx->ro_gpio = desc;
 
        return 0;
index a44ec8bb54181d048f5cdd7dc64a8c3aed91e208..28fcd8f580a1d7d711300c7126008d9c888f9d2c 100644 (file)
@@ -224,6 +224,7 @@ config MMC_SDHCI_ESDHC_IMX
        depends on ARCH_MXC
        depends on MMC_SDHCI_PLTFM
        select MMC_SDHCI_IO_ACCESSORS
+       select MMC_CQHCI
        help
          This selects the Freescale eSDHC/uSDHC controller support
          found on i.MX25, i.MX35 i.MX5x and i.MX6x.
@@ -250,6 +251,7 @@ config MMC_SDHCI_TEGRA
        depends on ARCH_TEGRA
        depends on MMC_SDHCI_PLTFM
        select MMC_SDHCI_IO_ACCESSORS
+       select MMC_CQHCI
        help
          This selects the Tegra SD/MMC controller. If you have a Tegra
          platform with SD or MMC devices, say Y or M here.
index 47189f9ed4e20bbb8d7b09a20f36c06c1a6ff14c..735aa5871358fc264f2ee819796e1aaab29ad3b7 100644 (file)
@@ -1410,6 +1410,9 @@ static void atmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        case MMC_BUS_WIDTH_4:
                slot->sdc_reg |= ATMCI_SDCBUS_4BIT;
                break;
+       case MMC_BUS_WIDTH_8:
+               slot->sdc_reg |= ATMCI_SDCBUS_8BIT;
+               break;
        }
 
        if (ios->clock) {
@@ -2275,8 +2278,11 @@ static int atmci_init_slot(struct atmel_mci *host,
         * use only one bit for data to prevent fifo underruns and overruns
         * which will corrupt data.
         */
-       if ((slot_data->bus_width >= 4) && host->caps.has_rwproof)
+       if ((slot_data->bus_width >= 4) && host->caps.has_rwproof) {
                mmc->caps |= MMC_CAP_4_BIT_DATA;
+               if (slot_data->bus_width >= 8)
+                       mmc->caps |= MMC_CAP_8_BIT_DATA;
+       }
 
        if (atmci_get_version(host) < 0x200) {
                mmc->max_segs = 256;
index c9e7aa50bb0ab5d05884d8ebfe6ef740adeda150..7e0d3a49c06d8ec443f0b8493c617411efbf7af8 100644 (file)
@@ -148,7 +148,6 @@ struct bcm2835_host {
        void __iomem            *ioaddr;
        u32                     phys_addr;
 
-       struct mmc_host         *mmc;
        struct platform_device  *pdev;
 
        int                     clock;          /* Current clock speed */
@@ -618,7 +617,7 @@ static void bcm2835_finish_request(struct bcm2835_host *host)
                                "failed to terminate DMA (%d)\n", err);
        }
 
-       mmc_request_done(host->mmc, mrq);
+       mmc_request_done(mmc_from_priv(host), mrq);
 }
 
 static
@@ -837,7 +836,7 @@ static void bcm2835_timeout(struct work_struct *work)
                dev_err(dev, "timeout waiting for hardware interrupt.\n");
                bcm2835_dumpregs(host);
 
-               bcm2835_reset(host->mmc);
+               bcm2835_reset(mmc_from_priv(host));
 
                if (host->data) {
                        host->data->error = -ETIMEDOUT;
@@ -1100,6 +1099,7 @@ static void bcm2835_dma_complete_work(struct work_struct *work)
 
 static void bcm2835_set_clock(struct bcm2835_host *host, unsigned int clock)
 {
+       struct mmc_host *mmc = mmc_from_priv(host);
        int div;
 
        /* The SDCDIV register has 11 bits, and holds (div - 2).  But
@@ -1143,18 +1143,18 @@ static void bcm2835_set_clock(struct bcm2835_host *host, unsigned int clock)
                div = SDCDIV_MAX_CDIV;
 
        clock = host->max_clk / (div + 2);
-       host->mmc->actual_clock = clock;
+       mmc->actual_clock = clock;
 
        /* Calibrate some delays */
 
        host->ns_per_fifo_word = (1000000000 / clock) *
-               ((host->mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32);
+               ((mmc->caps & MMC_CAP_4_BIT_DATA) ? 8 : 32);
 
        host->cdiv = div;
        writel(host->cdiv, host->ioaddr + SDCDIV);
 
        /* Set the timeout to 500ms */
-       writel(host->mmc->actual_clock / 2, host->ioaddr + SDTOUT);
+       writel(mmc->actual_clock / 2, host->ioaddr + SDTOUT);
 }
 
 static void bcm2835_request(struct mmc_host *mmc, struct mmc_request *mrq)
@@ -1264,7 +1264,7 @@ static const struct mmc_host_ops bcm2835_ops = {
 
 static int bcm2835_add_host(struct bcm2835_host *host)
 {
-       struct mmc_host *mmc = host->mmc;
+       struct mmc_host *mmc = mmc_from_priv(host);
        struct device *dev = &host->pdev->dev;
        char pio_limit_string[20];
        int ret;
@@ -1286,7 +1286,7 @@ static int bcm2835_add_host(struct bcm2835_host *host)
        spin_lock_init(&host->lock);
        mutex_init(&host->mutex);
 
-       if (IS_ERR_OR_NULL(host->dma_chan_rxtx)) {
+       if (!host->dma_chan_rxtx) {
                dev_warn(dev, "unable to initialise DMA channel. Falling back to PIO\n");
                host->use_dma = false;
        } else {
@@ -1370,7 +1370,6 @@ static int bcm2835_probe(struct platform_device *pdev)
 
        mmc->ops = &bcm2835_ops;
        host = mmc_priv(mmc);
-       host->mmc = mmc;
        host->pdev = pdev;
        spin_lock_init(&host->lock);
 
@@ -1441,8 +1440,9 @@ err:
 static int bcm2835_remove(struct platform_device *pdev)
 {
        struct bcm2835_host *host = platform_get_drvdata(pdev);
+       struct mmc_host *mmc = mmc_from_priv(host);
 
-       mmc_remove_host(host->mmc);
+       mmc_remove_host(mmc);
 
        writel(SDVDD_POWER_OFF, host->ioaddr + SDVDD);
 
@@ -1454,8 +1454,7 @@ static int bcm2835_remove(struct platform_device *pdev)
        if (host->dma_chan_rxtx)
                dma_release_channel(host->dma_chan_rxtx);
 
-       mmc_free_host(host->mmc);
-       platform_set_drvdata(pdev, NULL);
+       mmc_free_host(mmc);
 
        return 0;
 }
index 1087b4c79cd661bbf8bfe57f73470e681324b668..4c477dcd2adab71a8ac318d50094ba590c04bad4 100644 (file)
@@ -566,30 +566,32 @@ static void cb710_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
 
        cb710_mmc_select_clock_divider(mmc, ios->clock);
 
-       if (ios->power_mode != reader->last_power_mode)
-       switch (ios->power_mode) {
-       case MMC_POWER_ON:
-               err = cb710_mmc_powerup(slot);
-               if (err) {
-                       dev_warn(cb710_slot_dev(slot),
-                               "powerup failed (%d)- retrying\n", err);
-                       cb710_mmc_powerdown(slot);
-                       udelay(1);
+       if (ios->power_mode != reader->last_power_mode) {
+               switch (ios->power_mode) {
+               case MMC_POWER_ON:
                        err = cb710_mmc_powerup(slot);
-                       if (err)
+                       if (err) {
                                dev_warn(cb710_slot_dev(slot),
-                                       "powerup retry failed (%d) - expect errors\n",
+                                       "powerup failed (%d)- retrying\n", err);
+                               cb710_mmc_powerdown(slot);
+                               udelay(1);
+                               err = cb710_mmc_powerup(slot);
+                               if (err)
+                                       dev_warn(cb710_slot_dev(slot),
+                                               "powerup retry failed (%d) - expect errors\n",
                                        err);
+                       }
+                       reader->last_power_mode = MMC_POWER_ON;
+                       break;
+               case MMC_POWER_OFF:
+                       cb710_mmc_powerdown(slot);
+                       reader->last_power_mode = MMC_POWER_OFF;
+                       break;
+               case MMC_POWER_UP:
+               default:
+                       /* ignore */
+                       break;
                }
-               reader->last_power_mode = MMC_POWER_ON;
-               break;
-       case MMC_POWER_OFF:
-               cb710_mmc_powerdown(slot);
-               reader->last_power_mode = MMC_POWER_OFF;
-               break;
-       case MMC_POWER_UP:
-       default:
-               /* ignore */;
        }
 
        cb710_mmc_enable_4bit_data(slot, ios->bus_width != MMC_BUS_WIDTH_1);
index 9e68c3645e2270272f3bed4a5035e0dd8cdd2247..49e0daf2ef5e1a99cf13eb1d7b46d71f0195a9c5 100644 (file)
@@ -1193,7 +1193,7 @@ static int mmc_davinci_parse_pdata(struct mmc_host *mmc)
        else if (ret)
                mmc->caps |= MMC_CAP_NEEDS_POLL;
 
-       ret = mmc_gpiod_request_ro(mmc, "wp", 0, false, 0, NULL);
+       ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0, NULL);
        if (ret == -EPROBE_DEFER)
                return ret;
 
index 33215d66afa2ee764b6c28e84e5daf2b11be9c04..63303022669c94e34961c6957e7ecc2265d5b123 100644 (file)
@@ -21,7 +21,6 @@
 #include <linux/dmaengine.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
-#include <linux/gpio/consumer.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/irq.h>
@@ -36,7 +35,6 @@
 #include <asm/cacheflush.h>
 
 #include <asm/mach-jz4740/dma.h>
-#include <asm/mach-jz4740/jz4740_mmc.h>
 
 #define JZ_REG_MMC_STRPCL      0x00
 #define JZ_REG_MMC_STATUS      0x04
@@ -148,9 +146,7 @@ enum jz4780_cookie {
 struct jz4740_mmc_host {
        struct mmc_host *mmc;
        struct platform_device *pdev;
-       struct jz4740_mmc_platform_data *pdata;
        struct clk *clk;
-       struct gpio_desc *power;
 
        enum jz4740_mmc_version version;
 
@@ -743,6 +739,7 @@ static irqreturn_t jz_mmc_irq_worker(int irq, void *devid)
                        break;
 
                jz_mmc_prepare_data_transfer(host);
+               /* fall through */
 
        case JZ4740_MMC_STATE_TRANSFER_DATA:
                if (host->use_dma) {
@@ -777,6 +774,7 @@ static irqreturn_t jz_mmc_irq_worker(int irq, void *devid)
                        break;
                }
                jz4740_mmc_write_irq_reg(host, JZ_MMC_IRQ_DATA_TRAN_DONE);
+               /* fall through */
 
        case JZ4740_MMC_STATE_SEND_STOP:
                if (!req->stop)
@@ -894,16 +892,16 @@ static void jz4740_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
        switch (ios->power_mode) {
        case MMC_POWER_UP:
                jz4740_mmc_reset(host);
-               if (host->power)
-                       gpiod_set_value(host->power, 1);
+               if (!IS_ERR(mmc->supply.vmmc))
+                       mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, ios->vdd);
                host->cmdat |= JZ_MMC_CMDAT_INIT;
                clk_prepare_enable(host->clk);
                break;
        case MMC_POWER_ON:
                break;
        default:
-               if (host->power)
-                       gpiod_set_value(host->power, 0);
+               if (!IS_ERR(mmc->supply.vmmc))
+                       mmc_regulator_set_ocr(mmc, mmc->supply.vmmc, 0);
                clk_disable_unprepare(host->clk);
                break;
        }
@@ -936,38 +934,6 @@ static const struct mmc_host_ops jz4740_mmc_ops = {
        .enable_sdio_irq = jz4740_mmc_enable_sdio_irq,
 };
 
-static int jz4740_mmc_request_gpios(struct jz4740_mmc_host *host,
-                                   struct mmc_host *mmc,
-                                   struct platform_device *pdev)
-{
-       struct jz4740_mmc_platform_data *pdata = dev_get_platdata(&pdev->dev);
-       int ret = 0;
-
-       if (!pdata)
-               return 0;
-
-       if (!pdata->card_detect_active_low)
-               mmc->caps2 |= MMC_CAP2_CD_ACTIVE_HIGH;
-       if (!pdata->read_only_active_low)
-               mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
-
-       /*
-        * Get optional card detect and write protect GPIOs,
-        * only back out on probe deferral.
-        */
-       ret = mmc_gpiod_request_cd(mmc, "cd", 0, false, 0, NULL);
-       if (ret == -EPROBE_DEFER)
-               return ret;
-
-       ret = mmc_gpiod_request_ro(mmc, "wp", 0, false, 0, NULL);
-       if (ret == -EPROBE_DEFER)
-               return ret;
-
-       host->power = devm_gpiod_get_optional(&pdev->dev, "power",
-                                             GPIOD_OUT_HIGH);
-       return PTR_ERR_OR_ZERO(host->power);
-}
-
 static const struct of_device_id jz4740_mmc_of_match[] = {
        { .compatible = "ingenic,jz4740-mmc", .data = (void *) JZ_MMC_JZ4740 },
        { .compatible = "ingenic,jz4725b-mmc", .data = (void *)JZ_MMC_JZ4725B },
@@ -982,9 +948,6 @@ static int jz4740_mmc_probe(struct platform_device* pdev)
        struct mmc_host *mmc;
        struct jz4740_mmc_host *host;
        const struct of_device_id *match;
-       struct jz4740_mmc_platform_data *pdata;
-
-       pdata = dev_get_platdata(&pdev->dev);
 
        mmc = mmc_alloc_host(sizeof(struct jz4740_mmc_host), &pdev->dev);
        if (!mmc) {
@@ -993,29 +956,25 @@ static int jz4740_mmc_probe(struct platform_device* pdev)
        }
 
        host = mmc_priv(mmc);
-       host->pdata = pdata;
 
        match = of_match_device(jz4740_mmc_of_match, &pdev->dev);
        if (match) {
                host->version = (enum jz4740_mmc_version)match->data;
-               ret = mmc_of_parse(mmc);
-               if (ret) {
-                       if (ret != -EPROBE_DEFER)
-                               dev_err(&pdev->dev,
-                                       "could not parse of data: %d\n", ret);
-                       goto err_free_host;
-               }
        } else {
                /* JZ4740 should be the only one using legacy probe */
                host->version = JZ_MMC_JZ4740;
-               mmc->caps |= MMC_CAP_SDIO_IRQ;
-               if (!(pdata && pdata->data_1bit))
-                       mmc->caps |= MMC_CAP_4_BIT_DATA;
-               ret = jz4740_mmc_request_gpios(host, mmc, pdev);
-               if (ret)
-                       goto err_free_host;
        }
 
+       ret = mmc_of_parse(mmc);
+       if (ret) {
+               if (ret != -EPROBE_DEFER)
+                       dev_err(&pdev->dev,
+                               "could not parse device properties: %d\n", ret);
+               goto err_free_host;
+       }
+
+       mmc_regulator_get_supply(mmc);
+
        host->irq = platform_get_irq(pdev, 0);
        if (host->irq < 0) {
                ret = host->irq;
index 8ade14fb2148dbcf8a8fa8087fdbb8dfbd1842ca..1b1498805972c7fdd9ff2640c55424ad7003760b 100644 (file)
@@ -1453,7 +1453,7 @@ static int mmc_spi_probe(struct spi_device *spi)
        mmc_detect_change(mmc, 0);
 
        /* Index 1 is write protect/read only */
-       status = mmc_gpiod_request_ro(mmc, NULL, 1, false, 0, NULL);
+       status = mmc_gpiod_request_ro(mmc, NULL, 1, 0, NULL);
        if (status == -EPROBE_DEFER)
                goto fail_add_host;
        if (!status)
index e352f5ad58018cebcec91dd87a45e638cb4d8a7c..387ff14587b873cd327e75286235dbbd86069c31 100644 (file)
@@ -1127,6 +1127,12 @@ mmci_start_command(struct mmci_host *host, struct mmc_command *cmd, u32 c)
        writel(c, base + MMCICOMMAND);
 }
 
+static void mmci_stop_command(struct mmci_host *host)
+{
+       host->stop_abort.error = 0;
+       mmci_start_command(host, &host->stop_abort, 0);
+}
+
 static void
 mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
              unsigned int status)
@@ -1196,10 +1202,16 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
                        /* The error clause is handled above, success! */
                        data->bytes_xfered = data->blksz * data->blocks;
 
-               if (!data->stop || (host->mrq->sbc && !data->error))
+               if (!data->stop) {
+                       if (host->variant->cmdreg_stop && data->error)
+                               mmci_stop_command(host);
+                       else
+                               mmci_request_end(host, data->mrq);
+               } else if (host->mrq->sbc && !data->error) {
                        mmci_request_end(host, data->mrq);
-               else
+               } else {
                        mmci_start_command(host, data->stop, 0);
+               }
        }
 }
 
@@ -1298,6 +1310,10 @@ mmci_cmd_irq(struct mmci_host *host, struct mmc_command *cmd,
                        mmci_dma_error(host);
 
                        mmci_stop_data(host);
+                       if (host->variant->cmdreg_stop && cmd->error) {
+                               mmci_stop_command(host);
+                               return;
+                       }
                }
                mmci_request_end(host, host->mrq);
        } else if (sbc) {
@@ -1956,6 +1972,11 @@ static int mmci_probe(struct amba_device *dev,
                mmc->max_busy_timeout = 0;
        }
 
+       /* Prepare a CMD12 - needed to clear the DPSM on some variants. */
+       host->stop_abort.opcode = MMC_STOP_TRANSMISSION;
+       host->stop_abort.arg = 0;
+       host->stop_abort.flags = MMC_RSP_R1B | MMC_CMD_AC;
+
        mmc->ops = &mmci_ops;
 
        /* We support these PM capabilities. */
@@ -2011,7 +2032,7 @@ static int mmci_probe(struct amba_device *dev,
                if (ret == -EPROBE_DEFER)
                        goto clk_disable;
 
-               ret = mmc_gpiod_request_ro(mmc, "wp", 0, false, 0, NULL);
+               ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0, NULL);
                if (ret == -EPROBE_DEFER)
                        goto clk_disable;
        }
index 24229097d05c2c0fee4b083faeb1a37189c2f7fd..14df8105443844f6ac986c04806fdb0350f87b67 100644 (file)
@@ -377,6 +377,7 @@ struct mmci_host {
        void __iomem            *base;
        struct mmc_request      *mrq;
        struct mmc_command      *cmd;
+       struct mmc_command      stop_abort;
        struct mmc_data         *data;
        struct mmc_host         *mmc;
        struct clk              *clk;
index 4d17032d15eef5d1b412df99aa7b661c045ac48b..d54612257b068441ae3ffe3aaa9b7d7f85a69182 100644 (file)
 #include <linux/delay.h>
 #include <linux/clk.h>
 #include <linux/io.h>
-#include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
 #include <linux/dmaengine.h>
 #include <linux/types.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/of_dma.h>
-#include <linux/of_gpio.h>
 #include <linux/mmc/slot-gpio.h>
 
 #include <asm/dma.h>
index add1e70195ea6a2c7111f768c5865d15b17f085e..4f06fb03c0a2b4b0b7b30700da1e0c77d933164c 100644 (file)
@@ -25,7 +25,6 @@
 #include <linux/ioport.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-#include <linux/of_gpio.h>
 #include <linux/platform_device.h>
 #include <linux/delay.h>
 #include <linux/interrupt.h>
@@ -39,7 +38,6 @@
 #include <linux/mmc/mmc.h>
 #include <linux/mmc/sdio.h>
 #include <linux/mmc/slot-gpio.h>
-#include <linux/gpio.h>
 #include <linux/regulator/consumer.h>
 #include <linux/module.h>
 #include <linux/stmp_device.h>
index b294b221f225dd3a5b58eaef8e2aeae00efd035f..8a274b91804edac66621654100c6a658bab90a5c 100644 (file)
@@ -61,9 +61,6 @@ struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi)
        struct device *dev = &spi->dev;
        struct device_node *np = dev->of_node;
        struct of_mmc_spi *oms;
-       const __be32 *voltage_ranges;
-       int num_ranges;
-       int i;
 
        if (dev->platform_data || !np)
                return dev->platform_data;
@@ -72,25 +69,8 @@ struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi)
        if (!oms)
                return NULL;
 
-       voltage_ranges = of_get_property(np, "voltage-ranges", &num_ranges);
-       num_ranges = num_ranges / sizeof(*voltage_ranges) / 2;
-       if (!voltage_ranges || !num_ranges) {
-               dev_err(dev, "OF: voltage-ranges unspecified\n");
+       if (mmc_of_parse_voltage(np, &oms->pdata.ocr_mask) <= 0)
                goto err_ocr;
-       }
-
-       for (i = 0; i < num_ranges; i++) {
-               const int j = i * 2;
-               u32 mask;
-
-               mask = mmc_vddrange_to_ocrmask(be32_to_cpu(voltage_ranges[j]),
-                                              be32_to_cpu(voltage_ranges[j + 1]));
-               if (!mask) {
-                       dev_err(dev, "OF: voltage-range #%d is invalid\n", i);
-                       goto err_ocr;
-               }
-               oms->pdata.ocr_mask |= mask;
-       }
 
        oms->detect_irq = irq_of_parse_and_map(np, 0);
        if (oms->detect_irq != 0) {
index c60a7625b1fab7ff0657ea48be126fb384c261b7..b2873a2432b69fd374daa049729348c5af042ed6 100644 (file)
@@ -920,7 +920,7 @@ static inline void set_cmd_timeout(struct mmc_omap_host *host, struct mmc_reques
        reg &= ~(1 << 5);
        OMAP_MMC_WRITE(host, SDIO, reg);
        /* Set maximum timeout */
-       OMAP_MMC_WRITE(host, CTO, 0xff);
+       OMAP_MMC_WRITE(host, CTO, 0xfd);
 }
 
 static inline void set_data_timeout(struct mmc_omap_host *host, struct mmc_request *req)
index 8779bbaa6b697441fe50bc2c39d1337cfc0b43bf..c907bf502a123b5b588d8a70e3446fca1da20a66 100644 (file)
@@ -743,7 +743,7 @@ static int pxamci_probe(struct platform_device *pdev)
                        goto out;
                }
 
-               ret = mmc_gpiod_request_ro(mmc, "wp", 0, false, 0, NULL);
+               ret = mmc_gpiod_request_ro(mmc, "wp", 0, 0, NULL);
                if (ret && ret != -ENOENT) {
                        dev_err(dev, "Failed requesting gpio_ro\n");
                        goto out;
index da1e49c45bec8eb2ea3027ff02eacb0b932176ce..8394a7bb1fc11cf4149c4ba5dc297663d64aedfc 100644 (file)
@@ -15,6 +15,7 @@
 struct renesas_sdhi_scc {
        unsigned long clk_rate; /* clock rate for SDR104 */
        u32 tap;                /* sampling clock position for SDR104 */
+       u32 tap_hs400;          /* sampling clock position for HS400 */
 };
 
 struct renesas_sdhi_of_data {
@@ -49,6 +50,7 @@ struct renesas_sdhi {
        struct pinctrl_state *pins_default, *pins_uhs;
        void __iomem *scc_ctl;
        u32 scc_tappos;
+       u32 scc_tappos_hs400;
 };
 
 #define host_to_priv(host) \
index 31a351a20dc02aabbe7d5bb65ab1f76eee6d4f06..71e13844df6c0deaa1a498140e8f553a04ad3148 100644 (file)
@@ -337,6 +337,10 @@ static void renesas_sdhi_hs400_complete(struct tmio_mmc_host *host)
        /* Set HS400 mode */
        sd_ctrl_write16(host, CTL_SDIF_MODE, 0x0001 |
                        sd_ctrl_read16(host, CTL_SDIF_MODE));
+
+       sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DT2FF,
+                      priv->scc_tappos_hs400);
+
        sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2,
                       (SH_MOBILE_SDHI_SCC_TMPPORT2_HS400EN |
                        SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL) |
@@ -396,6 +400,9 @@ static void renesas_sdhi_reset_hs400_mode(struct tmio_mmc_host *host,
        /* Reset HS400 mode */
        sd_ctrl_write16(host, CTL_SDIF_MODE, ~0x0001 &
                        sd_ctrl_read16(host, CTL_SDIF_MODE));
+
+       sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_DT2FF, priv->scc_tappos);
+
        sd_scc_write32(host, priv, SH_MOBILE_SDHI_SCC_TMPPORT2,
                       ~(SH_MOBILE_SDHI_SCC_TMPPORT2_HS400EN |
                         SH_MOBILE_SDHI_SCC_TMPPORT2_HS400OSEL) &
@@ -723,6 +730,13 @@ int renesas_sdhi_probe(struct platform_device *pdev,
                host->ops.start_signal_voltage_switch =
                        renesas_sdhi_start_signal_voltage_switch;
                host->sdcard_irq_setbit_mask = TMIO_STAT_ALWAYS_SET_27;
+
+               /* SDR and HS200/400 registers requires HW reset */
+               if (of_data && of_data->scc_offset) {
+                       priv->scc_ctl = host->ctl + of_data->scc_offset;
+                       host->mmc->caps |= MMC_CAP_HW_RESET;
+                       host->hw_reset = renesas_sdhi_hw_reset;
+               }
        }
 
        /* Orginally registers were 16 bit apart, could be 32 or 64 nowadays */
@@ -775,12 +789,11 @@ int renesas_sdhi_probe(struct platform_device *pdev,
                const struct renesas_sdhi_scc *taps = of_data->taps;
                bool hit = false;
 
-               host->mmc->caps |= MMC_CAP_HW_RESET;
-
                for (i = 0; i < of_data->taps_num; i++) {
                        if (taps[i].clk_rate == 0 ||
                            taps[i].clk_rate == host->mmc->f_max) {
                                priv->scc_tappos = taps->tap;
+                               priv->scc_tappos_hs400 = taps->tap_hs400;
                                hit = true;
                                break;
                        }
@@ -789,12 +802,10 @@ int renesas_sdhi_probe(struct platform_device *pdev,
                if (!hit)
                        dev_warn(&host->pdev->dev, "Unknown clock rate for SDR104\n");
 
-               priv->scc_ctl = host->ctl + of_data->scc_offset;
                host->init_tuning = renesas_sdhi_init_tuning;
                host->prepare_tuning = renesas_sdhi_prepare_tuning;
                host->select_tuning = renesas_sdhi_select_tuning;
                host->check_scc_error = renesas_sdhi_check_scc_error;
-               host->hw_reset = renesas_sdhi_hw_reset;
                host->prepare_hs400_tuning =
                        renesas_sdhi_prepare_hs400_tuning;
                host->hs400_downgrade = renesas_sdhi_disable_scc;
index 92c9b15252da7e411db9eceb8191b5b042cde4a5..9dfafa2a90a386106c5d596c8e8bb89cf75cd025 100644 (file)
@@ -81,6 +81,7 @@ static struct renesas_sdhi_scc rcar_gen3_scc_taps[] = {
        {
                .clk_rate = 0,
                .tap = 0x00000300,
+               .tap_hs400 = 0x00000704,
        },
 };
 
index 10f5219b3b408fa3232d31498ce21910071f3503..f31333e831a70963c69b461239e795ab276eebc8 100644 (file)
@@ -1530,7 +1530,7 @@ static int s3cmci_probe_pdata(struct s3cmci_host *host)
                return ret;
        }
 
-       ret = mmc_gpiod_request_ro(host->mmc, "wp", 0, false, 0, NULL);
+       ret = mmc_gpiod_request_ro(host->mmc, "wp", 0, 0, NULL);
        if (ret != -ENOENT) {
                dev_err(&pdev->dev, "error requesting GPIO for WP %d\n",
                        ret);
index bdbd4897c0f7322a5e1dcb287b6ce36921b789f0..a6c2bd202b45fa8a112fbf3bb523ab3e8976d0aa 100644 (file)
 #include <linux/platform_device.h>
 #include <linux/mmc/host.h>
 #include <linux/io.h>
-#include <linux/gpio.h>
 #include <linux/clk.h>
 #include <linux/regulator/consumer.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
-#include <linux/of_gpio.h>
 #include <linux/mmc/slot-gpio.h>
 
 #include "sdhci-pltfm.h"
index 552bddc5096ce2e2d2638483f3baf7317115d5bf..1cd10356fc14fd1ddbe9d20306b913b684de0add 100644 (file)
@@ -55,7 +55,9 @@ static int sdhci_brcmstb_probe(struct platform_device *pdev)
        }
 
        sdhci_get_of_property(pdev);
-       mmc_of_parse(host->mmc);
+       res = mmc_of_parse(host->mmc);
+       if (res)
+               goto err;
 
        /*
         * Supply the existing CAPS, but clear the UHS modes. This
index 00d41b312c79af466a63241311f17103a98e781d..8dbbc1f62b708d53a7507a418e605037b78d94a1 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/pm_runtime.h>
 #include "sdhci-pltfm.h"
 #include "sdhci-esdhc.h"
+#include "cqhci.h"
 
 #define ESDHC_SYS_CTRL_DTOCV_MASK      0x0f
 #define        ESDHC_CTRL_D3CD                 0x08
@@ -50,6 +51,7 @@
 #define  ESDHC_MIX_CTRL_AUTO_TUNE_EN   (1 << 24)
 #define  ESDHC_MIX_CTRL_FBCLK_SEL      (1 << 25)
 #define  ESDHC_MIX_CTRL_HS400_EN       (1 << 26)
+#define  ESDHC_MIX_CTRL_HS400_ES_EN    (1 << 27)
 /* Bits 3 and 6 are not SDHCI standard definitions */
 #define  ESDHC_MIX_CTRL_SDHCI_MASK     0xb7
 /* Tuning bits */
@@ -76,6 +78,9 @@
 #define ESDHC_STROBE_DLL_STS_REF_LOCK  (1 << 1)
 #define ESDHC_STROBE_DLL_STS_SLV_LOCK  0x1
 
+#define ESDHC_VEND_SPEC2               0xc8
+#define ESDHC_VEND_SPEC2_EN_BUSY_IRQ   (1 << 8)
+
 #define ESDHC_TUNING_CTRL              0xcc
 #define ESDHC_STD_TUNING_EN            (1 << 24)
 /* NOTE: the minimum valid tuning start tap for mx6sl is 1 */
  */
 #define ESDHC_INT_VENDOR_SPEC_DMA_ERR  (1 << 28)
 
+/* the address offset of CQHCI */
+#define ESDHC_CQHCI_ADDR_OFFSET                0x100
+
 /*
  * The CMDTYPE of the CMD register (offset 0xE) should be set to
  * "11" when the STOP CMD12 is issued on imx53 to abort one
 #define ESDHC_FLAG_HS200               BIT(8)
 /* The IP supports HS400 mode */
 #define ESDHC_FLAG_HS400               BIT(9)
-
-/* A clock frequency higher than this rate requires strobe dll control */
-#define ESDHC_STROBE_DLL_CLK_FREQ      100000000
+/*
+ * The IP has errata ERR010450
+ * uSDHC: Due to the I/O timing limit, for SDR mode, SD card clock can't
+ * exceed 150MHz, for DDR mode, SD card clock can't exceed 45MHz.
+ */
+#define ESDHC_FLAG_ERR010450           BIT(10)
+/* The IP supports HS400ES mode */
+#define ESDHC_FLAG_HS400_ES            BIT(11)
+/* The IP has Host Controller Interface for Command Queuing */
+#define ESDHC_FLAG_CQHCI               BIT(12)
 
 struct esdhc_soc_data {
        u32 flags;
 };
 
-static struct esdhc_soc_data esdhc_imx25_data = {
+static const struct esdhc_soc_data esdhc_imx25_data = {
        .flags = ESDHC_FLAG_ERR004536,
 };
 
-static struct esdhc_soc_data esdhc_imx35_data = {
+static const struct esdhc_soc_data esdhc_imx35_data = {
        .flags = ESDHC_FLAG_ERR004536,
 };
 
-static struct esdhc_soc_data esdhc_imx51_data = {
+static const struct esdhc_soc_data esdhc_imx51_data = {
        .flags = 0,
 };
 
-static struct esdhc_soc_data esdhc_imx53_data = {
+static const struct esdhc_soc_data esdhc_imx53_data = {
        .flags = ESDHC_FLAG_MULTIBLK_NO_INT,
 };
 
-static struct esdhc_soc_data usdhc_imx6q_data = {
+static const struct esdhc_soc_data usdhc_imx6q_data = {
        .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_MAN_TUNING,
 };
 
-static struct esdhc_soc_data usdhc_imx6sl_data = {
+static const struct esdhc_soc_data usdhc_imx6sl_data = {
        .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
                        | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_ERR004536
                        | ESDHC_FLAG_HS200,
 };
 
-static struct esdhc_soc_data usdhc_imx6sx_data = {
+static const struct esdhc_soc_data usdhc_imx6sx_data = {
        .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
                        | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200,
 };
 
-static struct esdhc_soc_data usdhc_imx7d_data = {
+static const struct esdhc_soc_data usdhc_imx6ull_data = {
+       .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
+                       | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
+                       | ESDHC_FLAG_ERR010450,
+};
+
+static const struct esdhc_soc_data usdhc_imx7d_data = {
        .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
                        | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
                        | ESDHC_FLAG_HS400,
 };
 
+static struct esdhc_soc_data usdhc_imx8qxp_data = {
+       .flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
+                       | ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
+                       | ESDHC_FLAG_HS400 | ESDHC_FLAG_HS400_ES
+                       | ESDHC_FLAG_CQHCI,
+};
+
 struct pltfm_imx_data {
        u32 scratchpad;
        struct pinctrl *pinctrl;
@@ -227,7 +255,9 @@ static const struct of_device_id imx_esdhc_dt_ids[] = {
        { .compatible = "fsl,imx6sx-usdhc", .data = &usdhc_imx6sx_data, },
        { .compatible = "fsl,imx6sl-usdhc", .data = &usdhc_imx6sl_data, },
        { .compatible = "fsl,imx6q-usdhc", .data = &usdhc_imx6q_data, },
+       { .compatible = "fsl,imx6ull-usdhc", .data = &usdhc_imx6ull_data, },
        { .compatible = "fsl,imx7d-usdhc", .data = &usdhc_imx7d_data, },
+       { .compatible = "fsl,imx8qxp-usdhc", .data = &usdhc_imx8qxp_data, },
        { /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids);
@@ -733,6 +763,14 @@ static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
                | ESDHC_CLOCK_MASK);
        sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
 
+       if (imx_data->socdata->flags & ESDHC_FLAG_ERR010450) {
+               unsigned int max_clock;
+
+               max_clock = imx_data->is_ddr ? 45000000 : 150000000;
+
+               clock = min(clock, max_clock);
+       }
+
        while (host_clock / (16 * pre_div * ddr_pre_div) > clock &&
                        pre_div < 256)
                pre_div *= 2;
@@ -801,6 +839,20 @@ static void esdhc_pltfm_set_bus_width(struct sdhci_host *host, int width)
                        SDHCI_HOST_CONTROL);
 }
 
+static int usdhc_execute_tuning(struct mmc_host *mmc, u32 opcode)
+{
+       struct sdhci_host *host = mmc_priv(mmc);
+
+       /*
+        * i.MX uSDHC internally already uses a fixed optimized timing for
+        * DDR50, normally does not require tuning for DDR50 mode.
+        */
+       if (host->timing == MMC_TIMING_UHS_DDR50)
+               return 0;
+
+       return sdhci_execute_tuning(mmc, opcode);
+}
+
 static void esdhc_prepare_tuning(struct sdhci_host *host, u32 val)
 {
        u32 reg;
@@ -864,6 +916,19 @@ static int esdhc_executing_tuning(struct sdhci_host *host, u32 opcode)
        return ret;
 }
 
+static void esdhc_hs400_enhanced_strobe(struct mmc_host *mmc, struct mmc_ios *ios)
+{
+       struct sdhci_host *host = mmc_priv(mmc);
+       u32 m;
+
+       m = readl(host->ioaddr + ESDHC_MIX_CTRL);
+       if (ios->enhanced_strobe)
+               m |= ESDHC_MIX_CTRL_HS400_ES_EN;
+       else
+               m &= ~ESDHC_MIX_CTRL_HS400_ES_EN;
+       writel(m, host->ioaddr + ESDHC_MIX_CTRL);
+}
+
 static int esdhc_change_pinstate(struct sdhci_host *host,
                                                unsigned int uhs)
 {
@@ -905,39 +970,35 @@ static int esdhc_change_pinstate(struct sdhci_host *host,
  * edge of data_strobe line. Due to the time delay between CLK line and
  * data_strobe line, if the delay time is larger than one clock cycle,
  * then CLK and data_strobe line will be misaligned, read error shows up.
- * So when the CLK is higher than 100MHz, each clock cycle is short enough,
- * host should configure the delay target.
  */
 static void esdhc_set_strobe_dll(struct sdhci_host *host)
 {
        u32 v;
 
-       if (host->mmc->actual_clock > ESDHC_STROBE_DLL_CLK_FREQ) {
-               /* disable clock before enabling strobe dll */
-               writel(readl(host->ioaddr + ESDHC_VENDOR_SPEC) &
-                      ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
-                      host->ioaddr + ESDHC_VENDOR_SPEC);
+       /* disable clock before enabling strobe dll */
+       writel(readl(host->ioaddr + ESDHC_VENDOR_SPEC) &
+               ~ESDHC_VENDOR_SPEC_FRC_SDCLK_ON,
+               host->ioaddr + ESDHC_VENDOR_SPEC);
 
-               /* force a reset on strobe dll */
-               writel(ESDHC_STROBE_DLL_CTRL_RESET,
-                       host->ioaddr + ESDHC_STROBE_DLL_CTRL);
-               /*
-                * enable strobe dll ctrl and adjust the delay target
-                * for the uSDHC loopback read clock
-                */
-               v = ESDHC_STROBE_DLL_CTRL_ENABLE |
-                       (7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
-               writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
-               /* wait 1us to make sure strobe dll status register stable */
-               udelay(1);
-               v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
-               if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
-                       dev_warn(mmc_dev(host->mmc),
-                               "warning! HS400 strobe DLL status REF not lock!\n");
-               if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
-                       dev_warn(mmc_dev(host->mmc),
-                               "warning! HS400 strobe DLL status SLV not lock!\n");
-       }
+       /* force a reset on strobe dll */
+       writel(ESDHC_STROBE_DLL_CTRL_RESET,
+               host->ioaddr + ESDHC_STROBE_DLL_CTRL);
+       /*
+        * enable strobe dll ctrl and adjust the delay target
+        * for the uSDHC loopback read clock
+        */
+       v = ESDHC_STROBE_DLL_CTRL_ENABLE |
+               (7 << ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
+       writel(v, host->ioaddr + ESDHC_STROBE_DLL_CTRL);
+       /* wait 1us to make sure strobe dll status register stable */
+       udelay(1);
+       v = readl(host->ioaddr + ESDHC_STROBE_DLL_STATUS);
+       if (!(v & ESDHC_STROBE_DLL_STS_REF_LOCK))
+               dev_warn(mmc_dev(host->mmc),
+               "warning! HS400 strobe DLL status REF not lock!\n");
+       if (!(v & ESDHC_STROBE_DLL_STS_SLV_LOCK))
+               dev_warn(mmc_dev(host->mmc),
+               "warning! HS400 strobe DLL status SLV not lock!\n");
 }
 
 static void esdhc_reset_tuning(struct sdhci_host *host)
@@ -979,6 +1040,7 @@ static void esdhc_set_uhs_signaling(struct sdhci_host *host, unsigned timing)
        case MMC_TIMING_UHS_SDR25:
        case MMC_TIMING_UHS_SDR50:
        case MMC_TIMING_UHS_SDR104:
+       case MMC_TIMING_MMC_HS:
        case MMC_TIMING_MMC_HS200:
                writel(m, host->ioaddr + ESDHC_MIX_CTRL);
                break;
@@ -1042,6 +1104,19 @@ static void esdhc_set_timeout(struct sdhci_host *host, struct mmc_command *cmd)
                        SDHCI_TIMEOUT_CONTROL);
 }
 
+static u32 esdhc_cqhci_irq(struct sdhci_host *host, u32 intmask)
+{
+       int cmd_error = 0;
+       int data_error = 0;
+
+       if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
+               return intmask;
+
+       cqhci_irq(host->mmc, intmask, cmd_error, data_error);
+
+       return 0;
+}
+
 static struct sdhci_ops sdhci_esdhc_ops = {
        .read_l = esdhc_readl_le,
        .read_w = esdhc_readw_le,
@@ -1058,6 +1133,7 @@ static struct sdhci_ops sdhci_esdhc_ops = {
        .set_bus_width = esdhc_pltfm_set_bus_width,
        .set_uhs_signaling = esdhc_set_uhs_signaling,
        .reset = esdhc_reset,
+       .irq = esdhc_cqhci_irq,
 };
 
 static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
@@ -1106,6 +1182,23 @@ static void sdhci_esdhc_imx_hwinit(struct sdhci_host *host)
                /* disable DLL_CTRL delay line settings */
                writel(0x0, host->ioaddr + ESDHC_DLL_CTRL);
 
+               /*
+                * For the case of command with busy, if set the bit
+                * ESDHC_VEND_SPEC2_EN_BUSY_IRQ, USDHC will generate a
+                * transfer complete interrupt when busy is deasserted.
+                * When CQHCI use DCMD to send a CMD need R1b respons,
+                * CQHCI require to set ESDHC_VEND_SPEC2_EN_BUSY_IRQ,
+                * otherwise DCMD will always meet timeout waiting for
+                * hardware interrupt issue.
+                */
+               if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) {
+                       tmp = readl(host->ioaddr + ESDHC_VEND_SPEC2);
+                       tmp |= ESDHC_VEND_SPEC2_EN_BUSY_IRQ;
+                       writel(tmp, host->ioaddr + ESDHC_VEND_SPEC2);
+
+                       host->quirks &= ~SDHCI_QUIRK_NO_BUSY_IRQ;
+               }
+
                if (imx_data->socdata->flags & ESDHC_FLAG_STD_TUNING) {
                        tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL);
                        tmp |= ESDHC_STD_TUNING_EN |
@@ -1121,10 +1214,81 @@ static void sdhci_esdhc_imx_hwinit(struct sdhci_host *host)
                                        << ESDHC_TUNING_STEP_SHIFT;
                        }
                        writel(tmp, host->ioaddr + ESDHC_TUNING_CTRL);
+               } else if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING) {
+                       /*
+                        * ESDHC_STD_TUNING_EN may be configed in bootloader
+                        * or ROM code, so clear this bit here to make sure
+                        * the manual tuning can work.
+                        */
+                       tmp = readl(host->ioaddr + ESDHC_TUNING_CTRL);
+                       tmp &= ~ESDHC_STD_TUNING_EN;
+                       writel(tmp, host->ioaddr + ESDHC_TUNING_CTRL);
                }
        }
 }
 
+static void esdhc_cqe_enable(struct mmc_host *mmc)
+{
+       struct sdhci_host *host = mmc_priv(mmc);
+       struct cqhci_host *cq_host = mmc->cqe_private;
+       u32 reg;
+       u16 mode;
+       int count = 10;
+
+       /*
+        * CQE gets stuck if it sees Buffer Read Enable bit set, which can be
+        * the case after tuning, so ensure the buffer is drained.
+        */
+       reg = sdhci_readl(host, SDHCI_PRESENT_STATE);
+       while (reg & SDHCI_DATA_AVAILABLE) {
+               sdhci_readl(host, SDHCI_BUFFER);
+               reg = sdhci_readl(host, SDHCI_PRESENT_STATE);
+               if (count-- == 0) {
+                       dev_warn(mmc_dev(host->mmc),
+                               "CQE may get stuck because the Buffer Read Enable bit is set\n");
+                       break;
+               }
+               mdelay(1);
+       }
+
+       /*
+        * Runtime resume will reset the entire host controller, which
+        * will also clear the DMAEN/BCEN of register ESDHC_MIX_CTRL.
+        * Here set DMAEN and BCEN when enable CMDQ.
+        */
+       mode = sdhci_readw(host, SDHCI_TRANSFER_MODE);
+       if (host->flags & SDHCI_REQ_USE_DMA)
+               mode |= SDHCI_TRNS_DMA;
+       if (!(host->quirks2 & SDHCI_QUIRK2_SUPPORT_SINGLE))
+               mode |= SDHCI_TRNS_BLK_CNT_EN;
+       sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
+
+       /*
+        * Though Runtime resume reset the entire host controller,
+        * but do not impact the CQHCI side, need to clear the
+        * HALT bit, avoid CQHCI stuck in the first request when
+        * system resume back.
+        */
+       cqhci_writel(cq_host, 0, CQHCI_CTL);
+       if (cqhci_readl(cq_host, CQHCI_CTL) && CQHCI_HALT)
+               dev_err(mmc_dev(host->mmc),
+                       "failed to exit halt state when enable CQE\n");
+
+
+       sdhci_cqe_enable(mmc);
+}
+
+static void esdhc_sdhci_dumpregs(struct mmc_host *mmc)
+{
+       sdhci_dumpregs(mmc_priv(mmc));
+}
+
+static const struct cqhci_host_ops esdhc_cqhci_ops = {
+       .enable         = esdhc_cqe_enable,
+       .disable        = sdhci_cqe_disable,
+       .dumpregs       = esdhc_sdhci_dumpregs,
+};
+
 #ifdef CONFIG_OF
 static int
 sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
@@ -1201,7 +1365,7 @@ static int sdhci_esdhc_imx_probe_nondt(struct platform_device *pdev,
                                host->mmc->parent->platform_data);
        /* write_protect */
        if (boarddata->wp_type == ESDHC_WP_GPIO) {
-               err = mmc_gpiod_request_ro(host->mmc, "wp", 0, false, 0, NULL);
+               err = mmc_gpiod_request_ro(host->mmc, "wp", 0, 0, NULL);
                if (err) {
                        dev_err(mmc_dev(host->mmc),
                                "failed to request write-protect gpio!\n");
@@ -1256,6 +1420,7 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
                        of_match_device(imx_esdhc_dt_ids, &pdev->dev);
        struct sdhci_pltfm_host *pltfm_host;
        struct sdhci_host *host;
+       struct cqhci_host *cq_host;
        int err;
        struct pltfm_imx_data *imx_data;
 
@@ -1322,6 +1487,12 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
                writel(0x0, host->ioaddr + ESDHC_MIX_CTRL);
                writel(0x0, host->ioaddr + SDHCI_AUTO_CMD_STATUS);
                writel(0x0, host->ioaddr + ESDHC_TUNE_CTRL_STATUS);
+
+               /*
+                * Link usdhc specific mmc_host_ops execute_tuning function,
+                * to replace the standard one in sdhci_ops.
+                */
+               host->mmc_host_ops.execute_tuning = usdhc_execute_tuning;
        }
 
        if (imx_data->socdata->flags & ESDHC_FLAG_MAN_TUNING)
@@ -1334,6 +1505,28 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
        if (imx_data->socdata->flags & ESDHC_FLAG_HS400)
                host->quirks2 |= SDHCI_QUIRK2_CAPS_BIT63_FOR_HS400;
 
+       if (imx_data->socdata->flags & ESDHC_FLAG_HS400_ES) {
+               host->mmc->caps2 |= MMC_CAP2_HS400_ES;
+               host->mmc_host_ops.hs400_enhanced_strobe =
+                                       esdhc_hs400_enhanced_strobe;
+       }
+
+       if (imx_data->socdata->flags & ESDHC_FLAG_CQHCI) {
+               host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD;
+               cq_host = devm_kzalloc(&pdev->dev, sizeof(*cq_host), GFP_KERNEL);
+               if (!cq_host) {
+                       err = -ENOMEM;
+                       goto disable_ahb_clk;
+               }
+
+               cq_host->mmio = host->ioaddr + ESDHC_CQHCI_ADDR_OFFSET;
+               cq_host->ops = &esdhc_cqhci_ops;
+
+               err = cqhci_init(cq_host, host->mmc, false);
+               if (err)
+                       goto disable_ahb_clk;
+       }
+
        if (of_id)
                err = sdhci_esdhc_imx_probe_dt(pdev, host, imx_data);
        else
@@ -1341,6 +1534,8 @@ static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
        if (err)
                goto disable_ahb_clk;
 
+       host->tuning_delay = 1;
+
        sdhci_esdhc_imx_hwinit(host);
 
        err = sdhci_add_host(host);
@@ -1392,6 +1587,13 @@ static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
 static int sdhci_esdhc_suspend(struct device *dev)
 {
        struct sdhci_host *host = dev_get_drvdata(dev);
+       int ret;
+
+       if (host->mmc->caps2 & MMC_CAP2_CQE) {
+               ret = cqhci_suspend(host->mmc);
+               if (ret)
+                       return ret;
+       }
 
        if (host->tuning_mode != SDHCI_TUNING_MODE_3)
                mmc_retune_needed(host->mmc);
@@ -1402,11 +1604,19 @@ static int sdhci_esdhc_suspend(struct device *dev)
 static int sdhci_esdhc_resume(struct device *dev)
 {
        struct sdhci_host *host = dev_get_drvdata(dev);
+       int ret;
 
        /* re-initialize hw state in case it's lost in low power mode */
        sdhci_esdhc_imx_hwinit(host);
 
-       return sdhci_resume_host(host);
+       ret = sdhci_resume_host(host);
+       if (ret)
+               return ret;
+
+       if (host->mmc->caps2 & MMC_CAP2_CQE)
+               ret = cqhci_resume(host->mmc);
+
+       return ret;
 }
 #endif
 
@@ -1418,6 +1628,12 @@ static int sdhci_esdhc_runtime_suspend(struct device *dev)
        struct pltfm_imx_data *imx_data = sdhci_pltfm_priv(pltfm_host);
        int ret;
 
+       if (host->mmc->caps2 & MMC_CAP2_CQE) {
+               ret = cqhci_suspend(host->mmc);
+               if (ret)
+                       return ret;
+       }
+
        ret = sdhci_runtime_suspend_host(host);
        if (ret)
                return ret;
@@ -1461,7 +1677,10 @@ static int sdhci_esdhc_runtime_resume(struct device *dev)
        if (err)
                goto disable_ipg_clk;
 
-       return 0;
+       if (host->mmc->caps2 & MMC_CAP2_CQE)
+               err = cqhci_resume(host->mmc);
+
+       return err;
 
 disable_ipg_clk:
        if (!sdhci_sdio_irq_enabled(host))
index c11c18a9aacbdd1cf0c42a4738b6df2b61ca1f49..b1a66ca3821a51f97be942ee9596897008e64215 100644 (file)
@@ -1097,7 +1097,6 @@ static int sdhci_omap_probe(struct platform_device *pdev)
                goto err_put_sync;
        }
 
-       host->mmc_host_ops.get_ro = mmc_gpio_get_ro;
        host->mmc_host_ops.start_signal_voltage_switch =
                                        sdhci_omap_start_signal_voltage_switch;
        host->mmc_host_ops.set_ios = sdhci_omap_set_ios;
index 2a6eba74b94e01ed1a50542fda093e167ca828b2..99b0fec2836b21931b518da5cee82bd373fb004a 100644 (file)
@@ -1257,16 +1257,6 @@ static int jmicron_resume(struct sdhci_pci_chip *chip)
 }
 #endif
 
-static const struct sdhci_pci_fixes sdhci_o2 = {
-       .probe = sdhci_pci_o2_probe,
-       .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
-       .quirks2 = SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD,
-       .probe_slot = sdhci_pci_o2_probe_slot,
-#ifdef CONFIG_PM_SLEEP
-       .resume = sdhci_pci_o2_resume,
-#endif
-};
-
 static const struct sdhci_pci_fixes sdhci_jmicron = {
        .probe          = jmicron_probe,
 
index cc3ffeffd7a2e67db14309fbc3cea8c23176f5d7..05a012a694b2c6875a6189e5452b55af07fca04d 100644 (file)
 #define O2_SD_VENDOR_SETTING2  0x1C8
 #define O2_SD_HW_TUNING_DISABLE        BIT(4)
 
+#define O2_PLL_WDT_CONTROL1    0x1CC
+#define  O2_PLL_FORCE_ACTIVE   BIT(18)
+#define  O2_PLL_LOCK_STATUS    BIT(14)
+#define  O2_PLL_SOFT_RESET     BIT(12)
+
+#define O2_SD_DETECT_SETTING 0x324
+
 static void sdhci_o2_set_tuning_mode(struct sdhci_host *host)
 {
        u16 reg;
@@ -283,6 +290,113 @@ static void sdhci_pci_o2_enable_msi(struct sdhci_pci_chip *chip,
        host->irq = pci_irq_vector(chip->pdev, 0);
 }
 
+static void sdhci_o2_wait_card_detect_stable(struct sdhci_host *host)
+{
+       ktime_t timeout;
+       u32 scratch32;
+
+       /* Wait max 50 ms */
+       timeout = ktime_add_ms(ktime_get(), 50);
+       while (1) {
+               bool timedout = ktime_after(ktime_get(), timeout);
+
+               scratch32 = sdhci_readl(host, SDHCI_PRESENT_STATE);
+               if ((scratch32 & SDHCI_CARD_PRESENT) >> SDHCI_CARD_PRES_SHIFT
+                   == (scratch32 & SDHCI_CD_LVL) >> SDHCI_CD_LVL_SHIFT)
+                       break;
+
+               if (timedout) {
+                       pr_err("%s: Card Detect debounce never finished.\n",
+                              mmc_hostname(host->mmc));
+                       sdhci_dumpregs(host);
+                       return;
+               }
+               udelay(10);
+       }
+}
+
+static void sdhci_o2_enable_internal_clock(struct sdhci_host *host)
+{
+       ktime_t timeout;
+       u16 scratch;
+       u32 scratch32;
+
+       /* PLL software reset */
+       scratch32 = sdhci_readl(host, O2_PLL_WDT_CONTROL1);
+       scratch32 |= O2_PLL_SOFT_RESET;
+       sdhci_writel(host, scratch32, O2_PLL_WDT_CONTROL1);
+       udelay(1);
+       scratch32 &= ~(O2_PLL_SOFT_RESET);
+       sdhci_writel(host, scratch32, O2_PLL_WDT_CONTROL1);
+
+       /* PLL force active */
+       scratch32 |= O2_PLL_FORCE_ACTIVE;
+       sdhci_writel(host, scratch32, O2_PLL_WDT_CONTROL1);
+
+       /* Wait max 20 ms */
+       timeout = ktime_add_ms(ktime_get(), 20);
+       while (1) {
+               bool timedout = ktime_after(ktime_get(), timeout);
+
+               scratch = sdhci_readw(host, O2_PLL_WDT_CONTROL1);
+               if (scratch & O2_PLL_LOCK_STATUS)
+                       break;
+               if (timedout) {
+                       pr_err("%s: Internal clock never stabilised.\n",
+                              mmc_hostname(host->mmc));
+                       sdhci_dumpregs(host);
+                       goto out;
+               }
+               udelay(10);
+       }
+
+       /* Wait for card detect finish */
+       udelay(1);
+       sdhci_o2_wait_card_detect_stable(host);
+
+out:
+       /* Cancel PLL force active */
+       scratch32 = sdhci_readl(host, O2_PLL_WDT_CONTROL1);
+       scratch32 &= ~O2_PLL_FORCE_ACTIVE;
+       sdhci_writel(host, scratch32, O2_PLL_WDT_CONTROL1);
+}
+
+static int sdhci_o2_get_cd(struct mmc_host *mmc)
+{
+       struct sdhci_host *host = mmc_priv(mmc);
+
+       sdhci_o2_enable_internal_clock(host);
+
+       return !!(sdhci_readl(host, SDHCI_PRESENT_STATE) & SDHCI_CARD_PRESENT);
+}
+
+static void sdhci_o2_enable_clk(struct sdhci_host *host, u16 clk)
+{
+       /* Enable internal clock */
+       clk |= SDHCI_CLOCK_INT_EN;
+       sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+
+       if (sdhci_o2_get_cd(host->mmc)) {
+               clk |= SDHCI_CLOCK_CARD_EN;
+               sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
+       }
+}
+
+void sdhci_pci_o2_set_clock(struct sdhci_host *host, unsigned int clock)
+{
+       u16 clk;
+
+       host->mmc->actual_clock = 0;
+
+       sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
+
+       if (clock == 0)
+               return;
+
+       clk = sdhci_calc_clk(host, clock, &host->mmc->actual_clock);
+       sdhci_o2_enable_clk(host, clk);
+}
+
 int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot)
 {
        struct sdhci_pci_chip *chip;
@@ -314,9 +428,14 @@ int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot)
                                        mmc_hostname(host->mmc));
                                host->flags &= ~SDHCI_SIGNALING_330;
                                host->flags |= SDHCI_SIGNALING_180;
+                               host->quirks2 |= SDHCI_QUIRK2_CLEAR_TRANSFERMODE_REG_BEFORE_CMD;
                                host->mmc->caps2 |= MMC_CAP2_NO_SD;
                                host->mmc->caps2 |= MMC_CAP2_NO_SDIO;
+                               pci_write_config_dword(chip->pdev,
+                                                      O2_SD_DETECT_SETTING, 3);
                        }
+
+                       slot->host->mmc_host_ops.get_cd = sdhci_o2_get_cd;
                }
 
                host->mmc_host_ops.execute_tuning = sdhci_o2_execute_tuning;
@@ -490,9 +609,6 @@ int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip)
                pci_write_config_byte(chip->pdev, O2_SD_LOCK_WP, scratch);
                break;
        case PCI_DEVICE_ID_O2_SEABIRD0:
-               if (chip->pdev->revision == 0x01)
-                       chip->quirks |= SDHCI_QUIRK_DELAY_AFTER_POWER;
-               /* fall through */
        case PCI_DEVICE_ID_O2_SEABIRD1:
                /* UnLock WP */
                ret = pci_read_config_byte(chip->pdev,
@@ -550,3 +666,21 @@ int sdhci_pci_o2_resume(struct sdhci_pci_chip *chip)
        return sdhci_pci_resume_host(chip);
 }
 #endif
+
+static const struct sdhci_ops sdhci_pci_o2_ops = {
+       .set_clock = sdhci_pci_o2_set_clock,
+       .enable_dma = sdhci_pci_enable_dma,
+       .set_bus_width = sdhci_set_bus_width,
+       .reset = sdhci_reset,
+       .set_uhs_signaling = sdhci_set_uhs_signaling,
+};
+
+const struct sdhci_pci_fixes sdhci_o2 = {
+       .probe = sdhci_pci_o2_probe,
+       .quirks = SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC,
+       .probe_slot = sdhci_pci_o2_probe_slot,
+#ifdef CONFIG_PM_SLEEP
+       .resume = sdhci_pci_o2_resume,
+#endif
+       .ops = &sdhci_pci_o2_ops,
+};
index 2ef0bdca919743baaf51ae78d4cce8e215c5e65b..4ddb69a15cd7bba521e4d37ed2762a401b386ada 100644 (file)
@@ -179,13 +179,9 @@ static inline void *sdhci_pci_priv(struct sdhci_pci_slot *slot)
 int sdhci_pci_resume_host(struct sdhci_pci_chip *chip);
 #endif
 int sdhci_pci_enable_dma(struct sdhci_host *host);
-int sdhci_pci_o2_probe_slot(struct sdhci_pci_slot *slot);
-int sdhci_pci_o2_probe(struct sdhci_pci_chip *chip);
-#ifdef CONFIG_PM_SLEEP
-int sdhci_pci_o2_resume(struct sdhci_pci_chip *chip);
-#endif
 
 extern const struct sdhci_pci_fixes sdhci_arasan;
 extern const struct sdhci_pci_fixes sdhci_snps;
+extern const struct sdhci_pci_fixes sdhci_o2;
 
 #endif /* __SDHCI_PCI_H */
index 2c3827f54927e5658fc8e12cc70c4ede0e47c3c2..cdc8e16b45673ad9a5d8b02e94e6bb7805b71ce0 100644 (file)
@@ -23,7 +23,6 @@
 #include <linux/clk.h>
 #include <linux/module.h>
 #include <linux/io.h>
-#include <linux/gpio.h>
 #include <linux/mmc/card.h>
 #include <linux/mmc/host.h>
 #include <linux/platform_data/pxa_sdhci.h>
index e6ace31e2a418cc80e0df72eb66f89d1119c26ca..32e62904c0d3c8c0fdaf6316ef630f32d4987553 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/ktime.h>
 
 #include "sdhci-pltfm.h"
+#include "cqhci.h"
 
 /* Tegra SDHOST controller vendor register definitions */
 #define SDHCI_TEGRA_VENDOR_CLOCK_CTRL                  0x100
@@ -75,6 +76,7 @@
 #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_MASK   0x0000000f
 #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_VREF_SEL_VAL    0x7
 #define SDHCI_TEGRA_SDMEM_COMP_PADCTRL_E_INPUT_E_PWRD  BIT(31)
+#define SDHCI_COMP_PADCTRL_DRVUPDN_OFFSET_MASK         0x07FFF000
 
 #define SDHCI_TEGRA_AUTO_CAL_STATUS                    0x1ec
 #define SDHCI_TEGRA_AUTO_CAL_ACTIVE                    BIT(31)
@@ -89,6 +91,9 @@
 #define NVQUIRK_NEEDS_PAD_CONTROL                      BIT(7)
 #define NVQUIRK_DIS_CARD_CLK_CONFIG_TAP                        BIT(8)
 
+/* SDMMC CQE Base Address for Tegra Host Ver 4.1 and Higher */
+#define SDHCI_TEGRA_CQE_BASE_ADDR                      0xF000
+
 struct sdhci_tegra_soc_data {
        const struct sdhci_pltfm_data *pdata;
        u32 nvquirks;
@@ -121,6 +126,8 @@ struct sdhci_tegra {
        struct pinctrl *pinctrl_sdmmc;
        struct pinctrl_state *pinctrl_state_3v3;
        struct pinctrl_state *pinctrl_state_1v8;
+       struct pinctrl_state *pinctrl_state_3v3_drv;
+       struct pinctrl_state *pinctrl_state_1v8_drv;
 
        struct sdhci_tegra_autocal_offsets autocal_offsets;
        ktime_t last_calib;
@@ -128,6 +135,7 @@ struct sdhci_tegra {
        u32 default_tap;
        u32 default_trim;
        u32 dqs_trim;
+       bool enable_hwcq;
 };
 
 static u16 tegra_sdhci_readw(struct sdhci_host *host, int reg)
@@ -237,11 +245,6 @@ static void tegra210_sdhci_writew(struct sdhci_host *host, u16 val, int reg)
        }
 }
 
-static unsigned int tegra_sdhci_get_ro(struct sdhci_host *host)
-{
-       return mmc_gpio_get_ro(host->mmc);
-}
-
 static bool tegra_sdhci_is_pad_and_regulator_valid(struct sdhci_host *host)
 {
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -411,6 +414,76 @@ static void tegra_sdhci_set_pad_autocal_offset(struct sdhci_host *host,
        sdhci_writel(host, reg, SDHCI_TEGRA_AUTO_CAL_CONFIG);
 }
 
+static int tegra_sdhci_set_padctrl(struct sdhci_host *host, int voltage,
+                                  bool state_drvupdn)
+{
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+       struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
+       struct sdhci_tegra_autocal_offsets *offsets =
+                                               &tegra_host->autocal_offsets;
+       struct pinctrl_state *pinctrl_drvupdn = NULL;
+       int ret = 0;
+       u8 drvup = 0, drvdn = 0;
+       u32 reg;
+
+       if (!state_drvupdn) {
+               /* PADS Drive Strength */
+               if (voltage == MMC_SIGNAL_VOLTAGE_180) {
+                       if (tegra_host->pinctrl_state_1v8_drv) {
+                               pinctrl_drvupdn =
+                                       tegra_host->pinctrl_state_1v8_drv;
+                       } else {
+                               drvup = offsets->pull_up_1v8_timeout;
+                               drvdn = offsets->pull_down_1v8_timeout;
+                       }
+               } else {
+                       if (tegra_host->pinctrl_state_3v3_drv) {
+                               pinctrl_drvupdn =
+                                       tegra_host->pinctrl_state_3v3_drv;
+                       } else {
+                               drvup = offsets->pull_up_3v3_timeout;
+                               drvdn = offsets->pull_down_3v3_timeout;
+                       }
+               }
+
+               if (pinctrl_drvupdn != NULL) {
+                       ret = pinctrl_select_state(tegra_host->pinctrl_sdmmc,
+                                                       pinctrl_drvupdn);
+                       if (ret < 0)
+                               dev_err(mmc_dev(host->mmc),
+                                       "failed pads drvupdn, ret: %d\n", ret);
+               } else if ((drvup) || (drvdn)) {
+                       reg = sdhci_readl(host,
+                                       SDHCI_TEGRA_SDMEM_COMP_PADCTRL);
+                       reg &= ~SDHCI_COMP_PADCTRL_DRVUPDN_OFFSET_MASK;
+                       reg |= (drvup << 20) | (drvdn << 12);
+                       sdhci_writel(host, reg,
+                                       SDHCI_TEGRA_SDMEM_COMP_PADCTRL);
+               }
+
+       } else {
+               /* Dual Voltage PADS Voltage selection */
+               if (!tegra_host->pad_control_available)
+                       return 0;
+
+               if (voltage == MMC_SIGNAL_VOLTAGE_180) {
+                       ret = pinctrl_select_state(tegra_host->pinctrl_sdmmc,
+                                               tegra_host->pinctrl_state_1v8);
+                       if (ret < 0)
+                               dev_err(mmc_dev(host->mmc),
+                                       "setting 1.8V failed, ret: %d\n", ret);
+               } else {
+                       ret = pinctrl_select_state(tegra_host->pinctrl_sdmmc,
+                                               tegra_host->pinctrl_state_3v3);
+                       if (ret < 0)
+                               dev_err(mmc_dev(host->mmc),
+                                       "setting 3.3V failed, ret: %d\n", ret);
+               }
+       }
+
+       return ret;
+}
+
 static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
 {
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -437,6 +510,7 @@ static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
                        pdpu = offsets.pull_down_3v3 << 8 | offsets.pull_up_3v3;
        }
 
+       /* Set initial offset before auto-calibration */
        tegra_sdhci_set_pad_autocal_offset(host, pdpu);
 
        card_clk_enabled = tegra_sdhci_configure_card_clk(host, false);
@@ -460,19 +534,15 @@ static void tegra_sdhci_pad_autocalib(struct sdhci_host *host)
        if (ret) {
                dev_err(mmc_dev(host->mmc), "Pad autocal timed out\n");
 
-               if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)
-                       pdpu = offsets.pull_down_1v8_timeout << 8 |
-                              offsets.pull_up_1v8_timeout;
-               else
-                       pdpu = offsets.pull_down_3v3_timeout << 8 |
-                              offsets.pull_up_3v3_timeout;
-
-               /* Disable automatic calibration and use fixed offsets */
+               /* Disable automatic cal and use fixed Drive Strengths */
                reg = sdhci_readl(host, SDHCI_TEGRA_AUTO_CAL_CONFIG);
                reg &= ~SDHCI_AUTO_CAL_ENABLE;
                sdhci_writel(host, reg, SDHCI_TEGRA_AUTO_CAL_CONFIG);
 
-               tegra_sdhci_set_pad_autocal_offset(host, pdpu);
+               ret = tegra_sdhci_set_padctrl(host, ios->signal_voltage, false);
+               if (ret < 0)
+                       dev_err(mmc_dev(host->mmc),
+                               "Setting drive strengths failed: %d\n", ret);
        }
 }
 
@@ -511,26 +581,46 @@ static void tegra_sdhci_parse_pad_autocal_dt(struct sdhci_host *host)
        err = device_property_read_u32(host->mmc->parent,
                        "nvidia,pad-autocal-pull-up-offset-3v3-timeout",
                        &autocal->pull_up_3v3_timeout);
-       if (err)
+       if (err) {
+               if (!IS_ERR(tegra_host->pinctrl_state_3v3) &&
+                       (tegra_host->pinctrl_state_3v3_drv == NULL))
+                       pr_warn("%s: Missing autocal timeout 3v3-pad drvs\n",
+                               mmc_hostname(host->mmc));
                autocal->pull_up_3v3_timeout = 0;
+       }
 
        err = device_property_read_u32(host->mmc->parent,
                        "nvidia,pad-autocal-pull-down-offset-3v3-timeout",
                        &autocal->pull_down_3v3_timeout);
-       if (err)
+       if (err) {
+               if (!IS_ERR(tegra_host->pinctrl_state_3v3) &&
+                       (tegra_host->pinctrl_state_3v3_drv == NULL))
+                       pr_warn("%s: Missing autocal timeout 3v3-pad drvs\n",
+                               mmc_hostname(host->mmc));
                autocal->pull_down_3v3_timeout = 0;
+       }
 
        err = device_property_read_u32(host->mmc->parent,
                        "nvidia,pad-autocal-pull-up-offset-1v8-timeout",
                        &autocal->pull_up_1v8_timeout);
-       if (err)
+       if (err) {
+               if (!IS_ERR(tegra_host->pinctrl_state_1v8) &&
+                       (tegra_host->pinctrl_state_1v8_drv == NULL))
+                       pr_warn("%s: Missing autocal timeout 1v8-pad drvs\n",
+                               mmc_hostname(host->mmc));
                autocal->pull_up_1v8_timeout = 0;
+       }
 
        err = device_property_read_u32(host->mmc->parent,
                        "nvidia,pad-autocal-pull-down-offset-1v8-timeout",
                        &autocal->pull_down_1v8_timeout);
-       if (err)
+       if (err) {
+               if (!IS_ERR(tegra_host->pinctrl_state_1v8) &&
+                       (tegra_host->pinctrl_state_1v8_drv == NULL))
+                       pr_warn("%s: Missing autocal timeout 1v8-pad drvs\n",
+                               mmc_hostname(host->mmc));
                autocal->pull_down_1v8_timeout = 0;
+       }
 
        err = device_property_read_u32(host->mmc->parent,
                        "nvidia,pad-autocal-pull-up-offset-sdr104",
@@ -595,6 +685,20 @@ static void tegra_sdhci_parse_tap_and_trim(struct sdhci_host *host)
                tegra_host->dqs_trim = 0x11;
 }
 
+static void tegra_sdhci_parse_dt(struct sdhci_host *host)
+{
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+       struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
+
+       if (device_property_read_bool(host->mmc->parent, "supports-cqe"))
+               tegra_host->enable_hwcq = true;
+       else
+               tegra_host->enable_hwcq = false;
+
+       tegra_sdhci_parse_pad_autocal_dt(host);
+       tegra_sdhci_parse_tap_and_trim(host);
+}
+
 static void tegra_sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
 {
        struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
@@ -743,32 +847,6 @@ static int tegra_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
        return mmc_send_tuning(host->mmc, opcode, NULL);
 }
 
-static int tegra_sdhci_set_padctrl(struct sdhci_host *host, int voltage)
-{
-       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
-       struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
-       int ret;
-
-       if (!tegra_host->pad_control_available)
-               return 0;
-
-       if (voltage == MMC_SIGNAL_VOLTAGE_180) {
-               ret = pinctrl_select_state(tegra_host->pinctrl_sdmmc,
-                                          tegra_host->pinctrl_state_1v8);
-               if (ret < 0)
-                       dev_err(mmc_dev(host->mmc),
-                               "setting 1.8V failed, ret: %d\n", ret);
-       } else {
-               ret = pinctrl_select_state(tegra_host->pinctrl_sdmmc,
-                                          tegra_host->pinctrl_state_3v3);
-               if (ret < 0)
-                       dev_err(mmc_dev(host->mmc),
-                               "setting 3.3V failed, ret: %d\n", ret);
-       }
-
-       return ret;
-}
-
 static int sdhci_tegra_start_signal_voltage_switch(struct mmc_host *mmc,
                                                   struct mmc_ios *ios)
 {
@@ -778,7 +856,7 @@ static int sdhci_tegra_start_signal_voltage_switch(struct mmc_host *mmc,
        int ret = 0;
 
        if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
-               ret = tegra_sdhci_set_padctrl(host, ios->signal_voltage);
+               ret = tegra_sdhci_set_padctrl(host, ios->signal_voltage, true);
                if (ret < 0)
                        return ret;
                ret = sdhci_start_signal_voltage_switch(mmc, ios);
@@ -786,7 +864,7 @@ static int sdhci_tegra_start_signal_voltage_switch(struct mmc_host *mmc,
                ret = sdhci_start_signal_voltage_switch(mmc, ios);
                if (ret < 0)
                        return ret;
-               ret = tegra_sdhci_set_padctrl(host, ios->signal_voltage);
+               ret = tegra_sdhci_set_padctrl(host, ios->signal_voltage, true);
        }
 
        if (tegra_host->pad_calib_required)
@@ -805,6 +883,20 @@ static int tegra_sdhci_init_pinctrl_info(struct device *dev,
                return -1;
        }
 
+       tegra_host->pinctrl_state_1v8_drv = pinctrl_lookup_state(
+                               tegra_host->pinctrl_sdmmc, "sdmmc-1v8-drv");
+       if (IS_ERR(tegra_host->pinctrl_state_1v8_drv)) {
+               if (PTR_ERR(tegra_host->pinctrl_state_1v8_drv) == -ENODEV)
+                       tegra_host->pinctrl_state_1v8_drv = NULL;
+       }
+
+       tegra_host->pinctrl_state_3v3_drv = pinctrl_lookup_state(
+                               tegra_host->pinctrl_sdmmc, "sdmmc-3v3-drv");
+       if (IS_ERR(tegra_host->pinctrl_state_3v3_drv)) {
+               if (PTR_ERR(tegra_host->pinctrl_state_3v3_drv) == -ENODEV)
+                       tegra_host->pinctrl_state_3v3_drv = NULL;
+       }
+
        tegra_host->pinctrl_state_3v3 =
                pinctrl_lookup_state(tegra_host->pinctrl_sdmmc, "sdmmc-3v3");
        if (IS_ERR(tegra_host->pinctrl_state_3v3)) {
@@ -836,8 +928,50 @@ static void tegra_sdhci_voltage_switch(struct sdhci_host *host)
                tegra_host->pad_calib_required = true;
 }
 
+static void sdhci_tegra_cqe_enable(struct mmc_host *mmc)
+{
+       struct cqhci_host *cq_host = mmc->cqe_private;
+       u32 cqcfg = 0;
+
+       /*
+        * Tegra SDMMC Controller design prevents write access to BLOCK_COUNT
+        * registers when CQE is enabled.
+        */
+       cqcfg = cqhci_readl(cq_host, CQHCI_CFG);
+       if (cqcfg & CQHCI_ENABLE)
+               cqhci_writel(cq_host, (cqcfg & ~CQHCI_ENABLE), CQHCI_CFG);
+
+       sdhci_cqe_enable(mmc);
+
+       if (cqcfg & CQHCI_ENABLE)
+               cqhci_writel(cq_host, cqcfg, CQHCI_CFG);
+}
+
+static void sdhci_tegra_dumpregs(struct mmc_host *mmc)
+{
+       sdhci_dumpregs(mmc_priv(mmc));
+}
+
+static u32 sdhci_tegra_cqhci_irq(struct sdhci_host *host, u32 intmask)
+{
+       int cmd_error = 0;
+       int data_error = 0;
+
+       if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
+               return intmask;
+
+       cqhci_irq(host->mmc, intmask, cmd_error, data_error);
+
+       return 0;
+}
+
+static const struct cqhci_host_ops sdhci_tegra_cqhci_ops = {
+       .enable = sdhci_tegra_cqe_enable,
+       .disable = sdhci_cqe_disable,
+       .dumpregs = sdhci_tegra_dumpregs,
+};
+
 static const struct sdhci_ops tegra_sdhci_ops = {
-       .get_ro     = tegra_sdhci_get_ro,
        .read_w     = tegra_sdhci_readw,
        .write_l    = tegra_sdhci_writel,
        .set_clock  = tegra_sdhci_set_clock,
@@ -893,7 +1027,6 @@ static const struct sdhci_tegra_soc_data soc_data_tegra30 = {
 };
 
 static const struct sdhci_ops tegra114_sdhci_ops = {
-       .get_ro     = tegra_sdhci_get_ro,
        .read_w     = tegra_sdhci_readw,
        .write_w    = tegra_sdhci_writew,
        .write_l    = tegra_sdhci_writel,
@@ -947,7 +1080,6 @@ static const struct sdhci_tegra_soc_data soc_data_tegra124 = {
 };
 
 static const struct sdhci_ops tegra210_sdhci_ops = {
-       .get_ro     = tegra_sdhci_get_ro,
        .read_w     = tegra_sdhci_readw,
        .write_w    = tegra210_sdhci_writew,
        .write_l    = tegra_sdhci_writel,
@@ -980,7 +1112,6 @@ static const struct sdhci_tegra_soc_data soc_data_tegra210 = {
 };
 
 static const struct sdhci_ops tegra186_sdhci_ops = {
-       .get_ro     = tegra_sdhci_get_ro,
        .read_w     = tegra_sdhci_readw,
        .write_l    = tegra_sdhci_writel,
        .set_clock  = tegra_sdhci_set_clock,
@@ -989,6 +1120,7 @@ static const struct sdhci_ops tegra186_sdhci_ops = {
        .set_uhs_signaling = tegra_sdhci_set_uhs_signaling,
        .voltage_switch = tegra_sdhci_voltage_switch,
        .get_max_clock = tegra_sdhci_get_max_clock,
+       .irq = sdhci_tegra_cqhci_irq,
 };
 
 static const struct sdhci_pltfm_data sdhci_tegra186_pdata = {
@@ -1030,6 +1162,54 @@ static const struct of_device_id sdhci_tegra_dt_match[] = {
 };
 MODULE_DEVICE_TABLE(of, sdhci_tegra_dt_match);
 
+static int sdhci_tegra_add_host(struct sdhci_host *host)
+{
+       struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+       struct sdhci_tegra *tegra_host = sdhci_pltfm_priv(pltfm_host);
+       struct cqhci_host *cq_host;
+       bool dma64;
+       int ret;
+
+       if (!tegra_host->enable_hwcq)
+               return sdhci_add_host(host);
+
+       sdhci_enable_v4_mode(host);
+
+       ret = sdhci_setup_host(host);
+       if (ret)
+               return ret;
+
+       host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD;
+
+       cq_host = devm_kzalloc(host->mmc->parent,
+                               sizeof(*cq_host), GFP_KERNEL);
+       if (!cq_host) {
+               ret = -ENOMEM;
+               goto cleanup;
+       }
+
+       cq_host->mmio = host->ioaddr + SDHCI_TEGRA_CQE_BASE_ADDR;
+       cq_host->ops = &sdhci_tegra_cqhci_ops;
+
+       dma64 = host->flags & SDHCI_USE_64_BIT_DMA;
+       if (dma64)
+               cq_host->caps |= CQHCI_TASK_DESC_SZ_128;
+
+       ret = cqhci_init(cq_host, host->mmc, dma64);
+       if (ret)
+               goto cleanup;
+
+       ret = __sdhci_add_host(host);
+       if (ret)
+               goto cleanup;
+
+       return 0;
+
+cleanup:
+       sdhci_cleanup_host(host);
+       return ret;
+}
+
 static int sdhci_tegra_probe(struct platform_device *pdev)
 {
        const struct of_device_id *match;
@@ -1077,9 +1257,7 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
        if (tegra_host->soc_data->nvquirks & NVQUIRK_ENABLE_DDR50)
                host->mmc->caps |= MMC_CAP_1_8V_DDR;
 
-       tegra_sdhci_parse_pad_autocal_dt(host);
-
-       tegra_sdhci_parse_tap_and_trim(host);
+       tegra_sdhci_parse_dt(host);
 
        tegra_host->power_gpio = devm_gpiod_get_optional(&pdev->dev, "power",
                                                         GPIOD_OUT_HIGH);
@@ -1117,7 +1295,7 @@ static int sdhci_tegra_probe(struct platform_device *pdev)
 
        usleep_range(2000, 4000);
 
-       rc = sdhci_add_host(host);
+       rc = sdhci_tegra_add_host(host);
        if (rc)
                goto err_add_host;
 
index 5b5eb53a63d281b27c28979b40c8c27d22a7a2ec..8d07ee1b8f08704ee0f99633f751552d64e3f085 100644 (file)
@@ -530,7 +530,7 @@ static bool xenon_emmc_phy_slow_mode(struct sdhci_host *host,
                        ret = true;
                        break;
                }
-               /* else: fall through */
+               /* fall through */
        default:
                reg &= ~XENON_TIMING_ADJUST_SLOW_MODE;
                ret = false;
index eba9bcc92ad3c74a51b7e7d998c9a9c4ec90ae90..a8141ff9be038b4e97aabd16bf63c3ce9b3a2518 100644 (file)
@@ -883,7 +883,7 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd,
                             bool *too_big)
 {
        u8 count;
-       struct mmc_data *data = cmd->data;
+       struct mmc_data *data;
        unsigned target_timeout, current_timeout;
 
        *too_big = true;
@@ -897,6 +897,11 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_command *cmd,
        if (host->quirks & SDHCI_QUIRK_BROKEN_TIMEOUT_VAL)
                return 0xE;
 
+       /* Unspecified command, asume max */
+       if (cmd == NULL)
+               return 0xE;
+
+       data = cmd->data;
        /* Unspecified timeout, assume max */
        if (!data && !cmd->busy_timeout)
                return 0xE;
@@ -2048,6 +2053,8 @@ static int sdhci_check_ro(struct sdhci_host *host)
                is_readonly = 0;
        else if (host->ops->get_ro)
                is_readonly = host->ops->get_ro(host);
+       else if (mmc_can_gpio_ro(host->mmc))
+               is_readonly = mmc_gpio_get_ro(host->mmc);
        else
                is_readonly = !(sdhci_readl(host, SDHCI_PRESENT_STATE)
                                & SDHCI_WRITE_PROTECT);
@@ -2376,6 +2383,10 @@ static int __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
                        return -ETIMEDOUT;
                }
 
+               /* Spec does not require a delay between tuning cycles */
+               if (host->tuning_delay > 0)
+                       mdelay(host->tuning_delay);
+
                ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
                if (!(ctrl & SDHCI_CTRL_EXEC_TUNING)) {
                        if (ctrl & SDHCI_CTRL_TUNED_CLK)
@@ -2383,9 +2394,6 @@ static int __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
                        break;
                }
 
-               /* Spec does not require a delay between tuning cycles */
-               if (host->tuning_delay > 0)
-                       mdelay(host->tuning_delay);
        }
 
        pr_info("%s: Tuning failed, falling back to fixed sampling clock\n",
@@ -3353,7 +3361,14 @@ void sdhci_cqe_enable(struct mmc_host *mmc)
 
        ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
        ctrl &= ~SDHCI_CTRL_DMA_MASK;
-       if (host->flags & SDHCI_USE_64_BIT_DMA)
+       /*
+        * Host from V4.10 supports ADMA3 DMA type.
+        * ADMA3 performs integrated descriptor which is more suitable
+        * for cmd queuing to fetch both command and transfer descriptors.
+        */
+       if (host->v4_mode && (host->caps1 & SDHCI_CAN_DO_ADMA3))
+               ctrl |= SDHCI_CTRL_ADMA3;
+       else if (host->flags & SDHCI_USE_64_BIT_DMA)
                ctrl |= SDHCI_CTRL_ADMA64;
        else
                ctrl |= SDHCI_CTRL_ADMA32;
@@ -3363,7 +3378,7 @@ void sdhci_cqe_enable(struct mmc_host *mmc)
                     SDHCI_BLOCK_SIZE);
 
        /* Set maximum timeout */
-       sdhci_writeb(host, 0xE, SDHCI_TIMEOUT_CONTROL);
+       sdhci_set_timeout(host, NULL);
 
        host->ier = host->cqe_ier;
 
index 6cc9a3c2ac66c6d75e91511aa0332b901828caa9..01002cba1359404a9a7c2555bc30d206abe4aa69 100644 (file)
 #define  SDHCI_SPACE_AVAILABLE 0x00000400
 #define  SDHCI_DATA_AVAILABLE  0x00000800
 #define  SDHCI_CARD_PRESENT    0x00010000
+#define   SDHCI_CARD_PRES_SHIFT        16
+#define  SDHCI_CD_STABLE       0x00020000
+#define  SDHCI_CD_LVL          0x00040000
+#define   SDHCI_CD_LVL_SHIFT   18
 #define  SDHCI_WRITE_PROTECT   0x00080000
 #define  SDHCI_DATA_LVL_MASK   0x00F00000
 #define   SDHCI_DATA_LVL_SHIFT 20
@@ -88,6 +92,7 @@
 #define   SDHCI_CTRL_ADMA1     0x08
 #define   SDHCI_CTRL_ADMA32    0x10
 #define   SDHCI_CTRL_ADMA64    0x18
+#define   SDHCI_CTRL_ADMA3     0x18
 #define   SDHCI_CTRL_8BITBUS   0x20
 #define  SDHCI_CTRL_CDTEST_INS 0x40
 #define  SDHCI_CTRL_CDTEST_EN  0x80
 #define  SDHCI_RETUNING_MODE_SHIFT             14
 #define  SDHCI_CLOCK_MUL_MASK  0x00FF0000
 #define  SDHCI_CLOCK_MUL_SHIFT 16
+#define  SDHCI_CAN_DO_ADMA3    0x08000000
 #define  SDHCI_SUPPORT_HS400   0x80000000 /* Non-standard */
 
 #define SDHCI_CAPABILITIES_1   0x44
index 8c05879850a066e63da822ffe1c1e51307c1fcbc..eea183e90f1bab49e189a320ac7934233cdc20e1 100644 (file)
@@ -158,7 +158,7 @@ static void sdhci_am654_set_power(struct sdhci_host *host, unsigned char mode,
        sdhci_set_power_noreg(host, mode, vdd);
 }
 
-struct sdhci_ops sdhci_am654_ops = {
+static struct sdhci_ops sdhci_am654_ops = {
        .get_max_clock = sdhci_pltfm_clk_get_max_clock,
        .get_timeout_clock = sdhci_pltfm_clk_get_max_clock,
        .set_uhs_signaling = sdhci_set_uhs_signaling,
index 70fadc9767955c66fca6980d288ae32c260e2720..2901a5773d83cf9370ab049bc83fd1fb56359c31 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/err.h>
-#include <linux/gpio.h>
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/kernel.h>
@@ -32,7 +31,6 @@
 #include <linux/mmc/slot-gpio.h>
 #include <linux/module.h>
 #include <linux/of_address.h>
-#include <linux/of_gpio.h>
 #include <linux/of_platform.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
index f7a6f005899a351ace1b5b3ecf8c8dca702e157e..595949f1f00110270db78a3b957515767f4c26ed 100644 (file)
@@ -1073,7 +1073,7 @@ static int tmio_mmc_init_ocr(struct tmio_mmc_host *host)
 
        /* use ocr_mask if no regulator */
        if (!mmc->ocr_avail)
-               mmc->ocr_avail =  pdata->ocr_mask;
+               mmc->ocr_avail = pdata->ocr_mask;
 
        /*
         * try again.
@@ -1294,6 +1294,7 @@ void tmio_mmc_host_remove(struct tmio_mmc_host *host)
        cancel_delayed_work_sync(&host->delayed_reset_work);
        tmio_mmc_release_dma(host);
 
+       pm_runtime_dont_use_autosuspend(&pdev->dev);
        pm_runtime_put_sync(&pdev->dev);
        pm_runtime_disable(&pdev->dev);
 }
index 3ba42f50801435356973eabcbf1bb07108f9ffce..4fd6da29489e29644fe6d3a963c21180df7a8d76 100644 (file)
@@ -19,7 +19,6 @@
 #include <linux/io.h>
 #include <linux/irq.h>
 #include <linux/clk.h>
-#include <linux/gpio.h>
 #include <linux/interrupt.h>
 
 #include <linux/of.h>
index 8ef330027b134eb9ea073f5d4e9ac82d1d1bfc29..19566ab9decb4a86c5643ee9415129411c5090fa 100644 (file)
@@ -133,6 +133,8 @@ struct mmc_ext_csd {
 struct sd_scr {
        unsigned char           sda_vsn;
        unsigned char           sda_spec3;
+       unsigned char           sda_spec4;
+       unsigned char           sda_specx;
        unsigned char           bus_widths;
 #define SD_SCR_BUS_WIDTH_1     (1<<0)
 #define SD_SCR_BUS_WIDTH_4     (1<<2)
@@ -277,6 +279,7 @@ struct mmc_card {
        unsigned int            erase_shift;    /* if erase unit is power 2 */
        unsigned int            pref_erase;     /* in sectors */
        unsigned int            eg_boundary;    /* don't cross erase-group boundaries */
+       unsigned int            erase_arg;      /* erase / trim / discard */
        u8                      erased_byte;    /* value of erased bytes */
 
        u32                     raw_cid[4];     /* raw card CID */
index 4d35ff36ceffa7aa5daaa8b42e2d9a3a0e3bf84d..43d0f0c496f661880e19a19fff8a651148442d60 100644 (file)
@@ -478,6 +478,11 @@ static inline void *mmc_priv(struct mmc_host *host)
        return (void *)host->private;
 }
 
+static inline struct mmc_host *mmc_from_priv(void *priv)
+{
+       return container_of(priv, struct mmc_host, private);
+}
+
 #define mmc_host_is_spi(host)  ((host)->caps & MMC_CAP_SPI)
 
 #define mmc_dev(x)     ((x)->parent)
@@ -502,17 +507,11 @@ void sdio_run_irqs(struct mmc_host *host);
 void sdio_signal_irq(struct mmc_host *host);
 
 #ifdef CONFIG_REGULATOR
-int mmc_regulator_get_ocrmask(struct regulator *supply);
 int mmc_regulator_set_ocr(struct mmc_host *mmc,
                        struct regulator *supply,
                        unsigned short vdd_bit);
 int mmc_regulator_set_vqmmc(struct mmc_host *mmc, struct mmc_ios *ios);
 #else
-static inline int mmc_regulator_get_ocrmask(struct regulator *supply)
-{
-       return 0;
-}
-
 static inline int mmc_regulator_set_ocr(struct mmc_host *mmc,
                                 struct regulator *supply,
                                 unsigned short vdd_bit)
@@ -527,7 +526,6 @@ static inline int mmc_regulator_set_vqmmc(struct mmc_host *mmc,
 }
 #endif
 
-u32 mmc_vddrange_to_ocrmask(int vdd_min, int vdd_max);
 int mmc_regulator_get_supply(struct mmc_host *mmc);
 
 static inline int mmc_card_is_removable(struct mmc_host *host)
index 1ebcf9ba1256a0e9cdaeb5efdee1adb747723bc4..ec94a5aa02bb7b0a41aad3ceace9f9320d82f38c 100644 (file)
 #define SD_SWITCH_ACCESS_DEF   0
 #define SD_SWITCH_ACCESS_HS    1
 
+/*
+ * Erase/discard
+ */
+#define SD_ERASE_ARG                   0x00000000
+#define SD_DISCARD_ARG                 0x00000001
+
 #endif /* LINUX_MMC_SD_H */
index feebd7aa6f5c16abdd81548bd6502dc5d9c04794..9fd3ce64a885c84bb2afc0aa7b04d12f46c1dd4f 100644 (file)
@@ -22,7 +22,7 @@ int mmc_gpiod_request_cd(struct mmc_host *host, const char *con_id,
                         unsigned int idx, bool override_active_level,
                         unsigned int debounce, bool *gpio_invert);
 int mmc_gpiod_request_ro(struct mmc_host *host, const char *con_id,
-                        unsigned int idx, bool override_active_level,
+                        unsigned int idx,
                         unsigned int debounce, bool *gpio_invert);
 void mmc_gpio_set_cd_isr(struct mmc_host *host,
                         irqreturn_t (*isr)(int irq, void *dev_id));