sf_probe.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * SPI flash probing
  4. *
  5. * Copyright (C) 2008 Atmel Corporation
  6. * Copyright (C) 2010 Reinhard Meyer, EMK Elektronik
  7. * Copyright (C) 2013 Jagannadha Sutradharudu Teki, Xilinx Inc.
  8. */
  9. #include <common.h>
  10. #include <dm.h>
  11. #include <errno.h>
  12. #include <malloc.h>
  13. #include <spi.h>
  14. #include <spi_flash.h>
  15. #include "sf_internal.h"
  16. /**
  17. * spi_flash_probe_slave() - Probe for a SPI flash device on a bus
  18. *
  19. * @flashp: Pointer to place to put flash info, which may be NULL if the
  20. * space should be allocated
  21. */
  22. static int spi_flash_probe_slave(struct spi_flash *flash)
  23. {
  24. struct spi_slave *spi = flash->spi;
  25. int ret;
  26. /* Setup spi_slave */
  27. if (!spi) {
  28. printf("SF: Failed to set up slave\n");
  29. return -ENODEV;
  30. }
  31. /* Claim spi bus */
  32. ret = spi_claim_bus(spi);
  33. if (ret) {
  34. debug("SF: Failed to claim SPI bus: %d\n", ret);
  35. return ret;
  36. }
  37. ret = spi_nor_scan(flash);
  38. if (ret)
  39. goto err_read_id;
  40. #if CONFIG_IS_ENABLED(SPI_FLASH_MTD)
  41. ret = spi_flash_mtd_register(flash);
  42. #endif
  43. err_read_id:
  44. spi_release_bus(spi);
  45. return ret;
  46. }
  47. #ifndef CONFIG_DM_SPI_FLASH
  48. struct spi_flash *spi_flash_probe(unsigned int busnum, unsigned int cs,
  49. unsigned int max_hz, unsigned int spi_mode)
  50. {
  51. struct spi_slave *bus;
  52. struct spi_flash *flash;
  53. bus = spi_setup_slave(busnum, cs, max_hz, spi_mode);
  54. if (!bus)
  55. return NULL;
  56. /* Allocate space if needed (not used by sf-uclass */
  57. flash = calloc(1, sizeof(*flash));
  58. if (!flash) {
  59. debug("SF: Failed to allocate spi_flash\n");
  60. return NULL;
  61. }
  62. flash->spi = bus;
  63. if (spi_flash_probe_slave(flash)) {
  64. spi_free_slave(bus);
  65. free(flash);
  66. return NULL;
  67. }
  68. return flash;
  69. }
  70. void spi_flash_free(struct spi_flash *flash)
  71. {
  72. #if CONFIG_IS_ENABLED(SPI_FLASH_MTD)
  73. spi_flash_mtd_unregister();
  74. #endif
  75. spi_free_slave(flash->spi);
  76. free(flash);
  77. }
  78. #else /* defined CONFIG_DM_SPI_FLASH */
  79. static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len,
  80. void *buf)
  81. {
  82. struct spi_flash *flash = dev_get_uclass_priv(dev);
  83. struct mtd_info *mtd = &flash->mtd;
  84. size_t retlen;
  85. return log_ret(mtd->_read(mtd, offset, len, &retlen, buf));
  86. }
  87. static int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len,
  88. const void *buf)
  89. {
  90. struct spi_flash *flash = dev_get_uclass_priv(dev);
  91. struct mtd_info *mtd = &flash->mtd;
  92. size_t retlen;
  93. return mtd->_write(mtd, offset, len, &retlen, buf);
  94. }
  95. static int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len)
  96. {
  97. struct spi_flash *flash = dev_get_uclass_priv(dev);
  98. struct mtd_info *mtd = &flash->mtd;
  99. struct erase_info instr;
  100. if (offset % mtd->erasesize || len % mtd->erasesize) {
  101. printf("SF: Erase offset/length not multiple of erase size\n");
  102. return -EINVAL;
  103. }
  104. memset(&instr, 0, sizeof(instr));
  105. instr.addr = offset;
  106. instr.len = len;
  107. return mtd->_erase(mtd, &instr);
  108. }
  109. static int spi_flash_std_get_sw_write_prot(struct udevice *dev)
  110. {
  111. struct spi_flash *flash = dev_get_uclass_priv(dev);
  112. return spi_flash_cmd_get_sw_write_prot(flash);
  113. }
  114. int spi_flash_std_probe(struct udevice *dev)
  115. {
  116. struct spi_slave *slave = dev_get_parent_priv(dev);
  117. struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
  118. struct spi_flash *flash;
  119. flash = dev_get_uclass_priv(dev);
  120. flash->dev = dev;
  121. flash->spi = slave;
  122. debug("%s: slave=%p, cs=%d\n", __func__, slave, plat->cs);
  123. return spi_flash_probe_slave(flash);
  124. }
  125. static int spi_flash_std_remove(struct udevice *dev)
  126. {
  127. #if CONFIG_IS_ENABLED(SPI_FLASH_MTD)
  128. spi_flash_mtd_unregister();
  129. #endif
  130. return 0;
  131. }
  132. static const struct dm_spi_flash_ops spi_flash_std_ops = {
  133. .read = spi_flash_std_read,
  134. .write = spi_flash_std_write,
  135. .erase = spi_flash_std_erase,
  136. .get_sw_write_prot = spi_flash_std_get_sw_write_prot,
  137. };
  138. static const struct udevice_id spi_flash_std_ids[] = {
  139. { .compatible = "jedec,spi-nor" },
  140. { }
  141. };
  142. U_BOOT_DRIVER(spi_flash_std) = {
  143. .name = "spi_flash_std",
  144. .id = UCLASS_SPI_FLASH,
  145. .of_match = spi_flash_std_ids,
  146. .probe = spi_flash_std_probe,
  147. .remove = spi_flash_std_remove,
  148. .priv_auto_alloc_size = sizeof(struct spi_flash),
  149. .ops = &spi_flash_std_ops,
  150. };
  151. #endif /* CONFIG_DM_SPI_FLASH */