1*5c1def83SBjoern A. Zeeb // SPDX-License-Identifier: BSD-3-Clause-Clear
2*5c1def83SBjoern A. Zeeb /*
3*5c1def83SBjoern A. Zeeb * Copyright (c) 2020-2021 The Linux Foundation. All rights reserved.
4*5c1def83SBjoern A. Zeeb * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved.
5*5c1def83SBjoern A. Zeeb */
6*5c1def83SBjoern A. Zeeb
7*5c1def83SBjoern A. Zeeb #include <linux/msi.h>
8*5c1def83SBjoern A. Zeeb #include <linux/pci.h>
9*5c1def83SBjoern A. Zeeb #if defined(__FreeBSD__)
10*5c1def83SBjoern A. Zeeb #include <linux/delay.h>
11*5c1def83SBjoern A. Zeeb #endif
12*5c1def83SBjoern A. Zeeb
13*5c1def83SBjoern A. Zeeb #include "core.h"
14*5c1def83SBjoern A. Zeeb #include "debug.h"
15*5c1def83SBjoern A. Zeeb #include "mhi.h"
16*5c1def83SBjoern A. Zeeb #include "pci.h"
17*5c1def83SBjoern A. Zeeb
18*5c1def83SBjoern A. Zeeb #define MHI_TIMEOUT_DEFAULT_MS 90000
19*5c1def83SBjoern A. Zeeb
20*5c1def83SBjoern A. Zeeb static const struct mhi_channel_config ath12k_mhi_channels_qcn9274[] = {
21*5c1def83SBjoern A. Zeeb {
22*5c1def83SBjoern A. Zeeb .num = 0,
23*5c1def83SBjoern A. Zeeb .name = "LOOPBACK",
24*5c1def83SBjoern A. Zeeb .num_elements = 32,
25*5c1def83SBjoern A. Zeeb .event_ring = 1,
26*5c1def83SBjoern A. Zeeb .dir = DMA_TO_DEVICE,
27*5c1def83SBjoern A. Zeeb .ee_mask = 0x4,
28*5c1def83SBjoern A. Zeeb .pollcfg = 0,
29*5c1def83SBjoern A. Zeeb .doorbell = MHI_DB_BRST_DISABLE,
30*5c1def83SBjoern A. Zeeb .lpm_notify = false,
31*5c1def83SBjoern A. Zeeb .offload_channel = false,
32*5c1def83SBjoern A. Zeeb .doorbell_mode_switch = false,
33*5c1def83SBjoern A. Zeeb .auto_queue = false,
34*5c1def83SBjoern A. Zeeb },
35*5c1def83SBjoern A. Zeeb {
36*5c1def83SBjoern A. Zeeb .num = 1,
37*5c1def83SBjoern A. Zeeb .name = "LOOPBACK",
38*5c1def83SBjoern A. Zeeb .num_elements = 32,
39*5c1def83SBjoern A. Zeeb .event_ring = 1,
40*5c1def83SBjoern A. Zeeb .dir = DMA_FROM_DEVICE,
41*5c1def83SBjoern A. Zeeb .ee_mask = 0x4,
42*5c1def83SBjoern A. Zeeb .pollcfg = 0,
43*5c1def83SBjoern A. Zeeb .doorbell = MHI_DB_BRST_DISABLE,
44*5c1def83SBjoern A. Zeeb .lpm_notify = false,
45*5c1def83SBjoern A. Zeeb .offload_channel = false,
46*5c1def83SBjoern A. Zeeb .doorbell_mode_switch = false,
47*5c1def83SBjoern A. Zeeb .auto_queue = false,
48*5c1def83SBjoern A. Zeeb },
49*5c1def83SBjoern A. Zeeb {
50*5c1def83SBjoern A. Zeeb .num = 20,
51*5c1def83SBjoern A. Zeeb .name = "IPCR",
52*5c1def83SBjoern A. Zeeb .num_elements = 32,
53*5c1def83SBjoern A. Zeeb .event_ring = 1,
54*5c1def83SBjoern A. Zeeb .dir = DMA_TO_DEVICE,
55*5c1def83SBjoern A. Zeeb .ee_mask = 0x4,
56*5c1def83SBjoern A. Zeeb .pollcfg = 0,
57*5c1def83SBjoern A. Zeeb .doorbell = MHI_DB_BRST_DISABLE,
58*5c1def83SBjoern A. Zeeb .lpm_notify = false,
59*5c1def83SBjoern A. Zeeb .offload_channel = false,
60*5c1def83SBjoern A. Zeeb .doorbell_mode_switch = false,
61*5c1def83SBjoern A. Zeeb .auto_queue = false,
62*5c1def83SBjoern A. Zeeb },
63*5c1def83SBjoern A. Zeeb {
64*5c1def83SBjoern A. Zeeb .num = 21,
65*5c1def83SBjoern A. Zeeb .name = "IPCR",
66*5c1def83SBjoern A. Zeeb .num_elements = 32,
67*5c1def83SBjoern A. Zeeb .event_ring = 1,
68*5c1def83SBjoern A. Zeeb .dir = DMA_FROM_DEVICE,
69*5c1def83SBjoern A. Zeeb .ee_mask = 0x4,
70*5c1def83SBjoern A. Zeeb .pollcfg = 0,
71*5c1def83SBjoern A. Zeeb .doorbell = MHI_DB_BRST_DISABLE,
72*5c1def83SBjoern A. Zeeb .lpm_notify = false,
73*5c1def83SBjoern A. Zeeb .offload_channel = false,
74*5c1def83SBjoern A. Zeeb .doorbell_mode_switch = false,
75*5c1def83SBjoern A. Zeeb .auto_queue = true,
76*5c1def83SBjoern A. Zeeb },
77*5c1def83SBjoern A. Zeeb };
78*5c1def83SBjoern A. Zeeb
79*5c1def83SBjoern A. Zeeb static struct mhi_event_config ath12k_mhi_events_qcn9274[] = {
80*5c1def83SBjoern A. Zeeb {
81*5c1def83SBjoern A. Zeeb .num_elements = 32,
82*5c1def83SBjoern A. Zeeb .irq_moderation_ms = 0,
83*5c1def83SBjoern A. Zeeb .irq = 1,
84*5c1def83SBjoern A. Zeeb .data_type = MHI_ER_CTRL,
85*5c1def83SBjoern A. Zeeb .mode = MHI_DB_BRST_DISABLE,
86*5c1def83SBjoern A. Zeeb .hardware_event = false,
87*5c1def83SBjoern A. Zeeb .client_managed = false,
88*5c1def83SBjoern A. Zeeb .offload_channel = false,
89*5c1def83SBjoern A. Zeeb },
90*5c1def83SBjoern A. Zeeb {
91*5c1def83SBjoern A. Zeeb .num_elements = 256,
92*5c1def83SBjoern A. Zeeb .irq_moderation_ms = 1,
93*5c1def83SBjoern A. Zeeb .irq = 2,
94*5c1def83SBjoern A. Zeeb .mode = MHI_DB_BRST_DISABLE,
95*5c1def83SBjoern A. Zeeb .priority = 1,
96*5c1def83SBjoern A. Zeeb .hardware_event = false,
97*5c1def83SBjoern A. Zeeb .client_managed = false,
98*5c1def83SBjoern A. Zeeb .offload_channel = false,
99*5c1def83SBjoern A. Zeeb },
100*5c1def83SBjoern A. Zeeb };
101*5c1def83SBjoern A. Zeeb
102*5c1def83SBjoern A. Zeeb const struct mhi_controller_config ath12k_mhi_config_qcn9274 = {
103*5c1def83SBjoern A. Zeeb .max_channels = 30,
104*5c1def83SBjoern A. Zeeb .timeout_ms = 10000,
105*5c1def83SBjoern A. Zeeb .use_bounce_buf = false,
106*5c1def83SBjoern A. Zeeb .buf_len = 0,
107*5c1def83SBjoern A. Zeeb .num_channels = ARRAY_SIZE(ath12k_mhi_channels_qcn9274),
108*5c1def83SBjoern A. Zeeb .ch_cfg = ath12k_mhi_channels_qcn9274,
109*5c1def83SBjoern A. Zeeb .num_events = ARRAY_SIZE(ath12k_mhi_events_qcn9274),
110*5c1def83SBjoern A. Zeeb .event_cfg = ath12k_mhi_events_qcn9274,
111*5c1def83SBjoern A. Zeeb };
112*5c1def83SBjoern A. Zeeb
113*5c1def83SBjoern A. Zeeb static const struct mhi_channel_config ath12k_mhi_channels_wcn7850[] = {
114*5c1def83SBjoern A. Zeeb {
115*5c1def83SBjoern A. Zeeb .num = 0,
116*5c1def83SBjoern A. Zeeb .name = "LOOPBACK",
117*5c1def83SBjoern A. Zeeb .num_elements = 32,
118*5c1def83SBjoern A. Zeeb .event_ring = 0,
119*5c1def83SBjoern A. Zeeb .dir = DMA_TO_DEVICE,
120*5c1def83SBjoern A. Zeeb .ee_mask = 0x4,
121*5c1def83SBjoern A. Zeeb .pollcfg = 0,
122*5c1def83SBjoern A. Zeeb .doorbell = MHI_DB_BRST_DISABLE,
123*5c1def83SBjoern A. Zeeb .lpm_notify = false,
124*5c1def83SBjoern A. Zeeb .offload_channel = false,
125*5c1def83SBjoern A. Zeeb .doorbell_mode_switch = false,
126*5c1def83SBjoern A. Zeeb .auto_queue = false,
127*5c1def83SBjoern A. Zeeb },
128*5c1def83SBjoern A. Zeeb {
129*5c1def83SBjoern A. Zeeb .num = 1,
130*5c1def83SBjoern A. Zeeb .name = "LOOPBACK",
131*5c1def83SBjoern A. Zeeb .num_elements = 32,
132*5c1def83SBjoern A. Zeeb .event_ring = 0,
133*5c1def83SBjoern A. Zeeb .dir = DMA_FROM_DEVICE,
134*5c1def83SBjoern A. Zeeb .ee_mask = 0x4,
135*5c1def83SBjoern A. Zeeb .pollcfg = 0,
136*5c1def83SBjoern A. Zeeb .doorbell = MHI_DB_BRST_DISABLE,
137*5c1def83SBjoern A. Zeeb .lpm_notify = false,
138*5c1def83SBjoern A. Zeeb .offload_channel = false,
139*5c1def83SBjoern A. Zeeb .doorbell_mode_switch = false,
140*5c1def83SBjoern A. Zeeb .auto_queue = false,
141*5c1def83SBjoern A. Zeeb },
142*5c1def83SBjoern A. Zeeb {
143*5c1def83SBjoern A. Zeeb .num = 20,
144*5c1def83SBjoern A. Zeeb .name = "IPCR",
145*5c1def83SBjoern A. Zeeb .num_elements = 64,
146*5c1def83SBjoern A. Zeeb .event_ring = 1,
147*5c1def83SBjoern A. Zeeb .dir = DMA_TO_DEVICE,
148*5c1def83SBjoern A. Zeeb .ee_mask = 0x4,
149*5c1def83SBjoern A. Zeeb .pollcfg = 0,
150*5c1def83SBjoern A. Zeeb .doorbell = MHI_DB_BRST_DISABLE,
151*5c1def83SBjoern A. Zeeb .lpm_notify = false,
152*5c1def83SBjoern A. Zeeb .offload_channel = false,
153*5c1def83SBjoern A. Zeeb .doorbell_mode_switch = false,
154*5c1def83SBjoern A. Zeeb .auto_queue = false,
155*5c1def83SBjoern A. Zeeb },
156*5c1def83SBjoern A. Zeeb {
157*5c1def83SBjoern A. Zeeb .num = 21,
158*5c1def83SBjoern A. Zeeb .name = "IPCR",
159*5c1def83SBjoern A. Zeeb .num_elements = 64,
160*5c1def83SBjoern A. Zeeb .event_ring = 1,
161*5c1def83SBjoern A. Zeeb .dir = DMA_FROM_DEVICE,
162*5c1def83SBjoern A. Zeeb .ee_mask = 0x4,
163*5c1def83SBjoern A. Zeeb .pollcfg = 0,
164*5c1def83SBjoern A. Zeeb .doorbell = MHI_DB_BRST_DISABLE,
165*5c1def83SBjoern A. Zeeb .lpm_notify = false,
166*5c1def83SBjoern A. Zeeb .offload_channel = false,
167*5c1def83SBjoern A. Zeeb .doorbell_mode_switch = false,
168*5c1def83SBjoern A. Zeeb .auto_queue = true,
169*5c1def83SBjoern A. Zeeb },
170*5c1def83SBjoern A. Zeeb };
171*5c1def83SBjoern A. Zeeb
172*5c1def83SBjoern A. Zeeb static struct mhi_event_config ath12k_mhi_events_wcn7850[] = {
173*5c1def83SBjoern A. Zeeb {
174*5c1def83SBjoern A. Zeeb .num_elements = 32,
175*5c1def83SBjoern A. Zeeb .irq_moderation_ms = 0,
176*5c1def83SBjoern A. Zeeb .irq = 1,
177*5c1def83SBjoern A. Zeeb .mode = MHI_DB_BRST_DISABLE,
178*5c1def83SBjoern A. Zeeb .data_type = MHI_ER_CTRL,
179*5c1def83SBjoern A. Zeeb .hardware_event = false,
180*5c1def83SBjoern A. Zeeb .client_managed = false,
181*5c1def83SBjoern A. Zeeb .offload_channel = false,
182*5c1def83SBjoern A. Zeeb },
183*5c1def83SBjoern A. Zeeb {
184*5c1def83SBjoern A. Zeeb .num_elements = 256,
185*5c1def83SBjoern A. Zeeb .irq_moderation_ms = 1,
186*5c1def83SBjoern A. Zeeb .irq = 2,
187*5c1def83SBjoern A. Zeeb .mode = MHI_DB_BRST_DISABLE,
188*5c1def83SBjoern A. Zeeb .priority = 1,
189*5c1def83SBjoern A. Zeeb .hardware_event = false,
190*5c1def83SBjoern A. Zeeb .client_managed = false,
191*5c1def83SBjoern A. Zeeb .offload_channel = false,
192*5c1def83SBjoern A. Zeeb },
193*5c1def83SBjoern A. Zeeb };
194*5c1def83SBjoern A. Zeeb
195*5c1def83SBjoern A. Zeeb const struct mhi_controller_config ath12k_mhi_config_wcn7850 = {
196*5c1def83SBjoern A. Zeeb .max_channels = 128,
197*5c1def83SBjoern A. Zeeb .timeout_ms = 2000,
198*5c1def83SBjoern A. Zeeb .use_bounce_buf = false,
199*5c1def83SBjoern A. Zeeb .buf_len = 0,
200*5c1def83SBjoern A. Zeeb .num_channels = ARRAY_SIZE(ath12k_mhi_channels_wcn7850),
201*5c1def83SBjoern A. Zeeb .ch_cfg = ath12k_mhi_channels_wcn7850,
202*5c1def83SBjoern A. Zeeb .num_events = ARRAY_SIZE(ath12k_mhi_events_wcn7850),
203*5c1def83SBjoern A. Zeeb .event_cfg = ath12k_mhi_events_wcn7850,
204*5c1def83SBjoern A. Zeeb };
205*5c1def83SBjoern A. Zeeb
ath12k_mhi_set_mhictrl_reset(struct ath12k_base * ab)206*5c1def83SBjoern A. Zeeb void ath12k_mhi_set_mhictrl_reset(struct ath12k_base *ab)
207*5c1def83SBjoern A. Zeeb {
208*5c1def83SBjoern A. Zeeb u32 val;
209*5c1def83SBjoern A. Zeeb
210*5c1def83SBjoern A. Zeeb val = ath12k_pci_read32(ab, MHISTATUS);
211*5c1def83SBjoern A. Zeeb
212*5c1def83SBjoern A. Zeeb ath12k_dbg(ab, ATH12K_DBG_PCI, "MHISTATUS 0x%x\n", val);
213*5c1def83SBjoern A. Zeeb
214*5c1def83SBjoern A. Zeeb /* Observed on some targets that after SOC_GLOBAL_RESET, MHISTATUS
215*5c1def83SBjoern A. Zeeb * has SYSERR bit set and thus need to set MHICTRL_RESET
216*5c1def83SBjoern A. Zeeb * to clear SYSERR.
217*5c1def83SBjoern A. Zeeb */
218*5c1def83SBjoern A. Zeeb ath12k_pci_write32(ab, MHICTRL, MHICTRL_RESET_MASK);
219*5c1def83SBjoern A. Zeeb
220*5c1def83SBjoern A. Zeeb mdelay(10);
221*5c1def83SBjoern A. Zeeb }
222*5c1def83SBjoern A. Zeeb
ath12k_mhi_reset_txvecdb(struct ath12k_base * ab)223*5c1def83SBjoern A. Zeeb static void ath12k_mhi_reset_txvecdb(struct ath12k_base *ab)
224*5c1def83SBjoern A. Zeeb {
225*5c1def83SBjoern A. Zeeb ath12k_pci_write32(ab, PCIE_TXVECDB, 0);
226*5c1def83SBjoern A. Zeeb }
227*5c1def83SBjoern A. Zeeb
ath12k_mhi_reset_txvecstatus(struct ath12k_base * ab)228*5c1def83SBjoern A. Zeeb static void ath12k_mhi_reset_txvecstatus(struct ath12k_base *ab)
229*5c1def83SBjoern A. Zeeb {
230*5c1def83SBjoern A. Zeeb ath12k_pci_write32(ab, PCIE_TXVECSTATUS, 0);
231*5c1def83SBjoern A. Zeeb }
232*5c1def83SBjoern A. Zeeb
ath12k_mhi_reset_rxvecdb(struct ath12k_base * ab)233*5c1def83SBjoern A. Zeeb static void ath12k_mhi_reset_rxvecdb(struct ath12k_base *ab)
234*5c1def83SBjoern A. Zeeb {
235*5c1def83SBjoern A. Zeeb ath12k_pci_write32(ab, PCIE_RXVECDB, 0);
236*5c1def83SBjoern A. Zeeb }
237*5c1def83SBjoern A. Zeeb
ath12k_mhi_reset_rxvecstatus(struct ath12k_base * ab)238*5c1def83SBjoern A. Zeeb static void ath12k_mhi_reset_rxvecstatus(struct ath12k_base *ab)
239*5c1def83SBjoern A. Zeeb {
240*5c1def83SBjoern A. Zeeb ath12k_pci_write32(ab, PCIE_RXVECSTATUS, 0);
241*5c1def83SBjoern A. Zeeb }
242*5c1def83SBjoern A. Zeeb
ath12k_mhi_clear_vector(struct ath12k_base * ab)243*5c1def83SBjoern A. Zeeb void ath12k_mhi_clear_vector(struct ath12k_base *ab)
244*5c1def83SBjoern A. Zeeb {
245*5c1def83SBjoern A. Zeeb ath12k_mhi_reset_txvecdb(ab);
246*5c1def83SBjoern A. Zeeb ath12k_mhi_reset_txvecstatus(ab);
247*5c1def83SBjoern A. Zeeb ath12k_mhi_reset_rxvecdb(ab);
248*5c1def83SBjoern A. Zeeb ath12k_mhi_reset_rxvecstatus(ab);
249*5c1def83SBjoern A. Zeeb }
250*5c1def83SBjoern A. Zeeb
ath12k_mhi_get_msi(struct ath12k_pci * ab_pci)251*5c1def83SBjoern A. Zeeb static int ath12k_mhi_get_msi(struct ath12k_pci *ab_pci)
252*5c1def83SBjoern A. Zeeb {
253*5c1def83SBjoern A. Zeeb struct ath12k_base *ab = ab_pci->ab;
254*5c1def83SBjoern A. Zeeb u32 user_base_data, base_vector;
255*5c1def83SBjoern A. Zeeb int ret, num_vectors, i;
256*5c1def83SBjoern A. Zeeb int *irq;
257*5c1def83SBjoern A. Zeeb
258*5c1def83SBjoern A. Zeeb ret = ath12k_pci_get_user_msi_assignment(ab,
259*5c1def83SBjoern A. Zeeb "MHI", &num_vectors,
260*5c1def83SBjoern A. Zeeb &user_base_data, &base_vector);
261*5c1def83SBjoern A. Zeeb if (ret)
262*5c1def83SBjoern A. Zeeb return ret;
263*5c1def83SBjoern A. Zeeb
264*5c1def83SBjoern A. Zeeb ath12k_dbg(ab, ATH12K_DBG_PCI, "Number of assigned MSI for MHI is %d, base vector is %d\n",
265*5c1def83SBjoern A. Zeeb num_vectors, base_vector);
266*5c1def83SBjoern A. Zeeb
267*5c1def83SBjoern A. Zeeb irq = kcalloc(num_vectors, sizeof(*irq), GFP_KERNEL);
268*5c1def83SBjoern A. Zeeb if (!irq)
269*5c1def83SBjoern A. Zeeb return -ENOMEM;
270*5c1def83SBjoern A. Zeeb
271*5c1def83SBjoern A. Zeeb for (i = 0; i < num_vectors; i++)
272*5c1def83SBjoern A. Zeeb irq[i] = ath12k_pci_get_msi_irq(ab->dev,
273*5c1def83SBjoern A. Zeeb base_vector + i);
274*5c1def83SBjoern A. Zeeb
275*5c1def83SBjoern A. Zeeb ab_pci->mhi_ctrl->irq = irq;
276*5c1def83SBjoern A. Zeeb ab_pci->mhi_ctrl->nr_irqs = num_vectors;
277*5c1def83SBjoern A. Zeeb
278*5c1def83SBjoern A. Zeeb return 0;
279*5c1def83SBjoern A. Zeeb }
280*5c1def83SBjoern A. Zeeb
ath12k_mhi_op_runtime_get(struct mhi_controller * mhi_cntrl)281*5c1def83SBjoern A. Zeeb static int ath12k_mhi_op_runtime_get(struct mhi_controller *mhi_cntrl)
282*5c1def83SBjoern A. Zeeb {
283*5c1def83SBjoern A. Zeeb return 0;
284*5c1def83SBjoern A. Zeeb }
285*5c1def83SBjoern A. Zeeb
ath12k_mhi_op_runtime_put(struct mhi_controller * mhi_cntrl)286*5c1def83SBjoern A. Zeeb static void ath12k_mhi_op_runtime_put(struct mhi_controller *mhi_cntrl)
287*5c1def83SBjoern A. Zeeb {
288*5c1def83SBjoern A. Zeeb }
289*5c1def83SBjoern A. Zeeb
ath12k_mhi_op_callback_to_str(enum mhi_callback reason)290*5c1def83SBjoern A. Zeeb static char *ath12k_mhi_op_callback_to_str(enum mhi_callback reason)
291*5c1def83SBjoern A. Zeeb {
292*5c1def83SBjoern A. Zeeb switch (reason) {
293*5c1def83SBjoern A. Zeeb case MHI_CB_IDLE:
294*5c1def83SBjoern A. Zeeb return "MHI_CB_IDLE";
295*5c1def83SBjoern A. Zeeb case MHI_CB_PENDING_DATA:
296*5c1def83SBjoern A. Zeeb return "MHI_CB_PENDING_DATA";
297*5c1def83SBjoern A. Zeeb case MHI_CB_LPM_ENTER:
298*5c1def83SBjoern A. Zeeb return "MHI_CB_LPM_ENTER";
299*5c1def83SBjoern A. Zeeb case MHI_CB_LPM_EXIT:
300*5c1def83SBjoern A. Zeeb return "MHI_CB_LPM_EXIT";
301*5c1def83SBjoern A. Zeeb case MHI_CB_EE_RDDM:
302*5c1def83SBjoern A. Zeeb return "MHI_CB_EE_RDDM";
303*5c1def83SBjoern A. Zeeb case MHI_CB_EE_MISSION_MODE:
304*5c1def83SBjoern A. Zeeb return "MHI_CB_EE_MISSION_MODE";
305*5c1def83SBjoern A. Zeeb case MHI_CB_SYS_ERROR:
306*5c1def83SBjoern A. Zeeb return "MHI_CB_SYS_ERROR";
307*5c1def83SBjoern A. Zeeb case MHI_CB_FATAL_ERROR:
308*5c1def83SBjoern A. Zeeb return "MHI_CB_FATAL_ERROR";
309*5c1def83SBjoern A. Zeeb case MHI_CB_BW_REQ:
310*5c1def83SBjoern A. Zeeb return "MHI_CB_BW_REQ";
311*5c1def83SBjoern A. Zeeb default:
312*5c1def83SBjoern A. Zeeb return "UNKNOWN";
313*5c1def83SBjoern A. Zeeb }
314*5c1def83SBjoern A. Zeeb }
315*5c1def83SBjoern A. Zeeb
ath12k_mhi_op_status_cb(struct mhi_controller * mhi_cntrl,enum mhi_callback cb)316*5c1def83SBjoern A. Zeeb static void ath12k_mhi_op_status_cb(struct mhi_controller *mhi_cntrl,
317*5c1def83SBjoern A. Zeeb enum mhi_callback cb)
318*5c1def83SBjoern A. Zeeb {
319*5c1def83SBjoern A. Zeeb struct ath12k_base *ab = dev_get_drvdata(mhi_cntrl->cntrl_dev);
320*5c1def83SBjoern A. Zeeb
321*5c1def83SBjoern A. Zeeb ath12k_dbg(ab, ATH12K_DBG_BOOT, "mhi notify status reason %s\n",
322*5c1def83SBjoern A. Zeeb ath12k_mhi_op_callback_to_str(cb));
323*5c1def83SBjoern A. Zeeb
324*5c1def83SBjoern A. Zeeb switch (cb) {
325*5c1def83SBjoern A. Zeeb case MHI_CB_SYS_ERROR:
326*5c1def83SBjoern A. Zeeb ath12k_warn(ab, "firmware crashed: MHI_CB_SYS_ERROR\n");
327*5c1def83SBjoern A. Zeeb break;
328*5c1def83SBjoern A. Zeeb case MHI_CB_EE_RDDM:
329*5c1def83SBjoern A. Zeeb if (!(test_bit(ATH12K_FLAG_UNREGISTERING, &ab->dev_flags)))
330*5c1def83SBjoern A. Zeeb queue_work(ab->workqueue_aux, &ab->reset_work);
331*5c1def83SBjoern A. Zeeb break;
332*5c1def83SBjoern A. Zeeb default:
333*5c1def83SBjoern A. Zeeb break;
334*5c1def83SBjoern A. Zeeb }
335*5c1def83SBjoern A. Zeeb }
336*5c1def83SBjoern A. Zeeb
ath12k_mhi_op_read_reg(struct mhi_controller * mhi_cntrl,void __iomem * addr,u32 * out)337*5c1def83SBjoern A. Zeeb static int ath12k_mhi_op_read_reg(struct mhi_controller *mhi_cntrl,
338*5c1def83SBjoern A. Zeeb void __iomem *addr,
339*5c1def83SBjoern A. Zeeb u32 *out)
340*5c1def83SBjoern A. Zeeb {
341*5c1def83SBjoern A. Zeeb *out = readl(addr);
342*5c1def83SBjoern A. Zeeb
343*5c1def83SBjoern A. Zeeb return 0;
344*5c1def83SBjoern A. Zeeb }
345*5c1def83SBjoern A. Zeeb
ath12k_mhi_op_write_reg(struct mhi_controller * mhi_cntrl,void __iomem * addr,u32 val)346*5c1def83SBjoern A. Zeeb static void ath12k_mhi_op_write_reg(struct mhi_controller *mhi_cntrl,
347*5c1def83SBjoern A. Zeeb void __iomem *addr,
348*5c1def83SBjoern A. Zeeb u32 val)
349*5c1def83SBjoern A. Zeeb {
350*5c1def83SBjoern A. Zeeb writel(val, addr);
351*5c1def83SBjoern A. Zeeb }
352*5c1def83SBjoern A. Zeeb
ath12k_mhi_register(struct ath12k_pci * ab_pci)353*5c1def83SBjoern A. Zeeb int ath12k_mhi_register(struct ath12k_pci *ab_pci)
354*5c1def83SBjoern A. Zeeb {
355*5c1def83SBjoern A. Zeeb struct ath12k_base *ab = ab_pci->ab;
356*5c1def83SBjoern A. Zeeb struct mhi_controller *mhi_ctrl;
357*5c1def83SBjoern A. Zeeb int ret;
358*5c1def83SBjoern A. Zeeb
359*5c1def83SBjoern A. Zeeb mhi_ctrl = mhi_alloc_controller();
360*5c1def83SBjoern A. Zeeb if (!mhi_ctrl)
361*5c1def83SBjoern A. Zeeb return -ENOMEM;
362*5c1def83SBjoern A. Zeeb
363*5c1def83SBjoern A. Zeeb ath12k_core_create_firmware_path(ab, ATH12K_AMSS_FILE,
364*5c1def83SBjoern A. Zeeb ab_pci->amss_path,
365*5c1def83SBjoern A. Zeeb sizeof(ab_pci->amss_path));
366*5c1def83SBjoern A. Zeeb
367*5c1def83SBjoern A. Zeeb ab_pci->mhi_ctrl = mhi_ctrl;
368*5c1def83SBjoern A. Zeeb mhi_ctrl->cntrl_dev = ab->dev;
369*5c1def83SBjoern A. Zeeb mhi_ctrl->fw_image = ab_pci->amss_path;
370*5c1def83SBjoern A. Zeeb mhi_ctrl->regs = ab->mem;
371*5c1def83SBjoern A. Zeeb mhi_ctrl->reg_len = ab->mem_len;
372*5c1def83SBjoern A. Zeeb
373*5c1def83SBjoern A. Zeeb ret = ath12k_mhi_get_msi(ab_pci);
374*5c1def83SBjoern A. Zeeb if (ret) {
375*5c1def83SBjoern A. Zeeb ath12k_err(ab, "failed to get msi for mhi\n");
376*5c1def83SBjoern A. Zeeb mhi_free_controller(mhi_ctrl);
377*5c1def83SBjoern A. Zeeb return ret;
378*5c1def83SBjoern A. Zeeb }
379*5c1def83SBjoern A. Zeeb
380*5c1def83SBjoern A. Zeeb mhi_ctrl->iova_start = 0;
381*5c1def83SBjoern A. Zeeb mhi_ctrl->iova_stop = 0xffffffff;
382*5c1def83SBjoern A. Zeeb mhi_ctrl->sbl_size = SZ_512K;
383*5c1def83SBjoern A. Zeeb mhi_ctrl->seg_len = SZ_512K;
384*5c1def83SBjoern A. Zeeb mhi_ctrl->fbc_download = true;
385*5c1def83SBjoern A. Zeeb mhi_ctrl->runtime_get = ath12k_mhi_op_runtime_get;
386*5c1def83SBjoern A. Zeeb mhi_ctrl->runtime_put = ath12k_mhi_op_runtime_put;
387*5c1def83SBjoern A. Zeeb mhi_ctrl->status_cb = ath12k_mhi_op_status_cb;
388*5c1def83SBjoern A. Zeeb mhi_ctrl->read_reg = ath12k_mhi_op_read_reg;
389*5c1def83SBjoern A. Zeeb mhi_ctrl->write_reg = ath12k_mhi_op_write_reg;
390*5c1def83SBjoern A. Zeeb
391*5c1def83SBjoern A. Zeeb ret = mhi_register_controller(mhi_ctrl, ab->hw_params->mhi_config);
392*5c1def83SBjoern A. Zeeb if (ret) {
393*5c1def83SBjoern A. Zeeb ath12k_err(ab, "failed to register to mhi bus, err = %d\n", ret);
394*5c1def83SBjoern A. Zeeb mhi_free_controller(mhi_ctrl);
395*5c1def83SBjoern A. Zeeb return ret;
396*5c1def83SBjoern A. Zeeb }
397*5c1def83SBjoern A. Zeeb
398*5c1def83SBjoern A. Zeeb return 0;
399*5c1def83SBjoern A. Zeeb }
400*5c1def83SBjoern A. Zeeb
ath12k_mhi_unregister(struct ath12k_pci * ab_pci)401*5c1def83SBjoern A. Zeeb void ath12k_mhi_unregister(struct ath12k_pci *ab_pci)
402*5c1def83SBjoern A. Zeeb {
403*5c1def83SBjoern A. Zeeb struct mhi_controller *mhi_ctrl = ab_pci->mhi_ctrl;
404*5c1def83SBjoern A. Zeeb
405*5c1def83SBjoern A. Zeeb mhi_unregister_controller(mhi_ctrl);
406*5c1def83SBjoern A. Zeeb kfree(mhi_ctrl->irq);
407*5c1def83SBjoern A. Zeeb mhi_free_controller(mhi_ctrl);
408*5c1def83SBjoern A. Zeeb ab_pci->mhi_ctrl = NULL;
409*5c1def83SBjoern A. Zeeb }
410*5c1def83SBjoern A. Zeeb
ath12k_mhi_state_to_str(enum ath12k_mhi_state mhi_state)411*5c1def83SBjoern A. Zeeb static char *ath12k_mhi_state_to_str(enum ath12k_mhi_state mhi_state)
412*5c1def83SBjoern A. Zeeb {
413*5c1def83SBjoern A. Zeeb switch (mhi_state) {
414*5c1def83SBjoern A. Zeeb case ATH12K_MHI_INIT:
415*5c1def83SBjoern A. Zeeb return "INIT";
416*5c1def83SBjoern A. Zeeb case ATH12K_MHI_DEINIT:
417*5c1def83SBjoern A. Zeeb return "DEINIT";
418*5c1def83SBjoern A. Zeeb case ATH12K_MHI_POWER_ON:
419*5c1def83SBjoern A. Zeeb return "POWER_ON";
420*5c1def83SBjoern A. Zeeb case ATH12K_MHI_POWER_OFF:
421*5c1def83SBjoern A. Zeeb return "POWER_OFF";
422*5c1def83SBjoern A. Zeeb case ATH12K_MHI_FORCE_POWER_OFF:
423*5c1def83SBjoern A. Zeeb return "FORCE_POWER_OFF";
424*5c1def83SBjoern A. Zeeb case ATH12K_MHI_SUSPEND:
425*5c1def83SBjoern A. Zeeb return "SUSPEND";
426*5c1def83SBjoern A. Zeeb case ATH12K_MHI_RESUME:
427*5c1def83SBjoern A. Zeeb return "RESUME";
428*5c1def83SBjoern A. Zeeb case ATH12K_MHI_TRIGGER_RDDM:
429*5c1def83SBjoern A. Zeeb return "TRIGGER_RDDM";
430*5c1def83SBjoern A. Zeeb case ATH12K_MHI_RDDM_DONE:
431*5c1def83SBjoern A. Zeeb return "RDDM_DONE";
432*5c1def83SBjoern A. Zeeb default:
433*5c1def83SBjoern A. Zeeb return "UNKNOWN";
434*5c1def83SBjoern A. Zeeb }
435*5c1def83SBjoern A. Zeeb };
436*5c1def83SBjoern A. Zeeb
ath12k_mhi_set_state_bit(struct ath12k_pci * ab_pci,enum ath12k_mhi_state mhi_state)437*5c1def83SBjoern A. Zeeb static void ath12k_mhi_set_state_bit(struct ath12k_pci *ab_pci,
438*5c1def83SBjoern A. Zeeb enum ath12k_mhi_state mhi_state)
439*5c1def83SBjoern A. Zeeb {
440*5c1def83SBjoern A. Zeeb struct ath12k_base *ab = ab_pci->ab;
441*5c1def83SBjoern A. Zeeb
442*5c1def83SBjoern A. Zeeb switch (mhi_state) {
443*5c1def83SBjoern A. Zeeb case ATH12K_MHI_INIT:
444*5c1def83SBjoern A. Zeeb set_bit(ATH12K_MHI_INIT, &ab_pci->mhi_state);
445*5c1def83SBjoern A. Zeeb break;
446*5c1def83SBjoern A. Zeeb case ATH12K_MHI_DEINIT:
447*5c1def83SBjoern A. Zeeb clear_bit(ATH12K_MHI_INIT, &ab_pci->mhi_state);
448*5c1def83SBjoern A. Zeeb break;
449*5c1def83SBjoern A. Zeeb case ATH12K_MHI_POWER_ON:
450*5c1def83SBjoern A. Zeeb set_bit(ATH12K_MHI_POWER_ON, &ab_pci->mhi_state);
451*5c1def83SBjoern A. Zeeb break;
452*5c1def83SBjoern A. Zeeb case ATH12K_MHI_POWER_OFF:
453*5c1def83SBjoern A. Zeeb case ATH12K_MHI_FORCE_POWER_OFF:
454*5c1def83SBjoern A. Zeeb clear_bit(ATH12K_MHI_POWER_ON, &ab_pci->mhi_state);
455*5c1def83SBjoern A. Zeeb clear_bit(ATH12K_MHI_TRIGGER_RDDM, &ab_pci->mhi_state);
456*5c1def83SBjoern A. Zeeb clear_bit(ATH12K_MHI_RDDM_DONE, &ab_pci->mhi_state);
457*5c1def83SBjoern A. Zeeb break;
458*5c1def83SBjoern A. Zeeb case ATH12K_MHI_SUSPEND:
459*5c1def83SBjoern A. Zeeb set_bit(ATH12K_MHI_SUSPEND, &ab_pci->mhi_state);
460*5c1def83SBjoern A. Zeeb break;
461*5c1def83SBjoern A. Zeeb case ATH12K_MHI_RESUME:
462*5c1def83SBjoern A. Zeeb clear_bit(ATH12K_MHI_SUSPEND, &ab_pci->mhi_state);
463*5c1def83SBjoern A. Zeeb break;
464*5c1def83SBjoern A. Zeeb case ATH12K_MHI_TRIGGER_RDDM:
465*5c1def83SBjoern A. Zeeb set_bit(ATH12K_MHI_TRIGGER_RDDM, &ab_pci->mhi_state);
466*5c1def83SBjoern A. Zeeb break;
467*5c1def83SBjoern A. Zeeb case ATH12K_MHI_RDDM_DONE:
468*5c1def83SBjoern A. Zeeb set_bit(ATH12K_MHI_RDDM_DONE, &ab_pci->mhi_state);
469*5c1def83SBjoern A. Zeeb break;
470*5c1def83SBjoern A. Zeeb default:
471*5c1def83SBjoern A. Zeeb ath12k_err(ab, "unhandled mhi state (%d)\n", mhi_state);
472*5c1def83SBjoern A. Zeeb }
473*5c1def83SBjoern A. Zeeb }
474*5c1def83SBjoern A. Zeeb
ath12k_mhi_check_state_bit(struct ath12k_pci * ab_pci,enum ath12k_mhi_state mhi_state)475*5c1def83SBjoern A. Zeeb static int ath12k_mhi_check_state_bit(struct ath12k_pci *ab_pci,
476*5c1def83SBjoern A. Zeeb enum ath12k_mhi_state mhi_state)
477*5c1def83SBjoern A. Zeeb {
478*5c1def83SBjoern A. Zeeb struct ath12k_base *ab = ab_pci->ab;
479*5c1def83SBjoern A. Zeeb
480*5c1def83SBjoern A. Zeeb switch (mhi_state) {
481*5c1def83SBjoern A. Zeeb case ATH12K_MHI_INIT:
482*5c1def83SBjoern A. Zeeb if (!test_bit(ATH12K_MHI_INIT, &ab_pci->mhi_state))
483*5c1def83SBjoern A. Zeeb return 0;
484*5c1def83SBjoern A. Zeeb break;
485*5c1def83SBjoern A. Zeeb case ATH12K_MHI_DEINIT:
486*5c1def83SBjoern A. Zeeb case ATH12K_MHI_POWER_ON:
487*5c1def83SBjoern A. Zeeb if (test_bit(ATH12K_MHI_INIT, &ab_pci->mhi_state) &&
488*5c1def83SBjoern A. Zeeb !test_bit(ATH12K_MHI_POWER_ON, &ab_pci->mhi_state))
489*5c1def83SBjoern A. Zeeb return 0;
490*5c1def83SBjoern A. Zeeb break;
491*5c1def83SBjoern A. Zeeb case ATH12K_MHI_FORCE_POWER_OFF:
492*5c1def83SBjoern A. Zeeb if (test_bit(ATH12K_MHI_POWER_ON, &ab_pci->mhi_state))
493*5c1def83SBjoern A. Zeeb return 0;
494*5c1def83SBjoern A. Zeeb break;
495*5c1def83SBjoern A. Zeeb case ATH12K_MHI_POWER_OFF:
496*5c1def83SBjoern A. Zeeb case ATH12K_MHI_SUSPEND:
497*5c1def83SBjoern A. Zeeb if (test_bit(ATH12K_MHI_POWER_ON, &ab_pci->mhi_state) &&
498*5c1def83SBjoern A. Zeeb !test_bit(ATH12K_MHI_SUSPEND, &ab_pci->mhi_state))
499*5c1def83SBjoern A. Zeeb return 0;
500*5c1def83SBjoern A. Zeeb break;
501*5c1def83SBjoern A. Zeeb case ATH12K_MHI_RESUME:
502*5c1def83SBjoern A. Zeeb if (test_bit(ATH12K_MHI_SUSPEND, &ab_pci->mhi_state))
503*5c1def83SBjoern A. Zeeb return 0;
504*5c1def83SBjoern A. Zeeb break;
505*5c1def83SBjoern A. Zeeb case ATH12K_MHI_TRIGGER_RDDM:
506*5c1def83SBjoern A. Zeeb if (test_bit(ATH12K_MHI_POWER_ON, &ab_pci->mhi_state) &&
507*5c1def83SBjoern A. Zeeb !test_bit(ATH12K_MHI_TRIGGER_RDDM, &ab_pci->mhi_state))
508*5c1def83SBjoern A. Zeeb return 0;
509*5c1def83SBjoern A. Zeeb break;
510*5c1def83SBjoern A. Zeeb case ATH12K_MHI_RDDM_DONE:
511*5c1def83SBjoern A. Zeeb return 0;
512*5c1def83SBjoern A. Zeeb default:
513*5c1def83SBjoern A. Zeeb ath12k_err(ab, "unhandled mhi state: %s(%d)\n",
514*5c1def83SBjoern A. Zeeb ath12k_mhi_state_to_str(mhi_state), mhi_state);
515*5c1def83SBjoern A. Zeeb }
516*5c1def83SBjoern A. Zeeb
517*5c1def83SBjoern A. Zeeb ath12k_err(ab, "failed to set mhi state %s(%d) in current mhi state (0x%lx)\n",
518*5c1def83SBjoern A. Zeeb ath12k_mhi_state_to_str(mhi_state), mhi_state,
519*5c1def83SBjoern A. Zeeb ab_pci->mhi_state);
520*5c1def83SBjoern A. Zeeb
521*5c1def83SBjoern A. Zeeb return -EINVAL;
522*5c1def83SBjoern A. Zeeb }
523*5c1def83SBjoern A. Zeeb
ath12k_mhi_set_state(struct ath12k_pci * ab_pci,enum ath12k_mhi_state mhi_state)524*5c1def83SBjoern A. Zeeb static int ath12k_mhi_set_state(struct ath12k_pci *ab_pci,
525*5c1def83SBjoern A. Zeeb enum ath12k_mhi_state mhi_state)
526*5c1def83SBjoern A. Zeeb {
527*5c1def83SBjoern A. Zeeb struct ath12k_base *ab = ab_pci->ab;
528*5c1def83SBjoern A. Zeeb int ret;
529*5c1def83SBjoern A. Zeeb
530*5c1def83SBjoern A. Zeeb ret = ath12k_mhi_check_state_bit(ab_pci, mhi_state);
531*5c1def83SBjoern A. Zeeb if (ret)
532*5c1def83SBjoern A. Zeeb goto out;
533*5c1def83SBjoern A. Zeeb
534*5c1def83SBjoern A. Zeeb ath12k_dbg(ab, ATH12K_DBG_PCI, "setting mhi state: %s(%d)\n",
535*5c1def83SBjoern A. Zeeb ath12k_mhi_state_to_str(mhi_state), mhi_state);
536*5c1def83SBjoern A. Zeeb
537*5c1def83SBjoern A. Zeeb switch (mhi_state) {
538*5c1def83SBjoern A. Zeeb case ATH12K_MHI_INIT:
539*5c1def83SBjoern A. Zeeb ret = mhi_prepare_for_power_up(ab_pci->mhi_ctrl);
540*5c1def83SBjoern A. Zeeb break;
541*5c1def83SBjoern A. Zeeb case ATH12K_MHI_DEINIT:
542*5c1def83SBjoern A. Zeeb mhi_unprepare_after_power_down(ab_pci->mhi_ctrl);
543*5c1def83SBjoern A. Zeeb ret = 0;
544*5c1def83SBjoern A. Zeeb break;
545*5c1def83SBjoern A. Zeeb case ATH12K_MHI_POWER_ON:
546*5c1def83SBjoern A. Zeeb ret = mhi_async_power_up(ab_pci->mhi_ctrl);
547*5c1def83SBjoern A. Zeeb break;
548*5c1def83SBjoern A. Zeeb case ATH12K_MHI_POWER_OFF:
549*5c1def83SBjoern A. Zeeb mhi_power_down(ab_pci->mhi_ctrl, true);
550*5c1def83SBjoern A. Zeeb ret = 0;
551*5c1def83SBjoern A. Zeeb break;
552*5c1def83SBjoern A. Zeeb case ATH12K_MHI_FORCE_POWER_OFF:
553*5c1def83SBjoern A. Zeeb mhi_power_down(ab_pci->mhi_ctrl, false);
554*5c1def83SBjoern A. Zeeb ret = 0;
555*5c1def83SBjoern A. Zeeb break;
556*5c1def83SBjoern A. Zeeb case ATH12K_MHI_SUSPEND:
557*5c1def83SBjoern A. Zeeb ret = mhi_pm_suspend(ab_pci->mhi_ctrl);
558*5c1def83SBjoern A. Zeeb break;
559*5c1def83SBjoern A. Zeeb case ATH12K_MHI_RESUME:
560*5c1def83SBjoern A. Zeeb ret = mhi_pm_resume(ab_pci->mhi_ctrl);
561*5c1def83SBjoern A. Zeeb break;
562*5c1def83SBjoern A. Zeeb case ATH12K_MHI_TRIGGER_RDDM:
563*5c1def83SBjoern A. Zeeb ret = mhi_force_rddm_mode(ab_pci->mhi_ctrl);
564*5c1def83SBjoern A. Zeeb break;
565*5c1def83SBjoern A. Zeeb case ATH12K_MHI_RDDM_DONE:
566*5c1def83SBjoern A. Zeeb break;
567*5c1def83SBjoern A. Zeeb default:
568*5c1def83SBjoern A. Zeeb ath12k_err(ab, "unhandled MHI state (%d)\n", mhi_state);
569*5c1def83SBjoern A. Zeeb ret = -EINVAL;
570*5c1def83SBjoern A. Zeeb }
571*5c1def83SBjoern A. Zeeb
572*5c1def83SBjoern A. Zeeb if (ret)
573*5c1def83SBjoern A. Zeeb goto out;
574*5c1def83SBjoern A. Zeeb
575*5c1def83SBjoern A. Zeeb ath12k_mhi_set_state_bit(ab_pci, mhi_state);
576*5c1def83SBjoern A. Zeeb
577*5c1def83SBjoern A. Zeeb return 0;
578*5c1def83SBjoern A. Zeeb
579*5c1def83SBjoern A. Zeeb out:
580*5c1def83SBjoern A. Zeeb ath12k_err(ab, "failed to set mhi state: %s(%d)\n",
581*5c1def83SBjoern A. Zeeb ath12k_mhi_state_to_str(mhi_state), mhi_state);
582*5c1def83SBjoern A. Zeeb return ret;
583*5c1def83SBjoern A. Zeeb }
584*5c1def83SBjoern A. Zeeb
ath12k_mhi_start(struct ath12k_pci * ab_pci)585*5c1def83SBjoern A. Zeeb int ath12k_mhi_start(struct ath12k_pci *ab_pci)
586*5c1def83SBjoern A. Zeeb {
587*5c1def83SBjoern A. Zeeb int ret;
588*5c1def83SBjoern A. Zeeb
589*5c1def83SBjoern A. Zeeb ab_pci->mhi_ctrl->timeout_ms = MHI_TIMEOUT_DEFAULT_MS;
590*5c1def83SBjoern A. Zeeb
591*5c1def83SBjoern A. Zeeb ret = ath12k_mhi_set_state(ab_pci, ATH12K_MHI_INIT);
592*5c1def83SBjoern A. Zeeb if (ret)
593*5c1def83SBjoern A. Zeeb goto out;
594*5c1def83SBjoern A. Zeeb
595*5c1def83SBjoern A. Zeeb ret = ath12k_mhi_set_state(ab_pci, ATH12K_MHI_POWER_ON);
596*5c1def83SBjoern A. Zeeb if (ret)
597*5c1def83SBjoern A. Zeeb goto out;
598*5c1def83SBjoern A. Zeeb
599*5c1def83SBjoern A. Zeeb return 0;
600*5c1def83SBjoern A. Zeeb
601*5c1def83SBjoern A. Zeeb out:
602*5c1def83SBjoern A. Zeeb return ret;
603*5c1def83SBjoern A. Zeeb }
604*5c1def83SBjoern A. Zeeb
ath12k_mhi_stop(struct ath12k_pci * ab_pci)605*5c1def83SBjoern A. Zeeb void ath12k_mhi_stop(struct ath12k_pci *ab_pci)
606*5c1def83SBjoern A. Zeeb {
607*5c1def83SBjoern A. Zeeb ath12k_mhi_set_state(ab_pci, ATH12K_MHI_POWER_OFF);
608*5c1def83SBjoern A. Zeeb ath12k_mhi_set_state(ab_pci, ATH12K_MHI_DEINIT);
609*5c1def83SBjoern A. Zeeb }
610*5c1def83SBjoern A. Zeeb
ath12k_mhi_suspend(struct ath12k_pci * ab_pci)611*5c1def83SBjoern A. Zeeb void ath12k_mhi_suspend(struct ath12k_pci *ab_pci)
612*5c1def83SBjoern A. Zeeb {
613*5c1def83SBjoern A. Zeeb ath12k_mhi_set_state(ab_pci, ATH12K_MHI_SUSPEND);
614*5c1def83SBjoern A. Zeeb }
615*5c1def83SBjoern A. Zeeb
ath12k_mhi_resume(struct ath12k_pci * ab_pci)616*5c1def83SBjoern A. Zeeb void ath12k_mhi_resume(struct ath12k_pci *ab_pci)
617*5c1def83SBjoern A. Zeeb {
618*5c1def83SBjoern A. Zeeb ath12k_mhi_set_state(ab_pci, ATH12K_MHI_RESUME);
619*5c1def83SBjoern A. Zeeb }
620