TA的每日心情 | 怒 2019-11-20 15:22 |
|---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
开发板:TQ2440
4 F6 g2 L* a' M0 h9 N2 z% D% G1 u! ~* z2 v% P' e0 k
内核:Linux 2.6.32+ w! H" X! I7 k
3 m& h1 T+ Y% s7 N" J: g+ p# I1 jPC OS:Ubuntu 11.04
/ X1 U) U* L P+ D" D9 ?. u! w% }/ n& K G! p* ]2 ~
G7 u4 y0 [ v0 ]' |/ R0 g( D2 \- ~. ?
本文将对NAND驱动的移植进行简单介绍。其中,将对NAND控制器所需要的参数进行详细说明。
- G8 t" Y4 E) @& N* } M9 A5 o
. g( s5 \0 N" \1. 修改分区表2 F; @; J, J8 J: [ p5 _
( \2 L/ v5 u$ G8 d& x( ?& O
打开文件arch/ARM/plat-s3c24xx/common-smdk.c,修改mtd_partition结构体数组。
/ l# f! o& d! d( r) Y0 }
4 X3 y% |* v+ i" w+ w: X修改后如下:+ R8 w: K7 u7 ]
) Z$ j( `: [1 o& v0 Bstatic struct mtd_partition smdk_default_nand_part[] = {$ a# ?9 [- D% N* `
[0] = {9 T0 `0 l6 Z8 [( W1 m
.name = "Uboot",, E: i1 i) g& H$ y1 y% x4 H& g
.size = 0x00040000,
, H4 K9 b6 a v6 {/ }3 s .offset = 0x00000000,8 a h; J: b5 H! g/ `& V2 S! P
},; }% L7 r2 Q" C1 @0 K
[1] = {& |+ X5 l8 I- `' u( V' n, X. {
.name = "Kernel"," K8 `0 K4 f8 A, V" Y$ b
.offset = 0x00200000,- l$ r+ Z/ z$ q7 H% @* W
.size = 0x00300000,' O1 D0 ^1 K4 Q4 d. F! Q0 ^
},
6 b6 ?0 }; w* v0 H [2] = {
5 x) d% H( l, N3 W# @ .name = "filesystem",8 Y* K$ W7 e* R2 x9 w5 O
.offset = 0x00500000,+ b( b' p7 w1 ^, R- m
.size = MTDPART_SIZ_FULL,- {4 o7 a& `" K0 z
}# Z# H0 t4 J- ?# H5 e8 _
};8 S6 R k7 d; A" X9 {1 S' m
. v E: Z ]7 x5 t4 O% i A1 L
3 }% I h% y. r6 pTQ2440板上的NAND为256M,请根据你的NAND实际大小分配空间。4 _2 j. } a5 d) X
; Q+ g3 ]' Q: x# D: e; `9 W7 a
9 i: S' ?+ {+ P
3 Q$ \ g5 l% A5 j: K0 A2. 修改NAND控制器参数
' W! z2 q! `" m' M% p7 ~- O c% U: }8 i! g) h& Z
打开文件arch/arm/plat-s3c24xx/common-smdk.c,修改smdk_nand_info结构体。
8 |8 L) n1 f5 u5 q0 H% w
# ^1 m/ I: z9 F* \修改后如下:
% U& }7 K$ h/ H6 c! Y3 v1 p& A3 {2 i# y/ e
static struct s3c2410_platform_nand smdk_nand_info = {
9 ^ c5 ^( `3 O6 X8 d0 c4 A+ K7 Y .tacls = 0, //10,//20,
7 e6 r/ Q, j G' X5 A .twrph0 = 21, //25,//60,% y4 ^; A8 h) s7 y" W2 d9 L
.twrph1 = 5, //10,//20,( d4 z2 b8 |2 p. ]
.nr_sets = ARRAY_SIZE(smdk_nand_sets),9 K# ]" O8 s8 M7 B- I
.sets = smdk_nand_sets,
* u( T) S$ v P. O4 R* j% f4 V};2 y$ d! y. X6 b6 m1 t) c6 x
0 I- o+ @$ q2 H$ [: j R0 Y
这里的三个参数tacls,twrph0,和twrph1是如何给出的? 我们来分析下。
7 H. r" K7 D( G
- P1 o: C" \- ~; i9 ?- E6 R& i8 ?" u先看下这个结构体的定义,位于arch/arm/mach-s3c2410/include/mach/nand.h:, T/ Y0 |6 x- x X
8 b, E" f$ u, C. `. z3 Q/ Z! d2 W/ Xstruct s3c2410_platform_nand {
# b# B: f2 ^3 D- i7 R /* timing information for controller, all times in nanoseconds */
6 e; _# O1 _6 @: E5 I. O. A7 r5 X9 x( ]+ }! c% v+ D/ |7 g
int tacls; /* time for active CLE/ALE to nWE/nOE */
# \5 g4 N1 ?- i1 Y4 d int twrph0; /* active time for nWE/nOE */2 k5 [7 \6 V; f5 N
int twrph1; /* time for release CLE/ALE from nWE/nOE inactive */
" j; \! ?3 V0 I. {$ R0 [
! Q4 }+ k H* W3 i% J unsigned int ignore_unset_ecc:1;6 j+ a$ ?7 g& k$ O+ P
4 n: u! P4 R$ Z( r3 s2 W
int nr_sets;
- o, V% Q6 V4 m5 n) u5 l struct s3c2410_nand_set *sets;
9 C8 v* m: U% ~) j+ T/ @3 g# ^9 }) |* a. z, R
void (*select_chip)(struct s3c2410_nand_set *,) _: P2 R( e0 a, Z
int chip);: W# V+ e# P# L! O
};
9 V- p% \/ {' Z6 R
6 J; f+ ~, }" ?0 i' A. K看到了对这三个参数的说明,这里提到了这三个参数的单位为纳秒,请注意。
) z9 ]% ]# W! @- Z% @! H# c8 `* ?# n, o' N1 y3 A
那么这三个参数到底从哪来的呢? 它来自于S3C2440 nand 控制器的NFCONF控制器,如下:
3 |( L" L" ^/ s. W0 a3 X6 g0 N$ V3 {1 V; }+ b9 Y8 q
& g) z" _! u! l- V. P$ A* y2 u
- `8 i$ s0 \: K- s6 Z
' r5 J+ N0 L* A) W: W- E
! i6 h5 {* T% B/ [ 既然找到这三个参数的出处了,那么它们究竟是何含义呢?我们里看下:
; u/ o8 K! n/ `4 e* G7 _; |
- u/ ]' Z: q1 n$ }+ m
7 A! u; b }% w$ W4 J4 o) X) C! v P6 B c
7 @" b6 T' ^4 @
+ q% w" ?3 W! N* q这幅时序图同样来自S3C2440的datasheet。
3 n3 d. n& j6 \% ^- i) T6 x4 G0 ], z# k. t4 H
通过这幅图和struct s3c2410_platform_nand中的注释,我们可以对这3个参数做出如下定义。- R; x, g; o$ J+ n
0 X' ^* y# e2 J% N ]TACLS:表示在CLE/ALE拉高后,多少时间以后才允许将nWE拉低。& C u9 _% n h @" Z. f* S( n! x
: j2 |* {0 u6 ]+ \
TWRPH0:表示nWE低电平持续的时间。# ?# U, o4 p3 H" n( ^3 E
7 Y& e% [( z% f$ d
TWRPH1:表示nWE变为高电平后,多少时间后允许CLE/ALE拉低。
2 L4 W) W# W& r: I& E- R" }
& R0 V/ t" d( c9 n( o知道参数的意义后,我们来看下NAND芯片K9F1208U0C的datasheet来确定这3个参数的值。
5 G; F9 q7 ^2 Q* l
* n |9 X2 M$ i9 ]% ]$ V* u
, {9 v* c. K P+ W: ]
, r* [( ~- }6 K& V, L
+ a* y" M* Z) p1 D) U5 F1 K5 A3 P
, Q/ p8 C5 w- b( |# ~4 ~从这个时序图,我们可以直观地看到twp对应着参数twrph0,而tclh对于着参数twrph1。
# @" ^; Q" D5 _( }5 n$ f+ \' C2 Y
; M+ H$ s2 N' l8 r但是tacls如何得出呢?从图中并不能直接得出该参数的值,需要转个弯,那就是将tcls减去twp,就可以得到tacls了。( {3 d) I9 h/ h k
8 ]" h* [7 t+ t2 T综上所述,为了得到nand控制器所需的3个参数,我们需要获得该nand芯片的3个时序参数:twp,tcls和tclh。
; i8 r. W" x4 R: T6 n6 B" w/ o
1 W' M V; P( k通过查找该nand的datasheet,3个时序参数的值如下:
& M1 q: R/ D+ G5 l4 m
x1 Y& d- L3 Itwp=21, tcls=21, tclh=5。
: a* @* |7 u/ x. I! h/ A5 a$ V$ w, |5 M7 j& x: ]
将这3个时序参数转为我们需要的3个参数,单位为纳秒(ns):
$ T0 d4 s* L- d$ q8 X! n- M8 A9 i" |. D" D5 O0 ~3 p
tacls = tcls-twp = 21 - 21 = 0 ns; D- g2 K4 p7 y
& Q5 J4 \3 y6 Q9 C3 i/ Q( ztwrph0= twp = 21 ns! H( N9 X v/ D9 i5 J
4 c0 J( J' K# Btwrph1 = tclh = 5 ns: f7 t6 n$ ^" b0 S# W) ^* Z. C: _
: H1 G( @, ^1 Y I: P# v! [
至此,就成功计算出三个参数的值了 。
, h" m2 g0 c* q& `6 H8 \! N9 D
5 T, F' P5 t5 w- y# U9 `4 s c3. 配置内核
' `! W4 g/ W/ I+ J/ p/ K2 `! F4 z
; ~+ S" T( ~) E5 s- L7 P# u2 t4 w" Y' ]3 o
+ J) D) S1 X3 T W( A% @ P/ j
6 F) R3 Z J' U, O- t
4. 验证
' k+ z) e+ v" n2 h0 G& x3 L' n
! G% {: Z# F( x6 Y/ k9 ~7 T+ d 在经过上述步骤后,编译内核并将内核少入nand,启动系统。在Linux的启动信息中,会有如下输出:
2 U, s; U: p; F/ X* S5 J& |' Q/ L: [1 x) B% j/ M
......3 V4 d" ^9 c3 U( a' }8 C& S
+ y. S. l* v( h/ V. y7 [; c
S3C24XX NAND Driver, (c) 2004 Simtec Electronics
4 X- e& h4 W9 m2 `7 K; gs3c24xx-nand s3c2440-nand: Tacls=1, 10ns Twrph0=3 30ns, Twrph1=1 10ns
% o9 ]4 Q7 T; ^, k" r: V4 j9 hs3c24xx-nand s3c2440-nand: NAND hardware ECC" C) O. b. D, G5 E4 @8 S4 _5 A" F
NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)- z2 B. W& n3 Y/ v, h
Scanning device for bad blocks6 s$ h" \: F7 s2 [, }
Bad eraseblock 781 at 0x0000061a00005 a% C2 r4 {( E7 s5 d- ?) W
Bad eraseblock 1113 at 0x000008b20000
) o* Y% v( {3 `# f( T/ MBad eraseblock 1117 at 0x000008ba0000
, r7 B5 r0 F; o8 M& JBad eraseblock 1481 at 0x00000b9200000 J7 j* y' l3 @, d! ~9 e) Q
Bad eraseblock 1566 at 0x00000c3c00008 y; Q( Q" S" W: z* t3 I
Bad eraseblock 1885 at 0x00000eba0000& r. ~. t2 @' K& ?% g
Creating 3 MTD partitions on "NAND 256MiB 3,3V 8-bit":+ Z5 U" E) ]: r% u$ _& `
0x000000000000-0x000000040000 : "Uboot"
$ V. Q8 n1 E$ A, o' X! ~7 j s0x000000200000-0x000000500000 : "Kernel"
* D n! d7 `0 D0x000000500000-0x000010000000 : "filesystem"
% }" t# B, Y! w+ X% p, k( [2 F5 J7 i) N( n3 S5 J6 d
......- ~5 z1 Z1 ^( W, k4 e! a; R) C
( a; W3 V" H. t! z6 h' ?1 p上述信息表明以成功访问了NAND FLASH。
6 \- j9 H# D' G! |- {! D; \" X# _: y- D0 {" E! }6 i* U
这里,对第二行的输出进行个说明。% {( q; Z2 Y& @2 G0 L
* {7 P0 v0 b& V5 u2 v" A) t9 c1 d: c
UBOOT启动将S3C2440的工作频率 FCLK:HCLK: PCLK = 8:4 :1,6 a, o: i. D" P u7 z! t* C+ b
, |+ a% c" {* `' D$ i4 [2 L
而FCLK为400Mhz,那么HCLK为100Mhz,根据NFCONF寄存器的说明,寄存器中的这3个参数都跟HCLK有关,必须为1/HCLK的倍数,; k* Z: ^# O) g$ S& b# L% h
6 y) }8 t3 h3 `5 d0 R$ P) \' d也就是1/100MHz=10ns的倍数。
& I* q5 O; x0 ?
& l9 z9 h, o9 L9 @, p通过上面第二行的输出信息,Twrph0为 30ns而Twrph1为10ns,这是显而意见的。
$ e+ y; V1 J N& q' ?$ B7 b* _! [, n' ] d3 v/ L
由于参数必须为10ns的倍数,而且必须大于datasheet给出的值,因此向上取到10的倍数,也即5ns取到10ns,21ns取到30ns。
! E" P S x- M* @/ [* u0 z' R" s! q% r, q K# [1 j
那么为什么Tacls是10ns呢?明明给出的是0ns,是不是驱动不允许参数为0ns?
: B+ @: ~' s1 _6 }0 j. s2 Z# i f1 V3 x* Q" d- L
在S3C2440的nand驱动中,参数的值是通过如下函数确定的:
1 A8 b; Q1 R% ^/ V* S! c& R, V9 N% m2 Z; L
static int s3c_nand_calc_rate(int wanted, unsigned long clk, int max)
' n5 g: _5 R3 z{$ O4 B: H: [+ H& J/ i& N
int result;
6 y, x9 ~9 r; P m7 I
# T* K! ^# p8 r% U- h6 L result = DIV_ROUND_UP((wanted * clk), NS_IN_KHZ);
7 Q4 i2 r( y; l& L$ u# a+ v% n1 H
9 L1 f% P% j j" C3 ` pr_debug("result %d from %ld, %d\n", result, clk, wanted);
* u( B5 U, n$ H* x T/ j0 y, m
3 S; a4 x$ a" e( i! u% e- q" a if (result > max) {+ y5 m/ @ {, Y3 V- B+ j
printk("%d ns is too big for current clock rate %ld\n", wanted, clk);
% j1 H# H; e7 p# U% | return -1;. F3 v$ t* h7 t( s
}. i+ C; ]6 @+ p2 ], e
1 w! Z& P g* H# O6 M
if (result < 1)) @& P# Y2 R6 t8 M1 H
result = 1;- T) q; s2 d" r& j1 L2 \1 T! P4 r8 Y0 d
/ H3 I! Z+ W% Z+ H. X3 ^
return result;
2 Q* g3 p$ i: E. s}+ p) p9 c1 I. y `6 Q* m' j
- O' G' n% l7 D. N$ L参数wanted就是0(ns),而clk即为HCLK/1000。
2 {: M- F6 s) x8 n7 x9 u& J3 Y8 S- G" R7 ^. y
DIV_ROUND_UP宏将返回0,但是if对result进行了限制,也就是不允许小于0,因此将参数值设置为1,并返回给调用函数。
0 W! {9 x4 a9 n) U8 ^' h- a
$ h2 ]: @. I5 M* L
/ e2 R/ Y0 e% x! U; D8 f7 X
& ?) e8 R& Z* u8 h
& j, X: c. B: V/ \: i- ~6 T1 p0 T3 b: l8 J5 o
/ s6 ?% {# W* a$ R ~1 n
& X8 g3 ]. S: E. s2 s
- q5 J2 b4 T% A3 a0 x; v
" k" Z3 j. Z$ `9 w$ ~+ G. Z |
|