diff options
author | Tom Rini <trini@konsulko.com> | 2023-04-10 08:32:11 -0400 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-04-10 08:32:11 -0400 |
commit | 11c25c6df0b56ee7eee2c4ddc7f075880daeb8c7 (patch) | |
tree | e4660057ce4770ebd72f05a365b01240b10a467c /drivers | |
parent | 7daa8dd59bc8455a43cdd2d0e34206e406e5cdcc (diff) | |
parent | fbf368f176641029ac30843d4d3dbf26e384df38 (diff) |
Merge https://source.denx.de/u-boot/custodians/u-boot-mmc
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/mmc/Kconfig | 1 | ||||
-rw-r--r-- | drivers/mmc/mmc.c | 3 | ||||
-rw-r--r-- | drivers/mmc/mmc_write.c | 34 | ||||
-rw-r--r-- | drivers/mmc/mv_sdhci.c | 55 |
4 files changed, 36 insertions, 57 deletions
diff --git a/drivers/mmc/Kconfig b/drivers/mmc/Kconfig index 80641e1393..59fb0fb50f 100644 --- a/drivers/mmc/Kconfig +++ b/drivers/mmc/Kconfig @@ -621,6 +621,7 @@ config MMC_SDHCI_MV bool "SDHCI support on Marvell platform" depends on ARCH_MVEBU depends on MMC_SDHCI + depends on DM_MMC help This selects the Secure Digital Host Controller Interface on Marvell platform. diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index dde251c87b..1af6af82e6 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -2432,6 +2432,9 @@ static int mmc_startup_v4(struct mmc *mmc) mmc->wr_rel_set = ext_csd[EXT_CSD_WR_REL_SET]; + mmc->can_trim = + !!(ext_csd[EXT_CSD_SEC_FEATURE] & EXT_CSD_SEC_FEATURE_TRIM_EN); + return 0; error: if (mmc->ext_csd) { diff --git a/drivers/mmc/mmc_write.c b/drivers/mmc/mmc_write.c index 5b7aeeb012..a6f93380dd 100644 --- a/drivers/mmc/mmc_write.c +++ b/drivers/mmc/mmc_write.c @@ -15,7 +15,7 @@ #include <linux/math64.h> #include "mmc_private.h" -static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt) +static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt, u32 args) { struct mmc_cmd cmd; ulong end; @@ -52,7 +52,7 @@ static ulong mmc_erase_t(struct mmc *mmc, ulong start, lbaint_t blkcnt) goto err_out; cmd.cmdidx = MMC_CMD_ERASE; - cmd.cmdarg = MMC_ERASE_ARG; + cmd.cmdarg = args ? args : MMC_ERASE_ARG; cmd.resp_type = MMC_RSP_R1b; err = mmc_send_cmd(mmc, &cmd, NULL); @@ -77,7 +77,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt) #endif int dev_num = block_dev->devnum; int err = 0; - u32 start_rem, blkcnt_rem; + u32 start_rem, blkcnt_rem, erase_args = 0; struct mmc *mmc = find_mmc_device(dev_num); lbaint_t blk = 0, blk_r = 0; int timeout_ms = 1000; @@ -97,13 +97,25 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt) */ err = div_u64_rem(start, mmc->erase_grp_size, &start_rem); err = div_u64_rem(blkcnt, mmc->erase_grp_size, &blkcnt_rem); - if (start_rem || blkcnt_rem) - printf("\n\nCaution! Your devices Erase group is 0x%x\n" - "The erase range would be change to " - "0x" LBAF "~0x" LBAF "\n\n", - mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1), - ((start + blkcnt + mmc->erase_grp_size - 1) - & ~(mmc->erase_grp_size - 1)) - 1); + if (start_rem || blkcnt_rem) { + if (mmc->can_trim) { + /* Trim function applies the erase operation to write + * blocks instead of erase groups. + */ + erase_args = MMC_TRIM_ARG; + } else { + /* The card ignores all LSB's below the erase group + * size, rounding down the addess to a erase group + * boundary. + */ + printf("\n\nCaution! Your devices Erase group is 0x%x\n" + "The erase range would be change to " + "0x" LBAF "~0x" LBAF "\n\n", + mmc->erase_grp_size, start & ~(mmc->erase_grp_size - 1), + ((start + blkcnt + mmc->erase_grp_size - 1) + & ~(mmc->erase_grp_size - 1)) - 1); + } + } while (blk < blkcnt) { if (IS_SD(mmc) && mmc->ssr.au) { @@ -113,7 +125,7 @@ ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt) blk_r = ((blkcnt - blk) > mmc->erase_grp_size) ? mmc->erase_grp_size : (blkcnt - blk); } - err = mmc_erase_t(mmc, start + blk, blk_r); + err = mmc_erase_t(mmc, start + blk, blk_r, erase_args); if (err) break; diff --git a/drivers/mmc/mv_sdhci.c b/drivers/mmc/mv_sdhci.c index 336ebf1410..dbdd671c88 100644 --- a/drivers/mmc/mv_sdhci.c +++ b/drivers/mmc/mv_sdhci.c @@ -15,6 +15,13 @@ #define SDHCI_WINDOW_CTRL(win) (0x4080 + ((win) << 4)) #define SDHCI_WINDOW_BASE(win) (0x4084 + ((win) << 4)) +DECLARE_GLOBAL_DATA_PTR; + +struct mv_sdhci_plat { + struct mmc_config cfg; + struct mmc mmc; +}; + static void sdhci_mvebu_mbus_config(void __iomem *base) { const struct mbus_dram_target_info *dram; @@ -40,47 +47,6 @@ static void sdhci_mvebu_mbus_config(void __iomem *base) } } -#ifndef CONFIG_DM_MMC - -#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS -static struct sdhci_ops mv_ops; -#endif /* CONFIG_MMC_SDHCI_IO_ACCESSORS */ - -int mv_sdh_init(unsigned long regbase, u32 max_clk, u32 min_clk, u32 quirks) -{ - struct sdhci_host *host = NULL; - host = calloc(1, sizeof(*host)); - if (!host) { - printf("sdh_host malloc fail!\n"); - return -ENOMEM; - } - - host->name = MVSDH_NAME; - host->ioaddr = (void *)regbase; - host->quirks = quirks; - host->max_clk = max_clk; -#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS - memset(&mv_ops, 0, sizeof(struct sdhci_ops)); - host->ops = &mv_ops; -#endif - - if (CONFIG_IS_ENABLED(ARCH_MVEBU)) { - /* Configure SDHCI MBUS mbus bridge windows */ - sdhci_mvebu_mbus_config((void __iomem *)regbase); - } - - return add_sdhci(host, 0, min_clk); -} - -#else - -DECLARE_GLOBAL_DATA_PTR; - -struct mv_sdhci_plat { - struct mmc_config cfg; - struct mmc mmc; -}; - static int mv_sdhci_probe(struct udevice *dev) { struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev); @@ -103,10 +69,8 @@ static int mv_sdhci_probe(struct udevice *dev) if (ret) return ret; - if (CONFIG_IS_ENABLED(ARCH_MVEBU)) { - /* Configure SDHCI MBUS mbus bridge windows */ - sdhci_mvebu_mbus_config(host->ioaddr); - } + /* Configure SDHCI MBUS mbus bridge windows */ + sdhci_mvebu_mbus_config(host->ioaddr); upriv->mmc = host->mmc; @@ -135,4 +99,3 @@ U_BOOT_DRIVER(mv_sdhci_drv) = { .priv_auto = sizeof(struct sdhci_host), .plat_auto = sizeof(struct mv_sdhci_plat), }; -#endif /* CONFIG_DM_MMC */ |