1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /**
8 * @brief File containing QSPI Bus Layer specific function definitions of the
9 * Wi-Fi driver.
10 */
11
12 #include "bal_structs.h"
13 #include "qspi.h"
14 #include "common/pal.h"
15
16
nrf_wifi_bus_qspi_irq_handler(void * data)17 static int nrf_wifi_bus_qspi_irq_handler(void *data)
18 {
19 struct nrf_wifi_bus_qspi_dev_ctx *dev_ctx = NULL;
20 struct nrf_wifi_bus_qspi_priv *qspi_priv = NULL;
21 int ret = 0;
22
23 dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)data;
24 qspi_priv = dev_ctx->qspi_priv;
25
26 ret = qspi_priv->intr_callbk_fn(dev_ctx->bal_dev_ctx);
27
28 return ret;
29 }
30
31
nrf_wifi_bus_qspi_dev_add(void * bus_priv,void * bal_dev_ctx)32 static void *nrf_wifi_bus_qspi_dev_add(void *bus_priv,
33 void *bal_dev_ctx)
34 {
35 struct nrf_wifi_bus_qspi_priv *qspi_priv = NULL;
36 struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL;
37 struct nrf_wifi_osal_host_map host_map;
38
39 qspi_priv = bus_priv;
40
41 qspi_dev_ctx = nrf_wifi_osal_mem_zalloc(sizeof(*qspi_dev_ctx));
42
43 if (!qspi_dev_ctx) {
44 nrf_wifi_osal_log_err("%s: Unable to allocate qspi_dev_ctx", __func__);
45 goto out;
46 }
47
48 qspi_dev_ctx->qspi_priv = qspi_priv;
49 qspi_dev_ctx->bal_dev_ctx = bal_dev_ctx;
50
51 qspi_dev_ctx->os_qspi_dev_ctx = nrf_wifi_osal_bus_qspi_dev_add(qspi_priv->os_qspi_priv,
52 qspi_dev_ctx);
53
54 if (!qspi_dev_ctx->os_qspi_dev_ctx) {
55 nrf_wifi_osal_log_err("%s: nrf_wifi_osal_bus_qspi_dev_add failed", __func__);
56
57 nrf_wifi_osal_mem_free(qspi_dev_ctx);
58
59 qspi_dev_ctx = NULL;
60
61 goto out;
62 }
63
64 nrf_wifi_osal_bus_qspi_dev_host_map_get(qspi_dev_ctx->os_qspi_dev_ctx,
65 &host_map);
66
67 qspi_dev_ctx->host_addr_base = host_map.addr;
68
69 qspi_dev_ctx->addr_pktram_base = qspi_dev_ctx->host_addr_base +
70 qspi_priv->cfg_params.addr_pktram_base;
71
72 out:
73 return qspi_dev_ctx;
74 }
75
76
nrf_wifi_bus_qspi_dev_rem(void * bus_dev_ctx)77 static void nrf_wifi_bus_qspi_dev_rem(void *bus_dev_ctx)
78 {
79 struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL;
80
81 qspi_dev_ctx = bus_dev_ctx;
82
83 nrf_wifi_osal_bus_qspi_dev_rem(qspi_dev_ctx->os_qspi_dev_ctx);
84
85 nrf_wifi_osal_mem_free(qspi_dev_ctx);
86 }
87
88
nrf_wifi_bus_qspi_dev_init(void * bus_dev_ctx)89 static enum nrf_wifi_status nrf_wifi_bus_qspi_dev_init(void *bus_dev_ctx)
90 {
91 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
92 struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL;
93
94 qspi_dev_ctx = bus_dev_ctx;
95
96
97 status = nrf_wifi_osal_bus_qspi_dev_intr_reg(qspi_dev_ctx->os_qspi_dev_ctx,
98 qspi_dev_ctx,
99 &nrf_wifi_bus_qspi_irq_handler);
100
101 if (status != NRF_WIFI_STATUS_SUCCESS) {
102 nrf_wifi_osal_log_err("%s: Unable to register interrupt to the OS",
103 __func__);
104 qspi_dev_ctx = NULL;
105
106 goto out;
107 }
108
109 status = nrf_wifi_osal_bus_qspi_dev_init(qspi_dev_ctx->os_qspi_dev_ctx);
110
111 if (status != NRF_WIFI_STATUS_SUCCESS) {
112 nrf_wifi_osal_log_err("%s: nrf_wifi_osal_qspi_dev_init failed", __func__);
113
114 nrf_wifi_osal_bus_qspi_dev_intr_unreg(qspi_dev_ctx->os_qspi_dev_ctx);
115 goto out;
116 }
117 out:
118 return status;
119 }
120
121
nrf_wifi_bus_qspi_dev_deinit(void * bus_dev_ctx)122 static void nrf_wifi_bus_qspi_dev_deinit(void *bus_dev_ctx)
123 {
124 struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL;
125
126 qspi_dev_ctx = bus_dev_ctx;
127
128 nrf_wifi_osal_bus_qspi_dev_intr_unreg(qspi_dev_ctx->os_qspi_dev_ctx);
129
130 nrf_wifi_osal_bus_qspi_dev_deinit(qspi_dev_ctx->os_qspi_dev_ctx);
131 }
132
133
nrf_wifi_bus_qspi_init(void * params,enum nrf_wifi_status (* intr_callbk_fn)(void * bal_dev_ctx))134 static void *nrf_wifi_bus_qspi_init(void *params,
135 enum nrf_wifi_status (*intr_callbk_fn)(void *bal_dev_ctx))
136 {
137 struct nrf_wifi_bus_qspi_priv *qspi_priv = NULL;
138
139 qspi_priv = nrf_wifi_osal_mem_zalloc(sizeof(*qspi_priv));
140
141 if (!qspi_priv) {
142 nrf_wifi_osal_log_err("%s: Unable to allocate memory for qspi_priv",
143 __func__);
144 goto out;
145 }
146
147 nrf_wifi_osal_mem_cpy(&qspi_priv->cfg_params,
148 params,
149 sizeof(qspi_priv->cfg_params));
150
151 qspi_priv->intr_callbk_fn = intr_callbk_fn;
152
153 qspi_priv->os_qspi_priv = nrf_wifi_osal_bus_qspi_init();
154
155 if (!qspi_priv->os_qspi_priv) {
156 nrf_wifi_osal_log_err("%s: Unable to register QSPI driver",
157 __func__);
158
159 nrf_wifi_osal_mem_free(qspi_priv);
160
161 qspi_priv = NULL;
162
163 goto out;
164 }
165 out:
166 return qspi_priv;
167 }
168
169
nrf_wifi_bus_qspi_deinit(void * bus_priv)170 static void nrf_wifi_bus_qspi_deinit(void *bus_priv)
171 {
172 struct nrf_wifi_bus_qspi_priv *qspi_priv = NULL;
173
174 qspi_priv = bus_priv;
175
176 nrf_wifi_osal_bus_qspi_deinit(qspi_priv->os_qspi_priv);
177
178 nrf_wifi_osal_mem_free(qspi_priv);
179 }
180
181
nrf_wifi_bus_qspi_read_word(void * dev_ctx,unsigned long addr_offset)182 static unsigned int nrf_wifi_bus_qspi_read_word(void *dev_ctx,
183 unsigned long addr_offset)
184 {
185 struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL;
186 unsigned int val = 0;
187
188 qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx;
189
190 val = nrf_wifi_osal_qspi_read_reg32(qspi_dev_ctx->os_qspi_dev_ctx,
191 qspi_dev_ctx->host_addr_base + addr_offset);
192
193 return val;
194 }
195
196
nrf_wifi_bus_qspi_write_word(void * dev_ctx,unsigned long addr_offset,unsigned int val)197 static void nrf_wifi_bus_qspi_write_word(void *dev_ctx,
198 unsigned long addr_offset,
199 unsigned int val)
200 {
201 struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL;
202
203 qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx;
204
205 nrf_wifi_osal_qspi_write_reg32(qspi_dev_ctx->os_qspi_dev_ctx,
206 qspi_dev_ctx->host_addr_base + addr_offset,
207 val);
208 }
209
210
nrf_wifi_bus_qspi_read_block(void * dev_ctx,void * dest_addr,unsigned long src_addr_offset,size_t len)211 static void nrf_wifi_bus_qspi_read_block(void *dev_ctx,
212 void *dest_addr,
213 unsigned long src_addr_offset,
214 size_t len)
215 {
216 struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL;
217
218 qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx;
219
220 nrf_wifi_osal_qspi_cpy_from(qspi_dev_ctx->os_qspi_dev_ctx,
221 dest_addr,
222 qspi_dev_ctx->host_addr_base + src_addr_offset,
223 len);
224 }
225
226
nrf_wifi_bus_qspi_write_block(void * dev_ctx,unsigned long dest_addr_offset,const void * src_addr,size_t len)227 static void nrf_wifi_bus_qspi_write_block(void *dev_ctx,
228 unsigned long dest_addr_offset,
229 const void *src_addr,
230 size_t len)
231 {
232 struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL;
233
234 qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx;
235
236 nrf_wifi_osal_qspi_cpy_to(qspi_dev_ctx->os_qspi_dev_ctx,
237 qspi_dev_ctx->host_addr_base + dest_addr_offset,
238 src_addr,
239 len);
240 }
241
242
nrf_wifi_bus_qspi_dma_map(void * dev_ctx,unsigned long virt_addr,size_t len,enum nrf_wifi_osal_dma_dir dma_dir)243 static unsigned long nrf_wifi_bus_qspi_dma_map(void *dev_ctx,
244 unsigned long virt_addr,
245 size_t len,
246 enum nrf_wifi_osal_dma_dir dma_dir)
247 {
248 struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL;
249 unsigned long phy_addr = 0;
250
251 qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx;
252
253 phy_addr = qspi_dev_ctx->host_addr_base + (virt_addr - qspi_dev_ctx->addr_pktram_base);
254
255 return phy_addr;
256 }
257
258
nrf_wifi_bus_qspi_dma_unmap(void * dev_ctx,unsigned long phy_addr,size_t len,enum nrf_wifi_osal_dma_dir dma_dir)259 static unsigned long nrf_wifi_bus_qspi_dma_unmap(void *dev_ctx,
260 unsigned long phy_addr,
261 size_t len,
262 enum nrf_wifi_osal_dma_dir dma_dir)
263 {
264 struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL;
265 unsigned long virt_addr = 0;
266
267 qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx;
268
269 virt_addr = qspi_dev_ctx->addr_pktram_base + (phy_addr - qspi_dev_ctx->host_addr_base);
270
271 return virt_addr;
272 }
273
274
275 #ifdef NRF_WIFI_LOW_POWER
nrf_wifi_bus_qspi_ps_sleep(void * dev_ctx)276 static void nrf_wifi_bus_qspi_ps_sleep(void *dev_ctx)
277 {
278 struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL;
279
280 qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx;
281
282 nrf_wifi_osal_bus_qspi_ps_sleep(qspi_dev_ctx->os_qspi_dev_ctx);
283 }
284
285
nrf_wifi_bus_qspi_ps_wake(void * dev_ctx)286 static void nrf_wifi_bus_qspi_ps_wake(void *dev_ctx)
287 {
288 struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL;
289
290 qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx;
291
292 nrf_wifi_osal_bus_qspi_ps_wake(qspi_dev_ctx->os_qspi_dev_ctx);
293 }
294
295
nrf_wifi_bus_qspi_ps_status(void * dev_ctx)296 static int nrf_wifi_bus_qspi_ps_status(void *dev_ctx)
297 {
298 struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL;
299
300 qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx;
301
302 return nrf_wifi_osal_bus_qspi_ps_status(qspi_dev_ctx->os_qspi_dev_ctx);
303 }
304 #endif /* NRF_WIFI_LOW_POWER */
305
306
307 static struct nrf_wifi_bal_ops nrf_wifi_bus_qspi_ops = {
308 .init = &nrf_wifi_bus_qspi_init,
309 .deinit = &nrf_wifi_bus_qspi_deinit,
310 .dev_add = &nrf_wifi_bus_qspi_dev_add,
311 .dev_rem = &nrf_wifi_bus_qspi_dev_rem,
312 .dev_init = &nrf_wifi_bus_qspi_dev_init,
313 .dev_deinit = &nrf_wifi_bus_qspi_dev_deinit,
314 .read_word = &nrf_wifi_bus_qspi_read_word,
315 .write_word = &nrf_wifi_bus_qspi_write_word,
316 .read_block = &nrf_wifi_bus_qspi_read_block,
317 .write_block = &nrf_wifi_bus_qspi_write_block,
318 .dma_map = &nrf_wifi_bus_qspi_dma_map,
319 .dma_unmap = &nrf_wifi_bus_qspi_dma_unmap,
320 #ifdef NRF_WIFI_LOW_POWER
321 .rpu_ps_sleep = &nrf_wifi_bus_qspi_ps_sleep,
322 .rpu_ps_wake = &nrf_wifi_bus_qspi_ps_wake,
323 .rpu_ps_status = &nrf_wifi_bus_qspi_ps_status,
324 #endif /* NRF_WIFI_LOW_POWER */
325 };
326
327
get_bus_ops(void)328 struct nrf_wifi_bal_ops *get_bus_ops(void)
329 {
330 return &nrf_wifi_bus_qspi_ops;
331 }
332