flash_dq_mode.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include <drivers/flash.h>
  2. #include <drivers/spi.h>
  3. #include <logging/log.h>
  4. #include <soc.h>
  5. #include "spi_flash.h"
  6. extern void xspi_nor_enable_status_qe(struct spinor_info *sni);
  7. #define SPI_CTL_AHB_REQ (1<<8)
  8. #define SPI_STATUS_READY (1<<8)
  9. #define SPI_CTL_ADDR_MODE_MASK (1<<27)
  10. #define SPI_CTL_ADDR_MODE_2X4X (0<<27)
  11. #define SPI_CTL_ADDR_MODE_DUAL_QUAD (1<<27)
  12. static inline void spi_delay(void)
  13. {
  14. volatile int i = 100000;
  15. while (i--)
  16. ;
  17. }
  18. static inline void spi_setup_bus_width(struct spinor_info *sni, u8_t bus_width)
  19. {
  20. struct acts_spi_reg *spi= (struct acts_spi_reg *)sni->spi.base;
  21. spi->ctrl = (spi->ctrl & ~(0x3 << 10)) | (((bus_width & 0x7) / 2 + 1) << 10);
  22. spi_delay();
  23. }
  24. __ramfunc static void _nor_set_spi_read_mode(struct spinor_info *sni)
  25. {
  26. struct spi_info *si = (struct spi_info *)&sni->spi;
  27. if(sni->spi.bus_width == 4) {
  28. printk("nor is 4 line mode\n");
  29. xspi_nor_enable_status_qe(sni);
  30. /* enable 4x mode */
  31. spi_setup_bus_width(sni, 4);
  32. } else if(sni->spi.bus_width == 2) {
  33. printk("nor is 2 line mode\n");
  34. /* enable 2x mode */
  35. spi_setup_bus_width(sni, 2);
  36. } else {
  37. sni->spi.bus_width = 1;
  38. printk("nor is 1 line mode\n");
  39. /* enable 1x mode */
  40. spi_setup_bus_width(sni, 1);
  41. }
  42. }
  43. #define COMPARE_BYTES (32)
  44. void _nor_read_mode_try(struct spinor_info *sni, unsigned char bus_width)
  45. {
  46. u8_t temp_data[COMPARE_BYTES], src_data[COMPARE_BYTES];
  47. printk("_nor_read_mode_try:%d bit bus width\n", bus_width);
  48. sni->spi.bus_width = 1;
  49. sni->spi.flag &= ~SPI_FLAG_SPI_4XIO;
  50. memset(src_data, 0xff, COMPARE_BYTES);
  51. p_spinor_api->read(sni, 0, src_data, COMPARE_BYTES);
  52. /* try io mode */
  53. sni->spi.bus_width = bus_width;
  54. sni->spi.flag |= SPI_FLAG_SPI_4XIO;
  55. if (sni->spi.bus_width == 4) {
  56. xspi_nor_enable_status_qe(sni);
  57. }
  58. memset(temp_data, 0x00, COMPARE_BYTES);
  59. p_spinor_api->read(sni, 0, temp_data, COMPARE_BYTES);
  60. if (memcmp(temp_data, src_data, COMPARE_BYTES) == 0) {
  61. return ;
  62. }
  63. /* try output mode */
  64. sni->spi.flag &= ~SPI_FLAG_SPI_4XIO;
  65. memset(temp_data, 0x00, COMPARE_BYTES);
  66. p_spinor_api->read(sni, 0, temp_data, COMPARE_BYTES);
  67. if (memcmp(temp_data, src_data, COMPARE_BYTES) != 0) {
  68. sni->spi.bus_width = 1;
  69. }
  70. }
  71. void nor_dual_quad_read_mode_try(struct spinor_info *sni)
  72. {
  73. if(sni->spi.bus_width == 4) {
  74. _nor_read_mode_try(sni, 4);
  75. } else if(sni->spi.bus_width == 2) {
  76. _nor_read_mode_try(sni, 2);
  77. }
  78. _nor_set_spi_read_mode(sni);
  79. }