misc.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved. */
  3. #ifndef _MHI_CORE_MISC_H_
  4. #define _MHI_CORE_MISC_H_
  5. #include <linux/mhi_misc.h>
  6. #include <linux/msm_pcie.h>
  7. #define MHI_FORCE_WAKE_DELAY_US (100)
  8. #define MHI_IPC_LOG_PAGES (100)
  9. #define MAX_RDDM_TABLE_SIZE (12)
  10. #define MHI_REG_SIZE (SZ_4K)
  11. #define REG_WRITE_QUEUE_LEN 512
  12. /* MHI misc capability registers */
  13. #define MISC_OFFSET (0x24)
  14. #define MISC_CAP_MASK (0xFFFFFFFF)
  15. #define MISC_CAP_SHIFT (0)
  16. #define CAP_CAPID_MASK (0xFF000000)
  17. #define CAP_CAPID_SHIFT (24)
  18. #define CAP_NEXT_CAP_MASK (0x00FFF000)
  19. #define CAP_NEXT_CAP_SHIFT (12)
  20. /* MHI Bandwidth scaling offsets */
  21. #define BW_SCALE_CFG_OFFSET (0x04)
  22. #define BW_SCALE_CFG_CHAN_DB_ID_MASK (0xFE000000)
  23. #define BW_SCALE_CFG_CHAN_DB_ID_SHIFT (25)
  24. #define BW_SCALE_CFG_ENABLED_MASK (0x01000000)
  25. #define BW_SCALE_CFG_ENABLED_SHIFT (24)
  26. #define BW_SCALE_CFG_ER_ID_MASK (0x00F80000)
  27. #define BW_SCALE_CFG_ER_ID_SHIFT (19)
  28. #define BW_SCALE_CAP_ID (3)
  29. #define MHI_TRE_GET_EV_BW_REQ_SEQ(tre) (((tre)->dword[0] >> 8) & 0xFF)
  30. #define MHI_BW_SCALE_CHAN_DB 126
  31. #define MHI_BW_SCALE_SETUP(er_index) (((MHI_BW_SCALE_CHAN_DB << \
  32. BW_SCALE_CFG_CHAN_DB_ID_SHIFT) & BW_SCALE_CFG_CHAN_DB_ID_MASK) | \
  33. ((1 << BW_SCALE_CFG_ENABLED_SHIFT) & BW_SCALE_CFG_ENABLED_MASK) | \
  34. (((er_index) << BW_SCALE_CFG_ER_ID_SHIFT) & BW_SCALE_CFG_ER_ID_MASK))
  35. #define MHI_BW_SCALE_RESULT(status, seq) (((status) & 0xF) << 8 | \
  36. ((seq) & 0xFF))
  37. enum mhi_bw_scale_req_status {
  38. MHI_BW_SCALE_SUCCESS = 0x0,
  39. MHI_BW_SCALE_INVALID = 0x1,
  40. MHI_BW_SCALE_NACK = 0xF,
  41. };
  42. /* subsystem failure reason cfg command */
  43. #define MHI_TRE_CMD_SFR_CFG_PTR(ptr) (ptr)
  44. #define MHI_TRE_CMD_SFR_CFG_DWORD0(len) (len)
  45. #define MHI_TRE_CMD_SFR_CFG_DWORD1 (MHI_CMD_SFR_CFG << 16)
  46. /* MHI Timesync offsets */
  47. #define TIMESYNC_CFG_OFFSET (0x04)
  48. #define TIMESYNC_CFG_ENABLED_MASK (0x80000000)
  49. #define TIMESYNC_CFG_ENABLED_SHIFT (31)
  50. #define TIMESYNC_CFG_CHAN_DB_ID_MASK (0x0000FF00)
  51. #define TIMESYNC_CFG_CHAN_DB_ID_SHIFT (8)
  52. #define TIMESYNC_CFG_ER_ID_MASK (0x000000FF)
  53. #define TIMESYNC_CFG_ER_ID_SHIFT (0)
  54. #define TIMESYNC_TIME_LOW_OFFSET (0x8)
  55. #define TIMESYNC_TIME_HIGH_OFFSET (0xC)
  56. #define MHI_TIMESYNC_CHAN_DB (125)
  57. #define TIMESYNC_CAP_ID (2)
  58. #define MHI_TIMESYNC_DB_SETUP(er_index) ((MHI_TIMESYNC_CHAN_DB << \
  59. TIMESYNC_CFG_CHAN_DB_ID_SHIFT) & TIMESYNC_CFG_CHAN_DB_ID_MASK | \
  60. (1 << TIMESYNC_CFG_ENABLED_SHIFT) & TIMESYNC_CFG_ENABLED_MASK | \
  61. ((er_index) << TIMESYNC_CFG_ER_ID_SHIFT) & TIMESYNC_CFG_ER_ID_MASK)
  62. /* MHI WLAN specific offsets */
  63. #define MHI_HOST_NOTIFY_CFG_OFFSET (0x04)
  64. #define MHI_HOST_NOTIFY_ENABLE (1)
  65. #define MHI_HOST_NOTIFY_DB (124)
  66. #define MHI_HOST_NOTIFY_CAP_ID (6)
  67. #define MHI_HOST_NOTIFY_CFG_ENABLED_MASK (0x80000000)
  68. #define MHI_HOST_NOTIFY_CFG_ENABLED_SHIFT (31)
  69. #define MHI_HOST_NOTIFY_CFG_CHAN_DB_ID_MASK (0x000000FF)
  70. #define MHI_HOST_NOTIFY_CFG_CHAN_DB_ID_SHIFT (0)
  71. #define MHI_HOST_NOTIFY_ENABLE_SETUP ((MHI_HOST_NOTIFY_ENABLE << \
  72. MHI_HOST_NOTIFY_CFG_ENABLED_SHIFT) & \
  73. (MHI_HOST_NOTIFY_CFG_ENABLED_MASK))
  74. #define MHI_HOST_NOTIFY_DB_SETUP ((MHI_HOST_NOTIFY_DB << \
  75. MHI_HOST_NOTIFY_CFG_CHAN_DB_ID_SHIFT) & \
  76. (MHI_HOST_NOTIFY_CFG_CHAN_DB_ID_MASK))
  77. #define MHI_HOST_NOTIFY_CFG_SETUP ((MHI_HOST_NOTIFY_ENABLE_SETUP) | \
  78. (MHI_HOST_NOTIFY_DB_SETUP))
  79. #define MHI_VERB_EXTRA(dev, fmt, ...) do { \
  80. struct mhi_private *mhi_priv = \
  81. dev_get_drvdata(&mhi_cntrl->mhi_dev->dev); \
  82. dev_dbg(dev, "[D][%s] " fmt, __func__, ##__VA_ARGS__); \
  83. if (mhi_priv && mhi_priv->log_lvl <= MHI_MSG_LVL_VERBOSE) \
  84. ipc_log_string(mhi_priv->log_buf_extra, "[D][%s] " fmt, __func__, \
  85. ##__VA_ARGS__); \
  86. } while (0)
  87. #define MHI_VERB(dev, fmt, ...) do { \
  88. struct mhi_private *mhi_priv = \
  89. dev_get_drvdata(&mhi_cntrl->mhi_dev->dev); \
  90. dev_dbg(dev, "[D][%s] " fmt, __func__, ##__VA_ARGS__); \
  91. if (mhi_priv && mhi_priv->log_lvl <= MHI_MSG_LVL_VERBOSE) \
  92. ipc_log_string(mhi_priv->log_buf, "[D][%s] " fmt, __func__, \
  93. ##__VA_ARGS__); \
  94. } while (0)
  95. #define MHI_LOG(dev, fmt, ...) do { \
  96. struct mhi_private *mhi_priv = \
  97. dev_get_drvdata(&mhi_cntrl->mhi_dev->dev); \
  98. dev_dbg(dev, "[I][%s] " fmt, __func__, ##__VA_ARGS__); \
  99. if (mhi_priv && mhi_priv->log_lvl <= MHI_MSG_LVL_INFO) \
  100. ipc_log_string(mhi_priv->log_buf, "[I][%s] " fmt, __func__, \
  101. ##__VA_ARGS__); \
  102. } while (0)
  103. #define MHI_ERR(dev, fmt, ...) do { \
  104. struct mhi_private *mhi_priv = \
  105. dev_get_drvdata(&mhi_cntrl->mhi_dev->dev); \
  106. dev_err(dev, "[E][%s] " fmt, __func__, ##__VA_ARGS__); \
  107. if (mhi_priv && mhi_priv->log_lvl <= MHI_MSG_LVL_ERROR) \
  108. ipc_log_string(mhi_priv->log_buf, "[E][%s] " fmt, __func__, \
  109. ##__VA_ARGS__); \
  110. } while (0)
  111. #define MHI_CRITICAL(dev, fmt, ...) do { \
  112. struct mhi_private *mhi_priv = \
  113. dev_get_drvdata(&mhi_cntrl->mhi_dev->dev); \
  114. dev_crit(dev, "[C][%s] " fmt, __func__, ##__VA_ARGS__); \
  115. if (mhi_priv && mhi_priv->log_lvl <= MHI_MSG_LVL_CRITICAL) \
  116. ipc_log_string(mhi_priv->log_buf, "[C][%s] " fmt, __func__, \
  117. ##__VA_ARGS__); \
  118. } while (0)
  119. /**
  120. * struct rddm_table_info - rddm table info
  121. * @base_address - Start offset of the file
  122. * @actual_phys_address - phys addr offset of file
  123. * @size - size of file
  124. * @description - file description
  125. * @file_name - name of file
  126. */
  127. struct rddm_table_info {
  128. u64 base_address;
  129. u64 actual_phys_address;
  130. u64 size;
  131. char description[20];
  132. char file_name[20];
  133. };
  134. /**
  135. * struct rddm_header - rddm header
  136. * @version - header ver
  137. * @header_size - size of header
  138. * @rddm_table_info - array of rddm table info
  139. */
  140. struct rddm_header {
  141. u32 version;
  142. u32 header_size;
  143. struct rddm_table_info table_info[MAX_RDDM_TABLE_SIZE];
  144. };
  145. /**
  146. * struct file_info - keeping track of file info while traversing the rddm
  147. * table header
  148. * @file_offset - current file offset
  149. * @seg_idx - mhi buf seg array index
  150. * @rem_seg_len - remaining length of the segment containing current file
  151. */
  152. struct file_info {
  153. u8 *file_offset;
  154. u32 file_size;
  155. u32 seg_idx;
  156. u32 rem_seg_len;
  157. };
  158. /**
  159. * struct reg_write_info - offload reg write info
  160. * @reg_addr - register address
  161. * @val - value to be written to register
  162. * @chan - channel number
  163. * @valid - entry is valid or not
  164. */
  165. struct reg_write_info {
  166. void __iomem *reg_addr;
  167. u32 val;
  168. bool valid;
  169. };
  170. /**
  171. * struct mhi_private - For private variables of an MHI controller
  172. */
  173. struct mhi_private {
  174. struct list_head node;
  175. struct mhi_controller *mhi_cntrl;
  176. enum MHI_DEBUG_LEVEL log_lvl;
  177. void *log_buf;
  178. void *log_buf_extra;
  179. u32 saved_pm_state;
  180. enum mhi_state saved_dev_state;
  181. u32 m2_timeout_ms;
  182. void *priv_data;
  183. void __iomem *bw_scale_db;
  184. int (*bw_scale)(struct mhi_controller *mhi_cntrl,
  185. struct mhi_link_info *link_info);
  186. phys_addr_t base_addr;
  187. u32 numeric_id;
  188. u32 bw_response;
  189. struct mhi_sfr_info *sfr_info;
  190. struct mhi_timesync *timesync;
  191. /* reg write offload */
  192. struct workqueue_struct *offload_wq;
  193. struct work_struct reg_write_work;
  194. struct reg_write_info *reg_write_q;
  195. atomic_t write_idx;
  196. u32 read_idx;
  197. };
  198. /**
  199. * struct mhi_bus - For MHI controller debug
  200. */
  201. struct mhi_bus {
  202. struct list_head controller_list;
  203. struct mutex lock;
  204. };
  205. /**
  206. * struct mhi_sfr_info - For receiving MHI subsystem failure reason
  207. */
  208. struct mhi_sfr_info {
  209. void *buf_addr;
  210. dma_addr_t dma_addr;
  211. size_t len;
  212. char *str;
  213. unsigned int ccs;
  214. struct completion completion;
  215. };
  216. /**
  217. * struct mhi_timesync - For enabling use of MHI time synchronization feature
  218. */
  219. struct mhi_timesync {
  220. u64 (*time_get)(struct mhi_controller *mhi_cntrl);
  221. int (*lpm_disable)(struct mhi_controller *mhi_cntrl);
  222. int (*lpm_enable)(struct mhi_controller *mhi_cntrl);
  223. void __iomem *time_reg;
  224. void __iomem *time_db;
  225. u32 int_sequence;
  226. u64 local_time;
  227. u64 remote_time;
  228. bool db_pending;
  229. struct completion completion;
  230. spinlock_t lock; /* list protection */
  231. struct list_head head;
  232. struct mutex mutex;
  233. };
  234. /**
  235. * struct tsync_node - Stores requests when using the timesync doorbell method
  236. */
  237. struct tsync_node {
  238. struct list_head node;
  239. u32 sequence;
  240. u64 remote_time;
  241. struct mhi_device *mhi_dev;
  242. void (*cb_func)(struct mhi_device *mhi_dev, u32 sequence,
  243. u64 local_time, u64 remote_time);
  244. };
  245. #ifdef CONFIG_MHI_BUS_MISC
  246. void mhi_misc_init(void);
  247. void mhi_misc_exit(void);
  248. int mhi_misc_init_mmio(struct mhi_controller *mhi_cntrl);
  249. int mhi_misc_register_controller(struct mhi_controller *mhi_cntrl);
  250. void mhi_misc_unregister_controller(struct mhi_controller *mhi_cntrl);
  251. int mhi_misc_sysfs_create(struct mhi_controller *mhi_cntrl);
  252. void mhi_misc_sysfs_destroy(struct mhi_controller *mhi_cntrl);
  253. int mhi_process_misc_bw_ev_ring(struct mhi_controller *mhi_cntrl,
  254. struct mhi_event *mhi_event, u32 event_quota);
  255. int mhi_process_misc_tsync_ev_ring(struct mhi_controller *mhi_cntrl,
  256. struct mhi_event *mhi_event, u32 event_quota);
  257. void mhi_misc_mission_mode(struct mhi_controller *mhi_cntrl);
  258. void mhi_misc_dbs_pending(struct mhi_controller *mhi_cntrl);
  259. void mhi_misc_disable(struct mhi_controller *mhi_cntrl);
  260. void mhi_misc_cmd_configure(struct mhi_controller *mhi_cntrl,
  261. unsigned int type, u64 *ptr, u32 *dword0,
  262. u32 *dword1);
  263. void mhi_misc_cmd_completion(struct mhi_controller *mhi_cntrl,
  264. unsigned int type, unsigned int ccs);
  265. void mhi_write_offload_wakedb(struct mhi_controller *mhi_cntrl, int db_val);
  266. void mhi_reset_reg_write_q(struct mhi_controller *mhi_cntrl);
  267. void mhi_force_reg_write(struct mhi_controller *mhi_cntrl);
  268. #else
  269. static inline void mhi_misc_init(void)
  270. {
  271. }
  272. static inline void mhi_misc_exit(void)
  273. {
  274. }
  275. static inline int mhi_misc_init_mmio(struct mhi_controller *mhi_cntrl)
  276. {
  277. return 0;
  278. }
  279. static inline int mhi_misc_register_controller(struct mhi_controller *mhi_cntrl)
  280. {
  281. return 0;
  282. }
  283. static inline void mhi_misc_unregister_controller(struct mhi_controller
  284. *mhi_cntrl)
  285. {
  286. }
  287. static inline int mhi_misc_sysfs_create(struct mhi_controller *mhi_cntrl)
  288. {
  289. return 0;
  290. }
  291. static inline void mhi_misc_sysfs_destroy(struct mhi_controller *mhi_cntrl)
  292. {
  293. }
  294. static inline int mhi_process_misc_bw_ev_ring(struct mhi_controller *mhi_cntrl,
  295. struct mhi_event *mhi_event, u32 event_quota)
  296. {
  297. return 0;
  298. }
  299. static inline int mhi_process_misc_tsync_ev_ring
  300. (struct mhi_controller *mhi_cntrl,
  301. struct mhi_event *mhi_event, u32 event_quota)
  302. {
  303. return 0;
  304. }
  305. static inline void mhi_misc_mission_mode(struct mhi_controller *mhi_cntrl)
  306. {
  307. }
  308. static inline void mhi_special_dbs_pending(struct mhi_controller *mhi_cntrl)
  309. {
  310. }
  311. static inline void mhi_misc_disable(struct mhi_controller *mhi_cntrl)
  312. {
  313. }
  314. static inline void mhi_misc_cmd_configure(struct mhi_controller *mhi_cntrl,
  315. unsigned int type, u64 *ptr,
  316. u32 *dword0, u32 *dword1)
  317. {
  318. }
  319. static inline void mhi_misc_cmd_completion(struct mhi_controller *mhi_cntrl,
  320. unsigned int type, unsigned int ccs)
  321. {
  322. }
  323. static inline void mhi_write_offload_wakedb(struct mhi_controller *mhi_cntrl,
  324. int db_val)
  325. {
  326. }
  327. void mhi_reset_reg_write_q(struct mhi_controller *mhi_cntrl)
  328. {
  329. }
  330. void mhi_force_reg_write(struct mhi_controller *mhi_cntrl)
  331. {
  332. }
  333. #endif
  334. #endif /* _MHI_CORE_MISC_H_ */