18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2017 Free Electrons 48c2ecf20Sopenharmony_ci * Copyright (C) 2017 NextThing Co 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Author: Boris Brezillon <boris.brezillon@free-electrons.com> 78c2ecf20Sopenharmony_ci */ 88c2ecf20Sopenharmony_ci 98c2ecf20Sopenharmony_ci#include "internals.h" 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_cistatic void amd_nand_decode_id(struct nand_chip *chip) 128c2ecf20Sopenharmony_ci{ 138c2ecf20Sopenharmony_ci struct mtd_info *mtd = nand_to_mtd(chip); 148c2ecf20Sopenharmony_ci struct nand_memory_organization *memorg; 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci memorg = nanddev_get_memorg(&chip->base); 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci nand_decode_ext_id(chip); 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci /* 218c2ecf20Sopenharmony_ci * Check for Spansion/AMD ID + repeating 5th, 6th byte since 228c2ecf20Sopenharmony_ci * some Spansion chips have erasesize that conflicts with size 238c2ecf20Sopenharmony_ci * listed in nand_ids table. 248c2ecf20Sopenharmony_ci * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39) 258c2ecf20Sopenharmony_ci */ 268c2ecf20Sopenharmony_ci if (chip->id.data[4] != 0x00 && chip->id.data[5] == 0x00 && 278c2ecf20Sopenharmony_ci chip->id.data[6] == 0x00 && chip->id.data[7] == 0x00 && 288c2ecf20Sopenharmony_ci memorg->pagesize == 512) { 298c2ecf20Sopenharmony_ci memorg->pages_per_eraseblock = 256; 308c2ecf20Sopenharmony_ci memorg->pages_per_eraseblock <<= ((chip->id.data[3] & 0x03) << 1); 318c2ecf20Sopenharmony_ci mtd->erasesize = memorg->pages_per_eraseblock * 328c2ecf20Sopenharmony_ci memorg->pagesize; 338c2ecf20Sopenharmony_ci } 348c2ecf20Sopenharmony_ci} 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_cistatic int amd_nand_init(struct nand_chip *chip) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci if (nand_is_slc(chip)) 398c2ecf20Sopenharmony_ci /* 408c2ecf20Sopenharmony_ci * According to the datasheet of some Cypress SLC NANDs, 418c2ecf20Sopenharmony_ci * the bad block markers can be in the first, second or last 428c2ecf20Sopenharmony_ci * page of a block. So let's check all three locations. 438c2ecf20Sopenharmony_ci */ 448c2ecf20Sopenharmony_ci chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE | 458c2ecf20Sopenharmony_ci NAND_BBM_LASTPAGE; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci return 0; 488c2ecf20Sopenharmony_ci} 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ciconst struct nand_manufacturer_ops amd_nand_manuf_ops = { 518c2ecf20Sopenharmony_ci .detect = amd_nand_decode_id, 528c2ecf20Sopenharmony_ci .init = amd_nand_init, 538c2ecf20Sopenharmony_ci}; 54