Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OS
U-Boot.Mirror
提交
508eb85d
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,发现更多精彩内容 >>
提交
508eb85d
编写于
9月 13, 2008
作者:
W
Wolfgang Denk
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'master' of
git://git.denx.de/u-boot-nand-flash
上级
225f0eaa
0008b6d9
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
138 addition
and
19 deletion
+138
-19
board/delta/nand.c
board/delta/nand.c
+2
-4
board/zylonite/nand.c
board/zylonite/nand.c
+2
-4
cpu/arm926ejs/davinci/nand.c
cpu/arm926ejs/davinci/nand.c
+76
-5
doc/README.nand
doc/README.nand
+8
-0
drivers/mtd/nand/fsl_elbc_nand.c
drivers/mtd/nand/fsl_elbc_nand.c
+50
-6
未找到文件。
board/delta/nand.c
浏览文件 @
508eb85d
...
...
@@ -58,14 +58,12 @@ static struct nand_bbt_descr delta_bbt_descr = {
.
pattern
=
scan_ff_pattern
};
static
struct
nand_oobinfo
delta_oob
=
{
.
useecc
=
MTD_NANDECC_AUTOPL_USR
,
/* MTD_NANDECC_PLACEONLY, */
static
struct
nand_ecclayout
delta_oob
=
{
.
eccbytes
=
6
,
.
eccpos
=
{
2
,
3
,
4
,
5
,
6
,
7
},
.
oobfree
=
{
{
8
,
2
},
{
12
,
4
}
}
};
/*
* not required for Monahans DFC
*/
...
...
@@ -541,6 +539,7 @@ int board_nand_init(struct nand_chip *nand)
nand
->
cmd_ctrl
=
dfc_hwcontrol
;
/* nand->dev_ready = dfc_device_ready; */
nand
->
ecc
.
mode
=
NAND_ECC_SOFT
;
nand
->
ecc
.
layout
=
&
delta_oob
;
nand
->
options
=
NAND_BUSWIDTH_16
;
nand
->
waitfunc
=
dfc_wait
;
nand
->
read_byte
=
dfc_read_byte
;
...
...
@@ -549,7 +548,6 @@ int board_nand_init(struct nand_chip *nand)
nand
->
write_buf
=
dfc_write_buf
;
nand
->
cmdfunc
=
dfc_cmdfunc
;
/* nand->autooob = &delta_oob; */
nand
->
badblock_pattern
=
&
delta_bbt_descr
;
return
0
;
}
...
...
board/zylonite/nand.c
浏览文件 @
508eb85d
...
...
@@ -58,14 +58,12 @@ static struct nand_bbt_descr delta_bbt_descr = {
.
pattern
=
scan_ff_pattern
};
static
struct
nand_oobinfo
delta_oob
=
{
.
useecc
=
MTD_NANDECC_AUTOPL_USR
,
/* MTD_NANDECC_PLACEONLY, */
static
struct
nand_ecclayout
delta_oob
=
{
.
eccbytes
=
6
,
.
eccpos
=
{
2
,
3
,
4
,
5
,
6
,
7
},
.
oobfree
=
{
{
8
,
2
},
{
12
,
4
}
}
};
/*
* not required for Monahans DFC
*/
...
...
@@ -545,6 +543,7 @@ int board_nand_init(struct nand_chip *nand)
nand
->
cmd_ctrl
=
dfc_hwcontrol
;
/* nand->dev_ready = dfc_device_ready; */
nand
->
ecc
.
mode
=
NAND_ECC_SOFT
;
nand
->
ecc
.
layout
=
&
delta_oob
;
nand
->
options
=
NAND_BUSWIDTH_16
;
nand
->
waitfunc
=
dfc_wait
;
nand
->
read_byte
=
dfc_read_byte
;
...
...
@@ -553,7 +552,6 @@ int board_nand_init(struct nand_chip *nand)
nand
->
write_buf
=
dfc_write_buf
;
nand
->
cmdfunc
=
dfc_cmdfunc
;
/* nand->autooob = &delta_oob; */
nand
->
badblock_pattern
=
&
delta_bbt_descr
;
return
0
;
}
...
...
cpu/arm926ejs/davinci/nand.c
浏览文件 @
508eb85d
...
...
@@ -88,6 +88,9 @@ static void nand_davinci_select_chip(struct mtd_info *mtd, int chip)
}
#ifdef CFG_NAND_HW_ECC
#ifdef CFG_DAVINCI_BROKEN_ECC
/* Linux-compatible ECC uses MTD defaults. */
/* These layouts are not compatible with Linux or RBL/UBL. */
#ifdef CFG_NAND_LARGEPAGE
static
struct
nand_ecclayout
davinci_nand_ecclayout
=
{
.
eccbytes
=
12
,
...
...
@@ -112,6 +115,7 @@ static struct nand_ecclayout davinci_nand_ecclayout = {
#else
#error "Either CFG_NAND_LARGEPAGE or CFG_NAND_SMALLPAGE must be defined!"
#endif
#endif
/* CFG_DAVINCI_BROKEN_ECC */
static
void
nand_davinci_enable_hwecc
(
struct
mtd_info
*
mtd
,
int
mode
)
{
...
...
@@ -150,6 +154,15 @@ 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
)
{
u_int32_t
tmp
;
#ifdef CFG_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
;
...
...
@@ -163,9 +176,26 @@ static int nand_davinci_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u
*
ecc_code
++
=
((
tmp
>>
8
)
&
0x0f
)
|
((
tmp
>>
20
)
&
0xf0
);
region
++
;
}
#else
const
int
region
=
1
;
tmp
=
nand_davinci_readecc
(
mtd
,
region
);
/* Squeeze 4 bytes ECC into 3 bytes by removing RESERVED bits
* and shifting. RESERVED bits are 31 to 28 and 15 to 12. */
tmp
=
(
tmp
&
0x00000fff
)
|
((
tmp
&
0x0fff0000
)
>>
4
);
/* Invert so that erased block ECC is correct */
tmp
=
~
tmp
;
*
ecc_code
++
=
tmp
;
*
ecc_code
++
=
tmp
>>
8
;
*
ecc_code
++
=
tmp
>>
16
;
#endif
/* CFG_DAVINCI_BROKEN_ECC */
return
(
0
);
}
#ifdef CFG_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
);
...
...
@@ -282,13 +312,14 @@ static int nand_davinci_compare_ecc(u_int8_t *ecc_nand, u_int8_t *ecc_calc, u_in
return
(
-
1
);
}
}
#endif
/* CFG_DAVINCI_BROKEN_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
;
struct
nand_chip
*
this
=
mtd
->
priv
;
#ifdef CFG_DAVINCI_BROKEN_ECC
int
block_count
=
0
,
i
,
rc
;
this
=
mtd
->
priv
;
block_count
=
(
this
->
ecc
.
size
/
512
);
for
(
i
=
0
;
i
<
block_count
;
i
++
)
{
if
(
memcmp
(
read_ecc
,
calc_ecc
,
3
)
!=
0
)
{
...
...
@@ -301,9 +332,44 @@ static int nand_davinci_correct_data(struct mtd_info *mtd, u_char *dat, u_char *
calc_ecc
+=
3
;
dat
+=
512
;
}
#else
u_int32_t
ecc_nand
=
read_ecc
[
0
]
|
(
read_ecc
[
1
]
<<
8
)
|
(
read_ecc
[
2
]
<<
16
);
u_int32_t
ecc_calc
=
calc_ecc
[
0
]
|
(
calc_ecc
[
1
]
<<
8
)
|
(
calc_ecc
[
2
]
<<
16
);
u_int32_t
diff
=
ecc_calc
^
ecc_nand
;
if
(
diff
)
{
if
((((
diff
>>
12
)
^
diff
)
&
0xfff
)
==
0xfff
)
{
/* Correctable error */
if
((
diff
>>
(
12
+
3
))
<
this
->
ecc
.
size
)
{
uint8_t
find_bit
=
1
<<
((
diff
>>
12
)
&
7
);
uint32_t
find_byte
=
diff
>>
(
12
+
3
);
dat
[
find_byte
]
^=
find_bit
;
MTDDEBUG
(
MTD_DEBUG_LEVEL0
,
"Correcting single "
"bit ECC error at offset: %d, bit: "
"%d
\n
"
,
find_byte
,
find_bit
);
return
1
;
}
else
{
return
-
1
;
}
}
else
if
(
!
(
diff
&
(
diff
-
1
)))
{
/* Single bit ECC error in the ECC itself,
nothing to fix */
MTDDEBUG
(
MTD_DEBUG_LEVEL0
,
"Single bit ECC error in "
"ECC.
\n
"
);
return
1
;
}
else
{
/* Uncorrectable error */
MTDDEBUG
(
MTD_DEBUG_LEVEL0
,
"ECC UNCORRECTED_ERROR 1
\n
"
);
return
-
1
;
}
}
#endif
/* CFG_DAVINCI_BROKEN_ECC */
return
(
0
);
}
#endif
#endif
/* CFG_NAND_HW_ECC */
static
int
nand_davinci_dev_ready
(
struct
mtd_info
*
mtd
)
{
...
...
@@ -370,6 +436,8 @@ int board_nand_init(struct nand_chip *nand)
#endif
#ifdef CFG_NAND_HW_ECC
nand
->
ecc
.
mode
=
NAND_ECC_HW
;
#ifdef CFG_DAVINCI_BROKEN_ECC
nand
->
ecc
.
layout
=
&
davinci_nand_ecclayout
;
#ifdef CFG_NAND_LARGEPAGE
nand
->
ecc
.
size
=
2048
;
nand
->
ecc
.
bytes
=
12
;
...
...
@@ -379,13 +447,16 @@ int board_nand_init(struct nand_chip *nand)
#else
#error "Either CFG_NAND_LARGEPAGE or CFG_NAND_SMALLPAGE must be defined!"
#endif
nand
->
ecc
.
layout
=
&
davinci_nand_ecclayout
;
#else
nand
->
ecc
.
size
=
512
;
nand
->
ecc
.
bytes
=
3
;
#endif
/* CFG_DAVINCI_BROKEN_ECC */
nand
->
ecc
.
calculate
=
nand_davinci_calculate_ecc
;
nand
->
ecc
.
correct
=
nand_davinci_correct_data
;
nand
->
ecc
.
hwctl
=
nand_davinci_enable_hwecc
;
#else
nand
->
ecc
.
mode
=
NAND_ECC_SOFT
;
#endif
#endif
/* CFG_NAND_HW_ECC */
/* Set address of hardware control function */
nand
->
cmd_ctrl
=
nand_davinci_hwcontrol
;
...
...
doc/README.nand
浏览文件 @
508eb85d
...
...
@@ -174,6 +174,14 @@ More Definitions:
#define NAND_MAX_FLOORS 1
#define NAND_MAX_CHIPS 1
#define CFG_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:
=====
...
...
drivers/mtd/nand/fsl_elbc_nand.c
浏览文件 @
508eb85d
...
...
@@ -95,7 +95,6 @@ static struct nand_ecclayout fsl_elbc_oob_sp_eccm0 = {
.
eccbytes
=
3
,
.
eccpos
=
{
6
,
7
,
8
},
.
oobfree
=
{
{
0
,
5
},
{
9
,
7
}
},
.
oobavail
=
12
,
};
/* Small Page FLASH with FMR[ECCM] = 1 */
...
...
@@ -103,7 +102,6 @@ static struct nand_ecclayout fsl_elbc_oob_sp_eccm1 = {
.
eccbytes
=
3
,
.
eccpos
=
{
8
,
9
,
10
},
.
oobfree
=
{
{
0
,
5
},
{
6
,
2
},
{
11
,
5
}
},
.
oobavail
=
12
,
};
/* Large Page FLASH with FMR[ECCM] = 0 */
...
...
@@ -111,7 +109,6 @@ static struct nand_ecclayout fsl_elbc_oob_lp_eccm0 = {
.
eccbytes
=
12
,
.
eccpos
=
{
6
,
7
,
8
,
22
,
23
,
24
,
38
,
39
,
40
,
54
,
55
,
56
},
.
oobfree
=
{
{
1
,
5
},
{
9
,
13
},
{
25
,
13
},
{
41
,
13
},
{
57
,
7
}
},
.
oobavail
=
48
,
};
/* Large Page FLASH with FMR[ECCM] = 1 */
...
...
@@ -119,7 +116,48 @@ static struct nand_ecclayout fsl_elbc_oob_lp_eccm1 = {
.
eccbytes
=
12
,
.
eccpos
=
{
8
,
9
,
10
,
24
,
25
,
26
,
40
,
41
,
42
,
56
,
57
,
58
},
.
oobfree
=
{
{
1
,
7
},
{
11
,
13
},
{
27
,
13
},
{
43
,
13
},
{
59
,
5
}
},
.
oobavail
=
48
,
};
/*
* fsl_elbc_oob_lp_eccm* specify that LP NAND's OOB free area starts at offset
* 1, so we have to adjust bad block pattern. This pattern should be used for
* x8 chips only. So far hardware does not support x16 chips anyway.
*/
static
u8
scan_ff_pattern
[]
=
{
0xff
,
};
static
struct
nand_bbt_descr
largepage_memorybased
=
{
.
options
=
0
,
.
offs
=
0
,
.
len
=
1
,
.
pattern
=
scan_ff_pattern
,
};
/*
* ELBC may use HW ECC, so that OOB offsets, that NAND core uses for bbt,
* interfere with ECC positions, that's why we implement our own descriptors.
* OOB {11, 5}, works for both SP and LP chips, with ECCM = 1 and ECCM = 0.
*/
static
u8
bbt_pattern
[]
=
{
'B'
,
'b'
,
't'
,
'0'
};
static
u8
mirror_pattern
[]
=
{
'1'
,
't'
,
'b'
,
'B'
};
static
struct
nand_bbt_descr
bbt_main_descr
=
{
.
options
=
NAND_BBT_LASTBLOCK
|
NAND_BBT_CREATE
|
NAND_BBT_WRITE
|
NAND_BBT_2BIT
|
NAND_BBT_VERSION
,
.
offs
=
11
,
.
len
=
4
,
.
veroffs
=
15
,
.
maxblocks
=
4
,
.
pattern
=
bbt_pattern
,
};
static
struct
nand_bbt_descr
bbt_mirror_descr
=
{
.
options
=
NAND_BBT_LASTBLOCK
|
NAND_BBT_CREATE
|
NAND_BBT_WRITE
|
NAND_BBT_2BIT
|
NAND_BBT_VERSION
,
.
offs
=
11
,
.
len
=
4
,
.
veroffs
=
15
,
.
maxblocks
=
4
,
.
pattern
=
mirror_pattern
,
};
/*=================================*/
...
...
@@ -724,7 +762,12 @@ int board_nand_init(struct nand_chip *nand)
nand
->
waitfunc
=
fsl_elbc_wait
;
/* set up nand options */
nand
->
options
=
NAND_NO_READRDY
|
NAND_NO_AUTOINCR
;
nand
->
bbt_td
=
&
bbt_main_descr
;
nand
->
bbt_md
=
&
bbt_mirror_descr
;
/* set up nand options */
nand
->
options
=
NAND_NO_READRDY
|
NAND_NO_AUTOINCR
|
NAND_USE_FLASH_BBT
;
nand
->
controller
=
&
elbc_ctrl
->
controller
;
nand
->
priv
=
priv
;
...
...
@@ -750,9 +793,10 @@ int board_nand_init(struct nand_chip *nand)
priv
->
fmr
=
(
15
<<
FMR_CWTO_SHIFT
)
|
(
2
<<
FMR_AL_SHIFT
);
/*
adjust Option Register and ECC to match Flash page size
*/
/*
Large-page-specific setup
*/
if
(
or
&
OR_FCM_PGS
)
{
priv
->
page_size
=
1
;
nand
->
badblock_pattern
=
&
largepage_memorybased
;
/* adjust ecc setup if needed */
if
((
br
&
BR_DECC
)
==
BR_DECC_CHK_GEN
)
{
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录