nand_jedec.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
  4. * 2002-2006 Thomas Gleixner (tglx@linutronix.de)
  5. *
  6. * Credits:
  7. * David Woodhouse for adding multichip support
  8. *
  9. * Aleph One Ltd. and Toby Churchill Ltd. for supporting the
  10. * rework for 2K page size chips
  11. *
  12. * This file contains all ONFI helpers.
  13. */
  14. #include <linux/slab.h>
  15. #include "internals.h"
  16. /*
  17. * Check if the NAND chip is JEDEC compliant, returns 1 if it is, 0 otherwise.
  18. */
  19. int nand_jedec_detect(struct nand_chip *chip)
  20. {
  21. struct mtd_info *mtd = nand_to_mtd(chip);
  22. struct nand_jedec_params *p;
  23. struct jedec_ecc_info *ecc;
  24. int jedec_version = 0;
  25. char id[5];
  26. int i, val, ret;
  27. /* Try JEDEC for unknown chip or LP */
  28. ret = nand_readid_op(chip, 0x40, id, sizeof(id));
  29. if (ret || strncmp(id, "JEDEC", sizeof(id)))
  30. return 0;
  31. /* JEDEC chip: allocate a buffer to hold its parameter page */
  32. p = kzalloc(sizeof(*p), GFP_KERNEL);
  33. if (!p)
  34. return -ENOMEM;
  35. ret = nand_read_param_page_op(chip, 0x40, NULL, 0);
  36. if (ret) {
  37. ret = 0;
  38. goto free_jedec_param_page;
  39. }
  40. for (i = 0; i < 3; i++) {
  41. ret = nand_read_data_op(chip, p, sizeof(*p), true);
  42. if (ret) {
  43. ret = 0;
  44. goto free_jedec_param_page;
  45. }
  46. if (onfi_crc16(ONFI_CRC_BASE, (uint8_t *)p, 510) ==
  47. le16_to_cpu(p->crc))
  48. break;
  49. }
  50. if (i == 3) {
  51. pr_err("Could not find valid JEDEC parameter page; aborting\n");
  52. goto free_jedec_param_page;
  53. }
  54. /* Check version */
  55. val = le16_to_cpu(p->revision);
  56. if (val & (1 << 2))
  57. jedec_version = 10;
  58. else if (val & (1 << 1))
  59. jedec_version = 1; /* vendor specific version */
  60. if (!jedec_version) {
  61. pr_info("unsupported JEDEC version: %d\n", val);
  62. goto free_jedec_param_page;
  63. }
  64. sanitize_string(p->manufacturer, sizeof(p->manufacturer));
  65. sanitize_string(p->model, sizeof(p->model));
  66. chip->parameters.model = kstrdup(p->model, GFP_KERNEL);
  67. if (!chip->parameters.model) {
  68. ret = -ENOMEM;
  69. goto free_jedec_param_page;
  70. }
  71. mtd->writesize = le32_to_cpu(p->byte_per_page);
  72. /* Please reference to the comment for nand_flash_detect_onfi. */
  73. mtd->erasesize = 1 << (fls(le32_to_cpu(p->pages_per_block)) - 1);
  74. mtd->erasesize *= mtd->writesize;
  75. mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page);
  76. /* Please reference to the comment for nand_flash_detect_onfi. */
  77. chip->chipsize = 1 << (fls(le32_to_cpu(p->blocks_per_lun)) - 1);
  78. chip->chipsize *= (uint64_t)mtd->erasesize * p->lun_count;
  79. chip->bits_per_cell = p->bits_per_cell;
  80. if (le16_to_cpu(p->features) & JEDEC_FEATURE_16_BIT_BUS)
  81. chip->options |= NAND_BUSWIDTH_16;
  82. /* ECC info */
  83. ecc = &p->ecc_info[0];
  84. if (ecc->codeword_size >= 9) {
  85. chip->ecc_strength_ds = ecc->ecc_bits;
  86. chip->ecc_step_ds = 1 << ecc->codeword_size;
  87. } else {
  88. pr_warn("Invalid codeword size\n");
  89. }
  90. free_jedec_param_page:
  91. kfree(p);
  92. return ret;
  93. }