xref: /wlan-dirver/qca-wifi-host-cmn/hif/src/pcie/if_pci.h (revision 2f4b444fb7e689b83a4ab0e7b3b38f0bf4def8e0)
1 /*
2  * Copyright (c) 2013-2021 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 "hif_runtime_pm.h"
30 #include "cepci.h"
31 #include "ce_main.h"
32 
33 #ifdef FORCE_WAKE
34 /* Register offset to wake the UMAC from power collapse */
35 #define PCIE_REG_WAKE_UMAC_OFFSET 0x3004
36 /* Register used for handshake mechanism to validate UMAC is awake */
37 #define PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG (0x01E04000 + 0x40)
38 
39 /* Timeout duration to validate UMAC wake status */
40 #ifdef HAL_CONFIG_SLUB_DEBUG_ON
41 #define FORCE_WAKE_DELAY_TIMEOUT_MS 500
42 #else
43 #define FORCE_WAKE_DELAY_TIMEOUT_MS 50
44 #endif /* HAL_CONFIG_SLUB_DEBUG_ON */
45 /* Validate UMAC status every 5ms */
46 #define FORCE_WAKE_DELAY_MS 5
47 #endif /* FORCE_WAKE */
48 
49 #ifdef QCA_HIF_HIA_EXTND
50 extern int32_t frac, intval, ar900b_20_targ_clk, qca9888_20_targ_clk;
51 #endif
52 
53 /* An address (e.g. of a buffer) in Copy Engine space. */
54 
55 #define HIF_MAX_TASKLET_NUM 11
56 struct hif_tasklet_entry {
57 	uint8_t id;        /* 0 - 9: maps to CE, 10: fw */
58 	void *hif_handler; /* struct hif_pci_softc */
59 };
60 
61 struct hang_event_bus_info {
62 	uint16_t tlv_header;
63 	uint16_t dev_id;
64 } qdf_packed;
65 
66 /**
67  * struct hif_msi_info - Structure to hold msi info
68  * @magic: cookie
69  * @magic_da: dma address
70  * @dmaContext: dma address
71  *
72  * Structure to hold MSI information for PCIe interrupts
73  */
74 struct hif_msi_info {
75 	void *magic;
76 	dma_addr_t magic_da;
77 	OS_DMA_MEM_CONTEXT(dmacontext);
78 };
79 
80 /**
81  * struct hif_pci_stats - Account for hif pci based statistics
82  * @mhi_force_wake_request_vote: vote for mhi
83  * @mhi_force_wake_failure: mhi force wake failure
84  * @mhi_force_wake_success: mhi force wake success
85  * @soc_force_wake_register_write_success: write to soc wake
86  * @soc_force_wake_failure: soc force wake failure
87  * @soc_force_wake_success: soc force wake success
88  * @mhi_force_wake_release_success: mhi force wake release success
89  * @soc_force_wake_release_success: soc force wake release
90  */
91 struct hif_pci_stats {
92 	uint32_t mhi_force_wake_request_vote;
93 	uint32_t mhi_force_wake_failure;
94 	uint32_t mhi_force_wake_success;
95 	uint32_t soc_force_wake_register_write_success;
96 	uint32_t soc_force_wake_failure;
97 	uint32_t soc_force_wake_success;
98 	uint32_t mhi_force_wake_release_failure;
99 	uint32_t mhi_force_wake_release_success;
100 	uint32_t soc_force_wake_release_success;
101 };
102 
103 struct hif_soc_info {
104 	u32 family_number;
105 	u32 device_number;
106 	u32 major_version;
107 	u32 minor_version;
108 };
109 
110 struct hif_pci_softc {
111 	struct HIF_CE_state ce_sc;
112 	void __iomem *mem;      /* PCI address. */
113 	void __iomem *mem_ce;   /* PCI address for CE. */
114 	size_t mem_len;
115 
116 	struct device *dev;	/* For efficiency, should be first in struct */
117 	struct pci_dev *pdev;
118 	int num_msi_intrs;      /* number of MSI interrupts granted */
119 	/* 0 --> using legacy PCI line interrupts */
120 	struct tasklet_struct intr_tq;  /* tasklet */
121 	struct hif_msi_info msi_info;
122 	int ce_msi_irq_num[CE_COUNT_MAX];
123 	int irq;
124 	int irq_event;
125 	int cacheline_sz;
126 	u16 devid;
127 	struct hif_tasklet_entry tasklet_entries[HIF_MAX_TASKLET_NUM];
128 	bool pci_enabled;
129 	bool use_register_windowing;
130 	uint32_t register_window;
131 	qdf_spinlock_t register_access_lock;
132 	qdf_spinlock_t irq_lock;
133 	qdf_work_t reschedule_tasklet_work;
134 	uint32_t lcr_val;
135 #ifdef FEATURE_RUNTIME_PM
136 	struct hif_runtime_pm_ctx rpm_ctx;
137 #endif
138 	int (*hif_enable_pci)(struct hif_pci_softc *sc, struct pci_dev *pdev,
139 			      const struct pci_device_id *id);
140 	void (*hif_pci_deinit)(struct hif_pci_softc *sc);
141 	void (*hif_pci_get_soc_info)(struct hif_pci_softc *sc,
142 				     struct device *dev);
143 	struct hif_pci_stats stats;
144 #ifdef HIF_CPU_PERF_AFFINE_MASK
145 	/* Stores the affinity hint mask for each CE IRQ */
146 	qdf_cpu_mask ce_irq_cpu_mask[CE_COUNT_MAX];
147 #endif
148 	struct hif_soc_info device_version;
149 };
150 
151 bool hif_pci_targ_is_present(struct hif_softc *scn, void *__iomem *mem);
152 int hif_configure_irq(struct hif_softc *sc);
153 void hif_pci_cancel_deferred_target_sleep(struct hif_softc *scn);
154 void wlan_tasklet(unsigned long data);
155 irqreturn_t hif_pci_legacy_ce_interrupt_handler(int irq, void *arg);
156 int hif_pci_addr_in_boundary(struct hif_softc *scn, uint32_t offset);
157 
158 /*
159  * A firmware interrupt to the Host is indicated by the
160  * low bit of SCRATCH_3_ADDRESS being set.
161  */
162 #define FW_EVENT_PENDING_REG_ADDRESS SCRATCH_3_ADDRESS
163 
164 /*
165  * Typically, MSI Interrupts are used with PCIe. To force use of legacy
166  * "ABCD" PCI line interrupts rather than MSI, define
167  * FORCE_LEGACY_PCI_INTERRUPTS.
168  * Even when NOT forced, the driver may attempt to use legacy PCI interrupts
169  * MSI allocation fails
170  */
171 #define LEGACY_INTERRUPTS(sc) ((sc)->num_msi_intrs == 0)
172 
173 /*
174  * There may be some pending tx frames during platform suspend.
175  * Suspend operation should be delayed until those tx frames are
176  * transferred from the host to target. This macro specifies how
177  * long suspend thread has to sleep before checking pending tx
178  * frame count.
179  */
180 #define OL_ATH_TX_DRAIN_WAIT_DELAY     50       /* ms */
181 
182 #define HIF_CE_DRAIN_WAIT_DELAY        10       /* ms */
183 /*
184  * Wait time (in unit of OL_ATH_TX_DRAIN_WAIT_DELAY) for pending
185  * tx frame completion before suspend. Refer: hif_pci_suspend()
186  */
187 #ifndef QCA_WIFI_3_0_EMU
188 #define OL_ATH_TX_DRAIN_WAIT_CNT       10
189 #else
190 #define OL_ATH_TX_DRAIN_WAIT_CNT       60
191 #endif
192 
193 #ifdef FORCE_WAKE
194 /**
195  * hif_print_pci_stats() - Display HIF PCI stats
196  * @hif_ctx - HIF pci handle
197  *
198  * Return: None
199  */
200 void hif_print_pci_stats(struct hif_pci_softc *pci_scn);
201 #else
202 static inline
203 void hif_print_pci_stats(struct hif_pci_softc *pci_scn)
204 {
205 }
206 #endif /* FORCE_WAKE */
207 #ifdef HIF_BUS_LOG_INFO
208 bool hif_log_pcie_info(struct hif_softc *scn, uint8_t *data,
209 		       unsigned int *offset);
210 #else
211 static inline
212 bool hif_log_pcie_info(struct hif_softc *scn, uint8_t *data,
213 		       unsigned int *offset)
214 {
215 	return false;
216 }
217 #endif
218 #endif /* __ATH_PCI_H__ */
219