1 /* 2 * Copyright (c) 2018 Fuzhou Rockchip Electronics Co., Ltd 3 * 4 * SPDX-License-Identifier: GPL-2.0 5 */ 6 7 #include <common.h> 8 #include <linux/bug.h> 9 #include <linux/delay.h> 10 11 #include "flash_com.h" 12 #include "rkflash_debug.h" 13 #include "rk_sftl.h" 14 #include "sfc.h" 15 #include "sfc_nand.h" 16 17 static u32 sfc_nand_get_ecc_status0(void); 18 static u32 sfc_nand_get_ecc_status1(void); 19 static u32 sfc_nand_get_ecc_status2(void); 20 static u32 sfc_nand_get_ecc_status3(void); 21 static u32 sfc_nand_get_ecc_status4(void); 22 static u32 sfc_nand_get_ecc_status5(void); 23 static u32 sfc_nand_get_ecc_status6(void); 24 static u32 sfc_nand_get_ecc_status7(void); 25 static u32 sfc_nand_get_ecc_status8(void); 26 27 static struct nand_info spi_nand_tbl[] = { 28 /* TC58CVG0S0HxAIx */ 29 { 0x98, 0xC2, 0x00, 4, 0x40, 1, 1024, 0x00, 18, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 30 /* TC58CVG1S0HxAIx */ 31 { 0x98, 0xCB, 0x00, 4, 0x40, 2, 1024, 0x00, 19, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 32 /* TC58CVG2S0HRAIJ */ 33 { 0x98, 0xED, 0x00, 8, 0x40, 1, 2048, 0x0C, 20, 0x8, 0, { 0x04, 0x0C, 0x08, 0x10 }, &sfc_nand_get_ecc_status0 }, 34 /* TC58CVG1S3HRAIJ */ 35 { 0x98, 0xEB, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 36 /* TC58CVG0S3HRAIJ */ 37 { 0x98, 0xE2, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 38 39 /* MX35LF1GE4AB */ 40 { 0xC2, 0x12, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 41 /* MX35LF2GE4AB */ 42 { 0xC2, 0x22, 0x00, 4, 0x40, 2, 1024, 0x0C, 19, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 43 /* MX35LF2GE4AD */ 44 { 0xC2, 0x26, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 45 /* MX35LF4GE4AD */ 46 { 0xC2, 0x37, 0x00, 8, 0x40, 1, 2048, 0x0C, 20, 0x8, 1, { 0x04, 0x08, 0x14, 0x18 }, &sfc_nand_get_ecc_status0 }, 47 /* MX35UF1GE4AC */ 48 { 0xC2, 0x92, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 49 /* MX35UF2GE4AC */ 50 { 0xC2, 0xA2, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 51 52 /* GD5F1GQ4UAYIG */ 53 { 0xC8, 0xF1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 54 /* GD5F1GQ4RB9IGR */ 55 { 0xC8, 0xD1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 }, 56 /* GD5F2GQ40BY2GR */ 57 { 0xC8, 0xD2, 0x00, 4, 0x40, 2, 1024, 0x0C, 19, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 }, 58 /* GD5F1GQ5UEYIG */ 59 { 0xC8, 0x51, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status2 }, 60 /* GD5F2GQ5UEYIG */ 61 { 0xC8, 0x52, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status2 }, 62 /* GD5F1GQ4R */ 63 { 0xC8, 0xC1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 }, 64 /* GD5F4GQ6RExxG 1*4096 */ 65 { 0xC8, 0x45, 0x00, 4, 0x40, 2, 2048, 0x4C, 20, 0x4, 1, { 0x04, 0x08, 0X14, 0x18 }, &sfc_nand_get_ecc_status2 }, 66 /* GD5F4GQ6UExxG 1*4096 */ 67 { 0xC8, 0x55, 0x00, 4, 0x40, 2, 2048, 0x4C, 20, 0x4, 1, { 0x04, 0x08, 0X14, 0x18 }, &sfc_nand_get_ecc_status2 }, 68 /* GD5F1GQ4UExxH */ 69 { 0xC8, 0xD9, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status3 }, 70 71 /* W25N01GV */ 72 { 0xEF, 0xAA, 0x21, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status1 }, 73 /* W25N02KVZEIR */ 74 { 0xEF, 0xAA, 0x22, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status0 }, 75 /* W25N04KVZEIR */ 76 { 0xEF, 0xAA, 0x23, 4, 0x40, 1, 4096, 0x4C, 20, 0x8, 0, { 0x04, 0x14, 0x24, 0x34 }, &sfc_nand_get_ecc_status0 }, 77 /* W25N01GW */ 78 { 0xEF, 0xBA, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status1 }, 79 /* W25N512GVEIG */ 80 { 0xEF, 0xAA, 0x20, 4, 0x40, 1, 512, 0x4C, 17, 0x1, 0, { 0x04, 0x14, 0x24, 0xFF }, &sfc_nand_get_ecc_status1 }, 81 82 /* HYF2GQ4UAACAE */ 83 { 0xC9, 0x52, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0xE, 1, { 0x04, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 84 /* HYF1GQ4UDACAE */ 85 { 0xC9, 0x21, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 86 /* HYF1GQ4UPACAE */ 87 { 0xC9, 0xA1, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 88 /* HYF2GQ4UDACAE */ 89 { 0xC9, 0x22, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 90 /* HYF2GQ4UHCCAE */ 91 { 0xC9, 0x5A, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0xE, 1, { 0x04, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 92 /* HYF4GQ4UAACBE */ 93 { 0xC9, 0xD4, 0x00, 8, 0x40, 1, 2048, 0x4C, 20, 0x4, 1, { 0x20, 0x40, 0x24, 0x44 }, &sfc_nand_get_ecc_status0 }, 94 95 /* FS35ND01G-S1 */ 96 { 0xCD, 0xB1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x10, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status5 }, 97 /* FS35ND02G-S2 */ 98 { 0xCD, 0xA2, 0x00, 4, 0x40, 1, 2048, 0x00, 19, 0x4, 0, { 0x10, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status5 }, 99 /* FS35ND01G-S1Y2 */ 100 { 0xCD, 0xEA, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x4, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 101 /* FS35ND02G-S3Y2 */ 102 { 0xCD, 0xEB, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 103 /* FS35ND04G-S2Y2 1*4096 */ 104 { 0xCD, 0xEC, 0x00, 4, 0x40, 2, 2048, 0x4C, 20, 0x4, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 105 106 /* DS35Q1GA-IB */ 107 { 0xE5, 0x71, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 108 /* DS35Q2GA-IB */ 109 { 0xE5, 0x72, 0x00, 4, 0x40, 2, 1024, 0x0C, 19, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 110 /* DS35M1GA-1B */ 111 { 0xE5, 0x21, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 112 /* DS35Q2GB-IB */ 113 { 0xE5, 0xF2, 0x00, 4, 0x40, 2, 1024, 0x0C, 19, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 114 115 /* EM73C044VCC-H */ 116 { 0xD5, 0x22, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 117 /* EM73D044VCE-H */ 118 { 0xD5, 0x20, 0x00, 4, 0x40, 1, 2048, 0x0C, 19, 0x8, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 119 /* EM73E044SNA-G */ 120 { 0xD5, 0x03, 0x00, 8, 0x40, 1, 2048, 0x4C, 20, 0x8, 1, { 0x04, 0x28, 0x08, 0x2C }, &sfc_nand_get_ecc_status0 }, 121 /* EM73C044VCF-H */ 122 { 0xD5, 0x25, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x14, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 123 124 /* XT26G02A */ 125 { 0x0B, 0xE2, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status4 }, 126 /* XT26G01A */ 127 { 0x0B, 0xE1, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status4 }, 128 /* XT26G04A */ 129 { 0x0B, 0xE3, 0x00, 4, 0x80, 1, 2048, 0x4C, 20, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status4 }, 130 /* XT26G01B */ 131 { 0x0B, 0xF1, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status4 }, 132 /* XT26G02B */ 133 { 0x0B, 0xF2, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x4, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status5 }, 134 /* XT26G01C */ 135 { 0x0B, 0x11, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status7 }, 136 /* XT26G02C */ 137 { 0x0B, 0x12, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status7 }, 138 /* XT26G04C */ 139 { 0x0B, 0x13, 0x00, 8, 0x40, 1, 2048, 0x4C, 20, 0x8, 1, { 0x04, 0x08, 0x0C, 0x10 }, &sfc_nand_get_ecc_status7 }, 140 /* XT26G11C */ 141 { 0x0B, 0x15, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 142 143 /* MT29F2G01ABA, XT26G02E, F50L2G41XA */ 144 { 0x2C, 0x24, 0x00, 4, 0x40, 2, 1024, 0x4C, 19, 0x8, 0, { 0x20, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 145 /* MT29F1G01ABA, F50L1G41XA */ 146 { 0x2C, 0x14, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x8, 0, { 0x20, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status6 }, 147 148 /* FM25S01 */ 149 { 0xA1, 0xA1, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x00, 0x04, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 150 /* FM25S01A */ 151 { 0xA1, 0xE4, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 152 /* FM25S02A */ 153 { 0xA1, 0xE5, 0x00, 4, 0x40, 2, 1024, 0x4C, 19, 0x1, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 154 155 /* IS37SML01G1 */ 156 { 0xC8, 0x21, 0x00, 4, 0x40, 1, 1024, 0x00, 18, 0x1, 0, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 157 /* F50L1G41LB */ 158 { 0xC8, 0x01, 0x00, 4, 0x40, 1, 1024, 0x4C, 18, 0x1, 0, { 0x14, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 159 /* ATO25D1GA */ 160 { 0x9B, 0x12, 0x00, 4, 0x40, 1, 1024, 0x40, 18, 0x1, 1, { 0x14, 0x24, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 161 /* BWJX08K-2Gb */ 162 { 0xBC, 0xB3, 0x00, 4, 0x40, 1, 2048, 0x4C, 19, 0x8, 1, { 0x04, 0x10, 0xFF, 0xFF }, &sfc_nand_get_ecc_status0 }, 163 /* JS28U1GQSCAHG-83 */ 164 { 0xBF, 0x21, 0x00, 4, 0x40, 1, 1024, 0x40, 18, 0x4, 1, { 0x08, 0x0C, 0xFF, 0xFF }, &sfc_nand_get_ecc_status8 }, 165 /* SGM7000I-S24W1GH */ 166 { 0xEA, 0xC1, 0x00, 4, 0x40, 1, 1024, 0x0C, 18, 0x4, 1, { 0x04, 0x08, 0xFF, 0xFF }, &sfc_nand_get_ecc_status1 }, 167 }; 168 169 static struct nand_info *p_nand_info; 170 static u32 gp_page_buf[SFC_NAND_PAGE_MAX_SIZE / 4]; 171 static struct SFNAND_DEV sfc_nand_dev; 172 173 static struct nand_info *sfc_nand_get_info(u8 *nand_id) 174 { 175 u32 i; 176 177 for (i = 0; i < ARRAY_SIZE(spi_nand_tbl); i++) { 178 if (spi_nand_tbl[i].id0 == nand_id[0] && 179 spi_nand_tbl[i].id1 == nand_id[1]) { 180 if (spi_nand_tbl[i].id2 && 181 spi_nand_tbl[i].id2 != nand_id[2]) 182 continue; 183 184 return &spi_nand_tbl[i]; 185 } 186 } 187 188 return NULL; 189 } 190 191 static int sfc_nand_write_en(void) 192 { 193 int ret; 194 struct rk_sfc_op op; 195 196 op.sfcmd.d32 = 0; 197 op.sfcmd.b.cmd = CMD_WRITE_EN; 198 199 op.sfctrl.d32 = 0; 200 201 ret = sfc_request(&op, 0, NULL, 0); 202 return ret; 203 } 204 205 static int sfc_nand_rw_preset(void) 206 { 207 int ret; 208 struct rk_sfc_op op; 209 210 op.sfcmd.d32 = 0; 211 op.sfcmd.b.cmd = 0xff; 212 op.sfcmd.b.cs = 2; 213 214 op.sfctrl.d32 = 0; 215 op.sfctrl.b.datalines = 2; 216 op.sfctrl.b.cmdlines = 2; 217 op.sfctrl.b.addrlines = 2; 218 219 ret = sfc_request(&op, 0, NULL, 0); 220 return ret; 221 } 222 223 static int sfc_nand_read_feature(u8 addr, u8 *data) 224 { 225 int ret; 226 struct rk_sfc_op op; 227 228 op.sfcmd.d32 = 0; 229 op.sfcmd.b.cmd = 0x0F; 230 op.sfcmd.b.addrbits = SFC_ADDR_XBITS; 231 232 op.sfctrl.d32 = 0; 233 op.sfctrl.b.addrbits = 8; 234 235 *data = 0; 236 237 ret = sfc_request(&op, addr, data, 1); 238 239 if (ret != SFC_OK) 240 return ret; 241 242 return SFC_OK; 243 } 244 245 static int sfc_nand_write_feature(u32 addr, u8 status) 246 { 247 int ret; 248 struct rk_sfc_op op; 249 250 sfc_nand_write_en(); 251 252 op.sfcmd.d32 = 0; 253 op.sfcmd.b.cmd = 0x1F; 254 op.sfcmd.b.addrbits = SFC_ADDR_XBITS; 255 op.sfcmd.b.rw = SFC_WRITE; 256 257 op.sfctrl.d32 = 0; 258 op.sfctrl.b.addrbits = 8; 259 260 ret = sfc_request(&op, addr, &status, 1); 261 262 if (ret != SFC_OK) 263 return ret; 264 265 return ret; 266 } 267 268 static int sfc_nand_wait_busy(u8 *data, int timeout) 269 { 270 int ret; 271 int i; 272 u8 status; 273 274 *data = 0; 275 276 for (i = 0; i < timeout; i++) { 277 ret = sfc_nand_read_feature(0xC0, &status); 278 279 if (ret != SFC_OK) 280 return ret; 281 282 *data = status; 283 284 if (!(status & (1 << 0))) 285 return SFC_OK; 286 287 sfc_delay(1); 288 } 289 290 return SFC_NAND_WAIT_TIME_OUT; 291 } 292 293 /* 294 * ecc default: 295 * ecc bits: 0xC0[4,5] 296 * 0b00, No bit errors were detected 297 * 0b01, Bit errors were detected and corrected. 298 * 0b10, Multiple bit errors were detected and not corrected. 299 * 0b11, Bits errors were detected and corrected, bit error count 300 * reach the bit flip detection threshold 301 */ 302 static u32 sfc_nand_get_ecc_status0(void) 303 { 304 u32 ret; 305 u32 i; 306 u8 ecc; 307 u8 status; 308 u32 timeout = 1000 * 1000; 309 310 for (i = 0; i < timeout; i++) { 311 ret = sfc_nand_read_feature(0xC0, &status); 312 313 if (ret != SFC_OK) 314 return SFC_NAND_ECC_ERROR; 315 316 if (!(status & (1 << 0))) 317 break; 318 319 sfc_delay(1); 320 } 321 322 ecc = (status >> 4) & 0x03; 323 324 if (ecc <= 1) 325 ret = SFC_NAND_ECC_OK; 326 else if (ecc == 2) 327 ret = (u32)SFC_NAND_ECC_ERROR; 328 else 329 ret = SFC_NAND_ECC_REFRESH; 330 331 return ret; 332 } 333 334 /* 335 * ecc spectial type1: 336 * ecc bits: 0xC0[4,5] 337 * 0b00, No bit errors were detected; 338 * 0b01, Bits errors were detected and corrected, bit error count 339 * may reach the bit flip detection threshold; 340 * 0b10, Multiple bit errors were detected and not corrected; 341 * 0b11, Reserved. 342 */ 343 static u32 sfc_nand_get_ecc_status1(void) 344 { 345 u32 ret; 346 u32 i; 347 u8 ecc; 348 u8 status; 349 u32 timeout = 1000 * 1000; 350 351 for (i = 0; i < timeout; i++) { 352 ret = sfc_nand_read_feature(0xC0, &status); 353 354 if (ret != SFC_OK) 355 return SFC_NAND_ECC_ERROR; 356 357 if (!(status & (1 << 0))) 358 break; 359 360 sfc_delay(1); 361 } 362 363 ecc = (status >> 4) & 0x03; 364 365 if (ecc == 0) 366 ret = SFC_NAND_ECC_OK; 367 else if (ecc == 1) 368 ret = SFC_NAND_ECC_REFRESH; 369 else 370 ret = (u32)SFC_NAND_ECC_ERROR; 371 372 return ret; 373 } 374 375 /* 376 * ecc spectial type2: 377 * ecc bits: 0xC0[4,5] 0xF0[4,5] 378 * [0b0000, 0b0011], No bit errors were detected; 379 * [0b0100, 0b0111], Bit errors were detected and corrected. Not 380 * reach Flipping Bits; 381 * [0b1000, 0b1011], Multiple bit errors were detected and 382 * not corrected. 383 * [0b1100, 0b1111], reserved. 384 */ 385 static u32 sfc_nand_get_ecc_status2(void) 386 { 387 u32 ret; 388 u32 i; 389 u8 ecc; 390 u8 status, status1; 391 u32 timeout = 1000 * 1000; 392 393 for (i = 0; i < timeout; i++) { 394 ret = sfc_nand_read_feature(0xC0, &status); 395 396 if (ret != SFC_OK) 397 return SFC_NAND_ECC_ERROR; 398 399 ret = sfc_nand_read_feature(0xF0, &status1); 400 401 if (ret != SFC_OK) 402 return SFC_NAND_ECC_ERROR; 403 404 if (!(status & (1 << 0))) 405 break; 406 407 sfc_delay(1); 408 } 409 410 ecc = (status >> 4) & 0x03; 411 ecc = (ecc << 2) | ((status1 >> 4) & 0x03); 412 413 if (ecc < 7) 414 ret = SFC_NAND_ECC_OK; 415 else if (ecc == 7) 416 ret = SFC_NAND_ECC_REFRESH; 417 else 418 ret = (u32)SFC_NAND_ECC_ERROR; 419 420 return ret; 421 } 422 423 /* 424 * ecc spectial type3: 425 * ecc bits: 0xC0[4,5] 0xF0[4,5] 426 * [0b0000, 0b0011], No bit errors were detected; 427 * [0b0100, 0b0111], Bit errors were detected and corrected. Not 428 * reach Flipping Bits; 429 * [0b1000, 0b1011], Multiple bit errors were detected and 430 * not corrected. 431 * [0b1100, 0b1111], Bit error count equals the bit flip 432 * detectio nthreshold 433 */ 434 static u32 sfc_nand_get_ecc_status3(void) 435 { 436 u32 ret; 437 u32 i; 438 u8 ecc; 439 u8 status, status1; 440 u32 timeout = 1000 * 1000; 441 442 for (i = 0; i < timeout; i++) { 443 ret = sfc_nand_read_feature(0xC0, &status); 444 445 if (ret != SFC_OK) 446 return SFC_NAND_ECC_ERROR; 447 448 ret = sfc_nand_read_feature(0xF0, &status1); 449 450 if (ret != SFC_OK) 451 return SFC_NAND_ECC_ERROR; 452 453 if (!(status & (1 << 0))) 454 break; 455 456 sfc_delay(1); 457 } 458 459 ecc = (status >> 4) & 0x03; 460 ecc = (ecc << 2) | ((status1 >> 4) & 0x03); 461 462 if (ecc < 7) 463 ret = SFC_NAND_ECC_OK; 464 else if (ecc == 7 || ecc >= 12) 465 ret = SFC_NAND_ECC_REFRESH; 466 else 467 ret = (u32)SFC_NAND_ECC_ERROR; 468 469 return ret; 470 } 471 472 /* 473 * ecc spectial type4: 474 * ecc bits: 0xC0[2,5] 475 * [0b0000], No bit errors were detected; 476 * [0b0001, 0b0111], Bit errors were detected and corrected. Not 477 * reach Flipping Bits; 478 * [0b1000], Multiple bit errors were detected and 479 * not corrected. 480 * [0b1100], Bit error count equals the bit flip 481 * detection threshold 482 * else, reserved 483 */ 484 static u32 sfc_nand_get_ecc_status4(void) 485 { 486 u32 ret; 487 u32 i; 488 u8 ecc; 489 u8 status; 490 u32 timeout = 1000 * 1000; 491 492 for (i = 0; i < timeout; i++) { 493 ret = sfc_nand_read_feature(0xC0, &status); 494 495 if (ret != SFC_OK) 496 return SFC_NAND_ECC_ERROR; 497 498 if (!(status & (1 << 0))) 499 break; 500 501 sfc_delay(1); 502 } 503 504 ecc = (status >> 2) & 0x0f; 505 506 if (ecc < 7) 507 ret = SFC_NAND_ECC_OK; 508 else if (ecc == 7 || ecc == 12) 509 ret = SFC_NAND_ECC_REFRESH; 510 else 511 ret = (u32)SFC_NAND_ECC_ERROR; 512 513 return ret; 514 } 515 516 /* 517 * ecc spectial type5: 518 * ecc bits: 0xC0[4,6] 519 * [0b000], No bit errors were detected; 520 * [0b001, 0b011], Bit errors were detected and corrected. Not 521 * reach Flipping Bits; 522 * [0b100], Bit error count equals the bit flip 523 * detection threshold 524 * [0b101, 0b110], Reserved; 525 * [0b111], Multiple bit errors were detected and 526 * not corrected. 527 */ 528 static u32 sfc_nand_get_ecc_status5(void) 529 { 530 u32 ret; 531 u32 i; 532 u8 ecc; 533 u8 status; 534 u32 timeout = 1000 * 1000; 535 536 for (i = 0; i < timeout; i++) { 537 ret = sfc_nand_read_feature(0xC0, &status); 538 539 if (ret != SFC_OK) 540 return SFC_NAND_ECC_ERROR; 541 542 if (!(status & (1 << 0))) 543 break; 544 545 sfc_delay(1); 546 } 547 548 ecc = (status >> 4) & 0x07; 549 550 if (ecc < 4) 551 ret = SFC_NAND_ECC_OK; 552 else if (ecc == 4) 553 ret = SFC_NAND_ECC_REFRESH; 554 else 555 ret = (u32)SFC_NAND_ECC_ERROR; 556 557 return ret; 558 } 559 560 /* 561 * ecc spectial type6: 562 * ecc bits: 0xC0[4,6] 563 * [0b000], No bit errors were detected; 564 * [0b001], 1-3 Bit errors were detected and corrected. Not 565 * reach Flipping Bits; 566 * [0b010], Multiple bit errors were detected and 567 * not corrected. 568 * [0b011], 4-6 Bit errors were detected and corrected. Not 569 * reach Flipping Bits; 570 * [0b101], Bit error count equals the bit flip 571 * detectionthreshold 572 * others, Reserved. 573 */ 574 static u32 sfc_nand_get_ecc_status6(void) 575 { 576 u32 ret; 577 u32 i; 578 u8 ecc; 579 u8 status; 580 u32 timeout = 1000 * 1000; 581 582 for (i = 0; i < timeout; i++) { 583 ret = sfc_nand_read_feature(0xC0, &status); 584 585 if (ret != SFC_OK) 586 return SFC_NAND_ECC_ERROR; 587 588 if (!(status & (1 << 0))) 589 break; 590 591 sfc_delay(1); 592 } 593 594 ecc = (status >> 4) & 0x07; 595 596 if (ecc == 0 || ecc == 1 || ecc == 3) 597 ret = SFC_NAND_ECC_OK; 598 else if (ecc == 5) 599 ret = SFC_NAND_ECC_REFRESH; 600 else 601 ret = (u32)SFC_NAND_ECC_ERROR; 602 603 return ret; 604 } 605 606 /* 607 * ecc spectial type7: 608 * ecc bits: 0xC0[4,7] 609 * [0b0000], No bit errors were detected; 610 * [0b0001, 0b0111], 1-7 Bit errors were detected and corrected. Not 611 * reach Flipping Bits; 612 * [0b1000], 8 Bit errors were detected and corrected. Bit error count 613 * equals the bit flip detectionthreshold; 614 * [0b1111], Bit errors greater than ECC capability(8 bits) and not corrected; 615 * others, Reserved. 616 */ 617 static u32 sfc_nand_get_ecc_status7(void) 618 { 619 u32 ret; 620 u32 i; 621 u8 ecc; 622 u8 status; 623 u32 timeout = 1000 * 1000; 624 625 for (i = 0; i < timeout; i++) { 626 ret = sfc_nand_read_feature(0xC0, &status); 627 628 if (ret != SFC_OK) 629 return SFC_NAND_ECC_ERROR; 630 631 if (!(status & (1 << 0))) 632 break; 633 634 sfc_delay(1); 635 } 636 637 ecc = (status >> 4) & 0xf; 638 639 if (ecc < 7) 640 ret = SFC_NAND_ECC_OK; 641 else if (ecc == 7 || ecc == 8) 642 ret = SFC_NAND_ECC_REFRESH; 643 else 644 ret = (u32)SFC_NAND_ECC_ERROR; 645 646 return ret; 647 } 648 649 /* 650 * ecc spectial type8: 651 * ecc bits: 0xC0[4,6] 652 * [0b000], No bit errors were detected; 653 * [0b001, 0b011], 1~3 Bit errors were detected and corrected. Not 654 * reach Flipping Bits; 655 * [0b100], Bit error count equals the bit flip 656 * detection threshold 657 * others, Reserved. 658 */ 659 static u32 sfc_nand_get_ecc_status8(void) 660 { 661 u32 ret; 662 u32 i; 663 u8 ecc; 664 u8 status; 665 u32 timeout = 1000 * 1000; 666 667 for (i = 0; i < timeout; i++) { 668 ret = sfc_nand_read_feature(0xC0, &status); 669 670 if (ret != SFC_OK) 671 return SFC_NAND_ECC_ERROR; 672 673 if (!(status & (1 << 0))) 674 break; 675 676 sfc_delay(1); 677 } 678 679 ecc = (status >> 4) & 0x07; 680 681 if (ecc < 4) 682 ret = SFC_NAND_ECC_OK; 683 else if (ecc == 4) 684 ret = SFC_NAND_ECC_REFRESH; 685 else 686 ret = (u32)SFC_NAND_ECC_ERROR; 687 688 return ret; 689 } 690 691 u32 sfc_nand_erase_block(u8 cs, u32 addr) 692 { 693 int ret; 694 struct rk_sfc_op op; 695 u8 status; 696 697 rkflash_print_dio("%s %x\n", __func__, addr); 698 op.sfcmd.d32 = 0; 699 op.sfcmd.b.cmd = 0xd8; 700 op.sfcmd.b.addrbits = SFC_ADDR_24BITS; 701 op.sfcmd.b.rw = SFC_WRITE; 702 703 op.sfctrl.d32 = 0; 704 705 sfc_nand_write_en(); 706 ret = sfc_request(&op, addr, NULL, 0); 707 708 if (ret != SFC_OK) 709 return ret; 710 711 ret = sfc_nand_wait_busy(&status, 1000 * 1000); 712 713 if (status & (1 << 2)) 714 return SFC_NAND_PROG_ERASE_ERROR; 715 716 return ret; 717 } 718 719 static u32 sfc_nand_read_cache(u32 row, u32 *p_page_buf, u32 column, u32 len) 720 { 721 int ret; 722 u32 plane; 723 struct rk_sfc_op op; 724 725 op.sfcmd.d32 = 0; 726 op.sfcmd.b.cmd = sfc_nand_dev.page_read_cmd; 727 op.sfcmd.b.addrbits = SFC_ADDR_XBITS; 728 op.sfcmd.b.dummybits = 8; 729 730 op.sfctrl.d32 = 0; 731 op.sfctrl.b.datalines = sfc_nand_dev.read_lines; 732 op.sfctrl.b.addrbits = 16; 733 734 plane = p_nand_info->plane_per_die == 2 ? ((row >> 6) & 0x1) << 12 : 0; 735 736 ret = sfc_request(&op, plane | column, p_page_buf, len); 737 if (ret != SFC_OK) 738 return SFC_NAND_HW_ERROR; 739 740 return ret; 741 } 742 743 u32 sfc_nand_prog_page_raw(u8 cs, u32 addr, u32 *p_page_buf) 744 { 745 int ret; 746 u32 plane; 747 struct rk_sfc_op op; 748 u8 status; 749 u32 page_size = SFC_NAND_SECTOR_FULL_SIZE * p_nand_info->sec_per_page; 750 u32 data_area_size = SFC_NAND_SECTOR_SIZE * p_nand_info->sec_per_page; 751 752 rkflash_print_dio("%s %x %x\n", __func__, addr, p_page_buf[0]); 753 sfc_nand_write_en(); 754 755 if (sfc_nand_dev.prog_lines == DATA_LINES_X4 && 756 p_nand_info->feature & FEA_SOFT_QOP_BIT && 757 sfc_get_version() < SFC_VER_3) 758 sfc_nand_rw_preset(); 759 760 op.sfcmd.d32 = 0; 761 op.sfcmd.b.cmd = sfc_nand_dev.page_prog_cmd; 762 op.sfcmd.b.addrbits = SFC_ADDR_XBITS; 763 op.sfcmd.b.rw = SFC_WRITE; 764 765 op.sfctrl.d32 = 0; 766 op.sfctrl.b.datalines = sfc_nand_dev.prog_lines; 767 op.sfctrl.b.addrbits = 16; 768 plane = p_nand_info->plane_per_die == 2 ? ((addr >> 6) & 0x1) << 12 : 0; 769 sfc_request(&op, plane, p_page_buf, page_size); 770 771 /* 772 * At the moment of power lost, flash maybe work in a unkonw state 773 * and result in bit flip, when this situation is detected by cache 774 * recheck, it's better to wait a second for a reliable hardware 775 * environment to avoid abnormal data written to flash array. 776 */ 777 sfc_nand_read_cache(addr, (u32 *)sfc_nand_dev.recheck_buffer, 0, data_area_size); 778 if (memcmp(sfc_nand_dev.recheck_buffer, p_page_buf, data_area_size)) 779 rkflash_print_error("%s cache bitflip1\n", __func__); 780 781 op.sfcmd.d32 = 0; 782 op.sfcmd.b.cmd = 0x10; 783 op.sfcmd.b.addrbits = SFC_ADDR_24BITS; 784 op.sfcmd.b.rw = SFC_WRITE; 785 786 op.sfctrl.d32 = 0; 787 ret = sfc_request(&op, addr, p_page_buf, 0); 788 789 if (ret != SFC_OK) 790 return ret; 791 792 ret = sfc_nand_wait_busy(&status, 1000 * 1000); 793 if (status & (1 << 3)) 794 return SFC_NAND_PROG_ERASE_ERROR; 795 796 return ret; 797 } 798 799 u32 sfc_nand_prog_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare) 800 { 801 int ret; 802 u32 sec_per_page = p_nand_info->sec_per_page; 803 u32 data_size = sec_per_page * SFC_NAND_SECTOR_SIZE; 804 struct nand_mega_area *meta = &p_nand_info->meta; 805 806 memcpy(gp_page_buf, p_data, data_size); 807 memset(&gp_page_buf[data_size / 4], 0xff, sec_per_page * 16); 808 gp_page_buf[(data_size + meta->off0) / 4] = p_spare[0]; 809 gp_page_buf[(data_size + meta->off1) / 4] = p_spare[1]; 810 811 if (sec_per_page == 8) { 812 gp_page_buf[(data_size + meta->off2) / 4] = p_spare[2]; 813 gp_page_buf[(data_size + meta->off3) / 4] = p_spare[3]; 814 } 815 816 ret = sfc_nand_prog_page_raw(cs, addr, gp_page_buf); 817 818 return ret; 819 } 820 821 u32 sfc_nand_read(u32 row, u32 *p_page_buf, u32 column, u32 len) 822 { 823 int ret; 824 u32 plane; 825 struct rk_sfc_op op; 826 u32 ecc_result; 827 u8 status; 828 829 op.sfcmd.d32 = 0; 830 op.sfcmd.b.cmd = 0x13; 831 op.sfcmd.b.rw = SFC_WRITE; 832 op.sfcmd.b.addrbits = SFC_ADDR_24BITS; 833 834 op.sfctrl.d32 = 0; 835 836 sfc_request(&op, row, p_page_buf, 0); 837 838 if (sfc_nand_dev.read_lines == DATA_LINES_X4 && 839 p_nand_info->feature & FEA_SOFT_QOP_BIT && 840 sfc_get_version() < SFC_VER_3) 841 sfc_nand_rw_preset(); 842 843 sfc_nand_wait_busy(&status, 1000 * 1000); 844 ecc_result = p_nand_info->ecc_status(); 845 846 op.sfcmd.d32 = 0; 847 op.sfcmd.b.cmd = sfc_nand_dev.page_read_cmd; 848 op.sfcmd.b.addrbits = SFC_ADDR_XBITS; 849 op.sfcmd.b.dummybits = 8; 850 851 op.sfctrl.d32 = 0; 852 op.sfctrl.b.datalines = sfc_nand_dev.read_lines; 853 op.sfctrl.b.addrbits = 16; 854 855 plane = p_nand_info->plane_per_die == 2 ? ((row >> 6) & 0x1) << 12 : 0; 856 ret = sfc_request(&op, plane | column, p_page_buf, len); 857 rkflash_print_dio("%s %x %x\n", __func__, row, p_page_buf[0]); 858 859 if (ret != SFC_OK) 860 return SFC_NAND_HW_ERROR; 861 862 return ecc_result; 863 } 864 865 u32 sfc_nand_read_page_raw(u8 cs, u32 addr, u32 *p_page_buf) 866 { 867 u32 page_size = SFC_NAND_SECTOR_FULL_SIZE * p_nand_info->sec_per_page; 868 869 return sfc_nand_read(addr, p_page_buf, 0, page_size); 870 } 871 872 u32 sfc_nand_read_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare) 873 { 874 u32 ret; 875 u32 sec_per_page = p_nand_info->sec_per_page; 876 u32 data_size = sec_per_page * SFC_NAND_SECTOR_SIZE; 877 struct nand_mega_area *meta = &p_nand_info->meta; 878 879 ret = sfc_nand_read_page_raw(cs, addr, gp_page_buf); 880 memcpy(p_data, gp_page_buf, data_size); 881 p_spare[0] = gp_page_buf[(data_size + meta->off0) / 4]; 882 p_spare[1] = gp_page_buf[(data_size + meta->off1) / 4]; 883 884 if (p_nand_info->sec_per_page == 8) { 885 p_spare[2] = gp_page_buf[(data_size + meta->off2) / 4]; 886 p_spare[3] = gp_page_buf[(data_size + meta->off3) / 4]; 887 } 888 889 if (ret == SFC_NAND_HW_ERROR) 890 ret = SFC_NAND_ECC_ERROR; 891 892 if (ret != SFC_NAND_ECC_OK) { 893 rkflash_print_error("%s[0x%x], ret=0x%x\n", __func__, addr, ret); 894 895 if (p_data) 896 rkflash_print_hex("data:", p_data, 4, 8); 897 898 if (p_spare) 899 rkflash_print_hex("spare:", p_spare, 4, 2); 900 } 901 902 return ret; 903 } 904 905 u32 sfc_nand_check_bad_block(u8 cs, u32 addr) 906 { 907 u32 ret; 908 u32 data_size = p_nand_info->sec_per_page * SFC_NAND_SECTOR_SIZE; 909 u32 marker = 0; 910 911 ret = sfc_nand_read(addr, &marker, data_size, 2); 912 913 /* unify with mtd framework */ 914 if (ret == SFC_NAND_ECC_ERROR || (u16)marker != 0xffff) 915 rkflash_print_error("%s page= %x ret= %x spare= %x\n", 916 __func__, addr, ret, marker); 917 918 /* Original bad block */ 919 if ((u16)marker != 0xffff) 920 return true; 921 922 return false; 923 } 924 925 u32 sfc_nand_mark_bad_block(u8 cs, u32 addr) 926 { 927 u32 ret; 928 u32 data_size = p_nand_info->sec_per_page * SFC_NAND_SECTOR_SIZE; 929 930 ret = sfc_nand_read_page_raw(cs, addr, gp_page_buf); 931 932 if (ret) 933 return SFC_NAND_HW_ERROR; 934 935 gp_page_buf[data_size / 4] = 0x0; 936 ret = sfc_nand_prog_page_raw(cs, addr, gp_page_buf); 937 938 if (ret) 939 return SFC_NAND_HW_ERROR; 940 941 return ret; 942 } 943 944 int sfc_nand_read_id(u8 *data) 945 { 946 int ret; 947 struct rk_sfc_op op; 948 949 op.sfcmd.d32 = 0; 950 op.sfcmd.b.cmd = CMD_READ_JEDECID; 951 op.sfcmd.b.addrbits = SFC_ADDR_XBITS; 952 953 op.sfctrl.d32 = 0; 954 op.sfctrl.b.addrbits = 8; 955 956 ret = sfc_request(&op, 0, data, 3); 957 958 return ret; 959 } 960 961 /* 962 * Read the 1st page's 1st byte of a phy_blk 963 * If not FF, it's bad blk 964 */ 965 static int sfc_nand_get_bad_block_list(u16 *table, u32 die) 966 { 967 u32 bad_cnt, page; 968 u32 blk_per_die; 969 u16 blk; 970 971 rkflash_print_info("%s\n", __func__); 972 973 bad_cnt = 0; 974 blk_per_die = p_nand_info->plane_per_die * 975 p_nand_info->blk_per_plane; 976 977 for (blk = 0; blk < blk_per_die; blk++) { 978 page = (blk + blk_per_die * die) * 979 p_nand_info->page_per_blk; 980 981 if (sfc_nand_check_bad_block(die, page)) { 982 table[bad_cnt++] = blk; 983 rkflash_print_error("die[%d], bad_blk[%d]\n", die, blk); 984 } 985 } 986 987 return (int)bad_cnt; 988 } 989 990 void sfc_nand_ftl_ops_init(void) 991 { 992 /* para init */ 993 g_nand_phy_info.nand_type = 1; 994 g_nand_phy_info.die_num = 1; 995 g_nand_phy_info.plane_per_die = p_nand_info->plane_per_die; 996 g_nand_phy_info.blk_per_plane = p_nand_info->blk_per_plane; 997 g_nand_phy_info.page_per_blk = p_nand_info->page_per_blk; 998 g_nand_phy_info.page_per_slc_blk = p_nand_info->page_per_blk; 999 g_nand_phy_info.byte_per_sec = SFC_NAND_SECTOR_SIZE; 1000 g_nand_phy_info.sec_per_page = p_nand_info->sec_per_page; 1001 g_nand_phy_info.sec_per_blk = p_nand_info->sec_per_page * 1002 p_nand_info->page_per_blk; 1003 g_nand_phy_info.reserved_blk = 8; 1004 g_nand_phy_info.blk_per_die = p_nand_info->plane_per_die * 1005 p_nand_info->blk_per_plane; 1006 g_nand_phy_info.ecc_bits = p_nand_info->max_ecc_bits; 1007 1008 /* driver register */ 1009 g_nand_ops.get_bad_blk_list = sfc_nand_get_bad_block_list; 1010 g_nand_ops.erase_blk = sfc_nand_erase_block; 1011 g_nand_ops.prog_page = sfc_nand_prog_page; 1012 g_nand_ops.read_page = sfc_nand_read_page; 1013 g_nand_ops.bch_sel = NULL; 1014 } 1015 1016 static int sfc_nand_enable_QE(void) 1017 { 1018 int ret = SFC_OK; 1019 u8 status; 1020 1021 ret = sfc_nand_read_feature(0xB0, &status); 1022 1023 if (ret != SFC_OK) 1024 return ret; 1025 1026 if (status & 1) /* is QE bit set */ 1027 return SFC_OK; 1028 1029 status |= 1; 1030 1031 return sfc_nand_write_feature(0xB0, status); 1032 } 1033 1034 u32 sfc_nand_init(void) 1035 { 1036 u8 status, id_byte[8]; 1037 1038 sfc_nand_read_id(id_byte); 1039 rkflash_print_error("sfc_nand id: %x %x %x\n", 1040 id_byte[0], id_byte[1], id_byte[2]); 1041 1042 if (id_byte[0] == 0xFF || id_byte[0] == 0x00) 1043 return (u32)FTL_NO_FLASH; 1044 1045 p_nand_info = sfc_nand_get_info(id_byte); 1046 1047 if (!p_nand_info) 1048 return (u32)FTL_UNSUPPORTED_FLASH; 1049 1050 sfc_nand_dev.manufacturer = id_byte[0]; 1051 sfc_nand_dev.mem_type = id_byte[1]; 1052 sfc_nand_dev.capacity = p_nand_info->density; 1053 sfc_nand_dev.block_size = p_nand_info->page_per_blk * p_nand_info->sec_per_page; 1054 sfc_nand_dev.page_size = p_nand_info->sec_per_page; 1055 1056 /* disable block lock */ 1057 sfc_nand_write_feature(0xA0, 0); 1058 sfc_nand_dev.read_lines = DATA_LINES_X1; 1059 sfc_nand_dev.prog_lines = DATA_LINES_X1; 1060 sfc_nand_dev.page_read_cmd = 0x03; 1061 sfc_nand_dev.page_prog_cmd = 0x02; 1062 sfc_nand_dev.recheck_buffer = ftl_malloc(SFC_NAND_PAGE_MAX_SIZE); 1063 if (!sfc_nand_dev.recheck_buffer) { 1064 rkflash_print_error("%s recheck_buffer alloc failed\n", __func__); 1065 return -1; 1066 } 1067 1068 if (p_nand_info->feature & FEA_4BIT_READ) { 1069 if ((p_nand_info->has_qe_bits && sfc_nand_enable_QE() == SFC_OK) || 1070 !p_nand_info->has_qe_bits) { 1071 sfc_nand_dev.read_lines = DATA_LINES_X4; 1072 sfc_nand_dev.page_read_cmd = 0x6b; 1073 } 1074 } 1075 1076 if (p_nand_info->feature & FEA_4BIT_PROG && 1077 sfc_nand_dev.read_lines == DATA_LINES_X4) { 1078 sfc_nand_dev.prog_lines = DATA_LINES_X4; 1079 sfc_nand_dev.page_prog_cmd = 0x32; 1080 } 1081 1082 sfc_nand_read_feature(0xA0, &status); 1083 rkflash_print_info("sfc_nand A0 = 0x%x\n", status); 1084 sfc_nand_read_feature(0xB0, &status); 1085 rkflash_print_info("sfc_nand B0 = 0x%x\n", status); 1086 rkflash_print_info("read_lines = %x\n", sfc_nand_dev.read_lines); 1087 rkflash_print_info("prog_lines = %x\n", sfc_nand_dev.prog_lines); 1088 rkflash_print_info("page_read_cmd = %x\n", sfc_nand_dev.page_read_cmd); 1089 rkflash_print_info("page_prog_cmd = %x\n", sfc_nand_dev.page_prog_cmd); 1090 1091 return SFC_OK; 1092 } 1093 1094 void sfc_nand_deinit(void) 1095 { 1096 /* to-do */ 1097 kfree(sfc_nand_dev.recheck_buffer); 1098 } 1099 1100 struct SFNAND_DEV *sfc_nand_get_private_dev(void) 1101 { 1102 return &sfc_nand_dev; 1103 } 1104 1105