spi_probe.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. /* SPDX-License-Identifier: GPL-2.0-or-later */
  2. /**
  3. ******************************************************************************
  4. * @file spi_probe.c
  5. * @author StarFive Technology
  6. * @version V1.0
  7. * @date 07/24/2020
  8. * @brief
  9. ******************************************************************************
  10. * @copy
  11. *
  12. * THE PRESENT SOFTWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  13. * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  14. * TIME. AS A RESULT, STARFIVE SHALL NOT BE HELD LIABLE FOR ANY
  15. * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  16. * FROM THE CONTENT OF SUCH SOFTWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  17. * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  18. *
  19. * COPYRIGHT 2020 Shanghai StarFive Technology Co., Ltd.
  20. */
  21. #include <comdef.h>
  22. #include <sys.h>
  23. #include <spi_flash.h>
  24. #include <spi_flash_internal.h>
  25. #include <spi.h>
  26. #include <uart.h>
  27. #define IDCODE_CONT_LEN 0
  28. #define IDCODE_PART_LEN 3
  29. #define IDCODE_LEN (IDCODE_CONT_LEN + IDCODE_PART_LEN)
  30. #define CMD_READ_ID 0x9f
  31. #define NOR 0
  32. #define GIGANAND 1
  33. //#define CONFIG_SPI_FLASH_ATMEL
  34. //#define CONFIG_SPI_FLASH_GIGADEVICE
  35. //#define CONFIG_SPI_FLASH_EON
  36. //#define CONFIG_SPI_FLASH_MACRONIX
  37. //#define CONFIG_SPI_FLASH_SPANSION
  38. //#define CONFIG_SPI_FLASH_STMICRO
  39. //#define CONFIG_SPI_FLASH_SST
  40. //#define CONFIG_SPI_FLASH_WINBOND
  41. //#define TEST_GD25Q64B
  42. //#define TEST_GD25Q64C
  43. //#define TEST_GD25LB64C
  44. static struct spi_flash g_spi_flash[1];
  45. static const struct spi_flash_params spi_flash_table[] =
  46. {
  47. {"Common_flash", 0x534654, 8,16,16,256, NOR},
  48. };
  49. struct spi_flash *spi_flash_probe_nor(struct spi_slave *spi, u8 *idcode)
  50. {
  51. struct spi_flash_params *params;
  52. struct spi_flash *flash;
  53. u32 id = 0;
  54. static int i = 0;
  55. #if 0
  56. id = ((idcode[2] << 16) | (idcode[1] << 8) | idcode[0]);
  57. if(id == 0x0)
  58. {
  59. return NULL;
  60. }
  61. params = spi_flash_table;
  62. for (i = 0; spi_flash_table[i].name != NULL; i++)
  63. {
  64. if ((spi_flash_table[i].id & 0xFFFFFF) == id)
  65. {
  66. break;
  67. }
  68. }
  69. #endif
  70. flash = &g_spi_flash[0];
  71. if (!flash)
  72. {
  73. //uart_printf("SF: Failed to allocate memory\r\n");
  74. return NULL;
  75. }
  76. flash->name = spi_flash_table[i].name;
  77. if(spi_flash_table[i].flags == NOR)
  78. {
  79. /* Assuming power-of-two page size initially. */
  80. flash->write = spi_flash_cmd_write_mode;
  81. flash->erase = spi_flash_erase_mode;
  82. flash->read = spi_flash_read_mode;
  83. flash->page_size = 1 << spi_flash_table[i].l2_page_size;
  84. flash->sector_size = flash->page_size * spi_flash_table[i].pages_per_sector;
  85. flash->block_size = flash->sector_size * spi_flash_table[i].sectors_per_block;
  86. flash->size = flash->page_size * spi_flash_table[i].pages_per_sector
  87. * spi_flash_table[i].sectors_per_block
  88. * spi_flash_table[i].nr_blocks;
  89. }
  90. //uart_printf("spi probe complete\r\n");
  91. return flash;
  92. }
  93. #if 1
  94. static int print_id(u8 *idcode, int len)
  95. {
  96. int i;
  97. uart_printf("idcode:0x");
  98. for (i=len-1; i>=0; i--)
  99. print_ubyte_hex(idcode[i]);
  100. uart_printf("\r\n");
  101. return 0;
  102. }
  103. #endif
  104. static int spi_read_id(struct spi_slave *spi, unsigned char cmd, void *response, u32 len)
  105. {
  106. int ret = -1,ret1 = -1,ret2 = -1;
  107. unsigned char buf[4] = {0};// = {(u8)cmd, 0x00, 0x00, 0x00};
  108. unsigned char buf_nor[1]; // = {(u8)cmd};
  109. u8 *idcode = (u8 *)response;
  110. buf[0] = cmd;
  111. buf[1] = 0;
  112. buf[2] = 0;
  113. buf[3] = 0;
  114. buf_nor[0] = cmd;
  115. ret1 = spi_xfer(spi, 1*8, &buf[0], NULL, SPI_XFER_BEGIN, 8);
  116. ret2 = spi_xfer(spi, len*8, NULL, response, SPI_XFER_END, 8);
  117. return 0;
  118. }
  119. static struct spi_flash aic_flash;
  120. struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
  121. unsigned int max_hz, unsigned int mode, unsigned int bus_width)
  122. {
  123. struct spi_slave *spi;
  124. struct spi_flash *flash = &aic_flash;
  125. int ret = 0;
  126. u8 idcode[IDCODE_LEN];
  127. spi = spi_setup_slave(bus, cs, max_hz, mode, bus_width);
  128. if (!spi) {
  129. //uart_printf("SF: Failed to set up slave\n");
  130. return NULL;
  131. }
  132. /* Read the ID codes */
  133. ret = spi_read_id(spi, CMD_READ_ID, idcode, sizeof(idcode));
  134. if (ret)
  135. {
  136. //uart_printf("SF: Failed to read ID : %d\n", ret);
  137. goto err_read_id;
  138. }
  139. print_id(idcode, sizeof(idcode));
  140. flash = spi_flash_probe_nor(spi,idcode);
  141. if (!flash)
  142. {
  143. goto err_manufacturer_probe;
  144. }
  145. flash->spi = spi;
  146. return flash;
  147. err_manufacturer_probe:
  148. err_read_id:
  149. return NULL;
  150. }