2
0

435-drivers-mtd-spinand-Add-calibration-support-for-spin.patch 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. From 7670ec4a14891a1a182b98a9c403ffbf6b49e4b1 Mon Sep 17 00:00:00 2001
  2. From: "SkyLake.Huang" <[email protected]>
  3. Date: Thu, 23 Jun 2022 18:39:56 +0800
  4. Subject: [PATCH 5/6] drivers: mtd: spinand: Add calibration support for
  5. spinand
  6. Signed-off-by: SkyLake.Huang <[email protected]>
  7. ---
  8. drivers/mtd/nand/spi/core.c | 54 +++++++++++++++++++++++++++++++++++++
  9. 1 file changed, 54 insertions(+)
  10. --- a/drivers/mtd/nand/spi/core.c
  11. +++ b/drivers/mtd/nand/spi/core.c
  12. @@ -978,6 +978,56 @@ static int spinand_manufacturer_match(st
  13. return -ENOTSUPP;
  14. }
  15. +int spinand_cal_read(void *priv, u32 *addr, int addrlen, u8 *buf, int readlen) {
  16. + struct spinand_device *spinand = (struct spinand_device *)priv;
  17. + struct device *dev = &spinand->spimem->spi->dev;
  18. + struct spi_mem_op op = SPINAND_PAGE_READ_FROM_CACHE_OP(false, 0, 1, buf, readlen);
  19. + struct nand_pos pos;
  20. + struct nand_page_io_req req;
  21. + u8 status;
  22. + int ret;
  23. +
  24. + if(addrlen != sizeof(struct nand_addr)/sizeof(unsigned int)) {
  25. + dev_err(dev, "Must provide correct addr(length) for spinand calibration\n");
  26. + return -EINVAL;
  27. + }
  28. +
  29. + ret = spinand_reset_op(spinand);
  30. + if (ret)
  31. + return ret;
  32. +
  33. + /* We should store our golden data in first target because
  34. + * we can't switch target at this moment.
  35. + */
  36. + pos = (struct nand_pos){
  37. + .target = 0,
  38. + .lun = *addr,
  39. + .plane = *(addr+1),
  40. + .eraseblock = *(addr+2),
  41. + .page = *(addr+3),
  42. + };
  43. +
  44. + req = (struct nand_page_io_req){
  45. + .pos = pos,
  46. + .dataoffs = *(addr+4),
  47. + .datalen = readlen,
  48. + .databuf.in = buf,
  49. + .mode = MTD_OPS_AUTO_OOB,
  50. + };
  51. +
  52. + ret = spinand_load_page_op(spinand, &req);
  53. + if (ret)
  54. + return ret;
  55. +
  56. + ret = spinand_wait(spinand, &status);
  57. + if (ret < 0)
  58. + return ret;
  59. +
  60. + ret = spi_mem_exec_op(spinand->spimem, &op);
  61. +
  62. + return 0;
  63. +}
  64. +
  65. static int spinand_id_detect(struct spinand_device *spinand)
  66. {
  67. u8 *id = spinand->id.data;
  68. @@ -1228,6 +1278,10 @@ static int spinand_init(struct spinand_d
  69. if (!spinand->scratchbuf)
  70. return -ENOMEM;
  71. + ret = spi_mem_do_calibration(spinand->spimem, spinand_cal_read, spinand);
  72. + if (ret)
  73. + dev_err(dev, "Failed to calibrate SPI-NAND (err = %d)\n", ret);
  74. +
  75. ret = spinand_detect(spinand);
  76. if (ret)
  77. goto err_free_bufs;