Tom Rini 2023-04-10 08:32:11 -04:00
commit 11c25c6df0
10 changed files with 63 additions and 73 deletions

View File

@ -41,7 +41,7 @@ int board_early_init_f(void)
#if IS_ENABLED(CONFIG_LOAD_ENV_FROM_MMC_BOOT_PARTITION)
uint board_mmc_get_env_part(struct mmc *mmc)
{
uint part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
uint part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
if (part == 7)
part = 0;

View File

@ -175,7 +175,7 @@ static int do_mmcinfo(struct cmd_tbl *cmdtp, int flag, int argc,
curr_device = 0;
else {
puts("No MMC device available\n");
return 1;
return CMD_RET_FAILURE;
}
}
@ -927,7 +927,7 @@ static int mmc_partconf_print(struct mmc *mmc, const char *varname)
static int do_mmc_partconf(struct cmd_tbl *cmdtp, int flag,
int argc, char *const argv[])
{
int dev;
int ret, dev;
struct mmc *mmc;
u8 ack, part_num, access;
@ -953,13 +953,17 @@ static int do_mmc_partconf(struct cmd_tbl *cmdtp, int flag,
access = dectoul(argv[4], NULL);
/* acknowledge to be sent during boot operation */
return mmc_set_part_conf(mmc, ack, part_num, access);
ret = mmc_set_part_conf(mmc, ack, part_num, access);
if (ret != 0)
return CMD_RET_FAILURE;
return CMD_RET_SUCCESS;
}
static int do_mmc_rst_func(struct cmd_tbl *cmdtp, int flag,
int argc, char *const argv[])
{
int dev;
int ret, dev;
struct mmc *mmc;
u8 enable;
@ -988,7 +992,11 @@ static int do_mmc_rst_func(struct cmd_tbl *cmdtp, int flag,
return CMD_RET_FAILURE;
}
return mmc_set_rst_n_function(mmc, enable);
ret = mmc_set_rst_n_function(mmc, enable);
if (ret != 0)
return CMD_RET_FAILURE;
return CMD_RET_SUCCESS;
}
#endif
static int do_mmc_setdsr(struct cmd_tbl *cmdtp, int flag,

View File

@ -223,8 +223,7 @@ static int mmc_burn_image(size_t image_size)
orig_part = mmc->block_dev.hwpart;
#endif
part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
if (part == 7)
part = 0;

View File

@ -378,7 +378,7 @@ int default_spl_mmc_emmc_boot_partition(struct mmc *mmc)
* 1 and 2 match up to boot0 / boot1 and 7 is user data
* which is the first physical partition (0).
*/
part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
if (part == 7)
part = 0;
#endif

View File

@ -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.

View File

@ -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) {

View File

@ -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;

View File

@ -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 */

View File

@ -241,6 +241,7 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
#define EXT_CSD_HC_WP_GRP_SIZE 221 /* RO */
#define EXT_CSD_HC_ERASE_GRP_SIZE 224 /* RO */
#define EXT_CSD_BOOT_MULT 226 /* RO */
#define EXT_CSD_SEC_FEATURE 231 /* RO */
#define EXT_CSD_GENERIC_CMD6_TIME 248 /* RO */
#define EXT_CSD_BKOPS_SUPPORT 502 /* RO */
@ -315,6 +316,8 @@ static inline bool mmc_is_tuning_cmd(uint cmdidx)
#define EXT_CSD_WR_DATA_REL_USR (1 << 0) /* user data area WR_REL */
#define EXT_CSD_WR_DATA_REL_GP(x) (1 << ((x)+1)) /* GP part (x+1) WR_REL */
#define EXT_CSD_SEC_FEATURE_TRIM_EN (1 << 4) /* Support secure & insecure trim */
#define R1_ILLEGAL_COMMAND (1 << 22)
#define R1_APP_CMD (1 << 5)
@ -687,6 +690,7 @@ struct mmc {
uint tran_speed;
uint legacy_speed; /* speed for the legacy mode provided by the card */
uint read_bl_len;
bool can_trim;
#if CONFIG_IS_ENABLED(MMC_WRITE)
uint write_bl_len;
uint erase_grp_size; /* in 512-byte sectors */

View File

@ -30,7 +30,7 @@ static int dm_test_mmc_blk(struct unit_test_state *uts)
struct udevice *dev;
struct blk_desc *dev_desc;
int i;
char write[1024], read[1024];
char write[4 * 512], read[4 * 512];
ut_assertok(uclass_get_device(UCLASS_MMC, 0, &dev));
ut_assertok(blk_get_device_by_str("mmc", "0", &dev_desc));
@ -39,14 +39,14 @@ static int dm_test_mmc_blk(struct unit_test_state *uts)
ut_asserteq(512, dev_desc->blksz);
for (i = 0; i < sizeof(write); i++)
write[i] = i;
ut_asserteq(2, blk_dwrite(dev_desc, 0, 2, write));
ut_asserteq(2, blk_dread(dev_desc, 0, 2, read));
ut_asserteq(4, blk_dwrite(dev_desc, 0, 4, write));
ut_asserteq(4, blk_dread(dev_desc, 0, 4, read));
ut_asserteq_mem(write, read, sizeof(write));
/* Now erase them */
memset(write, '\0', sizeof(write));
ut_asserteq(2, blk_derase(dev_desc, 0, 2));
ut_asserteq(2, blk_dread(dev_desc, 0, 2, read));
/* Now erase two of them [1 - 2] and verify all blocks */
memset(&write[512], '\0', 2 * 512);
ut_asserteq(2, blk_derase(dev_desc, 1, 2));
ut_asserteq(4, blk_dread(dev_desc, 0, 4, read));
ut_asserteq_mem(write, read, sizeof(write));
return 0;