zoukankan      html  css  js  c++  java
  • -boot移植(十一)---代码修改---支持nandflash

    一、移植前的修改

    1.1 include/configs/jz2440修改

      原来的定义:

      

      可以看出,要先定义CONFIG_CMD_NAND才能使能NANDFlash。

      这个在我们文件中的82行有定义,所以不需要定义了。

      

      将里面的S3C2410全部改为S3C2440:

      

    1.2 drivers/mtd/nand/修改

      拷贝s3c2410_nand.c 成  s3c2440_nand.c

      

      在此目录的makefile中添加 s3c2440_nand.c

      

      修改s3c2440_nand.c 文件,从board_nand_init 逐行检测修改,代码如下:

      1 #include <common.h>
      2 
      3 #include <nand.h>
      4 #include <asm/arch/s3c24x0_cpu.h>
      5 #include <asm/io.h>
      6 
      7 /* NFCONF 寄存器定义 */
      8 #define S3C2440_NFCONF_EN          (1<<15)
      9 #define S3C2440_NFCONF_512BYTE     (1<<14)
     10 #define S3C2440_NFCONF_4STEP       (1<<13)
     11 #define S3C2440_NFCONF_INITECC     (1<<12)
     12 #define S3C2440_NFCONF_nFCE        (1<<1)
     13 #define S3C2440_NFCONF_TACLS(x)    ((x)<<12)
     14 #define S3C2440_NFCONF_TWRPH0(x)   ((x)<<8)
     15 #define S3C2440_NFCONF_TWRPH1(x)   ((x)<<4)
     16 
     17 /* NFCONF 寄存器定义 */
     18 #define S3C2440_NFCONT_LOCKTIGHT                  (1<<13)
     19 #define S3C2440_NFCONT_SOFTLOCK                  (1<<12)
     20 #define S3C2440_NFCONT_ENLLLEGALINT              (1<<10)
     21 #define S3C2440_NFCONT_ENRnBINT                 (1<<9)
     22 #define S3C2440_NFCONT_Rn                         (1<<8)
     23 #define S3C2440_NFCONT_SPAREECCLOCK             (1<<6)
     24 #define S3C2440_NFCONT_MAINECCLOCK                 (1<<5)
     25 #define S3C2440_NFCONT_ECC                      (1<<4)
     26 #define S3C2440_NFCONT_nCE                      (1<<1)
     27 #define S3C2440_NFCONT_MODE                      (1<<0)
     28 
     29 
     30 
     31 
     32 #define S3C2440_ADDR_NALE 4
     33 #define S3C2440_ADDR_NCLE 8
     34 
     35 #ifdef CONFIG_NAND_SPL
     36 
     37 /* in the early stage of NAND flash booting, printf() is not available */
     38 #define printf(fmt, args...)
     39 
     40 static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
     41 {
     42     int i;
     43     struct nand_chip *this = mtd->priv;
     44 
     45     for (i = 0; i < len; i++)
     46         buf[i] = readb(this->IO_ADDR_R);
     47 }
     48 #endif
     49 
     50 /* ctrl:表示做什么,选中芯片/取消片选,是发命令还是发地址
     51  * cmd :命令值或地址值
     52  */
     53 static void s3c24x0_hwcontrol(struct mtd_info *mtd, int cmd, unsigned int ctrl)
     54 {
     55     struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
     56 
     57     debug("hwcontrol(): 0x%02x 0x%02x
    ", cmd, ctrl);
     58 
     59     if (ctrl & NAND_CLE) {
     60         /* 发命令 */
     61         writeb(cmd, &nand->nfcmd);
     62     }
     63     else if (ctrl & NAND_ALE) {
     64         /* 发地址 */
     65         writeb(cmd, &nand->nfaddr);
     66     }
     67 
     68 }
     69 
     70 /**
     71  * nand_select_chip - [DEFAULT] control CE line
     72  * @mtd: MTD device structure
     73  * @chipnr: chipnumber to select, -1 for deselect
     74  *
     75  * Default select function for 1 chip devices.
     76  */
     77 void s3c2440_nand_select(struct mtd_info *mtd, int chipnr)
     78 {
     79     struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
     80 
     81     switch (chipnr) {
     82     case -1: /* 取消选中 */
     83         nand->nfcont |= S3C2440_NFCONT_nCE;
     84         break;
     85     case 0: /* 选中 */
     86         nand->nfcont &= ~S3C2440_NFCONT_nCE;
     87         break;
     88 
     89     default:
     90         BUG();
     91     }
     92 }
     93 
     94 static int s3c24x0_dev_ready(struct mtd_info *mtd)
     95 {
     96     struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
     97     debug("dev_ready
    ");
     98     return readl(&nand->nfstat) & 0x01;
     99 }
    100 
    101 #ifdef CONFIG_S3C2440_NAND_HWECC
    102 void s3c24x0_nand_enable_hwecc(struct mtd_info *mtd, int mode)
    103 {
    104     struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
    105     debug("s3c24x0_nand_enable_hwecc(%p, %d)
    ", mtd, mode);
    106     writel(readl(&nand->nfconf) | S3C2440_NFCONF_INITECC, &nand->nfconf);
    107 }
    108 
    109 static int s3c24x0_nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
    110                       u_char *ecc_code)
    111 {
    112     struct s3c24x0_nand *nand = s3c24x0_get_base_nand();
    113     ecc_code[0] = readb(&nand->nfecc);
    114     ecc_code[1] = readb(&nand->nfecc + 1);
    115     ecc_code[2] = readb(&nand->nfecc + 2);
    116     debug("s3c24x0_nand_calculate_hwecc(%p,): 0x%02x 0x%02x 0x%02x
    ",
    117           mtd , ecc_code[0], ecc_code[1], ecc_code[2]);
    118 
    119     return 0;
    120 }
    121 
    122 static int s3c24x0_nand_correct_data(struct mtd_info *mtd, u_char *dat,
    123                      u_char *read_ecc, u_char *calc_ecc)
    124 {
    125     if (read_ecc[0] == calc_ecc[0] &&
    126         read_ecc[1] == calc_ecc[1] &&
    127         read_ecc[2] == calc_ecc[2])
    128         return 0;
    129 
    130     printf("s3c24x0_nand_correct_data: not implemented
    ");
    131     return -1;
    132 }
    133 #endif
    134 
    135 int board_nand_init(struct nand_chip *nand)
    136 {
    137     u_int32_t cfg = 0;
    138     u_int8_t tacls, twrph0, twrph1;
    139     struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
    140     struct s3c24x0_nand *nand_reg = s3c24x0_get_base_nand();
    141 
    142     writel(readl(&clk_power->clkcon) | (1 << 4), &clk_power->clkcon);
    143 
    144     /* 时序设置 */
    145     tacls = 4;
    146     twrph0 = 8;
    147     twrph1 = 8;
    148     
    149     /* 初始化时序 */
    150     cfg |= S3C2440_NFCONF_TACLS(tacls - 1);
    151     cfg |= S3C2440_NFCONF_TWRPH0(twrph0 - 1);
    152     cfg |= S3C2440_NFCONF_TWRPH1(twrph1 - 1);
    153     writel(cfg, &nand_reg->nfconf);
    154 
    155     /* 使能NANDFLASH控制器,初始化ECC,禁止片选 */
    156     writel(S3C2440_NFCONT_MODE | S3C2440_NFCONT_nCE | S3C2440_NFCONT_ECC, &nand_reg->nfcont);
    157     
    158     /* initialize nand_chip data structure */
    159     nand->IO_ADDR_R = (void *)&nand_reg->nfdata;
    160     nand->IO_ADDR_W = (void *)&nand_reg->nfdata;
    161 
    162     nand->select_chip = s3c2440_nand_select;
    163 
    164     /* hwcontrol always must be implemented */
    165     nand->cmd_ctrl = s3c24x0_hwcontrol;
    166 
    167     nand->dev_ready = s3c24x0_dev_ready;
    168 
    169 #ifdef CONFIG_S3C2410_NAND_HWECC
    170     nand->ecc.hwctl = s3c24x0_nand_enable_hwecc;
    171     nand->ecc.calculate = s3c24x0_nand_calculate_ecc;
    172     nand->ecc.correct = s3c24x0_nand_correct_data;
    173     nand->ecc.mode = NAND_ECC_HW;
    174     nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
    175     nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
    176     nand->ecc.strength = 1;
    177 #else
    178     nand->ecc.mode = NAND_ECC_SOFT;
    179 #endif
    180 
    181 #ifdef CONFIG_S3C2440_NAND_BBT
    182     nand->bbt_options |= NAND_BBT_USE_FLASH;
    183 #endif
    184 
    185     return 0;
    186 }

      修改过程如下:

     1 u-boot-2016.05commonoard_r:board_init_r函数中的初始化序列init_sequence_r中的:
     2 initr_nand
     3     nand_init
     4         nand_init_chip
     5             board_nand_init
     6                 设置nand_chip结构体, 提供底层的操作函数
     7             nand_scan
     8                 nand_scan_ident
     9                     nand_set_defaults
    10                         chip->select_chip = nand_select_chip;
    11                         chip->cmdfunc = nand_command;
    12                         chip->read_byte = busw ? nand_read_byte16 : nand_read_byte;
    13 
    14                     nand_get_flash_type
    15                         chip->select_chip
    16                         chip->cmdfunc(mtd, NAND_CMD_RESET, -1, -1);
    17                                 nand_command()  // 即可以用来发命令,也可以用来发列地址(页内地址)、行地址(哪一页)
    18                                     chip->cmd_ctrl
    19                                             s3c24x0_hwcontrol
    20 
    21                         chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
    22                         *maf_id = chip->read_byte(mtd);
    23                         *dev_id = chip->read_byte(mtd);

       编译运行 结果如下:

      

       测试:

      执行写,在写之前注意一定要先擦除nandflash:

      SDRAM 0x31e00000 地址的 0xff 字节数据写到 NAND FLASH 0 地址

      

      执行读:NAND FLASH 0 地址读 0xff 字节数据到 SDRAM 0x31f00000 地址

      

      比较:

      

      

     

       

  • 相关阅读:
    jquery如何获取url中问号后面的数值
    CSS3 @font-face
    如何在代码中应用设计模式
    面试中可能被问到的常用排序算法
    《深入java虚拟机》读书笔记之垃圾收集器与内存分配策略
    《深入java虚拟机》读书笔记之Java内存区域
    Spring系列之手写一个SpringMVC
    Java多线程之Executor框架和手写简易的线程池
    Spring系列之手写注解与配置文件的解析
    Spring系列之AOP的原理及手动实现
  • 原文地址:https://www.cnblogs.com/kele-dad/p/7050780.html
Copyright © 2011-2022 走看看