Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OS
U-Boot.Mirror
提交
23bca26a
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,发现更多精彩内容 >>
提交
23bca26a
编写于
7月 08, 2009
作者:
W
Wolfgang Denk
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of /home/wd/git/u-boot/custodians
上级
efbf14e9
2e8a6f55
变更
20
隐藏空白更改
内联
并排
Showing
20 changed file
with
273 addition
and
581 deletion
+273
-581
README
README
+6
-0
board/bf537-stamp/Makefile
board/bf537-stamp/Makefile
+0
-1
board/bf537-stamp/nand.c
board/bf537-stamp/nand.c
+0
-100
board/davinci/sonata/sonata.c
board/davinci/sonata/sonata.c
+28
-0
common/cmd_nand.c
common/cmd_nand.c
+21
-10
common/cmd_onenand.c
common/cmd_onenand.c
+23
-12
common/env_nand.c
common/env_nand.c
+29
-22
common/env_onenand.c
common/env_onenand.c
+1
-1
doc/README.nand
doc/README.nand
+0
-9
drivers/mtd/nand/Makefile
drivers/mtd/nand/Makefile
+2
-1
drivers/mtd/nand/davinci_nand.c
drivers/mtd/nand/davinci_nand.c
+37
-252
drivers/mtd/nand/fsl_elbc_nand.c
drivers/mtd/nand/fsl_elbc_nand.c
+4
-0
drivers/mtd/nand/nand_plat.c
drivers/mtd/nand/nand_plat.c
+53
-0
drivers/mtd/nand/nand_util.c
drivers/mtd/nand/nand_util.c
+10
-10
include/asm-arm/arch-davinci/nand_defs.h
include/asm-arm/arch-davinci/nand_defs.h
+7
-123
include/configs/bf537-stamp.h
include/configs/bf537-stamp.h
+18
-26
include/configs/bfin_adi_common.h
include/configs/bfin_adi_common.h
+3
-0
include/configs/smdk6400.h
include/configs/smdk6400.h
+3
-0
include/nand.h
include/nand.h
+7
-7
nand_spl/nand_boot.c
nand_spl/nand_boot.c
+21
-7
未找到文件。
README
浏览文件 @
23bca26a
...
@@ -2428,6 +2428,12 @@ to save the current settings.
...
@@ -2428,6 +2428,12 @@ to save the current settings.
to a block boundary, and CONFIG_ENV_SIZE must be a multiple of
to a block boundary, and CONFIG_ENV_SIZE must be a multiple of
the NAND devices block size.
the NAND devices block size.
- CONFIG_NAND_ENV_DST
Defines address in RAM to which the nand_spl code should copy the
environment. If redundant environment is used, it will be copied to
CONFIG_NAND_ENV_DST + CONFIG_ENV_SIZE.
- CONFIG_SYS_SPI_INIT_OFFSET
- CONFIG_SYS_SPI_INIT_OFFSET
Defines offset to the initial SPI buffer area in DPRAM. The
Defines offset to the initial SPI buffer area in DPRAM. The
...
...
board/bf537-stamp/Makefile
浏览文件 @
23bca26a
...
@@ -32,7 +32,6 @@ LIB = $(obj)lib$(BOARD).a
...
@@ -32,7 +32,6 @@ LIB = $(obj)lib$(BOARD).a
COBJS-y
:=
$(BOARD)
.o cmd_bf537led.o
COBJS-y
:=
$(BOARD)
.o cmd_bf537led.o
COBJS-$(CONFIG_BFIN_IDE)
+=
ide-cf.o
COBJS-$(CONFIG_BFIN_IDE)
+=
ide-cf.o
COBJS-$(CONFIG_CMD_EEPROM)
+=
spi_flash.o
COBJS-$(CONFIG_CMD_EEPROM)
+=
spi_flash.o
COBJS-$(CONFIG_CMD_NAND)
+=
nand.o
COBJS-$(CONFIG_POST)
+=
post.o post-memory.o
COBJS-$(CONFIG_POST)
+=
post.o post-memory.o
SRCS
:=
$
(
SOBJS-y:.o
=
.S
)
$
(
COBJS-y:.o
=
.c
)
SRCS
:=
$
(
SOBJS-y:.o
=
.S
)
$
(
COBJS-y:.o
=
.c
)
...
...
board/bf537-stamp/nand.c
已删除
100644 → 0
浏览文件 @
efbf14e9
/*
* Copyright (c) 2006-2007 Analog Devices Inc.
*
* See file CREDITS for list of people who contributed to this
* project.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
#include <common.h>
#include <asm/io.h>
#include <nand.h>
#define CONCAT(a,b,c,d) a ## b ## c ## d
#define PORT(a,b) CONCAT(pPORT,a,b,)
#ifndef CONFIG_NAND_GPIO_PORT
#define CONFIG_NAND_GPIO_PORT F
#endif
/*
* hardware specific access to control-lines
*/
static
void
bfin_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
ctrl
)
{
register
struct
nand_chip
*
this
=
mtd
->
priv
;
u32
IO_ADDR_W
=
(
u32
)
this
->
IO_ADDR_W
;
if
(
ctrl
&
NAND_CTRL_CHANGE
)
{
if
(
ctrl
&
NAND_CLE
)
IO_ADDR_W
=
CONFIG_SYS_NAND_BASE
+
BFIN_NAND_CLE
;
else
IO_ADDR_W
=
CONFIG_SYS_NAND_BASE
;
if
(
ctrl
&
NAND_ALE
)
IO_ADDR_W
=
CONFIG_SYS_NAND_BASE
+
BFIN_NAND_ALE
;
else
IO_ADDR_W
=
CONFIG_SYS_NAND_BASE
;
this
->
IO_ADDR_W
=
(
void
__iomem
*
)
IO_ADDR_W
;
}
this
->
IO_ADDR_R
=
this
->
IO_ADDR_W
;
/* Drain the writebuffer */
SSYNC
();
if
(
cmd
!=
NAND_CMD_NONE
)
writeb
(
cmd
,
this
->
IO_ADDR_W
);
}
int
bfin_device_ready
(
struct
mtd_info
*
mtd
)
{
int
ret
=
(
*
PORT
(
CONFIG_NAND_GPIO_PORT
,
IO
)
&
BFIN_NAND_READY
)
?
1
:
0
;
SSYNC
();
return
ret
;
}
/*
* Board-specific NAND initialization. The following members of the
* argument are board-specific (per include/linux/mtd/nand.h):
* - IO_ADDR_R?: address to read the 8 I/O lines of the flash device
* - IO_ADDR_W?: address to write the 8 I/O lines of the flash device
* - cmd_ctrl: hardwarespecific function for accesing control-lines
* - dev_ready: hardwarespecific function for accesing device ready/busy line
* - enable_hwecc?: function to enable (reset) hardware ecc generator. Must
* only be provided if a hardware ECC is available
* - ecc.mode: mode of ecc, see defines
* - chip_delay: chip dependent delay for transfering data from array to
* read regs (tR)
* - options: various chip options. They can partly be set to inform
* nand_scan about special functionality. See the defines for further
* explanation
* Members with a "?" were not set in the merged testing-NAND branch,
* so they are not set here either.
*/
int
board_nand_init
(
struct
nand_chip
*
nand
)
{
*
PORT
(
CONFIG_NAND_GPIO_PORT
,
_FER
)
&=
~
BFIN_NAND_READY
;
*
PORT
(
CONFIG_NAND_GPIO_PORT
,
IO_DIR
)
&=
~
BFIN_NAND_READY
;
*
PORT
(
CONFIG_NAND_GPIO_PORT
,
IO_INEN
)
|=
BFIN_NAND_READY
;
nand
->
cmd_ctrl
=
bfin_hwcontrol
;
nand
->
ecc
.
mode
=
NAND_ECC_SOFT
;
nand
->
dev_ready
=
bfin_device_ready
;
nand
->
chip_delay
=
30
;
return
0
;
}
board/davinci/sonata/sonata.c
浏览文件 @
23bca26a
...
@@ -25,6 +25,8 @@
...
@@ -25,6 +25,8 @@
*/
*/
#include <common.h>
#include <common.h>
#include <nand.h>
#include <asm/arch/nand_defs.h>
#include <asm/arch/hardware.h>
#include <asm/arch/hardware.h>
#include "../common/misc.h"
#include "../common/misc.h"
...
@@ -72,3 +74,29 @@ int misc_init_r(void)
...
@@ -72,3 +74,29 @@ int misc_init_r(void)
return
(
0
);
return
(
0
);
}
}
#ifdef CONFIG_NAND_DAVINCI
/* Set WP on deselect, write enable on select */
static
void
nand_sonata_select_chip
(
struct
mtd_info
*
mtd
,
int
chip
)
{
#define GPIO_SET_DATA01 0x01c67018
#define GPIO_CLR_DATA01 0x01c6701c
#define GPIO_NAND_WP (1 << 4)
#ifdef SONATA_BOARD_GPIOWP
if
(
chip
<
0
)
{
REG
(
GPIO_CLR_DATA01
)
|=
GPIO_NAND_WP
;
}
else
{
REG
(
GPIO_SET_DATA01
)
|=
GPIO_NAND_WP
;
}
#endif
}
int
board_nand_init
(
struct
nand_chip
*
nand
)
{
davinci_nand_init
(
nand
);
nand
->
select_chip
=
nand_sonata_select_chip
;
return
0
;
}
#endif
/* CONFIG_NAND_DAVINCI */
common/cmd_nand.c
浏览文件 @
23bca26a
...
@@ -414,18 +414,29 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
...
@@ -414,18 +414,29 @@ int do_nand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
}
}
if
(
strcmp
(
cmd
,
"markbad"
)
==
0
)
{
if
(
strcmp
(
cmd
,
"markbad"
)
==
0
)
{
addr
=
(
ulong
)
simple_strtoul
(
argv
[
2
],
NULL
,
16
);
argc
-=
2
;
argv
+=
2
;
int
ret
=
nand
->
block_markbad
(
nand
,
addr
);
if
(
argc
<=
0
)
if
(
ret
==
0
)
{
goto
usage
;
printf
(
"block 0x%08lx successfully marked as bad
\n
"
,
(
ulong
)
addr
);
while
(
argc
>
0
)
{
return
0
;
addr
=
simple_strtoul
(
*
argv
,
NULL
,
16
);
}
else
{
printf
(
"block 0x%08lx NOT marked as bad! ERROR %d
\n
"
,
if
(
nand
->
block_markbad
(
nand
,
addr
))
{
(
ulong
)
addr
,
ret
);
printf
(
"block 0x%08lx NOT marked "
"as bad! ERROR %d
\n
"
,
addr
,
ret
);
ret
=
1
;
}
else
{
printf
(
"block 0x%08lx successfully "
"marked as bad
\n
"
,
addr
);
}
--
argc
;
++
argv
;
}
}
return
1
;
return
ret
;
}
}
if
(
strcmp
(
cmd
,
"biterr"
)
==
0
)
{
if
(
strcmp
(
cmd
,
"biterr"
)
==
0
)
{
...
...
common/cmd_onenand.c
浏览文件 @
23bca26a
...
@@ -340,7 +340,7 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
...
@@ -340,7 +340,7 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
int
blocksize
;
int
blocksize
;
ulong
addr
,
ofs
;
ulong
addr
,
ofs
;
size_t
len
,
retlen
=
0
;
size_t
len
,
retlen
=
0
;
int
ret
;
int
ret
=
0
;
char
*
cmd
,
*
s
;
char
*
cmd
,
*
s
;
mtd
=
&
onenand_mtd
;
mtd
=
&
onenand_mtd
;
...
@@ -434,18 +434,29 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
...
@@ -434,18 +434,29 @@ int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
}
}
if
(
strcmp
(
cmd
,
"markbad"
)
==
0
)
{
if
(
strcmp
(
cmd
,
"markbad"
)
==
0
)
{
addr
=
(
ulong
)
simple_strtoul
(
argv
[
2
],
NULL
,
16
);
argc
-=
2
;
argv
+=
2
;
int
ret
=
mtd
->
block_markbad
(
mtd
,
addr
);
if
(
argc
<=
0
)
if
(
ret
==
0
)
{
goto
usage
;
printf
(
"block 0x%08lx successfully marked as bad
\n
"
,
(
ulong
)
addr
);
while
(
argc
>
0
)
{
return
0
;
addr
=
simple_strtoul
(
*
argv
,
NULL
,
16
);
}
else
{
printf
(
"block 0x%08lx NOT marked as bad! ERROR %d
\n
"
,
if
(
mtd
->
block_markbad
(
mtd
,
addr
))
{
(
ulong
)
addr
,
ret
);
printf
(
"block 0x%08lx NOT marked "
"as bad! ERROR %d
\n
"
,
addr
,
ret
);
ret
=
1
;
}
else
{
printf
(
"block 0x%08lx successfully "
"marked as bad
\n
"
,
addr
);
}
--
argc
;
++
argv
;
}
}
return
1
;
return
ret
;
}
}
if
(
strncmp
(
cmd
,
"dump"
,
4
)
==
0
)
{
if
(
strncmp
(
cmd
,
"dump"
,
4
)
==
0
)
{
...
@@ -474,7 +485,7 @@ usage:
...
@@ -474,7 +485,7 @@ usage:
}
}
U_BOOT_CMD
(
U_BOOT_CMD
(
onenand
,
6
,
1
,
do_onenand
,
onenand
,
CONFIG_SYS_MAXARGS
,
1
,
do_onenand
,
"OneNAND sub-system"
,
"OneNAND sub-system"
,
"info - show available OneNAND devices
\n
"
"info - show available OneNAND devices
\n
"
"onenand bad - show bad blocks
\n
"
"onenand bad - show bad blocks
\n
"
...
...
common/env_nand.c
浏览文件 @
23bca26a
...
@@ -68,9 +68,11 @@ extern int default_environment_size;
...
@@ -68,9 +68,11 @@ extern int default_environment_size;
char
*
env_name_spec
=
"NAND"
;
char
*
env_name_spec
=
"NAND"
;
#if
def ENV_IS_EMBEDDED
#if
defined(ENV_IS_EMBEDDED)
extern
uchar
environment
[];
extern
uchar
environment
[];
env_t
*
env_ptr
=
(
env_t
*
)(
&
environment
[
0
]);
env_t
*
env_ptr
=
(
env_t
*
)(
&
environment
[
0
]);
#elif defined(CONFIG_NAND_ENV_DST)
env_t
*
env_ptr
=
(
env_t
*
)
CONFIG_NAND_ENV_DST
;
#else
/* ! ENV_IS_EMBEDDED */
#else
/* ! ENV_IS_EMBEDDED */
env_t
*
env_ptr
=
0
;
env_t
*
env_ptr
=
0
;
#endif
/* ENV_IS_EMBEDDED */
#endif
/* ENV_IS_EMBEDDED */
...
@@ -102,26 +104,33 @@ uchar env_get_char_spec (int index)
...
@@ -102,26 +104,33 @@ uchar env_get_char_spec (int index)
*/
*/
int
env_init
(
void
)
int
env_init
(
void
)
{
{
#if defined(ENV_IS_EMBEDDED)
#if defined(ENV_IS_EMBEDDED) || defined(CONFIG_NAND_ENV_DST)
size_t
total
;
int
crc1_ok
=
0
,
crc2_ok
=
0
;
int
crc1_ok
=
0
,
crc2_ok
=
0
;
env_t
*
tmp_env1
,
*
tmp_env2
;
env_t
*
tmp_env1
;
total
=
CONFIG_ENV_SIZE
;
#ifdef CONFIG_ENV_OFFSET_REDUND
env_t
*
tmp_env2
;
tmp_env1
=
env_ptr
;
tmp_env2
=
(
env_t
*
)((
ulong
)
env_ptr
+
CONFIG_ENV_SIZE
);
tmp_env2
=
(
env_t
*
)((
ulong
)
env_ptr
+
CONFIG_ENV_SIZE
);
crc2_ok
=
(
crc32
(
0
,
tmp_env2
->
data
,
ENV_SIZE
)
==
tmp_env2
->
crc
);
#endif
tmp_env1
=
env_ptr
;
crc1_ok
=
(
crc32
(
0
,
tmp_env1
->
data
,
ENV_SIZE
)
==
tmp_env1
->
crc
);
crc1_ok
=
(
crc32
(
0
,
tmp_env1
->
data
,
ENV_SIZE
)
==
tmp_env1
->
crc
);
crc2_ok
=
(
crc32
(
0
,
tmp_env2
->
data
,
ENV_SIZE
)
==
tmp_env2
->
crc
);
if
(
!
crc1_ok
&&
!
crc2_ok
)
if
(
!
crc1_ok
&&
!
crc2_ok
)
{
gd
->
env_addr
=
0
;
gd
->
env_valid
=
0
;
gd
->
env_valid
=
0
;
else
if
(
crc1_ok
&&
!
crc2_ok
)
return
0
;
}
else
if
(
crc1_ok
&&
!
crc2_ok
)
{
gd
->
env_valid
=
1
;
gd
->
env_valid
=
1
;
else
if
(
!
crc1_ok
&&
crc2_ok
)
}
#ifdef CONFIG_ENV_OFFSET_REDUND
else
if
(
!
crc1_ok
&&
crc2_ok
)
{
gd
->
env_valid
=
2
;
gd
->
env_valid
=
2
;
else
{
}
else
{
/* both ok - check serial */
/* both ok - check serial */
if
(
tmp_env1
->
flags
==
255
&&
tmp_env2
->
flags
==
0
)
if
(
tmp_env1
->
flags
==
255
&&
tmp_env2
->
flags
==
0
)
gd
->
env_valid
=
2
;
gd
->
env_valid
=
2
;
...
@@ -135,14 +144,19 @@ int env_init(void)
...
@@ -135,14 +144,19 @@ int env_init(void)
gd
->
env_valid
=
1
;
gd
->
env_valid
=
1
;
}
}
if
(
gd
->
env_valid
==
2
)
env_ptr
=
tmp_env2
;
else
#endif
if
(
gd
->
env_valid
==
1
)
if
(
gd
->
env_valid
==
1
)
env_ptr
=
tmp_env1
;
env_ptr
=
tmp_env1
;
else
if
(
gd
->
env_valid
==
2
)
env_ptr
=
tmp_env2
;
gd
->
env_addr
=
(
ulong
)
env_ptr
->
data
;
#else
/* ENV_IS_EMBEDDED */
#else
/* ENV_IS_EMBEDDED || CONFIG_NAND_ENV_DST */
gd
->
env_addr
=
(
ulong
)
&
default_environment
[
0
];
gd
->
env_addr
=
(
ulong
)
&
default_environment
[
0
];
gd
->
env_valid
=
1
;
gd
->
env_valid
=
1
;
#endif
/* ENV_IS_EMBEDDED */
#endif
/* ENV_IS_EMBEDDED
|| CONFIG_NAND_ENV_DST
*/
return
(
0
);
return
(
0
);
}
}
...
@@ -183,12 +197,10 @@ int writeenv(size_t offset, u_char *buf)
...
@@ -183,12 +197,10 @@ int writeenv(size_t offset, u_char *buf)
#ifdef CONFIG_ENV_OFFSET_REDUND
#ifdef CONFIG_ENV_OFFSET_REDUND
int
saveenv
(
void
)
int
saveenv
(
void
)
{
{
size_t
total
;
int
ret
=
0
;
int
ret
=
0
;
nand_erase_options_t
nand_erase_options
;
nand_erase_options_t
nand_erase_options
;
env_ptr
->
flags
++
;
env_ptr
->
flags
++
;
total
=
CONFIG_ENV_SIZE
;
nand_erase_options
.
length
=
CONFIG_ENV_RANGE
;
nand_erase_options
.
length
=
CONFIG_ENV_RANGE
;
nand_erase_options
.
quiet
=
0
;
nand_erase_options
.
quiet
=
0
;
...
@@ -226,7 +238,6 @@ int saveenv(void)
...
@@ -226,7 +238,6 @@ int saveenv(void)
#else
/* ! CONFIG_ENV_OFFSET_REDUND */
#else
/* ! CONFIG_ENV_OFFSET_REDUND */
int
saveenv
(
void
)
int
saveenv
(
void
)
{
{
size_t
total
;
int
ret
=
0
;
int
ret
=
0
;
nand_erase_options_t
nand_erase_options
;
nand_erase_options_t
nand_erase_options
;
...
@@ -243,7 +254,6 @@ int saveenv(void)
...
@@ -243,7 +254,6 @@ int saveenv(void)
return
1
;
return
1
;
puts
(
"Writing to Nand... "
);
puts
(
"Writing to Nand... "
);
total
=
CONFIG_ENV_SIZE
;
if
(
writeenv
(
CONFIG_ENV_OFFSET
,
(
u_char
*
)
env_ptr
))
{
if
(
writeenv
(
CONFIG_ENV_OFFSET
,
(
u_char
*
)
env_ptr
))
{
puts
(
"FAILED!
\n
"
);
puts
(
"FAILED!
\n
"
);
return
1
;
return
1
;
...
@@ -287,12 +297,9 @@ int readenv (size_t offset, u_char * buf)
...
@@ -287,12 +297,9 @@ int readenv (size_t offset, u_char * buf)
void
env_relocate_spec
(
void
)
void
env_relocate_spec
(
void
)
{
{
#if !defined(ENV_IS_EMBEDDED)
#if !defined(ENV_IS_EMBEDDED)
size_t
total
;
int
crc1_ok
=
0
,
crc2_ok
=
0
;
int
crc1_ok
=
0
,
crc2_ok
=
0
;
env_t
*
tmp_env1
,
*
tmp_env2
;
env_t
*
tmp_env1
,
*
tmp_env2
;
total
=
CONFIG_ENV_SIZE
;
tmp_env1
=
(
env_t
*
)
malloc
(
CONFIG_ENV_SIZE
);
tmp_env1
=
(
env_t
*
)
malloc
(
CONFIG_ENV_SIZE
);
tmp_env2
=
(
env_t
*
)
malloc
(
CONFIG_ENV_SIZE
);
tmp_env2
=
(
env_t
*
)
malloc
(
CONFIG_ENV_SIZE
);
...
...
common/env_onenand.c
浏览文件 @
23bca26a
...
@@ -58,7 +58,7 @@ uchar env_get_char_spec(int index)
...
@@ -58,7 +58,7 @@ uchar env_get_char_spec(int index)
void
env_relocate_spec
(
void
)
void
env_relocate_spec
(
void
)
{
{
unsigned
long
env_addr
;
loff_t
env_addr
;
int
use_default
=
0
;
int
use_default
=
0
;
size_t
retlen
;
size_t
retlen
;
...
...
doc/README.nand
浏览文件 @
23bca26a
...
@@ -101,15 +101,6 @@ Configuration Options:
...
@@ -101,15 +101,6 @@ Configuration Options:
CONFIG_SYS_NAND_MAX_CHIPS
CONFIG_SYS_NAND_MAX_CHIPS
The maximum number of NAND chips per device to be supported.
The maximum number of NAND chips per device to be supported.
CONFIG_SYS_DAVINCI_BROKEN_ECC
Versions of U-Boot <= 1.3.3 and Montavista Linux kernels
generated bogus ECCs on large-page NAND. Both large and small page
NAND ECCs were incompatible with the Linux davinci git tree (since
NAND was integrated in 2.6.24).
Turn this ON if you want backwards compatibility.
Turn this OFF if you want U-Boot and the Linux davinci git kernel
to use the same ECC format.
NOTE:
NOTE:
=====
=====
...
...
drivers/mtd/nand/Makefile
浏览文件 @
23bca26a
...
@@ -42,9 +42,10 @@ COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
...
@@ -42,9 +42,10 @@ COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_nand.o
COBJS-$(CONFIG_NAND_FSL_UPM)
+=
fsl_upm.o
COBJS-$(CONFIG_NAND_FSL_UPM)
+=
fsl_upm.o
COBJS-$(CONFIG_NAND_MPC5121_NFC)
+=
mpc5121_nfc.o
COBJS-$(CONFIG_NAND_MPC5121_NFC)
+=
mpc5121_nfc.o
COBJS-$(CONFIG_NAND_NOMADIK)
+=
nomadik.o
COBJS-$(CONFIG_NAND_NOMADIK)
+=
nomadik.o
COBJS-$(CONFIG_NAND_S3C2410)
+=
s3c2410_nand.
c
COBJS-$(CONFIG_NAND_S3C2410)
+=
s3c2410_nand.
o
COBJS-$(CONFIG_NAND_S3C64XX)
+=
s3c64xx.o
COBJS-$(CONFIG_NAND_S3C64XX)
+=
s3c64xx.o
COBJS-$(CONFIG_NAND_OMAP_GPMC)
+=
omap_gpmc.o
COBJS-$(CONFIG_NAND_OMAP_GPMC)
+=
omap_gpmc.o
COBJS-$(CONFIG_NAND_PLAT)
+=
nand_plat.o
endif
endif
COBJS
:=
$
(
COBJS-y
)
COBJS
:=
$
(
COBJS-y
)
...
...
drivers/mtd/nand/davinci_nand.c
浏览文件 @
23bca26a
...
@@ -47,7 +47,7 @@
...
@@ -47,7 +47,7 @@
#include <asm/arch/nand_defs.h>
#include <asm/arch/nand_defs.h>
#include <asm/arch/emif_defs.h>
#include <asm/arch/emif_defs.h>
extern
struct
nand_chip
nand_dev_desc
[
CONFIG_SYS_MAX_NAND_DEVICE
]
;
static
emif_registers
*
const
emif_regs
=
(
void
*
)
DAVINCI_ASYNC_EMIF_CNTRL_BASE
;
static
void
nand_davinci_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
ctrl
)
static
void
nand_davinci_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
ctrl
)
{
{
...
@@ -68,81 +68,30 @@ static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int c
...
@@ -68,81 +68,30 @@ static void nand_davinci_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int c
writeb
(
cmd
,
this
->
IO_ADDR_W
);
writeb
(
cmd
,
this
->
IO_ADDR_W
);
}
}
/* Set WP on deselect, write enable on select */
static
void
nand_davinci_select_chip
(
struct
mtd_info
*
mtd
,
int
chip
)
{
#define GPIO_SET_DATA01 0x01c67018
#define GPIO_CLR_DATA01 0x01c6701c
#define GPIO_NAND_WP (1 << 4)
#ifdef SONATA_BOARD_GPIOWP
if
(
chip
<
0
)
{
REG
(
GPIO_CLR_DATA01
)
|=
GPIO_NAND_WP
;
}
else
{
REG
(
GPIO_SET_DATA01
)
|=
GPIO_NAND_WP
;
}
#endif
}
#ifdef CONFIG_SYS_NAND_HW_ECC
#ifdef CONFIG_SYS_NAND_HW_ECC
#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
/* Linux-compatible ECC uses MTD defaults. */
/* These layouts are not compatible with Linux or RBL/UBL. */
#ifdef CONFIG_SYS_NAND_LARGEPAGE
static
struct
nand_ecclayout
davinci_nand_ecclayout
=
{
.
eccbytes
=
12
,
.
eccpos
=
{
8
,
9
,
10
,
24
,
25
,
26
,
40
,
41
,
42
,
56
,
57
,
58
},
.
oobfree
=
{
{.
offset
=
2
,
.
length
=
6
},
{.
offset
=
12
,
.
length
=
12
},
{.
offset
=
28
,
.
length
=
12
},
{.
offset
=
44
,
.
length
=
12
},
{.
offset
=
60
,
.
length
=
4
}
}
};
#elif defined(CONFIG_SYS_NAND_SMALLPAGE)
static
struct
nand_ecclayout
davinci_nand_ecclayout
=
{
.
eccbytes
=
3
,
.
eccpos
=
{
0
,
1
,
2
},
.
oobfree
=
{
{.
offset
=
6
,
.
length
=
2
},
{.
offset
=
8
,
.
length
=
8
}
}
};
#else
#error "Either CONFIG_SYS_NAND_LARGEPAGE or CONFIG_SYS_NAND_SMALLPAGE must be defined!"
#endif
#endif
/* CONFIG_SYS_DAVINCI_BROKEN_ECC */
static
void
nand_davinci_enable_hwecc
(
struct
mtd_info
*
mtd
,
int
mode
)
static
void
nand_davinci_enable_hwecc
(
struct
mtd_info
*
mtd
,
int
mode
)
{
{
emifregs
emif_addr
;
int
dummy
;
int
dummy
;
emif_addr
=
(
emifregs
)
DAVINCI_ASYNC_EMIF_CNTRL_BASE
;
dummy
=
emif_regs
->
NANDF1ECC
;
dummy
=
emif_addr
->
NANDF1ECC
;
/* FIXME: only chipselect 0 is supported for now */
dummy
=
emif_addr
->
NANDF2ECC
;
emif_regs
->
NANDFCR
|=
1
<<
8
;
dummy
=
emif_addr
->
NANDF3ECC
;
dummy
=
emif_addr
->
NANDF4ECC
;
emif_addr
->
NANDFCR
|=
(
1
<<
8
);
}
}
static
u_int32_t
nand_davinci_readecc
(
struct
mtd_info
*
mtd
,
u_int32_t
region
)
static
u_int32_t
nand_davinci_readecc
(
struct
mtd_info
*
mtd
,
u_int32_t
region
)
{
{
u_int32_t
ecc
=
0
;
u_int32_t
ecc
=
0
;
emifregs
emif_base_addr
;
emif_base_addr
=
(
emifregs
)
DAVINCI_ASYNC_EMIF_CNTRL_BASE
;
if
(
region
==
1
)
if
(
region
==
1
)
ecc
=
emif_
base_addr
->
NANDF1ECC
;
ecc
=
emif_
regs
->
NANDF1ECC
;
else
if
(
region
==
2
)
else
if
(
region
==
2
)
ecc
=
emif_
base_addr
->
NANDF2ECC
;
ecc
=
emif_
regs
->
NANDF2ECC
;
else
if
(
region
==
3
)
else
if
(
region
==
3
)
ecc
=
emif_
base_addr
->
NANDF3ECC
;
ecc
=
emif_
regs
->
NANDF3ECC
;
else
if
(
region
==
4
)
else
if
(
region
==
4
)
ecc
=
emif_
base_addr
->
NANDF4ECC
;
ecc
=
emif_
regs
->
NANDF4ECC
;
return
(
ecc
);
return
(
ecc
);
}
}
...
@@ -150,29 +99,6 @@ static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region)
...
@@ -150,29 +99,6 @@ static u_int32_t nand_davinci_readecc(struct mtd_info *mtd, u_int32_t region)
static
int
nand_davinci_calculate_ecc
(
struct
mtd_info
*
mtd
,
const
u_char
*
dat
,
u_char
*
ecc_code
)
static
int
nand_davinci_calculate_ecc
(
struct
mtd_info
*
mtd
,
const
u_char
*
dat
,
u_char
*
ecc_code
)
{
{
u_int32_t
tmp
;
u_int32_t
tmp
;
#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
/*
* This is not how you should read ECCs on large page Davinci devices.
* The region parameter gets you ECCs for flash chips on different chip
* selects, not the 4x512 byte pages in a 2048 byte page.
*
* Preserved for backwards compatibility though.
*/
int
region
,
n
;
struct
nand_chip
*
this
=
mtd
->
priv
;
n
=
(
this
->
ecc
.
size
/
512
);
region
=
1
;
while
(
n
--
)
{
tmp
=
nand_davinci_readecc
(
mtd
,
region
);
*
ecc_code
++
=
tmp
;
*
ecc_code
++
=
tmp
>>
16
;
*
ecc_code
++
=
((
tmp
>>
8
)
&
0x0f
)
|
((
tmp
>>
20
)
&
0xf0
);
region
++
;
}
#else
const
int
region
=
1
;
const
int
region
=
1
;
tmp
=
nand_davinci_readecc
(
mtd
,
region
);
tmp
=
nand_davinci_readecc
(
mtd
,
region
);
...
@@ -187,148 +113,26 @@ static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u
...
@@ -187,148 +113,26 @@ static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u
*
ecc_code
++
=
tmp
;
*
ecc_code
++
=
tmp
;
*
ecc_code
++
=
tmp
>>
8
;
*
ecc_code
++
=
tmp
>>
8
;
*
ecc_code
++
=
tmp
>>
16
;
*
ecc_code
++
=
tmp
>>
16
;
#endif
/* CONFIG_SYS_DAVINCI_BROKEN_ECC */
return
(
0
);
}
#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
static
void
nand_davinci_gen_true_ecc
(
u_int8_t
*
ecc_buf
)
{
u_int32_t
tmp
=
ecc_buf
[
0
]
|
(
ecc_buf
[
1
]
<<
16
)
|
((
ecc_buf
[
2
]
&
0xf0
)
<<
20
)
|
((
ecc_buf
[
2
]
&
0x0f
)
<<
8
);
ecc_buf
[
0
]
=
~
(
P64o
(
tmp
)
|
P64e
(
tmp
)
|
P32o
(
tmp
)
|
P32e
(
tmp
)
|
P16o
(
tmp
)
|
P16e
(
tmp
)
|
P8o
(
tmp
)
|
P8e
(
tmp
));
ecc_buf
[
1
]
=
~
(
P1024o
(
tmp
)
|
P1024e
(
tmp
)
|
P512o
(
tmp
)
|
P512e
(
tmp
)
|
P256o
(
tmp
)
|
P256e
(
tmp
)
|
P128o
(
tmp
)
|
P128e
(
tmp
));
ecc_buf
[
2
]
=
~
(
P4o
(
tmp
)
|
P4e
(
tmp
)
|
P2o
(
tmp
)
|
P2e
(
tmp
)
|
P1o
(
tmp
)
|
P1e
(
tmp
)
|
P2048o
(
tmp
)
|
P2048e
(
tmp
));
}
static
int
nand_davinci_compare_ecc
(
u_int8_t
*
ecc_nand
,
u_int8_t
*
ecc_calc
,
u_int8_t
*
page_data
)
{
u_int32_t
i
;
u_int8_t
tmp0_bit
[
8
],
tmp1_bit
[
8
],
tmp2_bit
[
8
];
u_int8_t
comp0_bit
[
8
],
comp1_bit
[
8
],
comp2_bit
[
8
];
u_int8_t
ecc_bit
[
24
];
u_int8_t
ecc_sum
=
0
;
u_int8_t
find_bit
=
0
;
u_int32_t
find_byte
=
0
;
int
is_ecc_ff
;
is_ecc_ff
=
((
*
ecc_nand
==
0xff
)
&&
(
*
(
ecc_nand
+
1
)
==
0xff
)
&&
(
*
(
ecc_nand
+
2
)
==
0xff
));
nand_davinci_gen_true_ecc
(
ecc_nand
);
nand_davinci_gen_true_ecc
(
ecc_calc
);
for
(
i
=
0
;
i
<=
2
;
i
++
)
{
*
(
ecc_nand
+
i
)
=
~
(
*
(
ecc_nand
+
i
));
*
(
ecc_calc
+
i
)
=
~
(
*
(
ecc_calc
+
i
));
}
for
(
i
=
0
;
i
<
8
;
i
++
)
{
/* NOTE: the above code matches mainline Linux:
tmp0_bit
[
i
]
=
*
ecc_nand
%
2
;
* .PQR.stu ==> ~PQRstu
*
ecc_nand
=
*
ecc_nand
/
2
;
*
}
* MontaVista/TI kernels encode those bytes differently, use
* complicated (and allegedly sometimes-wrong) correction code,
for
(
i
=
0
;
i
<
8
;
i
++
)
{
* and usually shipped with U-Boot that uses software ECC:
tmp1_bit
[
i
]
=
*
(
ecc_nand
+
1
)
%
2
;
* .PQR.stu ==> PsQRtu
*
(
ecc_nand
+
1
)
=
*
(
ecc_nand
+
1
)
/
2
;
*
}
* If you need MV/TI compatible NAND I/O in U-Boot, it should
* be possible to (a) change the mangling above, (b) reverse
for
(
i
=
0
;
i
<
8
;
i
++
)
{
* that mangling in nand_davinci_correct_data() below.
tmp2_bit
[
i
]
=
*
(
ecc_nand
+
2
)
%
2
;
*/
*
(
ecc_nand
+
2
)
=
*
(
ecc_nand
+
2
)
/
2
;
}
for
(
i
=
0
;
i
<
8
;
i
++
)
{
comp0_bit
[
i
]
=
*
ecc_calc
%
2
;
*
ecc_calc
=
*
ecc_calc
/
2
;
}
for
(
i
=
0
;
i
<
8
;
i
++
)
{
comp1_bit
[
i
]
=
*
(
ecc_calc
+
1
)
%
2
;
*
(
ecc_calc
+
1
)
=
*
(
ecc_calc
+
1
)
/
2
;
}
for
(
i
=
0
;
i
<
8
;
i
++
)
{
comp2_bit
[
i
]
=
*
(
ecc_calc
+
2
)
%
2
;
*
(
ecc_calc
+
2
)
=
*
(
ecc_calc
+
2
)
/
2
;
}
for
(
i
=
0
;
i
<
6
;
i
++
)
ecc_bit
[
i
]
=
tmp2_bit
[
i
+
2
]
^
comp2_bit
[
i
+
2
];
for
(
i
=
0
;
i
<
8
;
i
++
)
ecc_bit
[
i
+
6
]
=
tmp0_bit
[
i
]
^
comp0_bit
[
i
];
for
(
i
=
0
;
i
<
8
;
i
++
)
ecc_bit
[
i
+
14
]
=
tmp1_bit
[
i
]
^
comp1_bit
[
i
];
ecc_bit
[
22
]
=
tmp2_bit
[
0
]
^
comp2_bit
[
0
];
ecc_bit
[
23
]
=
tmp2_bit
[
1
]
^
comp2_bit
[
1
];
for
(
i
=
0
;
i
<
24
;
i
++
)
ecc_sum
+=
ecc_bit
[
i
];
switch
(
ecc_sum
)
{
return
0
;
case
0
:
/* Not reached because this function is not called if
ECC values are equal */
return
0
;
case
1
:
/* Uncorrectable error */
MTDDEBUG
(
MTD_DEBUG_LEVEL0
,
"ECC UNCORRECTED_ERROR 1
\n
"
);
return
(
-
1
);
case
12
:
/* Correctable error */
find_byte
=
(
ecc_bit
[
23
]
<<
8
)
+
(
ecc_bit
[
21
]
<<
7
)
+
(
ecc_bit
[
19
]
<<
6
)
+
(
ecc_bit
[
17
]
<<
5
)
+
(
ecc_bit
[
15
]
<<
4
)
+
(
ecc_bit
[
13
]
<<
3
)
+
(
ecc_bit
[
11
]
<<
2
)
+
(
ecc_bit
[
9
]
<<
1
)
+
ecc_bit
[
7
];
find_bit
=
(
ecc_bit
[
5
]
<<
2
)
+
(
ecc_bit
[
3
]
<<
1
)
+
ecc_bit
[
1
];
MTDDEBUG
(
MTD_DEBUG_LEVEL0
,
"Correcting single bit ECC "
"error at offset: %d, bit: %d
\n
"
,
find_byte
,
find_bit
);
page_data
[
find_byte
]
^=
(
1
<<
find_bit
);
return
(
0
);
default:
if
(
is_ecc_ff
)
{
if
(
ecc_calc
[
0
]
==
0
&&
ecc_calc
[
1
]
==
0
&&
ecc_calc
[
2
]
==
0
)
return
(
0
);
}
MTDDEBUG
(
MTD_DEBUG_LEVEL0
,
"UNCORRECTED_ERROR default
\n
"
);
return
(
-
1
);
}
}
}
#endif
/* CONFIG_SYS_DAVINCI_BROKEN_ECC */
static
int
nand_davinci_correct_data
(
struct
mtd_info
*
mtd
,
u_char
*
dat
,
u_char
*
read_ecc
,
u_char
*
calc_ecc
)
static
int
nand_davinci_correct_data
(
struct
mtd_info
*
mtd
,
u_char
*
dat
,
u_char
*
read_ecc
,
u_char
*
calc_ecc
)
{
{
struct
nand_chip
*
this
=
mtd
->
priv
;
struct
nand_chip
*
this
=
mtd
->
priv
;
#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
int
block_count
=
0
,
i
,
rc
;
block_count
=
(
this
->
ecc
.
size
/
512
);
for
(
i
=
0
;
i
<
block_count
;
i
++
)
{
if
(
memcmp
(
read_ecc
,
calc_ecc
,
3
)
!=
0
)
{
rc
=
nand_davinci_compare_ecc
(
read_ecc
,
calc_ecc
,
dat
);
if
(
rc
<
0
)
{
return
(
rc
);
}
}
read_ecc
+=
3
;
calc_ecc
+=
3
;
dat
+=
512
;
}
#else
u_int32_t
ecc_nand
=
read_ecc
[
0
]
|
(
read_ecc
[
1
]
<<
8
)
|
u_int32_t
ecc_nand
=
read_ecc
[
0
]
|
(
read_ecc
[
1
]
<<
8
)
|
(
read_ecc
[
2
]
<<
16
);
(
read_ecc
[
2
]
<<
16
);
u_int32_t
ecc_calc
=
calc_ecc
[
0
]
|
(
calc_ecc
[
1
]
<<
8
)
|
u_int32_t
ecc_calc
=
calc_ecc
[
0
]
|
(
calc_ecc
[
1
]
<<
8
)
|
...
@@ -362,31 +166,24 @@ static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char *
...
@@ -362,31 +166,24 @@ static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char *
return
-
1
;
return
-
1
;
}
}
}
}
#endif
/* CONFIG_SYS_DAVINCI_BROKEN_ECC */
return
(
0
);
return
(
0
);
}
}
#endif
/* CONFIG_SYS_NAND_HW_ECC */
#endif
/* CONFIG_SYS_NAND_HW_ECC */
static
int
nand_davinci_dev_ready
(
struct
mtd_info
*
mtd
)
static
int
nand_davinci_dev_ready
(
struct
mtd_info
*
mtd
)
{
{
emifregs
emif_addr
;
return
emif_regs
->
NANDFSR
&
0x1
;
emif_addr
=
(
emifregs
)
DAVINCI_ASYNC_EMIF_CNTRL_BASE
;
return
(
emif_addr
->
NANDFSR
&
0x1
);
}
static
int
nand_davinci_waitfunc
(
struct
mtd_info
*
mtd
,
struct
nand_chip
*
this
)
{
while
(
!
nand_davinci_dev_ready
(
mtd
))
{;}
*
NAND_CE0CLE
=
NAND_STATUS
;
return
(
*
NAND_CE0DATA
);
}
}
static
void
nand_flash_init
(
void
)
static
void
nand_flash_init
(
void
)
{
{
/* This is for DM6446 EVM and *very* similar. DO NOT GROW THIS!
* Instead, have your board_init() set EMIF timings, based on its
* knowledge of the clocks and what devices are hooked up ... and
* don't even do that unless no UBL handled it.
*/
#ifdef CONFIG_SOC_DM6446
u_int32_t
acfg1
=
0x3ffffffc
;
u_int32_t
acfg1
=
0x3ffffffc
;
emifregs
emif_regs
;
/*------------------------------------------------------------------*
/*------------------------------------------------------------------*
* NAND FLASH CHIP TIMEOUT @ 459 MHz *
* NAND FLASH CHIP TIMEOUT @ 459 MHz *
...
@@ -408,39 +205,22 @@ static void nand_flash_init(void)
...
@@ -408,39 +205,22 @@ static void nand_flash_init(void)
|
(
0
<<
0
)
/* asyncSize 8-bit bus */
|
(
0
<<
0
)
/* asyncSize 8-bit bus */
;
;
emif_regs
=
(
emifregs
)
DAVINCI_ASYNC_EMIF_CNTRL_BASE
;
emif_regs
->
AB1CR
=
acfg1
;
/* CS2 */
emif_regs
->
AB1CR
=
acfg1
;
/* CS2 */
emif_regs
->
NANDFCR
=
0x00000101
;
/* NAND flash on CS2 */
emif_regs
->
NANDFCR
=
0x00000101
;
/* NAND flash on CS2 */
#endif
}
}
int
board
_nand_init
(
struct
nand_chip
*
nand
)
void
davinci
_nand_init
(
struct
nand_chip
*
nand
)
{
{
nand
->
IO_ADDR_R
=
(
void
__iomem
*
)
NAND_CE0DATA
;
nand
->
IO_ADDR_W
=
(
void
__iomem
*
)
NAND_CE0DATA
;
nand
->
chip_delay
=
0
;
nand
->
chip_delay
=
0
;
nand
->
select_chip
=
nand_davinci_select_chip
;
#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
#ifdef CONFIG_SYS_NAND_USE_FLASH_BBT
nand
->
options
=
NAND_USE_FLASH_BBT
;
nand
->
options
=
NAND_USE_FLASH_BBT
;
#endif
#endif
#ifdef CONFIG_SYS_NAND_HW_ECC
#ifdef CONFIG_SYS_NAND_HW_ECC
nand
->
ecc
.
mode
=
NAND_ECC_HW
;
nand
->
ecc
.
mode
=
NAND_ECC_HW
;
#ifdef CONFIG_SYS_DAVINCI_BROKEN_ECC
nand
->
ecc
.
layout
=
&
davinci_nand_ecclayout
;
#ifdef CONFIG_SYS_NAND_LARGEPAGE
nand
->
ecc
.
size
=
2048
;
nand
->
ecc
.
bytes
=
12
;
#elif defined(CONFIG_SYS_NAND_SMALLPAGE)
nand
->
ecc
.
size
=
512
;
nand
->
ecc
.
size
=
512
;
nand
->
ecc
.
bytes
=
3
;
nand
->
ecc
.
bytes
=
3
;
#else
#error "Either CONFIG_SYS_NAND_LARGEPAGE or CONFIG_SYS_NAND_SMALLPAGE must be defined!"
#endif
#else
nand
->
ecc
.
size
=
512
;
nand
->
ecc
.
bytes
=
3
;
#endif
/* CONFIG_SYS_DAVINCI_BROKEN_ECC */
nand
->
ecc
.
calculate
=
nand_davinci_calculate_ecc
;
nand
->
ecc
.
calculate
=
nand_davinci_calculate_ecc
;
nand
->
ecc
.
correct
=
nand_davinci_correct_data
;
nand
->
ecc
.
correct
=
nand_davinci_correct_data
;
nand
->
ecc
.
hwctl
=
nand_davinci_enable_hwecc
;
nand
->
ecc
.
hwctl
=
nand_davinci_enable_hwecc
;
...
@@ -452,9 +232,14 @@ int board_nand_init(struct nand_chip *nand)
...
@@ -452,9 +232,14 @@ int board_nand_init(struct nand_chip *nand)
nand
->
cmd_ctrl
=
nand_davinci_hwcontrol
;
nand
->
cmd_ctrl
=
nand_davinci_hwcontrol
;
nand
->
dev_ready
=
nand_davinci_dev_ready
;
nand
->
dev_ready
=
nand_davinci_dev_ready
;
nand
->
waitfunc
=
nand_davinci_waitfunc
;
nand_flash_init
();
nand_flash_init
();
}
return
(
0
);
int
board_nand_init
(
struct
nand_chip
*
chip
)
__attribute__
((
weak
));
int
board_nand_init
(
struct
nand_chip
*
chip
)
{
davinci_nand_init
(
chip
);
return
0
;
}
}
drivers/mtd/nand/fsl_elbc_nand.c
浏览文件 @
23bca26a
...
@@ -766,6 +766,9 @@ int board_nand_init(struct nand_chip *nand)
...
@@ -766,6 +766,9 @@ int board_nand_init(struct nand_chip *nand)
nand
->
waitfunc
=
fsl_elbc_wait
;
nand
->
waitfunc
=
fsl_elbc_wait
;
/* set up nand options */
/* set up nand options */
/* redirect the pointer of bbt pattern to RAM */
bbt_main_descr
.
pattern
=
bbt_pattern
;
bbt_mirror_descr
.
pattern
=
mirror_pattern
;
nand
->
bbt_td
=
&
bbt_main_descr
;
nand
->
bbt_td
=
&
bbt_main_descr
;
nand
->
bbt_md
=
&
bbt_mirror_descr
;
nand
->
bbt_md
=
&
bbt_mirror_descr
;
...
@@ -812,6 +815,7 @@ int board_nand_init(struct nand_chip *nand)
...
@@ -812,6 +815,7 @@ int board_nand_init(struct nand_chip *nand)
/* Large-page-specific setup */
/* Large-page-specific setup */
if
(
or
&
OR_FCM_PGS
)
{
if
(
or
&
OR_FCM_PGS
)
{
priv
->
page_size
=
1
;
priv
->
page_size
=
1
;
largepage_memorybased
.
pattern
=
scan_ff_pattern
;
nand
->
badblock_pattern
=
&
largepage_memorybased
;
nand
->
badblock_pattern
=
&
largepage_memorybased
;
/* adjust ecc setup if needed */
/* adjust ecc setup if needed */
...
...
drivers/mtd/nand/nand_plat.c
0 → 100644
浏览文件 @
23bca26a
/*
* Genericish driver for memory mapped NAND devices
*
* Copyright (c) 2006-2009 Analog Devices Inc.
* Licensed under the GPL-2 or later.
*/
/* Your board must implement the following macros:
* NAND_PLAT_WRITE_CMD(chip, cmd)
* NAND_PLAT_WRITE_ADR(chip, cmd)
* NAND_PLAT_INIT()
*
* It may also implement the following:
* NAND_PLAT_DEV_READY(chip)
*/
#include <common.h>
#include <asm/io.h>
#include <nand.h>
static
void
plat_cmd_ctrl
(
struct
mtd_info
*
mtd
,
int
cmd
,
unsigned
int
ctrl
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
if
(
cmd
==
NAND_CMD_NONE
)
return
;
if
(
ctrl
&
NAND_CLE
)
NAND_PLAT_WRITE_CMD
(
this
,
cmd
);
else
NAND_PLAT_WRITE_ADR
(
this
,
cmd
);
}
#ifdef NAND_PLAT_DEV_READY
static
int
plat_dev_ready
(
struct
mtd_info
*
mtd
)
{
return
NAND_PLAT_DEV_READY
((
struct
nand_chip
*
)
mtd
->
priv
);
}
#else
# define plat_dev_ready NULL
#endif
int
board_nand_init
(
struct
nand_chip
*
nand
)
{
NAND_PLAT_INIT
();
nand
->
cmd_ctrl
=
plat_cmd_ctrl
;
nand
->
dev_ready
=
plat_dev_ready
;
nand
->
ecc
.
mode
=
NAND_ECC_SOFT
;
return
0
;
}
drivers/mtd/nand/nand_util.c
浏览文件 @
23bca26a
...
@@ -315,7 +315,7 @@ int nand_lock(struct mtd_info *mtd, int tight)
...
@@ -315,7 +315,7 @@ int nand_lock(struct mtd_info *mtd, int tight)
* NAND_LOCK_STATUS_UNLOCK: page unlocked
* NAND_LOCK_STATUS_UNLOCK: page unlocked
*
*
*/
*/
int
nand_get_lock_status
(
struct
mtd_info
*
mtd
,
ulong
offset
)
int
nand_get_lock_status
(
struct
mtd_info
*
mtd
,
loff_t
offset
)
{
{
int
ret
=
0
;
int
ret
=
0
;
int
chipnr
;
int
chipnr
;
...
@@ -436,7 +436,7 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length)
...
@@ -436,7 +436,7 @@ int nand_unlock(struct mtd_info *mtd, ulong start, ulong length)
* @param length image length
* @param length image length
* @return image length including bad blocks
* @return image length including bad blocks
*/
*/
static
size_t
get_len_incl_bad
(
nand_info_t
*
nand
,
size
_t
offset
,
static
size_t
get_len_incl_bad
(
nand_info_t
*
nand
,
loff
_t
offset
,
const
size_t
length
)
const
size_t
length
)
{
{
size_t
len_incl_bad
=
0
;
size_t
len_incl_bad
=
0
;
...
@@ -473,7 +473,7 @@ static size_t get_len_incl_bad (nand_info_t *nand, size_t offset,
...
@@ -473,7 +473,7 @@ static size_t get_len_incl_bad (nand_info_t *nand, size_t offset,
* @param buf buffer to read from
* @param buf buffer to read from
* @return 0 in case of success
* @return 0 in case of success
*/
*/
int
nand_write_skip_bad
(
nand_info_t
*
nand
,
size
_t
offset
,
size_t
*
length
,
int
nand_write_skip_bad
(
nand_info_t
*
nand
,
loff
_t
offset
,
size_t
*
length
,
u_char
*
buffer
)
u_char
*
buffer
)
{
{
int
rval
;
int
rval
;
...
@@ -498,7 +498,7 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
...
@@ -498,7 +498,7 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
if
(
len_incl_bad
==
*
length
)
{
if
(
len_incl_bad
==
*
length
)
{
rval
=
nand_write
(
nand
,
offset
,
length
,
buffer
);
rval
=
nand_write
(
nand
,
offset
,
length
,
buffer
);
if
(
rval
!=
0
)
if
(
rval
!=
0
)
printf
(
"NAND write to offset %
z
x failed %d
\n
"
,
printf
(
"NAND write to offset %
ll
x failed %d
\n
"
,
offset
,
rval
);
offset
,
rval
);
return
rval
;
return
rval
;
...
@@ -509,7 +509,7 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
...
@@ -509,7 +509,7 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
size_t
write_size
;
size_t
write_size
;
if
(
nand_block_isbad
(
nand
,
offset
&
~
(
nand
->
erasesize
-
1
)))
{
if
(
nand_block_isbad
(
nand
,
offset
&
~
(
nand
->
erasesize
-
1
)))
{
printf
(
"Skip bad block 0x%08
z
x
\n
"
,
printf
(
"Skip bad block 0x%08
ll
x
\n
"
,
offset
&
~
(
nand
->
erasesize
-
1
));
offset
&
~
(
nand
->
erasesize
-
1
));
offset
+=
nand
->
erasesize
-
block_offset
;
offset
+=
nand
->
erasesize
-
block_offset
;
continue
;
continue
;
...
@@ -522,7 +522,7 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
...
@@ -522,7 +522,7 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
rval
=
nand_write
(
nand
,
offset
,
&
write_size
,
p_buffer
);
rval
=
nand_write
(
nand
,
offset
,
&
write_size
,
p_buffer
);
if
(
rval
!=
0
)
{
if
(
rval
!=
0
)
{
printf
(
"NAND write to offset %
z
x failed %d
\n
"
,
printf
(
"NAND write to offset %
ll
x failed %d
\n
"
,
offset
,
rval
);
offset
,
rval
);
*
length
-=
left_to_write
;
*
length
-=
left_to_write
;
return
rval
;
return
rval
;
...
@@ -550,7 +550,7 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
...
@@ -550,7 +550,7 @@ int nand_write_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
* @param buffer buffer to write to
* @param buffer buffer to write to
* @return 0 in case of success
* @return 0 in case of success
*/
*/
int
nand_read_skip_bad
(
nand_info_t
*
nand
,
size
_t
offset
,
size_t
*
length
,
int
nand_read_skip_bad
(
nand_info_t
*
nand
,
loff
_t
offset
,
size_t
*
length
,
u_char
*
buffer
)
u_char
*
buffer
)
{
{
int
rval
;
int
rval
;
...
@@ -568,7 +568,7 @@ int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
...
@@ -568,7 +568,7 @@ int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
if
(
len_incl_bad
==
*
length
)
{
if
(
len_incl_bad
==
*
length
)
{
rval
=
nand_read
(
nand
,
offset
,
length
,
buffer
);
rval
=
nand_read
(
nand
,
offset
,
length
,
buffer
);
if
(
rval
!=
0
)
if
(
rval
!=
0
)
printf
(
"NAND read from offset %
z
x failed %d
\n
"
,
printf
(
"NAND read from offset %
ll
x failed %d
\n
"
,
offset
,
rval
);
offset
,
rval
);
return
rval
;
return
rval
;
...
@@ -579,7 +579,7 @@ int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
...
@@ -579,7 +579,7 @@ int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
size_t
read_length
;
size_t
read_length
;
if
(
nand_block_isbad
(
nand
,
offset
&
~
(
nand
->
erasesize
-
1
)))
{
if
(
nand_block_isbad
(
nand
,
offset
&
~
(
nand
->
erasesize
-
1
)))
{
printf
(
"Skipping bad block 0x%08
z
x
\n
"
,
printf
(
"Skipping bad block 0x%08
ll
x
\n
"
,
offset
&
~
(
nand
->
erasesize
-
1
));
offset
&
~
(
nand
->
erasesize
-
1
));
offset
+=
nand
->
erasesize
-
block_offset
;
offset
+=
nand
->
erasesize
-
block_offset
;
continue
;
continue
;
...
@@ -592,7 +592,7 @@ int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
...
@@ -592,7 +592,7 @@ int nand_read_skip_bad(nand_info_t *nand, size_t offset, size_t *length,
rval
=
nand_read
(
nand
,
offset
,
&
read_length
,
p_buffer
);
rval
=
nand_read
(
nand
,
offset
,
&
read_length
,
p_buffer
);
if
(
rval
!=
0
)
{
if
(
rval
!=
0
)
{
printf
(
"NAND read from offset %
z
x failed %d
\n
"
,
printf
(
"NAND read from offset %
ll
x failed %d
\n
"
,
offset
,
rval
);
offset
,
rval
);
*
length
-=
left_to_read
;
*
length
-=
left_to_read
;
return
rval
;
return
rval
;
...
...
include/asm-arm/arch-davinci/nand_defs.h
浏览文件 @
23bca26a
...
@@ -28,134 +28,18 @@
...
@@ -28,134 +28,18 @@
#include <asm/arch/hardware.h>
#include <asm/arch/hardware.h>
#ifdef CONFIG_SOC_DM646x
#define MASK_CLE 0x80000
#define MASK_ALE 0x40000
#else
#define MASK_CLE 0x10
#define MASK_CLE 0x10
#define MASK_ALE 0x0a
#define MASK_ALE 0x08
#endif
#define NAND_CE0CLE ((volatile u_int8_t *)(CONFIG_SYS_NAND_BASE + 0x10))
#define NAND_CE0ALE ((volatile u_int8_t *)(CONFIG_SYS_NAND_BASE + 0x0a))
#define NAND_CE0DATA ((volatile u_int8_t *)CONFIG_SYS_NAND_BASE)
typedef
struct
{
u_int32_t
NRCSR
;
u_int32_t
AWCCR
;
u_int8_t
RSVD0
[
8
];
u_int32_t
AB1CR
;
u_int32_t
AB2CR
;
u_int32_t
AB3CR
;
u_int32_t
AB4CR
;
u_int8_t
RSVD1
[
32
];
u_int32_t
NIRR
;
u_int32_t
NIMR
;
u_int32_t
NIMSR
;
u_int32_t
NIMCR
;
u_int8_t
RSVD2
[
16
];
u_int32_t
NANDFCR
;
u_int32_t
NANDFSR
;
u_int8_t
RSVD3
[
8
];
u_int32_t
NANDF1ECC
;
u_int32_t
NANDF2ECC
;
u_int32_t
NANDF3ECC
;
u_int32_t
NANDF4ECC
;
u_int8_t
RSVD4
[
4
];
u_int32_t
IODFTECR
;
u_int32_t
IODFTGCR
;
u_int8_t
RSVD5
[
4
];
u_int32_t
IODFTMRLR
;
u_int32_t
IODFTMRMR
;
u_int32_t
IODFTMRMSBR
;
u_int8_t
RSVD6
[
20
];
u_int32_t
MODRNR
;
u_int8_t
RSVD7
[
76
];
u_int32_t
CE0DATA
;
u_int32_t
CE0ALE
;
u_int32_t
CE0CLE
;
u_int8_t
RSVD8
[
4
];
u_int32_t
CE1DATA
;
u_int32_t
CE1ALE
;
u_int32_t
CE1CLE
;
u_int8_t
RSVD9
[
4
];
u_int32_t
CE2DATA
;
u_int32_t
CE2ALE
;
u_int32_t
CE2CLE
;
u_int8_t
RSVD10
[
4
];
u_int32_t
CE3DATA
;
u_int32_t
CE3ALE
;
u_int32_t
CE3CLE
;
}
nand_registers
;
typedef
volatile
nand_registers
*
nandregs
;
#define NAND_READ_START 0x00
#define NAND_READ_START 0x00
#define NAND_READ_END 0x30
#define NAND_READ_END 0x30
#define NAND_STATUS 0x70
#define NAND_STATUS 0x70
#ifdef CONFIG_SYS_NAND_HW_ECC
extern
void
davinci_nand_init
(
struct
nand_chip
*
nand
);
#define NAND_Ecc_P1e (1 << 0)
#define NAND_Ecc_P2e (1 << 1)
#define NAND_Ecc_P4e (1 << 2)
#define NAND_Ecc_P8e (1 << 3)
#define NAND_Ecc_P16e (1 << 4)
#define NAND_Ecc_P32e (1 << 5)
#define NAND_Ecc_P64e (1 << 6)
#define NAND_Ecc_P128e (1 << 7)
#define NAND_Ecc_P256e (1 << 8)
#define NAND_Ecc_P512e (1 << 9)
#define NAND_Ecc_P1024e (1 << 10)
#define NAND_Ecc_P2048e (1 << 11)
#define NAND_Ecc_P1o (1 << 16)
#define NAND_Ecc_P2o (1 << 17)
#define NAND_Ecc_P4o (1 << 18)
#define NAND_Ecc_P8o (1 << 19)
#define NAND_Ecc_P16o (1 << 20)
#define NAND_Ecc_P32o (1 << 21)
#define NAND_Ecc_P64o (1 << 22)
#define NAND_Ecc_P128o (1 << 23)
#define NAND_Ecc_P256o (1 << 24)
#define NAND_Ecc_P512o (1 << 25)
#define NAND_Ecc_P1024o (1 << 26)
#define NAND_Ecc_P2048o (1 << 27)
#define TF(v) (v ? 1 : 0)
#define P2048e(a) (TF(a & NAND_Ecc_P2048e) << 0)
#define P2048o(a) (TF(a & NAND_Ecc_P2048o) << 1)
#define P1e(a) (TF(a & NAND_Ecc_P1e) << 2)
#define P1o(a) (TF(a & NAND_Ecc_P1o) << 3)
#define P2e(a) (TF(a & NAND_Ecc_P2e) << 4)
#define P2o(a) (TF(a & NAND_Ecc_P2o) << 5)
#define P4e(a) (TF(a & NAND_Ecc_P4e) << 6)
#define P4o(a) (TF(a & NAND_Ecc_P4o) << 7)
#define P8e(a) (TF(a & NAND_Ecc_P8e) << 0)
#define P8o(a) (TF(a & NAND_Ecc_P8o) << 1)
#define P16e(a) (TF(a & NAND_Ecc_P16e) << 2)
#define P16o(a) (TF(a & NAND_Ecc_P16o) << 3)
#define P32e(a) (TF(a & NAND_Ecc_P32e) << 4)
#define P32o(a) (TF(a & NAND_Ecc_P32o) << 5)
#define P64e(a) (TF(a & NAND_Ecc_P64e) << 6)
#define P64o(a) (TF(a & NAND_Ecc_P64o) << 7)
#define P128e(a) (TF(a & NAND_Ecc_P128e) << 0)
#define P128o(a) (TF(a & NAND_Ecc_P128o) << 1)
#define P256e(a) (TF(a & NAND_Ecc_P256e) << 2)
#define P256o(a) (TF(a & NAND_Ecc_P256o) << 3)
#define P512e(a) (TF(a & NAND_Ecc_P512e) << 4)
#define P512o(a) (TF(a & NAND_Ecc_P512o) << 5)
#define P1024e(a) (TF(a & NAND_Ecc_P1024e) << 6)
#define P1024o(a) (TF(a & NAND_Ecc_P1024o) << 7)
#define P8e_s(a) (TF(a & NAND_Ecc_P8e) << 0)
#define P8o_s(a) (TF(a & NAND_Ecc_P8o) << 1)
#define P16e_s(a) (TF(a & NAND_Ecc_P16e) << 2)
#define P16o_s(a) (TF(a & NAND_Ecc_P16o) << 3)
#define P1e_s(a) (TF(a & NAND_Ecc_P1e) << 4)
#define P1o_s(a) (TF(a & NAND_Ecc_P1o) << 5)
#define P2e_s(a) (TF(a & NAND_Ecc_P2e) << 6)
#define P2o_s(a) (TF(a & NAND_Ecc_P2o) << 7)
#define P4e_s(a) (TF(a & NAND_Ecc_P4e) << 0)
#define P4o_s(a) (TF(a & NAND_Ecc_P4o) << 1)
#endif
#endif
#endif
include/configs/bf537-stamp.h
浏览文件 @
23bca26a
...
@@ -151,36 +151,28 @@
...
@@ -151,36 +151,28 @@
/*
/*
* NAND Settings
* NAND Settings
*/
*/
/* #define CONFIG_BF537_NAND */
/* #define CONFIG_NAND_PLAT */
#ifdef CONFIG_BF537_NAND
#define CONFIG_SYS_NAND_BASE 0x20212000
# define CONFIG_CMD_NAND
#endif
#define CONFIG_SYS_NAND_ADDR 0x20212000
#define CONFIG_SYS_NAND_BASE CONFIG_SYS_NAND_ADDR
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define CONFIG_SYS_MAX_NAND_DEVICE 1
#define SECTORSIZE 512
#define ADDR_COLUMN 1
#define BFIN_NAND_CLE(chip) ((unsigned long)(chip)->IO_ADDR_W | (1 << 2))
#define ADDR_PAGE 2
#define BFIN_NAND_ALE(chip) ((unsigned long)(chip)->IO_ADDR_W | (1 << 1))
#define ADDR_COLUMN_PAGE 3
#define BFIN_NAND_READY PF3
#define NAND_ChipID_UNKNOWN 0x00
#define BFIN_NAND_WRITE(addr, cmd) \
#define NAND_MAX_FLOORS 1
#define BFIN_NAND_READY PF3
#define NAND_WAIT_READY(nand) \
do { \
do { \
int timeout = 0; \
bfin_write8(addr, cmd); \
while (!(*pPORTFIO & PF3)) \
SSYNC(); \
if (timeout++ > 100000) \
break; \
} while (0)
} while (0)
#define BFIN_NAND_CLE (1 << 2)
/* A2 -> Command Enable */
#define NAND_PLAT_WRITE_CMD(chip, cmd) BFIN_NAND_WRITE(BFIN_NAND_CLE(chip), cmd)
#define BFIN_NAND_ALE (1 << 1)
/* A1 -> Address Enable */
#define NAND_PLAT_WRITE_ADR(chip, cmd) BFIN_NAND_WRITE(BFIN_NAND_ALE(chip), cmd)
#define WRITE_NAND_COMMAND(d, adr) bfin_write8(adr | BFIN_NAND_CLE, d)
#define NAND_PLAT_DEV_READY(chip) (bfin_read_PORTFIO() & BFIN_NAND_READY)
#define WRITE_NAND_ADDRESS(d, adr) bfin_write8(adr | BFIN_NAND_ALE, d)
#define NAND_PLAT_INIT() \
#define WRITE_NAND(d, adr) bfin_write8(adr, d)
do { \
#define READ_NAND(adr) bfin_read8(adr)
bfin_write_PORTF_FER(bfin_read_PORTF_FER() & ~BFIN_NAND_READY); \
bfin_write_PORTFIO_DIR(bfin_read_PORTFIO_DIR() & ~BFIN_NAND_READY); \
bfin_write_PORTFIO_INEN(bfin_read_PORTFIO_INEN() | BFIN_NAND_READY); \
} while (0)
/*
/*
...
...
include/configs/bfin_adi_common.h
浏览文件 @
23bca26a
...
@@ -38,6 +38,9 @@
...
@@ -38,6 +38,9 @@
# define CONFIG_CMD_USB_STORAGE
# define CONFIG_CMD_USB_STORAGE
# define CONFIG_DOS_PARTITION
# define CONFIG_DOS_PARTITION
# endif
# endif
# ifdef CONFIG_NAND_PLAT
# define CONFIG_CMD_NAND
# endif
# ifdef CONFIG_POST
# ifdef CONFIG_POST
# define CONFIG_CMD_DIAG
# define CONFIG_CMD_DIAG
# endif
# endif
...
...
include/configs/smdk6400.h
浏览文件 @
23bca26a
...
@@ -209,6 +209,9 @@
...
@@ -209,6 +209,9 @@
/* total memory available to uboot */
/* total memory available to uboot */
#define CONFIG_SYS_UBOOT_SIZE (1024 * 1024)
#define CONFIG_SYS_UBOOT_SIZE (1024 * 1024)
/* Put environment copies after the end of U-Boot owned RAM */
#define CONFIG_NAND_ENV_DST (CONFIG_SYS_UBOOT_BASE + CONFIG_SYS_UBOOT_SIZE)
#ifdef CONFIG_ENABLE_MMU
#ifdef CONFIG_ENABLE_MMU
#define CONFIG_SYS_MAPPED_RAM_BASE 0xc0000000
#define CONFIG_SYS_MAPPED_RAM_BASE 0xc0000000
#define CONFIG_BOOTCOMMAND "nand read 0xc0018000 0x60000 0x1c0000;" \
#define CONFIG_BOOTCOMMAND "nand read 0xc0018000 0x60000 0x1c0000;" \
...
...
include/nand.h
浏览文件 @
23bca26a
...
@@ -38,22 +38,22 @@ typedef struct mtd_info nand_info_t;
...
@@ -38,22 +38,22 @@ typedef struct mtd_info nand_info_t;
extern
int
nand_curr_device
;
extern
int
nand_curr_device
;
extern
nand_info_t
nand_info
[];
extern
nand_info_t
nand_info
[];
static
inline
int
nand_read
(
nand_info_t
*
info
,
off_t
ofs
,
size_t
*
len
,
u_char
*
buf
)
static
inline
int
nand_read
(
nand_info_t
*
info
,
l
off_t
ofs
,
size_t
*
len
,
u_char
*
buf
)
{
{
return
info
->
read
(
info
,
ofs
,
*
len
,
(
size_t
*
)
len
,
buf
);
return
info
->
read
(
info
,
ofs
,
*
len
,
(
size_t
*
)
len
,
buf
);
}
}
static
inline
int
nand_write
(
nand_info_t
*
info
,
off_t
ofs
,
size_t
*
len
,
u_char
*
buf
)
static
inline
int
nand_write
(
nand_info_t
*
info
,
l
off_t
ofs
,
size_t
*
len
,
u_char
*
buf
)
{
{
return
info
->
write
(
info
,
ofs
,
*
len
,
(
size_t
*
)
len
,
buf
);
return
info
->
write
(
info
,
ofs
,
*
len
,
(
size_t
*
)
len
,
buf
);
}
}
static
inline
int
nand_block_isbad
(
nand_info_t
*
info
,
off_t
ofs
)
static
inline
int
nand_block_isbad
(
nand_info_t
*
info
,
l
off_t
ofs
)
{
{
return
info
->
block_isbad
(
info
,
ofs
);
return
info
->
block_isbad
(
info
,
ofs
);
}
}
static
inline
int
nand_erase
(
nand_info_t
*
info
,
off_t
off
,
size_t
size
)
static
inline
int
nand_erase
(
nand_info_t
*
info
,
l
off_t
off
,
size_t
size
)
{
{
struct
erase_info
instr
;
struct
erase_info
instr
;
...
@@ -110,9 +110,9 @@ struct nand_erase_options {
...
@@ -110,9 +110,9 @@ struct nand_erase_options {
typedef
struct
nand_erase_options
nand_erase_options_t
;
typedef
struct
nand_erase_options
nand_erase_options_t
;
int
nand_read_skip_bad
(
nand_info_t
*
nand
,
size
_t
offset
,
size_t
*
length
,
int
nand_read_skip_bad
(
nand_info_t
*
nand
,
loff
_t
offset
,
size_t
*
length
,
u_char
*
buffer
);
u_char
*
buffer
);
int
nand_write_skip_bad
(
nand_info_t
*
nand
,
size
_t
offset
,
size_t
*
length
,
int
nand_write_skip_bad
(
nand_info_t
*
nand
,
loff
_t
offset
,
size_t
*
length
,
u_char
*
buffer
);
u_char
*
buffer
);
int
nand_erase_opts
(
nand_info_t
*
meminfo
,
const
nand_erase_options_t
*
opts
);
int
nand_erase_opts
(
nand_info_t
*
meminfo
,
const
nand_erase_options_t
*
opts
);
...
@@ -122,7 +122,7 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts);
...
@@ -122,7 +122,7 @@ int nand_erase_opts(nand_info_t *meminfo, const nand_erase_options_t *opts);
int
nand_lock
(
nand_info_t
*
meminfo
,
int
tight
);
int
nand_lock
(
nand_info_t
*
meminfo
,
int
tight
);
int
nand_unlock
(
nand_info_t
*
meminfo
,
ulong
start
,
ulong
length
);
int
nand_unlock
(
nand_info_t
*
meminfo
,
ulong
start
,
ulong
length
);
int
nand_get_lock_status
(
nand_info_t
*
meminfo
,
ulong
offset
);
int
nand_get_lock_status
(
nand_info_t
*
meminfo
,
loff_t
offset
);
#ifdef CONFIG_SYS_NAND_SELECT_DEVICE
#ifdef CONFIG_SYS_NAND_SELECT_DEVICE
void
board_nand_select_device
(
struct
nand_chip
*
nand
,
int
chip
);
void
board_nand_select_device
(
struct
nand_chip
*
nand
,
int
chip
);
...
...
nand_spl/nand_boot.c
浏览文件 @
23bca26a
...
@@ -47,11 +47,13 @@ static int nand_command(struct mtd_info *mtd, int block, int page, int offs, u8
...
@@ -47,11 +47,13 @@ static int nand_command(struct mtd_info *mtd, int block, int page, int offs, u8
/* Set ALE and clear CLE to start address cycle */
/* Set ALE and clear CLE to start address cycle */
/* Column address */
/* Column address */
this
->
cmd_ctrl
(
mtd
,
offs
,
NAND_CTRL_ALE
|
NAND_CTRL_CHANGE
);
this
->
cmd_ctrl
(
mtd
,
offs
,
NAND_CTRL_ALE
|
NAND_CTRL_CHANGE
);
this
->
cmd_ctrl
(
mtd
,
page_addr
&
0xff
,
0
);
/* A[16:9] */
this
->
cmd_ctrl
(
mtd
,
page_addr
&
0xff
,
NAND_CTRL_ALE
);
/* A[16:9] */
this
->
cmd_ctrl
(
mtd
,
(
page_addr
>>
8
)
&
0xff
,
0
);
/* A[24:17] */
this
->
cmd_ctrl
(
mtd
,
(
page_addr
>>
8
)
&
0xff
,
NAND_CTRL_ALE
);
/* A[24:17] */
#ifdef CONFIG_SYS_NAND_4_ADDR_CYCLE
#ifdef CONFIG_SYS_NAND_4_ADDR_CYCLE
/* One more address cycle for devices > 32MiB */
/* One more address cycle for devices > 32MiB */
this
->
cmd_ctrl
(
mtd
,
(
page_addr
>>
16
)
&
0x0f
,
0
);
/* A[28:25] */
this
->
cmd_ctrl
(
mtd
,
(
page_addr
>>
16
)
&
0x0f
,
NAND_CTRL_ALE
);
/* A[28:25] */
#endif
#endif
/* Latch in address */
/* Latch in address */
this
->
cmd_ctrl
(
mtd
,
NAND_CMD_NONE
,
NAND_NCE
|
NAND_CTRL_CHANGE
);
this
->
cmd_ctrl
(
mtd
,
NAND_CMD_NONE
,
NAND_NCE
|
NAND_CTRL_CHANGE
);
...
@@ -94,13 +96,15 @@ static int nand_command(struct mtd_info *mtd, int block, int page, int offs, u8
...
@@ -94,13 +96,15 @@ static int nand_command(struct mtd_info *mtd, int block, int page, int offs, u8
/* Column address */
/* Column address */
this
->
cmd_ctrl
(
mtd
,
offs
&
0xff
,
this
->
cmd_ctrl
(
mtd
,
offs
&
0xff
,
NAND_CTRL_ALE
|
NAND_CTRL_CHANGE
);
/* A[7:0] */
NAND_CTRL_ALE
|
NAND_CTRL_CHANGE
);
/* A[7:0] */
this
->
cmd_ctrl
(
mtd
,
(
offs
>>
8
)
&
0xff
,
0
);
/* A[11:9] */
this
->
cmd_ctrl
(
mtd
,
(
offs
>>
8
)
&
0xff
,
NAND_CTRL_ALE
);
/* A[11:9] */
/* Row address */
/* Row address */
this
->
cmd_ctrl
(
mtd
,
(
page_addr
&
0xff
),
0
);
/* A[19:12] */
this
->
cmd_ctrl
(
mtd
,
(
page_addr
&
0xff
),
NAND_CTRL_ALE
);
/* A[19:12] */
this
->
cmd_ctrl
(
mtd
,
((
page_addr
>>
8
)
&
0xff
),
0
);
/* A[27:20] */
this
->
cmd_ctrl
(
mtd
,
((
page_addr
>>
8
)
&
0xff
),
NAND_CTRL_ALE
);
/* A[27:20] */
#ifdef CONFIG_SYS_NAND_5_ADDR_CYCLE
#ifdef CONFIG_SYS_NAND_5_ADDR_CYCLE
/* One more address cycle for devices > 128MiB */
/* One more address cycle for devices > 128MiB */
this
->
cmd_ctrl
(
mtd
,
(
page_addr
>>
16
)
&
0x0f
,
0
);
/* A[31:28] */
this
->
cmd_ctrl
(
mtd
,
(
page_addr
>>
16
)
&
0x0f
,
NAND_CTRL_ALE
);
/* A[31:28] */
#endif
#endif
/* Latch in address */
/* Latch in address */
this
->
cmd_ctrl
(
mtd
,
NAND_CMD_READSTART
,
this
->
cmd_ctrl
(
mtd
,
NAND_CMD_READSTART
,
...
@@ -246,6 +250,16 @@ void nand_boot(void)
...
@@ -246,6 +250,16 @@ void nand_boot(void)
ret
=
nand_load
(
&
nand_info
,
CONFIG_SYS_NAND_U_BOOT_OFFS
,
CONFIG_SYS_NAND_U_BOOT_SIZE
,
ret
=
nand_load
(
&
nand_info
,
CONFIG_SYS_NAND_U_BOOT_OFFS
,
CONFIG_SYS_NAND_U_BOOT_SIZE
,
(
uchar
*
)
CONFIG_SYS_NAND_U_BOOT_DST
);
(
uchar
*
)
CONFIG_SYS_NAND_U_BOOT_DST
);
#ifdef CONFIG_NAND_ENV_DST
nand_load
(
&
nand_info
,
CONFIG_ENV_OFFSET
,
CONFIG_ENV_SIZE
,
(
uchar
*
)
CONFIG_NAND_ENV_DST
);
#ifdef CONFIG_ENV_OFFSET_REDUND
nand_load
(
&
nand_info
,
CONFIG_ENV_OFFSET_REDUND
,
CONFIG_ENV_SIZE
,
(
uchar
*
)
CONFIG_NAND_ENV_DST
+
CONFIG_ENV_SIZE
);
#endif
#endif
if
(
nand_chip
.
select_chip
)
if
(
nand_chip
.
select_chip
)
nand_chip
.
select_chip
(
&
nand_info
,
-
1
);
nand_chip
.
select_chip
(
&
nand_info
,
-
1
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录