diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/Kconfig | 15 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 67 | ||||
-rw-r--r-- | drivers/mmc/mmc_legacy.c | 32 | ||||
-rw-r--r-- | drivers/mmc/s5p_sdhci.c | 2 |
4 files changed, 113 insertions, 3 deletions
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 24f4b285a9..5e84a41491 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -26,6 +26,21 @@ config DM_MMC_OPS option will be removed as soon as all DM_MMC drivers use it, as it will the only supported behaviour. +config SPL_MMC_TINY + bool "Tiny MMC framework in SPL" + help + Enable MMC framework tinification support. This option is useful if + if your SPL is extremely size constrained. Heed the warning, enable + this option if and only if you know exactly what you are doing, if + you are reading this help text, you most likely have no idea :-) + + The MMC framework is reduced to bare minimum to be useful. No malloc + support is needed for the MMC framework operation with this option + enabled. The framework supports exactly one MMC device and exactly + one MMC driver. The MMC driver can be adjusted to avoid any malloc + operations too, which can remove the need for malloc support in SPL + and thus further reduce footprint. + config MSM_SDHCI bool "Qualcomm SDHCI controller" depends on DM_MMC && BLK && DM_MMC_OPS diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index d6b7e4f510..9f8368a123 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -30,6 +30,29 @@ static const unsigned int sd_au_size[] = { SZ_16M / 512, (SZ_16M + SZ_8M) / 512, SZ_32M / 512, SZ_64M / 512, }; +#if CONFIG_IS_ENABLED(MMC_TINY) +static struct mmc mmc_static; +struct mmc *find_mmc_device(int dev_num) +{ + return &mmc_static; +} + +void mmc_do_preinit(void) +{ + struct mmc *m = &mmc_static; +#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT + mmc_set_preinit(m, 1); +#endif + if (m->preinit) + mmc_start_init(m); +} + +struct blk_desc *mmc_get_blk_desc(struct mmc *mmc) +{ + return &mmc->block_dev; +} +#endif + #ifndef CONFIG_DM_MMC_OPS __weak int board_mmc_getwp(struct mmc *mmc) { @@ -259,7 +282,11 @@ ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt, if (!mmc) return 0; - err = blk_dselect_hwpart(block_dev, block_dev->hwpart); + if (CONFIG_IS_ENABLED(MMC_TINY)) + err = mmc_switch_part(mmc, block_dev->hwpart); + else + err = blk_dselect_hwpart(block_dev, block_dev->hwpart); + if (err < 0) return 0; @@ -1708,7 +1735,7 @@ static int mmc_complete_init(struct mmc *mmc) int mmc_init(struct mmc *mmc) { int err = 0; - unsigned start; + __maybe_unused unsigned start; #ifdef CONFIG_DM_MMC struct mmc_uclass_priv *upriv = dev_get_uclass_priv(mmc->dev); @@ -1804,8 +1831,10 @@ int mmc_initialize(bd_t *bis) initialized = 1; #ifndef CONFIG_BLK +#if !CONFIG_IS_ENABLED(MMC_TINY) mmc_list_init(); #endif +#endif ret = mmc_probe(bis); if (ret) return ret; @@ -1817,3 +1846,37 @@ int mmc_initialize(bd_t *bis) mmc_do_preinit(); return 0; } + +#ifdef CONFIG_CMD_BKOPS_ENABLE +int mmc_set_bkops_enable(struct mmc *mmc) +{ + int err; + ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN); + + err = mmc_send_ext_csd(mmc, ext_csd); + if (err) { + puts("Could not get ext_csd register values\n"); + return err; + } + + if (!(ext_csd[EXT_CSD_BKOPS_SUPPORT] & 0x1)) { + puts("Background operations not supported on device\n"); + return -EMEDIUMTYPE; + } + + if (ext_csd[EXT_CSD_BKOPS_EN] & 0x1) { + puts("Background operations already enabled\n"); + return 0; + } + + err = mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BKOPS_EN, 1); + if (err) { + puts("Failed to enable manual background operations\n"); + return err; + } + + puts("Enabled manual background operations\n"); + + return 0; +} +#endif diff --git a/drivers/mmc/mmc_legacy.c b/drivers/mmc/mmc_legacy.c index 25361d10f6..bdf9d984dd 100644 --- a/drivers/mmc/mmc_legacy.c +++ b/drivers/mmc/mmc_legacy.c @@ -13,6 +13,7 @@ static struct list_head mmc_devices; static int cur_dev_num = -1; +#if !CONFIG_IS_ENABLED(MMC_TINY) struct mmc *find_mmc_device(int dev_num) { struct mmc *m; @@ -62,6 +63,7 @@ void mmc_do_preinit(void) mmc_start_init(m); } } +#endif void mmc_list_init(void) { @@ -109,6 +111,35 @@ void print_mmc_devices(char separator) void print_mmc_devices(char separator) { } #endif +#if CONFIG_IS_ENABLED(MMC_TINY) +static struct mmc mmc_static = { + .dsr_imp = 0, + .dsr = 0xffffffff, + .block_dev = { + .if_type = IF_TYPE_MMC, + .removable = 1, + .devnum = 0, + .block_read = mmc_bread, + .block_write = mmc_bwrite, + .block_erase = mmc_berase, + .part_type = 0, + }, +}; + +struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) +{ + struct mmc *mmc = &mmc_static; + + mmc->cfg = cfg; + mmc->priv = priv; + + return mmc; +} + +void mmc_destroy(struct mmc *mmc) +{ +} +#else struct mmc *mmc_create(const struct mmc_config *cfg, void *priv) { struct blk_desc *bdesc; @@ -157,6 +188,7 @@ void mmc_destroy(struct mmc *mmc) /* only freeing memory for now */ free(mmc); } +#endif static int mmc_select_hwpartp(struct blk_desc *desc, int hwpart) { diff --git a/drivers/mmc/s5p_sdhci.c b/drivers/mmc/s5p_sdhci.c index b329bef5fd..ac737e0f0f 100644 --- a/drivers/mmc/s5p_sdhci.c +++ b/drivers/mmc/s5p_sdhci.c @@ -152,7 +152,7 @@ static int sdhci_get_config(const void *blob, int node, struct sdhci_host *host) /* Get device id */ dev_id = pinmux_decode_periph_id(blob, node); - if (dev_id < PERIPH_ID_SDMMC0 && dev_id > PERIPH_ID_SDMMC3) { + if (dev_id < PERIPH_ID_SDMMC0 || dev_id > PERIPH_ID_SDMMC3) { debug("MMC: Can't get device id\n"); return -EINVAL; } |