if_pci.h 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. /*
  2. * Copyright (c) 2013-2020 The Linux Foundation. All rights reserved.
  3. *
  4. * Permission to use, copy, modify, and/or distribute this software for
  5. * any purpose with or without fee is hereby granted, provided that the
  6. * above copyright notice and this permission notice appear in all
  7. * copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
  10. * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
  11. * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
  12. * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  13. * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  14. * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  15. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  16. * PERFORMANCE OF THIS SOFTWARE.
  17. */
  18. #ifndef __ATH_PCI_H__
  19. #define __ATH_PCI_H__
  20. #include <linux/version.h>
  21. #include <linux/semaphore.h>
  22. #include <linux/interrupt.h>
  23. #define ATH_DBG_DEFAULT 0
  24. #define DRAM_SIZE 0x000a8000
  25. #include "hif.h"
  26. #include "cepci.h"
  27. #include "ce_main.h"
  28. #ifdef FORCE_WAKE
  29. /* Register to wake the UMAC from power collapse */
  30. #define PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG 0x4040
  31. /* Register used for handshake mechanism to validate UMAC is awake */
  32. #define PCIE_PCIE_LOCAL_REG_PCIE_SOC_WAKE_PCIE_LOCAL_REG 0x3004
  33. /* Timeout duration to validate UMAC wake status */
  34. #ifdef HAL_CONFIG_SLUB_DEBUG_ON
  35. #define FORCE_WAKE_DELAY_TIMEOUT_MS 500
  36. #else
  37. #define FORCE_WAKE_DELAY_TIMEOUT_MS 50
  38. #endif /* HAL_CONFIG_SLUB_DEBUG_ON */
  39. /* Validate UMAC status every 5ms */
  40. #define FORCE_WAKE_DELAY_MS 5
  41. #endif /* FORCE_WAKE */
  42. #ifdef QCA_HIF_HIA_EXTND
  43. extern int32_t frac, intval, ar900b_20_targ_clk, qca9888_20_targ_clk;
  44. #endif
  45. /* An address (e.g. of a buffer) in Copy Engine space. */
  46. #define HIF_MAX_TASKLET_NUM 11
  47. struct hif_tasklet_entry {
  48. uint8_t id; /* 0 - 9: maps to CE, 10: fw */
  49. void *hif_handler; /* struct hif_pci_softc */
  50. };
  51. /**
  52. * enum hif_pm_runtime_state - Driver States for Runtime Power Management
  53. * HIF_PM_RUNTIME_STATE_NONE: runtime pm is off
  54. * HIF_PM_RUNTIME_STATE_ON: runtime pm is active and link is active
  55. * HIF_PM_RUNTIME_STATE_RESUMING: a runtime resume is in progress
  56. * HIF_PM_RUNTIME_STATE_SUSPENDING: a runtime suspend is in progress
  57. * HIF_PM_RUNTIME_STATE_SUSPENDED: the driver is runtime suspended
  58. */
  59. enum hif_pm_runtime_state {
  60. HIF_PM_RUNTIME_STATE_NONE,
  61. HIF_PM_RUNTIME_STATE_ON,
  62. HIF_PM_RUNTIME_STATE_RESUMING,
  63. HIF_PM_RUNTIME_STATE_SUSPENDING,
  64. HIF_PM_RUNTIME_STATE_SUSPENDED,
  65. };
  66. #ifdef FEATURE_RUNTIME_PM
  67. #define PM_STATUS_RUNTIME_CALLER_MAX 128
  68. #define HIF_PM_STATS_RUNTIME_GET_RECORD(sc) \
  69. {\
  70. typeof(sc) sc_ = (sc); \
  71. int32_t index = \
  72. qdf_atomic_read(&sc_->pm_stats.runtime_get_caller_index) % \
  73. PM_STATUS_RUNTIME_CALLER_MAX; \
  74. sc_->pm_stats.runtime_get_caller[index] = (void *)_RET_IP_; \
  75. qdf_atomic_inc(&sc_->pm_stats.runtime_get_caller_index); \
  76. qdf_atomic_inc(&sc_->pm_stats.runtime_get); \
  77. }
  78. #define HIF_PM_STATS_RUNTIME_PUT_RECORD(sc) \
  79. {\
  80. typeof(sc) sc_ = (sc); \
  81. int32_t index = \
  82. qdf_atomic_read(&sc_->pm_stats.runtime_put_caller_index) % \
  83. PM_STATUS_RUNTIME_CALLER_MAX; \
  84. sc_->pm_stats.runtime_put_caller[index] = (void *)_RET_IP_; \
  85. qdf_atomic_inc(&sc_->pm_stats.runtime_put_caller_index); \
  86. qdf_atomic_inc(&sc_->pm_stats.runtime_put); \
  87. }
  88. /**
  89. * struct hif_pm_runtime_lock - data structure for preventing runtime suspend
  90. * @list - global list of runtime locks
  91. * @active - true if this lock is preventing suspend
  92. * @name - character string for tracking this lock
  93. */
  94. struct hif_pm_runtime_lock {
  95. struct list_head list;
  96. bool active;
  97. uint32_t timeout;
  98. const char *name;
  99. };
  100. /* Debugging stats for Runtime PM */
  101. struct hif_pci_pm_stats {
  102. u32 suspended;
  103. u32 suspend_err;
  104. u32 resumed;
  105. atomic_t runtime_get;
  106. atomic_t runtime_put;
  107. atomic_t runtime_get_caller_index;
  108. atomic_t runtime_put_caller_index;
  109. void *runtime_get_caller[PM_STATUS_RUNTIME_CALLER_MAX];
  110. void *runtime_put_caller[PM_STATUS_RUNTIME_CALLER_MAX];
  111. u32 request_resume;
  112. atomic_t allow_suspend;
  113. atomic_t prevent_suspend;
  114. u32 prevent_suspend_timeout;
  115. u32 allow_suspend_timeout;
  116. u32 runtime_get_err;
  117. void *last_resume_caller;
  118. void *last_busy_marker;
  119. qdf_time_t last_busy_timestamp;
  120. unsigned long suspend_jiffies;
  121. };
  122. #endif
  123. /**
  124. * struct hif_msi_info - Structure to hold msi info
  125. * @magic: cookie
  126. * @magic_da: dma address
  127. * @dmaContext: dma address
  128. *
  129. * Structure to hold MSI information for PCIe interrupts
  130. */
  131. struct hif_msi_info {
  132. void *magic;
  133. dma_addr_t magic_da;
  134. OS_DMA_MEM_CONTEXT(dmacontext);
  135. };
  136. /**
  137. * struct hif_pci_stats - Account for hif pci based statistics
  138. * @mhi_force_wake_request_vote: vote for mhi
  139. * @mhi_force_wake_failure: mhi force wake failure
  140. * @mhi_force_wake_success: mhi force wake success
  141. * @soc_force_wake_register_write_success: write to soc wake
  142. * @soc_force_wake_failure: soc force wake failure
  143. * @soc_force_wake_success: soc force wake success
  144. * @mhi_force_wake_release_success: mhi force wake release success
  145. * @soc_force_wake_release_success: soc force wake release
  146. */
  147. struct hif_pci_stats {
  148. uint32_t mhi_force_wake_request_vote;
  149. uint32_t mhi_force_wake_failure;
  150. uint32_t mhi_force_wake_success;
  151. uint32_t soc_force_wake_register_write_success;
  152. uint32_t soc_force_wake_failure;
  153. uint32_t soc_force_wake_success;
  154. uint32_t mhi_force_wake_release_failure;
  155. uint32_t mhi_force_wake_release_success;
  156. uint32_t soc_force_wake_release_success;
  157. };
  158. struct hif_pci_softc {
  159. struct HIF_CE_state ce_sc;
  160. void __iomem *mem; /* PCI address. */
  161. size_t mem_len;
  162. struct device *dev; /* For efficiency, should be first in struct */
  163. struct pci_dev *pdev;
  164. int num_msi_intrs; /* number of MSI interrupts granted */
  165. /* 0 --> using legacy PCI line interrupts */
  166. struct tasklet_struct intr_tq; /* tasklet */
  167. struct hif_msi_info msi_info;
  168. int ce_msi_irq_num[CE_COUNT_MAX];
  169. int irq;
  170. int irq_event;
  171. int cacheline_sz;
  172. u16 devid;
  173. struct hif_tasklet_entry tasklet_entries[HIF_MAX_TASKLET_NUM];
  174. bool pci_enabled;
  175. bool use_register_windowing;
  176. uint32_t register_window;
  177. qdf_spinlock_t register_access_lock;
  178. qdf_spinlock_t irq_lock;
  179. qdf_work_t reschedule_tasklet_work;
  180. uint32_t lcr_val;
  181. #ifdef FEATURE_RUNTIME_PM
  182. atomic_t pm_state;
  183. atomic_t monitor_wake_intr;
  184. uint32_t prevent_suspend_cnt;
  185. struct hif_pci_pm_stats pm_stats;
  186. struct work_struct pm_work;
  187. spinlock_t runtime_lock;
  188. qdf_timer_t runtime_timer;
  189. struct list_head prevent_suspend_list;
  190. unsigned long runtime_timer_expires;
  191. qdf_runtime_lock_t prevent_linkdown_lock;
  192. atomic_t pm_dp_rx_busy;
  193. qdf_time_t dp_last_busy_timestamp;
  194. #ifdef WLAN_OPEN_SOURCE
  195. struct dentry *pm_dentry;
  196. #endif
  197. #endif
  198. int (*hif_enable_pci)(struct hif_pci_softc *sc, struct pci_dev *pdev,
  199. const struct pci_device_id *id);
  200. void (*hif_pci_deinit)(struct hif_pci_softc *sc);
  201. void (*hif_pci_get_soc_info)(struct hif_pci_softc *sc,
  202. struct device *dev);
  203. struct hif_pci_stats stats;
  204. };
  205. bool hif_pci_targ_is_present(struct hif_softc *scn, void *__iomem *mem);
  206. int hif_configure_irq(struct hif_softc *sc);
  207. void hif_pci_cancel_deferred_target_sleep(struct hif_softc *scn);
  208. void wlan_tasklet(unsigned long data);
  209. irqreturn_t hif_pci_legacy_ce_interrupt_handler(int irq, void *arg);
  210. int hif_pci_addr_in_boundary(struct hif_softc *scn, uint32_t offset);
  211. /*
  212. * A firmware interrupt to the Host is indicated by the
  213. * low bit of SCRATCH_3_ADDRESS being set.
  214. */
  215. #define FW_EVENT_PENDING_REG_ADDRESS SCRATCH_3_ADDRESS
  216. /*
  217. * Typically, MSI Interrupts are used with PCIe. To force use of legacy
  218. * "ABCD" PCI line interrupts rather than MSI, define
  219. * FORCE_LEGACY_PCI_INTERRUPTS.
  220. * Even when NOT forced, the driver may attempt to use legacy PCI interrupts
  221. * MSI allocation fails
  222. */
  223. #define LEGACY_INTERRUPTS(sc) ((sc)->num_msi_intrs == 0)
  224. /*
  225. * There may be some pending tx frames during platform suspend.
  226. * Suspend operation should be delayed until those tx frames are
  227. * transferred from the host to target. This macro specifies how
  228. * long suspend thread has to sleep before checking pending tx
  229. * frame count.
  230. */
  231. #define OL_ATH_TX_DRAIN_WAIT_DELAY 50 /* ms */
  232. #define HIF_CE_DRAIN_WAIT_DELAY 10 /* ms */
  233. /*
  234. * Wait time (in unit of OL_ATH_TX_DRAIN_WAIT_DELAY) for pending
  235. * tx frame completion before suspend. Refer: hif_pci_suspend()
  236. */
  237. #ifndef QCA_WIFI_3_0_EMU
  238. #define OL_ATH_TX_DRAIN_WAIT_CNT 10
  239. #else
  240. #define OL_ATH_TX_DRAIN_WAIT_CNT 60
  241. #endif
  242. #ifdef FORCE_WAKE
  243. /**
  244. * hif_print_pci_stats() - Display HIF PCI stats
  245. * @hif_ctx - HIF pci handle
  246. *
  247. * Return: None
  248. */
  249. void hif_print_pci_stats(struct hif_pci_softc *pci_scn);
  250. #else
  251. static inline
  252. void hif_print_pci_stats(struct hif_pci_softc *pci_scn)
  253. {
  254. }
  255. #endif /* FORCE_WAKE */
  256. #ifdef FEATURE_RUNTIME_PM
  257. #include <linux/pm_runtime.h>
  258. static inline int hif_pm_request_resume(struct device *dev)
  259. {
  260. return pm_request_resume(dev);
  261. }
  262. static inline int __hif_pm_runtime_get(struct device *dev)
  263. {
  264. return pm_runtime_get(dev);
  265. }
  266. static inline int hif_pm_runtime_put_auto(struct device *dev)
  267. {
  268. return pm_runtime_put_autosuspend(dev);
  269. }
  270. #endif /* FEATURE_RUNTIME_PM */
  271. #endif /* __ATH_PCI_H__ */