Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OS
U-Boot.Mirror
提交
3dde8f20
U
U-Boot.Mirror
项目概览
OS
/
U-Boot.Mirror
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
U
U-Boot.Mirror
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
3dde8f20
编写于
1月 14, 2018
作者:
T
Tom Rini
浏览文件
操作
浏览文件
下载
差异文件
Merge
git://git.denx.de/u-boot-mmc
上级
18af9657
db359efd
变更
23
展开全部
隐藏空白更改
内联
并排
Showing
23 changed file
with
1745 addition
and
469 deletion
+1745
-469
cmd/mmc.c
cmd/mmc.c
+20
-1
cmd/mvebu/bubt.c
cmd/mvebu/bubt.c
+1
-1
common/Makefile
common/Makefile
+2
-0
common/spl/Kconfig
common/spl/Kconfig
+9
-0
configs/am335x_hs_evm_defconfig
configs/am335x_hs_evm_defconfig
+4
-0
configs/omapl138_lcdk_defconfig
configs/omapl138_lcdk_defconfig
+1
-0
configs/openrd_base_defconfig
configs/openrd_base_defconfig
+1
-0
configs/openrd_client_defconfig
configs/openrd_client_defconfig
+1
-0
configs/openrd_ultimate_defconfig
configs/openrd_ultimate_defconfig
+1
-0
drivers/mmc/Kconfig
drivers/mmc/Kconfig
+76
-0
drivers/mmc/Makefile
drivers/mmc/Makefile
+1
-3
drivers/mmc/exynos_dw_mmc.c
drivers/mmc/exynos_dw_mmc.c
+3
-0
drivers/mmc/fsl_esdhc.c
drivers/mmc/fsl_esdhc.c
+6
-5
drivers/mmc/gen_atmel_mci.c
drivers/mmc/gen_atmel_mci.c
+20
-22
drivers/mmc/meson_gx_mmc.c
drivers/mmc/meson_gx_mmc.c
+1
-1
drivers/mmc/mmc-uclass.c
drivers/mmc/mmc-uclass.c
+97
-2
drivers/mmc/mmc.c
drivers/mmc/mmc.c
+1255
-387
drivers/mmc/mmc_private.h
drivers/mmc/mmc_private.h
+2
-2
drivers/mmc/omap_hsmmc.c
drivers/mmc/omap_hsmmc.c
+2
-2
drivers/mmc/sandbox_mmc.c
drivers/mmc/sandbox_mmc.c
+4
-1
drivers/mmc/sdhci.c
drivers/mmc/sdhci.c
+4
-3
drivers/power/power_core.c
drivers/power/power_core.c
+29
-32
include/mmc.h
include/mmc.h
+205
-7
未找到文件。
cmd/mmc.c
浏览文件 @
3dde8f20
...
...
@@ -23,7 +23,12 @@ static void print_mmcinfo(struct mmc *mmc)
(
mmc
->
cid
[
1
]
>>
24
),
(
mmc
->
cid
[
1
]
>>
16
)
&
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
(
"%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
,
mmc
->
ddr_mode
?
" DDR"
:
""
);
#if CONFIG_IS_ENABLED(MMC_WRITE)
puts
(
"Erase Group Size: "
);
print_size
(((
u64
)
mmc
->
erase_grp_size
)
<<
9
,
"
\n
"
);
#endif
if
(
!
IS_SD
(
mmc
)
&&
mmc
->
version
>=
MMC_VERSION_4_41
)
{
bool
has_enh
=
(
mmc
->
part_support
&
ENHNCD_SUPPORT
)
!=
0
;
bool
usr_enh
=
has_enh
&&
(
mmc
->
part_attr
&
EXT_CSD_ENH_USR
);
#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
puts
(
"HC WP Group Size: "
);
print_size
(((
u64
)
mmc
->
hc_wp_grp_size
)
<<
9
,
"
\n
"
);
#endif
puts
(
"User Capacity: "
);
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
;
}
#if CONFIG_IS_ENABLED(MMC_WRITE)
static
int
do_mmc_write
(
cmd_tbl_t
*
cmdtp
,
int
flag
,
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
;
}
#endif
static
int
do_mmc_rescan
(
cmd_tbl_t
*
cmdtp
,
int
flag
,
int
argc
,
char
*
const
argv
[])
{
...
...
@@ -433,6 +446,7 @@ static int do_mmc_list(cmd_tbl_t *cmdtp, int flag,
return
CMD_RET_SUCCESS
;
}
#if CONFIG_IS_ENABLED(MMC_HW_PARTITIONING)
static
int
parse_hwpart_user
(
struct
mmc_hwpart_conf
*
pconf
,
int
argc
,
char
*
const
argv
[])
{
...
...
@@ -582,6 +596,7 @@ static int do_mmc_hwpartition(cmd_tbl_t *cmdtp, int flag,
return
CMD_RET_FAILURE
;
}
}
#endif
#ifdef CONFIG_SUPPORT_EMMC_BOOT
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
[]
=
{
U_BOOT_CMD_MKENT
(
info
,
1
,
0
,
do_mmcinfo
,
""
,
""
),
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
(
erase
,
3
,
0
,
do_mmc_erase
,
""
,
""
),
#endif
U_BOOT_CMD_MKENT
(
rescan
,
1
,
1
,
do_mmc_rescan
,
""
,
""
),
U_BOOT_CMD_MKENT
(
part
,
1
,
1
,
do_mmc_part
,
""
,
""
),
U_BOOT_CMD_MKENT
(
dev
,
3
,
0
,
do_mmc_dev
,
""
,
""
),
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
,
""
,
""
),
#endif
#ifdef CONFIG_SUPPORT_EMMC_BOOT
U_BOOT_CMD_MKENT
(
bootbus
,
5
,
0
,
do_mmc_bootbus
,
""
,
""
),
U_BOOT_CMD_MKENT
(
bootpart
-
resize
,
4
,
0
,
do_mmc_boot_resize
,
""
,
""
),
...
...
cmd/mvebu/bubt.c
浏览文件 @
3dde8f20
...
...
@@ -110,7 +110,7 @@ static ulong get_load_addr(void)
/********************************************************************
* eMMC services
********************************************************************/
#if
def CONFIG_DM_MMC
#if
CONFIG_IS_ENABLED(DM_MMC) && CONFIG_IS_ENABLED(MMC_WRITE)
static
int
mmc_burn_image
(
size_t
image_size
)
{
struct
mmc
*
mmc
;
...
...
common/Makefile
浏览文件 @
3dde8f20
...
...
@@ -109,6 +109,7 @@ obj-$(CONFIG_IO_TRACE) += iotrace.o
obj-y
+=
memsize.o
obj-y
+=
stdio.o
ifndef
CONFIG_SPL_BUILD
# This option is not just y/n - it can have a numeric value
ifdef
CONFIG_FASTBOOT_FLASH
obj-y
+=
image-sparse.o
...
...
@@ -119,6 +120,7 @@ ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
obj-y
+=
fb_nand.o
endif
endif
endif
ifdef
CONFIG_CMD_EEPROM_LAYOUT
obj-y
+=
eeprom/eeprom_field.o eeprom/eeprom_layout.o
...
...
common/spl/Kconfig
浏览文件 @
3dde8f20
...
...
@@ -301,6 +301,7 @@ config SPL_ENV_SUPPORT
config SPL_SAVEENV
bool "Support save environment"
depends on SPL_ENV_SUPPORT
select SPL_MMC_WRITE if ENV_IS_IN_MMC
help
Enable save environment support in SPL after setenv. By default
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
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
bool "Support MPC8XXX DDR init"
help
...
...
configs/am335x_hs_evm_defconfig
浏览文件 @
3dde8f20
...
...
@@ -13,10 +13,12 @@ CONFIG_ANDROID_BOOT_IMAGE=y
CONFIG_FIT_IMAGE_POST_PROCESS=y
CONFIG_SPL_LOAD_FIT=y
CONFIG_SPL_FIT_IMAGE_POST_PROCESS=y
CONFIG_LOGLEVEL=3
CONFIG_SYS_CONSOLE_INFO_QUIET=y
CONFIG_VERSION_VARIABLE=y
CONFIG_ARCH_MISC_INIT=y
CONFIG_SPL=y
CONFIG_SPL_FIT_IMAGE_TINY=y
# CONFIG_SPL_ENV_SUPPORT is not set
# CONFIG_SPL_EXT_SUPPORT is not set
CONFIG_SPL_MTD_SUPPORT=y
...
...
@@ -37,6 +39,7 @@ CONFIG_DFU_RAM=y
CONFIG_DM_I2C=y
CONFIG_MISC=y
CONFIG_DM_MMC=y
# CONFIG_MMC_HW_PARTITIONING is not set
CONFIG_MMC_OMAP_HS=y
CONFIG_NAND=y
CONFIG_SPI_FLASH=y
...
...
@@ -60,5 +63,6 @@ CONFIG_USB_GADGET_VENDOR_NUM=0x0451
CONFIG_USB_GADGET_PRODUCT_NUM=0xd022
CONFIG_USB_GADGET_DOWNLOAD=y
CONFIG_USB_ETHER=y
CONFIG_SPL_TINY_MEMSET=y
CONFIG_RSA=y
CONFIG_LZO=y
configs/omapl138_lcdk_defconfig
浏览文件 @
3dde8f20
...
...
@@ -8,6 +8,7 @@ CONFIG_SPL_MMC_SUPPORT=y
CONFIG_SPL_SERIAL_SUPPORT=y
CONFIG_SPL_NAND_SUPPORT=y
CONFIG_BOOTDELAY=3
CONFIG_LOGLEVEL=3
CONFIG_VERSION_VARIABLE=y
# CONFIG_DISPLAY_CPUINFO is not set
# CONFIG_DISPLAY_BOARDINFO is not set
...
...
configs/openrd_base_defconfig
浏览文件 @
3dde8f20
...
...
@@ -25,6 +25,7 @@ CONFIG_CMD_UBI=y
CONFIG_ISO_PARTITION=y
CONFIG_ENV_IS_IN_NAND=y
CONFIG_MVSATA_IDE=y
# CONFIG_MMC_HW_PARTITIONING is not set
CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
...
...
configs/openrd_client_defconfig
浏览文件 @
3dde8f20
...
...
@@ -25,6 +25,7 @@ CONFIG_CMD_UBI=y
CONFIG_ISO_PARTITION=y
CONFIG_ENV_IS_IN_NAND=y
CONFIG_MVSATA_IDE=y
# CONFIG_MMC_HW_PARTITIONING is not set
CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
...
...
configs/openrd_ultimate_defconfig
浏览文件 @
3dde8f20
...
...
@@ -25,6 +25,7 @@ CONFIG_CMD_UBI=y
CONFIG_ISO_PARTITION=y
CONFIG_ENV_IS_IN_NAND=y
CONFIG_MVSATA_IDE=y
# CONFIG_MMC_HW_PARTITIONING is not set
CONFIG_SYS_NS16550=y
CONFIG_USB=y
CONFIG_USB_EHCI_HCD=y
...
...
drivers/mmc/Kconfig
浏览文件 @
3dde8f20
...
...
@@ -10,6 +10,13 @@ config MMC
If you want MMC/SD/SDIO support, you should say Y here and
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
bool "Enable MMC controllers using Driver Model"
depends on DM
...
...
@@ -42,6 +49,75 @@ config ARM_PL180_MMCI
If you have an ARM(R) platform with a Multimedia Card slot,
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
bool "Tiny MMC framework in SPL"
help
...
...
drivers/mmc/Makefile
浏览文件 @
3dde8f20
...
...
@@ -7,6 +7,7 @@
obj-y
+=
mmc.o
obj-$(CONFIG_$(SPL_)DM_MMC)
+=
mmc-uclass.o
obj-$(CONFIG_$(SPL_)MMC_WRITE)
+=
mmc_write.o
ifndef
CONFIG_$(SPL_)BLK
obj-y
+=
mmc_legacy.o
...
...
@@ -16,9 +17,6 @@ obj-$(CONFIG_SUPPORT_EMMC_BOOT) += mmc_boot.o
ifdef
CONFIG_SPL_BUILD
obj-$(CONFIG_SPL_MMC_BOOT)
+=
fsl_esdhc_spl.o
obj-$(CONFIG_SPL_SAVEENV)
+=
mmc_write.o
else
obj-y
+=
mmc_write.o
endif
obj-$(CONFIG_ARM_PL180_MMCI)
+=
arm_pl180_mmci.o
...
...
drivers/mmc/exynos_dw_mmc.c
浏览文件 @
3dde8f20
...
...
@@ -168,6 +168,7 @@ static int exynos_dwmci_get_config(const void *blob, int node,
if
(
host
->
dev_index
>
4
)
{
printf
(
"DWMMC%d: Can't get the dev index
\n
"
,
host
->
dev_index
);
free
(
priv
);
return
-
EINVAL
;
}
...
...
@@ -178,6 +179,7 @@ static int exynos_dwmci_get_config(const void *blob, int node,
base
=
fdtdec_get_addr
(
blob
,
node
,
"reg"
);
if
(
!
base
)
{
printf
(
"DWMMC%d: Can't get base address
\n
"
,
host
->
dev_index
);
free
(
priv
);
return
-
EINVAL
;
}
host
->
ioaddr
=
(
void
*
)
base
;
...
...
@@ -187,6 +189,7 @@ static int exynos_dwmci_get_config(const void *blob, int node,
if
(
err
)
{
printf
(
"DWMMC%d: Can't get sdr-timings for devider
\n
"
,
host
->
dev_index
);
free
(
priv
);
return
-
EINVAL
;
}
...
...
drivers/mmc/fsl_esdhc.c
浏览文件 @
3dde8f20
...
...
@@ -647,7 +647,11 @@ static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
esdhc_write32
(
&
regs
->
clktunectrlstatus
,
0x0
);
/* Put VEND_SPEC to default value */
esdhc_write32
(
&
regs
->
vendorspec
,
VENDORSPEC_INIT
);
if
(
priv
->
vs18_enable
)
esdhc_write32
(
&
regs
->
vendorspec
,
(
VENDORSPEC_INIT
|
ESDHC_VENDORSPEC_VSELECT
));
else
esdhc_write32
(
&
regs
->
vendorspec
,
VENDORSPEC_INIT
);
/* Disable DLL_CTRL delay line */
esdhc_write32
(
&
regs
->
dllctrl
,
0x0
);
...
...
@@ -665,7 +669,7 @@ static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
#endif
/* Set the initial clock speed */
mmc_set_clock
(
mmc
,
400000
);
mmc_set_clock
(
mmc
,
400000
,
false
);
/* Disable the BRR and BWR bits in IRQSTAT */
esdhc_clrbits32
(
&
regs
->
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 */
esdhc_clrsetbits32
(
&
regs
->
sysctl
,
SYSCTL_TIMEOUT_MASK
,
14
<<
16
);
if
(
priv
->
vs18_enable
)
esdhc_setbits32
(
&
regs
->
vendorspec
,
ESDHC_VENDORSPEC_VSELECT
);
return
0
;
}
...
...
drivers/mmc/gen_atmel_mci.c
浏览文件 @
3dde8f20
...
...
@@ -74,6 +74,20 @@ static void dump_cmd(u32 cmdr, u32 arg, u32 status, const char* 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 */
#ifdef CONFIG_DM_MMC
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
);
else
priv
->
curr_clk
=
(
bus_hz
/
(
clkdiv
+
1
))
/
2
;
blklen
&=
0xfffc
;
mr
=
MMCI_BF
(
CLKDIV
,
clkdiv
);
...
...
@@ -138,14 +151,10 @@ static void mci_set_mode(struct mmc *mmc, u32 hz, u32 blklen)
*/
if
(
version
>=
0x500
)
mr
|=
MMCI_BF
(
CLKODD
,
clkodd
);
else
mr
|=
MMCI_BF
(
BLKLEN
,
blklen
);
writel
(
mr
,
&
mci
->
mr
);
/* MCI IP version >= 0x200 has blkr */
if
(
version
>=
0x200
)
writel
(
MMCI_BF
(
BLKLEN
,
blklen
),
&
mci
->
blkr
);
mci_set_blklen
(
mci
,
blklen
);
if
(
mmc
->
card_caps
&
mmc
->
cfg
->
host_caps
&
MMC_MODE_HS
)
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_priv
*
priv
=
dev_get_priv
(
dev
);
struct
mmc
*
mmc
=
mmc_get_mmc_dev
(
dev
);
atmel_mci_t
*
mci
=
plat
->
mci
;
#else
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 */
cmdr
=
mci_encode_cmd
(
cmd
,
data
,
&
error_flags
);
mci_set_blklen
(
mci
,
data
->
blocksize
);
/* For multi blocks read/write, set the block register */
if
((
cmd
->
cmdidx
==
MMC_CMD_READ_MULTIPLE_BLOCK
)
||
(
cmd
->
cmdidx
==
MMC_CMD_WRITE_MULTIPLE_BLOCK
))
writel
(
data
->
blocks
|
MMCI_BF
(
BLKLEN
,
mmc
->
read_bl_len
),
&
mci
->
blkr
);
writel
(
data
->
blocks
|
MMCI_BF
(
BLKLEN
,
data
->
blocksize
),
&
mci
->
blkr
);
/* Send the command */
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
)
{
u32
word_count
,
block_count
;
u32
*
ioptr
;
u32
sys_blocksize
,
dummy
,
i
;
u32
i
;
u32
(
*
mci_data_op
)
(
atmel_mci_t
*
mci
,
u32
*
data
,
u32
error_flags
);
if
(
data
->
flags
&
MMC_DATA_READ
)
{
mci_data_op
=
mci_data_read
;
sys_blocksize
=
mmc
->
read_bl_len
;
ioptr
=
(
u32
*
)
data
->
dest
;
}
else
{
mci_data_op
=
mci_data_write
;
sys_blocksize
=
mmc
->
write_bl_len
;
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
);
}
#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
)
{
dump_cmd
(
cmdr
,
cmd
->
cmdarg
,
status
,
"Data Transfer Failed"
);
...
...
drivers/mmc/meson_gx_mmc.c
浏览文件 @
3dde8f20
...
...
@@ -250,7 +250,7 @@ static int meson_mmc_probe(struct udevice *dev)
mmc
->
priv
=
pdata
;
upriv
->
mmc
=
mmc
;
mmc_set_clock
(
mmc
,
cfg
->
f_min
);
mmc_set_clock
(
mmc
,
cfg
->
f_min
,
false
);
/* reset all status bits */
meson_write
(
mmc
,
STATUS_MASK
,
MESON_SD_EMMC_STATUS
);
...
...
drivers/mmc/mmc-uclass.c
浏览文件 @
3dde8f20
...
...
@@ -10,7 +10,6 @@
#include <dm.h>
#include <dm/device-internal.h>
#include <dm/lists.h>
#include <dm/root.h>
#include "mmc_private.h"
DECLARE_GLOBAL_DATA_PTR
;
...
...
@@ -51,6 +50,35 @@ int mmc_set_ios(struct mmc *mmc)
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
)
{
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
);
}
#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_uclass_priv
*
upriv
;
...
...
@@ -275,7 +370,7 @@ static int mmc_blk_probe(struct udevice *dev)
static
const
struct
blk_ops
mmc_blk_ops
=
{
.
read
=
mmc_bread
,
#if
ndef CONFIG_SPL_BUILD
#if
CONFIG_IS_ENABLED(MMC_WRITE)
.
write
=
mmc_bwrite
,
.
erase
=
mmc_berase
,
#endif
...
...
drivers/mmc/mmc.c
浏览文件 @
3dde8f20
此差异已折叠。
点击以展开。
drivers/mmc/mmc_private.h
浏览文件 @
3dde8f20
...
...
@@ -28,7 +28,7 @@ ulong mmc_bread(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
void
*
dst
);
#endif
#if
!(defined(CONFIG_SPL_BUILD) && !defined(CONFIG_SPL_SAVEENV)
)
#if
CONFIG_IS_ENABLED(MMC_WRITE
)
#if CONFIG_IS_ENABLED(BLK)
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
);
#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. */
...
...
drivers/mmc/omap_hsmmc.c
浏览文件 @
3dde8f20
...
...
@@ -28,9 +28,9 @@
#include <mmc.h>
#include <part.h>
#include <i2c.h>
#include <twl4030.h>
#include <twl6030.h>
#if defined(CONFIG_OMAP54XX) || defined(CONFIG_OMAP44XX)
#include <palmas.h>
#endif
#include <asm/io.h>
#include <asm/arch/mmc_host_def.h>
#if !defined(CONFIG_SOC_KEYSTONE)
...
...
drivers/mmc/sandbox_mmc.c
浏览文件 @
3dde8f20
...
...
@@ -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 */
break
;
case
SD_CMD_SWITCH_FUNC
:
{
if
(
!
data
)
break
;
u32
*
resp
=
(
u32
*
)
data
->
dest
;
resp
[
7
]
=
cpu_to_be32
(
SD_HIGHSPEED_BUSY
);
if
((
cmd
->
cmdarg
&
0xF
)
==
UHS_SDR12_BUS_SPEED
)
resp
[
4
]
=
(
cmd
->
cmdarg
&
0xF
)
<<
24
;
break
;
}
case
MMC_CMD_READ_SINGLE_BLOCK
:
...
...
drivers/mmc/sdhci.c
浏览文件 @
3dde8f20
...
...
@@ -157,7 +157,6 @@ static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
/* Timeout unit - ms */
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
;
/* 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
);
}
sdhci_writel
(
host
,
SDHCI_INT_ALL_MASK
,
SDHCI_INT_STATUS
);
mask
=
SDHCI_INT_RESPONSE
;
if
(
!
(
cmd
->
resp_type
&
MMC_RSP_PRESENT
))
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
;
/* Set Transfer mode regarding to data flag */
if
(
data
!=
0
)
{
if
(
data
)
{
sdhci_writeb
(
host
,
0xe
,
SDHCI_TIMEOUT_CONTROL
);
mode
=
SDHCI_TRNS_BLK_CNT_EN
;
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
);
#ifdef CONFIG_MMC_SDHCI_SDMA
if
(
data
!=
0
)
{
if
(
data
)
{
trans_bytes
=
ALIGN
(
trans_bytes
,
CONFIG_SYS_CACHELINE_SIZE
);
flush_cache
(
start_addr
,
trans_bytes
);
}
...
...
drivers/power/power_core.c
浏览文件 @
3dde8f20
...
...
@@ -47,36 +47,6 @@ int pmic_set_output(struct pmic *p, u32 reg, int out, int on)
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
(
"
\n
0x%02x: "
,
i
);
printf
(
"%08x "
,
val
);
}
puts
(
"
\n
"
);
return
0
;
}
struct
pmic
*
pmic_alloc
(
void
)
{
struct
pmic
*
p
;
...
...
@@ -108,7 +78,33 @@ struct pmic *pmic_get(const char *s)
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
(
"
\n
0x%02x: "
,
i
);
printf
(
"%08x "
,
val
);
}
puts
(
"
\n
"
);
return
0
;
}
static
const
char
*
power_get_interface
(
int
interface
)
{
const
char
*
power_interface
[]
=
{
"I2C"
,
"SPI"
,
"|+|-|"
};
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
;
char
*
cmd
,
*
name
;
...
...
@@ -221,3 +217,4 @@ U_BOOT_CMD(
"pmic name bat state - write register
\n
"
"pmic name bat charge - write register
\n
"
);
#endif
include/mmc.h
浏览文件 @
3dde8f20
...
...
@@ -15,6 +15,13 @@
#include <linux/compiler.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 */
#define SD_VERSION_SD (1U << 31)
#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_1 MAKE_MMC_VERSION(5, 1, 0)
#define MMC_MODE_HS (1 << 0)
#define MMC_MODE_HS_52MHz (1 << 1)
#define MMC_MODE_4BIT (1 << 2)
#define MMC_MODE_8BIT (1 << 3)
#define MMC_MODE_SPI (1 << 4)
#define MMC_MODE_DDR_52MHz (1 << 5)
#define MMC_CAP(mode) (1 << mode)
#define MMC_MODE_HS (MMC_CAP(MMC_HS) | MMC_CAP(SD_HS))
#define MMC_MODE_HS_52MHz MMC_CAP(MMC_HS_52)
#define MMC_MODE_DDR_52MHz MMC_CAP(MMC_DDR_52)
#define MMC_MODE_HS200 MMC_CAP(MMC_HS_200)
#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
...
...
@@ -82,6 +94,8 @@
#define MMC_CMD_SET_BLOCKLEN 16
#define MMC_CMD_READ_SINGLE_BLOCK 17
#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_WRITE_SINGLE_BLOCK 24
#define MMC_CMD_WRITE_MULTIPLE_BLOCK 25
...
...
@@ -109,12 +123,34 @@
#define SD_CMD_APP_SEND_OP_COND 41
#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 */
#define SD_HIGHSPEED_BUSY 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_HCS 0x40000000
#define OCR_S18R 0x1000000
#define OCR_VOLTAGE_MASK 0x007FFF80
#define OCR_ACCESS_MODE 0x60000000
...
...
@@ -206,11 +242,23 @@
#define EXT_CSD_CARD_TYPE_DDR_52 (EXT_CSD_CARD_TYPE_DDR_1_8V \
| 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_4 1
/* Card is in 4 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_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_PARTITION_ENABLE (1 << 3)
...
...
@@ -265,6 +313,20 @@
#define ENHNCD_SUPPORT (0x2)
#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 */
#define MMC_MAX_BLOCK_LEN 512
...
...
@@ -346,6 +408,14 @@ struct dm_mmc_ops {
*/
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
*
...
...
@@ -361,6 +431,30 @@ struct dm_mmc_ops {
* @return 0 if write-enabled, 1 if write-protected, -ve on error
*/
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)
...
...
@@ -368,13 +462,19 @@ struct dm_mmc_ops {
int
dm_mmc_send_cmd
(
struct
udevice
*
dev
,
struct
mmc_cmd
*
cmd
,
struct
mmc_data
*
data
);
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_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 */
int
mmc_set_ios
(
struct
mmc
*
mmc
);
void
mmc_send_init_stream
(
struct
mmc
*
mmc
);
int
mmc_getcd
(
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
struct
mmc_ops
{
...
...
@@ -406,6 +506,50 @@ struct sd_ssr {
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 mmc_get_mmc_dev().
...
...
@@ -421,9 +565,12 @@ struct mmc {
void
*
priv
;
uint
has_init
;
int
high_capacity
;
bool
clk_disable
;
/* true if the clock can be turned off */
uint
bus_width
;
uint
clock
;
enum
mmc_voltage
signal_voltage
;
uint
card_caps
;
uint
host_caps
;
uint
ocr
;
uint
dsr
;
uint
dsr_imp
;
...
...
@@ -436,18 +583,27 @@ struct mmc {
u8
wr_rel_set
;
u8
part_config
;
uint
tran_speed
;
uint
legacy_speed
;
/* speed for the legacy mode provided by the card */
uint
read_bl_len
;
#if CONFIG_IS_ENABLED(MMC_WRITE)
uint
write_bl_len
;
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 */
#endif
#if CONFIG_IS_ENABLED(MMC_WRITE)
struct
sd_ssr
ssr
;
/* SD status register */
#endif
u64
capacity
;
u64
capacity_user
;
u64
capacity_boot
;
u64
capacity_rpmb
;
u64
capacity_gp
[
4
];
#ifndef CONFIG_SPL_BUILD
u64
enh_user_start
;
u64
enh_user_size
;
#endif
#if !CONFIG_IS_ENABLED(BLK)
struct
blk_desc
block_dev
;
#endif
...
...
@@ -457,7 +613,21 @@ struct mmc {
int
ddr_mode
;
#if CONFIG_IS_ENABLED(DM_MMC)
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
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
{
...
...
@@ -507,8 +677,36 @@ void mmc_destroy(struct mmc *mmc);
int
mmc_unbind
(
struct
udevice
*
dev
);
int
mmc_initialize
(
bd_t
*
bis
);
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
);
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
);
int
mmc_set_dev
(
int
dev_num
);
void
print_mmc_devices
(
char
separator
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录