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