diff options
Diffstat (limited to 'drivers/mmc')
65 files changed, 285 insertions, 159 deletions
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 06e32e75696..d0944793c92 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -147,9 +147,16 @@ config SPL_MMC_IO_VOLTAGE support. For eMMC this not mandatory, but not enabling this option may prevent the driver of using the faster modes. +config MMC_SUPPORTS_TUNING + bool + +config SPL_MMC_SUPPORTS_TUNING + bool + config MMC_UHS_SUPPORT bool "enable UHS support" depends on MMC_IO_VOLTAGE + select MMC_SUPPORTS_TUNING help The Ultra High Speed (UHS) bus is available on some SDHC and SDXC cards. The IO voltage must be switchable from 3.3v to 1.8v. The bus @@ -158,6 +165,7 @@ config MMC_UHS_SUPPORT config SPL_MMC_UHS_SUPPORT bool "enable UHS support in SPL" depends on SPL_MMC_IO_VOLTAGE + select SPL_MMC_SUPPORTS_TUNING help The Ultra High Speed (UHS) bus is available on some SDHC and SDXC cards. The IO voltage must be switchable from 3.3v to 1.8v. The bus @@ -193,6 +201,7 @@ config SPL_MMC_HS400_SUPPORT config MMC_HS200_SUPPORT bool "enable HS200 support" + select MMC_SUPPORTS_TUNING help The HS200 mode is support by some eMMC. The bus frequency is up to 200MHz. This mode requires tuning the IO. @@ -200,6 +209,7 @@ config MMC_HS200_SUPPORT config SPL_MMC_HS200_SUPPORT bool "enable HS200 support in SPL" depends on SPL_MMC + select SPL_MMC_SUPPORTS_TUNING help The HS200 mode is support by some eMMC. The bus frequency is up to 200MHz. This mode requires tuning the IO. @@ -347,6 +357,7 @@ config MMC_OCTEONTX bool "Marvell Octeon Multimedia Card Interface support" depends on (ARCH_OCTEON || ARCH_OCTEONTX || ARCH_OCTEONTX2) depends on DM_MMC + select MMC_SUPPORTS_TUNING if ARCH_OCTEONTX2 help This selects the Octeon Multimedia card Interface. If you have an OcteonTX/TX2 or MIPS Octeon board with a @@ -504,6 +515,24 @@ config SPL_MMC_SDHCI_ADMA This enables support for the ADMA (Advanced DMA) defined in the SD Host Controller Standard Specification Version 3.00 in SPL. +config MMC_SDHCI_ADMA_FORCE_32BIT + bool "Force 32 bit mode for ADMA on 64 bit platforms" + help + This forces SDHCI ADMA to be built for 32 bit descriptors, even + on a 64 bit platform where they would otherwise be assumed to + be 64 bits. This is necessary for certain hardware platforms + that are 64-bit but include only 32-bit support within the selected + SD host controller IP. + +config MMC_SDHCI_ADMA_64BIT + bool "Use SHDCI ADMA with 64 bit descriptors" + depends on !MMC_SDHCI_ADMA_FORCE_32BIT + default y if DMA_ADDR_T_64BIT + help + This selects 64 bit descriptors for SDHCI ADMA. It is enabled by + default on 64 bit systems, but can be disabled if one of these + systems includes 32-bit ADMA. + config FIXED_SDHCI_ALIGNED_BUFFER hex "SDRAM address for fixed buffer" depends on SPL && MVEBU_SPL_BOOT_DEVICE_MMC diff --git a/drivers/mmc/am654_sdhci.c b/drivers/mmc/am654_sdhci.c index 2139fea04d5..48fac7a11b4 100644 --- a/drivers/mmc/am654_sdhci.c +++ b/drivers/mmc/am654_sdhci.c @@ -6,7 +6,6 @@ */ #include <clk.h> -#include <common.h> #include <dm.h> #include <malloc.h> #include <mmc.h> @@ -85,6 +84,8 @@ #define AM654_SDHCI_MIN_FREQ 400000 #define CLOCK_TOO_SLOW_HZ 50000000 +#define ENABLE 0x1 + struct am654_sdhci_plat { struct mmc_config cfg; struct mmc mmc; @@ -92,11 +93,13 @@ struct am654_sdhci_plat { bool non_removable; u32 otap_del_sel[MMC_MODES_END]; u32 itap_del_sel[MMC_MODES_END]; + u32 itap_del_ena[MMC_MODES_END]; u32 trm_icp; u32 drv_strength; u32 strb_sel; u32 clkbuf_sel; u32 flags; + bool dll_enable; #define DLL_PRESENT BIT(0) #define IOMUX_PRESENT BIT(1) #define FREQSEL_2_BIT BIT(2) @@ -110,6 +113,12 @@ struct timing_data { u32 capability; }; +struct window { + u8 start; + u8 end; + u8 length; +}; + static const struct timing_data td[] = { [MMC_LEGACY] = {"ti,otap-del-sel-legacy", "ti,itap-del-sel-legacy", @@ -216,8 +225,10 @@ static int am654_sdhci_setup_dll(struct am654_sdhci_plat *plat, } static void am654_sdhci_write_itapdly(struct am654_sdhci_plat *plat, - u32 itapdly) + u32 itapdly, u32 enable) { + regmap_update_bits(plat->base, PHY_CTRL4, ITAPDLYENA_MASK, + enable << ITAPDLYENA_SHIFT); /* Set ITAPCHGWIN before writing to ITAPDLY */ regmap_update_bits(plat->base, PHY_CTRL4, ITAPCHGWIN_MASK, 1 << ITAPCHGWIN_SHIFT); @@ -235,7 +246,8 @@ static void am654_sdhci_setup_delay_chain(struct am654_sdhci_plat *plat, mask = SELDLYTXCLK_MASK | SELDLYRXCLK_MASK; regmap_update_bits(plat->base, PHY_CTRL5, mask, val); - am654_sdhci_write_itapdly(plat, plat->itap_del_sel[mode]); + am654_sdhci_write_itapdly(plat, plat->itap_del_sel[mode], + plat->itap_del_ena[mode]); } static int am654_sdhci_set_ios_post(struct sdhci_host *host) @@ -276,12 +288,22 @@ static int am654_sdhci_set_ios_post(struct sdhci_host *host) regmap_update_bits(plat->base, PHY_CTRL4, mask, val); - if (mode > UHS_SDR25 && speed >= CLOCK_TOO_SLOW_HZ) { + if ((mode > UHS_SDR25 || mode == MMC_DDR_52) && speed >= CLOCK_TOO_SLOW_HZ) { ret = am654_sdhci_setup_dll(plat, speed); if (ret) return ret; + + plat->dll_enable = true; + if (mode == MMC_HS_400) { + plat->itap_del_ena[mode] = ENABLE; + plat->itap_del_sel[mode] = plat->itap_del_sel[mode - 1]; + } + + am654_sdhci_write_itapdly(plat, plat->itap_del_sel[mode], + plat->itap_del_ena[mode]); } else { am654_sdhci_setup_delay_chain(plat, mode); + plat->dll_enable = false; } regmap_update_bits(plat->base, PHY_CTRL5, CLKBUFSEL_MASK, @@ -374,46 +396,110 @@ static void am654_sdhci_write_b(struct sdhci_host *host, u8 val, int reg) writeb(val, host->ioaddr + reg); } -#ifdef MMC_SUPPORTS_TUNING -#define ITAP_MAX 32 +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) +#define ITAPDLY_LENGTH 32 +#define ITAPDLY_LAST_INDEX (ITAPDLY_LENGTH - 1) + +static u32 am654_sdhci_calculate_itap(struct udevice *dev, struct window + *fail_window, u8 num_fails, bool circular_buffer) +{ + u8 itap = 0, start_fail = 0, end_fail = 0, pass_length = 0; + u8 first_fail_start = 0, last_fail_end = 0; + struct window pass_window = {0, 0, 0}; + int prev_fail_end = -1; + u8 i; + + if (!num_fails) + return ITAPDLY_LAST_INDEX >> 1; + + if (fail_window->length == ITAPDLY_LENGTH) { + dev_err(dev, "No passing ITAPDLY, return 0\n"); + return 0; + } + + first_fail_start = fail_window->start; + last_fail_end = fail_window[num_fails - 1].end; + + for (i = 0; i < num_fails; i++) { + start_fail = fail_window[i].start; + end_fail = fail_window[i].end; + pass_length = start_fail - (prev_fail_end + 1); + + if (pass_length > pass_window.length) { + pass_window.start = prev_fail_end + 1; + pass_window.length = pass_length; + } + prev_fail_end = end_fail; + } + + if (!circular_buffer) + pass_length = ITAPDLY_LAST_INDEX - last_fail_end; + else + pass_length = ITAPDLY_LAST_INDEX - last_fail_end + first_fail_start; + + if (pass_length > pass_window.length) { + pass_window.start = last_fail_end + 1; + pass_window.length = pass_length; + } + + if (!circular_buffer) + itap = pass_window.start + (pass_window.length >> 1); + else + itap = (pass_window.start + (pass_window.length >> 1)) % ITAPDLY_LENGTH; + + return (itap > ITAPDLY_LAST_INDEX) ? ITAPDLY_LAST_INDEX >> 1 : itap; +} + static int am654_sdhci_execute_tuning(struct mmc *mmc, u8 opcode) { struct udevice *dev = mmc->dev; struct am654_sdhci_plat *plat = dev_get_plat(dev); - int cur_val, prev_val = 1, fail_len = 0, pass_window = 0, pass_len; - u32 itap; + struct window fail_window[ITAPDLY_LENGTH]; + int mode = mmc->selected_mode; + u8 curr_pass, itap; + u8 fail_index = 0; + u8 prev_pass = 1; + + memset(fail_window, 0, sizeof(fail_window)); /* Enable ITAPDLY */ - regmap_update_bits(plat->base, PHY_CTRL4, ITAPDLYENA_MASK, - 1 << ITAPDLYENA_SHIFT); + plat->itap_del_ena[mode] = ENABLE; - for (itap = 0; itap < ITAP_MAX; itap++) { - am654_sdhci_write_itapdly(plat, itap); + for (itap = 0; itap < ITAPDLY_LENGTH; itap++) { + am654_sdhci_write_itapdly(plat, itap, plat->itap_del_ena[mode]); - cur_val = !mmc_send_tuning(mmc, opcode); - if (cur_val && !prev_val) - pass_window = itap; + curr_pass = !mmc_send_tuning(mmc, opcode); - if (!cur_val) - fail_len++; + if (!curr_pass && prev_pass) + fail_window[fail_index].start = itap; - prev_val = cur_val; + if (!curr_pass) { + fail_window[fail_index].end = itap; + fail_window[fail_index].length++; + } + + if (curr_pass && !prev_pass) + fail_index++; + + prev_pass = curr_pass; } - /* - * Having determined the length of the failing window and start of - * the passing window calculate the length of the passing window and - * set the final value halfway through it considering the range as a - * circular buffer - */ - pass_len = ITAP_MAX - fail_len; - itap = (pass_window + (pass_len >> 1)) % ITAP_MAX; - am654_sdhci_write_itapdly(plat, itap); + + if (fail_window[fail_index].length != 0) + fail_index++; + + itap = am654_sdhci_calculate_itap(dev, fail_window, fail_index, + plat->dll_enable); + + /* Save ITAPDLY */ + plat->itap_del_sel[mode] = itap; + + am654_sdhci_write_itapdly(plat, itap, plat->itap_del_ena[mode]); return 0; } #endif const struct sdhci_ops am654_sdhci_ops = { -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) .platform_execute_tuning = am654_sdhci_execute_tuning, #endif .deferred_probe = am654_sdhci_deferred_probe, @@ -442,12 +528,29 @@ static int j721e_4bit_sdhci_set_ios_post(struct sdhci_host *host) { struct udevice *dev = host->mmc->dev; struct am654_sdhci_plat *plat = dev_get_plat(dev); - u32 otap_del_sel, mask, val; + int mode = host->mmc->selected_mode; + u32 otap_del_sel; + u32 itap_del_ena; + u32 itap_del_sel; + u32 mask, val; + + otap_del_sel = plat->otap_del_sel[mode]; - otap_del_sel = plat->otap_del_sel[host->mmc->selected_mode]; mask = OTAPDLYENA_MASK | OTAPDLYSEL_MASK; - val = (1 << OTAPDLYENA_SHIFT) | (otap_del_sel << OTAPDLYSEL_SHIFT); + val = (1 << OTAPDLYENA_SHIFT) | + (otap_del_sel << OTAPDLYSEL_SHIFT); + + itap_del_ena = plat->itap_del_ena[mode]; + itap_del_sel = plat->itap_del_sel[mode]; + + mask |= ITAPDLYENA_MASK | ITAPDLYSEL_MASK; + val |= (itap_del_ena << ITAPDLYENA_SHIFT) | + (itap_del_sel << ITAPDLYSEL_SHIFT); + + regmap_update_bits(plat->base, PHY_CTRL4, ITAPCHGWIN_MASK, + 1 << ITAPCHGWIN_SHIFT); regmap_update_bits(plat->base, PHY_CTRL4, mask, val); + regmap_update_bits(plat->base, PHY_CTRL4, ITAPCHGWIN_MASK, 0); regmap_update_bits(plat->base, PHY_CTRL5, CLKBUFSEL_MASK, plat->clkbuf_sel); @@ -456,7 +559,7 @@ static int j721e_4bit_sdhci_set_ios_post(struct sdhci_host *host) } const struct sdhci_ops j721e_4bit_sdhci_ops = { -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) .platform_execute_tuning = am654_sdhci_execute_tuning, #endif .deferred_probe = am654_sdhci_deferred_probe, @@ -501,7 +604,7 @@ static int sdhci_am654_get_otap_delay(struct udevice *dev, * Remove the corresponding capability if an otap-del-sel * value is not found */ - for (i = MMC_HS; i <= MMC_HS_400; i++) { + for (i = MMC_LEGACY; i <= MMC_HS_400; i++) { ret = dev_read_u32(dev, td[i].otap_binding, &plat->otap_del_sel[i]); if (ret) { @@ -513,9 +616,13 @@ static int sdhci_am654_get_otap_delay(struct udevice *dev, cfg->host_caps &= ~td[i].capability; } - if (td[i].itap_binding) - dev_read_u32(dev, td[i].itap_binding, - &plat->itap_del_sel[i]); + if (td[i].itap_binding) { + ret = dev_read_u32(dev, td[i].itap_binding, + &plat->itap_del_sel[i]); + + if (!ret) + plat->itap_del_ena[i] = ENABLE; + } } return 0; diff --git a/drivers/mmc/arm_pl180_mmci.c b/drivers/mmc/arm_pl180_mmci.c index 2666b65362b..f00b0ff0dc9 100644 --- a/drivers/mmc/arm_pl180_mmci.c +++ b/drivers/mmc/arm_pl180_mmci.c @@ -11,7 +11,6 @@ /* #define DEBUG */ -#include "common.h" #include <clk.h> #include <errno.h> #include <log.h> @@ -229,6 +228,7 @@ static int do_data_transfer(struct mmc *dev, u32 blksz = 0; u32 data_ctrl = 0; u32 data_len = (u32) (data->blocks * data->blocksize); + assert(data_len < U16_MAX); /* should be ensured by arm_pl180_get_b_max */ if (!host->version2) { blksz = (ffs(data->blocksize) - 1); @@ -356,6 +356,14 @@ static int host_set_ios(struct mmc *dev) return 0; } +static int arm_pl180_get_b_max(struct udevice *dev, void *dst, lbaint_t blkcnt) +{ + struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); + struct mmc *mmc = upriv->mmc; + + return U16_MAX / mmc->read_bl_len; +} + static void arm_pl180_mmc_init(struct pl180_mmc_host *host) { u32 sdi_u32; @@ -470,6 +478,7 @@ static const struct dm_mmc_ops arm_pl180_dm_mmc_ops = { .send_cmd = dm_host_request, .set_ios = dm_host_set_ios, .get_cd = dm_mmc_getcd, + .get_b_max = arm_pl180_get_b_max, }; static int arm_pl180_mmc_of_to_plat(struct udevice *dev) diff --git a/drivers/mmc/aspeed_sdhci.c b/drivers/mmc/aspeed_sdhci.c index c9626c6beb8..87a6f66ebb3 100644 --- a/drivers/mmc/aspeed_sdhci.c +++ b/drivers/mmc/aspeed_sdhci.c @@ -4,7 +4,6 @@ * Eddie James <eajames@linux.ibm.com> */ -#include <common.h> #include <clk.h> #include <dm.h> #include <malloc.h> diff --git a/drivers/mmc/atmel_sdhci.c b/drivers/mmc/atmel_sdhci.c index d92bad97b71..0b265196f02 100644 --- a/drivers/mmc/atmel_sdhci.c +++ b/drivers/mmc/atmel_sdhci.c @@ -4,7 +4,6 @@ * Wenyou.Yang <wenyou.yang@atmel.com> */ -#include <common.h> #include <clk.h> #include <dm.h> #include <malloc.h> diff --git a/drivers/mmc/bcm2835_sdhci.c b/drivers/mmc/bcm2835_sdhci.c index 5e48394fd0f..598a51d914a 100644 --- a/drivers/mmc/bcm2835_sdhci.c +++ b/drivers/mmc/bcm2835_sdhci.c @@ -36,7 +36,6 @@ * Inspired by sdhci-pci.c, by Pierre Ossman */ -#include <common.h> #include <dm.h> #include <log.h> #include <malloc.h> diff --git a/drivers/mmc/bcm2835_sdhost.c b/drivers/mmc/bcm2835_sdhost.c index 5c23c03d10d..720127468d3 100644 --- a/drivers/mmc/bcm2835_sdhost.c +++ b/drivers/mmc/bcm2835_sdhost.c @@ -30,7 +30,6 @@ * sdhci.c and sdhci-pci.c by Pierre Ossman */ #include <clk.h> -#include <common.h> #include <dm.h> #include <mmc.h> #include <asm/arch/msg.h> diff --git a/drivers/mmc/bcmstb_sdhci.c b/drivers/mmc/bcmstb_sdhci.c index 49846adcf54..7bddbebb162 100644 --- a/drivers/mmc/bcmstb_sdhci.c +++ b/drivers/mmc/bcmstb_sdhci.c @@ -6,7 +6,6 @@ * Author: Thomas Fitzsimmons <fitzsim@fitzsim.org> */ -#include <common.h> #include <dm.h> #include <mach/sdhci.h> #include <malloc.h> diff --git a/drivers/mmc/ca_dw_mmc.c b/drivers/mmc/ca_dw_mmc.c index a17ed8c11cb..54a2ba4795e 100644 --- a/drivers/mmc/ca_dw_mmc.c +++ b/drivers/mmc/ca_dw_mmc.c @@ -4,7 +4,6 @@ * Arthur Li <arthur.li@cortina-access.com> */ -#include <common.h> #include <dwmmc.h> #include <fdtdec.h> #include <asm/global_data.h> diff --git a/drivers/mmc/cv1800b_sdhci.c b/drivers/mmc/cv1800b_sdhci.c index 9af6b971984..4e75051c317 100644 --- a/drivers/mmc/cv1800b_sdhci.c +++ b/drivers/mmc/cv1800b_sdhci.c @@ -12,6 +12,8 @@ #define MMC_MAX_CLOCK 375000000 #define TUNE_MAX_PHCODE 128 +#define PHY_TX_SRC_INVERT BIT(8) + struct cv1800b_sdhci_plat { struct mmc_config cfg; struct mmc mmc; @@ -19,7 +21,7 @@ struct cv1800b_sdhci_plat { static void cv1800b_set_tap_delay(struct sdhci_host *host, u16 tap) { - sdhci_writel(host, tap << 16, SDHCI_PHY_TX_RX_DLY); + sdhci_writel(host, PHY_TX_SRC_INVERT | tap << 16, SDHCI_PHY_TX_RX_DLY); } static void cv1800b_sdhci_reset(struct sdhci_host *host, u8 mask) diff --git a/drivers/mmc/davinci_mmc.c b/drivers/mmc/davinci_mmc.c index 3a3d23aec00..5107fcd8362 100644 --- a/drivers/mmc/davinci_mmc.c +++ b/drivers/mmc/davinci_mmc.c @@ -6,7 +6,6 @@ */ #include <config.h> -#include <common.h> #include <dm.h> #include <errno.h> #include <mmc.h> diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index e1036641452..e6107c770fe 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -6,7 +6,6 @@ */ #include <bouncebuf.h> -#include <common.h> #include <cpu_func.h> #include <errno.h> #include <log.h> diff --git a/drivers/mmc/exynos_dw_mmc.c b/drivers/mmc/exynos_dw_mmc.c index 2f849c43b12..a51f762988d 100644 --- a/drivers/mmc/exynos_dw_mmc.c +++ b/drivers/mmc/exynos_dw_mmc.c @@ -4,7 +4,6 @@ * Jaehoon Chung <jh80.chung@samsung.com> */ -#include <common.h> #include <dwmmc.h> #include <fdtdec.h> #include <asm/global_data.h> diff --git a/drivers/mmc/f_sdh30.c b/drivers/mmc/f_sdh30.c index 3d587a464d5..f47cf848521 100644 --- a/drivers/mmc/f_sdh30.c +++ b/drivers/mmc/f_sdh30.c @@ -5,7 +5,6 @@ * Copyright 2021 Socionext, Inc. */ -#include <common.h> #include <clk.h> #include <dm.h> #include <malloc.h> diff --git a/drivers/mmc/fsl_esdhc.c b/drivers/mmc/fsl_esdhc.c index d44dfa5d06f..0c66980b621 100644 --- a/drivers/mmc/fsl_esdhc.c +++ b/drivers/mmc/fsl_esdhc.c @@ -10,7 +10,6 @@ */ #include <config.h> -#include <common.h> #include <command.h> #include <cpu_func.h> #include <errno.h> @@ -252,7 +251,7 @@ static void esdhc_setup_dma(struct fsl_esdhc_priv *priv, struct mmc_data *data) priv->adma_desc_table) { debug("Using ADMA2\n"); /* prefer ADMA2 if it is available */ - sdhci_prepare_adma_table(priv->adma_desc_table, data, + sdhci_prepare_adma_table(NULL, priv->adma_desc_table, data, priv->dma_addr); adma_addr = virt_to_phys(priv->adma_desc_table); @@ -1102,7 +1101,7 @@ static int fsl_esdhc_reinit(struct udevice *dev) return esdhc_init_common(priv, &plat->mmc); } -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode) { struct fsl_esdhc_plat *plat = dev_get_plat(dev); @@ -1175,7 +1174,7 @@ static const struct dm_mmc_ops fsl_esdhc_ops = { .get_cd = fsl_esdhc_get_cd, .send_cmd = fsl_esdhc_send_cmd, .set_ios = fsl_esdhc_set_ios, -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) .execute_tuning = fsl_esdhc_execute_tuning, #endif .reinit = fsl_esdhc_reinit, diff --git a/drivers/mmc/fsl_esdhc_imx.c b/drivers/mmc/fsl_esdhc_imx.c index b74c0140020..a9b8d7dd67f 100644 --- a/drivers/mmc/fsl_esdhc_imx.c +++ b/drivers/mmc/fsl_esdhc_imx.c @@ -11,7 +11,6 @@ */ #include <config.h> -#include <common.h> #include <command.h> #include <clk.h> #include <cpu_func.h> @@ -635,7 +634,7 @@ static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock) priv->clock = clock; } -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) static int esdhc_change_pinstate(struct udevice *dev) { struct fsl_esdhc_priv *priv = dev_get_priv(dev); @@ -913,7 +912,7 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) int ret __maybe_unused; u32 clock; -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) /* * call esdhc_set_timing() before update the clock rate, * This is because current we support DDR and SDR mode, @@ -951,7 +950,7 @@ static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc) esdhc_setbits32(®s->sysctl, SYSCTL_PEREN | SYSCTL_CKEN); } -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) /* * For HS400/HS400ES mode, make sure set the strobe dll in the * target clock rate. So call esdhc_set_strobe_dll() after the @@ -1618,7 +1617,7 @@ static const struct dm_mmc_ops fsl_esdhc_ops = { .get_cd = fsl_esdhc_get_cd, .send_cmd = fsl_esdhc_send_cmd, .set_ios = fsl_esdhc_set_ios, -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) .execute_tuning = fsl_esdhc_execute_tuning, #endif #if CONFIG_IS_ENABLED(MMC_HS400_ES_SUPPORT) diff --git a/drivers/mmc/fsl_esdhc_spl.c b/drivers/mmc/fsl_esdhc_spl.c index 6d7c0cff22a..1a11258be4d 100644 --- a/drivers/mmc/fsl_esdhc_spl.c +++ b/drivers/mmc/fsl_esdhc_spl.c @@ -3,7 +3,7 @@ * Copyright 2013 Freescale Semiconductor, Inc. */ -#include <common.h> +#include <config.h> #include <cpu_func.h> #include <hang.h> #include <mmc.h> diff --git a/drivers/mmc/ftsdc010_mci.c b/drivers/mmc/ftsdc010_mci.c index cabb747fbbd..11e44264e47 100644 --- a/drivers/mmc/ftsdc010_mci.c +++ b/drivers/mmc/ftsdc010_mci.c @@ -9,7 +9,6 @@ * Author: Rick Chen (rick@andestech.com) */ -#include <common.h> #include <clk.h> #include <log.h> #include <malloc.h> diff --git a/drivers/mmc/gen_atmel_mci.c b/drivers/mmc/gen_atmel_mci.c index 3ee99558f6f..6a531fa0961 100644 --- a/drivers/mmc/gen_atmel_mci.c +++ b/drivers/mmc/gen_atmel_mci.c @@ -8,7 +8,7 @@ * Copyright (C) 2004-2006 Atmel Corporation */ -#include <common.h> +#include <config.h> #include <clk.h> #include <display_options.h> #include <dm.h> diff --git a/drivers/mmc/hi6220_dw_mmc.c b/drivers/mmc/hi6220_dw_mmc.c index dc0210402bd..c68a9157bfc 100644 --- a/drivers/mmc/hi6220_dw_mmc.c +++ b/drivers/mmc/hi6220_dw_mmc.c @@ -4,7 +4,6 @@ * peter.griffin <peter.griffin@linaro.org> */ -#include <common.h> #include <clk.h> #include <dm.h> #include <dwmmc.h> diff --git a/drivers/mmc/iproc_sdhci.c b/drivers/mmc/iproc_sdhci.c index 11d86ad658f..7ab74ff117a 100644 --- a/drivers/mmc/iproc_sdhci.c +++ b/drivers/mmc/iproc_sdhci.c @@ -4,7 +4,6 @@ * */ -#include <common.h> #include <dm.h> #include <errno.h> #include <malloc.h> diff --git a/drivers/mmc/jz_mmc.c b/drivers/mmc/jz_mmc.c index 61e48ee0f62..fc10bb256a4 100644 --- a/drivers/mmc/jz_mmc.c +++ b/drivers/mmc/jz_mmc.c @@ -6,7 +6,6 @@ * Author: Paul Burton <paul.burton@imgtec.com> */ -#include <common.h> #include <malloc.h> #include <mmc.h> #include <asm/global_data.h> diff --git a/drivers/mmc/kona_sdhci.c b/drivers/mmc/kona_sdhci.c index 2bbe673b912..83f14122632 100644 --- a/drivers/mmc/kona_sdhci.c +++ b/drivers/mmc/kona_sdhci.c @@ -3,7 +3,6 @@ * Copyright 2013 Broadcom Corporation. */ -#include <common.h> #include <malloc.h> #include <sdhci.h> #include <linux/delay.h> diff --git a/drivers/mmc/meson_gx_mmc.c b/drivers/mmc/meson_gx_mmc.c index 0825c0a2a83..5852b24c6d2 100644 --- a/drivers/mmc/meson_gx_mmc.c +++ b/drivers/mmc/meson_gx_mmc.c @@ -3,7 +3,6 @@ * (C) Copyright 2016 Carlo Caione <carlo@caione.org> */ -#include <common.h> #include <clk.h> #include <cpu_func.h> #include <dm.h> diff --git a/drivers/mmc/mmc-pwrseq.c b/drivers/mmc/mmc-pwrseq.c index 2539f61323d..a1c9624a222 100644 --- a/drivers/mmc/mmc-pwrseq.c +++ b/drivers/mmc/mmc-pwrseq.c @@ -4,7 +4,6 @@ * Jaehoon Chung <jh80.chung@samsung.com> */ -#include <common.h> #include <dm.h> #include <mmc.h> #include <pwrseq.h> diff --git a/drivers/mmc/mmc-uclass.c b/drivers/mmc/mmc-uclass.c index 1e03901e9dc..da6a39b7d99 100644 --- a/drivers/mmc/mmc-uclass.c +++ b/drivers/mmc/mmc-uclass.c @@ -7,7 +7,6 @@ #define LOG_CATEGORY UCLASS_MMC -#include <common.h> #include <bootdev.h> #include <log.h> #include <mmc.h> @@ -112,7 +111,7 @@ int mmc_getcd(struct mmc *mmc) return dm_mmc_get_cd(mmc->dev); } -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) static int dm_mmc_execute_tuning(struct udevice *dev, uint opcode) { struct dm_mmc_ops *ops = mmc_get_ops(dev); @@ -257,11 +256,14 @@ int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg) if (dev_read_bool(dev, "mmc-hs200-1_2v")) cfg->host_caps |= MMC_CAP(MMC_HS_200); if (dev_read_bool(dev, "mmc-hs400-1_8v")) - cfg->host_caps |= MMC_CAP(MMC_HS_400); + cfg->host_caps |= MMC_CAP(MMC_HS_400) | MMC_CAP(MMC_HS_200); if (dev_read_bool(dev, "mmc-hs400-1_2v")) - cfg->host_caps |= MMC_CAP(MMC_HS_400); + cfg->host_caps |= MMC_CAP(MMC_HS_400) | MMC_CAP(MMC_HS_200); if (dev_read_bool(dev, "mmc-hs400-enhanced-strobe")) cfg->host_caps |= MMC_CAP(MMC_HS_400_ES); + if (dev_read_bool(dev, "no-mmc-hs400")) + cfg->host_caps &= ~(MMC_CAP(MMC_HS_400) | + MMC_CAP(MMC_HS_400_ES)); if (dev_read_bool(dev, "non-removable")) { cfg->host_caps |= MMC_CAP_NONREMOVABLE; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index 7b068c71ff3..b18dc331f78 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -8,7 +8,6 @@ */ #include <config.h> -#include <common.h> #include <blk.h> #include <command.h> #include <dm.h> @@ -17,6 +16,7 @@ #include <errno.h> #include <mmc.h> #include <part.h> +#include <time.h> #include <linux/bitops.h> #include <linux/delay.h> #include <linux/printk.h> @@ -24,6 +24,7 @@ #include <malloc.h> #include <memalign.h> #include <linux/list.h> +#include <linux/printk.h> #include <div64.h> #include "mmc_private.h" @@ -329,7 +330,7 @@ int mmc_set_blocklen(struct mmc *mmc, int len) MMC_QUIRK_RETRY_SET_BLOCKLEN, 4); } -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) static const u8 tuning_blk_pattern_4bit[] = { 0xff, 0x0f, 0xff, 0x00, 0xff, 0xcc, 0xc3, 0xcc, 0xc3, 0x3c, 0xcc, 0xff, 0xfe, 0xff, 0xfe, 0xef, @@ -1621,7 +1622,7 @@ static inline int bus_width(uint cap) } #if !CONFIG_IS_ENABLED(DM_MMC) -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) static int mmc_execute_tuning(struct mmc *mmc, uint opcode) { return -ENOTSUPP; @@ -1702,7 +1703,7 @@ void mmc_dump_capabilities(const char *text, uint caps) struct mode_width_tuning { enum bus_mode mode; uint widths; -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) uint tuning; #endif }; @@ -1743,7 +1744,7 @@ static inline int mmc_set_signal_voltage(struct mmc *mmc, uint signal_voltage) #if !CONFIG_IS_ENABLED(MMC_TINY) static const struct mode_width_tuning sd_modes_by_pref[] = { #if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT) -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) { .mode = UHS_SDR104, .widths = MMC_MODE_4BIT | MMC_MODE_1BIT, @@ -1846,7 +1847,7 @@ static int sd_select_mode_and_width(struct mmc *mmc, uint card_caps) mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE); -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) /* execute tuning if needed */ if (mwt->tuning && !mmc_host_is_spi(mmc)) { err = mmc_execute_tuning(mmc, @@ -2224,7 +2225,7 @@ static int mmc_select_mode_and_width(struct mmc *mmc, uint card_caps) mmc_select_mode(mmc, mwt->mode); mmc_set_clock(mmc, mmc->tran_speed, MMC_CLK_ENABLE); -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) /* execute tuning if needed */ if (mwt->tuning) { diff --git a/drivers/mmc/mmc_boot.c b/drivers/mmc/mmc_boot.c index 0a74b1fb776..367c957b518 100644 --- a/drivers/mmc/mmc_boot.c +++ b/drivers/mmc/mmc_boot.c @@ -4,7 +4,6 @@ * Written by Amar <amarendra.xt@samsung.com> */ -#include <common.h> #include <log.h> #include <mmc.h> #include "mmc_private.h" diff --git a/drivers/mmc/mmc_bootdev.c b/drivers/mmc/mmc_bootdev.c index 55ecead2ddf..5a1688b75d0 100644 --- a/drivers/mmc/mmc_bootdev.c +++ b/drivers/mmc/mmc_bootdev.c @@ -6,7 +6,6 @@ * Written by Simon Glass <sjg@chromium.org> */ -#include <common.h> #include <bootdev.h> #include <dm.h> #include <mmc.h> diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c index a101ee43fde..a87d2276c1b 100644 --- a/drivers/mmc/mmc_legacy.c +++ b/drivers/mmc/mmc_legacy.c @@ -5,7 +5,6 @@ * Written by Simon Glass <sjg@chromium.org> */ -#include <common.h> #include <log.h> #include <malloc.h> #include <mmc.h> diff --git a/drivers/mmc/mmc_spi.c b/drivers/mmc/mmc_spi.c index bcea800e5f6..675e642efd0 100644 --- a/drivers/mmc/mmc_spi.c +++ b/drivers/mmc/mmc_spi.c @@ -6,7 +6,6 @@ * * Licensed under the GPL-2 or later. */ -#include <common.h> #include <errno.h> #include <log.h> #include <malloc.h> diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c index a6f93380dd0..c023d15e52a 100644 --- a/drivers/mmc/mmc_write.c +++ b/drivers/mmc/mmc_write.c @@ -7,7 +7,6 @@ */ #include <config.h> -#include <common.h> #include <blk.h> #include <dm.h> #include <part.h> diff --git a/drivers/mmc/msm_sdhci.c b/drivers/mmc/msm_sdhci.c index 5e9d66526a8..4ce0de6c47d 100644 --- a/drivers/mmc/msm_sdhci.c +++ b/drivers/mmc/msm_sdhci.c @@ -7,7 +7,6 @@ * Based on Linux driver */ -#include <common.h> #include <clk.h> #include <dm.h> #include <malloc.h> diff --git a/drivers/mmc/mtk-sd.c b/drivers/mmc/mtk-sd.c index 296aaee7331..3a9258255a7 100644 --- a/drivers/mmc/mtk-sd.c +++ b/drivers/mmc/mtk-sd.c @@ -7,7 +7,6 @@ */ #include <clk.h> -#include <common.h> #include <dm.h> #include <mmc.h> #include <errno.h> @@ -1011,7 +1010,7 @@ static int msdc_ops_get_wp(struct udevice *dev) #endif } -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) static u32 test_delay_bit(u32 delay, u32 bit) { bit %= PAD_DELAY_MAX; @@ -1760,7 +1759,7 @@ static const struct dm_mmc_ops msdc_ops = { .set_ios = msdc_ops_set_ios, .get_cd = msdc_ops_get_cd, .get_wp = msdc_ops_get_wp, -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) .execute_tuning = msdc_execute_tuning, #endif .wait_dat0 = msdc_ops_wait_dat0, diff --git a/drivers/mmc/mv_sdhci.c b/drivers/mmc/mv_sdhci.c index dbdd671c88b..2da5334c21f 100644 --- a/drivers/mmc/mv_sdhci.c +++ b/drivers/mmc/mv_sdhci.c @@ -3,7 +3,6 @@ * Marvell SD Host Controller Interface */ -#include <common.h> #include <dm.h> #include <malloc.h> #include <sdhci.h> diff --git a/drivers/mmc/mvebu_mmc.c b/drivers/mmc/mvebu_mmc.c index fea55c61ed7..5af1953cd14 100644 --- a/drivers/mmc/mvebu_mmc.c +++ b/drivers/mmc/mvebu_mmc.c @@ -7,7 +7,6 @@ * Written-by: Maen Suleiman, Gerald Kerma */ -#include <common.h> #include <errno.h> #include <log.h> #include <malloc.h> diff --git a/drivers/mmc/mxcmmc.c b/drivers/mmc/mxcmmc.c index 0057273a2a7..1acea6f820b 100644 --- a/drivers/mmc/mxcmmc.c +++ b/drivers/mmc/mxcmmc.c @@ -17,7 +17,6 @@ */ #include <config.h> -#include <common.h> #include <command.h> #include <mmc.h> #include <part.h> diff --git a/drivers/mmc/mxsmmc.c b/drivers/mmc/mxsmmc.c index 35a8e21058e..95390a5be7e 100644 --- a/drivers/mmc/mxsmmc.c +++ b/drivers/mmc/mxsmmc.c @@ -20,7 +20,6 @@ * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net */ -#include <common.h> #include <log.h> #include <malloc.h> #include <mmc.h> diff --git a/drivers/mmc/nexell_dw_mmc.c b/drivers/mmc/nexell_dw_mmc.c index 2723e4887cf..2e1ce54c7d5 100644 --- a/drivers/mmc/nexell_dw_mmc.c +++ b/drivers/mmc/nexell_dw_mmc.c @@ -6,7 +6,6 @@ * (C) Copyright 2019 Stefan Bosch <stefan_b@posteo.net> */ -#include <common.h> #include <dm.h> #include <dt-structs.h> #include <dwmmc.h> diff --git a/drivers/mmc/npcm_sdhci.c b/drivers/mmc/npcm_sdhci.c index d63521d6855..dff4732ea06 100644 --- a/drivers/mmc/npcm_sdhci.c +++ b/drivers/mmc/npcm_sdhci.c @@ -3,7 +3,6 @@ * Copyright (c) 2022 Nuvoton Technology Corp. */ -#include <common.h> #include <dm.h> #include <sdhci.h> #include <clk.h> diff --git a/drivers/mmc/octeontx_hsmmc.c b/drivers/mmc/octeontx_hsmmc.c index 7f9c4f4d36d..3b5e1221732 100644 --- a/drivers/mmc/octeontx_hsmmc.c +++ b/drivers/mmc/octeontx_hsmmc.c @@ -794,7 +794,7 @@ octeontx_mmc_get_cr_mods(struct mmc *mmc, const struct mmc_cmd *cmd, u8 desired_ctype = 0; if (IS_MMC(mmc)) { -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) if (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200) { if (cmd->resp_type == MMC_RSP_R1) cr.rtype_xor = 1; @@ -1631,7 +1631,7 @@ static int octeontx_mmc_dev_send_cmd(struct udevice *dev, struct mmc_cmd *cmd, return octeontx_mmc_send_cmd(dev_to_mmc(dev), cmd, data); } -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) static int octeontx_mmc_test_cmd(struct mmc *mmc, u32 opcode, int *statp) { struct mmc_cmd cmd; @@ -2421,12 +2421,12 @@ static int octeontx_mmc_execute_tuning(struct udevice *dev, u32 opcode) return 0; } -#else /* MMC_SUPPORTS_TUNING */ +#else /* CONFIG_MMC_SUPPORTS_TUNING */ static void octeontx_mmc_set_emm_timing(struct mmc *mmc, union mio_emm_timing emm_timing) { } -#endif /* MMC_SUPPORTS_TUNING */ +#endif /* CONFIG_MMC_SUPPORTS_TUNING */ /** * Calculate the clock period with rounding up @@ -2573,7 +2573,7 @@ static int octeontx_mmc_set_ios(struct udevice *dev) err = octeontx_mmc_configure_delay(mmc); -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) if (!err && mmc->selected_mode == MMC_HS_400 && !slot->hs400_tuned) { debug("%s: Tuning HS400 mode\n", __func__); err = octeontx_tune_hs400(mmc); @@ -3776,7 +3776,7 @@ static const struct dm_mmc_ops octeontx_hsmmc_ops = { .set_ios = octeontx_mmc_set_ios, .get_cd = octeontx_mmc_get_cd, .get_wp = octeontx_mmc_get_wp, -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) .execute_tuning = octeontx_mmc_execute_tuning, #endif }; diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c index 99f21b2c546..2b7f9fc9a20 100644 --- a/drivers/mmc/omap_hsmmc.c +++ b/drivers/mmc/omap_hsmmc.c @@ -23,7 +23,6 @@ */ #include <config.h> -#include <common.h> #include <cpu_func.h> #include <log.h> #include <malloc.h> @@ -577,7 +576,7 @@ static uint32_t omap_hsmmc_set_capabilities(struct mmc *mmc) return val; } -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) static void omap_hsmmc_disable_tuning(struct mmc *mmc) { struct hsmmc *mmc_base; @@ -1518,7 +1517,7 @@ static const struct dm_mmc_ops omap_hsmmc_ops = { .get_cd = omap_hsmmc_getcd, .get_wp = omap_hsmmc_getwp, #endif -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) .execute_tuning = omap_hsmmc_execute_tuning, #endif .wait_dat0 = omap_hsmmc_wait_dat0, diff --git a/drivers/mmc/owl_mmc.c b/drivers/mmc/owl_mmc.c index e84171a661a..bd4906f58e7 100644 --- a/drivers/mmc/owl_mmc.c +++ b/drivers/mmc/owl_mmc.c @@ -11,7 +11,6 @@ * channel, and those special bits used in this driver is picked from vendor * source exclusively for MMC/SD. */ -#include <common.h> #include <clk.h> #include <cpu_func.h> #include <dm.h> diff --git a/drivers/mmc/pci_mmc.c b/drivers/mmc/pci_mmc.c index 4d163ccba04..d446c55f72b 100644 --- a/drivers/mmc/pci_mmc.c +++ b/drivers/mmc/pci_mmc.c @@ -4,7 +4,6 @@ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com> */ -#include <common.h> #include <dm.h> #include <errno.h> #include <log.h> diff --git a/drivers/mmc/piton_mmc.c b/drivers/mmc/piton_mmc.c index a330bbf8cbe..fed1f841608 100644 --- a/drivers/mmc/piton_mmc.c +++ b/drivers/mmc/piton_mmc.c @@ -11,7 +11,6 @@ #include <asm/gpio.h> #include <asm/io.h> -#include <common.h> #include <div64.h> #include <dm.h> #include <errno.h> diff --git a/drivers/mmc/rockchip_dw_mmc.c b/drivers/mmc/rockchip_dw_mmc.c index ad4529d6afa..1a10b7057a4 100644 --- a/drivers/mmc/rockchip_dw_mmc.c +++ b/drivers/mmc/rockchip_dw_mmc.c @@ -3,7 +3,6 @@ * Copyright (c) 2013 Google, Inc */ -#include <common.h> #include <clk.h> #include <dm.h> #include <dt-structs.h> diff --git a/drivers/mmc/rockchip_sdhci.c b/drivers/mmc/rockchip_sdhci.c index 706fb123579..35667b86b50 100644 --- a/drivers/mmc/rockchip_sdhci.c +++ b/drivers/mmc/rockchip_sdhci.c @@ -5,7 +5,6 @@ * Rockchip SD Host Controller Interface */ -#include <common.h> #include <clk.h> #include <dm.h> #include <dm/ofnode.h> @@ -391,6 +390,8 @@ static int rk3568_sdhci_config_dll(struct sdhci_host *host, u32 clock, bool enab static int rk3568_sdhci_set_ios_post(struct sdhci_host *host) { struct mmc *mmc = host->mmc; + struct rockchip_sdhc_plat *plat = dev_get_plat(mmc->dev); + struct mmc_config *cfg = &plat->cfg; u32 reg; reg = sdhci_readw(host, SDHCI_HOST_CONTROL2); @@ -437,6 +438,20 @@ static int rk3568_sdhci_set_ios_post(struct sdhci_host *host) sdhci_writew(host, reg, DWCMSHC_EMMC_EMMC_CTRL); + /* + * Reading more than 4 blocks with a single CMD18 command in PIO mode + * triggers Data End Bit Error using a slower mode than HS200. Limit to + * reading max 4 blocks in one command when using PIO mode. + */ + if (!(host->flags & USE_DMA)) { + if (mmc->selected_mode == MMC_HS_200 || + mmc->selected_mode == MMC_HS_400 || + mmc->selected_mode == MMC_HS_400_ES) + cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT; + else + cfg->b_max = 4; + } + return 0; } @@ -598,16 +613,6 @@ static int rockchip_sdhci_probe(struct udevice *dev) dev_read_bool(dev, "u-boot,spl-fifo-mode")) host->flags &= ~USE_DMA; - /* - * Reading more than 4 blocks with a single CMD18 command in PIO mode - * triggers Data End Bit Error on RK3568 and RK3588. Limit to reading - * max 4 blocks in one command when using PIO mode. - */ - if (!(host->flags & USE_DMA) && - (device_is_compatible(dev, "rockchip,rk3568-dwcmshc") || - device_is_compatible(dev, "rockchip,rk3588-dwcmshc"))) - cfg->b_max = 4; - return sdhci_probe(dev); } diff --git a/drivers/mmc/rpmb.c b/drivers/mmc/rpmb.c index b68d98573c9..0658ce22cf1 100644 --- a/drivers/mmc/rpmb.c +++ b/drivers/mmc/rpmb.c @@ -8,7 +8,6 @@ */ #include <config.h> -#include <common.h> #include <log.h> #include <memalign.h> #include <mmc.h> diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index 3b74feae68c..80dbb38c9b3 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -4,7 +4,6 @@ * Jaehoon Chung <jh80.chung@samsung.com> */ -#include <common.h> #include <dm.h> #include <log.h> #include <malloc.h> diff --git a/drivers/mmc/sandbox_mmc.c b/drivers/mmc/sandbox_mmc.c index 0ba7940a4db..a24520f2e78 100644 --- a/drivers/mmc/sandbox_mmc.c +++ b/drivers/mmc/sandbox_mmc.c @@ -4,7 +4,6 @@ * Written by Simon Glass <sjg@chromium.org> */ -#include <common.h> #include <dm.h> #include <errno.h> #include <fdtdec.h> diff --git a/drivers/mmc/sdhci-adma.c b/drivers/mmc/sdhci-adma.c index 8213223d3f9..fdb189d71a6 100644 --- a/drivers/mmc/sdhci-adma.c +++ b/drivers/mmc/sdhci-adma.c @@ -3,15 +3,15 @@ * SDHCI ADMA2 helper functions. */ -#include <common.h> #include <cpu_func.h> #include <sdhci.h> #include <malloc.h> #include <asm/cache.h> -static void sdhci_adma_desc(struct sdhci_adma_desc *desc, - dma_addr_t addr, u16 len, bool end) +void sdhci_adma_write_desc(struct sdhci_host *host, void **next_desc, + dma_addr_t addr, int len, bool end) { + struct sdhci_adma_desc *desc = *next_desc; u8 attr; attr = ADMA_DESC_ATTR_VALID | ADMA_DESC_TRANSFER_DATA; @@ -19,17 +19,30 @@ static void sdhci_adma_desc(struct sdhci_adma_desc *desc, attr |= ADMA_DESC_ATTR_END; desc->attr = attr; - desc->len = len; + desc->len = len & 0xffff; desc->reserved = 0; desc->addr_lo = lower_32_bits(addr); -#ifdef CONFIG_DMA_ADDR_T_64BIT +#ifdef CONFIG_MMC_SDHCI_ADMA_64BIT desc->addr_hi = upper_32_bits(addr); #endif + + *next_desc += ADMA_DESC_LEN; +} + +static inline void __sdhci_adma_write_desc(struct sdhci_host *host, + void **desc, dma_addr_t addr, + int len, bool end) +{ + if (host && host->ops && host->ops->adma_write_desc) + host->ops->adma_write_desc(host, desc, addr, len, end); + else + sdhci_adma_write_desc(host, desc, addr, len, end); } /** * sdhci_prepare_adma_table() - Populate the ADMA table * + * @host: Pointer to the sdhci_host * @table: Pointer to the ADMA table * @data: Pointer to MMC data * @addr: DMA address to write to or read from @@ -39,25 +52,26 @@ static void sdhci_adma_desc(struct sdhci_adma_desc *desc, * Please note, that the table size depends on CONFIG_SYS_MMC_MAX_BLK_COUNT and * we don't have to check for overflow. */ -void sdhci_prepare_adma_table(struct sdhci_adma_desc *table, - struct mmc_data *data, dma_addr_t addr) +void sdhci_prepare_adma_table(struct sdhci_host *host, + struct sdhci_adma_desc *table, + struct mmc_data *data, dma_addr_t start_addr) { + dma_addr_t addr = start_addr; uint trans_bytes = data->blocksize * data->blocks; - uint desc_count = DIV_ROUND_UP(trans_bytes, ADMA_MAX_LEN); - struct sdhci_adma_desc *desc = table; - int i = desc_count; + void *next_desc = table; + int i = DIV_ROUND_UP(trans_bytes, ADMA_MAX_LEN); while (--i) { - sdhci_adma_desc(desc, addr, ADMA_MAX_LEN, false); + __sdhci_adma_write_desc(host, &next_desc, addr, + ADMA_MAX_LEN, false); addr += ADMA_MAX_LEN; trans_bytes -= ADMA_MAX_LEN; - desc++; } - sdhci_adma_desc(desc, addr, trans_bytes, true); + __sdhci_adma_write_desc(host, &next_desc, addr, trans_bytes, true); - flush_cache((dma_addr_t)table, - ROUND(desc_count * sizeof(struct sdhci_adma_desc), + flush_cache((phys_addr_t)table, + ROUND(next_desc - (void *)table, ARCH_DMA_MINALIGN)); } diff --git a/drivers/mmc/sdhci-cadence.c b/drivers/mmc/sdhci-cadence.c index c0a9f60b149..07ec35a0463 100644 --- a/drivers/mmc/sdhci-cadence.c +++ b/drivers/mmc/sdhci-cadence.c @@ -4,7 +4,6 @@ * Author: Masahiro Yamada <yamada.masahiro@socionext.com> */ -#include <common.h> #include <dm.h> #include <asm/global_data.h> #include <dm/device_compat.h> @@ -274,7 +273,7 @@ static int sdhci_cdns_probe(struct udevice *dev) host->ops = &sdhci_cdns_ops; host->quirks |= SDHCI_QUIRK_WAIT_SEND_CMD; sdhci_cdns_mmc_ops = sdhci_ops; -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) sdhci_cdns_mmc_ops.execute_tuning = sdhci_cdns_execute_tuning; #endif diff --git a/drivers/mmc/sdhci.c b/drivers/mmc/sdhci.c index 0178ed8a11e..560b7e889c7 100644 --- a/drivers/mmc/sdhci.c +++ b/drivers/mmc/sdhci.c @@ -7,7 +7,6 @@ * Murray.Jensen@cmst.csiro.au, 27-Jan-01. */ -#include <common.h> #include <cpu_func.h> #include <dm.h> #include <errno.h> @@ -15,6 +14,7 @@ #include <malloc.h> #include <mmc.h> #include <sdhci.h> +#include <time.h> #include <asm/cache.h> #include <linux/bitops.h> #include <linux/delay.h> @@ -111,7 +111,7 @@ static void sdhci_prepare_dma(struct sdhci_host *host, struct mmc_data *data, } #if CONFIG_IS_ENABLED(MMC_SDHCI_ADMA) else if (host->flags & (USE_ADMA | USE_ADMA64)) { - sdhci_prepare_adma_table(host->adma_desc_table, data, + sdhci_prepare_adma_table(host, host->adma_desc_table, data, host->start_addr); sdhci_writel(host, lower_32_bits(host->adma_addr), @@ -351,7 +351,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd, return -ECOMM; } -#if defined(CONFIG_DM_MMC) && defined(MMC_SUPPORTS_TUNING) +#if defined(CONFIG_DM_MMC) && CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) static int sdhci_execute_tuning(struct udevice *dev, uint opcode) { int err; @@ -848,7 +848,7 @@ const struct dm_mmc_ops sdhci_ops = { .set_ios = sdhci_set_ios, .get_cd = sdhci_get_cd, .deferred_probe = sdhci_deferred_probe, -#ifdef MMC_SUPPORTS_TUNING +#if CONFIG_IS_ENABLED(MMC_SUPPORTS_TUNING) .execute_tuning = sdhci_execute_tuning, #endif .wait_dat0 = sdhci_wait_dat0, @@ -897,14 +897,15 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host, __func__); return -EINVAL; } - host->adma_desc_table = sdhci_adma_init(); - host->adma_addr = (dma_addr_t)host->adma_desc_table; + if (!host->adma_desc_table) { + host->adma_desc_table = sdhci_adma_init(); + host->adma_addr = virt_to_phys(host->adma_desc_table); + } -#ifdef CONFIG_DMA_ADDR_T_64BIT - host->flags |= USE_ADMA64; -#else - host->flags |= USE_ADMA; -#endif + if (IS_ENABLED(CONFIG_MMC_SDHCI_ADMA_64BIT)) + host->flags |= USE_ADMA64; + else + host->flags |= USE_ADMA; #endif if (host->quirks & SDHCI_QUIRK_REG32_RW) host->version = @@ -929,6 +930,15 @@ int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host, debug("%s, caps_1: 0x%x\n", __func__, caps_1); host->clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >> SDHCI_CLOCK_MUL_SHIFT; + + /* + * In case the value in Clock Multiplier is 0, then programmable + * clock mode is not supported, otherwise the actual clock + * multiplier is one more than the value of Clock Multiplier + * in the Capabilities Register. + */ + if (host->clk_mul) + host->clk_mul += 1; } if (host->max_clk == 0) { diff --git a/drivers/mmc/sh_mmcif.c b/drivers/mmc/sh_mmcif.c index 76dc1c68b82..06a30d5efb8 100644 --- a/drivers/mmc/sh_mmcif.c +++ b/drivers/mmc/sh_mmcif.c @@ -6,7 +6,6 @@ */ #include <config.h> -#include <common.h> #include <log.h> #include <watchdog.h> #include <command.h> diff --git a/drivers/mmc/snps_dw_mmc.c b/drivers/mmc/snps_dw_mmc.c index 0134399e393..9bdbe5070b1 100644 --- a/drivers/mmc/snps_dw_mmc.c +++ b/drivers/mmc/snps_dw_mmc.c @@ -7,7 +7,6 @@ * Author: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> */ -#include <common.h> #include <clk.h> #include <dm.h> #include <dwmmc.h> diff --git a/drivers/mmc/socfpga_dw_mmc.c b/drivers/mmc/socfpga_dw_mmc.c index 387cb8b6b50..f738019b835 100644 --- a/drivers/mmc/socfpga_dw_mmc.c +++ b/drivers/mmc/socfpga_dw_mmc.c @@ -3,7 +3,6 @@ * (C) Copyright 2013 Altera Corporation <www.altera.com> */ -#include <common.h> #include <log.h> #include <asm/arch/clock_manager.h> #include <asm/arch/secure_reg_helper.h> diff --git a/drivers/mmc/sti_sdhci.c b/drivers/mmc/sti_sdhci.c index 23a1dd43c9b..91018b7e21a 100644 --- a/drivers/mmc/sti_sdhci.c +++ b/drivers/mmc/sti_sdhci.c @@ -4,7 +4,6 @@ * Author(s): Patrice Chotard, <patrice.chotard@foss.st.com> for STMicroelectronics. */ -#include <common.h> #include <dm.h> #include <log.h> #include <mmc.h> diff --git a/drivers/mmc/stm32_sdmmc2.c b/drivers/mmc/stm32_sdmmc2.c index 39ae79ba129..9483fb57daf 100644 --- a/drivers/mmc/stm32_sdmmc2.c +++ b/drivers/mmc/stm32_sdmmc2.c @@ -6,7 +6,6 @@ #define LOG_CATEGORY UCLASS_MMC -#include <common.h> #include <clk.h> #include <cpu_func.h> #include <dm.h> diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index 714706d2411..0b56d1405be 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -13,7 +13,6 @@ * proper DM_MMC implementation at the end. */ -#include <common.h> #include <dm.h> #include <errno.h> #include <log.h> diff --git a/drivers/mmc/tangier_sdhci.c b/drivers/mmc/tangier_sdhci.c index 11564273324..ae65c310b68 100644 --- a/drivers/mmc/tangier_sdhci.c +++ b/drivers/mmc/tangier_sdhci.c @@ -2,7 +2,6 @@ /* * Copyright (c) 2017 Intel Corporation */ -#include <common.h> #include <dm.h> #include <dm/device.h> #include <linux/io.h> diff --git a/drivers/mmc/tegra_mmc.c b/drivers/mmc/tegra_mmc.c index c01fb3d0165..5ed7f01d3f3 100644 --- a/drivers/mmc/tegra_mmc.c +++ b/drivers/mmc/tegra_mmc.c @@ -7,7 +7,6 @@ */ #include <bouncebuf.h> -#include <common.h> #include <dm.h> #include <errno.h> #include <log.h> diff --git a/drivers/mmc/tmio-common.c b/drivers/mmc/tmio-common.c index 719c4830bc3..0b396122b46 100644 --- a/drivers/mmc/tmio-common.c +++ b/drivers/mmc/tmio-common.c @@ -4,7 +4,6 @@ * Author: Masahiro Yamada <yamada.masahiro@socionext.com> */ -#include <common.h> #include <clk.h> #include <cpu_func.h> #include <fdtdec.h> diff --git a/drivers/mmc/uniphier-sd.c b/drivers/mmc/uniphier-sd.c index 8cde4308aae..5b3650d52ee 100644 --- a/drivers/mmc/uniphier-sd.c +++ b/drivers/mmc/uniphier-sd.c @@ -4,7 +4,6 @@ * Author: Masahiro Yamada <yamada.masahiro@socionext.com> */ -#include <common.h> #include <clk.h> #include <fdtdec.h> #include <malloc.h> diff --git a/drivers/mmc/xenon_sdhci.c b/drivers/mmc/xenon_sdhci.c index 27dbe0404e0..0e4902fab77 100644 --- a/drivers/mmc/xenon_sdhci.c +++ b/drivers/mmc/xenon_sdhci.c @@ -14,7 +14,6 @@ * Stefan Roese <sr@denx.de> */ -#include <common.h> #include <dm.h> #include <fdtdec.h> #include <asm/global_data.h> diff --git a/drivers/mmc/zynq_sdhci.c b/drivers/mmc/zynq_sdhci.c index 935540d1719..898be5a0913 100644 --- a/drivers/mmc/zynq_sdhci.c +++ b/drivers/mmc/zynq_sdhci.c @@ -7,7 +7,6 @@ */ #include <clk.h> -#include <common.h> #include <dm.h> #include <fdtdec.h> #include <linux/delay.h> |