spi.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. #pragma once
  2. #include <debug.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <platform/mt_typedefs.h>
  6. #include <platform/mt_reg_base.h>
  7. #include <platform/mt_gpio.h>
  8. #include <platform/sync_write.h>
  9. #include <sys/types.h>
  10. #include <debug.h>
  11. #include <platform/mt_gpt.h>
  12. #define MTK_SPI_ROUNDUP_DIV(a, b) (((a) + ((b)-1)) / (b))
  13. /* #define SPI_EARLY_PORTING */
  14. #define BUS_COUNT 8
  15. enum {
  16. SPI_HZ = 109000000,
  17. MTK_FIFO_DEPTH = 32,
  18. MTK_PACKET_SIZE = 1024,
  19. MTK_TXRX_TIMEOUT_US = 10*1000*1000,
  20. MTK_ARBITRARY_VALUE = 0xdadadada
  21. };
  22. enum {
  23. MTK_SPI_IDLE = 0,
  24. MTK_SPI_PAUSE_IDLE = 1
  25. };
  26. enum {
  27. MTK_SPI_BUSY_STATUS = 0x01,
  28. MTK_SPI_PAUSE_FINISH_INT_STATUS = 3
  29. };
  30. /* SPI_CFG0_REG */
  31. enum {
  32. SPI_CFG0_CS_HOLD_OFFSET = 0,
  33. SPI_CFG0_CS_SETUP_OFFSET = 16,
  34. };
  35. /*SPI_CFG1_REG*/
  36. enum {
  37. SPI_CFG1_CS_IDLE_SHIFT = 0,
  38. SPI_CFG1_PACKET_LOOP_SHIFT = 8,
  39. SPI_CFG1_PACKET_LENGTH_SHIFT = 16,
  40. SPI_CFG1_GET_TICK_DLY_SHIFT = 29,
  41. SPI_CFG1_CS_IDLE_MASK = 0xff << SPI_CFG1_CS_IDLE_SHIFT,
  42. SPI_CFG1_PACKET_LOOP_MASK = 0xff << SPI_CFG1_PACKET_LOOP_SHIFT,
  43. SPI_CFG1_PACKET_LENGTH_MASK = 0x3ff << SPI_CFG1_PACKET_LENGTH_SHIFT,
  44. SPI_CFG1_GET_TICK_DLY_MASK = 0x7 << SPI_CFG1_GET_TICK_DLY_SHIFT,
  45. };
  46. /*SPI_CFG2_REG*/
  47. enum {
  48. SPI_CFG2_SCK_HIGH_OFFSET = 0,
  49. SPI_CFG2_SCK_LOW_OFFSET = 16,
  50. };
  51. enum {
  52. SPI_CMD_ACT_SHIFT = 0,
  53. SPI_CMD_RESUME_SHIFT = 1,
  54. SPI_CMD_RST_SHIFT = 2,
  55. SPI_CMD_PAUSE_EN_SHIFT = 4,
  56. SPI_CMD_DEASSERT_SHIFT = 5,
  57. SPI_CMD_SAMPLE_SEL_SHIFT = 6,
  58. SPI_CMD_CS_POL_SHIFT = 7,
  59. SPI_CMD_CPHA_SHIFT = 8,
  60. SPI_CMD_CPOL_SHIFT = 9,
  61. SPI_CMD_RX_DMA_SHIFT = 10,
  62. SPI_CMD_TX_DMA_SHIFT = 11,
  63. SPI_CMD_TXMSBF_SHIFT = 12,
  64. SPI_CMD_RXMSBF_SHIFT = 13,
  65. SPI_CMD_RX_ENDIAN_SHIFT = 14,
  66. SPI_CMD_TX_ENDIAN_SHIFT = 15,
  67. SPI_CMD_FINISH_IE_SHIFT = 16,
  68. SPI_CMD_PAUSE_IE_SHIFT = 17,
  69. SPI_CMD_ACT_EN = 1 << SPI_CMD_ACT_SHIFT,
  70. SPI_CMD_RESUME_EN = 1 << SPI_CMD_RESUME_SHIFT,
  71. SPI_CMD_RST_EN = 1 << SPI_CMD_RST_SHIFT,
  72. SPI_CMD_PAUSE_EN = 1 << SPI_CMD_PAUSE_EN_SHIFT,
  73. SPI_CMD_DEASSERT_EN = 1 << SPI_CMD_DEASSERT_SHIFT,
  74. SPI_CMD_CPHA_EN = 1 << SPI_CMD_CPHA_SHIFT,
  75. SPI_CMD_CPOL_EN = 1 << SPI_CMD_CPOL_SHIFT,
  76. SPI_CMD_RX_DMA_EN = 1 << SPI_CMD_RX_DMA_SHIFT,
  77. SPI_CMD_TX_DMA_EN = 1 << SPI_CMD_TX_DMA_SHIFT,
  78. SPI_CMD_TXMSBF_EN = 1 << SPI_CMD_TXMSBF_SHIFT,
  79. SPI_CMD_RXMSBF_EN = 1 << SPI_CMD_RXMSBF_SHIFT,
  80. SPI_CMD_RX_ENDIAN_EN = 1 << SPI_CMD_RX_ENDIAN_SHIFT,
  81. SPI_CMD_TX_ENDIAN_EN = 1 << SPI_CMD_TX_ENDIAN_SHIFT,
  82. SPI_CMD_FINISH_IE_EN = 1 << SPI_CMD_FINISH_IE_SHIFT,
  83. SPI_CMD_PAUSE_IE_EN = 1 << SPI_CMD_PAUSE_IE_SHIFT,
  84. };
  85. /* SPI peripheral register map. */
  86. struct mtk_spi_regs {
  87. unsigned int spi_cfg0_reg;
  88. unsigned int spi_cfg1_reg;
  89. unsigned int spi_tx_src_reg;
  90. unsigned int spi_rx_dst_reg;
  91. unsigned int spi_tx_data_reg;
  92. unsigned int spi_rx_data_reg;
  93. unsigned int spi_cmd_reg;
  94. unsigned int spi_status0_reg;
  95. unsigned int spi_status1_reg;
  96. unsigned int spi_pad_sel_reg;
  97. unsigned int spi_cfg2_reg;
  98. unsigned int spi_tx_src_reg_64;
  99. unsigned int spi_rx_dst_reg_64;
  100. };
  101. struct mtk_spi_bus {
  102. struct mtk_spi_regs *reg_addr;
  103. uint32_t state;
  104. uint32_t spi_bus_fdt_offset;
  105. uint32_t pad_select;
  106. };
  107. struct mtk_spi_bus_config {
  108. #define SPI_CPHA 0x01
  109. #define SPI_CPOL 0x02
  110. u32 spi_mode;
  111. u32 tick_delay;
  112. };
  113. struct spi_transfer {
  114. void *tx_buf;
  115. void *rx_buf;
  116. u32 len;
  117. u32 speed_hz;
  118. u32 cs_change;
  119. u32 tick_delay;
  120. };
  121. void mtk_spi_init(int bus_num, struct mtk_spi_bus_config *spi_config);
  122. int init_spi_bus_from_dt(const char *compatible,
  123. struct mtk_spi_bus_config *config);
  124. int spi_sync(int bus_num, struct spi_transfer *transfer);