Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OS
U-Boot.Mirror
提交
d0b96168
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,发现更多精彩内容 >>
提交
d0b96168
编写于
9月 20, 2013
作者:
T
Tom Rini
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.denx.de/u-boot-mmc
上级
03c1bb24
2c011847
变更
12
隐藏空白更改
内联
并排
Showing
12 changed file
with
336 addition
and
195 deletion
+336
-195
common/spl/spl_mmc.c
common/spl/spl_mmc.c
+16
-1
drivers/mmc/Makefile
drivers/mmc/Makefile
+2
-0
drivers/mmc/dw_mmc.c
drivers/mmc/dw_mmc.c
+5
-4
drivers/mmc/mmc.c
drivers/mmc/mmc.c
+30
-175
drivers/mmc/mmc_private.h
drivers/mmc/mmc_private.h
+45
-0
drivers/mmc/mmc_write.c
drivers/mmc/mmc_write.c
+179
-0
drivers/mmc/omap_hsmmc.c
drivers/mmc/omap_hsmmc.c
+38
-3
drivers/mmc/s5p_sdhci.c
drivers/mmc/s5p_sdhci.c
+3
-1
drivers/mmc/sdhci.c
drivers/mmc/sdhci.c
+9
-9
include/common.h
include/common.h
+2
-2
include/mmc.h
include/mmc.h
+4
-0
include/sdhci.h
include/sdhci.h
+3
-0
未找到文件。
common/spl/spl_mmc.c
浏览文件 @
d0b96168
...
...
@@ -9,7 +9,6 @@
#include <common.h>
#include <spl.h>
#include <asm/u-boot.h>
#include <asm/utils.h>
#include <mmc.h>
#include <fat.h>
#include <version.h>
...
...
@@ -45,8 +44,10 @@ static int mmc_load_image_raw(struct mmc *mmc, unsigned long sector)
(
void
*
)
spl_image
.
load_addr
);
end:
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
if
(
err
==
0
)
printf
(
"spl: mmc blk read err - %lu
\n
"
,
err
);
#endif
return
(
err
==
0
);
}
...
...
@@ -58,7 +59,9 @@ static int mmc_load_image_raw_os(struct mmc *mmc)
CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR
,
CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS
,
(
void
*
)
CONFIG_SYS_SPL_ARGS_ADDR
))
{
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
printf
(
"mmc args blk read error
\n
"
);
#endif
return
-
1
;
}
...
...
@@ -84,9 +87,11 @@ static int mmc_load_image_fat(struct mmc *mmc, const char *filename)
err
=
file_fat_read
(
filename
,
(
u8
*
)
spl_image
.
load_addr
,
0
);
end:
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
if
(
err
<=
0
)
printf
(
"spl: error reading image %s, err - %d
\n
"
,
filename
,
err
);
#endif
return
(
err
<=
0
);
}
...
...
@@ -99,8 +104,10 @@ static int mmc_load_image_fat_os(struct mmc *mmc)
err
=
file_fat_read
(
CONFIG_SPL_FAT_LOAD_ARGS_NAME
,
(
void
*
)
CONFIG_SYS_SPL_ARGS_ADDR
,
0
);
if
(
err
<=
0
)
{
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
printf
(
"spl: error reading image %s, err - %d
\n
"
,
CONFIG_SPL_FAT_LOAD_ARGS_NAME
,
err
);
#endif
return
-
1
;
}
...
...
@@ -120,13 +127,17 @@ void spl_mmc_load_image(void)
/* We register only one device. So, the dev id is always 0 */
mmc
=
find_mmc_device
(
0
);
if
(
!
mmc
)
{
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
puts
(
"spl: mmc device not found!!
\n
"
);
#endif
hang
();
}
err
=
mmc_init
(
mmc
);
if
(
err
)
{
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
printf
(
"spl: mmc init failed: err - %d
\n
"
,
err
);
#endif
hang
();
}
...
...
@@ -145,7 +156,9 @@ void spl_mmc_load_image(void)
err
=
fat_register_device
(
&
mmc
->
block_dev
,
CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION
);
if
(
err
)
{
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
printf
(
"spl: fat register err - %d
\n
"
,
err
);
#endif
hang
();
}
...
...
@@ -155,7 +168,9 @@ void spl_mmc_load_image(void)
err
=
mmc_load_image_fat
(
mmc
,
CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME
);
#endif
}
else
{
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
puts
(
"spl: wrong MMC boot mode
\n
"
);
#endif
hang
();
}
...
...
drivers/mmc/Makefile
浏览文件 @
d0b96168
...
...
@@ -34,6 +34,8 @@ COBJS-$(CONFIG_EXYNOS_DWMMC) += exynos_dw_mmc.o
COBJS-$(CONFIG_ZYNQ_SDHCI)
+=
zynq_sdhci.o
ifdef
CONFIG_SPL_BUILD
COBJS-$(CONFIG_SPL_MMC_BOOT)
+=
fsl_esdhc_spl.o
else
COBJS-$(CONFIG_GENERIC_MMC)
+=
mmc_write.o
endif
COBJS
:=
$
(
COBJS-y
)
...
...
drivers/mmc/dw_mmc.c
浏览文件 @
d0b96168
...
...
@@ -41,12 +41,11 @@ static void dwmci_set_idma_desc(struct dwmci_idmac *idmac,
}
static
void
dwmci_prepare_data
(
struct
dwmci_host
*
host
,
struct
mmc_data
*
data
)
struct
mmc_data
*
data
,
struct
dwmci_idmac
*
cur_idmac
)
{
unsigned
long
ctrl
;
unsigned
int
i
=
0
,
flags
,
cnt
,
blk_cnt
;
ulong
data_start
,
data_end
,
start_addr
;
ALLOC_CACHE_ALIGN_BUFFER
(
struct
dwmci_idmac
,
cur_idmac
,
data
->
blocks
);
blk_cnt
=
data
->
blocks
;
...
...
@@ -73,7 +72,7 @@ static void dwmci_prepare_data(struct dwmci_host *host,
dwmci_set_idma_desc
(
cur_idmac
,
flags
,
cnt
,
start_addr
+
(
i
*
PAGE_SIZE
));
if
(
blk_cnt
<
8
)
if
(
blk_cnt
<=
8
)
break
;
blk_cnt
-=
8
;
cur_idmac
++
;
...
...
@@ -111,6 +110,8 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
struct
mmc_data
*
data
)
{
struct
dwmci_host
*
host
=
(
struct
dwmci_host
*
)
mmc
->
priv
;
ALLOC_CACHE_ALIGN_BUFFER
(
struct
dwmci_idmac
,
cur_idmac
,
data
?
DIV_ROUND_UP
(
data
->
blocks
,
8
)
:
0
);
int
flags
=
0
,
i
;
unsigned
int
timeout
=
100000
;
u32
retry
=
10000
;
...
...
@@ -127,7 +128,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
dwmci_writel
(
host
,
DWMCI_RINTSTS
,
DWMCI_INTMSK_ALL
);
if
(
data
)
dwmci_prepare_data
(
host
,
data
);
dwmci_prepare_data
(
host
,
data
,
cur_idmac
);
dwmci_writel
(
host
,
DWMCI_CMDARG
,
cmd
->
cmdarg
);
...
...
drivers/mmc/mmc.c
浏览文件 @
d0b96168
...
...
@@ -15,6 +15,7 @@
#include <malloc.h>
#include <linux/list.h>
#include <div64.h>
#include "mmc_private.h"
/* Set block count limit because of 16 bit register limit on some hardware*/
#ifndef CONFIG_SYS_MMC_MAX_BLK_COUNT
...
...
@@ -52,14 +53,10 @@ int __board_mmc_getcd(struct mmc *mmc) {
int
board_mmc_getcd
(
struct
mmc
*
mmc
)
__attribute__
((
weak
,
alias
(
"__board_mmc_getcd"
)));
static
int
mmc_send_cmd
(
struct
mmc
*
mmc
,
struct
mmc_cmd
*
cmd
,
struct
mmc_data
*
data
)
int
mmc_send_cmd
(
struct
mmc
*
mmc
,
struct
mmc_cmd
*
cmd
,
struct
mmc_data
*
data
)
{
struct
mmc_data
backup
;
int
ret
;
memset
(
&
backup
,
0
,
sizeof
(
backup
));
#ifdef CONFIG_MMC_TRACE
int
i
;
u8
*
ptr
;
...
...
@@ -114,7 +111,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
return
ret
;
}
static
int
mmc_send_status
(
struct
mmc
*
mmc
,
int
timeout
)
int
mmc_send_status
(
struct
mmc
*
mmc
,
int
timeout
)
{
struct
mmc_cmd
cmd
;
int
err
,
retries
=
5
;
...
...
@@ -135,8 +132,10 @@ static int mmc_send_status(struct mmc *mmc, int timeout)
MMC_STATE_PRG
)
break
;
else
if
(
cmd
.
response
[
0
]
&
MMC_STATUS_MASK
)
{
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf
(
"Status Error: 0x%08X
\n
"
,
cmd
.
response
[
0
]);
#endif
return
COMM_ERR
;
}
}
else
if
(
--
retries
<
0
)
...
...
@@ -151,14 +150,16 @@ static int mmc_send_status(struct mmc *mmc, int timeout)
printf
(
"CURR STATE:%d
\n
"
,
status
);
#endif
if
(
timeout
<=
0
)
{
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf
(
"Timeout waiting card ready
\n
"
);
#endif
return
TIMEOUT
;
}
return
0
;
}
static
int
mmc_set_blocklen
(
struct
mmc
*
mmc
,
int
len
)
int
mmc_set_blocklen
(
struct
mmc
*
mmc
,
int
len
)
{
struct
mmc_cmd
cmd
;
...
...
@@ -181,179 +182,13 @@ struct mmc *find_mmc_device(int dev_num)
return
m
;
}
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf
(
"MMC Device %d not found
\n
"
,
dev_num
);
#endif
return
NULL
;
}
static
ulong
mmc_erase_t
(
struct
mmc
*
mmc
,
ulong
start
,
lbaint_t
blkcnt
)
{
struct
mmc_cmd
cmd
;
ulong
end
;
int
err
,
start_cmd
,
end_cmd
;
if
(
mmc
->
high_capacity
)
end
=
start
+
blkcnt
-
1
;
else
{
end
=
(
start
+
blkcnt
-
1
)
*
mmc
->
write_bl_len
;
start
*=
mmc
->
write_bl_len
;
}
if
(
IS_SD
(
mmc
))
{
start_cmd
=
SD_CMD_ERASE_WR_BLK_START
;
end_cmd
=
SD_CMD_ERASE_WR_BLK_END
;
}
else
{
start_cmd
=
MMC_CMD_ERASE_GROUP_START
;
end_cmd
=
MMC_CMD_ERASE_GROUP_END
;
}
cmd
.
cmdidx
=
start_cmd
;
cmd
.
cmdarg
=
start
;
cmd
.
resp_type
=
MMC_RSP_R1
;
err
=
mmc_send_cmd
(
mmc
,
&
cmd
,
NULL
);
if
(
err
)
goto
err_out
;
cmd
.
cmdidx
=
end_cmd
;
cmd
.
cmdarg
=
end
;
err
=
mmc_send_cmd
(
mmc
,
&
cmd
,
NULL
);
if
(
err
)
goto
err_out
;
cmd
.
cmdidx
=
MMC_CMD_ERASE
;
cmd
.
cmdarg
=
SECURE_ERASE
;
cmd
.
resp_type
=
MMC_RSP_R1b
;
err
=
mmc_send_cmd
(
mmc
,
&
cmd
,
NULL
);
if
(
err
)
goto
err_out
;
return
0
;
err_out:
puts
(
"mmc erase failed
\n
"
);
return
err
;
}
static
unsigned
long
mmc_berase
(
int
dev_num
,
lbaint_t
start
,
lbaint_t
blkcnt
)
{
int
err
=
0
;
struct
mmc
*
mmc
=
find_mmc_device
(
dev_num
);
lbaint_t
blk
=
0
,
blk_r
=
0
;
int
timeout
=
1000
;
if
(
!
mmc
)
return
-
1
;
if
((
start
%
mmc
->
erase_grp_size
)
||
(
blkcnt
%
mmc
->
erase_grp_size
))
printf
(
"
\n\n
Caution! 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
)
&
~
(
mmc
->
erase_grp_size
-
1
))
-
1
);
while
(
blk
<
blkcnt
)
{
blk_r
=
((
blkcnt
-
blk
)
>
mmc
->
erase_grp_size
)
?
mmc
->
erase_grp_size
:
(
blkcnt
-
blk
);
err
=
mmc_erase_t
(
mmc
,
start
+
blk
,
blk_r
);
if
(
err
)
break
;
blk
+=
blk_r
;
/* Waiting for the ready status */
if
(
mmc_send_status
(
mmc
,
timeout
))
return
0
;
}
return
blk
;
}
static
ulong
mmc_write_blocks
(
struct
mmc
*
mmc
,
lbaint_t
start
,
lbaint_t
blkcnt
,
const
void
*
src
)
{
struct
mmc_cmd
cmd
;
struct
mmc_data
data
;
int
timeout
=
1000
;
if
((
start
+
blkcnt
)
>
mmc
->
block_dev
.
lba
)
{
printf
(
"MMC: block number 0x"
LBAF
" exceeds max(0x"
LBAF
")
\n
"
,
start
+
blkcnt
,
mmc
->
block_dev
.
lba
);
return
0
;
}
if
(
blkcnt
==
0
)
return
0
;
else
if
(
blkcnt
==
1
)
cmd
.
cmdidx
=
MMC_CMD_WRITE_SINGLE_BLOCK
;
else
cmd
.
cmdidx
=
MMC_CMD_WRITE_MULTIPLE_BLOCK
;
if
(
mmc
->
high_capacity
)
cmd
.
cmdarg
=
start
;
else
cmd
.
cmdarg
=
start
*
mmc
->
write_bl_len
;
cmd
.
resp_type
=
MMC_RSP_R1
;
data
.
src
=
src
;
data
.
blocks
=
blkcnt
;
data
.
blocksize
=
mmc
->
write_bl_len
;
data
.
flags
=
MMC_DATA_WRITE
;
if
(
mmc_send_cmd
(
mmc
,
&
cmd
,
&
data
))
{
printf
(
"mmc write failed
\n
"
);
return
0
;
}
/* SPI multiblock writes terminate using a special
* token, not a STOP_TRANSMISSION request.
*/
if
(
!
mmc_host_is_spi
(
mmc
)
&&
blkcnt
>
1
)
{
cmd
.
cmdidx
=
MMC_CMD_STOP_TRANSMISSION
;
cmd
.
cmdarg
=
0
;
cmd
.
resp_type
=
MMC_RSP_R1b
;
if
(
mmc_send_cmd
(
mmc
,
&
cmd
,
NULL
))
{
printf
(
"mmc fail to send stop cmd
\n
"
);
return
0
;
}
}
/* Waiting for the ready status */
if
(
mmc_send_status
(
mmc
,
timeout
))
return
0
;
return
blkcnt
;
}
static
ulong
mmc_bwrite
(
int
dev_num
,
lbaint_t
start
,
lbaint_t
blkcnt
,
const
void
*
src
)
{
lbaint_t
cur
,
blocks_todo
=
blkcnt
;
struct
mmc
*
mmc
=
find_mmc_device
(
dev_num
);
if
(
!
mmc
)
return
0
;
if
(
mmc_set_blocklen
(
mmc
,
mmc
->
write_bl_len
))
return
0
;
do
{
cur
=
(
blocks_todo
>
mmc
->
b_max
)
?
mmc
->
b_max
:
blocks_todo
;
if
(
mmc_write_blocks
(
mmc
,
start
,
cur
,
src
)
!=
cur
)
return
0
;
blocks_todo
-=
cur
;
start
+=
cur
;
src
+=
cur
*
mmc
->
write_bl_len
;
}
while
(
blocks_todo
>
0
);
return
blkcnt
;
}
static
int
mmc_read_blocks
(
struct
mmc
*
mmc
,
void
*
dst
,
lbaint_t
start
,
lbaint_t
blkcnt
)
{
...
...
@@ -385,7 +220,9 @@ static int mmc_read_blocks(struct mmc *mmc, void *dst, lbaint_t start,
cmd
.
cmdarg
=
0
;
cmd
.
resp_type
=
MMC_RSP_R1b
;
if
(
mmc_send_cmd
(
mmc
,
&
cmd
,
NULL
))
{
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf
(
"mmc fail to send stop cmd
\n
"
);
#endif
return
0
;
}
}
...
...
@@ -405,8 +242,10 @@ static ulong mmc_bread(int dev_num, lbaint_t start, lbaint_t blkcnt, void *dst)
return
0
;
if
((
start
+
blkcnt
)
>
mmc
->
block_dev
.
lba
)
{
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf
(
"MMC: block number 0x"
LBAF
" exceeds max(0x"
LBAF
")
\n
"
,
start
+
blkcnt
,
mmc
->
block_dev
.
lba
);
#endif
return
0
;
}
...
...
@@ -1268,6 +1107,7 @@ static int mmc_startup(struct mmc *mmc)
mmc
->
block_dev
.
blksz
=
mmc
->
read_bl_len
;
mmc
->
block_dev
.
log2blksz
=
LOG2
(
mmc
->
block_dev
.
blksz
);
mmc
->
block_dev
.
lba
=
lldiv
(
mmc
->
capacity
,
mmc
->
read_bl_len
);
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
sprintf
(
mmc
->
block_dev
.
vendor
,
"Man %06x Snr %04x%04x"
,
mmc
->
cid
[
0
]
>>
24
,
(
mmc
->
cid
[
2
]
&
0xffff
),
(
mmc
->
cid
[
3
]
>>
16
)
&
0xffff
);
...
...
@@ -1277,6 +1117,11 @@ static int mmc_startup(struct mmc *mmc)
(
mmc
->
cid
[
2
]
>>
24
)
&
0xff
);
sprintf
(
mmc
->
block_dev
.
revision
,
"%d.%d"
,
(
mmc
->
cid
[
2
]
>>
20
)
&
0xf
,
(
mmc
->
cid
[
2
]
>>
16
)
&
0xf
);
#else
mmc
->
block_dev
.
vendor
[
0
]
=
0
;
mmc
->
block_dev
.
product
[
0
]
=
0
;
mmc
->
block_dev
.
revision
[
0
]
=
0
;
#endif
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBDISK_SUPPORT)
init_part
(
&
mmc
->
block_dev
);
#endif
...
...
@@ -1343,7 +1188,9 @@ int mmc_start_init(struct mmc *mmc)
if
(
mmc_getcd
(
mmc
)
==
0
)
{
mmc
->
has_init
=
0
;
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf
(
"MMC: no card present
\n
"
);
#endif
return
NO_CARD_ERR
;
}
...
...
@@ -1378,7 +1225,9 @@ int mmc_start_init(struct mmc *mmc)
err
=
mmc_send_op_cond
(
mmc
);
if
(
err
&&
err
!=
IN_PROGRESS
)
{
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
printf
(
"Card did not respond to voltage select!
\n
"
);
#endif
return
UNUSABLE_ERR
;
}
}
...
...
@@ -1434,6 +1283,8 @@ static int __def_mmc_init(bd_t *bis)
int
cpu_mmc_init
(
bd_t
*
bis
)
__attribute__
((
weak
,
alias
(
"__def_mmc_init"
)));
int
board_mmc_init
(
bd_t
*
bis
)
__attribute__
((
weak
,
alias
(
"__def_mmc_init"
)));
#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_LIBCOMMON_SUPPORT)
void
print_mmc_devices
(
char
separator
)
{
struct
mmc
*
m
;
...
...
@@ -1451,6 +1302,10 @@ void print_mmc_devices(char separator)
printf
(
"
\n
"
);
}
#else
void
print_mmc_devices
(
char
separator
)
{
}
#endif
int
get_mmc_num
(
void
)
{
return
cur_dev_num
;
...
...
drivers/mmc/mmc_private.h
0 → 100644
浏览文件 @
d0b96168
/*
* Copyright 2008,2010 Freescale Semiconductor, Inc
* Andy Fleming
*
* Based (loosely) on the Linux code
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _MMC_PRIVATE_H_
#define _MMC_PRIVATE_H_
#include <mmc.h>
extern
int
mmc_send_cmd
(
struct
mmc
*
mmc
,
struct
mmc_cmd
*
cmd
,
struct
mmc_data
*
data
);
extern
int
mmc_send_status
(
struct
mmc
*
mmc
,
int
timeout
);
extern
int
mmc_set_blocklen
(
struct
mmc
*
mmc
,
int
len
);
#ifndef CONFIG_SPL_BUILD
extern
unsigned
long
mmc_berase
(
int
dev_num
,
lbaint_t
start
,
lbaint_t
blkcnt
);
extern
ulong
mmc_bwrite
(
int
dev_num
,
lbaint_t
start
,
lbaint_t
blkcnt
,
const
void
*
src
);
#else
/* CONFIG_SPL_BUILD */
/* SPL will never write or erase, declare dummies to reduce code size. */
static
inline
unsigned
long
mmc_berase
(
int
dev_num
,
lbaint_t
start
,
lbaint_t
blkcnt
)
{
return
0
;
}
static
inline
ulong
mmc_bwrite
(
int
dev_num
,
lbaint_t
start
,
lbaint_t
blkcnt
,
const
void
*
src
)
{
return
0
;
}
#endif
/* CONFIG_SPL_BUILD */
#endif
/* _MMC_PRIVATE_H_ */
drivers/mmc/mmc_write.c
0 → 100644
浏览文件 @
d0b96168
/*
* Copyright 2008, Freescale Semiconductor, Inc
* Andy Fleming
*
* Based vaguely on the Linux code
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <config.h>
#include <common.h>
#include <part.h>
#include "mmc_private.h"
static
ulong
mmc_erase_t
(
struct
mmc
*
mmc
,
ulong
start
,
lbaint_t
blkcnt
)
{
struct
mmc_cmd
cmd
;
ulong
end
;
int
err
,
start_cmd
,
end_cmd
;
if
(
mmc
->
high_capacity
)
{
end
=
start
+
blkcnt
-
1
;
}
else
{
end
=
(
start
+
blkcnt
-
1
)
*
mmc
->
write_bl_len
;
start
*=
mmc
->
write_bl_len
;
}
if
(
IS_SD
(
mmc
))
{
start_cmd
=
SD_CMD_ERASE_WR_BLK_START
;
end_cmd
=
SD_CMD_ERASE_WR_BLK_END
;
}
else
{
start_cmd
=
MMC_CMD_ERASE_GROUP_START
;
end_cmd
=
MMC_CMD_ERASE_GROUP_END
;
}
cmd
.
cmdidx
=
start_cmd
;
cmd
.
cmdarg
=
start
;
cmd
.
resp_type
=
MMC_RSP_R1
;
err
=
mmc_send_cmd
(
mmc
,
&
cmd
,
NULL
);
if
(
err
)
goto
err_out
;
cmd
.
cmdidx
=
end_cmd
;
cmd
.
cmdarg
=
end
;
err
=
mmc_send_cmd
(
mmc
,
&
cmd
,
NULL
);
if
(
err
)
goto
err_out
;
cmd
.
cmdidx
=
MMC_CMD_ERASE
;
cmd
.
cmdarg
=
SECURE_ERASE
;
cmd
.
resp_type
=
MMC_RSP_R1b
;
err
=
mmc_send_cmd
(
mmc
,
&
cmd
,
NULL
);
if
(
err
)
goto
err_out
;
return
0
;
err_out:
puts
(
"mmc erase failed
\n
"
);
return
err
;
}
unsigned
long
mmc_berase
(
int
dev_num
,
lbaint_t
start
,
lbaint_t
blkcnt
)
{
int
err
=
0
;
struct
mmc
*
mmc
=
find_mmc_device
(
dev_num
);
lbaint_t
blk
=
0
,
blk_r
=
0
;
int
timeout
=
1000
;
if
(
!
mmc
)
return
-
1
;
if
((
start
%
mmc
->
erase_grp_size
)
||
(
blkcnt
%
mmc
->
erase_grp_size
))
printf
(
"
\n\n
Caution! 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
)
&
~
(
mmc
->
erase_grp_size
-
1
))
-
1
);
while
(
blk
<
blkcnt
)
{
blk_r
=
((
blkcnt
-
blk
)
>
mmc
->
erase_grp_size
)
?
mmc
->
erase_grp_size
:
(
blkcnt
-
blk
);
err
=
mmc_erase_t
(
mmc
,
start
+
blk
,
blk_r
);
if
(
err
)
break
;
blk
+=
blk_r
;
/* Waiting for the ready status */
if
(
mmc_send_status
(
mmc
,
timeout
))
return
0
;
}
return
blk
;
}
static
ulong
mmc_write_blocks
(
struct
mmc
*
mmc
,
lbaint_t
start
,
lbaint_t
blkcnt
,
const
void
*
src
)
{
struct
mmc_cmd
cmd
;
struct
mmc_data
data
;
int
timeout
=
1000
;
if
((
start
+
blkcnt
)
>
mmc
->
block_dev
.
lba
)
{
printf
(
"MMC: block number 0x"
LBAF
" exceeds max(0x"
LBAF
")
\n
"
,
start
+
blkcnt
,
mmc
->
block_dev
.
lba
);
return
0
;
}
if
(
blkcnt
==
0
)
return
0
;
else
if
(
blkcnt
==
1
)
cmd
.
cmdidx
=
MMC_CMD_WRITE_SINGLE_BLOCK
;
else
cmd
.
cmdidx
=
MMC_CMD_WRITE_MULTIPLE_BLOCK
;
if
(
mmc
->
high_capacity
)
cmd
.
cmdarg
=
start
;
else
cmd
.
cmdarg
=
start
*
mmc
->
write_bl_len
;
cmd
.
resp_type
=
MMC_RSP_R1
;
data
.
src
=
src
;
data
.
blocks
=
blkcnt
;
data
.
blocksize
=
mmc
->
write_bl_len
;
data
.
flags
=
MMC_DATA_WRITE
;
if
(
mmc_send_cmd
(
mmc
,
&
cmd
,
&
data
))
{
printf
(
"mmc write failed
\n
"
);
return
0
;
}
/* SPI multiblock writes terminate using a special
* token, not a STOP_TRANSMISSION request.
*/
if
(
!
mmc_host_is_spi
(
mmc
)
&&
blkcnt
>
1
)
{
cmd
.
cmdidx
=
MMC_CMD_STOP_TRANSMISSION
;
cmd
.
cmdarg
=
0
;
cmd
.
resp_type
=
MMC_RSP_R1b
;
if
(
mmc_send_cmd
(
mmc
,
&
cmd
,
NULL
))
{
printf
(
"mmc fail to send stop cmd
\n
"
);
return
0
;
}
}
/* Waiting for the ready status */
if
(
mmc_send_status
(
mmc
,
timeout
))
return
0
;
return
blkcnt
;
}
ulong
mmc_bwrite
(
int
dev_num
,
lbaint_t
start
,
lbaint_t
blkcnt
,
const
void
*
src
)
{
lbaint_t
cur
,
blocks_todo
=
blkcnt
;
struct
mmc
*
mmc
=
find_mmc_device
(
dev_num
);
if
(
!
mmc
)
return
0
;
if
(
mmc_set_blocklen
(
mmc
,
mmc
->
write_bl_len
))
return
0
;
do
{
cur
=
(
blocks_todo
>
mmc
->
b_max
)
?
mmc
->
b_max
:
blocks_todo
;
if
(
mmc_write_blocks
(
mmc
,
start
,
cur
,
src
)
!=
cur
)
return
0
;
blocks_todo
-=
cur
;
start
+=
cur
;
src
+=
cur
*
mmc
->
write_bl_len
;
}
while
(
blocks_todo
>
0
);
return
blkcnt
;
}
drivers/mmc/omap_hsmmc.c
浏览文件 @
d0b96168
...
...
@@ -288,6 +288,30 @@ static void mmc_reset_controller_fsm(struct hsmmc *mmc_base, u32 bit)
mmc_reg_out
(
&
mmc_base
->
sysctl
,
bit
,
bit
);
/*
* CMD(DAT) lines reset procedures are slightly different
* for OMAP3 and OMAP4(AM335x,OMAP5,DRA7xx).
* According to OMAP3 TRM:
* Set SRC(SRD) bit in MMCHS_SYSCTL register to 0x1 and wait until it
* returns to 0x0.
* According to OMAP4(AM335x,OMAP5,DRA7xx) TRMs, CMD(DATA) lines reset
* procedure steps must be as follows:
* 1. Initiate CMD(DAT) line reset by writing 0x1 to SRC(SRD) bit in
* MMCHS_SYSCTL register (SD_SYSCTL for AM335x).
* 2. Poll the SRC(SRD) bit until it is set to 0x1.
* 3. Wait until the SRC (SRD) bit returns to 0x0
* (reset procedure is completed).
*/
#if defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \
defined(CONFIG_AM33XX)
if
(
!
(
readl
(
&
mmc_base
->
sysctl
)
&
bit
))
{
start
=
get_timer
(
0
);
while
(
!
(
readl
(
&
mmc_base
->
sysctl
)
&
bit
))
{
if
(
get_timer
(
0
)
-
start
>
MAX_RETRY_MS
)
return
;
}
}
#endif
start
=
get_timer
(
0
);
while
((
readl
(
&
mmc_base
->
sysctl
)
&
bit
)
!=
0
)
{
if
(
get_timer
(
0
)
-
start
>
MAX_RETRY_MS
)
{
...
...
@@ -376,6 +400,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
}
writel
(
cmd
->
cmdarg
,
&
mmc_base
->
arg
);
udelay
(
20
);
/* To fix "No status update" error on eMMC */
writel
((
cmd
->
cmdidx
<<
24
)
|
flags
,
&
mmc_base
->
cmd
);
start
=
get_timer
(
0
);
...
...
@@ -480,7 +505,7 @@ static int mmc_write_data(struct hsmmc *mmc_base, const char *buf,
unsigned
int
count
;
/*
* Start Polled
Read
* Start Polled
Write
*/
count
=
(
size
>
MMCSD_SECTOR_SIZE
)
?
MMCSD_SECTOR_SIZE
:
size
;
count
/=
4
;
...
...
@@ -586,6 +611,8 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
{
struct
mmc
*
mmc
=
&
hsmmc_dev
[
dev_index
];
struct
omap_hsmmc_data
*
priv_data
=
&
hsmmc_dev_data
[
dev_index
];
uint
host_caps_val
=
MMC_MODE_4BIT
|
MMC_MODE_HS_52MHz
|
MMC_MODE_HS
|
MMC_MODE_HC
;
sprintf
(
mmc
->
name
,
"OMAP SD/MMC"
);
mmc
->
send_cmd
=
mmc_send_cmd
;
...
...
@@ -600,11 +627,20 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
#ifdef OMAP_HSMMC2_BASE
case
1
:
priv_data
->
base_addr
=
(
struct
hsmmc
*
)
OMAP_HSMMC2_BASE
;
#if (defined(CONFIG_OMAP44XX) || defined(CONFIG_OMAP54XX) || \
defined(CONFIG_DRA7XX)) && defined(CONFIG_HSMMC2_8BIT)
/* Enable 8-bit interface for eMMC on OMAP4/5 or DRA7XX */
host_caps_val
|=
MMC_MODE_8BIT
;
#endif
break
;
#endif
#ifdef OMAP_HSMMC3_BASE
case
2
:
priv_data
->
base_addr
=
(
struct
hsmmc
*
)
OMAP_HSMMC3_BASE
;
#if defined(CONFIG_DRA7XX) && defined(CONFIG_HSMMC3_8BIT)
/* Enable 8-bit interface for eMMC on DRA7XX */
host_caps_val
|=
MMC_MODE_8BIT
;
#endif
break
;
#endif
default:
...
...
@@ -620,8 +656,7 @@ int omap_mmc_init(int dev_index, uint host_caps_mask, uint f_max, int cd_gpio,
mmc
->
getwp
=
omap_mmc_getwp
;
mmc
->
voltages
=
MMC_VDD_32_33
|
MMC_VDD_33_34
|
MMC_VDD_165_195
;
mmc
->
host_caps
=
(
MMC_MODE_4BIT
|
MMC_MODE_HS_52MHz
|
MMC_MODE_HS
|
MMC_MODE_HC
)
&
~
host_caps_mask
;
mmc
->
host_caps
=
host_caps_val
&
~
host_caps_mask
;
mmc
->
f_min
=
400000
;
...
...
drivers/mmc/s5p_sdhci.c
浏览文件 @
d0b96168
...
...
@@ -72,7 +72,7 @@ int s5p_sdhci_init(u32 regbase, int index, int bus_width)
host
->
quirks
=
SDHCI_QUIRK_NO_HISPD_BIT
|
SDHCI_QUIRK_BROKEN_VOLTAGE
|
SDHCI_QUIRK_BROKEN_R1B
|
SDHCI_QUIRK_32BIT_DMA_ADDR
|
SDHCI_QUIRK_WAIT_SEND_CMD
;
SDHCI_QUIRK_WAIT_SEND_CMD
|
SDHCI_QUIRK_USE_WIDE8
;
host
->
voltages
=
MMC_VDD_32_33
|
MMC_VDD_33_34
|
MMC_VDD_165_195
;
host
->
version
=
sdhci_readw
(
host
,
SDHCI_HOST_VERSION
);
...
...
@@ -81,6 +81,8 @@ int s5p_sdhci_init(u32 regbase, int index, int bus_width)
host
->
index
=
index
;
host
->
host_caps
=
MMC_MODE_HC
;
if
(
bus_width
==
8
)
host
->
host_caps
|=
MMC_MODE_8BIT
;
return
add_sdhci
(
host
,
52000000
,
400000
);
}
drivers/mmc/sdhci.c
浏览文件 @
d0b96168
...
...
@@ -68,10 +68,9 @@ static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
unsigned
int
stat
,
rdy
,
mask
,
timeout
,
block
=
0
;
#ifdef CONFIG_MMC_SDMA
unsigned
char
ctrl
;
ctrl
=
sdhci_read
l
(
host
,
SDHCI_HOST_CONTROL
);
ctrl
=
sdhci_read
b
(
host
,
SDHCI_HOST_CONTROL
);
ctrl
&=
~
SDHCI_CTRL_DMA_MASK
;
ctrl
|=
SDHCI_CTRL_SDMA
;
sdhci_writel
(
host
,
ctrl
,
SDHCI_HOST_CONTROL
);
sdhci_writeb
(
host
,
ctrl
,
SDHCI_HOST_CONTROL
);
#endif
timeout
=
1000000
;
...
...
@@ -254,7 +253,7 @@ static int sdhci_set_clock(struct mmc *mmc, unsigned int clock)
if
(
clock
==
0
)
return
0
;
if
(
(
host
->
version
&
SDHCI_SPEC_VER_MASK
)
>=
SDHCI_SPEC_300
)
{
if
(
SDHCI_GET_VERSION
(
host
)
>=
SDHCI_SPEC_300
)
{
/* Version 3.00 divisors must be a multiple of 2. */
if
(
mmc
->
f_max
<=
clock
)
div
=
1
;
...
...
@@ -347,10 +346,11 @@ void sdhci_set_ios(struct mmc *mmc)
ctrl
=
sdhci_readb
(
host
,
SDHCI_HOST_CONTROL
);
if
(
mmc
->
bus_width
==
8
)
{
ctrl
&=
~
SDHCI_CTRL_4BITBUS
;
if
((
host
->
version
&
SDHCI_SPEC_VER_MASK
)
>=
SDHCI_SPEC_300
)
if
((
SDHCI_GET_VERSION
(
host
)
>=
SDHCI_SPEC_300
)
||
(
host
->
quirks
&
SDHCI_QUIRK_USE_WIDE8
))
ctrl
|=
SDHCI_CTRL_8BITBUS
;
}
else
{
if
(
(
host
->
version
&
SDHCI_SPEC_VER_MASK
)
>=
SDHCI_SPEC_300
)
if
(
SDHCI_GET_VERSION
(
host
)
>=
SDHCI_SPEC_300
)
ctrl
&=
~
SDHCI_CTRL_8BITBUS
;
if
(
mmc
->
bus_width
==
4
)
ctrl
|=
SDHCI_CTRL_4BITBUS
;
...
...
@@ -437,7 +437,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
if
(
max_clk
)
mmc
->
f_max
=
max_clk
;
else
{
if
(
(
host
->
version
&
SDHCI_SPEC_VER_MASK
)
>=
SDHCI_SPEC_300
)
if
(
SDHCI_GET_VERSION
(
host
)
>=
SDHCI_SPEC_300
)
mmc
->
f_max
=
(
caps
&
SDHCI_CLOCK_V3_BASE_MASK
)
>>
SDHCI_CLOCK_BASE_SHIFT
;
else
...
...
@@ -452,7 +452,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
if
(
min_clk
)
mmc
->
f_min
=
min_clk
;
else
{
if
(
(
host
->
version
&
SDHCI_SPEC_VER_MASK
)
>=
SDHCI_SPEC_300
)
if
(
SDHCI_GET_VERSION
(
host
)
>=
SDHCI_SPEC_300
)
mmc
->
f_min
=
mmc
->
f_max
/
SDHCI_MAX_DIV_SPEC_300
;
else
mmc
->
f_min
=
mmc
->
f_max
/
SDHCI_MAX_DIV_SPEC_200
;
...
...
@@ -470,7 +470,7 @@ int add_sdhci(struct sdhci_host *host, u32 max_clk, u32 min_clk)
mmc
->
voltages
|=
host
->
voltages
;
mmc
->
host_caps
=
MMC_MODE_HS
|
MMC_MODE_HS_52MHz
|
MMC_MODE_4BIT
;
if
(
(
host
->
version
&
SDHCI_SPEC_VER_MASK
)
>=
SDHCI_SPEC_300
)
{
if
(
SDHCI_GET_VERSION
(
host
)
>=
SDHCI_SPEC_300
)
{
if
(
caps
&
SDHCI_CAN_DO_8BIT
)
mmc
->
host_caps
|=
MMC_MODE_8BIT
;
}
...
...
include/common.h
浏览文件 @
d0b96168
...
...
@@ -1015,10 +1015,10 @@ static inline phys_addr_t map_to_sysmem(void *ptr)
* of a function scoped static buffer. It can not be used to create a cache
* line aligned global buffer.
*/
#define PAD_COUNT(s, pad) ((
s - 1) / pad
+ 1)
#define PAD_COUNT(s, pad) ((
(s) - 1) / (pad)
+ 1)
#define PAD_SIZE(s, pad) (PAD_COUNT(s, pad) * pad)
#define ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, pad) \
char __##name[ROUND(PAD_SIZE(
size
* sizeof(type), pad), align) \
char __##name[ROUND(PAD_SIZE(
(size)
* sizeof(type), pad), align) \
+ (align - 1)]; \
\
type *name = (type *) ALIGN((uintptr_t)__##name, align)
...
...
include/mmc.h
浏览文件 @
d0b96168
...
...
@@ -335,7 +335,11 @@ int mmc_start_init(struct mmc *mmc);
void
mmc_set_preinit
(
struct
mmc
*
mmc
,
int
preinit
);
#ifdef CONFIG_GENERIC_MMC
#ifdef CONFIG_MMC_SPI
#define mmc_host_is_spi(mmc) ((mmc)->host_caps & MMC_MODE_SPI)
#else
#define mmc_host_is_spi(mmc) 0
#endif
struct
mmc
*
mmc_spi_init
(
uint
bus
,
uint
cs
,
uint
speed
,
uint
mode
);
#else
int
mmc_legacy_init
(
int
verbose
);
...
...
include/sdhci.h
浏览文件 @
d0b96168
...
...
@@ -192,6 +192,8 @@
#define SDHCI_SPEC_200 1
#define SDHCI_SPEC_300 2
#define SDHCI_GET_VERSION(x) (x->version & SDHCI_SPEC_VER_MASK)
/*
* End of controller registers.
*/
...
...
@@ -210,6 +212,7 @@
#define SDHCI_QUIRK_NO_CD (1 << 5)
#define SDHCI_QUIRK_WAIT_SEND_CMD (1 << 6)
#define SDHCI_QUIRK_NO_SIMULT_VDD_AND_POWER (1 << 7)
#define SDHCI_QUIRK_USE_WIDE8 (1 << 8)
/* to make gcc happy */
struct
sdhci_host
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录