aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorTom Rini <trini@konsulko.com>2023-04-10 08:32:11 -0400
committerTom Rini <trini@konsulko.com>2023-04-10 08:32:11 -0400
commit11c25c6df0b56ee7eee2c4ddc7f075880daeb8c7 (patch)
treee4660057ce4770ebd72f05a365b01240b10a467c /drivers
parent7daa8dd59bc8455a43cdd2d0e34206e406e5cdcc (diff)
parentfbf368f176641029ac30843d4d3dbf26e384df38 (diff)
Merge https://source.denx.de/u-boot/custodians/u-boot-mmc
Diffstat (limited to 'drivers')
-rw-r--r--drivers/mmc/Kconfig1
-rw-r--r--drivers/mmc/mmc.c3
-rw-r--r--drivers/mmc/mmc_write.c34
-rw-r--r--drivers/mmc/mv_sdhci.c55
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 */