xref: /wlan-driver/qca-wifi-host-cmn/hif/src/pcie/if_pci.h (revision 5113495b16420b49004c444715d2daae2066e7dc)
1*5113495bSYour Name /*
2*5113495bSYour Name  * Copyright (c) 2013-2021 The Linux Foundation. All rights reserved.
3*5113495bSYour Name  * Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
4*5113495bSYour Name  *
5*5113495bSYour Name  * Permission to use, copy, modify, and/or distribute this software for
6*5113495bSYour Name  * any purpose with or without fee is hereby granted, provided that the
7*5113495bSYour Name  * above copyright notice and this permission notice appear in all
8*5113495bSYour Name  * copies.
9*5113495bSYour Name  *
10*5113495bSYour Name  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11*5113495bSYour Name  * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12*5113495bSYour Name  * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13*5113495bSYour Name  * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14*5113495bSYour Name  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15*5113495bSYour Name  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16*5113495bSYour Name  * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*5113495bSYour Name  * PERFORMANCE OF THIS SOFTWARE.
18*5113495bSYour Name  */
19*5113495bSYour Name 
20*5113495bSYour Name #ifndef __ATH_PCI_H__
21*5113495bSYour Name #define __ATH_PCI_H__
22*5113495bSYour Name 
23*5113495bSYour Name #include <linux/version.h>
24*5113495bSYour Name #include <linux/semaphore.h>
25*5113495bSYour Name #include <linux/interrupt.h>
26*5113495bSYour Name 
27*5113495bSYour Name #define ATH_DBG_DEFAULT   0
28*5113495bSYour Name #define DRAM_SIZE               0x000a8000
29*5113495bSYour Name #include "hif.h"
30*5113495bSYour Name #include "hif_runtime_pm.h"
31*5113495bSYour Name #include "cepci.h"
32*5113495bSYour Name #include "ce_main.h"
33*5113495bSYour Name 
34*5113495bSYour Name #ifdef FORCE_WAKE
35*5113495bSYour Name /* Register offset to wake the UMAC from power collapse */
36*5113495bSYour Name #define PCIE_REG_WAKE_UMAC_OFFSET 0x3004
37*5113495bSYour Name /* Register used for handshake mechanism to validate UMAC is awake */
38*5113495bSYour Name #define PCIE_SOC_PCIE_REG_PCIE_SCRATCH_0_SOC_PCIE_REG (0x01E04000 + 0x40)
39*5113495bSYour Name 
40*5113495bSYour Name /* Timeout duration to validate UMAC wake status */
41*5113495bSYour Name #ifdef HAL_CONFIG_SLUB_DEBUG_ON
42*5113495bSYour Name #define FORCE_WAKE_DELAY_TIMEOUT_MS 500
43*5113495bSYour Name #else
44*5113495bSYour Name #define FORCE_WAKE_DELAY_TIMEOUT_MS 50
45*5113495bSYour Name #endif /* HAL_CONFIG_SLUB_DEBUG_ON */
46*5113495bSYour Name /* Validate UMAC status every 5ms */
47*5113495bSYour Name #define FORCE_WAKE_DELAY_MS 5
48*5113495bSYour Name #endif /* FORCE_WAKE */
49*5113495bSYour Name 
50*5113495bSYour Name #ifdef CONFIG_PCI_LOW_POWER_INT_REG
51*5113495bSYour Name /* PCIe low power interrupt mask register */
52*5113495bSYour Name #define PCIE_LOW_POWER_INT_MASK_OFFSET	0x38044
53*5113495bSYour Name #define INTR_L1SS			BIT(3)
54*5113495bSYour Name #define INTR_CLKPM			BIT(4)
55*5113495bSYour Name #endif
56*5113495bSYour Name 
57*5113495bSYour Name #ifdef QCA_HIF_HIA_EXTND
58*5113495bSYour Name extern int32_t frac, intval, ar900b_20_targ_clk, qca9888_20_targ_clk;
59*5113495bSYour Name #endif
60*5113495bSYour Name 
61*5113495bSYour Name /* An address (e.g. of a buffer) in Copy Engine space. */
62*5113495bSYour Name 
63*5113495bSYour Name #define HIF_MAX_TASKLET_NUM 11
64*5113495bSYour Name struct hif_tasklet_entry {
65*5113495bSYour Name 	uint8_t id;        /* 0 - 9: maps to CE, 10: fw */
66*5113495bSYour Name 	void *hif_handler; /* struct hif_pci_softc */
67*5113495bSYour Name };
68*5113495bSYour Name 
69*5113495bSYour Name struct hang_event_bus_info {
70*5113495bSYour Name 	uint16_t tlv_header;
71*5113495bSYour Name 	uint16_t dev_id;
72*5113495bSYour Name } qdf_packed;
73*5113495bSYour Name 
74*5113495bSYour Name /*
75*5113495bSYour Name  * struct hif_msi_info - Structure to hold msi info
76*5113495bSYour Name  * @magic: cookie
77*5113495bSYour Name  * @magic_da: dma address
78*5113495bSYour Name  * @dmacontext: dma address
79*5113495bSYour Name  *
80*5113495bSYour Name  * Structure to hold MSI information for PCIe interrupts
81*5113495bSYour Name  *
82*5113495bSYour Name  * NB: Intentionally not using kernel-doc comment since the kernel-doc
83*5113495bSYour Name  *     script doesn't handle the OS_DMA_MEM_CONTEXT() macro
84*5113495bSYour Name  */
85*5113495bSYour Name struct hif_msi_info {
86*5113495bSYour Name 	void *magic;
87*5113495bSYour Name 	dma_addr_t magic_da;
88*5113495bSYour Name 	OS_DMA_MEM_CONTEXT(dmacontext);
89*5113495bSYour Name };
90*5113495bSYour Name 
91*5113495bSYour Name /**
92*5113495bSYour Name  * struct hif_pci_stats - Account for hif pci based statistics
93*5113495bSYour Name  * @mhi_force_wake_request_vote: vote for mhi
94*5113495bSYour Name  * @mhi_force_wake_failure: mhi force wake failure
95*5113495bSYour Name  * @mhi_force_wake_success: mhi force wake success
96*5113495bSYour Name  * @soc_force_wake_register_write_success: write to soc wake
97*5113495bSYour Name  * @soc_force_wake_failure: soc force wake failure
98*5113495bSYour Name  * @soc_force_wake_success: soc force wake success
99*5113495bSYour Name  * @mhi_force_wake_release_failure: mhi force wake release failure
100*5113495bSYour Name  * @mhi_force_wake_release_success: mhi force wake release success
101*5113495bSYour Name  * @soc_force_wake_release_success: soc force wake release
102*5113495bSYour Name  */
103*5113495bSYour Name struct hif_pci_stats {
104*5113495bSYour Name 	uint32_t mhi_force_wake_request_vote;
105*5113495bSYour Name 	uint32_t mhi_force_wake_failure;
106*5113495bSYour Name 	uint32_t mhi_force_wake_success;
107*5113495bSYour Name 	uint32_t soc_force_wake_register_write_success;
108*5113495bSYour Name 	uint32_t soc_force_wake_failure;
109*5113495bSYour Name 	uint32_t soc_force_wake_success;
110*5113495bSYour Name 	uint32_t mhi_force_wake_release_failure;
111*5113495bSYour Name 	uint32_t mhi_force_wake_release_success;
112*5113495bSYour Name 	uint32_t soc_force_wake_release_success;
113*5113495bSYour Name };
114*5113495bSYour Name 
115*5113495bSYour Name struct hif_soc_info {
116*5113495bSYour Name 	u32 family_number;
117*5113495bSYour Name 	u32 device_number;
118*5113495bSYour Name 	u32 major_version;
119*5113495bSYour Name 	u32 minor_version;
120*5113495bSYour Name };
121*5113495bSYour Name 
122*5113495bSYour Name struct hif_pci_softc {
123*5113495bSYour Name 	struct HIF_CE_state ce_sc;
124*5113495bSYour Name 	void __iomem *mem;      /* PCI address. */
125*5113495bSYour Name 	void __iomem *mem_ce;   /* PCI address for CE. */
126*5113495bSYour Name 	void __iomem *mem_cmem;   /* PCI address for CMEM. */
127*5113495bSYour Name 	void __iomem *mem_pmm_base;   /* address for PMM. */
128*5113495bSYour Name 	size_t mem_len;
129*5113495bSYour Name 
130*5113495bSYour Name 	struct device *dev;	/* For efficiency, should be first in struct */
131*5113495bSYour Name 	struct pci_dev *pdev;
132*5113495bSYour Name 	int num_msi_intrs;      /* number of MSI interrupts granted */
133*5113495bSYour Name 	/* 0 --> using legacy PCI line interrupts */
134*5113495bSYour Name 	struct tasklet_struct intr_tq;  /* tasklet */
135*5113495bSYour Name 	struct hif_msi_info msi_info;
136*5113495bSYour Name 	int ce_irq_num[CE_COUNT_MAX];
137*5113495bSYour Name 	int irq;
138*5113495bSYour Name 	int irq_event;
139*5113495bSYour Name 	int cacheline_sz;
140*5113495bSYour Name 	u16 devid;
141*5113495bSYour Name 	struct hif_tasklet_entry tasklet_entries[HIF_MAX_TASKLET_NUM];
142*5113495bSYour Name 	bool pci_enabled;
143*5113495bSYour Name 	bool use_register_windowing;
144*5113495bSYour Name 	uint32_t register_window;
145*5113495bSYour Name 	qdf_spinlock_t register_access_lock;
146*5113495bSYour Name 	qdf_spinlock_t irq_lock;
147*5113495bSYour Name 	qdf_work_t reschedule_tasklet_work;
148*5113495bSYour Name 	uint32_t lcr_val;
149*5113495bSYour Name 	int (*hif_enable_pci)(struct hif_pci_softc *sc, struct pci_dev *pdev,
150*5113495bSYour Name 			      const struct pci_device_id *id);
151*5113495bSYour Name 	void (*hif_pci_deinit)(struct hif_pci_softc *sc);
152*5113495bSYour Name 	void (*hif_pci_get_soc_info)(struct hif_pci_softc *sc,
153*5113495bSYour Name 				     struct device *dev);
154*5113495bSYour Name 	struct hif_pci_stats stats;
155*5113495bSYour Name #ifdef HIF_CPU_PERF_AFFINE_MASK
156*5113495bSYour Name 	/* Stores the affinity hint mask for each CE IRQ */
157*5113495bSYour Name 	qdf_cpu_mask ce_irq_cpu_mask[CE_COUNT_MAX];
158*5113495bSYour Name #endif
159*5113495bSYour Name 	struct hif_soc_info device_version;
160*5113495bSYour Name 	qdf_spinlock_t force_wake_lock;
161*5113495bSYour Name };
162*5113495bSYour Name 
163*5113495bSYour Name bool hif_pci_targ_is_present(struct hif_softc *scn, void *__iomem *mem);
164*5113495bSYour Name int hif_configure_irq(struct hif_softc *sc);
165*5113495bSYour Name void hif_pci_cancel_deferred_target_sleep(struct hif_softc *scn);
166*5113495bSYour Name void wlan_tasklet(unsigned long data);
167*5113495bSYour Name irqreturn_t hif_pci_legacy_ce_interrupt_handler(int irq, void *arg);
168*5113495bSYour Name int hif_pci_addr_in_boundary(struct hif_softc *scn, uint32_t offset);
169*5113495bSYour Name 
170*5113495bSYour Name /*
171*5113495bSYour Name  * A firmware interrupt to the Host is indicated by the
172*5113495bSYour Name  * low bit of SCRATCH_3_ADDRESS being set.
173*5113495bSYour Name  */
174*5113495bSYour Name #define FW_EVENT_PENDING_REG_ADDRESS SCRATCH_3_ADDRESS
175*5113495bSYour Name 
176*5113495bSYour Name /*
177*5113495bSYour Name  * Typically, MSI Interrupts are used with PCIe. To force use of legacy
178*5113495bSYour Name  * "ABCD" PCI line interrupts rather than MSI, define
179*5113495bSYour Name  * FORCE_LEGACY_PCI_INTERRUPTS.
180*5113495bSYour Name  * Even when NOT forced, the driver may attempt to use legacy PCI interrupts
181*5113495bSYour Name  * MSI allocation fails
182*5113495bSYour Name  */
183*5113495bSYour Name #define LEGACY_INTERRUPTS(sc) ((sc)->num_msi_intrs == 0)
184*5113495bSYour Name 
185*5113495bSYour Name /*
186*5113495bSYour Name  * There may be some pending tx frames during platform suspend.
187*5113495bSYour Name  * Suspend operation should be delayed until those tx frames are
188*5113495bSYour Name  * transferred from the host to target. This macro specifies how
189*5113495bSYour Name  * long suspend thread has to sleep before checking pending tx
190*5113495bSYour Name  * frame count.
191*5113495bSYour Name  */
192*5113495bSYour Name #define OL_ATH_TX_DRAIN_WAIT_DELAY     50       /* ms */
193*5113495bSYour Name 
194*5113495bSYour Name #define HIF_CE_DRAIN_WAIT_DELAY        10       /* ms */
195*5113495bSYour Name /*
196*5113495bSYour Name  * Wait time (in unit of OL_ATH_TX_DRAIN_WAIT_DELAY) for pending
197*5113495bSYour Name  * tx frame completion before suspend. Refer: hif_pci_suspend()
198*5113495bSYour Name  */
199*5113495bSYour Name #ifndef QCA_WIFI_3_0_EMU
200*5113495bSYour Name #define OL_ATH_TX_DRAIN_WAIT_CNT       10
201*5113495bSYour Name #else
202*5113495bSYour Name #define OL_ATH_TX_DRAIN_WAIT_CNT       60
203*5113495bSYour Name #endif
204*5113495bSYour Name 
205*5113495bSYour Name #ifdef FORCE_WAKE
206*5113495bSYour Name /**
207*5113495bSYour Name  * hif_print_pci_stats() - Display HIF PCI stats
208*5113495bSYour Name  * @pci_scn: HIF pci handle
209*5113495bSYour Name  *
210*5113495bSYour Name  * Return: None
211*5113495bSYour Name  */
212*5113495bSYour Name void hif_print_pci_stats(struct hif_pci_softc *pci_scn);
213*5113495bSYour Name #else
214*5113495bSYour Name static inline
hif_print_pci_stats(struct hif_pci_softc * pci_scn)215*5113495bSYour Name void hif_print_pci_stats(struct hif_pci_softc *pci_scn)
216*5113495bSYour Name {
217*5113495bSYour Name }
218*5113495bSYour Name #endif /* FORCE_WAKE */
219*5113495bSYour Name #ifdef HIF_BUS_LOG_INFO
220*5113495bSYour Name bool hif_log_pcie_info(struct hif_softc *scn, uint8_t *data,
221*5113495bSYour Name 		       unsigned int *offset);
222*5113495bSYour Name #else
223*5113495bSYour Name static inline
hif_log_pcie_info(struct hif_softc * scn,uint8_t * data,unsigned int * offset)224*5113495bSYour Name bool hif_log_pcie_info(struct hif_softc *scn, uint8_t *data,
225*5113495bSYour Name 		       unsigned int *offset)
226*5113495bSYour Name {
227*5113495bSYour Name 	return false;
228*5113495bSYour Name }
229*5113495bSYour Name #endif
230*5113495bSYour Name #endif /* __ATH_PCI_H__ */
231