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