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

S3C2440 Linux驱动移植——NAND驱动

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

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

    [LV.1]初来乍到

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

    EDA365欢迎您登录!

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    开发板:TQ2440
    + q% M. o( d" t5 \& x/ U
    6 E; a! D( B/ }, r. `; g内核:Linux 2.6.32
    3 I6 l- {: x. l2 f. [9 {2 [4 W! f: s- M) H0 U; j1 u" D" Y) p
    PC OS:Ubuntu 11.041 n, l. {! [- f2 l
    ' D6 U% t7 d9 _3 Y" U: {* |
    " l3 i2 L& H6 _

    7 ]% k- a, {1 K/ k   本文将对NAND驱动的移植进行简单介绍。其中,将对NAND控制器所需要的参数进行详细说明。$ V( o# y( S- }  k. O

    2 `* i, H1 G. i- A+ ?1.  修改分区表
    4 ?$ V+ a( W7 G: X% n6 H
    ( w6 x7 _$ \) ]0 p" H1 K9 V打开文件arch/ARM/plat-s3c24xx/common-smdk.c,修改mtd_partition结构体数组。
    " W2 K$ [9 ]. h
    8 y1 A! l# N' l6 V+ d, X* H: p% _! }修改后如下:" N3 b8 A/ ~' F) ~/ U' v

    , J, Y9 H- Y" J9 e2 [static struct mtd_partition smdk_default_nand_part[] = {
    7 k: H) X# H% ]% A* D        [0] = {
    * Y0 G6 Z9 {2 g' W8 A                .name        = "Uboot",3 a. T4 c* n' K5 T+ |
                    .size        = 0x00040000,) b+ F' J% h1 h' s, g$ K$ w! c2 ^. B
                    .offset        = 0x00000000,
    ) Q4 l! l  r% f# [$ J' m  M        },
    0 o6 f8 x8 t* |: K" J; J: U* ]3 `        [1] = {3 |' h. r* D$ l8 ~! X
                    .name        = "Kernel",
    ! x; K9 p" g$ `& G                .offset = 0x00200000,# J+ [; l) q- i6 R
                    .size        = 0x00300000,6 |1 E9 r! w2 s: c+ m$ ]
            },% L  t" f3 w$ _% w1 j  w, ]. A* m8 R
            [2] = {6 I! K8 I/ z+ p! S' h
                    .name        = "filesystem",- C) L+ W; G4 ]: a
                    .offset = 0x00500000,
    5 n  U( \, Z: }1 g+ p7 [2 ~/ |                .size        = MTDPART_SIZ_FULL,$ i* v9 H7 \( N" `, [! v
            }& r! K5 s5 n. h6 J8 g
    };
    9 P# V0 I+ I8 M3 k) i
    + l  ], B" S  x! Q) D$ E) ~5 G8 z  q* D5 U- i2 u, ~, D: Y" n5 ?
    TQ2440板上的NAND为256M,请根据你的NAND实际大小分配空间。
    & b5 h0 _3 s" i, N' h. j2 a& F- [# t

    " `" T' ]* @0 n
    $ T% `4 ]- T+ v& b8 g2. 修改NAND控制器参数
    5 A. N1 i3 D- ~8 F. ^) L) x; u/ X/ ]8 `$ L; @0 V; ]' {0 Z
    打开文件arch/arm/plat-s3c24xx/common-smdk.c,修改smdk_nand_info结构体。1 g+ l# p3 Z5 m  g! V
      D; B& y/ O5 D' ]$ D2 Z# Z/ X+ w
    修改后如下:% g3 J* r6 {, ]! ~$ U# R0 G
    + b1 e* k* p( C* G9 L  Z4 ~3 d& S
    static struct s3c2410_platform_nand smdk_nand_info = {
    ( i$ E/ }4 p3 s( @0 b8 ]+ L        .tacls                = 0, //10,//20,6 M$ q" L/ T" Y8 p8 |7 C
            .twrph0                = 21, //25,//60,4 q  A7 @1 [* R
            .twrph1                = 5, //10,//20,
    : [" Y7 e2 ~; h. ~4 ^        .nr_sets        = ARRAY_SIZE(smdk_nand_sets),
    1 V/ D- K; f& E% ?" _' r        .sets                = smdk_nand_sets,
    4 z7 z  G+ c3 q' q" h# z  E};" A" Y" I: E' a7 t2 s" L
    ; B5 `, Z" D+ r: m3 }- g% b/ d8 S
    这里的三个参数tacls,twrph0,和twrph1是如何给出的? 我们来分析下。; C: w' R- n3 D8 S& p$ c
    - N; \! M% T/ h3 D
    先看下这个结构体的定义,位于arch/arm/mach-s3c2410/include/mach/nand.h:
    $ u+ }3 R6 q& v& j9 r" `/ L
    / @4 H$ O* j* R) j: S) cstruct s3c2410_platform_nand {
    2 k2 U1 z0 Z( o9 H        /* timing information for controller, all times in nanoseconds */- t+ i$ A, K9 T- i; S6 `

    * _4 h7 n+ y* Z( H; Q        int        tacls;        /* time for active CLE/ALE to nWE/nOE *// j: g2 `5 E  h7 @8 Z
            int        twrph0;        /* active time for nWE/nOE */
    8 Z, x0 `" p5 }8 w        int        twrph1;        /* time for release CLE/ALE from nWE/nOE inactive */+ h( |: k9 g: w
    * }& B( X1 Q; Q( d
            unsigned int        ignore_unset_ecc:1;
    , f! Z" x/ D3 ^: e+ a; i7 A5 I; w4 X! s- v) K4 W0 `
            int                        nr_sets;
    7 M+ W3 n- X0 P- h0 B3 [        struct s3c2410_nand_set *sets;; s, Z: o2 t, g+ y/ @

    2 }. ^( I! l% _9 P, x        void                        (*select_chip)(struct s3c2410_nand_set *,- H1 _6 O" K+ O8 A# ~$ r) L% S
                                                   int chip);& V& g! \$ R% j% U3 D8 H
    };
    * q' S( P5 C4 k9 _- r- S5 |# `* ^9 ?6 j  a! ~. ]# J
    看到了对这三个参数的说明,这里提到了这三个参数的单位为纳秒,请注意。, _: h# _$ @* S8 v5 U& v2 M
    ; D* @9 T( q8 ]: T  R% ?
    那么这三个参数到底从哪来的呢? 它来自于S3C2440 nand 控制器的NFCONF控制器,如下:
    6 m4 B% z$ W4 m3 F  S' x
    ! h' Q- F! L6 p; S 0 |% U: X! E6 V
    & P- m+ }. h0 h. `6 l7 P

    8 B: j4 ~8 o2 s- e6 E- h4 ]) H" e1 W+ w4 p
    既然找到这三个参数的出处了,那么它们究竟是何含义呢?我们里看下:
    * V. _3 {8 w" ?$ k+ N3 Y2 p1 `" ~8 c1 A# Y: u0 z# s- c# V! x5 e

    * P, ~0 a: \/ l' t$ N9 e% [" U, m
    : _/ |2 D# I5 m/ C7 Y
    # Z% Z8 B' u4 F9 S2 v, E0 X
    这幅时序图同样来自S3C2440的datasheet。
    % H% H8 F. ^5 K5 e5 B; R) J9 W9 Y5 D$ m. Y4 w
    通过这幅图和struct s3c2410_platform_nand中的注释,我们可以对这3个参数做出如下定义。. q  A& l* u/ l6 v

    5 h" I6 Q/ {' n  WTACLS:表示在CLE/ALE拉高后,多少时间以后才允许将nWE拉低。
      n; g* O& x' `9 l$ P& x- C2 p2 h- I' c% k, k& B; G2 Z
    TWRPH0:表示nWE低电平持续的时间。5 }, R5 s" _8 i: m/ B3 E
    ) Y0 P* U. o" V  F) {, q! o- s. @
    TWRPH1:表示nWE变为高电平后,多少时间后允许CLE/ALE拉低。/ e8 R: ?/ w2 u& Z, F% m
    ( a, f3 Y. h$ P) n$ c( f
    知道参数的意义后,我们来看下NAND芯片K9F1208U0C的datasheet来确定这3个参数的值。1 r8 v" s* L! N& X

      z& T7 o$ M7 K8 i
    2 |) l* u* a9 I5 U! F
    6 b6 K0 w1 b$ Q' ?8 }: L+ E( d& s# h5 x$ E7 T
    9 j' C/ o: U8 W( F* ~
    从这个时序图,我们可以直观地看到twp对应着参数twrph0,而tclh对于着参数twrph1。# g% c$ ?: j4 d2 X- X' g, b* Y6 P
    & [9 @2 [. ^6 C) [) \+ q
    但是tacls如何得出呢?从图中并不能直接得出该参数的值,需要转个弯,那就是将tcls减去twp,就可以得到tacls了。
    " M' J* ]( P  k6 U% L! f3 v3 q7 _- |' G
    综上所述,为了得到nand控制器所需的3个参数,我们需要获得该nand芯片的3个时序参数:twp,tcls和tclh。
    * L* o' m/ Q. c6 V" W8 N  A5 C% s2 ]
    通过查找该nand的datasheet,3个时序参数的值如下:7 X) e$ U# n3 D; T7 X- D
    : B1 n. |4 b) ?$ O) `
    twp=21, tcls=21, tclh=5。; ^6 m: b9 g/ T) b) P  v1 x( P

    % P% Z2 h# E- d$ [将这3个时序参数转为我们需要的3个参数,单位为纳秒(ns):; Z# x# a5 B! ^0 v) R+ l  I

    5 S9 _9 W6 v  otacls = tcls-twp = 21 - 21 = 0 ns
    & h* }! y* d8 x5 i+ X9 @$ I$ Z- D  R# \) y. C
    twrph0= twp = 21 ns5 O9 \9 {, B2 {6 M5 X, S  a
    2 I( _. P" v8 b
    twrph1 = tclh = 5 ns3 V: K/ {$ K& {) T

    3 N; N  c3 L& Z至此,就成功计算出三个参数的值了 。
    ) y4 ~- s# e% P& F8 C
      N2 g7 ^+ f  g; M6 {, Y4 ?3. 配置内核
    - ^6 b9 _& r( \+ }0 @( S- |2 ]+ ~. a0 c: T

    5 R# f7 ^6 ^7 U) M# \) _! D! u8 q' E  U7 U# i

    / u; }3 d: E9 n! j( j2 S4 P
    2 \1 f, B; G4 N( W$ J0 @0 ~8 O8 M4. 验证8 P* P8 d/ @) G+ z( I5 O. F
    : M2 a" e& W, X/ U" D& m/ g$ W. M
      在经过上述步骤后,编译内核并将内核少入nand,启动系统。在Linux的启动信息中,会有如下输出:# i2 l/ W* g7 }0 o+ k

    ; G) c& a' D; J3 H, L......! D& u  Z/ s6 j1 H
    / g' T: E7 q2 ~# o7 A7 k
    S3C24XX NAND Driver, (c) 2004 Simtec Electronics/ W/ m3 l: W% z
    s3c24xx-nand s3c2440-nand: Tacls=1, 10ns Twrph0=3 30ns, Twrph1=1 10ns; e+ |" J3 E9 o$ Q! _; a  b  I' z
    s3c24xx-nand s3c2440-nand: NAND hardware ECC3 @. p* r7 w1 ^4 I- V, o
    NAND device: Manufacturer ID: 0xec, Chip ID: 0xda (Samsung NAND 256MiB 3,3V 8-bit)
    . c7 {/ y9 g1 I" l0 CScanning device for bad blocks+ `7 l1 Z  \' F
    Bad eraseblock 781 at 0x0000061a0000" ^5 s. {: R+ Z, q  v
    Bad eraseblock 1113 at 0x000008b20000
    ) j; H/ V; _- H& @$ }. p8 tBad eraseblock 1117 at 0x000008ba0000
    2 K: B9 W4 A5 u& N6 oBad eraseblock 1481 at 0x00000b920000
    3 ^3 l( t. E$ U5 q/ EBad eraseblock 1566 at 0x00000c3c0000
    : Q, e! b$ c# f* D6 N% _Bad eraseblock 1885 at 0x00000eba00000 F; D2 ]  c9 J  T
    Creating 3 MTD partitions on "NAND 256MiB 3,3V 8-bit":! s: R7 E1 g1 b! I, m! n
    0x000000000000-0x000000040000 : "Uboot"0 _1 h( a" Q7 a$ \$ }) M
    0x000000200000-0x000000500000 : "Kernel"6 y' [/ S$ Y9 y1 t7 M
    0x000000500000-0x000010000000 : "filesystem"
    & E3 h  _, |* L2 _
    7 I$ v; o% j) M0 [/ [  E......
    * K3 i* }! `+ L0 N" F+ A6 N& ]2 d5 P8 I# q* \# `  S% S; U
    上述信息表明以成功访问了NAND FLASH。4 B! F  `6 q) ]5 p) X; C3 j
    " B% R0 ?+ M3 N
    这里,对第二行的输出进行个说明。
    ( Q7 ~0 V( Q" F
    ' I% g1 q  G3 z# m8 e+ @5 t, PUBOOT启动将S3C2440的工作频率 FCLK:HCLK: PCLK = 8:4 :1,
    5 t; e* c9 W! F) x% e) G
    ) a$ W8 ~4 x0 x8 L6 L+ I而FCLK为400Mhz,那么HCLK为100Mhz,根据NFCONF寄存器的说明,寄存器中的这3个参数都跟HCLK有关,必须为1/HCLK的倍数,6 C) z+ x, E9 K: m! q8 l2 J# v; X

    ; Z8 h* L6 w9 V% k  e! {) I也就是1/100MHz=10ns的倍数。) O+ O" w; M; v; t
    . F- \8 u9 ?1 O8 r
    通过上面第二行的输出信息,Twrph0为 30ns而Twrph1为10ns,这是显而意见的。+ d+ \0 }# X5 E. v
    + D; ?% W& O1 J+ ]
    由于参数必须为10ns的倍数,而且必须大于datasheet给出的值,因此向上取到10的倍数,也即5ns取到10ns,21ns取到30ns。
    . ]$ c% ?+ a$ P2 K0 D
    5 ?* X/ }- G- o$ a) K9 a& h那么为什么Tacls是10ns呢?明明给出的是0ns,是不是驱动不允许参数为0ns?
    $ b% ]8 J  J! I4 B* I9 `3 ~8 Q! P5 n2 A- c0 U
    在S3C2440的nand驱动中,参数的值是通过如下函数确定的:
      ^& ?* j! n) n9 _% h
    0 y$ \: i0 R+ L2 Tstatic int s3c_nand_calc_rate(int wanted, unsigned long clk, int max)6 V& u5 d$ w/ d/ m# M# x, T
    {4 }" ?( E) y9 T( {) @6 ]) W* W
            int result;
    / Q) G; d2 K! `- ]+ \0 T  W
    6 w2 P! G' f; ]/ o        result = DIV_ROUND_UP((wanted * clk), NS_IN_KHZ);1 o, B! V+ `5 b+ d% o. g
    7 m; U! z/ h3 @( {
            pr_debug("result %d from %ld, %d\n", result, clk, wanted);
    ' \5 w" [! h+ [. H3 {; n* \5 V) N" {% P4 R* l) }
            if (result > max) {' ]" Z4 R6 V1 H1 I+ n' v# X& D: I$ I+ V
                    printk("%d ns is too big for current clock rate %ld\n", wanted, clk);
    9 O; T( w! _' ^                return -1;3 Y9 U# I2 e3 l7 z& p
            }% r2 V6 d. ?9 `9 j6 ?+ k  S
    - {1 U4 O/ A) S0 {- h) A
            if (result < 1)
    7 M& R7 [6 `$ @6 i& ~                result = 1;
    2 f- @7 h+ `8 m6 S9 J' w7 g8 U  z2 R3 t) ^- R/ P4 P' I+ a
            return result;
    : j  J8 N0 s, [: f& l0 I% E2 e}; @3 j8 l& l2 x" ]; x5 C

    1 Y! n; Y5 G3 y2 h5 ^/ b参数wanted就是0(ns),而clk即为HCLK/1000。
    1 O2 q" ~; r: Q7 ~$ u7 P  s( A) ?+ P+ q! w
    DIV_ROUND_UP宏将返回0,但是if对result进行了限制,也就是不允许小于0,因此将参数值设置为1,并返回给调用函数。9 d1 H2 m7 i$ n$ E! N
    1 U" {0 L* L2 p( M9 U0 f5 A! O6 P
    # F. s5 w0 _' h9 R" U0 `1 R

    9 d& d% H& K1 P( \9 g& }/ O
    % A% G) K0 s7 ^* z8 m  N& F. j9 y7 l& z

    2 g# L1 }% c, f) K/ P# l1 F7 N+ A6 \' _- H

    6 l  K0 l/ C2 _/ t5 y! u: z6 `' _% \$ t; m6 l
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-7-3 05:20 , Processed in 0.078125 second(s), 26 queries , Gzip On.

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

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

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