找回密码
 注册
关于网站域名变更的通知
查看: 240|回复: 1
打印 上一主题 下一主题

S3C2440 Linux驱动移植——NAND驱动

[复制链接]
  • TA的每日心情

    2019-11-20 15:22
  • 签到天数: 2 天

    [LV.1]初来乍到

    跳转到指定楼层
    1#
    发表于 2020-6-3 11:01 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

    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
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-11-25 21:36 , Processed in 0.156250 second(s), 27 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表