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.h" 12 #include "flash_com.h" 13 #include "sfc.h" 14 #include "sfc_nand.h" 15 #include "rkflash_debug.h" 16 17 static struct nand_info spi_nand_tbl[] = { 18 /* TC58CVG0S0HxAIx */ 19 {0x98C2, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x02, 0xD8, 0x00, 18, 8, 0xB0, 0XFF, 4, 8, NULL}, 20 /* TC58CVG1S0HxAIx */ 21 {0x98CB, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x02, 0xD8, 0x00, 19, 8, 0xB0, 0XFF, 4, 8, NULL}, 22 /* MX35LF1GE4AB */ 23 {0xC212, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 4, 0xB0, 0, 4, 8, &sfc_nand_ecc_status_sp1}, 24 /* MX35LF2GE4AB */ 25 {0xC222, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 4, 0xB0, 0, 4, 8, &sfc_nand_ecc_status_sp1}, 26 /* GD5F1GQ4UAYIG */ 27 {0xC8F1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xB0, 0, 4, 8, NULL}, 28 /* MT29F1G01ZAC */ 29 {0x2C12, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x00, 18, 1, 0xB0, 0, 4, 8, &sfc_nand_ecc_status_sp1}, 30 /* GD5F2GQ40BY2GR */ 31 {0xC8D2, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 8, 0xB0, 0, 4, 8, &sfc_nand_ecc_status_sp3}, 32 /* GD5F1GQ4U */ 33 {0xC8D1, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 8, 0xB0, 0, 4, 8, &sfc_nand_ecc_status_sp3}, 34 /* IS37SML01G1 */ 35 {0xC821, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x00, 18, 1, 0xB0, 0XFF, 8, 12, &sfc_nand_ecc_status_sp1}, 36 /* W25N01GV */ 37 {0xEFAA, 4, 64, 1, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 1, 0xFF, 0XFF, 4, 20, &sfc_nand_ecc_status_sp1}, 38 /* HYF2GQ4UAACAE */ 39 {0xC952, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 14, 0xB0, 0, 4, 36, NULL}, 40 /* HYF2GQ4UDACAE */ 41 {0xC922, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 19, 4, 0xB0, 0, 4, 20, NULL}, 42 /* HYF1GQ4UDACAE */ 43 {0xC921, 4, 64, 2, 1024, 0x13, 0x10, 0x03, 0x02, 0x6B, 0x32, 0xD8, 0x0C, 18, 4, 0xB0, 0, 4, 20, NULL}, 44 }; 45 46 static u8 id_byte[8]; 47 static struct nand_info *p_nand_info; 48 static u32 gp_page_buf[SFC_NAND_PAGE_MAX_SIZE / 4]; 49 static struct SFNAND_DEV sfc_nand_dev; 50 51 static struct nand_info *spi_nand_get_info(u8 *nand_id) 52 { 53 u32 i; 54 u32 id = (nand_id[0] << 8) | (nand_id[1] << 0); 55 56 for (i = 0; i < ARRAY_SIZE(spi_nand_tbl); i++) { 57 if (spi_nand_tbl[i].id == id) 58 return &spi_nand_tbl[i]; 59 } 60 return NULL; 61 } 62 63 static int sfc_nand_write_en(void) 64 { 65 int ret; 66 union SFCCMD_DATA sfcmd; 67 68 sfcmd.d32 = 0; 69 sfcmd.b.cmd = CMD_WRITE_EN; 70 ret = sfc_request(sfcmd.d32, 0, 0, NULL); 71 return ret; 72 } 73 74 static int sfc_nand_rw_preset(void) 75 { 76 int ret; 77 union SFCCTRL_DATA sfctrl; 78 union SFCCMD_DATA sfcmd; 79 u8 status = 0xFF; 80 81 sfcmd.d32 = 0; 82 sfcmd.b.cmd = 0; 83 sfcmd.b.datasize = 1; 84 sfcmd.b.rw = SFC_WRITE; 85 86 sfctrl.b.datalines = 2; 87 ret = sfc_request(sfcmd.d32, sfctrl.d32, 0, &status); 88 return ret; 89 } 90 91 static int sfc_nand_read_feature(u8 addr, u8 *data) 92 { 93 int ret; 94 union SFCCMD_DATA sfcmd; 95 96 sfcmd.d32 = 0; 97 sfcmd.b.cmd = 0x0F; 98 sfcmd.b.datasize = 1; 99 sfcmd.b.addrbits = SFC_ADDR_XBITS; 100 *data = 0; 101 102 ret = sfc_request(sfcmd.d32, 0x8 << 16, addr, data); 103 if (ret != SFC_OK) 104 return ret; 105 return SFC_OK; 106 } 107 108 static int sfc_nand_write_feature(u32 addr, u8 status) 109 { 110 int ret; 111 union SFCCMD_DATA sfcmd; 112 113 sfc_nand_write_en(); 114 115 sfcmd.d32 = 0; 116 sfcmd.b.cmd = 0x1F; 117 sfcmd.b.datasize = 1; 118 sfcmd.b.addrbits = SFC_ADDR_XBITS; 119 sfcmd.b.rw = SFC_WRITE; 120 121 ret = sfc_request(sfcmd.d32, 0x8 << 16, addr, &status); 122 if (ret != SFC_OK) 123 return ret; 124 return ret; 125 } 126 127 static int sfc_nand_wait_busy(u8 *data, int timeout) 128 { 129 int ret; 130 int i; 131 u8 status; 132 133 *data = 0; 134 for (i = 0; i < timeout; i++) { 135 ret = sfc_nand_read_feature(0xC0, &status); 136 if (ret != SFC_OK) 137 return ret; 138 *data = status; 139 if (!(status & (1 << 0))) 140 return SFC_OK; 141 sfc_delay(1); 142 } 143 return -1; 144 } 145 146 /* 147 * ecc default: 148 * 0, No bit errors were detected 149 * 1, Bit errors were detected and corrected. 150 * 2, Multiple bit errors were detected and not corrected. 151 * 3, Bits errors were detected and corrected, bit error count 152 * exceed the bit flip detection threshold 153 */ 154 static u32 sfc_nand_ecc_status(void) 155 { 156 int ret; 157 u32 i; 158 u8 ecc; 159 u8 status; 160 u32 timeout = 1000 * 1000; 161 162 for (i = 0; i < timeout; i++) { 163 ret = sfc_nand_read_feature(0xC0, &status); 164 if (ret != SFC_OK) 165 return SFC_NAND_ECC_ERROR; 166 if (!(status & (1 << 0))) 167 break; 168 sfc_delay(1); 169 } 170 171 ecc = (status >> 4) & 0x03; 172 173 if (ecc <= 1) 174 ret = SFC_NAND_ECC_OK; 175 else if (ecc == 2) 176 ret = SFC_NAND_ECC_ERROR; 177 else 178 ret = SFC_NAND_ECC_REFRESH; 179 180 return ret; 181 } 182 183 /* 184 * ecc spectial type1: 185 * 0x00, No bit errors were detected; 186 * 0x01, Bits errors were detected and corrected, bit error count 187 * may reach the bit flip detection threshold; 188 * 0x10, Multiple bit errors were detected and not corrected; 189 * 0x11, Reserved. 190 */ 191 u32 sfc_nand_ecc_status_sp1(void) 192 { 193 int ret; 194 u32 i; 195 u8 ecc; 196 u8 status; 197 u32 timeout = 1000 * 1000; 198 199 for (i = 0; i < timeout; i++) { 200 ret = sfc_nand_read_feature(0xC0, &status); 201 if (ret != SFC_OK) 202 return SFC_NAND_ECC_ERROR; 203 if (!(status & (1 << 0))) 204 break; 205 sfc_delay(1); 206 } 207 208 ecc = (status >> 4) & 0x03; 209 210 if (ecc == 0) 211 ret = SFC_NAND_ECC_OK; 212 else if (ecc == 1) 213 ret = SFC_NAND_ECC_REFRESH; 214 else 215 ret = SFC_NAND_ECC_ERROR; 216 217 return ret; 218 } 219 220 /* 221 * ecc spectial type3: 222 * [0x0000, 0x0011], No bit errors were detected; 223 * [0x0100, 0x0111], Bit errors were detected and corrected. Not 224 * reach Flipping Bits; 225 * [0x1000, 0x1011], Multiple bit errors were detected and 226 * not corrected. 227 * [0x1100, 0x1111], Bit error count equals the bit flip 228 * detectionthreshold 229 */ 230 u32 sfc_nand_ecc_status_sp3(void) 231 { 232 int ret; 233 u32 i; 234 u8 ecc; 235 u8 status, status1; 236 u32 timeout = 1000 * 1000; 237 238 for (i = 0; i < timeout; i++) { 239 ret = sfc_nand_read_feature(0xC0, &status); 240 if (ret != SFC_OK) 241 return SFC_NAND_ECC_ERROR; 242 ret = sfc_nand_read_feature(0xF0, &status1); 243 if (ret != SFC_OK) 244 return SFC_NAND_ECC_ERROR; 245 if (!(status & (1 << 0))) 246 break; 247 sfc_delay(1); 248 } 249 250 ecc = (status >> 4) & 0x03; 251 ecc = (ecc << 2) | ((status1 >> 4) & 0x03); 252 if (ecc < 7) 253 ret = SFC_NAND_ECC_OK; 254 else if (ecc == 7 || ecc >= 12) 255 ret = SFC_NAND_ECC_REFRESH; 256 else 257 ret = SFC_NAND_ECC_ERROR; 258 259 return ret; 260 } 261 262 static u32 sfc_nand_erase_block(u8 cs, u32 addr) 263 { 264 int ret; 265 union SFCCMD_DATA sfcmd; 266 u8 status; 267 268 sfcmd.d32 = 0; 269 sfcmd.b.cmd = p_nand_info->block_erase_cmd; 270 sfcmd.b.addrbits = SFC_ADDR_24BITS; 271 sfc_nand_write_en(); 272 ret = sfc_request(sfcmd.d32, 0, addr, NULL); 273 if (ret != SFC_OK) 274 return ret; 275 ret = sfc_nand_wait_busy(&status, 1000 * 1000); 276 if (status & (1 << 2)) 277 return SFC_NAND_PROG_ERASE_ERROR; 278 return ret; 279 } 280 281 static u32 sfc_nand_prog_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare) 282 { 283 int ret; 284 union SFCCMD_DATA sfcmd; 285 union SFCCTRL_DATA sfctrl; 286 u8 status; 287 u32 data_sz = 2048; 288 u32 spare_offs_1 = p_nand_info->spare_offs_1; 289 u32 spare_offs_2 = p_nand_info->spare_offs_2; 290 291 memcpy(gp_page_buf, p_data, data_sz); 292 gp_page_buf[(data_sz + spare_offs_1) / 4] = p_spare[0]; 293 gp_page_buf[(data_sz + spare_offs_2) / 4] = p_spare[1]; 294 295 sfc_nand_write_en(); 296 if (sfc_nand_dev.prog_lines == DATA_LINES_X4 && 297 p_nand_info->QE_address == 0xFF && 298 sfc_get_version() != SFC_VER_3) 299 sfc_nand_rw_preset(); 300 301 sfcmd.d32 = 0; 302 sfcmd.b.cmd = sfc_nand_dev.page_prog_cmd; 303 sfcmd.b.addrbits = SFC_ADDR_XBITS; 304 sfcmd.b.datasize = SFC_NAND_PAGE_MAX_SIZE; 305 sfcmd.b.rw = SFC_WRITE; 306 307 sfctrl.d32 = 0; 308 sfctrl.b.datalines = sfc_nand_dev.prog_lines; 309 sfctrl.b.addrbits = 16; 310 sfc_request(sfcmd.d32, sfctrl.d32, 0, gp_page_buf); 311 312 sfcmd.d32 = 0; 313 sfcmd.b.cmd = p_nand_info->page_prog_cmd; 314 sfcmd.b.addrbits = SFC_ADDR_24BITS; 315 sfcmd.b.datasize = 0; 316 sfcmd.b.rw = SFC_WRITE; 317 ret = sfc_request(sfcmd.d32, 0, addr, p_data); 318 if (ret != SFC_OK) 319 return ret; 320 ret = sfc_nand_wait_busy(&status, 1000 * 1000); 321 if (status & (1 << 3)) 322 return SFC_NAND_PROG_ERASE_ERROR; 323 return ret; 324 } 325 326 static u32 sfc_nand_read_page(u8 cs, u32 addr, u32 *p_data, u32 *p_spare) 327 { 328 int ret; 329 union SFCCMD_DATA sfcmd; 330 union SFCCTRL_DATA sfctrl; 331 u32 ecc_result; 332 u32 data_sz = 2048; 333 u32 spare_offs_1 = p_nand_info->spare_offs_1; 334 u32 spare_offs_2 = p_nand_info->spare_offs_2; 335 336 sfcmd.d32 = 0; 337 sfcmd.b.cmd = p_nand_info->page_read_cmd; 338 sfcmd.b.datasize = 0; 339 sfcmd.b.addrbits = SFC_ADDR_24BITS; 340 sfc_request(sfcmd.d32, 0, addr, p_data); 341 342 if (p_nand_info->ecc_status) 343 ecc_result = p_nand_info->ecc_status(); 344 else 345 ecc_result = sfc_nand_ecc_status(); 346 347 if (sfc_nand_dev.read_lines == DATA_LINES_X4 && 348 p_nand_info->QE_address == 0xFF && 349 sfc_get_version() != SFC_VER_3) 350 sfc_nand_rw_preset(); 351 352 sfcmd.d32 = 0; 353 sfcmd.b.cmd = sfc_nand_dev.page_read_cmd; 354 sfcmd.b.datasize = SFC_NAND_PAGE_MAX_SIZE; 355 sfcmd.b.addrbits = SFC_ADDR_24BITS; 356 sfctrl.d32 = 0; 357 sfctrl.b.datalines = sfc_nand_dev.read_lines; 358 359 memset(gp_page_buf, 0, SFC_NAND_PAGE_MAX_SIZE); 360 ret = sfc_request(sfcmd.d32, sfctrl.d32, 0, gp_page_buf); 361 362 memcpy(p_data, gp_page_buf, data_sz); 363 p_spare[0] = gp_page_buf[(data_sz + spare_offs_1) / 4]; 364 p_spare[1] = gp_page_buf[(data_sz + spare_offs_2) / 4]; 365 if (ret != SFC_OK) 366 return SFC_NAND_ECC_ERROR; 367 368 if (ecc_result != SFC_NAND_ECC_OK) { 369 PRINT_SFC_E("%s[0x%x], ret=0x%x\n", __func__, addr, ecc_result); 370 if (p_data) 371 PRINT_SFC_HEX("data:", p_data, 4, 8); 372 if (p_spare) 373 PRINT_SFC_HEX("spare:", p_spare, 4, 2); 374 } 375 return ecc_result; 376 } 377 378 static int sfc_nand_read_id_raw(u8 *data) 379 { 380 int ret; 381 union SFCCMD_DATA sfcmd; 382 383 sfcmd.d32 = 0; 384 sfcmd.b.cmd = CMD_READ_JEDECID; 385 sfcmd.b.datasize = 3; 386 sfcmd.b.addrbits = SFC_ADDR_XBITS; 387 388 ret = sfc_request(sfcmd.d32, 0x8 << 16, 0, data); 389 390 return ret; 391 } 392 393 /* 394 * Read the 1st page's 1st byte of a phy_blk 395 * If not FF, it's bad blk 396 */ 397 static int sfc_nand_get_bad_block_list(u16 *table, u32 die) 398 { 399 u16 blk; 400 u32 bad_cnt, page; 401 u32 blk_per_die; 402 u32 *pread; 403 u32 *pspare_read; 404 405 PRINT_SFC_E("%s\n", __func__); 406 pread = ftl_malloc(2048); 407 pspare_read = ftl_malloc(8); 408 bad_cnt = 0; 409 blk_per_die = p_nand_info->plane_per_die * 410 p_nand_info->blk_per_plane; 411 for (blk = 0; blk < blk_per_die; blk++) { 412 page = (blk + blk_per_die * die) * 413 p_nand_info->page_per_blk; 414 sfc_nand_read_page(0, page, pread, pspare_read); 415 416 if (pread[0] != 0xFFFFFFFF || 417 pspare_read[0] != 0xFFFFFFFF) { 418 table[bad_cnt++] = blk; 419 PRINT_SFC_E("die[%d], bad_blk[%d]\n", die, blk); 420 } 421 } 422 ftl_free(pread); 423 ftl_free(pspare_read); 424 return (int)bad_cnt; 425 } 426 427 #if SFC_NAND_STRESS_TEST_EN 428 429 #define SFC_NAND_PAGE_SIZE 2048 430 #define SFC_NAND_SPARE_SIZE 8 431 432 static u16 bad_blk_list[1024]; 433 static u32 pwrite[SFC_NAND_PAGE_SIZE / 4]; 434 static u32 pread[SFC_NAND_PAGE_SIZE / 4]; 435 static u32 pspare_write[SFC_NAND_SPARE_SIZE / 4]; 436 static u32 pspare_read[SFC_NAND_SPARE_SIZE / 4]; 437 static u32 bad_blk_num; 438 static u32 bad_page_num; 439 440 static void sfc_nand_test(void) 441 { 442 u32 i, blk, page, bad_cnt, page_addr; 443 int ret; 444 u32 pages_num = 64; 445 u32 blk_addr = 64; 446 u32 is_bad_blk = 0; 447 448 PRINT_SFC_E("%s\n", __func__); 449 450 bad_blk_num = 0; 451 bad_page_num = 0; 452 bad_cnt = sfc_nand_get_bad_block_list(bad_blk_list, 0); 453 454 for (blk = 0; blk < 1024; blk++) { 455 for (i = 0; i < bad_cnt; i++) { 456 if (bad_blk_list[i] == blk) 457 break; 458 } 459 if (i < bad_cnt) 460 continue; 461 is_bad_blk = 0; 462 PRINT_SFC_E("Flash prog block: %x\n", blk); 463 sfc_nand_erase_block(0, blk * blk_addr); 464 for (page = 0; page < pages_num; page++) { 465 page_addr = blk * blk_addr + page; 466 for (i = 0; i < 512; i++) 467 pwrite[i] = (page_addr << 16) + i; 468 pspare_write[0] = pwrite[0] + 0x5AF0; 469 pspare_write[1] = pspare_write[0] + 1; 470 sfc_nand_prog_page(0, page_addr, pwrite, pspare_write); 471 memset(pread, 0, 2048); 472 memset(pspare_read, 0, 8); 473 ret = sfc_nand_read_page(0, page_addr, pread, 474 pspare_read); 475 if (ret != SFC_NAND_ECC_OK) 476 is_bad_blk = 1; 477 for (i = 0; i < 512; i++) { 478 if (pwrite[i] != pread[i]) { 479 is_bad_blk = 1; 480 break; 481 } 482 } 483 for (i = 0; i < 2; i++) { 484 if (pspare_write[i] != pspare_read[i]) { 485 is_bad_blk = 1; 486 break; 487 } 488 } 489 if (is_bad_blk) { 490 bad_page_num++; 491 PRINT_SFC_E("ERR:page%x, ret=%x\n", 492 page_addr, ret); 493 PRINT_SFC_HEX("data:", pread, 4, 8); 494 PRINT_SFC_HEX("spare:", pspare_read, 4, 2); 495 } 496 } 497 sfc_nand_erase_block(0, blk * blk_addr); 498 if (is_bad_blk) 499 bad_blk_num++; 500 } 501 PRINT_SFC_E("bad_blk_num = %d, bad_page_num = %d\n", 502 bad_blk_num, bad_page_num); 503 504 PRINT_SFC_E("Flash Test Finish!!!\n"); 505 while (1) 506 ; 507 } 508 #endif 509 510 static void ftl_flash_init(void) 511 { 512 /* para init */ 513 g_nand_phy_info.nand_type = 1; 514 g_nand_phy_info.die_num = 1; 515 g_nand_phy_info.plane_per_die = p_nand_info->plane_per_die; 516 g_nand_phy_info.blk_per_plane = p_nand_info->blk_per_plane; 517 g_nand_phy_info.page_per_blk = p_nand_info->page_per_blk; 518 g_nand_phy_info.page_per_slc_blk = p_nand_info->page_per_blk; 519 g_nand_phy_info.byte_per_sec = 512; 520 g_nand_phy_info.sec_per_page = p_nand_info->sec_per_page; 521 g_nand_phy_info.sec_per_blk = p_nand_info->sec_per_page * 522 p_nand_info->page_per_blk; 523 g_nand_phy_info.reserved_blk = 8; 524 g_nand_phy_info.blk_per_die = p_nand_info->plane_per_die * 525 p_nand_info->blk_per_plane; 526 g_nand_phy_info.ecc_bits = p_nand_info->max_ecc_bits; 527 528 /* driver register */ 529 g_nand_ops.get_bad_blk_list = sfc_nand_get_bad_block_list; 530 g_nand_ops.erase_blk = sfc_nand_erase_block; 531 g_nand_ops.prog_page = sfc_nand_prog_page; 532 g_nand_ops.read_page = sfc_nand_read_page; 533 } 534 535 static int spi_nand_enable_QE(void) 536 { 537 int ret = SFC_OK; 538 u8 status; 539 int bit_offset = p_nand_info->QE_bits; 540 541 if (bit_offset == 0xFF) 542 return SFC_OK; 543 544 ret = sfc_nand_read_feature(p_nand_info->QE_address, &status); 545 if (ret != SFC_OK) 546 return ret; 547 548 if (status & (1 << bit_offset)) /* is QE bit set */ 549 return SFC_OK; 550 551 status |= (1 << bit_offset); 552 return sfc_nand_write_feature(p_nand_info->QE_address, status); 553 554 return ret; 555 } 556 557 u32 sfc_nand_init(void) 558 { 559 PRINT_SFC_I("...%s enter...\n", __func__); 560 561 sfc_nand_read_id_raw(id_byte); 562 PRINT_SFC_E("sfc_nand id: %x %x %x\n", 563 id_byte[0], id_byte[1], id_byte[2]); 564 if (id_byte[0] == 0xFF || id_byte[0] == 0x00) 565 return FTL_NO_FLASH; 566 567 p_nand_info = spi_nand_get_info(id_byte); 568 if (!p_nand_info) 569 return FTL_UNSUPPORTED_FLASH; 570 571 sfc_nand_dev.manufacturer = id_byte[0]; 572 sfc_nand_dev.mem_type = id_byte[1]; 573 574 /* disable block lock */ 575 sfc_nand_write_feature(0xA0, 0); 576 sfc_nand_dev.read_lines = DATA_LINES_X1; 577 sfc_nand_dev.prog_lines = DATA_LINES_X1; 578 sfc_nand_dev.page_read_cmd = p_nand_info->read_cache_cmd_1; 579 sfc_nand_dev.page_prog_cmd = p_nand_info->prog_cache_cmd_1; 580 if (p_nand_info->feature & FEA_4BIT_READ) { 581 if (spi_nand_enable_QE() == SFC_OK) { 582 sfc_nand_dev.read_lines = DATA_LINES_X4; 583 sfc_nand_dev.page_read_cmd = 584 p_nand_info->read_cache_cmd_4; 585 } 586 } 587 588 if (p_nand_info->feature & FEA_4BIT_PROG && 589 sfc_nand_dev.read_lines == DATA_LINES_X4) { 590 sfc_nand_dev.prog_lines = DATA_LINES_X4; 591 sfc_nand_dev.page_prog_cmd = p_nand_info->prog_cache_cmd_4; 592 } 593 594 if (1) { 595 u8 status; 596 597 sfc_nand_read_feature(0xA0, &status); 598 PRINT_SFC_I("sfc_nand A0 = 0x%x\n", status); 599 sfc_nand_read_feature(0xB0, &status); 600 PRINT_SFC_I("sfc_nand B0 = 0x%x\n", status); 601 sfc_nand_read_feature(0xC0, &status); 602 PRINT_SFC_I("sfc_nand C0 = 0x%x\n", status); 603 PRINT_SFC_I("read_lines = %x\n", sfc_nand_dev.read_lines); 604 PRINT_SFC_I("prog_lines = %x\n", sfc_nand_dev.prog_lines); 605 PRINT_SFC_I("page_read_cmd = %x\n", sfc_nand_dev.page_read_cmd); 606 PRINT_SFC_I("page_prog_cmd = %x\n", sfc_nand_dev.page_prog_cmd); 607 } 608 ftl_flash_init(); 609 610 #if SFC_NAND_STRESS_TEST_EN 611 sfc_nand_test(); 612 #endif 613 614 return SFC_OK; 615 } 616 617 int sfc_nand_read_id(u8 *data) 618 { 619 memcpy(data, id_byte, 3); 620 return 0; 621 } 622