xref: /wlan-dirver/qca-wifi-host-cmn/hif/src/pcie/if_pci.h (revision bea437e2293c3d4fb1b5704fcf633aedac996962)
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 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 static inline int hif_pm_runtime_resume(struct device *dev)
272 {
273 	return pm_runtime_resume(dev);
274 }
275 #endif /* FEATURE_RUNTIME_PM */
276 #endif /* __ATH_PCI_H__ */
277