一、移植前的修改
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 2 3 #include 4 #include 5 #include 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%02xn", 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_readyn"); 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)n", 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%02xn", 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 implementedn"); 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.05commonboard_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;