nand_amd.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2017 Free Electrons
  4. * Copyright (C) 2017 NextThing Co
  5. *
  6. * Author: Boris Brezillon <[email protected]>
  7. */
  8. #include "internals.h"
  9. static void amd_nand_decode_id(struct nand_chip *chip)
  10. {
  11. struct mtd_info *mtd = nand_to_mtd(chip);
  12. struct nand_memory_organization *memorg;
  13. memorg = nanddev_get_memorg(&chip->base);
  14. nand_decode_ext_id(chip);
  15. /*
  16. * Check for Spansion/AMD ID + repeating 5th, 6th byte since
  17. * some Spansion chips have erasesize that conflicts with size
  18. * listed in nand_ids table.
  19. * Data sheet (5 byte ID): Spansion S30ML-P ORNAND (p.39)
  20. */
  21. if (chip->id.data[4] != 0x00 && chip->id.data[5] == 0x00 &&
  22. chip->id.data[6] == 0x00 && chip->id.data[7] == 0x00 &&
  23. memorg->pagesize == 512) {
  24. memorg->pages_per_eraseblock = 256;
  25. memorg->pages_per_eraseblock <<= ((chip->id.data[3] & 0x03) << 1);
  26. mtd->erasesize = memorg->pages_per_eraseblock *
  27. memorg->pagesize;
  28. }
  29. }
  30. static int amd_nand_init(struct nand_chip *chip)
  31. {
  32. if (nand_is_slc(chip))
  33. /*
  34. * According to the datasheet of some Cypress SLC NANDs,
  35. * the bad block markers can be in the first, second or last
  36. * page of a block. So let's check all three locations.
  37. */
  38. chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE |
  39. NAND_BBM_LASTPAGE;
  40. return 0;
  41. }
  42. const struct nand_manufacturer_ops amd_nand_manuf_ops = {
  43. .detect = amd_nand_decode_id,
  44. .init = amd_nand_init,
  45. };