internal.h 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. /* SPDX-License-Identifier: GPL-2.0 */
  2. /*
  3. * Copyright (c) 2022, Linaro Ltd.
  4. *
  5. */
  6. #ifndef _MHI_EP_INTERNAL_
  7. #define _MHI_EP_INTERNAL_
  8. #include <linux/bitfield.h>
  9. #include "../common.h"
  10. extern struct bus_type mhi_ep_bus_type;
  11. #define MHI_REG_OFFSET 0x100
  12. #define BHI_REG_OFFSET 0x200
  13. /* MHI registers */
  14. #define EP_MHIREGLEN (MHI_REG_OFFSET + MHIREGLEN)
  15. #define EP_MHIVER (MHI_REG_OFFSET + MHIVER)
  16. #define EP_MHICFG (MHI_REG_OFFSET + MHICFG)
  17. #define EP_CHDBOFF (MHI_REG_OFFSET + CHDBOFF)
  18. #define EP_ERDBOFF (MHI_REG_OFFSET + ERDBOFF)
  19. #define EP_BHIOFF (MHI_REG_OFFSET + BHIOFF)
  20. #define EP_BHIEOFF (MHI_REG_OFFSET + BHIEOFF)
  21. #define EP_DEBUGOFF (MHI_REG_OFFSET + DEBUGOFF)
  22. #define EP_MHICTRL (MHI_REG_OFFSET + MHICTRL)
  23. #define EP_MHISTATUS (MHI_REG_OFFSET + MHISTATUS)
  24. #define EP_CCABAP_LOWER (MHI_REG_OFFSET + CCABAP_LOWER)
  25. #define EP_CCABAP_HIGHER (MHI_REG_OFFSET + CCABAP_HIGHER)
  26. #define EP_ECABAP_LOWER (MHI_REG_OFFSET + ECABAP_LOWER)
  27. #define EP_ECABAP_HIGHER (MHI_REG_OFFSET + ECABAP_HIGHER)
  28. #define EP_CRCBAP_LOWER (MHI_REG_OFFSET + CRCBAP_LOWER)
  29. #define EP_CRCBAP_HIGHER (MHI_REG_OFFSET + CRCBAP_HIGHER)
  30. #define EP_CRDB_LOWER (MHI_REG_OFFSET + CRDB_LOWER)
  31. #define EP_CRDB_HIGHER (MHI_REG_OFFSET + CRDB_HIGHER)
  32. #define EP_MHICTRLBASE_LOWER (MHI_REG_OFFSET + MHICTRLBASE_LOWER)
  33. #define EP_MHICTRLBASE_HIGHER (MHI_REG_OFFSET + MHICTRLBASE_HIGHER)
  34. #define EP_MHICTRLLIMIT_LOWER (MHI_REG_OFFSET + MHICTRLLIMIT_LOWER)
  35. #define EP_MHICTRLLIMIT_HIGHER (MHI_REG_OFFSET + MHICTRLLIMIT_HIGHER)
  36. #define EP_MHIDATABASE_LOWER (MHI_REG_OFFSET + MHIDATABASE_LOWER)
  37. #define EP_MHIDATABASE_HIGHER (MHI_REG_OFFSET + MHIDATABASE_HIGHER)
  38. #define EP_MHIDATALIMIT_LOWER (MHI_REG_OFFSET + MHIDATALIMIT_LOWER)
  39. #define EP_MHIDATALIMIT_HIGHER (MHI_REG_OFFSET + MHIDATALIMIT_HIGHER)
  40. /* MHI BHI registers */
  41. #define EP_BHI_INTVEC (BHI_REG_OFFSET + BHI_INTVEC)
  42. #define EP_BHI_EXECENV (BHI_REG_OFFSET + BHI_EXECENV)
  43. /* MHI Doorbell registers */
  44. #define CHDB_LOWER_n(n) (0x400 + 0x8 * (n))
  45. #define CHDB_HIGHER_n(n) (0x404 + 0x8 * (n))
  46. #define ERDB_LOWER_n(n) (0x800 + 0x8 * (n))
  47. #define ERDB_HIGHER_n(n) (0x804 + 0x8 * (n))
  48. #define MHI_CTRL_INT_STATUS 0x4
  49. #define MHI_CTRL_INT_STATUS_MSK BIT(0)
  50. #define MHI_CTRL_INT_STATUS_CRDB_MSK BIT(1)
  51. #define MHI_CHDB_INT_STATUS_n(n) (0x28 + 0x4 * (n))
  52. #define MHI_ERDB_INT_STATUS_n(n) (0x38 + 0x4 * (n))
  53. #define MHI_CTRL_INT_CLEAR 0x4c
  54. #define MHI_CTRL_INT_MMIO_WR_CLEAR BIT(2)
  55. #define MHI_CTRL_INT_CRDB_CLEAR BIT(1)
  56. #define MHI_CTRL_INT_CRDB_MHICTRL_CLEAR BIT(0)
  57. #define MHI_CHDB_INT_CLEAR_n(n) (0x70 + 0x4 * (n))
  58. #define MHI_CHDB_INT_CLEAR_n_CLEAR_ALL GENMASK(31, 0)
  59. #define MHI_ERDB_INT_CLEAR_n(n) (0x80 + 0x4 * (n))
  60. #define MHI_ERDB_INT_CLEAR_n_CLEAR_ALL GENMASK(31, 0)
  61. /*
  62. * Unlike the usual "masking" convention, writing "1" to a bit in this register
  63. * enables the interrupt and writing "0" will disable it..
  64. */
  65. #define MHI_CTRL_INT_MASK 0x94
  66. #define MHI_CTRL_INT_MASK_MASK GENMASK(1, 0)
  67. #define MHI_CTRL_MHICTRL_MASK BIT(0)
  68. #define MHI_CTRL_CRDB_MASK BIT(1)
  69. #define MHI_CHDB_INT_MASK_n(n) (0xb8 + 0x4 * (n))
  70. #define MHI_CHDB_INT_MASK_n_EN_ALL GENMASK(31, 0)
  71. #define MHI_ERDB_INT_MASK_n(n) (0xc8 + 0x4 * (n))
  72. #define MHI_ERDB_INT_MASK_n_EN_ALL GENMASK(31, 0)
  73. #define NR_OF_CMD_RINGS 1
  74. #define MHI_MASK_ROWS_CH_DB 4
  75. #define MHI_MASK_ROWS_EV_DB 4
  76. #define MHI_MASK_CH_LEN 32
  77. #define MHI_MASK_EV_LEN 32
  78. /* Generic context */
  79. struct mhi_generic_ctx {
  80. __le32 reserved0;
  81. __le32 reserved1;
  82. __le32 reserved2;
  83. __le64 rbase __packed __aligned(4);
  84. __le64 rlen __packed __aligned(4);
  85. __le64 rp __packed __aligned(4);
  86. __le64 wp __packed __aligned(4);
  87. };
  88. enum mhi_ep_ring_type {
  89. RING_TYPE_CMD,
  90. RING_TYPE_ER,
  91. RING_TYPE_CH,
  92. };
  93. /* Ring element */
  94. union mhi_ep_ring_ctx {
  95. struct mhi_cmd_ctxt cmd;
  96. struct mhi_event_ctxt ev;
  97. struct mhi_chan_ctxt ch;
  98. struct mhi_generic_ctx generic;
  99. };
  100. struct mhi_ep_ring_item {
  101. struct list_head node;
  102. struct mhi_ep_ring *ring;
  103. };
  104. struct mhi_ep_ring {
  105. struct mhi_ep_cntrl *mhi_cntrl;
  106. union mhi_ep_ring_ctx *ring_ctx;
  107. struct mhi_ring_element *ring_cache;
  108. enum mhi_ep_ring_type type;
  109. u64 rbase;
  110. size_t rd_offset;
  111. size_t wr_offset;
  112. size_t ring_size;
  113. u32 db_offset_h;
  114. u32 db_offset_l;
  115. u32 ch_id;
  116. u32 er_index;
  117. u32 irq_vector;
  118. bool started;
  119. };
  120. struct mhi_ep_cmd {
  121. struct mhi_ep_ring ring;
  122. };
  123. struct mhi_ep_event {
  124. struct mhi_ep_ring ring;
  125. };
  126. struct mhi_ep_state_transition {
  127. struct list_head node;
  128. enum mhi_state state;
  129. };
  130. struct mhi_ep_chan {
  131. char *name;
  132. struct mhi_ep_device *mhi_dev;
  133. struct mhi_ep_ring ring;
  134. struct mutex lock;
  135. void (*xfer_cb)(struct mhi_ep_device *mhi_dev, struct mhi_result *result);
  136. enum mhi_ch_state state;
  137. enum dma_data_direction dir;
  138. u64 tre_loc;
  139. u32 tre_size;
  140. u32 tre_bytes_left;
  141. u32 chan;
  142. bool skip_td;
  143. };
  144. /* MHI Ring related functions */
  145. void mhi_ep_ring_init(struct mhi_ep_ring *ring, enum mhi_ep_ring_type type, u32 id);
  146. void mhi_ep_ring_reset(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring);
  147. int mhi_ep_ring_start(struct mhi_ep_cntrl *mhi_cntrl, struct mhi_ep_ring *ring,
  148. union mhi_ep_ring_ctx *ctx);
  149. size_t mhi_ep_ring_addr2offset(struct mhi_ep_ring *ring, u64 ptr);
  150. int mhi_ep_ring_add_element(struct mhi_ep_ring *ring, struct mhi_ring_element *element);
  151. void mhi_ep_ring_inc_index(struct mhi_ep_ring *ring);
  152. int mhi_ep_update_wr_offset(struct mhi_ep_ring *ring);
  153. /* MMIO related functions */
  154. u32 mhi_ep_mmio_read(struct mhi_ep_cntrl *mhi_cntrl, u32 offset);
  155. void mhi_ep_mmio_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 val);
  156. void mhi_ep_mmio_masked_write(struct mhi_ep_cntrl *mhi_cntrl, u32 offset, u32 mask, u32 val);
  157. u32 mhi_ep_mmio_masked_read(struct mhi_ep_cntrl *dev, u32 offset, u32 mask);
  158. void mhi_ep_mmio_enable_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl);
  159. void mhi_ep_mmio_disable_ctrl_interrupt(struct mhi_ep_cntrl *mhi_cntrl);
  160. void mhi_ep_mmio_enable_cmdb_interrupt(struct mhi_ep_cntrl *mhi_cntrl);
  161. void mhi_ep_mmio_disable_cmdb_interrupt(struct mhi_ep_cntrl *mhi_cntrl);
  162. void mhi_ep_mmio_enable_chdb(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id);
  163. void mhi_ep_mmio_disable_chdb(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id);
  164. void mhi_ep_mmio_enable_chdb_interrupts(struct mhi_ep_cntrl *mhi_cntrl);
  165. bool mhi_ep_mmio_read_chdb_status_interrupts(struct mhi_ep_cntrl *mhi_cntrl);
  166. void mhi_ep_mmio_mask_interrupts(struct mhi_ep_cntrl *mhi_cntrl);
  167. void mhi_ep_mmio_get_chc_base(struct mhi_ep_cntrl *mhi_cntrl);
  168. void mhi_ep_mmio_get_erc_base(struct mhi_ep_cntrl *mhi_cntrl);
  169. void mhi_ep_mmio_get_crc_base(struct mhi_ep_cntrl *mhi_cntrl);
  170. u64 mhi_ep_mmio_get_db(struct mhi_ep_ring *ring);
  171. void mhi_ep_mmio_set_env(struct mhi_ep_cntrl *mhi_cntrl, u32 value);
  172. void mhi_ep_mmio_clear_reset(struct mhi_ep_cntrl *mhi_cntrl);
  173. void mhi_ep_mmio_reset(struct mhi_ep_cntrl *mhi_cntrl);
  174. void mhi_ep_mmio_get_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state *state,
  175. bool *mhi_reset);
  176. void mhi_ep_mmio_init(struct mhi_ep_cntrl *mhi_cntrl);
  177. void mhi_ep_mmio_update_ner(struct mhi_ep_cntrl *mhi_cntrl);
  178. /* MHI EP core functions */
  179. int mhi_ep_send_state_change_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state state);
  180. int mhi_ep_send_ee_event(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_ee_type exec_env);
  181. bool mhi_ep_check_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state cur_mhi_state,
  182. enum mhi_state mhi_state);
  183. int mhi_ep_set_mhi_state(struct mhi_ep_cntrl *mhi_cntrl, enum mhi_state mhi_state);
  184. int mhi_ep_set_m0_state(struct mhi_ep_cntrl *mhi_cntrl);
  185. int mhi_ep_set_m3_state(struct mhi_ep_cntrl *mhi_cntrl);
  186. int mhi_ep_set_ready_state(struct mhi_ep_cntrl *mhi_cntrl);
  187. void mhi_ep_handle_syserr(struct mhi_ep_cntrl *mhi_cntrl);
  188. void mhi_ep_resume_channels(struct mhi_ep_cntrl *mhi_cntrl);
  189. void mhi_ep_suspend_channels(struct mhi_ep_cntrl *mhi_cntrl);
  190. #endif