ipclite.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (c) 2021-2023, Qualcomm Innovation Center, Inc. All rights reserved..
  4. */
  5. #include <linux/hwspinlock.h>
  6. #include <linux/module.h>
  7. #include <linux/platform_device.h>
  8. #include <dt-bindings/soc/qcom,ipcc.h>
  9. #include <linux/mailbox_client.h>
  10. #include <linux/mailbox_controller.h>
  11. #include "ipclite_client.h"
  12. /* version related entries */
  13. #define MAJOR_VERSION 1
  14. #define MINOR_VERSION 0
  15. #define IPCMEM_INIT_COMPLETED 0x1
  16. #define ACTIVE_CHANNEL 0x1
  17. #define IPCMEM_TOC_SIZE (4*1024)
  18. #define IPCMEM_TOC_VAR_OFFSET 0x100
  19. #define GLOBAL_ATOMIC_SUPPORT_BMSK 0x1UL
  20. /* IPCC signal info */
  21. #define IPCLITE_MSG_SIGNAL 0
  22. #define IPCLITE_MEM_INIT_SIGNAL 1
  23. #define IPCLITE_VERSION_SIGNAL 2
  24. #define IPCLITE_TEST_SIGNAL 3
  25. #define IPCLITE_SSR_SIGNAL 4
  26. #define IPCLITE_DEBUG_SIGNAL 5
  27. #define MAX_CHANNEL_SIGNALS 6
  28. /** Flag definitions for the entries */
  29. #define IPCMEM_FLAGS_ENABLE_READ_PROTECTION (0x01)
  30. #define IPCMEM_FLAGS_ENABLE_WRITE_PROTECTION (0x02)
  31. #define IPCMEM_FLAGS_ENABLE_RW_PROTECTION \
  32. (IPCMEM_FLAGS_ENABLE_READ_PROTECTION | \
  33. IPCMEM_FLAGS_ENABLE_WRITE_PROTECTION)
  34. #define IPCMEM_FLAGS_IGNORE_PARTITION (0x00000004)
  35. /*Hardcoded macro to identify local host on each core*/
  36. #define LOCAL_HOST IPCMEM_APPS
  37. /* Timeout (ms) for the trylock of remote spinlocks */
  38. #define HWSPINLOCK_TIMEOUT 1000
  39. /* queue related entries */
  40. #define FIFO_FULL_RESERVE 8
  41. #define FIFO_ALIGNMENT 8
  42. /* debug related entries */
  43. #define IPCLITE_DEBUG_INFO_SIZE 256
  44. #define IPCLITE_CORE_DBG_LABEL "APSS:"
  45. #define IPCLITE_LOG_MSG_SIZE 100
  46. #define IPCLITE_LOG_BUF_SIZE 512
  47. #define IPCLITE_DBG_LABEL_SIZE 5
  48. #define IPCLITE_SIGNAL_LABEL_SIZE 10
  49. #define PREV_INDEX 2
  50. #define ADD_OFFSET(x, y) ((void *)((size_t)x + y))
  51. /* IPCLite Logging Mechanism */
  52. #define IPCLITE_OS_LOG(__level, __fmt, arg...) \
  53. do { \
  54. if (ipclite_debug_level & __level) { \
  55. if (ipclite_debug_control & IPCLITE_DMESG_LOG) \
  56. pr_info(IPCLITE_CORE_DBG_LABEL "%s:"__fmt, \
  57. ipclite_dbg_label[__level], ## arg); \
  58. if (ipclite_debug_control & IPCLITE_INMEM_LOG) \
  59. ipclite_inmem_log(IPCLITE_CORE_DBG_LABEL "%s:"__fmt, \
  60. ipclite_dbg_label[__level], ## arg); \
  61. } \
  62. } while (0)
  63. /* IPCLite Debug enable status */
  64. #define IS_DEBUG_CONFIG(ipclite_debug) (ipclite_debug_control & ipclite_debug)
  65. /* IPCLite Feature enable status */
  66. #define IS_FEATURE_CONFIG(ipclite_feature) (feature_mask & ipclite_feature)
  67. /* Global Atomic status */
  68. #define ATOMIC_HW_MUTEX_ACQUIRE \
  69. (IS_FEATURE_CONFIG(IPCLITE_GLOBAL_ATOMIC) ?: ipclite_hw_mutex_acquire())
  70. #define ATOMIC_HW_MUTEX_RELEASE \
  71. (IS_FEATURE_CONFIG(IPCLITE_GLOBAL_ATOMIC) ?: ipclite_hw_mutex_release())
  72. /* API Structure */
  73. struct ipclite_api_list {
  74. int (*init)(struct platform_device *pdev);
  75. int32_t (*register_client)(IPCLite_Client cb_func_ptr, void *priv);
  76. int32_t (*register_test_client)(IPCLite_Client cb_func_ptr, void *priv);
  77. int32_t (*msg_send)(int32_t proc_id, uint64_t data);
  78. int32_t (*test_msg_send)(int32_t proc_id, uint64_t data);
  79. int32_t (*partition_info)(struct global_region_info *global_ipcmem);
  80. void (*recover)(enum ipcmem_host_type core_id);
  81. } api_list_t;
  82. /**
  83. * enum ipclite_channel_status - channel status
  84. *
  85. * INACTIVE : Channel uninitialized or init failed
  86. * IN_PROGRESS : Channel init passed, awaiting confirmation from remote host
  87. * ACTIVE : Channel init passed in local and remote host, thus active
  88. */
  89. enum ipclite_channel_status {
  90. INACTIVE = 0,
  91. IN_PROGRESS = 1,
  92. ACTIVE = 2,
  93. };
  94. enum ipclite_feature_mask {
  95. IPCLITE_GLOBAL_ATOMIC = 0x0001ULL,
  96. IPCLITE_TEST_SUITE = 0x0002ULL,
  97. };
  98. enum ipclite_debug_level {
  99. IPCLITE_ERR = 0x0001,
  100. IPCLITE_WARN = 0x0002,
  101. IPCLITE_INFO = 0x0004,
  102. IPCLITE_DBG = 0x0008,
  103. };
  104. enum ipclite_debug_control {
  105. IPCLITE_DMESG_LOG = 0x0001,
  106. IPCLITE_DBG_STRUCT = 0x0002,
  107. IPCLITE_INMEM_LOG = 0x0004,
  108. };
  109. enum ipclite_debug_dump {
  110. IPCLITE_DUMP_DBG_STRUCT = 0x0001,
  111. IPCLITE_DUMP_INMEM_LOG = 0x0002,
  112. IPCLITE_DUMP_SSR = 0x0004,
  113. };
  114. static const char ipclite_dbg_label[][IPCLITE_DBG_LABEL_SIZE] = {
  115. [IPCLITE_ERR] = "err",
  116. [IPCLITE_WARN] = "warn",
  117. [IPCLITE_INFO] = "info",
  118. [IPCLITE_DBG] = "dbg"
  119. };
  120. /**
  121. * IPCMEM Debug Structure Definitions
  122. * - Present in Local Memory
  123. */
  124. struct ipclite_debug_info_host {
  125. uint32_t numsig_sent; //no. of signals sent from the core
  126. uint32_t numsig_recv; //no. of signals received on the core
  127. uint32_t tx_wr_index; //write index of tx queue
  128. uint32_t tx_rd_index; //read index of tx queue
  129. uint32_t rx_wr_index; //write index of rx queue
  130. uint32_t rx_rd_index; //read index of rx queue
  131. uint32_t num_intr; //no. of interrupts received on the core
  132. uint32_t prev_tx_wr_index[PREV_INDEX]; //previous write index of tx queue
  133. uint32_t prev_tx_rd_index[PREV_INDEX]; //previous read index of tx queue
  134. uint32_t prev_rx_wr_index[PREV_INDEX]; //previous write index of rx queue
  135. uint32_t prev_rx_rd_index[PREV_INDEX]; //previous read index of rx queue
  136. };
  137. struct ipclite_debug_info_overall {
  138. uint32_t total_numsig_sent; //total no. of signals sent
  139. uint32_t total_numsig_recv; //total no. of signals received
  140. uint32_t last_sent_host_id; //last signal sent to host
  141. uint32_t last_recv_host_id; //last signal received from host
  142. uint32_t last_sigid_sent; //last sent signal id
  143. uint32_t last_sigid_recv; //last received signal id
  144. };
  145. struct ipclite_debug_info {
  146. uint32_t debug_version;
  147. uint32_t debug_level;
  148. uint32_t debug_control;
  149. uint32_t debug_dump;
  150. uint32_t debug_log_index;
  151. };
  152. struct ipclite_debug_inmem_buf {
  153. char IPCLITELog[IPCLITE_LOG_BUF_SIZE][IPCLITE_LOG_MSG_SIZE];
  154. };
  155. struct ipclite_debug_struct {
  156. struct ipclite_debug_info_overall dbg_info_overall;
  157. struct ipclite_debug_info_host dbg_info_host[IPCMEM_NUM_HOSTS];
  158. };
  159. /**
  160. * IPCMEM TOC Structure Definitions
  161. * - Present in toc in shared memory
  162. */
  163. struct ipcmem_host_info {
  164. uint32_t hwlock_owner;
  165. uint32_t configured_host;
  166. };
  167. struct ipcmem_partition_entry {
  168. uint32_t base_offset; /*partition offset from IPCMEM base*/
  169. uint32_t size; /*partition size*/
  170. uint32_t flags; /*partition flags if required*/
  171. uint32_t host0; /*subsystem 0 who can access this partition*/
  172. uint32_t host1; /*subsystem 1 who can access this partition*/
  173. uint32_t reserved; /*legacy partition active status*/
  174. };
  175. struct ipcmem_partition_info {
  176. uint32_t num_entries; /* Number of channel partitions */
  177. uint32_t entry_size; /* Size of partition_entry structure */
  178. };
  179. struct ipcmem_offsets {
  180. uint32_t host_info;
  181. uint32_t global_entry;
  182. uint32_t partition_info;
  183. uint32_t partition_entry;
  184. uint32_t debug;
  185. uint32_t reserved; /*Padded for 64-bit alignment*/
  186. };
  187. /**
  188. * Any change in TOC header size can only be accomodated with
  189. * major version change, as it is not backward compatible.
  190. */
  191. struct ipcmem_toc_header {
  192. uint32_t magic_number; /*Checksum of TOC*/
  193. uint32_t init_done; /*TOC initialization status*/
  194. uint32_t major_version;
  195. uint32_t minor_version;
  196. uint64_t feature_mask;
  197. uint32_t reserved[6]; /*Padded for future use and 64-bit alignment*/
  198. };
  199. /**
  200. * struct ipcmem_toc - Table of contents in ipcmem
  201. *
  202. * @hdr : Header to check for toc integrity, version and features
  203. * @offsets : List of offsetted structures and partition entries
  204. * available in the toc data region (ipcmem_toc_data)
  205. */
  206. struct ipcmem_toc {
  207. struct ipcmem_toc_header hdr;
  208. struct ipcmem_offsets offsets;
  209. /* ---------------------------------------
  210. * ipcmem_toc_data @ 256-byte offset
  211. * struct ipcmem_host_info host_info;
  212. * struct ipcmem_partition_entry global_entry;
  213. * struct ipcmem_partition_info partition_info;
  214. * struct ipcmem_partition_entry partition_entry[num_entries];
  215. * ---------------------------------------
  216. */
  217. };
  218. /**
  219. * IPCMEM Partition Structure Definitions
  220. * - Present in partitions in shared memory
  221. */
  222. struct global_partition_header {
  223. uint32_t partition_type;
  224. uint32_t region_offset;
  225. uint32_t region_size;
  226. };
  227. struct ipcmem_global_partition {
  228. struct global_partition_header hdr;
  229. };
  230. struct ipcmem_partition_header {
  231. uint32_t type; /*partition type*/
  232. uint32_t desc_offset; /*descriptor offset*/
  233. uint32_t desc_size; /*descriptor size*/
  234. uint32_t fifo0_offset; /*fifo 0 offset*/
  235. uint32_t fifo0_size; /*fifo 0 size*/
  236. uint32_t fifo1_offset; /*fifo 1 offset*/
  237. uint32_t fifo1_size; /*fifo 1 size*/
  238. uint32_t status; /*partition status*/
  239. };
  240. struct ipcmem_partition {
  241. struct ipcmem_partition_header hdr;
  242. };
  243. /**
  244. * IPCMEM Helper Structure Definitions
  245. * - Present in local memory
  246. * - Can have pointers to toc and partitions in shared memory
  247. */
  248. /*Pointers to offsetted structures in TOC*/
  249. struct ipcmem_toc_data {
  250. struct ipcmem_host_info *host_info;
  251. struct ipcmem_partition_entry *global_entry;
  252. struct ipcmem_partition_info *partition_info;
  253. struct ipcmem_partition_entry *partition_entry;
  254. };
  255. struct ipcmem_region {
  256. u64 aux_base;
  257. void __iomem *virt_base;
  258. uint32_t size;
  259. };
  260. struct ipclite_mem {
  261. struct ipcmem_toc *toc;
  262. struct ipcmem_toc_data toc_data;
  263. struct ipcmem_region mem;
  264. struct ipcmem_global_partition *global_partition;
  265. struct ipcmem_partition **partition;
  266. };
  267. /**
  268. * IPCLite Structure Definitions
  269. * - Present in local memory
  270. * - Can have pointers to partitions in shared memory
  271. */
  272. struct ipclite_fifo {
  273. uint32_t length;
  274. __le32 *tail;
  275. __le32 *head;
  276. void *fifo;
  277. size_t (*avail)(struct ipclite_fifo *fifo);
  278. void (*peak)(struct ipclite_fifo *fifo,
  279. void *data, size_t count);
  280. void (*advance)(struct ipclite_fifo *fifo,
  281. size_t count, uint32_t core_id);
  282. void (*write)(struct ipclite_fifo *fifo,
  283. const void *data, size_t dlen, uint32_t core_id, uint32_t signal_id);
  284. void (*reset)(struct ipclite_fifo *fifo);
  285. };
  286. struct ipclite_irq_info {
  287. struct mbox_client mbox_client;
  288. struct mbox_chan *mbox_chan;
  289. int irq;
  290. int signal_id;
  291. char irqname[32];
  292. };
  293. struct ipclite_client {
  294. IPCLite_Client callback;
  295. void *priv_data;
  296. int reg_complete;
  297. };
  298. struct ipclite_channel {
  299. uint32_t remote_pid;
  300. struct ipclite_fifo *tx_fifo;
  301. struct ipclite_fifo *rx_fifo;
  302. spinlock_t tx_lock;
  303. struct ipclite_irq_info irq_info[MAX_CHANNEL_SIGNALS];
  304. struct ipclite_client client;
  305. uint32_t channel_version;
  306. uint32_t version_finalised;
  307. uint32_t *gstatus_ptr;
  308. uint32_t status;
  309. };
  310. /*Single structure that defines everything about IPCLite*/
  311. struct ipclite_info {
  312. struct device *dev;
  313. struct ipclite_channel channel[IPCMEM_NUM_HOSTS];
  314. struct ipclite_mem ipcmem;
  315. struct hwspinlock *hwlock;
  316. unsigned long hw_mutex_flags;
  317. };
  318. /*Default partition parameters*/
  319. #define DEFAULT_PARTITION_TYPE 0x0
  320. #define DEFAULT_PARTITION_STATUS INACTIVE
  321. #define DEFAULT_PARTITION_HDR_SIZE 1024
  322. #define DEFAULT_DESCRIPTOR_OFFSET 1024
  323. #define DEFAULT_DESCRIPTOR_SIZE (3*1024)
  324. #define DEFAULT_FIFO0_OFFSET (4*1024)
  325. #define DEFAULT_FIFO0_SIZE (8*1024)
  326. #define DEFAULT_FIFO1_OFFSET (12*1024)
  327. #define DEFAULT_FIFO1_SIZE (8*1024)
  328. #define DEFAULT_PARTITION_SIZE (32*1024)
  329. #define DEFAULT_PARTITION_FLAGS IPCMEM_FLAGS_ENABLE_RW_PROTECTION
  330. /*Loopback partition parameters*/
  331. #define LOOPBACK_PARTITION_TYPE 0x1
  332. /*Global partition parameters*/
  333. #define GLOBAL_PARTITION_TYPE 0xFF
  334. #define GLOBAL_PARTITION_HDR_SIZE (4*1024)
  335. #define GLOBAL_REGION_OFFSET (4*1024)
  336. #define GLOBAL_REGION_SIZE (124*1024)
  337. #define GLOBAL_PARTITION_SIZE (128*1024)
  338. #define GLOBAL_PARTITION_FLAGS IPCMEM_FLAGS_ENABLE_RW_PROTECTION
  339. /*Debug partition parameters*/
  340. #define DEBUG_PARTITION_SIZE (64*1024)
  341. const struct ipcmem_partition_header default_partition_hdr = {
  342. DEFAULT_PARTITION_TYPE,
  343. DEFAULT_DESCRIPTOR_OFFSET,
  344. DEFAULT_DESCRIPTOR_SIZE,
  345. DEFAULT_FIFO0_OFFSET,
  346. DEFAULT_FIFO0_SIZE,
  347. DEFAULT_FIFO1_OFFSET,
  348. DEFAULT_FIFO1_SIZE,
  349. DEFAULT_PARTITION_STATUS,
  350. };
  351. /* TX and RX FIFO point to same location for such loopback partition type
  352. * (FIFO0 offset = FIFO1 offset)
  353. */
  354. const struct ipcmem_partition_header loopback_partition_hdr = {
  355. LOOPBACK_PARTITION_TYPE,
  356. DEFAULT_DESCRIPTOR_OFFSET,
  357. DEFAULT_DESCRIPTOR_SIZE,
  358. DEFAULT_FIFO0_OFFSET,
  359. DEFAULT_FIFO0_SIZE,
  360. DEFAULT_FIFO0_OFFSET,
  361. DEFAULT_FIFO0_SIZE,
  362. DEFAULT_PARTITION_STATUS,
  363. };
  364. const struct global_partition_header global_partition_hdr = {
  365. GLOBAL_PARTITION_TYPE,
  366. GLOBAL_REGION_OFFSET,
  367. GLOBAL_REGION_SIZE,
  368. };