1 /* 2 * Copyright (c) 2013-2019 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 QCA_HIF_HIA_EXTND 33 extern int32_t frac, intval, ar900b_20_targ_clk, qca9888_20_targ_clk; 34 #endif 35 36 /* An address (e.g. of a buffer) in Copy Engine space. */ 37 38 #define HIF_MAX_TASKLET_NUM 11 39 struct hif_tasklet_entry { 40 uint8_t id; /* 0 - 9: maps to CE, 10: fw */ 41 void *hif_handler; /* struct hif_pci_softc */ 42 }; 43 44 /** 45 * enum hif_pm_runtime_state - Driver States for Runtime Power Management 46 * HIF_PM_RUNTIME_STATE_NONE: runtime pm is off 47 * HIF_PM_RUNTIME_STATE_ON: runtime pm is active and link is active 48 * HIF_PM_RUNTIME_STATE_RESUMING: a runtime resume is in progress 49 * HIF_PM_RUNTIME_STATE_SUSPENDING: a runtime suspend is in progress 50 * HIF_PM_RUNTIME_STATE_SUSPENDED: the driver is runtime suspended 51 */ 52 enum hif_pm_runtime_state { 53 HIF_PM_RUNTIME_STATE_NONE, 54 HIF_PM_RUNTIME_STATE_ON, 55 HIF_PM_RUNTIME_STATE_RESUMING, 56 HIF_PM_RUNTIME_STATE_SUSPENDING, 57 HIF_PM_RUNTIME_STATE_SUSPENDED, 58 }; 59 60 #ifdef FEATURE_RUNTIME_PM 61 62 /** 63 * struct hif_pm_runtime_lock - data structure for preventing runtime suspend 64 * @list - global list of runtime locks 65 * @active - true if this lock is preventing suspend 66 * @name - character string for tracking this lock 67 */ 68 struct hif_pm_runtime_lock { 69 struct list_head list; 70 bool active; 71 uint32_t timeout; 72 const char *name; 73 }; 74 75 /* Debugging stats for Runtime PM */ 76 struct hif_pci_pm_stats { 77 u32 suspended; 78 u32 suspend_err; 79 u32 resumed; 80 u32 runtime_get; 81 u32 runtime_put; 82 u32 request_resume; 83 u32 allow_suspend; 84 u32 prevent_suspend; 85 u32 prevent_suspend_timeout; 86 u32 allow_suspend_timeout; 87 u32 runtime_get_err; 88 void *last_resume_caller; 89 void *last_busy_marker; 90 qdf_time_t last_busy_timestamp; 91 unsigned long suspend_jiffies; 92 }; 93 #endif 94 95 /** 96 * struct hif_msi_info - Structure to hold msi info 97 * @magic: cookie 98 * @magic_da: dma address 99 * @dmaContext: dma address 100 * 101 * Structure to hold MSI information for PCIe interrupts 102 */ 103 struct hif_msi_info { 104 void *magic; 105 dma_addr_t magic_da; 106 OS_DMA_MEM_CONTEXT(dmacontext); 107 }; 108 109 struct hif_pci_softc { 110 struct HIF_CE_state ce_sc; 111 void __iomem *mem; /* PCI address. */ 112 size_t mem_len; 113 114 struct device *dev; /* For efficiency, should be first in struct */ 115 struct pci_dev *pdev; 116 int num_msi_intrs; /* number of MSI interrupts granted */ 117 /* 0 --> using legacy PCI line interrupts */ 118 struct tasklet_struct intr_tq; /* tasklet */ 119 struct hif_msi_info msi_info; 120 int ce_msi_irq_num[CE_COUNT_MAX]; 121 int irq; 122 int irq_event; 123 int cacheline_sz; 124 u16 devid; 125 struct hif_tasklet_entry tasklet_entries[HIF_MAX_TASKLET_NUM]; 126 bool pci_enabled; 127 bool use_register_windowing; 128 uint32_t register_window; 129 qdf_spinlock_t register_access_lock; 130 qdf_spinlock_t irq_lock; 131 qdf_work_t reschedule_tasklet_work; 132 uint32_t lcr_val; 133 #ifdef FEATURE_RUNTIME_PM 134 atomic_t pm_state; 135 atomic_t monitor_wake_intr; 136 uint32_t prevent_suspend_cnt; 137 struct hif_pci_pm_stats pm_stats; 138 struct work_struct pm_work; 139 spinlock_t runtime_lock; 140 qdf_timer_t runtime_timer; 141 struct list_head prevent_suspend_list; 142 unsigned long runtime_timer_expires; 143 qdf_runtime_lock_t prevent_linkdown_lock; 144 atomic_t pm_dp_rx_busy; 145 qdf_time_t dp_last_busy_timestamp; 146 #ifdef WLAN_OPEN_SOURCE 147 struct dentry *pm_dentry; 148 #endif 149 #endif 150 int (*hif_enable_pci)(struct hif_pci_softc *sc, struct pci_dev *pdev, 151 const struct pci_device_id *id); 152 void (*hif_pci_deinit)(struct hif_pci_softc *sc); 153 void (*hif_pci_get_soc_info)(struct hif_pci_softc *sc, 154 struct device *dev); 155 }; 156 157 bool hif_pci_targ_is_present(struct hif_softc *scn, void *__iomem *mem); 158 int hif_configure_irq(struct hif_softc *sc); 159 void hif_pci_cancel_deferred_target_sleep(struct hif_softc *scn); 160 void wlan_tasklet(unsigned long data); 161 irqreturn_t hif_pci_legacy_ce_interrupt_handler(int irq, void *arg); 162 int hif_pci_addr_in_boundary(struct hif_softc *scn, uint32_t offset); 163 164 /* 165 * A firmware interrupt to the Host is indicated by the 166 * low bit of SCRATCH_3_ADDRESS being set. 167 */ 168 #define FW_EVENT_PENDING_REG_ADDRESS SCRATCH_3_ADDRESS 169 170 /* 171 * Typically, MSI Interrupts are used with PCIe. To force use of legacy 172 * "ABCD" PCI line interrupts rather than MSI, define 173 * FORCE_LEGACY_PCI_INTERRUPTS. 174 * Even when NOT forced, the driver may attempt to use legacy PCI interrupts 175 * MSI allocation fails 176 */ 177 #define LEGACY_INTERRUPTS(sc) ((sc)->num_msi_intrs == 0) 178 179 /* 180 * There may be some pending tx frames during platform suspend. 181 * Suspend operation should be delayed until those tx frames are 182 * transferred from the host to target. This macro specifies how 183 * long suspend thread has to sleep before checking pending tx 184 * frame count. 185 */ 186 #define OL_ATH_TX_DRAIN_WAIT_DELAY 50 /* ms */ 187 188 #define HIF_CE_DRAIN_WAIT_DELAY 10 /* ms */ 189 /* 190 * Wait time (in unit of OL_ATH_TX_DRAIN_WAIT_DELAY) for pending 191 * tx frame completion before suspend. Refer: hif_pci_suspend() 192 */ 193 #ifndef QCA_WIFI_3_0_EMU 194 #define OL_ATH_TX_DRAIN_WAIT_CNT 10 195 #else 196 #define OL_ATH_TX_DRAIN_WAIT_CNT 60 197 #endif 198 199 #ifdef FEATURE_RUNTIME_PM 200 #include <linux/pm_runtime.h> 201 202 static inline int hif_pm_request_resume(struct device *dev) 203 { 204 return pm_request_resume(dev); 205 } 206 207 static inline int __hif_pm_runtime_get(struct device *dev) 208 { 209 return pm_runtime_get(dev); 210 } 211 212 static inline int hif_pm_runtime_put_auto(struct device *dev) 213 { 214 return pm_runtime_put_autosuspend(dev); 215 } 216 217 static inline int hif_pm_runtime_resume(struct device *dev) 218 { 219 return pm_runtime_resume(dev); 220 } 221 #endif /* FEATURE_RUNTIME_PM */ 222 #endif /* __ATH_PCI_H__ */ 223