mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-19 13:41:31 +00:00
Merge git://git.denx.de/u-boot-mmc
This commit is contained in:
commit
3dde8f2037
23 changed files with 1745 additions and 469 deletions
21
cmd/mmc.c
21
cmd/mmc.c
|
@ -23,7 +23,12 @@ static void print_mmcinfo(struct mmc *mmc)
|
||||||
(mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
|
(mmc->cid[1] >> 24), (mmc->cid[1] >> 16) & 0xff,
|
||||||
(mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
|
(mmc->cid[1] >> 8) & 0xff, mmc->cid[1] & 0xff);
|
||||||
|
|
||||||
printf("Tran Speed: %d\n", mmc->tran_speed);
|
printf("Bus Speed: %d\n", mmc->clock);
|
||||||
|
#if CONFIG_IS_ENABLED(MMC_VERBOSE)
|
||||||
|
printf("Mode : %s\n", mmc_mode_name(mmc->selected_mode));
|
||||||
|
mmc_dump_capabilities("card capabilities", mmc->card_caps);
|
||||||
|
mmc_dump_capabilities("host capabilities", mmc->host_caps);
|
||||||
|
#endif
|
||||||
printf("Rd Block Len: %d\n", mmc->read_bl_len);
|
printf("Rd Block Len: %d\n", mmc->read_bl_len);
|
||||||
|
|
||||||
printf("%s version %d.%d", IS_SD(mmc) ? "SD" : "MMC",
|
printf("%s version %d.%d", IS_SD(mmc) ? "SD" : "MMC",
|
||||||
|
@ -40,15 +45,19 @@ static void print_mmcinfo(struct mmc *mmc)
|
||||||
printf("Bus Width: %d-bit%s\n", mmc->bus_width,
|
printf("Bus Width: %d-bit%s\n", mmc->bus_width,
|
||||||
mmc->ddr_mode ? " DDR" : "");
|
mmc->ddr_mode ? " DDR" : "");
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(MMC_WRITE)
|
||||||
puts("Erase Group Size: ");
|
puts("Erase Group Size: ");
|
||||||
print_size(((u64)mmc->erase_grp_size) << 9, "\n");
|
print_size(((u64)mmc->erase_grp_size) << 9, "\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!IS_SD(mmc) && mmc->version >= MMC_VERSION_4_41) {
|
if (!IS_SD(mmc) && mmc->version >= MMC_VERSION_4_41) {
|
||||||
bool has_enh = (mmc->part_support & ENHNCD_SUPPORT) != 0;
|
bool has_enh = (mmc->part_support & ENHNCD_SUPPORT) != 0;
|
||||||
bool usr_enh = has_enh && (mmc->part_attr & EXT_CSD_ENH_USR);
|
bool usr_enh = has_enh && (mmc->part_attr & EXT_CSD_ENH_USR);
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
|
||||||
puts("HC WP Group Size: ");
|
puts("HC WP Group Size: ");
|
||||||
print_size(((u64)mmc->hc_wp_grp_size) << 9, "\n");
|
print_size(((u64)mmc->hc_wp_grp_size) << 9, "\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
puts("User Capacity: ");
|
puts("User Capacity: ");
|
||||||
print_size(mmc->capacity_user, usr_enh ? " ENH" : "");
|
print_size(mmc->capacity_user, usr_enh ? " ENH" : "");
|
||||||
|
@ -297,6 +306,8 @@ static int do_mmc_read(cmd_tbl_t *cmdtp, int flag,
|
||||||
|
|
||||||
return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
|
return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(MMC_WRITE)
|
||||||
static int do_mmc_write(cmd_tbl_t *cmdtp, int flag,
|
static int do_mmc_write(cmd_tbl_t *cmdtp, int flag,
|
||||||
int argc, char * const argv[])
|
int argc, char * const argv[])
|
||||||
{
|
{
|
||||||
|
@ -355,6 +366,8 @@ static int do_mmc_erase(cmd_tbl_t *cmdtp, int flag,
|
||||||
|
|
||||||
return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
|
return (n == cnt) ? CMD_RET_SUCCESS : CMD_RET_FAILURE;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static int do_mmc_rescan(cmd_tbl_t *cmdtp, int flag,
|
static int do_mmc_rescan(cmd_tbl_t *cmdtp, int flag,
|
||||||
int argc, char * const argv[])
|
int argc, char * const argv[])
|
||||||
{
|
{
|
||||||
|
@ -433,6 +446,7 @@ static int do_mmc_list(cmd_tbl_t *cmdtp, int flag,
|
||||||
return CMD_RET_SUCCESS;
|
return CMD_RET_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
|
||||||
static int parse_hwpart_user(struct mmc_hwpart_conf *pconf,
|
static int parse_hwpart_user(struct mmc_hwpart_conf *pconf,
|
||||||
int argc, char * const argv[])
|
int argc, char * const argv[])
|
||||||
{
|
{
|
||||||
|
@ -582,6 +596,7 @@ static int do_mmc_hwpartition(cmd_tbl_t *cmdtp, int flag,
|
||||||
return CMD_RET_FAILURE;
|
return CMD_RET_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_SUPPORT_EMMC_BOOT
|
#ifdef CONFIG_SUPPORT_EMMC_BOOT
|
||||||
static int do_mmc_bootbus(cmd_tbl_t *cmdtp, int flag,
|
static int do_mmc_bootbus(cmd_tbl_t *cmdtp, int flag,
|
||||||
|
@ -785,13 +800,17 @@ static int do_mmc_bkops_enable(cmd_tbl_t *cmdtp, int flag,
|
||||||
static cmd_tbl_t cmd_mmc[] = {
|
static cmd_tbl_t cmd_mmc[] = {
|
||||||
U_BOOT_CMD_MKENT(info, 1, 0, do_mmcinfo, "", ""),
|
U_BOOT_CMD_MKENT(info, 1, 0, do_mmcinfo, "", ""),
|
||||||
U_BOOT_CMD_MKENT(read, 4, 1, do_mmc_read, "", ""),
|
U_BOOT_CMD_MKENT(read, 4, 1, do_mmc_read, "", ""),
|
||||||
|
#if CONFIG_IS_ENABLED(MMC_WRITE)
|
||||||
U_BOOT_CMD_MKENT(write, 4, 0, do_mmc_write, "", ""),
|
U_BOOT_CMD_MKENT(write, 4, 0, do_mmc_write, "", ""),
|
||||||
U_BOOT_CMD_MKENT(erase, 3, 0, do_mmc_erase, "", ""),
|
U_BOOT_CMD_MKENT(erase, 3, 0, do_mmc_erase, "", ""),
|
||||||
|
#endif
|
||||||
U_BOOT_CMD_MKENT(rescan, 1, 1, do_mmc_rescan, "", ""),
|
U_BOOT_CMD_MKENT(rescan, 1, 1, do_mmc_rescan, "", ""),
|
||||||
U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""),
|
U_BOOT_CMD_MKENT(part, 1, 1, do_mmc_part, "", ""),
|
||||||
U_BOOT_CMD_MKENT(dev, 3, 0, do_mmc_dev, "", ""),
|
U_BOOT_CMD_MKENT(dev, 3, 0, do_mmc_dev, "", ""),
|
||||||
U_BOOT_CMD_MKENT(list, 1, 1, do_mmc_list, "", ""),
|
U_BOOT_CMD_MKENT(list, 1, 1, do_mmc_list, "", ""),
|
||||||
|
#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
|
||||||
U_BOOT_CMD_MKENT(hwpartition, 28, 0, do_mmc_hwpartition, "", ""),
|
U_BOOT_CMD_MKENT(hwpartition, 28, 0, do_mmc_hwpartition, "", ""),
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_SUPPORT_EMMC_BOOT
|
#ifdef CONFIG_SUPPORT_EMMC_BOOT
|
||||||
U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""),
|
U_BOOT_CMD_MKENT(bootbus, 5, 0, do_mmc_bootbus, "", ""),
|
||||||
U_BOOT_CMD_MKENT(bootpart-resize, 4, 0, do_mmc_boot_resize, "", ""),
|
U_BOOT_CMD_MKENT(bootpart-resize, 4, 0, do_mmc_boot_resize, "", ""),
|
||||||
|
|
|
@ -110,7 +110,7 @@ static ulong get_load_addr(void)
|
||||||
/********************************************************************
|
/********************************************************************
|
||||||
* eMMC services
|
* eMMC services
|
||||||
********************************************************************/
|
********************************************************************/
|
||||||
#ifdef CONFIG_DM_MMC
|
#if CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(MMC_WRITE)
|
||||||
static int mmc_burn_image(size_t image_size)
|
static int mmc_burn_image(size_t image_size)
|
||||||
{
|
{
|
||||||
struct mmc *mmc;
|
struct mmc *mmc;
|
||||||
|
|
|
@ -109,6 +109,7 @@ obj-$(CONFIG_IO_TRACE) += iotrace.o
|
||||||
obj-y += memsize.o
|
obj-y += memsize.o
|
||||||
obj-y += stdio.o
|
obj-y += stdio.o
|
||||||
|
|
||||||
|
ifndef CONFIG_SPL_BUILD
|
||||||
# This option is not just y/n - it can have a numeric value
|
# This option is not just y/n - it can have a numeric value
|
||||||
ifdef CONFIG_FASTBOOT_FLASH
|
ifdef CONFIG_FASTBOOT_FLASH
|
||||||
obj-y += image-sparse.o
|
obj-y += image-sparse.o
|
||||||
|
@ -119,6 +120,7 @@ ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
|
||||||
obj-y += fb_nand.o
|
obj-y += fb_nand.o
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_CMD_EEPROM_LAYOUT
|
ifdef CONFIG_CMD_EEPROM_LAYOUT
|
||||||
obj-y += eeprom/eeprom_field.o eeprom/eeprom_layout.o
|
obj-y += eeprom/eeprom_field.o eeprom/eeprom_layout.o
|
||||||
|
|
|
@ -301,6 +301,7 @@ config SPL_ENV_SUPPORT
|
||||||
config SPL_SAVEENV
|
config SPL_SAVEENV
|
||||||
bool "Support save environment"
|
bool "Support save environment"
|
||||||
depends on SPL_ENV_SUPPORT
|
depends on SPL_ENV_SUPPORT
|
||||||
|
select SPL_MMC_WRITE if ENV_IS_IN_MMC
|
||||||
help
|
help
|
||||||
Enable save environment support in SPL after setenv. By default
|
Enable save environment support in SPL after setenv. By default
|
||||||
the saveenv option is not provided in SPL, but some boards need
|
the saveenv option is not provided in SPL, but some boards need
|
||||||
|
@ -415,6 +416,14 @@ config SPL_MMC_SUPPORT
|
||||||
this option to build the drivers in drivers/mmc as part of an SPL
|
this option to build the drivers in drivers/mmc as part of an SPL
|
||||||
build.
|
build.
|
||||||
|
|
||||||
|
config SPL_MMC_WRITE
|
||||||
|
bool "MMC/SD/SDIO card support for write operations in SPL"
|
||||||
|
depends on SPL_MMC_SUPPORT
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
Enable write access to MMC and SD Cards in SPL
|
||||||
|
|
||||||
|
|
||||||
config SPL_MPC8XXX_INIT_DDR_SUPPORT
|
config SPL_MPC8XXX_INIT_DDR_SUPPORT
|
||||||
bool "Support MPC8XXX DDR init"
|
bool "Support MPC8XXX DDR init"
|
||||||
help
|
help
|
||||||
|
|
|
@ -13,10 +13,12 @@ CONFIG_ANDROID_BOOT_IMAGE=y
|
||||||
CONFIG_FIT_IMAGE_POST_PROCESS=y
|
CONFIG_FIT_IMAGE_POST_PROCESS=y
|
||||||
CONFIG_SPL_LOAD_FIT=y
|
CONFIG_SPL_LOAD_FIT=y
|
||||||
CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
|
CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
|
||||||
|
CONFIG_LOGLEVEL=3
|
||||||
CONFIG_SYS_CONSOLE_INFO_QUIET=y
|
CONFIG_SYS_CONSOLE_INFO_QUIET=y
|
||||||
CONFIG_VERSION_VARIABLE=y
|
CONFIG_VERSION_VARIABLE=y
|
||||||
CONFIG_ARCH_MISC_INIT=y
|
CONFIG_ARCH_MISC_INIT=y
|
||||||
CONFIG_SPL=y
|
CONFIG_SPL=y
|
||||||
|
CONFIG_SPL_FIT_IMAGE_TINY=y
|
||||||
# CONFIG_SPL_ENV_SUPPORT is not set
|
# CONFIG_SPL_ENV_SUPPORT is not set
|
||||||
# CONFIG_SPL_EXT_SUPPORT is not set
|
# CONFIG_SPL_EXT_SUPPORT is not set
|
||||||
CONFIG_SPL_MTD_SUPPORT=y
|
CONFIG_SPL_MTD_SUPPORT=y
|
||||||
|
@ -37,6 +39,7 @@ CONFIG_DFU_RAM=y
|
||||||
CONFIG_DM_I2C=y
|
CONFIG_DM_I2C=y
|
||||||
CONFIG_MISC=y
|
CONFIG_MISC=y
|
||||||
CONFIG_DM_MMC=y
|
CONFIG_DM_MMC=y
|
||||||
|
# CONFIG_MMC_HW_PARTITIONING is not set
|
||||||
CONFIG_MMC_OMAP_HS=y
|
CONFIG_MMC_OMAP_HS=y
|
||||||
CONFIG_NAND=y
|
CONFIG_NAND=y
|
||||||
CONFIG_SPI_FLASH=y
|
CONFIG_SPI_FLASH=y
|
||||||
|
@ -60,5 +63,6 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x0451
|
||||||
CONFIG_USB_GADGET_PRODUCT_NUM=0xd022
|
CONFIG_USB_GADGET_PRODUCT_NUM=0xd022
|
||||||
CONFIG_USB_GADGET_DOWNLOAD=y
|
CONFIG_USB_GADGET_DOWNLOAD=y
|
||||||
CONFIG_USB_ETHER=y
|
CONFIG_USB_ETHER=y
|
||||||
|
CONFIG_SPL_TINY_MEMSET=y
|
||||||
CONFIG_RSA=y
|
CONFIG_RSA=y
|
||||||
CONFIG_LZO=y
|
CONFIG_LZO=y
|
||||||
|
|
|
@ -8,6 +8,7 @@ CONFIG_SPL_MMC_SUPPORT=y
|
||||||
CONFIG_SPL_SERIAL_SUPPORT=y
|
CONFIG_SPL_SERIAL_SUPPORT=y
|
||||||
CONFIG_SPL_NAND_SUPPORT=y
|
CONFIG_SPL_NAND_SUPPORT=y
|
||||||
CONFIG_BOOTDELAY=3
|
CONFIG_BOOTDELAY=3
|
||||||
|
CONFIG_LOGLEVEL=3
|
||||||
CONFIG_VERSION_VARIABLE=y
|
CONFIG_VERSION_VARIABLE=y
|
||||||
# CONFIG_DISPLAY_CPUINFO is not set
|
# CONFIG_DISPLAY_CPUINFO is not set
|
||||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||||
|
|
|
@ -25,6 +25,7 @@ CONFIG_CMD_UBI=y
|
||||||
CONFIG_ISO_PARTITION=y
|
CONFIG_ISO_PARTITION=y
|
||||||
CONFIG_ENV_IS_IN_NAND=y
|
CONFIG_ENV_IS_IN_NAND=y
|
||||||
CONFIG_MVSATA_IDE=y
|
CONFIG_MVSATA_IDE=y
|
||||||
|
# CONFIG_MMC_HW_PARTITIONING is not set
|
||||||
CONFIG_SYS_NS16550=y
|
CONFIG_SYS_NS16550=y
|
||||||
CONFIG_USB=y
|
CONFIG_USB=y
|
||||||
CONFIG_USB_EHCI_HCD=y
|
CONFIG_USB_EHCI_HCD=y
|
||||||
|
|
|
@ -25,6 +25,7 @@ CONFIG_CMD_UBI=y
|
||||||
CONFIG_ISO_PARTITION=y
|
CONFIG_ISO_PARTITION=y
|
||||||
CONFIG_ENV_IS_IN_NAND=y
|
CONFIG_ENV_IS_IN_NAND=y
|
||||||
CONFIG_MVSATA_IDE=y
|
CONFIG_MVSATA_IDE=y
|
||||||
|
# CONFIG_MMC_HW_PARTITIONING is not set
|
||||||
CONFIG_SYS_NS16550=y
|
CONFIG_SYS_NS16550=y
|
||||||
CONFIG_USB=y
|
CONFIG_USB=y
|
||||||
CONFIG_USB_EHCI_HCD=y
|
CONFIG_USB_EHCI_HCD=y
|
||||||
|
|
|
@ -25,6 +25,7 @@ CONFIG_CMD_UBI=y
|
||||||
CONFIG_ISO_PARTITION=y
|
CONFIG_ISO_PARTITION=y
|
||||||
CONFIG_ENV_IS_IN_NAND=y
|
CONFIG_ENV_IS_IN_NAND=y
|
||||||
CONFIG_MVSATA_IDE=y
|
CONFIG_MVSATA_IDE=y
|
||||||
|
# CONFIG_MMC_HW_PARTITIONING is not set
|
||||||
CONFIG_SYS_NS16550=y
|
CONFIG_SYS_NS16550=y
|
||||||
CONFIG_USB=y
|
CONFIG_USB=y
|
||||||
CONFIG_USB_EHCI_HCD=y
|
CONFIG_USB_EHCI_HCD=y
|
||||||
|
|
|
@ -10,6 +10,13 @@ config MMC
|
||||||
If you want MMC/SD/SDIO support, you should say Y here and
|
If you want MMC/SD/SDIO support, you should say Y here and
|
||||||
also to your specific host controller driver.
|
also to your specific host controller driver.
|
||||||
|
|
||||||
|
config MMC_WRITE
|
||||||
|
bool "support for MMC/SD write operations"
|
||||||
|
depends on MMC
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enable write access to MMC and SD Cards
|
||||||
|
|
||||||
config DM_MMC
|
config DM_MMC
|
||||||
bool "Enable MMC controllers using Driver Model"
|
bool "Enable MMC controllers using Driver Model"
|
||||||
depends on DM
|
depends on DM
|
||||||
|
@ -42,6 +49,75 @@ config ARM_PL180_MMCI
|
||||||
If you have an ARM(R) platform with a Multimedia Card slot,
|
If you have an ARM(R) platform with a Multimedia Card slot,
|
||||||
say Y or M here.
|
say Y or M here.
|
||||||
|
|
||||||
|
config MMC_QUIRKS
|
||||||
|
bool "Enable quirks"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Some cards and hosts may sometimes behave unexpectedly (quirks).
|
||||||
|
This option enable workarounds to handle those quirks. Some of them
|
||||||
|
are enabled by default, other may require additionnal flags or are
|
||||||
|
enabled by the host driver.
|
||||||
|
|
||||||
|
config MMC_HW_PARTITIONING
|
||||||
|
bool "Support for HW partitioning command(eMMC)"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
This adds a command and an API to do hardware partitioning on eMMC
|
||||||
|
devices.
|
||||||
|
|
||||||
|
config MMC_IO_VOLTAGE
|
||||||
|
bool "Support IO voltage configuration"
|
||||||
|
help
|
||||||
|
IO voltage configuration allows selecting the voltage level of the IO
|
||||||
|
lines (not the level of main supply). This is required for UHS
|
||||||
|
support. For eMMC this not mandatory, but not enabling this option may
|
||||||
|
prevent the driver of using the faster modes.
|
||||||
|
|
||||||
|
config SPL_MMC_IO_VOLTAGE
|
||||||
|
bool "Support IO voltage configuration in SPL"
|
||||||
|
default n
|
||||||
|
help
|
||||||
|
IO voltage configuration allows selecting the voltage level of the IO
|
||||||
|
lines (not the level of main supply). This is required for UHS
|
||||||
|
support. For eMMC this not mandatory, but not enabling this option may
|
||||||
|
prevent the driver of using the faster modes.
|
||||||
|
|
||||||
|
config MMC_UHS_SUPPORT
|
||||||
|
bool "enable UHS support"
|
||||||
|
depends on MMC_IO_VOLTAGE
|
||||||
|
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
|
||||||
|
frequency can go up to 208MHz (SDR104)
|
||||||
|
|
||||||
|
config SPL_MMC_UHS_SUPPORT
|
||||||
|
bool "enable UHS support in SPL"
|
||||||
|
depends on SPL_MMC_IO_VOLTAGE
|
||||||
|
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
|
||||||
|
frequency can go up to 208MHz (SDR104)
|
||||||
|
|
||||||
|
config MMC_HS200_SUPPORT
|
||||||
|
bool "enable HS200 support"
|
||||||
|
help
|
||||||
|
The HS200 mode is support by some eMMC. The bus frequency is up to
|
||||||
|
200MHz. This mode requires tuning the IO.
|
||||||
|
|
||||||
|
|
||||||
|
config SPL_MMC_HS200_SUPPORT
|
||||||
|
bool "enable HS200 support in SPL"
|
||||||
|
help
|
||||||
|
The HS200 mode is support by some eMMC. The bus frequency is up to
|
||||||
|
200MHz. This mode requires tuning the IO.
|
||||||
|
|
||||||
|
config MMC_VERBOSE
|
||||||
|
bool "Output more information about the MMC"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Enable the output of more information about the card such as the
|
||||||
|
operating mode.
|
||||||
|
|
||||||
config SPL_MMC_TINY
|
config SPL_MMC_TINY
|
||||||
bool "Tiny MMC framework in SPL"
|
bool "Tiny MMC framework in SPL"
|
||||||
help
|
help
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
|
|
||||||
obj-y += mmc.o
|
obj-y += mmc.o
|
||||||
obj-$(CONFIG_$(SPL_)DM_MMC) += mmc-uclass.o
|
obj-$(CONFIG_$(SPL_)DM_MMC) += mmc-uclass.o
|
||||||
|
obj-$(CONFIG_$(SPL_)MMC_WRITE) += mmc_write.o
|
||||||
|
|
||||||
ifndef CONFIG_$(SPL_)BLK
|
ifndef CONFIG_$(SPL_)BLK
|
||||||
obj-y += mmc_legacy.o
|
obj-y += mmc_legacy.o
|
||||||
|
@ -16,9 +17,6 @@ obj-$(CONFIG_SUPPORT_EMMC_BOOT) += mmc_boot.o
|
||||||
|
|
||||||
ifdef CONFIG_SPL_BUILD
|
ifdef CONFIG_SPL_BUILD
|
||||||
obj-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o
|
obj-$(CONFIG_SPL_MMC_BOOT) += fsl_esdhc_spl.o
|
||||||
obj-$(CONFIG_SPL_SAVEENV) += mmc_write.o
|
|
||||||
else
|
|
||||||
obj-y += mmc_write.o
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
|
obj-$(CONFIG_ARM_PL180_MMCI) += arm_pl180_mmci.o
|
||||||
|
|
|
@ -168,6 +168,7 @@ static int exynos_dwmci_get_config(const void *blob, int node,
|
||||||
|
|
||||||
if (host->dev_index > 4) {
|
if (host->dev_index > 4) {
|
||||||
printf("DWMMC%d: Can't get the dev index\n", host->dev_index);
|
printf("DWMMC%d: Can't get the dev index\n", host->dev_index);
|
||||||
|
free(priv);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,6 +179,7 @@ static int exynos_dwmci_get_config(const void *blob, int node,
|
||||||
base = fdtdec_get_addr(blob, node, "reg");
|
base = fdtdec_get_addr(blob, node, "reg");
|
||||||
if (!base) {
|
if (!base) {
|
||||||
printf("DWMMC%d: Can't get base address\n", host->dev_index);
|
printf("DWMMC%d: Can't get base address\n", host->dev_index);
|
||||||
|
free(priv);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
host->ioaddr = (void *)base;
|
host->ioaddr = (void *)base;
|
||||||
|
@ -187,6 +189,7 @@ static int exynos_dwmci_get_config(const void *blob, int node,
|
||||||
if (err) {
|
if (err) {
|
||||||
printf("DWMMC%d: Can't get sdr-timings for devider\n",
|
printf("DWMMC%d: Can't get sdr-timings for devider\n",
|
||||||
host->dev_index);
|
host->dev_index);
|
||||||
|
free(priv);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -647,7 +647,11 @@ static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
|
||||||
esdhc_write32(®s->clktunectrlstatus, 0x0);
|
esdhc_write32(®s->clktunectrlstatus, 0x0);
|
||||||
|
|
||||||
/* Put VEND_SPEC to default value */
|
/* Put VEND_SPEC to default value */
|
||||||
esdhc_write32(®s->vendorspec, VENDORSPEC_INIT);
|
if (priv->vs18_enable)
|
||||||
|
esdhc_write32(®s->vendorspec, (VENDORSPEC_INIT |
|
||||||
|
ESDHC_VENDORSPEC_VSELECT));
|
||||||
|
else
|
||||||
|
esdhc_write32(®s->vendorspec, VENDORSPEC_INIT);
|
||||||
|
|
||||||
/* Disable DLL_CTRL delay line */
|
/* Disable DLL_CTRL delay line */
|
||||||
esdhc_write32(®s->dllctrl, 0x0);
|
esdhc_write32(®s->dllctrl, 0x0);
|
||||||
|
@ -665,7 +669,7 @@ static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Set the initial clock speed */
|
/* Set the initial clock speed */
|
||||||
mmc_set_clock(mmc, 400000);
|
mmc_set_clock(mmc, 400000, false);
|
||||||
|
|
||||||
/* Disable the BRR and BWR bits in IRQSTAT */
|
/* Disable the BRR and BWR bits in IRQSTAT */
|
||||||
esdhc_clrbits32(®s->irqstaten, IRQSTATEN_BRR | IRQSTATEN_BWR);
|
esdhc_clrbits32(®s->irqstaten, IRQSTATEN_BRR | IRQSTATEN_BWR);
|
||||||
|
@ -676,9 +680,6 @@ static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
|
||||||
/* Set timout to the maximum value */
|
/* Set timout to the maximum value */
|
||||||
esdhc_clrsetbits32(®s->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
|
esdhc_clrsetbits32(®s->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
|
||||||
|
|
||||||
if (priv->vs18_enable)
|
|
||||||
esdhc_setbits32(®s->vendorspec, ESDHC_VENDORSPEC_VSELECT);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,20 @@ static void dump_cmd(u32 cmdr, u32 arg, u32 status, const char* msg)
|
||||||
cmdr, cmdr & 0x3F, arg, status, msg);
|
cmdr, cmdr & 0x3F, arg, status, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void mci_set_blklen(atmel_mci_t *mci, int blklen)
|
||||||
|
{
|
||||||
|
unsigned int version = atmel_mci_get_version(mci);
|
||||||
|
|
||||||
|
blklen &= 0xfffc;
|
||||||
|
|
||||||
|
/* MCI IP version >= 0x200 has blkr */
|
||||||
|
if (version >= 0x200)
|
||||||
|
writel(MMCI_BFINS(BLKLEN, blklen, readl(&mci->blkr)),
|
||||||
|
&mci->blkr);
|
||||||
|
else
|
||||||
|
writel(MMCI_BFINS(BLKLEN, blklen, readl(&mci->mr)), &mci->mr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Setup for MCI Clock and Block Size */
|
/* Setup for MCI Clock and Block Size */
|
||||||
#ifdef CONFIG_DM_MMC
|
#ifdef CONFIG_DM_MMC
|
||||||
static void mci_set_mode(struct udevice *dev, u32 hz, u32 blklen)
|
static void mci_set_mode(struct udevice *dev, u32 hz, u32 blklen)
|
||||||
|
@ -124,7 +138,6 @@ static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen)
|
||||||
priv->curr_clk = bus_hz / (clkdiv * 2 + clkodd + 2);
|
priv->curr_clk = bus_hz / (clkdiv * 2 + clkodd + 2);
|
||||||
else
|
else
|
||||||
priv->curr_clk = (bus_hz / (clkdiv + 1)) / 2;
|
priv->curr_clk = (bus_hz / (clkdiv + 1)) / 2;
|
||||||
blklen &= 0xfffc;
|
|
||||||
|
|
||||||
mr = MMCI_BF(CLKDIV, clkdiv);
|
mr = MMCI_BF(CLKDIV, clkdiv);
|
||||||
|
|
||||||
|
@ -138,14 +151,10 @@ static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen)
|
||||||
*/
|
*/
|
||||||
if (version >= 0x500)
|
if (version >= 0x500)
|
||||||
mr |= MMCI_BF(CLKODD, clkodd);
|
mr |= MMCI_BF(CLKODD, clkodd);
|
||||||
else
|
|
||||||
mr |= MMCI_BF(BLKLEN, blklen);
|
|
||||||
|
|
||||||
writel(mr, &mci->mr);
|
writel(mr, &mci->mr);
|
||||||
|
|
||||||
/* MCI IP version >= 0x200 has blkr */
|
mci_set_blklen(mci, blklen);
|
||||||
if (version >= 0x200)
|
|
||||||
writel(MMCI_BF(BLKLEN, blklen), &mci->blkr);
|
|
||||||
|
|
||||||
if (mmc->card_caps & mmc->cfg->host_caps & MMC_MODE_HS)
|
if (mmc->card_caps & mmc->cfg->host_caps & MMC_MODE_HS)
|
||||||
writel(MMCI_BIT(HSMODE), &mci->cfg);
|
writel(MMCI_BIT(HSMODE), &mci->cfg);
|
||||||
|
@ -236,7 +245,6 @@ static int atmel_mci_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
|
||||||
{
|
{
|
||||||
struct atmel_mci_plat *plat = dev_get_platdata(dev);
|
struct atmel_mci_plat *plat = dev_get_platdata(dev);
|
||||||
struct atmel_mci_priv *priv = dev_get_priv(dev);
|
struct atmel_mci_priv *priv = dev_get_priv(dev);
|
||||||
struct mmc *mmc = mmc_get_mmc_dev(dev);
|
|
||||||
atmel_mci_t *mci = plat->mci;
|
atmel_mci_t *mci = plat->mci;
|
||||||
#else
|
#else
|
||||||
static int
|
static int
|
||||||
|
@ -257,11 +265,13 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
||||||
/* Figure out the transfer arguments */
|
/* Figure out the transfer arguments */
|
||||||
cmdr = mci_encode_cmd(cmd, data, &error_flags);
|
cmdr = mci_encode_cmd(cmd, data, &error_flags);
|
||||||
|
|
||||||
|
mci_set_blklen(mci, data->blocksize);
|
||||||
|
|
||||||
/* For multi blocks read/write, set the block register */
|
/* For multi blocks read/write, set the block register */
|
||||||
if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK)
|
if ((cmd->cmdidx == MMC_CMD_READ_MULTIPLE_BLOCK)
|
||||||
|| (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK))
|
|| (cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK))
|
||||||
writel(data->blocks | MMCI_BF(BLKLEN, mmc->read_bl_len),
|
writel(data->blocks | MMCI_BF(BLKLEN, data->blocksize),
|
||||||
&mci->blkr);
|
&mci->blkr);
|
||||||
|
|
||||||
/* Send the command */
|
/* Send the command */
|
||||||
writel(cmd->cmdarg, &mci->argr);
|
writel(cmd->cmdarg, &mci->argr);
|
||||||
|
@ -295,17 +305,15 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
||||||
if (data) {
|
if (data) {
|
||||||
u32 word_count, block_count;
|
u32 word_count, block_count;
|
||||||
u32* ioptr;
|
u32* ioptr;
|
||||||
u32 sys_blocksize, dummy, i;
|
u32 i;
|
||||||
u32 (*mci_data_op)
|
u32 (*mci_data_op)
|
||||||
(atmel_mci_t *mci, u32* data, u32 error_flags);
|
(atmel_mci_t *mci, u32* data, u32 error_flags);
|
||||||
|
|
||||||
if (data->flags & MMC_DATA_READ) {
|
if (data->flags & MMC_DATA_READ) {
|
||||||
mci_data_op = mci_data_read;
|
mci_data_op = mci_data_read;
|
||||||
sys_blocksize = mmc->read_bl_len;
|
|
||||||
ioptr = (u32*)data->dest;
|
ioptr = (u32*)data->dest;
|
||||||
} else {
|
} else {
|
||||||
mci_data_op = mci_data_write;
|
mci_data_op = mci_data_write;
|
||||||
sys_blocksize = mmc->write_bl_len;
|
|
||||||
ioptr = (u32*)data->src;
|
ioptr = (u32*)data->src;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -328,16 +336,6 @@ mci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, struct mmc_data *data)
|
||||||
1, cnt, 0);
|
1, cnt, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#ifdef DEBUG
|
|
||||||
if (!status && word_count < (sys_blocksize / 4))
|
|
||||||
printf("filling rest of block...\n");
|
|
||||||
#endif
|
|
||||||
/* fill the rest of a full block */
|
|
||||||
while (!status && word_count < (sys_blocksize / 4)) {
|
|
||||||
status = mci_data_op(mci, &dummy,
|
|
||||||
error_flags);
|
|
||||||
word_count++;
|
|
||||||
}
|
|
||||||
if (status) {
|
if (status) {
|
||||||
dump_cmd(cmdr, cmd->cmdarg, status,
|
dump_cmd(cmdr, cmd->cmdarg, status,
|
||||||
"Data Transfer Failed");
|
"Data Transfer Failed");
|
||||||
|
|
|
@ -250,7 +250,7 @@ static int meson_mmc_probe(struct udevice *dev)
|
||||||
mmc->priv = pdata;
|
mmc->priv = pdata;
|
||||||
upriv->mmc = mmc;
|
upriv->mmc = mmc;
|
||||||
|
|
||||||
mmc_set_clock(mmc, cfg->f_min);
|
mmc_set_clock(mmc, cfg->f_min, false);
|
||||||
|
|
||||||
/* reset all status bits */
|
/* reset all status bits */
|
||||||
meson_write(mmc, STATUS_MASK, MESON_SD_EMMC_STATUS);
|
meson_write(mmc, STATUS_MASK, MESON_SD_EMMC_STATUS);
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <dm/device-internal.h>
|
#include <dm/device-internal.h>
|
||||||
#include <dm/lists.h>
|
#include <dm/lists.h>
|
||||||
#include <dm/root.h>
|
|
||||||
#include "mmc_private.h"
|
#include "mmc_private.h"
|
||||||
|
|
||||||
DECLARE_GLOBAL_DATA_PTR;
|
DECLARE_GLOBAL_DATA_PTR;
|
||||||
|
@ -51,6 +50,35 @@ int mmc_set_ios(struct mmc *mmc)
|
||||||
return dm_mmc_set_ios(mmc->dev);
|
return dm_mmc_set_ios(mmc->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void dm_mmc_send_init_stream(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct dm_mmc_ops *ops = mmc_get_ops(dev);
|
||||||
|
|
||||||
|
if (ops->send_init_stream)
|
||||||
|
ops->send_init_stream(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mmc_send_init_stream(struct mmc *mmc)
|
||||||
|
{
|
||||||
|
dm_mmc_send_init_stream(mmc->dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
|
||||||
|
int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout)
|
||||||
|
{
|
||||||
|
struct dm_mmc_ops *ops = mmc_get_ops(dev);
|
||||||
|
|
||||||
|
if (!ops->wait_dat0)
|
||||||
|
return -ENOSYS;
|
||||||
|
return ops->wait_dat0(dev, state, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mmc_wait_dat0(struct mmc *mmc, int state, int timeout)
|
||||||
|
{
|
||||||
|
return dm_mmc_wait_dat0(mmc->dev, state, timeout);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int dm_mmc_get_wp(struct udevice *dev)
|
int dm_mmc_get_wp(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct dm_mmc_ops *ops = mmc_get_ops(dev);
|
struct dm_mmc_ops *ops = mmc_get_ops(dev);
|
||||||
|
@ -79,6 +107,73 @@ int mmc_getcd(struct mmc *mmc)
|
||||||
return dm_mmc_get_cd(mmc->dev);
|
return dm_mmc_get_cd(mmc->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MMC_SUPPORTS_TUNING
|
||||||
|
int dm_mmc_execute_tuning(struct udevice *dev, uint opcode)
|
||||||
|
{
|
||||||
|
struct dm_mmc_ops *ops = mmc_get_ops(dev);
|
||||||
|
|
||||||
|
if (!ops->execute_tuning)
|
||||||
|
return -ENOSYS;
|
||||||
|
return ops->execute_tuning(dev, opcode);
|
||||||
|
}
|
||||||
|
|
||||||
|
int mmc_execute_tuning(struct mmc *mmc, uint opcode)
|
||||||
|
{
|
||||||
|
return dm_mmc_execute_tuning(mmc->dev, opcode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg)
|
||||||
|
{
|
||||||
|
int val;
|
||||||
|
|
||||||
|
val = dev_read_u32_default(dev, "bus-width", 1);
|
||||||
|
|
||||||
|
switch (val) {
|
||||||
|
case 0x8:
|
||||||
|
cfg->host_caps |= MMC_MODE_8BIT;
|
||||||
|
/* fall through */
|
||||||
|
case 0x4:
|
||||||
|
cfg->host_caps |= MMC_MODE_4BIT;
|
||||||
|
/* fall through */
|
||||||
|
case 0x1:
|
||||||
|
cfg->host_caps |= MMC_MODE_1BIT;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
debug("warning: %s invalid bus-width property. using 1-bit\n",
|
||||||
|
dev_read_name(dev));
|
||||||
|
cfg->host_caps |= MMC_MODE_1BIT;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg->f_max = dev_read_u32_default(dev, "max-frequency", 52000000);
|
||||||
|
|
||||||
|
if (dev_read_bool(dev, "cap-sd-highspeed"))
|
||||||
|
cfg->host_caps |= MMC_CAP(SD_HS);
|
||||||
|
if (dev_read_bool(dev, "cap-mmc-highspeed"))
|
||||||
|
cfg->host_caps |= MMC_CAP(MMC_HS);
|
||||||
|
if (dev_read_bool(dev, "sd-uhs-sdr12"))
|
||||||
|
cfg->host_caps |= MMC_CAP(UHS_SDR12);
|
||||||
|
if (dev_read_bool(dev, "sd-uhs-sdr25"))
|
||||||
|
cfg->host_caps |= MMC_CAP(UHS_SDR25);
|
||||||
|
if (dev_read_bool(dev, "sd-uhs-sdr50"))
|
||||||
|
cfg->host_caps |= MMC_CAP(UHS_SDR50);
|
||||||
|
if (dev_read_bool(dev, "sd-uhs-sdr104"))
|
||||||
|
cfg->host_caps |= MMC_CAP(UHS_SDR104);
|
||||||
|
if (dev_read_bool(dev, "sd-uhs-ddr50"))
|
||||||
|
cfg->host_caps |= MMC_CAP(UHS_DDR50);
|
||||||
|
if (dev_read_bool(dev, "mmc-ddr-1_8v"))
|
||||||
|
cfg->host_caps |= MMC_CAP(MMC_DDR_52);
|
||||||
|
if (dev_read_bool(dev, "mmc-ddr-1_2v"))
|
||||||
|
cfg->host_caps |= MMC_CAP(MMC_DDR_52);
|
||||||
|
if (dev_read_bool(dev, "mmc-hs200-1_8v"))
|
||||||
|
cfg->host_caps |= MMC_CAP(MMC_HS_200);
|
||||||
|
if (dev_read_bool(dev, "mmc-hs200-1_2v"))
|
||||||
|
cfg->host_caps |= MMC_CAP(MMC_HS_200);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
struct mmc *mmc_get_mmc_dev(struct udevice *dev)
|
struct mmc *mmc_get_mmc_dev(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct mmc_uclass_priv *upriv;
|
struct mmc_uclass_priv *upriv;
|
||||||
|
@ -275,7 +370,7 @@ static int mmc_blk_probe(struct udevice *dev)
|
||||||
|
|
||||||
static const struct blk_ops mmc_blk_ops = {
|
static const struct blk_ops mmc_blk_ops = {
|
||||||
.read = mmc_bread,
|
.read = mmc_bread,
|
||||||
#ifndef CONFIG_SPL_BUILD
|
#if CONFIG_IS_ENABLED(MMC_WRITE)
|
||||||
.write = mmc_bwrite,
|
.write = mmc_bwrite,
|
||||||
.erase = mmc_berase,
|
.erase = mmc_berase,
|
||||||
#endif
|
#endif
|
||||||
|
|
1642
drivers/mmc/mmc.c
1642
drivers/mmc/mmc.c
File diff suppressed because it is too large
Load diff
|
@ -28,7 +28,7 @@ ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
|
||||||
void *dst);
|
void *dst);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if !(defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SPL_SAVEENV))
|
#if CONFIG_IS_ENABLED(MMC_WRITE)
|
||||||
|
|
||||||
#if CONFIG_IS_ENABLED(BLK)
|
#if CONFIG_IS_ENABLED(BLK)
|
||||||
ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
|
ulong mmc_bwrite(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
|
||||||
|
@ -40,7 +40,7 @@ ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
|
||||||
ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt);
|
ulong mmc_berase(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#else /* CONFIG_SPL_BUILD and CONFIG_SPL_SAVEENV is not defined */
|
#else /* CONFIG_SPL_MMC_WRITE is not defined */
|
||||||
|
|
||||||
/* declare dummies to reduce code size. */
|
/* declare dummies to reduce code size. */
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,9 @@
|
||||||
#include <mmc.h>
|
#include <mmc.h>
|
||||||
#include <part.h>
|
#include <part.h>
|
||||||
#include <i2c.h>
|
#include <i2c.h>
|
||||||
#include <twl4030.h>
|
#if defined(CONFIG_OMAP54XX) || defined(CONFIG_OMAP44XX)
|
||||||
#include <twl6030.h>
|
|
||||||
#include <palmas.h>
|
#include <palmas.h>
|
||||||
|
#endif
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include <asm/arch/mmc_host_def.h>
|
#include <asm/arch/mmc_host_def.h>
|
||||||
#if !defined(CONFIG_SOC_KEYSTONE)
|
#if !defined(CONFIG_SOC_KEYSTONE)
|
||||||
|
|
|
@ -48,9 +48,12 @@ static int sandbox_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
|
||||||
cmd->response[1] = 10 << 16; /* 1 << block_len */
|
cmd->response[1] = 10 << 16; /* 1 << block_len */
|
||||||
break;
|
break;
|
||||||
case SD_CMD_SWITCH_FUNC: {
|
case SD_CMD_SWITCH_FUNC: {
|
||||||
|
if (!data)
|
||||||
|
break;
|
||||||
u32 *resp = (u32 *)data->dest;
|
u32 *resp = (u32 *)data->dest;
|
||||||
|
|
||||||
resp[7] = cpu_to_be32(SD_HIGHSPEED_BUSY);
|
resp[7] = cpu_to_be32(SD_HIGHSPEED_BUSY);
|
||||||
|
if ((cmd->cmdarg & 0xF) == UHS_SDR12_BUS_SPEED)
|
||||||
|
resp[4] = (cmd->cmdarg & 0xF) << 24;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MMC_CMD_READ_SINGLE_BLOCK:
|
case MMC_CMD_READ_SINGLE_BLOCK:
|
||||||
|
|
|
@ -157,7 +157,6 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
|
||||||
/* Timeout unit - ms */
|
/* Timeout unit - ms */
|
||||||
static unsigned int cmd_timeout = SDHCI_CMD_DEFAULT_TIMEOUT;
|
static unsigned int cmd_timeout = SDHCI_CMD_DEFAULT_TIMEOUT;
|
||||||
|
|
||||||
sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
|
|
||||||
mask = SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT;
|
mask = SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT;
|
||||||
|
|
||||||
/* We shouldn't wait for data inihibit for stop commands, even
|
/* We shouldn't wait for data inihibit for stop commands, even
|
||||||
|
@ -181,6 +180,8 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
|
||||||
udelay(1000);
|
udelay(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
|
||||||
|
|
||||||
mask = SDHCI_INT_RESPONSE;
|
mask = SDHCI_INT_RESPONSE;
|
||||||
if (!(cmd->resp_type & MMC_RSP_PRESENT))
|
if (!(cmd->resp_type & MMC_RSP_PRESENT))
|
||||||
flags = SDHCI_CMD_RESP_NONE;
|
flags = SDHCI_CMD_RESP_NONE;
|
||||||
|
@ -201,7 +202,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
|
||||||
flags |= SDHCI_CMD_DATA;
|
flags |= SDHCI_CMD_DATA;
|
||||||
|
|
||||||
/* Set Transfer mode regarding to data flag */
|
/* Set Transfer mode regarding to data flag */
|
||||||
if (data != 0) {
|
if (data) {
|
||||||
sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL);
|
sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL);
|
||||||
mode = SDHCI_TRNS_BLK_CNT_EN;
|
mode = SDHCI_TRNS_BLK_CNT_EN;
|
||||||
trans_bytes = data->blocks * data->blocksize;
|
trans_bytes = data->blocks * data->blocksize;
|
||||||
|
@ -249,7 +250,7 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
|
||||||
|
|
||||||
sdhci_writel(host, cmd->cmdarg, SDHCI_ARGUMENT);
|
sdhci_writel(host, cmd->cmdarg, SDHCI_ARGUMENT);
|
||||||
#ifdef CONFIG_MMC_SDHCI_SDMA
|
#ifdef CONFIG_MMC_SDHCI_SDMA
|
||||||
if (data != 0) {
|
if (data) {
|
||||||
trans_bytes = ALIGN(trans_bytes, CONFIG_SYS_CACHELINE_SIZE);
|
trans_bytes = ALIGN(trans_bytes, CONFIG_SYS_CACHELINE_SIZE);
|
||||||
flush_cache(start_addr, trans_bytes);
|
flush_cache(start_addr, trans_bytes);
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,36 +47,6 @@ int pmic_set_output(struct pmic *p, u32 reg, int out, int on)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pmic_show_info(struct pmic *p)
|
|
||||||
{
|
|
||||||
printf("PMIC: %s\n", p->name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int pmic_dump(struct pmic *p)
|
|
||||||
{
|
|
||||||
int i, ret;
|
|
||||||
u32 val;
|
|
||||||
|
|
||||||
if (!p) {
|
|
||||||
puts("Wrong PMIC name!\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
pmic_show_info(p);
|
|
||||||
for (i = 0; i < p->number_of_regs; i++) {
|
|
||||||
ret = pmic_reg_read(p, i, &val);
|
|
||||||
if (ret)
|
|
||||||
puts("PMIC: Registers dump failed\n");
|
|
||||||
|
|
||||||
if (!(i % 8))
|
|
||||||
printf("\n0x%02x: ", i);
|
|
||||||
|
|
||||||
printf("%08x ", val);
|
|
||||||
}
|
|
||||||
puts("\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pmic *pmic_alloc(void)
|
struct pmic *pmic_alloc(void)
|
||||||
{
|
{
|
||||||
struct pmic *p;
|
struct pmic *p;
|
||||||
|
@ -108,7 +78,33 @@ struct pmic *pmic_get(const char *s)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *power_get_interface(int interface)
|
#ifndef CONFIG_SPL_BUILD
|
||||||
|
static int pmic_dump(struct pmic *p)
|
||||||
|
{
|
||||||
|
int i, ret;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
if (!p) {
|
||||||
|
puts("Wrong PMIC name!\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("PMIC: %s\n", p->name);
|
||||||
|
for (i = 0; i < p->number_of_regs; i++) {
|
||||||
|
ret = pmic_reg_read(p, i, &val);
|
||||||
|
if (ret)
|
||||||
|
puts("PMIC: Registers dump failed\n");
|
||||||
|
|
||||||
|
if (!(i % 8))
|
||||||
|
printf("\n0x%02x: ", i);
|
||||||
|
|
||||||
|
printf("%08x ", val);
|
||||||
|
}
|
||||||
|
puts("\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *power_get_interface(int interface)
|
||||||
{
|
{
|
||||||
const char *power_interface[] = {"I2C", "SPI", "|+|-|"};
|
const char *power_interface[] = {"I2C", "SPI", "|+|-|"};
|
||||||
return power_interface[interface];
|
return power_interface[interface];
|
||||||
|
@ -125,7 +121,7 @@ static void pmic_list_names(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
static int do_pmic(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||||
{
|
{
|
||||||
u32 ret, reg, val;
|
u32 ret, reg, val;
|
||||||
char *cmd, *name;
|
char *cmd, *name;
|
||||||
|
@ -221,3 +217,4 @@ U_BOOT_CMD(
|
||||||
"pmic name bat state - write register\n"
|
"pmic name bat state - write register\n"
|
||||||
"pmic name bat charge - write register\n"
|
"pmic name bat charge - write register\n"
|
||||||
);
|
);
|
||||||
|
#endif
|
||||||
|
|
212
include/mmc.h
212
include/mmc.h
|
@ -15,6 +15,13 @@
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <part.h>
|
#include <part.h>
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(MMC_HS200_SUPPORT)
|
||||||
|
#define MMC_SUPPORTS_TUNING
|
||||||
|
#endif
|
||||||
|
#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
|
||||||
|
#define MMC_SUPPORTS_TUNING
|
||||||
|
#endif
|
||||||
|
|
||||||
/* SD/MMC version bits; 8 flags, 8 major, 8 minor, 8 change */
|
/* SD/MMC version bits; 8 flags, 8 major, 8 minor, 8 change */
|
||||||
#define SD_VERSION_SD (1U << 31)
|
#define SD_VERSION_SD (1U << 31)
|
||||||
#define MMC_VERSION_MMC (1U << 30)
|
#define MMC_VERSION_MMC (1U << 30)
|
||||||
|
@ -52,12 +59,17 @@
|
||||||
#define MMC_VERSION_5_0 MAKE_MMC_VERSION(5, 0, 0)
|
#define MMC_VERSION_5_0 MAKE_MMC_VERSION(5, 0, 0)
|
||||||
#define MMC_VERSION_5_1 MAKE_MMC_VERSION(5, 1, 0)
|
#define MMC_VERSION_5_1 MAKE_MMC_VERSION(5, 1, 0)
|
||||||
|
|
||||||
#define MMC_MODE_HS (1 << 0)
|
#define MMC_CAP(mode) (1 << mode)
|
||||||
#define MMC_MODE_HS_52MHz (1 << 1)
|
#define MMC_MODE_HS (MMC_CAP(MMC_HS) | MMC_CAP(SD_HS))
|
||||||
#define MMC_MODE_4BIT (1 << 2)
|
#define MMC_MODE_HS_52MHz MMC_CAP(MMC_HS_52)
|
||||||
#define MMC_MODE_8BIT (1 << 3)
|
#define MMC_MODE_DDR_52MHz MMC_CAP(MMC_DDR_52)
|
||||||
#define MMC_MODE_SPI (1 << 4)
|
#define MMC_MODE_HS200 MMC_CAP(MMC_HS_200)
|
||||||
#define MMC_MODE_DDR_52MHz (1 << 5)
|
|
||||||
|
#define MMC_MODE_8BIT BIT(30)
|
||||||
|
#define MMC_MODE_4BIT BIT(29)
|
||||||
|
#define MMC_MODE_1BIT BIT(28)
|
||||||
|
#define MMC_MODE_SPI BIT(27)
|
||||||
|
|
||||||
|
|
||||||
#define SD_DATA_4BIT 0x00040000
|
#define SD_DATA_4BIT 0x00040000
|
||||||
|
|
||||||
|
@ -82,6 +94,8 @@
|
||||||
#define MMC_CMD_SET_BLOCKLEN 16
|
#define MMC_CMD_SET_BLOCKLEN 16
|
||||||
#define MMC_CMD_READ_SINGLE_BLOCK 17
|
#define MMC_CMD_READ_SINGLE_BLOCK 17
|
||||||
#define MMC_CMD_READ_MULTIPLE_BLOCK 18
|
#define MMC_CMD_READ_MULTIPLE_BLOCK 18
|
||||||
|
#define MMC_CMD_SEND_TUNING_BLOCK 19
|
||||||
|
#define MMC_CMD_SEND_TUNING_BLOCK_HS200 21
|
||||||
#define MMC_CMD_SET_BLOCK_COUNT 23
|
#define MMC_CMD_SET_BLOCK_COUNT 23
|
||||||
#define MMC_CMD_WRITE_SINGLE_BLOCK 24
|
#define MMC_CMD_WRITE_SINGLE_BLOCK 24
|
||||||
#define MMC_CMD_WRITE_MULTIPLE_BLOCK 25
|
#define MMC_CMD_WRITE_MULTIPLE_BLOCK 25
|
||||||
|
@ -109,12 +123,34 @@
|
||||||
#define SD_CMD_APP_SEND_OP_COND 41
|
#define SD_CMD_APP_SEND_OP_COND 41
|
||||||
#define SD_CMD_APP_SEND_SCR 51
|
#define SD_CMD_APP_SEND_SCR 51
|
||||||
|
|
||||||
|
static inline bool mmc_is_tuning_cmd(uint cmdidx)
|
||||||
|
{
|
||||||
|
if ((cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200) ||
|
||||||
|
(cmdidx == MMC_CMD_SEND_TUNING_BLOCK))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/* SCR definitions in different words */
|
/* SCR definitions in different words */
|
||||||
#define SD_HIGHSPEED_BUSY 0x00020000
|
#define SD_HIGHSPEED_BUSY 0x00020000
|
||||||
#define SD_HIGHSPEED_SUPPORTED 0x00020000
|
#define SD_HIGHSPEED_SUPPORTED 0x00020000
|
||||||
|
|
||||||
|
#define UHS_SDR12_BUS_SPEED 0
|
||||||
|
#define HIGH_SPEED_BUS_SPEED 1
|
||||||
|
#define UHS_SDR25_BUS_SPEED 1
|
||||||
|
#define UHS_SDR50_BUS_SPEED 2
|
||||||
|
#define UHS_SDR104_BUS_SPEED 3
|
||||||
|
#define UHS_DDR50_BUS_SPEED 4
|
||||||
|
|
||||||
|
#define SD_MODE_UHS_SDR12 BIT(UHS_SDR12_BUS_SPEED)
|
||||||
|
#define SD_MODE_UHS_SDR25 BIT(UHS_SDR25_BUS_SPEED)
|
||||||
|
#define SD_MODE_UHS_SDR50 BIT(UHS_SDR50_BUS_SPEED)
|
||||||
|
#define SD_MODE_UHS_SDR104 BIT(UHS_SDR104_BUS_SPEED)
|
||||||
|
#define SD_MODE_UHS_DDR50 BIT(UHS_DDR50_BUS_SPEED)
|
||||||
|
|
||||||
#define OCR_BUSY 0x80000000
|
#define OCR_BUSY 0x80000000
|
||||||
#define OCR_HCS 0x40000000
|
#define OCR_HCS 0x40000000
|
||||||
|
#define OCR_S18R 0x1000000
|
||||||
#define OCR_VOLTAGE_MASK 0x007FFF80
|
#define OCR_VOLTAGE_MASK 0x007FFF80
|
||||||
#define OCR_ACCESS_MODE 0x60000000
|
#define OCR_ACCESS_MODE 0x60000000
|
||||||
|
|
||||||
|
@ -206,11 +242,23 @@
|
||||||
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
|
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
|
||||||
| EXT_CSD_CARD_TYPE_DDR_1_2V)
|
| EXT_CSD_CARD_TYPE_DDR_1_2V)
|
||||||
|
|
||||||
|
#define EXT_CSD_CARD_TYPE_HS200_1_8V BIT(4) /* Card can run at 200MHz */
|
||||||
|
/* SDR mode @1.8V I/O */
|
||||||
|
#define EXT_CSD_CARD_TYPE_HS200_1_2V BIT(5) /* Card can run at 200MHz */
|
||||||
|
/* SDR mode @1.2V I/O */
|
||||||
|
#define EXT_CSD_CARD_TYPE_HS200 (EXT_CSD_CARD_TYPE_HS200_1_8V | \
|
||||||
|
EXT_CSD_CARD_TYPE_HS200_1_2V)
|
||||||
|
|
||||||
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
|
#define EXT_CSD_BUS_WIDTH_1 0 /* Card is in 1 bit mode */
|
||||||
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
|
#define EXT_CSD_BUS_WIDTH_4 1 /* Card is in 4 bit mode */
|
||||||
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
|
#define EXT_CSD_BUS_WIDTH_8 2 /* Card is in 8 bit mode */
|
||||||
#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */
|
#define EXT_CSD_DDR_BUS_WIDTH_4 5 /* Card is in 4 bit DDR mode */
|
||||||
#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */
|
#define EXT_CSD_DDR_BUS_WIDTH_8 6 /* Card is in 8 bit DDR mode */
|
||||||
|
#define EXT_CSD_DDR_FLAG BIT(2) /* Flag for DDR mode */
|
||||||
|
|
||||||
|
#define EXT_CSD_TIMING_LEGACY 0 /* no high speed */
|
||||||
|
#define EXT_CSD_TIMING_HS 1 /* HS */
|
||||||
|
#define EXT_CSD_TIMING_HS200 2 /* HS200 */
|
||||||
|
|
||||||
#define EXT_CSD_BOOT_ACK_ENABLE (1 << 6)
|
#define EXT_CSD_BOOT_ACK_ENABLE (1 << 6)
|
||||||
#define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3)
|
#define EXT_CSD_BOOT_PARTITION_ENABLE (1 << 3)
|
||||||
|
@ -265,6 +313,20 @@
|
||||||
#define ENHNCD_SUPPORT (0x2)
|
#define ENHNCD_SUPPORT (0x2)
|
||||||
#define PART_ENH_ATTRIB (0x1f)
|
#define PART_ENH_ATTRIB (0x1f)
|
||||||
|
|
||||||
|
#define MMC_QUIRK_RETRY_SEND_CID BIT(0)
|
||||||
|
#define MMC_QUIRK_RETRY_SET_BLOCKLEN BIT(1)
|
||||||
|
|
||||||
|
enum mmc_voltage {
|
||||||
|
MMC_SIGNAL_VOLTAGE_000 = 0,
|
||||||
|
MMC_SIGNAL_VOLTAGE_120 = 1,
|
||||||
|
MMC_SIGNAL_VOLTAGE_180 = 2,
|
||||||
|
MMC_SIGNAL_VOLTAGE_330 = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MMC_ALL_SIGNAL_VOLTAGE (MMC_SIGNAL_VOLTAGE_120 |\
|
||||||
|
MMC_SIGNAL_VOLTAGE_180 |\
|
||||||
|
MMC_SIGNAL_VOLTAGE_330)
|
||||||
|
|
||||||
/* Maximum block size for MMC */
|
/* Maximum block size for MMC */
|
||||||
#define MMC_MAX_BLOCK_LEN 512
|
#define MMC_MAX_BLOCK_LEN 512
|
||||||
|
|
||||||
|
@ -346,6 +408,14 @@ struct dm_mmc_ops {
|
||||||
*/
|
*/
|
||||||
int (*set_ios)(struct udevice *dev);
|
int (*set_ios)(struct udevice *dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* send_init_stream() - send the initialization stream: 74 clock cycles
|
||||||
|
* This is used after power up before sending the first command
|
||||||
|
*
|
||||||
|
* @dev: Device to update
|
||||||
|
*/
|
||||||
|
void (*send_init_stream)(struct udevice *dev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get_cd() - See whether a card is present
|
* get_cd() - See whether a card is present
|
||||||
*
|
*
|
||||||
|
@ -361,6 +431,30 @@ struct dm_mmc_ops {
|
||||||
* @return 0 if write-enabled, 1 if write-protected, -ve on error
|
* @return 0 if write-enabled, 1 if write-protected, -ve on error
|
||||||
*/
|
*/
|
||||||
int (*get_wp)(struct udevice *dev);
|
int (*get_wp)(struct udevice *dev);
|
||||||
|
|
||||||
|
#ifdef MMC_SUPPORTS_TUNING
|
||||||
|
/**
|
||||||
|
* execute_tuning() - Start the tuning process
|
||||||
|
*
|
||||||
|
* @dev: Device to start the tuning
|
||||||
|
* @opcode: Command opcode to send
|
||||||
|
* @return 0 if OK, -ve on error
|
||||||
|
*/
|
||||||
|
int (*execute_tuning)(struct udevice *dev, uint opcode);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
|
||||||
|
/**
|
||||||
|
* wait_dat0() - wait until dat0 is in the target state
|
||||||
|
* (CLK must be running during the wait)
|
||||||
|
*
|
||||||
|
* @dev: Device to check
|
||||||
|
* @state: target state
|
||||||
|
* @timeout: timeout in us
|
||||||
|
* @return 0 if dat0 is in the target state, -ve on error
|
||||||
|
*/
|
||||||
|
int (*wait_dat0)(struct udevice *dev, int state, int timeout);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#define mmc_get_ops(dev) ((struct dm_mmc_ops *)(dev)->driver->ops)
|
#define mmc_get_ops(dev) ((struct dm_mmc_ops *)(dev)->driver->ops)
|
||||||
|
@ -368,13 +462,19 @@ struct dm_mmc_ops {
|
||||||
int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
|
int dm_mmc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
|
||||||
struct mmc_data *data);
|
struct mmc_data *data);
|
||||||
int dm_mmc_set_ios(struct udevice *dev);
|
int dm_mmc_set_ios(struct udevice *dev);
|
||||||
|
void dm_mmc_send_init_stream(struct udevice *dev);
|
||||||
int dm_mmc_get_cd(struct udevice *dev);
|
int dm_mmc_get_cd(struct udevice *dev);
|
||||||
int dm_mmc_get_wp(struct udevice *dev);
|
int dm_mmc_get_wp(struct udevice *dev);
|
||||||
|
int dm_mmc_execute_tuning(struct udevice *dev, uint opcode);
|
||||||
|
int dm_mmc_wait_dat0(struct udevice *dev, int state, int timeout);
|
||||||
|
|
||||||
/* Transition functions for compatibility */
|
/* Transition functions for compatibility */
|
||||||
int mmc_set_ios(struct mmc *mmc);
|
int mmc_set_ios(struct mmc *mmc);
|
||||||
|
void mmc_send_init_stream(struct mmc *mmc);
|
||||||
int mmc_getcd(struct mmc *mmc);
|
int mmc_getcd(struct mmc *mmc);
|
||||||
int mmc_getwp(struct mmc *mmc);
|
int mmc_getwp(struct mmc *mmc);
|
||||||
|
int mmc_execute_tuning(struct mmc *mmc, uint opcode);
|
||||||
|
int mmc_wait_dat0(struct mmc *mmc, int state, int timeout);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
struct mmc_ops {
|
struct mmc_ops {
|
||||||
|
@ -406,6 +506,50 @@ struct sd_ssr {
|
||||||
unsigned int erase_offset; /* In milliseconds */
|
unsigned int erase_offset; /* In milliseconds */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum bus_mode {
|
||||||
|
MMC_LEGACY,
|
||||||
|
SD_LEGACY,
|
||||||
|
MMC_HS,
|
||||||
|
SD_HS,
|
||||||
|
MMC_HS_52,
|
||||||
|
MMC_DDR_52,
|
||||||
|
UHS_SDR12,
|
||||||
|
UHS_SDR25,
|
||||||
|
UHS_SDR50,
|
||||||
|
UHS_DDR50,
|
||||||
|
UHS_SDR104,
|
||||||
|
MMC_HS_200,
|
||||||
|
MMC_MODES_END
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *mmc_mode_name(enum bus_mode mode);
|
||||||
|
void mmc_dump_capabilities(const char *text, uint caps);
|
||||||
|
|
||||||
|
static inline bool mmc_is_mode_ddr(enum bus_mode mode)
|
||||||
|
{
|
||||||
|
if (mode == MMC_DDR_52)
|
||||||
|
return true;
|
||||||
|
#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
|
||||||
|
else if (mode == UHS_DDR50)
|
||||||
|
return true;
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define UHS_CAPS (MMC_CAP(UHS_SDR12) | MMC_CAP(UHS_SDR25) | \
|
||||||
|
MMC_CAP(UHS_SDR50) | MMC_CAP(UHS_SDR104) | \
|
||||||
|
MMC_CAP(UHS_DDR50))
|
||||||
|
|
||||||
|
static inline bool supports_uhs(uint caps)
|
||||||
|
{
|
||||||
|
#if CONFIG_IS_ENABLED(MMC_UHS_SUPPORT)
|
||||||
|
return (caps & UHS_CAPS) ? true : false;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* With CONFIG_DM_MMC enabled, struct mmc can be accessed from the MMC device
|
* With CONFIG_DM_MMC enabled, struct mmc can be accessed from the MMC device
|
||||||
* with mmc_get_mmc_dev().
|
* with mmc_get_mmc_dev().
|
||||||
|
@ -421,9 +565,12 @@ struct mmc {
|
||||||
void *priv;
|
void *priv;
|
||||||
uint has_init;
|
uint has_init;
|
||||||
int high_capacity;
|
int high_capacity;
|
||||||
|
bool clk_disable; /* true if the clock can be turned off */
|
||||||
uint bus_width;
|
uint bus_width;
|
||||||
uint clock;
|
uint clock;
|
||||||
|
enum mmc_voltage signal_voltage;
|
||||||
uint card_caps;
|
uint card_caps;
|
||||||
|
uint host_caps;
|
||||||
uint ocr;
|
uint ocr;
|
||||||
uint dsr;
|
uint dsr;
|
||||||
uint dsr_imp;
|
uint dsr_imp;
|
||||||
|
@ -436,18 +583,27 @@ struct mmc {
|
||||||
u8 wr_rel_set;
|
u8 wr_rel_set;
|
||||||
u8 part_config;
|
u8 part_config;
|
||||||
uint tran_speed;
|
uint tran_speed;
|
||||||
|
uint legacy_speed; /* speed for the legacy mode provided by the card */
|
||||||
uint read_bl_len;
|
uint read_bl_len;
|
||||||
|
#if CONFIG_IS_ENABLED(MMC_WRITE)
|
||||||
uint write_bl_len;
|
uint write_bl_len;
|
||||||
uint erase_grp_size; /* in 512-byte sectors */
|
uint erase_grp_size; /* in 512-byte sectors */
|
||||||
|
#endif
|
||||||
|
#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
|
||||||
uint hc_wp_grp_size; /* in 512-byte sectors */
|
uint hc_wp_grp_size; /* in 512-byte sectors */
|
||||||
|
#endif
|
||||||
|
#if CONFIG_IS_ENABLED(MMC_WRITE)
|
||||||
struct sd_ssr ssr; /* SD status register */
|
struct sd_ssr ssr; /* SD status register */
|
||||||
|
#endif
|
||||||
u64 capacity;
|
u64 capacity;
|
||||||
u64 capacity_user;
|
u64 capacity_user;
|
||||||
u64 capacity_boot;
|
u64 capacity_boot;
|
||||||
u64 capacity_rpmb;
|
u64 capacity_rpmb;
|
||||||
u64 capacity_gp[4];
|
u64 capacity_gp[4];
|
||||||
|
#ifndef CONFIG_SPL_BUILD
|
||||||
u64 enh_user_start;
|
u64 enh_user_start;
|
||||||
u64 enh_user_size;
|
u64 enh_user_size;
|
||||||
|
#endif
|
||||||
#if !CONFIG_IS_ENABLED(BLK)
|
#if !CONFIG_IS_ENABLED(BLK)
|
||||||
struct blk_desc block_dev;
|
struct blk_desc block_dev;
|
||||||
#endif
|
#endif
|
||||||
|
@ -457,7 +613,21 @@ struct mmc {
|
||||||
int ddr_mode;
|
int ddr_mode;
|
||||||
#if CONFIG_IS_ENABLED(DM_MMC)
|
#if CONFIG_IS_ENABLED(DM_MMC)
|
||||||
struct udevice *dev; /* Device for this MMC controller */
|
struct udevice *dev; /* Device for this MMC controller */
|
||||||
|
#if CONFIG_IS_ENABLED(DM_REGULATOR)
|
||||||
|
struct udevice *vmmc_supply; /* Main voltage regulator (Vcc)*/
|
||||||
|
struct udevice *vqmmc_supply; /* IO voltage regulator (Vccq)*/
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
u8 *ext_csd;
|
||||||
|
u32 cardtype; /* cardtype read from the MMC */
|
||||||
|
enum mmc_voltage current_voltage;
|
||||||
|
enum bus_mode selected_mode; /* mode currently used */
|
||||||
|
enum bus_mode best_mode; /* best mode is the supported mode with the
|
||||||
|
* highest bandwidth. It may not always be the
|
||||||
|
* operating mode due to limitations when
|
||||||
|
* accessing the boot partitions
|
||||||
|
*/
|
||||||
|
u32 quirks;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mmc_hwpart_conf {
|
struct mmc_hwpart_conf {
|
||||||
|
@ -507,8 +677,36 @@ void mmc_destroy(struct mmc *mmc);
|
||||||
int mmc_unbind(struct udevice *dev);
|
int mmc_unbind(struct udevice *dev);
|
||||||
int mmc_initialize(bd_t *bis);
|
int mmc_initialize(bd_t *bis);
|
||||||
int mmc_init(struct mmc *mmc);
|
int mmc_init(struct mmc *mmc);
|
||||||
|
int mmc_send_tuning(struct mmc *mmc, u32 opcode, int *cmd_error);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mmc_of_parse() - Parse the device tree to get the capabilities of the host
|
||||||
|
*
|
||||||
|
* @dev: MMC device
|
||||||
|
* @cfg: MMC configuration
|
||||||
|
* @return 0 if OK, -ve on error
|
||||||
|
*/
|
||||||
|
int mmc_of_parse(struct udevice *dev, struct mmc_config *cfg);
|
||||||
|
|
||||||
int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
|
int mmc_read(struct mmc *mmc, u64 src, uchar *dst, int size);
|
||||||
void mmc_set_clock(struct mmc *mmc, uint clock);
|
|
||||||
|
/**
|
||||||
|
* mmc_voltage_to_mv() - Convert a mmc_voltage in mV
|
||||||
|
*
|
||||||
|
* @voltage: The mmc_voltage to convert
|
||||||
|
* @return the value in mV if OK, -EINVAL on error (invalid mmc_voltage value)
|
||||||
|
*/
|
||||||
|
int mmc_voltage_to_mv(enum mmc_voltage voltage);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mmc_set_clock() - change the bus clock
|
||||||
|
* @mmc: MMC struct
|
||||||
|
* @clock: bus frequency in Hz
|
||||||
|
* @disable: flag indicating if the clock must on or off
|
||||||
|
* @return 0 if OK, -ve on error
|
||||||
|
*/
|
||||||
|
int mmc_set_clock(struct mmc *mmc, uint clock, bool disable);
|
||||||
|
|
||||||
struct mmc *find_mmc_device(int dev_num);
|
struct mmc *find_mmc_device(int dev_num);
|
||||||
int mmc_set_dev(int dev_num);
|
int mmc_set_dev(int dev_num);
|
||||||
void print_mmc_devices(char separator);
|
void print_mmc_devices(char separator);
|
||||||
|
|
Loading…
Add table
Reference in a new issue