nand_esmt.c 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2018 Toradex AG
  4. *
  5. * Author: Marcel Ziswiler <marcel.ziswiler@toradex.com>
  6. */
  7. #include <linux/mtd/rawnand.h>
  8. #include "internals.h"
  9. static void esmt_nand_decode_id(struct nand_chip *chip)
  10. {
  11. struct nand_device *base = &chip->base;
  12. struct nand_ecc_props requirements = {};
  13. nand_decode_ext_id(chip);
  14. /* Extract ECC requirements from 5th id byte. */
  15. if (chip->id.len >= 5 && nand_is_slc(chip)) {
  16. requirements.step_size = 512;
  17. switch (chip->id.data[4] & 0x3) {
  18. case 0x0:
  19. requirements.strength = 4;
  20. break;
  21. case 0x1:
  22. requirements.strength = 2;
  23. break;
  24. case 0x2:
  25. requirements.strength = 1;
  26. break;
  27. default:
  28. WARN(1, "Could not get ECC info");
  29. requirements.step_size = 0;
  30. break;
  31. }
  32. }
  33. nanddev_set_ecc_requirements(base, &requirements);
  34. }
  35. static int esmt_nand_init(struct nand_chip *chip)
  36. {
  37. if (nand_is_slc(chip))
  38. /*
  39. * It is known that some ESMT SLC NANDs have been shipped
  40. * with the factory bad block markers in the first or last page
  41. * of the block, instead of the first or second page. To be on
  42. * the safe side, let's check all three locations.
  43. */
  44. chip->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE |
  45. NAND_BBM_LASTPAGE;
  46. return 0;
  47. }
  48. const struct nand_manufacturer_ops esmt_nand_manuf_ops = {
  49. .detect = esmt_nand_decode_id,
  50. .init = esmt_nand_init,
  51. };