blob: 475e9db39bd80956954ab3a6e9dd078e44690281 [file] [log] [blame]
Jishnu Prakash71524642019-03-13 18:12:26 +05301/* Copyright (c) 2011-2019, The Linux Foundation. All rights reserved.
Yan Heaabe3fc2016-11-14 17:04:53 -08002 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/types.h> /* u32 */
14#include <linux/kernel.h> /* pr_info() */
15#include <linux/mutex.h> /* mutex */
16#include <linux/list.h> /* list_head */
17#include <linux/slab.h> /* kzalloc() */
18#include <linux/interrupt.h> /* request_irq() */
19#include <linux/memory.h> /* memset */
20#include <linux/vmalloc.h>
21
22#include "sps_bam.h"
23#include "bam.h"
24#include "spsi.h"
25
26/* All BAM global IRQ sources */
27#define BAM_IRQ_ALL (BAM_DEV_IRQ_HRESP_ERROR | BAM_DEV_IRQ_ERROR | \
28 BAM_DEV_IRQ_TIMER)
29
30/* BAM device state flags */
31#define BAM_STATE_INIT (1UL << 1)
32#define BAM_STATE_IRQ (1UL << 2)
33#define BAM_STATE_ENABLED (1UL << 3)
34#define BAM_STATE_BAM2BAM (1UL << 4)
35#define BAM_STATE_MTI (1UL << 5)
36#define BAM_STATE_REMOTE (1UL << 6)
37
38/* Mask for valid hardware descriptor flags */
39#define BAM_IOVEC_FLAG_MASK \
40 (SPS_IOVEC_FLAG_INT | SPS_IOVEC_FLAG_EOT | SPS_IOVEC_FLAG_EOB | \
41 SPS_IOVEC_FLAG_NWD | SPS_IOVEC_FLAG_CMD | SPS_IOVEC_FLAG_LOCK | \
42 SPS_IOVEC_FLAG_UNLOCK | SPS_IOVEC_FLAG_IMME)
43
44/* Mask for invalid BAM-to-BAM pipe options */
45#define BAM2BAM_O_INVALID \
46 (SPS_O_DESC_DONE | \
47 SPS_O_EOT | \
48 SPS_O_POLL | \
49 SPS_O_NO_Q | \
50 SPS_O_ACK_TRANSFERS)
51
52/**
53 * Pipe/client pointer value indicating pipe is allocated, but no client has
54 * been assigned
55 */
56#define BAM_PIPE_UNASSIGNED ((struct sps_pipe *)((~0x0ul) - 0x88888888))
57
58/* Check whether pipe has been assigned */
59#define BAM_PIPE_IS_ASSIGNED(p) \
60 (((p) != NULL) && ((p) != BAM_PIPE_UNASSIGNED))
61
62/* Is MTI use supported for a specific BAM version? */
63#define BAM_VERSION_MTI_SUPPORT(ver) (ver <= 2)
64
65/* Event option<->event translation table entry */
66struct sps_bam_opt_event_table {
67 enum sps_event event_id;
68 enum sps_option option;
69 enum bam_pipe_irq pipe_irq;
70};
71
72static const struct sps_bam_opt_event_table opt_event_table[] = {
73 {SPS_EVENT_EOT, SPS_O_EOT, BAM_PIPE_IRQ_EOT},
74 {SPS_EVENT_DESC_DONE, SPS_O_DESC_DONE, BAM_PIPE_IRQ_DESC_INT},
75 {SPS_EVENT_WAKEUP, SPS_O_WAKEUP, BAM_PIPE_IRQ_WAKE},
76 {SPS_EVENT_INACTIVE, SPS_O_INACTIVE, BAM_PIPE_IRQ_TIMER},
77 {SPS_EVENT_OUT_OF_DESC, SPS_O_OUT_OF_DESC,
78 BAM_PIPE_IRQ_OUT_OF_DESC},
79 {SPS_EVENT_ERROR, SPS_O_ERROR, BAM_PIPE_IRQ_ERROR},
80 {SPS_EVENT_RST_ERROR, SPS_O_RST_ERROR, BAM_PIPE_IRQ_RST_ERROR},
81 {SPS_EVENT_HRESP_ERROR, SPS_O_HRESP_ERROR, BAM_PIPE_IRQ_HRESP_ERROR}
82};
83
84/* Pipe event source handler */
85static void pipe_handler(struct sps_bam *dev,
86 struct sps_pipe *pipe);
87
88/**
89 * Pipe transfer event (EOT, DESC_DONE) source handler.
90 * This function is called by pipe_handler() and other functions to process the
91 * descriptor FIFO.
92 */
93static void pipe_handler_eot(struct sps_bam *dev,
94 struct sps_pipe *pipe);
95
96/**
97 * BAM driver initialization
98 */
99int sps_bam_driver_init(u32 options)
100{
101 int n;
102
103 /*
104 * Check that SPS_O_ and BAM_PIPE_IRQ_ values are identical.
105 * This is required so that the raw pipe IRQ status can be passed
106 * to the client in the SPS_EVENT_IRQ.
107 */
108 for (n = 0; n < ARRAY_SIZE(opt_event_table); n++) {
109 if ((u32)opt_event_table[n].option !=
110 (u32)opt_event_table[n].pipe_irq) {
111 SPS_ERR(sps, "sps:SPS_O 0x%x != HAL IRQ 0x%x\n",
112 opt_event_table[n].option,
113 opt_event_table[n].pipe_irq);
114 return SPS_ERROR;
115 }
116 }
117
118 return 0;
119}
120
121/*
122 * Check BAM interrupt
123 */
124int sps_bam_check_irq(struct sps_bam *dev)
125{
126 struct sps_pipe *pipe;
127 u32 source;
128 unsigned long flags = 0;
129 int ret = 0;
130
131 SPS_DBG1(dev, "sps:%s:bam=%pa.\n", __func__, BAM_ID(dev));
132
133 spin_lock_irqsave(&dev->isr_lock, flags);
134
135polling:
136 /* Get BAM interrupt source(s) */
137 if ((dev->state & BAM_STATE_MTI) == 0) {
138 u32 mask = dev->pipe_active_mask;
139 enum sps_callback_case cb_case;
140
141 source = bam_check_irq_source(&dev->base, dev->props.ee,
142 mask, &cb_case);
143
144 SPS_DBG1(dev, "sps:bam=%pa;source=0x%x;mask=0x%x.\n",
145 BAM_ID(dev), source, mask);
146
147 if ((source == 0) &&
148 (dev->props.options & SPS_BAM_RES_CONFIRM)) {
149 SPS_DBG2(dev,
150 "sps: BAM %pa has no source (source = 0x%x).\n",
151 BAM_ID(dev), source);
152
153 spin_unlock_irqrestore(&dev->isr_lock, flags);
154 return SPS_ERROR;
155 }
156
157 if ((source & (1UL << 31)) && (dev->props.callback)) {
158 SPS_DBG1(dev, "sps:bam=%pa;callback for case %d.\n",
159 BAM_ID(dev), cb_case);
160 dev->props.callback(cb_case, dev->props.user);
161 }
162
163 /* Mask any non-local source */
164 source &= dev->pipe_active_mask;
165 } else {
166 /* If MTIs are used, must poll each active pipe */
167 source = dev->pipe_active_mask;
168
169 SPS_DBG1(dev, "sps:MTI:bam=%pa;source=0x%x.\n",
170 BAM_ID(dev), source);
171 }
172
173 /* Process active pipe sources */
174 pipe = list_first_entry(&dev->pipes_q, struct sps_pipe, list);
175
176 list_for_each_entry(pipe, &dev->pipes_q, list) {
177 /* Check this pipe's bit in the source mask */
178 if (BAM_PIPE_IS_ASSIGNED(pipe)
179 && (!pipe->disconnecting)
180 && (source & pipe->pipe_index_mask)) {
181 /* This pipe has an interrupt pending */
182 pipe_handler(dev, pipe);
183 source &= ~pipe->pipe_index_mask;
184 }
185 if (source == 0)
186 break;
187 }
188
189 /* Process any inactive pipe sources */
190 if (source) {
191 SPS_ERR(dev, "sps:IRQ from BAM %pa inactive pipe(s) 0x%x\n",
192 BAM_ID(dev), source);
193 dev->irq_from_disabled_pipe++;
194 }
195
196 if (dev->props.options & SPS_BAM_RES_CONFIRM) {
197 u32 mask = dev->pipe_active_mask;
198 enum sps_callback_case cb_case;
199
200 source = bam_check_irq_source(&dev->base, dev->props.ee,
201 mask, &cb_case);
202
203 SPS_DBG1(dev,
204 "sps:check if there is any new IRQ coming:bam=%pa;source=0x%x;mask=0x%x.\n",
205 BAM_ID(dev), source, mask);
206
207 if ((source & (1UL << 31)) && (dev->props.callback)) {
208 SPS_DBG1(dev, "sps:bam=%pa;callback for case %d.\n",
209 BAM_ID(dev), cb_case);
210 dev->props.callback(cb_case, dev->props.user);
211 }
212
213 if (source)
214 goto polling;
215 }
216
217 spin_unlock_irqrestore(&dev->isr_lock, flags);
218
219 return ret;
220}
221
222/**
223 * BAM interrupt service routine
224 *
225 * This function is the BAM interrupt service routine.
226 *
227 * @ctxt - pointer to ISR's registered argument
228 *
229 * @return void
230 */
231static irqreturn_t bam_isr(int irq, void *ctxt)
232{
233 struct sps_bam *dev = ctxt;
234
235 SPS_DBG1(dev, "sps:bam_isr: bam:%pa; IRQ #:%d.\n",
236 BAM_ID(dev), irq);
237
238 if (dev->props.options & SPS_BAM_RES_CONFIRM) {
239 if (dev->props.callback) {
240 bool ready = false;
241
242 dev->props.callback(SPS_CALLBACK_BAM_RES_REQ, &ready);
243 if (ready) {
244 SPS_DBG1(dev,
245 "sps:bam_isr: handle IRQ for bam:%pa IRQ #:%d.\n",
246 BAM_ID(dev), irq);
247 if (sps_bam_check_irq(dev))
248 SPS_DBG2(dev,
249 "sps:bam_isr: callback bam:%pa IRQ #:%d to poll the pipes.\n",
250 BAM_ID(dev), irq);
251 dev->props.callback(SPS_CALLBACK_BAM_RES_REL,
252 &ready);
253 } else {
254 SPS_DBG1(dev,
255 "sps:bam_isr: BAM is not ready and thus skip IRQ for bam:%pa IRQ #:%d.\n",
256 BAM_ID(dev), irq);
257 }
258 } else {
259 SPS_ERR(dev,
260 "sps:Client of BAM %pa requires confirmation but does not register callback\n",
261 BAM_ID(dev));
262 }
263 } else {
264 sps_bam_check_irq(dev);
265 }
266
267 return IRQ_HANDLED;
268}
269
270/**
271 * BAM device enable
272 */
273int sps_bam_enable(struct sps_bam *dev)
274{
275 u32 num_pipes;
276 u32 irq_mask;
277 int result;
278 int rc;
279 int MTIenabled;
280
281 /* Is this BAM enabled? */
282 if ((dev->state & BAM_STATE_ENABLED))
283 return 0; /* Yes, so no work to do */
284
285 /* Is there any access to this BAM? */
286 if ((dev->props.manage & SPS_BAM_MGR_ACCESS_MASK) == SPS_BAM_MGR_NONE) {
287 SPS_ERR(dev, "sps:No local access to BAM %pa\n", BAM_ID(dev));
288 return SPS_ERROR;
289 }
290
291 /* Set interrupt handling */
292 if ((dev->props.options & SPS_BAM_OPT_IRQ_DISABLED) != 0 ||
293 dev->props.irq == SPS_IRQ_INVALID) {
294 /* Disable the BAM interrupt */
295 irq_mask = 0;
296 dev->state &= ~BAM_STATE_IRQ;
297 } else {
298 /* Register BAM ISR */
299 if (dev->props.irq > 0) {
300 if (dev->props.options & SPS_BAM_RES_CONFIRM) {
301 result = request_irq(dev->props.irq,
302 (irq_handler_t) bam_isr,
303 IRQF_TRIGGER_RISING, "sps", dev);
304 SPS_DBG3(dev,
305 "sps:BAM %pa uses edge for IRQ# %d\n",
306 BAM_ID(dev), dev->props.irq);
307 } else {
308 result = request_irq(dev->props.irq,
309 (irq_handler_t) bam_isr,
310 IRQF_TRIGGER_HIGH, "sps", dev);
311 SPS_DBG3(dev,
312 "sps:BAM %pa uses level for IRQ# %d\n",
313 BAM_ID(dev), dev->props.irq);
314 }
315 } else {
316 SPS_DBG3(dev,
317 "sps:BAM %pa does not have an valid IRQ# %d\n",
318 BAM_ID(dev), dev->props.irq);
319 }
320
321 if (result) {
322 SPS_ERR(dev, "sps:Failed to enable BAM %pa IRQ %d\n",
323 BAM_ID(dev), dev->props.irq);
324 return SPS_ERROR;
325 }
326
327 /* Enable the BAM interrupt */
328 irq_mask = BAM_IRQ_ALL;
329 dev->state |= BAM_STATE_IRQ;
330
331 /* Register BAM IRQ for apps wakeup */
332 if (dev->props.options & SPS_BAM_OPT_IRQ_WAKEUP) {
333 result = enable_irq_wake(dev->props.irq);
334
335 if (result) {
336 SPS_ERR(dev,
337 "sps:Fail to enable wakeup irq for BAM %pa IRQ %d\n",
338 BAM_ID(dev), dev->props.irq);
339 return SPS_ERROR;
340 }
341 SPS_DBG3(dev,
342 "sps:Enable wakeup irq for BAM %pa IRQ %d\n",
343 BAM_ID(dev), dev->props.irq);
344 }
345 }
346
347 /* Is global BAM control managed by the local processor? */
348 num_pipes = 0;
349 if ((dev->props.manage & SPS_BAM_MGR_DEVICE_REMOTE) == 0)
350 /* Yes, so initialize the BAM device */
351 rc = bam_init(&dev->base,
352 dev->props.ee,
353 (u16) dev->props.summing_threshold,
354 irq_mask,
355 &dev->version, &num_pipes,
356 dev->props.options);
357 else
358 /* No, so just verify that it is enabled */
359 rc = bam_check(&dev->base, &dev->version,
360 dev->props.ee, &num_pipes);
361
362 if (rc) {
363 SPS_ERR(dev, "sps:Fail to init BAM %pa IRQ %d\n",
364 BAM_ID(dev), dev->props.irq);
365 return SPS_ERROR;
366 }
367
368 /* Check if this BAM supports MTIs (Message Triggered Interrupts) or
369 * multiple EEs (Execution Environments).
370 * MTI and EE support are mutually exclusive.
371 */
372 MTIenabled = BAM_VERSION_MTI_SUPPORT(dev->version);
373
374 if ((dev->props.manage & SPS_BAM_MGR_DEVICE_REMOTE) != 0 &&
375 (dev->props.manage & SPS_BAM_MGR_MULTI_EE) != 0 &&
376 dev->props.ee == 0 && MTIenabled) {
377 /*
378 * BAM global is owned by remote processor and local processor
379 * must use MTI. Thus, force EE index to a non-zero value to
380 * insure that EE zero globals can't be modified.
381 */
382 SPS_ERR(dev,
383 "sps:%s:EE for satellite BAM must be set to non-zero.\n",
384 __func__);
385 return SPS_ERROR;
386 }
387
388 /*
389 * Enable MTI use (message triggered interrupt)
390 * if local processor does not control the global BAM config
391 * and this BAM supports MTIs.
392 */
393 if ((dev->state & BAM_STATE_IRQ) != 0 &&
394 (dev->props.manage & SPS_BAM_MGR_DEVICE_REMOTE) != 0 &&
395 MTIenabled) {
396 if (dev->props.irq_gen_addr == 0 ||
397 dev->props.irq_gen_addr == SPS_ADDR_INVALID) {
398 SPS_ERR(dev,
399 "sps:MTI destination address not specified for BAM %pa\n",
400 BAM_ID(dev));
401 return SPS_ERROR;
402 }
403 dev->state |= BAM_STATE_MTI;
404 }
405
406 if (num_pipes) {
407 dev->props.num_pipes = num_pipes;
408 SPS_DBG3(dev,
409 "sps:BAM %pa number of pipes reported by hw: %d\n",
410 BAM_ID(dev), dev->props.num_pipes);
411 }
412
413 /* Check EE index */
414 if (!MTIenabled && dev->props.ee >= SPS_BAM_NUM_EES) {
415 SPS_ERR(dev, "sps:Invalid EE BAM %pa: %d\n", BAM_ID(dev),
416 dev->props.ee);
417 return SPS_ERROR;
418 }
419
420 /*
421 * Process EE configuration parameters,
422 * if specified in the properties
423 */
424 if (!MTIenabled && dev->props.sec_config == SPS_BAM_SEC_DO_CONFIG) {
425 struct sps_bam_sec_config_props *p_sec =
426 dev->props.p_sec_config_props;
427 if (p_sec == NULL) {
428 SPS_ERR(dev,
429 "sps:EE config table is not specified for BAM %pa\n",
430 BAM_ID(dev));
431 return SPS_ERROR;
432 }
433
434 /*
435 * Set restricted pipes based on the pipes assigned to local EE
436 */
437 dev->props.restricted_pipes =
438 ~p_sec->ees[dev->props.ee].pipe_mask;
439
440 /*
441 * If local processor manages the BAM, perform the EE
442 * configuration
443 */
444 if ((dev->props.manage & SPS_BAM_MGR_DEVICE_REMOTE) == 0) {
445 u32 ee;
446 u32 pipe_mask;
447 int n, i;
448
449 /*
450 * Verify that there are no overlapping pipe
451 * assignments
452 */
453 for (n = 0; n < SPS_BAM_NUM_EES - 1; n++) {
454 for (i = n + 1; i < SPS_BAM_NUM_EES; i++) {
455 if ((p_sec->ees[n].pipe_mask &
456 p_sec->ees[i].pipe_mask) != 0) {
457 SPS_ERR(dev,
458 "sps:Overlapping pipe assignments for BAM %pa: EEs %d and %d\n",
459 BAM_ID(dev), n, i);
460 return SPS_ERROR;
461 }
462 }
463 }
464
465 for (ee = 0; ee < SPS_BAM_NUM_EES; ee++) {
466 /*
467 * MSbit specifies EE for the global (top-level)
468 * BAM interrupt
469 */
470 pipe_mask = p_sec->ees[ee].pipe_mask;
471 if (ee == dev->props.ee)
472 pipe_mask |= (1UL << 31);
473 else
474 pipe_mask &= ~(1UL << 31);
475
476 bam_security_init(&dev->base, ee,
477 p_sec->ees[ee].vmid, pipe_mask);
478 }
479 }
480 }
481
482 /*
483 * If local processor manages the BAM and the BAM supports MTIs
484 * but does not support multiple EEs, set all restricted pipes
485 * to MTI mode.
486 */
487 if ((dev->props.manage & SPS_BAM_MGR_DEVICE_REMOTE) == 0
488 && MTIenabled) {
489 u32 pipe_index;
490 u32 pipe_mask;
491
492 for (pipe_index = 0, pipe_mask = 1;
493 pipe_index < dev->props.num_pipes;
494 pipe_index++, pipe_mask <<= 1) {
495 if ((pipe_mask & dev->props.restricted_pipes) == 0)
496 continue; /* This is a local pipe */
497
498 /*
499 * Enable MTI with destination address of zero
500 * (and source mask zero). Pipe is in reset,
501 * so no interrupt will be generated.
502 */
503 bam_pipe_satellite_mti(&dev->base, pipe_index, 0,
504 dev->props.ee);
505 }
506 }
507
508 dev->state |= BAM_STATE_ENABLED;
509
510 if (!dev->props.constrained_logging ||
511 (dev->props.constrained_logging && dev->props.logging_number)) {
512 if (dev->props.logging_number > 0)
513 dev->props.logging_number--;
514 SPS_INFO(dev,
Jishnu Prakash120aa392017-11-14 18:59:34 +0530515 "sps:BAM %pa (va:0x%pK) enabled: ver:0x%x, number of pipes:%d\n",
Yan Heaabe3fc2016-11-14 17:04:53 -0800516 BAM_ID(dev), dev->base, dev->version,
517 dev->props.num_pipes);
518 } else
519 SPS_DBG3(dev,
Jishnu Prakash120aa392017-11-14 18:59:34 +0530520 "sps:BAM %pa (va:0x%pK) enabled: ver:0x%x, number of pipes:%d\n",
Yan Heaabe3fc2016-11-14 17:04:53 -0800521 BAM_ID(dev), dev->base, dev->version,
522 dev->props.num_pipes);
523
524 return 0;
525}
526
527/**
528 * BAM device disable
529 *
530 */
531int sps_bam_disable(struct sps_bam *dev)
532{
533 if ((dev->state & BAM_STATE_ENABLED) == 0)
534 return 0;
535
536 /* Is there any access to this BAM? */
537 if ((dev->props.manage & SPS_BAM_MGR_ACCESS_MASK) == SPS_BAM_MGR_NONE) {
538 SPS_ERR(dev, "sps:No local access to BAM %pa\n", BAM_ID(dev));
539 return SPS_ERROR;
540 }
541
542 /* Is this BAM controlled by the local processor? */
543 if ((dev->props.manage & SPS_BAM_MGR_DEVICE_REMOTE)) {
544 /* No, so just mark it disabled */
545 dev->state &= ~BAM_STATE_ENABLED;
546 if ((dev->state & BAM_STATE_IRQ) && (dev->props.irq > 0)) {
547 free_irq(dev->props.irq, dev);
548 dev->state &= ~BAM_STATE_IRQ;
549 }
550 return 0;
551 }
552
553 /* Disable BAM (interrupts) */
554 if ((dev->state & BAM_STATE_IRQ)) {
555 bam_exit(&dev->base, dev->props.ee);
556
557 /* Deregister BAM ISR */
558 if ((dev->state & BAM_STATE_IRQ))
559 if (dev->props.irq > 0)
560 free_irq(dev->props.irq, dev);
561 dev->state &= ~BAM_STATE_IRQ;
562 }
563
564 dev->state &= ~BAM_STATE_ENABLED;
565
566 SPS_DBG3(dev, "sps:BAM %pa disabled\n", BAM_ID(dev));
567
568 return 0;
569}
570
571/**
572 * BAM device initialization
573 */
574int sps_bam_device_init(struct sps_bam *dev)
575{
576 if (dev->props.virt_addr == NULL) {
577 SPS_ERR(dev, "sps:%s:NULL BAM virtual address\n", __func__);
578 return SPS_ERROR;
579 }
580 dev->base = (void *) dev->props.virt_addr;
581
582 if (dev->props.num_pipes == 0) {
583 /* Assume max number of pipes until BAM registers can be read */
584 dev->props.num_pipes = BAM_MAX_PIPES;
585 SPS_DBG3(dev, "sps:BAM %pa: assuming max number of pipes: %d\n",
586 BAM_ID(dev), dev->props.num_pipes);
587 }
588
589 /* Init BAM state data */
590 dev->state = 0;
591 dev->pipe_active_mask = 0;
592 dev->pipe_remote_mask = 0;
593 INIT_LIST_HEAD(&dev->pipes_q);
594
595 spin_lock_init(&dev->isr_lock);
596
597 spin_lock_init(&dev->connection_lock);
598
599 if ((dev->props.options & SPS_BAM_OPT_ENABLE_AT_BOOT))
600 if (sps_bam_enable(dev)) {
601 SPS_ERR(dev, "sps:%s:Fail to enable bam device\n",
602 __func__);
603 return SPS_ERROR;
604 }
605
606 SPS_DBG3(dev, "sps:BAM device: phys %pa IRQ %d\n",
607 BAM_ID(dev), dev->props.irq);
608
609 return 0;
610}
611
612/**
613 * BAM device de-initialization
614 *
615 */
616int sps_bam_device_de_init(struct sps_bam *dev)
617{
618 int result;
619
620 SPS_DBG3(dev, "sps:BAM device DEINIT: phys %pa IRQ %d\n",
621 BAM_ID(dev), dev->props.irq);
622
623 result = sps_bam_disable(dev);
624
625 return result;
626}
627
628/**
629 * BAM device reset
630 *
631 */
632int sps_bam_reset(struct sps_bam *dev)
633{
634 struct sps_pipe *pipe;
635 u32 pipe_index;
636 int result;
637
638 SPS_DBG3(dev, "sps:BAM device RESET: phys %pa IRQ %d\n",
639 BAM_ID(dev), dev->props.irq);
640
641 /* If BAM is enabled, then disable */
642 result = 0;
643 if ((dev->state & BAM_STATE_ENABLED)) {
644 /* Verify that no pipes are currently allocated */
645 for (pipe_index = 0; pipe_index < dev->props.num_pipes;
646 pipe_index++) {
647 pipe = dev->pipes[pipe_index];
648 if (BAM_PIPE_IS_ASSIGNED(pipe)) {
Rama Krishna Phani Aa0550c92016-07-11 15:58:02 +0530649 if (!(dev->props.options &
650 SPS_BAM_FORCE_RESET)) {
651 SPS_ERR(dev,
652 "sps:BAM device %pa RESET failed: pipe %d in use\n",
653 BAM_ID(dev), pipe_index);
654 result = SPS_ERROR;
655 break;
656 }
657
658 SPS_DBG2(dev,
659 "sps: BAM %pa is force reset with pipe %d in use\n",
Yan Heaabe3fc2016-11-14 17:04:53 -0800660 BAM_ID(dev), pipe_index);
Yan Heaabe3fc2016-11-14 17:04:53 -0800661 }
662 }
663
664 if (result == 0)
665 result = sps_bam_disable(dev);
666 }
667
668 /* BAM will be reset as part of the enable process */
669 if (result == 0)
670 result = sps_bam_enable(dev);
671
672 return result;
673}
674
675/**
676 * Clear the BAM pipe state struct
677 *
678 * This function clears the BAM pipe state struct.
679 *
680 * @pipe - pointer to client pipe struct
681 *
682 */
683static void pipe_clear(struct sps_pipe *pipe)
684{
685 INIT_LIST_HEAD(&pipe->list);
686
687 pipe->state = 0;
688 pipe->pipe_index = SPS_BAM_PIPE_INVALID;
689 pipe->pipe_index_mask = 0;
690 pipe->irq_mask = 0;
691 pipe->mode = -1;
692 pipe->num_descs = 0;
693 pipe->desc_size = 0;
694 pipe->disconnecting = false;
695 pipe->late_eot = false;
696 memset(&pipe->sys, 0, sizeof(pipe->sys));
697 INIT_LIST_HEAD(&pipe->sys.events_q);
698}
699
700/**
701 * Allocate a BAM pipe
702 *
703 */
704u32 sps_bam_pipe_alloc(struct sps_bam *dev, u32 pipe_index)
705{
706 u32 pipe_mask;
707
708 if (pipe_index == SPS_BAM_PIPE_INVALID) {
709 /* Allocate a pipe from the BAM */
710 if ((dev->props.manage & SPS_BAM_MGR_PIPE_NO_ALLOC)) {
711 SPS_ERR(dev,
712 "sps:Restricted from allocating pipes on BAM %pa\n",
713 BAM_ID(dev));
714 return SPS_BAM_PIPE_INVALID;
715 }
716 for (pipe_index = 0, pipe_mask = 1;
717 pipe_index < dev->props.num_pipes;
718 pipe_index++, pipe_mask <<= 1) {
719 if ((pipe_mask & dev->props.restricted_pipes))
720 continue; /* This is a restricted pipe */
721
722 if (dev->pipes[pipe_index] == NULL)
723 break; /* Found an available pipe */
724 }
725 if (pipe_index >= dev->props.num_pipes) {
726 SPS_ERR(dev, "sps:Fail to allocate pipe on BAM %pa\n",
727 BAM_ID(dev));
728 return SPS_BAM_PIPE_INVALID;
729 }
730 } else {
731 /* Check that client-specified pipe is available */
732 if (pipe_index >= dev->props.num_pipes) {
733 SPS_ERR(dev,
734 "sps:Invalid pipe %d for allocate on BAM %pa\n",
735 pipe_index, BAM_ID(dev));
736 return SPS_BAM_PIPE_INVALID;
737 }
738 if ((dev->props.restricted_pipes & (1UL << pipe_index))) {
739 SPS_ERR(dev, "sps:BAM %pa pipe %d is not local\n",
740 BAM_ID(dev), pipe_index);
741 return SPS_BAM_PIPE_INVALID;
742 }
743 if (dev->pipes[pipe_index] != NULL) {
744 SPS_ERR(dev,
745 "sps:Pipe %d already allocated on BAM %pa\n",
746 pipe_index, BAM_ID(dev));
747 return SPS_BAM_PIPE_INVALID;
748 }
749 }
750
751 /* Mark pipe as allocated */
752 dev->pipes[pipe_index] = BAM_PIPE_UNASSIGNED;
753
754 return pipe_index;
755}
756
757/**
758 * Free a BAM pipe
759 *
760 */
761void sps_bam_pipe_free(struct sps_bam *dev, u32 pipe_index)
762{
763 struct sps_pipe *pipe;
764
765 if (pipe_index >= dev->props.num_pipes) {
766 SPS_ERR(dev, "sps:Invalid BAM %pa pipe: %d\n", BAM_ID(dev),
767 pipe_index);
768 return;
769 }
770
771 /* Get the client pipe struct and mark the pipe free */
772 pipe = dev->pipes[pipe_index];
773 dev->pipes[pipe_index] = NULL;
774
775 /* Is the pipe currently allocated? */
776 if (pipe == NULL) {
777 SPS_ERR(dev,
778 "sps:Attempt to free unallocated pipe %d on BAM %pa\n",
779 pipe_index, BAM_ID(dev));
780 return;
781 }
782
783 if (pipe == BAM_PIPE_UNASSIGNED)
784 return; /* Never assigned, so no work to do */
785
786 /* Return pending items to appropriate pools */
787 if (!list_empty(&pipe->sys.events_q)) {
788 struct sps_q_event *sps_event;
789
790 SPS_ERR(dev,
791 "sps:Disconnect BAM %pa pipe %d with events pending\n",
792 BAM_ID(dev), pipe_index);
793
794 sps_event = list_entry((&pipe->sys.events_q)->next,
795 typeof(*sps_event), list);
796
797 while (&sps_event->list != (&pipe->sys.events_q)) {
798 struct sps_q_event *sps_event_delete = sps_event;
799
800 list_del(&sps_event->list);
801 sps_event = list_entry(sps_event->list.next,
802 typeof(*sps_event), list);
803 kfree(sps_event_delete);
804 }
805 }
806
807 /* Clear the BAM pipe state struct */
808 pipe_clear(pipe);
809}
810
811/**
812 * Establish BAM pipe connection
813 *
814 */
815int sps_bam_pipe_connect(struct sps_pipe *bam_pipe,
816 const struct sps_bam_connect_param *params)
817{
818 struct bam_pipe_parameters hw_params;
819 struct sps_bam *dev;
820 const struct sps_connection *map = bam_pipe->map;
821 const struct sps_conn_end_pt *map_pipe;
822 const struct sps_conn_end_pt *other_pipe;
823 void *desc_buf = NULL;
824 u32 pipe_index;
825 int result;
826
827 /* Clear the client pipe state and hw init struct */
828 pipe_clear(bam_pipe);
829 memset(&hw_params, 0, sizeof(hw_params));
830
831 /* Initialize the BAM state struct */
832 bam_pipe->mode = params->mode;
833
834 /* Set pipe streaming mode */
835 if ((params->options & SPS_O_STREAMING) == 0)
836 hw_params.stream_mode = BAM_STREAM_MODE_DISABLE;
837 else
838 hw_params.stream_mode = BAM_STREAM_MODE_ENABLE;
839
840 /* Determine which end point to connect */
841 if (bam_pipe->mode == SPS_MODE_SRC) {
842 map_pipe = &map->src;
843 other_pipe = &map->dest;
844 hw_params.dir = BAM_PIPE_PRODUCER;
845 } else {
846 map_pipe = &map->dest;
847 other_pipe = &map->src;
848 hw_params.dir = BAM_PIPE_CONSUMER;
849 }
850
851 /* Process map parameters */
852 dev = map_pipe->bam;
853 pipe_index = map_pipe->pipe_index;
854
855 SPS_DBG2(dev,
856 "sps:BAM %pa; pipe %d; mode:%d; options:0x%x.\n",
857 BAM_ID(dev), pipe_index, params->mode, params->options);
858
859 if (pipe_index >= dev->props.num_pipes) {
860 SPS_ERR(dev, "sps:Invalid BAM %pa pipe: %d\n", BAM_ID(dev),
861 pipe_index);
862 return SPS_ERROR;
863 }
864 hw_params.event_threshold = (u16) map_pipe->event_threshold;
865 hw_params.ee = dev->props.ee;
866 hw_params.lock_group = map_pipe->lock_group;
867
868 /* Verify that control of this pipe is allowed */
869 if ((dev->props.manage & SPS_BAM_MGR_PIPE_NO_CTRL) ||
870 (dev->props.restricted_pipes & (1UL << pipe_index))) {
871 SPS_ERR(dev, "sps:BAM %pa pipe %d is not local\n",
872 BAM_ID(dev), pipe_index);
873 return SPS_ERROR;
874 }
875
876 /* Control without configuration permission is not supported yet */
877 if ((dev->props.manage & SPS_BAM_MGR_PIPE_NO_CONFIG)) {
878 SPS_ERR(dev,
879 "sps:BAM %pa pipe %d remote config is not supported\n",
880 BAM_ID(dev), pipe_index);
881 return SPS_ERROR;
882 }
883
884 /* Determine operational mode */
885 if (other_pipe->bam != NULL) {
886 unsigned long iova;
887 struct sps_bam *peer_bam = (struct sps_bam *)(other_pipe->bam);
888 /* BAM-to-BAM mode */
889 bam_pipe->state |= BAM_STATE_BAM2BAM;
890 hw_params.mode = BAM_PIPE_MODE_BAM2BAM;
891
892 if (dev->props.options & SPS_BAM_SMMU_EN) {
893 if (bam_pipe->mode == SPS_MODE_SRC)
894 iova = bam_pipe->connect.dest_iova;
895 else
896 iova = bam_pipe->connect.source_iova;
897 SPS_DBG2(dev,
Jishnu Prakash71524642019-03-13 18:12:26 +0530898 "sps:BAM %pa pipe %d uses IOVA 0x%pK.\n",
899 BAM_ID(dev), pipe_index, (void *)iova);
Yan Heaabe3fc2016-11-14 17:04:53 -0800900 hw_params.peer_phys_addr = (u32)iova;
901 } else {
902 hw_params.peer_phys_addr = peer_bam->props.phys_addr;
903 }
904
905 hw_params.peer_pipe = other_pipe->pipe_index;
906
907 /* Verify FIFO buffers are allocated for BAM-to-BAM pipes */
908 if (map->desc.phys_base == SPS_ADDR_INVALID ||
909 map->data.phys_base == SPS_ADDR_INVALID ||
910 map->desc.size == 0 || map->data.size == 0) {
911 SPS_ERR(dev,
912 "sps:FIFO buffers are not allocated for BAM %pa pipe %d.\n",
913 BAM_ID(dev), pipe_index);
914 return SPS_ERROR;
915 }
916
917 if (dev->props.options & SPS_BAM_SMMU_EN) {
918 hw_params.data_base =
919 (phys_addr_t)bam_pipe->connect.data.iova;
920 SPS_DBG2(dev,
Jishnu Prakash71524642019-03-13 18:12:26 +0530921 "sps:BAM %pa pipe %d uses IOVA 0x%pK for data FIFO.\n",
Yan Heaabe3fc2016-11-14 17:04:53 -0800922 BAM_ID(dev), pipe_index,
Jishnu Prakash71524642019-03-13 18:12:26 +0530923 (void *)(bam_pipe->connect.data.iova));
Yan Heaabe3fc2016-11-14 17:04:53 -0800924 } else {
925 hw_params.data_base = map->data.phys_base;
926 }
927
928 hw_params.data_size = map->data.size;
929
930 /* Clear the data FIFO for debug */
931 if (map->data.base != NULL && bam_pipe->mode == SPS_MODE_SRC)
932 memset_io(map->data.base, 0, hw_params.data_size);
933
934 /* set NWD bit for BAM2BAM producer pipe */
935 if (bam_pipe->mode == SPS_MODE_SRC) {
936 if ((params->options & SPS_O_WRITE_NWD) == 0)
937 hw_params.write_nwd = BAM_WRITE_NWD_DISABLE;
938 else
939 hw_params.write_nwd = BAM_WRITE_NWD_ENABLE;
940 }
941 } else {
942 /* System mode */
943 hw_params.mode = BAM_PIPE_MODE_SYSTEM;
944 bam_pipe->sys.desc_buf = map->desc.base;
945 bam_pipe->sys.desc_offset = 0;
946 bam_pipe->sys.acked_offset = 0;
947 }
948
949 /* Initialize the client pipe state */
950 bam_pipe->pipe_index = pipe_index;
951 bam_pipe->pipe_index_mask = 1UL << pipe_index;
952
953 /* Get virtual address for descriptor FIFO */
954 if (map->desc.phys_base != SPS_ADDR_INVALID) {
955 if (map->desc.size < (2 * sizeof(struct sps_iovec))) {
956 SPS_ERR(dev,
957 "sps:Invalid descriptor FIFO size for BAM %pa pipe %d: %d\n",
958 BAM_ID(dev), pipe_index, map->desc.size);
959 return SPS_ERROR;
960 }
961 desc_buf = map->desc.base;
962
963 /*
964 * Note that descriptor base and size will be left zero from
965 * the memset() above if the physical address was invalid.
966 * This allows a satellite driver to set the FIFO as
967 * local memory for system mode.
968 */
969
970 if (dev->props.options & SPS_BAM_SMMU_EN) {
971 hw_params.desc_base =
972 (phys_addr_t)bam_pipe->connect.desc.iova;
973 SPS_DBG2(dev,
Jishnu Prakash71524642019-03-13 18:12:26 +0530974 "sps:BAM %pa pipe %d uses IOVA 0x%pK for desc FIFO.\n",
Yan Heaabe3fc2016-11-14 17:04:53 -0800975 BAM_ID(dev), pipe_index,
Jishnu Prakash71524642019-03-13 18:12:26 +0530976 (void *)(bam_pipe->connect.desc.iova));
Yan Heaabe3fc2016-11-14 17:04:53 -0800977 } else {
978 hw_params.desc_base = map->desc.phys_base;
979 }
980
981 hw_params.desc_size = map->desc.size;
982 }
983
984 /* Configure the descriptor FIFO for both operational modes */
985 if (desc_buf != NULL)
986 if (bam_pipe->mode == SPS_MODE_SRC ||
987 hw_params.mode == BAM_PIPE_MODE_SYSTEM)
988 memset_io(desc_buf, 0, hw_params.desc_size);
989
990 bam_pipe->desc_size = hw_params.desc_size;
991 bam_pipe->num_descs = bam_pipe->desc_size / sizeof(struct sps_iovec);
992
993 result = SPS_ERROR;
994 /* Insure that the BAM is enabled */
995 if ((dev->state & BAM_STATE_ENABLED) == 0)
996 if (sps_bam_enable(dev))
997 goto exit_init_err;
998
999 /* Check pipe allocation */
1000 if (dev->pipes[pipe_index] != BAM_PIPE_UNASSIGNED) {
1001 SPS_ERR(dev, "sps:Invalid pipe %d on BAM %pa for connect\n",
1002 pipe_index, BAM_ID(dev));
1003 return SPS_ERROR;
1004 }
1005
1006 if (bam_pipe_is_enabled(&dev->base, pipe_index)) {
1007 if (params->options & SPS_O_NO_DISABLE)
1008 SPS_DBG2(dev,
1009 "sps:BAM %pa pipe %d is already enabled.\n",
1010 BAM_ID(dev), pipe_index);
1011 else {
1012 SPS_ERR(dev, "sps:BAM %pa pipe %d sharing violation\n",
1013 BAM_ID(dev), pipe_index);
1014 return SPS_ERROR;
1015 }
1016 }
1017
1018 if (bam_pipe_init(&dev->base, pipe_index, &hw_params, dev->props.ee)) {
1019 SPS_ERR(dev, "sps:BAM %pa pipe %d init error\n",
1020 BAM_ID(dev), pipe_index);
1021 goto exit_err;
1022 }
1023
1024 /* Assign pipe to client */
1025 dev->pipes[pipe_index] = bam_pipe;
1026
1027 /* Process configuration parameters */
1028 if (params->options != 0 ||
1029 (bam_pipe->state & BAM_STATE_BAM2BAM) == 0) {
1030 /* Process init-time only parameters */
1031 u32 irq_gen_addr;
1032
1033 /* Set interrupt mode */
1034 irq_gen_addr = SPS_ADDR_INVALID;
1035 if ((params->options & SPS_O_IRQ_MTI))
1036 /* Client has directly specified the MTI address */
1037 irq_gen_addr = params->irq_gen_addr;
1038 else if ((dev->state & BAM_STATE_MTI))
1039 /* This BAM has MTI use enabled */
1040 irq_gen_addr = dev->props.irq_gen_addr;
1041
1042 if (irq_gen_addr != SPS_ADDR_INVALID) {
1043 /*
1044 * No checks - assume BAM is already setup for
1045 * MTI generation,
1046 * or the pipe will be set to satellite control.
1047 */
1048 bam_pipe->state |= BAM_STATE_MTI;
1049 bam_pipe->irq_gen_addr = irq_gen_addr;
1050 }
1051
1052 /* Process runtime parameters */
1053 if (sps_bam_pipe_set_params(dev, pipe_index,
1054 params->options)) {
1055 dev->pipes[pipe_index] = BAM_PIPE_UNASSIGNED;
1056 goto exit_err;
1057 }
1058 }
1059
1060 /* Indicate initialization is complete */
1061 dev->pipes[pipe_index] = bam_pipe;
1062 dev->pipe_active_mask |= 1UL << pipe_index;
1063 list_add_tail(&bam_pipe->list, &dev->pipes_q);
1064
1065 SPS_DBG2(dev,
1066 "sps:BAM %pa; pipe %d; pipe_index_mask:0x%x; pipe_active_mask:0x%x.\n",
1067 BAM_ID(dev), pipe_index,
1068 bam_pipe->pipe_index_mask, dev->pipe_active_mask);
1069
1070 bam_pipe->state |= BAM_STATE_INIT;
1071 result = 0;
1072exit_err:
1073 if (result) {
1074 if (params->options & SPS_O_NO_DISABLE)
1075 SPS_DBG2(dev, "sps:BAM %pa pipe %d connection exits\n",
1076 BAM_ID(dev), pipe_index);
1077 else
1078 bam_pipe_exit(&dev->base, pipe_index, dev->props.ee);
1079 }
1080exit_init_err:
1081 if (result) {
1082 /* Clear the client pipe state */
1083 pipe_clear(bam_pipe);
1084 }
1085
1086 return result;
1087}
1088
1089/**
1090 * Disconnect a BAM pipe connection
1091 *
1092 */
1093int sps_bam_pipe_disconnect(struct sps_bam *dev, u32 pipe_index)
1094{
1095 struct sps_pipe *pipe;
1096 int result;
1097 unsigned long flags;
1098
1099 if (pipe_index >= dev->props.num_pipes) {
1100 SPS_ERR(dev, "sps:Invalid BAM %pa pipe: %d\n", BAM_ID(dev),
1101 pipe_index);
1102 return SPS_ERROR;
1103 }
1104
1105 /* Deallocate and reset the BAM pipe */
1106 pipe = dev->pipes[pipe_index];
1107 if (BAM_PIPE_IS_ASSIGNED(pipe)) {
1108 if ((dev->pipe_active_mask & (1UL << pipe_index))) {
1109 spin_lock_irqsave(&dev->isr_lock, flags);
1110 list_del(&pipe->list);
1111 dev->pipe_active_mask &= ~(1UL << pipe_index);
1112 spin_unlock_irqrestore(&dev->isr_lock, flags);
1113 }
1114 dev->pipe_remote_mask &= ~(1UL << pipe_index);
1115 if (pipe->connect.options & SPS_O_NO_DISABLE)
1116 SPS_DBG2(dev, "sps:BAM %pa pipe %d exits.\n",
1117 BAM_ID(dev), pipe_index);
1118 else
1119 bam_pipe_exit(&dev->base, pipe_index, dev->props.ee);
1120 if (pipe->sys.desc_cache != NULL) {
1121 u32 size = pipe->num_descs * sizeof(void *);
1122
1123 if (pipe->desc_size + size <= PAGE_SIZE) {
1124 if (dev->props.options & SPS_BAM_HOLD_MEM)
1125 memset(pipe->sys.desc_cache, 0,
1126 pipe->desc_size + size);
1127 else
1128 kfree(pipe->sys.desc_cache);
1129 } else {
1130 vfree(pipe->sys.desc_cache);
1131 }
1132 pipe->sys.desc_cache = NULL;
1133 }
1134 dev->pipes[pipe_index] = BAM_PIPE_UNASSIGNED;
1135 pipe_clear(pipe);
1136 result = 0;
1137 } else {
1138 result = SPS_ERROR;
1139 }
1140
1141 if (result)
1142 SPS_ERR(dev, "sps:BAM %pa pipe %d already disconnected\n",
1143 BAM_ID(dev), pipe_index);
1144
1145 return result;
1146}
1147
1148/**
1149 * Set BAM pipe interrupt enable state
1150 *
1151 * This function sets the interrupt enable state for a BAM pipe.
1152 *
1153 * @dev - pointer to BAM device descriptor
1154 *
1155 * @pipe_index - pipe index
1156 *
1157 * @poll - true if SPS_O_POLL is set, false otherwise
1158 *
1159 */
1160static void pipe_set_irq(struct sps_bam *dev, u32 pipe_index,
1161 u32 poll)
1162{
1163 struct sps_pipe *pipe = dev->pipes[pipe_index];
1164 enum bam_enable irq_enable;
1165
1166 SPS_DBG2(dev,
1167 "sps:BAM:%pa; pipe %d; poll:%d, irq_mask:0x%x; pipe state:0x%x; dev state:0x%x.\n",
1168 BAM_ID(dev), pipe_index, poll, pipe->irq_mask,
1169 pipe->state, dev->state);
1170
1171 if (poll == 0 && pipe->irq_mask != 0 &&
1172 (dev->state & BAM_STATE_IRQ)) {
1173 if ((pipe->state & BAM_STATE_BAM2BAM) != 0 &&
1174 (pipe->state & BAM_STATE_IRQ) == 0) {
1175 /*
1176 * If enabling the interrupt for a BAM-to-BAM pipe,
1177 * clear the existing interrupt status
1178 */
1179 (void)bam_pipe_get_and_clear_irq_status(&dev->base,
1180 pipe_index);
1181 }
1182 pipe->state |= BAM_STATE_IRQ;
1183 irq_enable = BAM_ENABLE;
1184 pipe->polled = false;
1185 } else {
1186 pipe->state &= ~BAM_STATE_IRQ;
1187 irq_enable = BAM_DISABLE;
1188 pipe->polled = true;
1189 if (poll == 0 && pipe->irq_mask)
1190 SPS_DBG2(dev,
1191 "sps:BAM %pa pipe %d forced to use polling\n",
1192 BAM_ID(dev), pipe_index);
1193 }
1194 if ((pipe->state & BAM_STATE_MTI) == 0)
1195 bam_pipe_set_irq(&dev->base, pipe_index, irq_enable,
1196 pipe->irq_mask, dev->props.ee);
1197 else
1198 bam_pipe_set_mti(&dev->base, pipe_index, irq_enable,
1199 pipe->irq_mask, pipe->irq_gen_addr);
1200
1201}
1202
1203/**
1204 * Set BAM pipe parameters
1205 *
1206 */
1207int sps_bam_pipe_set_params(struct sps_bam *dev, u32 pipe_index, u32 options)
1208{
1209 struct sps_pipe *pipe = dev->pipes[pipe_index];
1210 u32 mask;
1211 int wake_up_is_one_shot;
1212 int no_queue;
1213 int ack_xfers;
1214 u32 size;
1215 int n;
1216
1217 SPS_DBG2(dev, "sps:BAM %pa pipe %d opt 0x%x\n",
1218 BAM_ID(dev), pipe_index, options);
1219
1220 /* Capture some options */
1221 wake_up_is_one_shot = ((options & SPS_O_WAKEUP_IS_ONESHOT));
1222 no_queue = ((options & SPS_O_NO_Q));
1223 ack_xfers = ((options & SPS_O_ACK_TRANSFERS));
1224
1225 pipe->hybrid = options & SPS_O_HYBRID;
1226 pipe->late_eot = options & SPS_O_LATE_EOT;
1227
1228 /* Create interrupt source mask */
1229 mask = 0;
1230 for (n = 0; n < ARRAY_SIZE(opt_event_table); n++) {
1231 /* Is client registering for this event? */
1232 if ((options & opt_event_table[n].option) == 0)
1233 continue; /* No */
1234
1235 mask |= opt_event_table[n].pipe_irq;
1236 }
1237
1238#ifdef SPS_BAM_STATISTICS
1239 /* Is an illegal mode change specified? */
1240 if (pipe->sys.desc_wr_count > 0 &&
1241 (no_queue != pipe->sys.no_queue
1242 || ack_xfers != pipe->sys.ack_xfers)) {
1243 SPS_ERR(dev,
1244 "sps:Queue/ack mode change after transfer: BAM %pa pipe %d opt 0x%x\n",
1245 BAM_ID(dev), pipe_index, options);
1246 return SPS_ERROR;
1247 }
1248#endif /* SPS_BAM_STATISTICS */
1249
1250 /* Is client setting invalid options for a BAM-to-BAM connection? */
1251 if ((pipe->state & BAM_STATE_BAM2BAM) &&
1252 (options & BAM2BAM_O_INVALID)) {
1253 SPS_ERR(dev,
1254 "sps:Invalid option for BAM-to-BAM: BAM %pa pipe %d opt 0x%x\n",
1255 BAM_ID(dev), pipe_index, options);
1256 return SPS_ERROR;
1257 }
1258
1259 /* Allocate descriptor FIFO cache if NO_Q option is disabled */
1260 if (!no_queue && pipe->sys.desc_cache == NULL && pipe->num_descs > 0
1261 && (pipe->state & BAM_STATE_BAM2BAM) == 0) {
1262 /* Allocate both descriptor cache and user pointer array */
1263 size = pipe->num_descs * sizeof(void *);
1264
1265 if (pipe->desc_size + size <= PAGE_SIZE) {
1266 if ((dev->props.options &
1267 SPS_BAM_HOLD_MEM)) {
1268 if (dev->desc_cache_pointers[pipe_index]) {
1269 pipe->sys.desc_cache =
1270 dev->desc_cache_pointers
1271 [pipe_index];
1272 } else {
1273 pipe->sys.desc_cache =
1274 kzalloc(pipe->desc_size + size,
1275 GFP_KERNEL);
1276 dev->desc_cache_pointers[pipe_index] =
1277 pipe->sys.desc_cache;
1278 }
1279 } else {
1280 pipe->sys.desc_cache =
1281 kzalloc(pipe->desc_size + size,
1282 GFP_KERNEL);
1283 }
1284 if (pipe->sys.desc_cache == NULL) {
1285 SPS_ERR(dev,
1286 "sps:No memory for pipe%d of BAM %pa\n",
1287 pipe_index, BAM_ID(dev));
1288 return -ENOMEM;
1289 }
1290 } else {
1291 pipe->sys.desc_cache =
1292 vmalloc(pipe->desc_size + size);
1293
1294 if (pipe->sys.desc_cache == NULL) {
1295 SPS_ERR(dev,
1296 "sps:No memory for pipe %d of BAM %pa\n",
1297 pipe_index, BAM_ID(dev));
1298 return -ENOMEM;
1299 }
1300
1301 memset(pipe->sys.desc_cache, 0, pipe->desc_size + size);
1302 }
1303
1304 if (pipe->sys.desc_cache == NULL) {
1305 /*** MUST BE LAST POINT OF FAILURE (see below) *****/
1306 SPS_ERR(dev,
1307 "sps:Desc cache error: BAM %pa pipe %d: %d\n",
1308 BAM_ID(dev), pipe_index,
1309 pipe->desc_size + size);
1310 return SPS_ERROR;
1311 }
1312 pipe->sys.user_ptrs = (void **)(pipe->sys.desc_cache +
1313 pipe->desc_size);
1314 pipe->sys.cache_offset = pipe->sys.acked_offset;
1315 }
1316
1317 /*
1318 * No failures beyond this point. Note that malloc() is last point of
1319 * failure, so no free() handling is needed.
1320 */
1321
1322 /* Enable/disable the pipe's interrupt sources */
1323 pipe->irq_mask = mask;
1324 pipe_set_irq(dev, pipe_index, (options & SPS_O_POLL));
1325
1326 /* Store software feature enables */
1327 pipe->wake_up_is_one_shot = wake_up_is_one_shot;
1328 pipe->sys.no_queue = no_queue;
1329 pipe->sys.ack_xfers = ack_xfers;
1330
1331 return 0;
1332}
1333
1334/**
1335 * Enable a BAM pipe
1336 *
1337 */
1338int sps_bam_pipe_enable(struct sps_bam *dev, u32 pipe_index)
1339{
1340 struct sps_pipe *pipe = dev->pipes[pipe_index];
1341
1342 /* Enable the BAM pipe */
1343 bam_pipe_enable(&dev->base, pipe_index);
1344 pipe->state |= BAM_STATE_ENABLED;
1345
1346 return 0;
1347}
1348
1349/**
1350 * Disable a BAM pipe
1351 *
1352 */
1353int sps_bam_pipe_disable(struct sps_bam *dev, u32 pipe_index)
1354{
1355 struct sps_pipe *pipe = dev->pipes[pipe_index];
1356
1357 /* Disable the BAM pipe */
1358 if (pipe->connect.options & SPS_O_NO_DISABLE)
1359 SPS_DBG2(dev, "sps:BAM %pa pipe %d enters disable state\n",
1360 BAM_ID(dev), pipe_index);
1361 else
1362 bam_pipe_disable(&dev->base, pipe_index);
1363
1364 pipe->state &= ~BAM_STATE_ENABLED;
1365
1366 return 0;
1367}
1368
1369/**
1370 * Register an event for a BAM pipe
1371 *
1372 */
1373int sps_bam_pipe_reg_event(struct sps_bam *dev,
1374 u32 pipe_index,
1375 struct sps_register_event *reg)
1376{
1377 struct sps_pipe *pipe = dev->pipes[pipe_index];
1378 struct sps_bam_event_reg *event_reg;
1379 int n;
1380
1381 if (pipe->sys.no_queue && reg->xfer_done != NULL &&
1382 reg->mode != SPS_TRIGGER_CALLBACK) {
1383 SPS_ERR(dev,
1384 "sps:Only callback events support for NO_Q: BAM %pa pipe %d mode %d\n",
1385 BAM_ID(dev), pipe_index, reg->mode);
1386 return SPS_ERROR;
1387 }
1388
1389 for (n = 0; n < ARRAY_SIZE(opt_event_table); n++) {
1390 int index;
1391
1392 /* Is client registering for this event? */
1393 if ((reg->options & opt_event_table[n].option) == 0)
1394 continue; /* No */
1395
1396 index = SPS_EVENT_INDEX(opt_event_table[n].event_id);
1397 if (index < 0)
1398 SPS_ERR(dev,
1399 "sps:Negative event index: BAM %pa pipe %d mode %d\n",
1400 BAM_ID(dev), pipe_index, reg->mode);
1401 else {
1402 event_reg = &pipe->sys.event_regs[index];
1403 event_reg->xfer_done = reg->xfer_done;
1404 event_reg->callback = reg->callback;
1405 event_reg->mode = reg->mode;
1406 event_reg->user = reg->user;
1407 }
1408 }
1409
1410 return 0;
1411}
1412
1413/**
1414 * Submit a transfer of a single buffer to a BAM pipe
1415 *
1416 */
1417int sps_bam_pipe_transfer_one(struct sps_bam *dev,
1418 u32 pipe_index, u32 addr, u32 size,
1419 void *user, u32 flags)
1420{
1421 struct sps_pipe *pipe = dev->pipes[pipe_index];
1422 struct sps_iovec *desc;
1423 struct sps_iovec iovec;
1424 u32 next_write;
1425 static int show_recom;
1426
Jishnu Prakash71524642019-03-13 18:12:26 +05301427 SPS_DBG(dev, "sps:BAM %pa pipe %d addr 0x%pK size 0x%x flags 0x%x\n",
1428 BAM_ID(dev), pipe_index,
1429 (void *)(long)addr, size, flags);
Yan Heaabe3fc2016-11-14 17:04:53 -08001430
1431 /* Is this a BAM-to-BAM or satellite connection? */
1432 if ((pipe->state & (BAM_STATE_BAM2BAM | BAM_STATE_REMOTE))) {
1433 SPS_ERR(dev, "sps:Transfer on BAM-to-BAM: BAM %pa pipe %d\n",
1434 BAM_ID(dev), pipe_index);
1435 return SPS_ERROR;
1436 }
1437
1438 /*
1439 * Client identifier (user pointer) is not supported for
1440 * SPS_O_NO_Q option.
1441 */
1442 if (pipe->sys.no_queue && user != NULL) {
1443 SPS_ERR(dev, "sps:User pointer arg non-NULL: BAM %pa pipe %d\n",
1444 BAM_ID(dev), pipe_index);
1445 return SPS_ERROR;
1446 }
1447
1448 /* Determine if descriptor can be queued */
1449 next_write = pipe->sys.desc_offset + sizeof(struct sps_iovec);
1450 if (next_write >= pipe->desc_size)
1451 next_write = 0;
1452
1453 if (next_write == pipe->sys.acked_offset) {
1454 /*
1455 * If pipe is polled and client is not ACK'ing descriptors,
1456 * perform polling operation so that any outstanding ACKs
1457 * can occur.
1458 */
1459 if (!pipe->sys.ack_xfers && pipe->polled) {
1460 pipe_handler_eot(dev, pipe);
1461 if (next_write == pipe->sys.acked_offset) {
1462 if (!show_recom) {
1463 show_recom = true;
1464 SPS_ERR(dev,
1465 "sps:Client of BAM %pa pipe %d is recommended to have flow control\n",
1466 BAM_ID(dev), pipe_index);
1467 }
1468
1469 SPS_DBG1(dev,
1470 "sps:Descriptor FIFO is full for BAM %pa pipe %d after pipe_handler_eot\n",
1471 BAM_ID(dev), pipe_index);
1472 return SPS_ERROR;
1473 }
1474 } else {
1475 if (!show_recom) {
1476 show_recom = true;
1477 SPS_ERR(dev,
1478 "sps:Client of BAM %pa pipe %d is recommended to have flow control.\n",
1479 BAM_ID(dev), pipe_index);
1480 }
1481
1482 SPS_DBG1(dev,
1483 "sps:Descriptor FIFO is full for BAM %pa pipe %d\n",
1484 BAM_ID(dev), pipe_index);
1485 return SPS_ERROR;
1486 }
1487 }
1488
1489 /* Create descriptor */
1490 if (!pipe->sys.no_queue)
1491 desc = (struct sps_iovec *) (pipe->sys.desc_cache +
1492 pipe->sys.desc_offset);
1493 else
1494 desc = &iovec;
1495
1496 desc->addr = addr;
1497 desc->size = size;
1498
1499 if ((flags & SPS_IOVEC_FLAG_DEFAULT) == 0) {
1500 desc->flags = (flags & BAM_IOVEC_FLAG_MASK)
1501 | DESC_UPPER_ADDR(flags);
1502 } else {
1503 if (pipe->mode == SPS_MODE_SRC)
1504 desc->flags = SPS_IOVEC_FLAG_INT
1505 | DESC_UPPER_ADDR(flags);
1506 else
1507 desc->flags = (SPS_IOVEC_FLAG_INT | SPS_IOVEC_FLAG_EOT)
1508 | DESC_UPPER_ADDR(flags);
1509 }
1510
1511#ifdef SPS_BAM_STATISTICS
1512 if ((flags & SPS_IOVEC_FLAG_INT))
1513 pipe->sys.int_flags++;
1514 if ((flags & SPS_IOVEC_FLAG_EOT))
1515 pipe->sys.eot_flags++;
1516#endif /* SPS_BAM_STATISTICS */
1517
1518 /* Update hardware descriptor FIFO - should result in burst */
1519 *((struct sps_iovec *) (pipe->sys.desc_buf + pipe->sys.desc_offset))
1520 = *desc;
1521
1522 /* Record user pointer value */
1523 if (!pipe->sys.no_queue) {
1524 u32 index = pipe->sys.desc_offset / sizeof(struct sps_iovec);
1525
1526 pipe->sys.user_ptrs[index] = user;
1527#ifdef SPS_BAM_STATISTICS
1528 if (user != NULL)
1529 pipe->sys.user_ptrs_count++;
1530#endif /* SPS_BAM_STATISTICS */
1531 }
1532
1533 /* Update descriptor ACK offset */
1534 pipe->sys.desc_offset = next_write;
1535
1536#ifdef SPS_BAM_STATISTICS
1537 /* Update statistics */
1538 pipe->sys.desc_wr_count++;
1539#endif /* SPS_BAM_STATISTICS */
1540
1541 /* Notify pipe */
1542 if ((flags & SPS_IOVEC_FLAG_NO_SUBMIT) == 0) {
1543 wmb(); /* Memory Barrier */
1544 bam_pipe_set_desc_write_offset(&dev->base, pipe_index,
1545 next_write);
1546 }
1547
1548 if (dev->ipc_loglevel == 0)
1549 SPS_DBG(dev,
1550 "sps:%s: BAM phy addr:%pa; pipe %d; write pointer to tell HW: 0x%x; write pointer read from HW: 0x%x\n",
1551 __func__, BAM_ID(dev), pipe_index, next_write,
1552 bam_pipe_get_desc_write_offset(&dev->base, pipe_index));
1553
1554 return 0;
1555}
1556
1557/**
1558 * Submit a transfer to a BAM pipe
1559 *
1560 */
1561int sps_bam_pipe_transfer(struct sps_bam *dev,
1562 u32 pipe_index, struct sps_transfer *transfer)
1563{
1564 struct sps_iovec *iovec;
1565 u32 count;
1566 u32 flags;
1567 void *user;
1568 int n;
1569 int result;
1570 struct sps_pipe *pipe = dev->pipes[pipe_index];
1571
1572 if (transfer->iovec_count == 0) {
1573 SPS_ERR(dev, "sps:iovec count zero: BAM %pa pipe %d\n",
1574 BAM_ID(dev), pipe_index);
1575 return SPS_ERROR;
1576 }
1577
1578 if (!pipe->sys.ack_xfers && pipe->polled) {
1579 sps_bam_pipe_get_unused_desc_num(dev, pipe_index,
1580 &count);
1581 count = pipe->desc_size / sizeof(struct sps_iovec) - count - 1;
1582 } else
1583 sps_bam_get_free_count(dev, pipe_index, &count);
1584
1585 if (count < transfer->iovec_count) {
1586 SPS_ERR(dev,
1587 "sps:Insufficient free desc: BAM %pa pipe %d: %d\n",
1588 BAM_ID(dev), pipe_index, count);
1589 return SPS_ERROR;
1590 }
1591
1592 user = NULL; /* NULL for all except last descriptor */
1593 for (n = (int)transfer->iovec_count - 1, iovec = transfer->iovec;
1594 n >= 0; n--, iovec++) {
1595 if (n > 0) {
1596 /* This is *not* the last descriptor */
1597 flags = iovec->flags | SPS_IOVEC_FLAG_NO_SUBMIT;
1598 } else {
1599 /* This *is* the last descriptor */
1600 flags = iovec->flags;
1601 user = transfer->user;
1602 }
1603 result = sps_bam_pipe_transfer_one(dev, pipe_index,
1604 iovec->addr,
1605 iovec->size, user,
1606 flags);
1607 if (result)
1608 return SPS_ERROR;
1609 }
1610
1611 return 0;
1612}
1613
1614int sps_bam_pipe_inject_zlt(struct sps_bam *dev, u32 pipe_index)
1615{
1616 struct sps_pipe *pipe = dev->pipes[pipe_index];
1617 struct sps_iovec *desc;
1618 u32 read_p, write_p, next_write;
1619
1620 if (pipe->state & BAM_STATE_BAM2BAM)
1621 SPS_DBG2(dev, "sps: BAM-to-BAM pipe: BAM %pa pipe %d\n",
1622 BAM_ID(dev), pipe_index);
1623 else
1624 SPS_DBG2(dev, "sps: BAM-to-System pipe: BAM %pa pipe %d\n",
1625 BAM_ID(dev), pipe_index);
1626
1627 if (!(pipe->state & BAM_STATE_ENABLED)) {
1628 SPS_ERR(dev,
1629 "sps: BAM %pa pipe %d is not enabled.\n",
1630 BAM_ID(dev), pipe_index);
1631 return SPS_ERROR;
1632 }
1633
1634 read_p = bam_pipe_get_desc_read_offset(&dev->base, pipe_index);
1635 write_p = bam_pipe_get_desc_write_offset(&dev->base, pipe_index);
1636
1637 SPS_DBG2(dev,
1638 "sps: BAM %pa pipe %d: read pointer:0x%x; write pointer:0x%x.\n",
1639 BAM_ID(dev), pipe_index, read_p, write_p);
1640
1641 if (read_p == write_p) {
1642 SPS_ERR(dev,
1643 "sps: BAM %pa pipe %d: read pointer 0x%x is already equal to write pointer.\n",
1644 BAM_ID(dev), pipe_index, read_p);
1645 return SPS_ERROR;
1646 }
1647
1648 next_write = write_p + sizeof(struct sps_iovec);
1649 if (next_write >= pipe->desc_size) {
1650 SPS_DBG2(dev,
1651 "sps: BAM %pa pipe %d: next write is 0x%x: wrap around.\n",
1652 BAM_ID(dev), pipe_index, next_write);
1653 next_write = 0;
1654 }
1655
1656 desc = (struct sps_iovec *) (pipe->connect.desc.base + write_p);
1657 desc->addr = 0;
1658 desc->size = 0;
1659 desc->flags = SPS_IOVEC_FLAG_EOT;
1660
1661 bam_pipe_set_desc_write_offset(&dev->base, pipe_index,
1662 next_write);
1663 wmb(); /* update write pointer in HW */
1664 SPS_DBG2(dev,
1665 "sps: BAM %pa pipe %d: write pointer to tell HW: 0x%x; write pointer read from HW: 0x%x\n",
1666 BAM_ID(dev), pipe_index, next_write,
1667 bam_pipe_get_desc_write_offset(&dev->base, pipe_index));
1668
1669 return 0;
1670}
1671
1672/**
1673 * Allocate an event tracking struct
1674 *
1675 * This function allocates an event tracking struct.
1676 *
1677 * @pipe - pointer to pipe state
1678 *
1679 * @event_reg - pointer to event registration
1680 *
1681 * @return - pointer to event notification struct, or NULL
1682 *
1683 */
1684static struct sps_q_event *alloc_event(struct sps_pipe *pipe,
1685 struct sps_bam_event_reg *event_reg)
1686{
1687 struct sps_q_event *event;
1688
1689 /* A callback event object is registered, so trigger with payload */
1690 event = &pipe->sys.event;
1691 memset(event, 0, sizeof(*event));
1692
1693 return event;
1694}
1695
1696/**
1697 * Trigger an event notification
1698 *
1699 * This function triggers an event notification.
1700 *
1701 * @dev - pointer to BAM device descriptor
1702 *
1703 * @pipe - pointer to pipe state
1704 *
1705 * @event_reg - pointer to event registration
1706 *
1707 * @sps_event - pointer to event struct
1708 *
1709 */
1710static void trigger_event(struct sps_bam *dev,
1711 struct sps_pipe *pipe,
1712 struct sps_bam_event_reg *event_reg,
1713 struct sps_q_event *sps_event)
1714{
1715 if (sps_event == NULL) {
1716 SPS_DBG1(dev, "%s", "sps:trigger_event.sps_event is NULL.\n");
1717 return;
1718 }
1719
1720 if (event_reg->xfer_done) {
1721 complete(event_reg->xfer_done);
1722 SPS_DBG(dev, "sps:trigger_event.done=%d.\n",
1723 event_reg->xfer_done->done);
1724 }
1725
1726 if (event_reg->callback) {
1727 SPS_DBG(dev, "%s", "sps:trigger_event.using callback.\n");
1728 event_reg->callback(&sps_event->notify);
1729 }
1730
1731}
1732
1733/**
1734 * Handle a BAM pipe's generic interrupt sources
1735 *
1736 * This function creates the event notification for a BAM pipe's
1737 * generic interrupt sources. The caller of this function must lock the BAM
1738 * device's mutex.
1739 *
1740 * @dev - pointer to BAM device descriptor
1741 *
1742 * @pipe - pointer to pipe state
1743 *
1744 * @event_id - event identifier enum
1745 *
1746 */
1747static void pipe_handler_generic(struct sps_bam *dev,
1748 struct sps_pipe *pipe,
1749 enum sps_event event_id)
1750{
1751 struct sps_bam_event_reg *event_reg;
1752 struct sps_q_event *sps_event;
1753 int index;
1754
1755 index = SPS_EVENT_INDEX(event_id);
1756 if (index < 0 || index >= SPS_EVENT_INDEX(SPS_EVENT_MAX))
1757 return;
1758
1759 event_reg = &pipe->sys.event_regs[index];
1760 sps_event = alloc_event(pipe, event_reg);
1761 if (sps_event != NULL) {
1762 sps_event->notify.event_id = event_id;
1763 sps_event->notify.user = event_reg->user;
1764 trigger_event(dev, pipe, event_reg, sps_event);
1765 }
1766}
1767
1768/**
1769 * Handle a BAM pipe's WAKEUP interrupt sources
1770 *
1771 * This function creates the event notification for a BAM pipe's
1772 * WAKEUP interrupt source. The caller of this function must lock the BAM
1773 * device's mutex.
1774 *
1775 * @dev - pointer to BAM device descriptor
1776 *
1777 * @pipe - pointer to pipe state
1778 *
1779 */
1780static void pipe_handler_wakeup(struct sps_bam *dev, struct sps_pipe *pipe)
1781{
1782 struct sps_bam_event_reg *event_reg;
1783 struct sps_q_event *event;
1784 u32 pipe_index = pipe->pipe_index;
1785
1786 if (pipe->wake_up_is_one_shot) {
1787 SPS_DBG2(dev,
1788 "sps:BAM:%pa pipe %d wake_up_is_one_shot; irq_mask:0x%x.\n",
1789 BAM_ID(dev), pipe_index, pipe->irq_mask);
1790 /* Disable the pipe WAKEUP interrupt source */
1791 pipe->irq_mask &= ~BAM_PIPE_IRQ_WAKE;
1792 pipe_set_irq(dev, pipe_index, pipe->polled);
1793 }
1794
1795 event_reg = &pipe->sys.event_regs[SPS_EVENT_INDEX(SPS_EVENT_WAKEUP)];
1796 event = alloc_event(pipe, event_reg);
1797 if (event != NULL) {
1798 event->notify.event_id = SPS_EVENT_WAKEUP;
1799 event->notify.user = event_reg->user;
1800 trigger_event(dev, pipe, event_reg, event);
1801 }
1802}
1803
1804/**
1805 * Handle a BAM pipe's EOT/INT interrupt sources
1806 *
1807 * This function creates the event notification for a BAM pipe's EOT interrupt
1808 * source. The caller of this function must lock the BAM device's mutex.
1809 *
1810 * @dev - pointer to BAM device descriptor
1811 *
1812 * @pipe - pointer to pipe state
1813 *
1814 */
1815static void pipe_handler_eot(struct sps_bam *dev, struct sps_pipe *pipe)
1816{
1817 struct sps_bam_event_reg *event_reg;
1818 struct sps_q_event *event;
1819 struct sps_iovec *desc;
1820 struct sps_iovec *cache;
1821 void **user;
1822 u32 *update_offset;
1823 u32 pipe_index = pipe->pipe_index;
1824 u32 offset;
1825 u32 end_offset;
1826 enum sps_event event_id;
1827 u32 flags;
1828 u32 enabled;
1829 int producer = (pipe->mode == SPS_MODE_SRC);
1830
1831 if (pipe->sys.handler_eot) {
1832 /*
1833 * This can happen if the pipe is configured for polling
1834 * (IRQ disabled) and callback event generation.
1835 * The client may perform a get_iovec() inside the callback.
1836 */
1837 SPS_DBG(dev,
1838 "sps:%s; still handling EOT for pipe %d.\n",
1839 __func__, pipe->pipe_index);
1840 return;
1841 }
1842
1843 pipe->sys.handler_eot = true;
1844
1845 /* Get offset of last descriptor completed by the pipe */
1846 end_offset = bam_pipe_get_desc_read_offset(&dev->base, pipe_index);
1847
1848 if (dev->ipc_loglevel == 0)
1849 SPS_DBG(dev,
1850 "sps:%s; pipe index:%d; read pointer:0x%x; write pointer:0x%x; sys.acked_offset:0x%x.\n",
1851 __func__, pipe->pipe_index, end_offset,
1852 bam_pipe_get_desc_write_offset(&dev->base, pipe_index),
1853 pipe->sys.acked_offset);
1854
1855 if (producer && pipe->late_eot) {
1856 struct sps_iovec *desc_end;
1857
1858 if (end_offset == 0)
1859 desc_end = (struct sps_iovec *)(pipe->sys.desc_buf
1860 + pipe->desc_size - sizeof(struct sps_iovec));
1861 else
1862 desc_end = (struct sps_iovec *) (pipe->sys.desc_buf
1863 + end_offset - sizeof(struct sps_iovec));
1864
1865 if (!(desc_end->flags & SPS_IOVEC_FLAG_EOT)) {
1866 if (end_offset == 0)
1867 end_offset = pipe->desc_size
1868 - sizeof(struct sps_iovec);
1869 else
1870 end_offset -= sizeof(struct sps_iovec);
1871 }
1872 }
1873
1874 /* If no queue, then do not generate any events */
1875 if (pipe->sys.no_queue) {
1876 if (!pipe->sys.ack_xfers) {
1877 /* Client is not ACK'ing transfers, so do it now */
1878 pipe->sys.acked_offset = end_offset;
1879 }
1880 pipe->sys.handler_eot = false;
1881 SPS_DBG(dev,
1882 "sps:%s; pipe %d has no queue.\n",
1883 __func__, pipe->pipe_index);
1884 return;
1885 }
1886
1887 /*
1888 * Get offset of last descriptor processed by software,
1889 * and update to the last descriptor completed by the pipe
1890 */
1891 if (!pipe->sys.ack_xfers) {
1892 update_offset = &pipe->sys.acked_offset;
1893 offset = *update_offset;
1894 } else {
1895 update_offset = &pipe->sys.cache_offset;
1896 offset = *update_offset;
1897 }
1898
1899 /* Are there any completed descriptors to process? */
1900 if (offset == end_offset) {
1901 pipe->sys.handler_eot = false;
1902 SPS_DBG(dev,
1903 "sps:%s; there is no completed desc to process for pipe %d.\n",
1904 __func__, pipe->pipe_index);
1905 return;
1906 }
1907
1908 /* Determine enabled events */
1909 enabled = 0;
1910 if ((pipe->irq_mask & SPS_O_EOT))
1911 enabled |= SPS_IOVEC_FLAG_EOT;
1912
1913 if ((pipe->irq_mask & SPS_O_DESC_DONE))
1914 enabled |= SPS_IOVEC_FLAG_INT;
1915
1916 /*
1917 * For producer pipe, update the cached descriptor byte count and flags.
1918 * For consumer pipe, the BAM does not update the descriptors, so just
1919 * use the cached copies.
1920 */
1921 if (producer) {
1922 /*
1923 * Do copies in a tight loop to increase chance of
1924 * multi-descriptor burst accesses on the bus
1925 */
1926 struct sps_iovec *desc_end;
1927
1928 /* Set starting point for copy */
1929 desc = (struct sps_iovec *) (pipe->sys.desc_buf + offset);
1930 cache = (struct sps_iovec *) (pipe->sys.desc_cache + offset);
1931
1932 /* Fetch all completed descriptors to end of FIFO (wrap) */
1933 if (end_offset < offset) {
1934 desc_end = (struct sps_iovec *)
1935 (pipe->sys.desc_buf + pipe->desc_size);
1936 while (desc < desc_end)
1937 *cache++ = *desc++;
1938
1939 desc = (void *)pipe->sys.desc_buf;
1940 cache = (void *)pipe->sys.desc_cache;
1941 }
1942
1943 /* Fetch all remaining completed descriptors (no wrap) */
1944 desc_end = (struct sps_iovec *) (pipe->sys.desc_buf +
1945 end_offset);
1946 while (desc < desc_end)
1947 *cache++ = *desc++;
1948 }
1949
1950 /* Process all completed descriptors */
1951 cache = (struct sps_iovec *) (pipe->sys.desc_cache + offset);
1952 user = &pipe->sys.user_ptrs[offset / sizeof(struct sps_iovec)];
1953 for (;;) {
1954 SPS_DBG(dev,
Jishnu Prakash71524642019-03-13 18:12:26 +05301955 "sps:%s; pipe index:%d; iovec addr:0x%pK; size:0x%x; flags:0x%x; enabled:0x%x; *user is %s NULL.\n",
1956 __func__, pipe->pipe_index, (void *)(long)cache->addr,
Yan Heaabe3fc2016-11-14 17:04:53 -08001957 cache->size, cache->flags, enabled,
1958 (*user == NULL) ? "" : "not");
1959
1960 /*
1961 * Increment offset to next descriptor and update pipe offset
1962 * so a client callback can fetch the I/O vector.
1963 */
1964 offset += sizeof(struct sps_iovec);
1965 if (offset >= pipe->desc_size)
1966 /* Roll to start of descriptor FIFO */
1967 offset = 0;
1968
1969 *update_offset = offset;
1970#ifdef SPS_BAM_STATISTICS
1971 pipe->sys.desc_rd_count++;
1972#endif /* SPS_BAM_STATISTICS */
1973
1974 /* Did client request notification for this descriptor? */
1975 flags = cache->flags & enabled;
1976 if (*user != NULL || flags) {
1977 int index;
1978
1979 if ((flags & SPS_IOVEC_FLAG_EOT))
1980 event_id = SPS_EVENT_EOT;
1981 else
1982 event_id = SPS_EVENT_DESC_DONE;
1983
1984 index = SPS_EVENT_INDEX(event_id);
1985 event_reg = &pipe->sys.event_regs[index];
1986 event = alloc_event(pipe, event_reg);
1987 if (event != NULL) {
1988 /*
1989 * Store the descriptor and user pointer
1990 * in the notification
1991 */
1992 event->notify.data.transfer.iovec = *cache;
1993 event->notify.data.transfer.user = *user;
1994
1995 event->notify.event_id = event_id;
1996 event->notify.user = event_reg->user;
1997 trigger_event(dev, pipe, event_reg, event);
1998 } else {
1999 SPS_ERR(dev,
2000 "sps: %s: pipe %d: event is NULL.\n",
2001 __func__, pipe->pipe_index);
2002 }
2003#ifdef SPS_BAM_STATISTICS
2004 if (*user != NULL)
2005 pipe->sys.user_found++;
2006#endif /* SPS_BAM_STATISTICS */
2007 }
2008
2009 /* Increment to next descriptor */
2010 if (offset == end_offset)
2011 break; /* No more descriptors */
2012
2013 if (offset) {
2014 cache++;
2015 user++;
2016 } else {
2017 cache = (void *)pipe->sys.desc_cache;
2018 user = pipe->sys.user_ptrs;
2019 }
2020 }
2021
2022 pipe->sys.handler_eot = false;
2023}
2024
2025/**
2026 * Handle a BAM pipe's interrupt sources
2027 *
2028 * This function handles a BAM pipe's interrupt sources.
2029 * The caller of this function must lock the BAM device's mutex.
2030 *
2031 * @dev - pointer to BAM device descriptor
2032 *
2033 * @pipe_index - pipe index
2034 *
2035 * @return void
2036 *
2037 */
2038static void pipe_handler(struct sps_bam *dev, struct sps_pipe *pipe)
2039{
2040 u32 pipe_index;
2041 u32 status;
2042 enum sps_event event_id;
2043
2044 /* Get interrupt sources and ack all */
2045 pipe_index = pipe->pipe_index;
2046 status = bam_pipe_get_and_clear_irq_status(&dev->base, pipe_index);
2047
2048 SPS_DBG(dev, "sps:pipe_handler.bam %pa.pipe %d.status=0x%x.\n",
2049 BAM_ID(dev), pipe_index, status);
2050
2051 /* Check for enabled interrupt sources */
2052 status &= pipe->irq_mask;
2053 if (status == 0)
2054 /* No enabled interrupt sources are active */
2055 return;
2056
2057 /*
2058 * Process the interrupt sources in order of frequency of occurrance.
2059 * Check for early exit opportunities.
2060 */
2061
2062 if ((status & (SPS_O_EOT | SPS_O_DESC_DONE)) &&
2063 (pipe->state & BAM_STATE_BAM2BAM) == 0) {
2064 pipe_handler_eot(dev, pipe);
2065 if (pipe->sys.no_queue) {
2066 /*
2067 * EOT handler will not generate any event if there
2068 * is no queue,
2069 * so generate "empty" (no descriptor) event
2070 */
2071 if ((status & SPS_O_EOT))
2072 event_id = SPS_EVENT_EOT;
2073 else
2074 event_id = SPS_EVENT_DESC_DONE;
2075
2076 pipe_handler_generic(dev, pipe, event_id);
2077 }
2078 status &= ~(SPS_O_EOT | SPS_O_DESC_DONE);
2079 if (status == 0)
2080 return;
2081 }
2082
2083 if ((status & SPS_O_WAKEUP)) {
2084 pipe_handler_wakeup(dev, pipe);
2085 status &= ~SPS_O_WAKEUP;
2086 if (status == 0)
2087 return;
2088 }
2089
2090 if ((status & SPS_O_INACTIVE)) {
2091 pipe_handler_generic(dev, pipe, SPS_EVENT_INACTIVE);
2092 status &= ~SPS_O_INACTIVE;
2093 if (status == 0)
2094 return;
2095 }
2096
2097 if ((status & SPS_O_OUT_OF_DESC)) {
2098 pipe_handler_generic(dev, pipe,
2099 SPS_EVENT_OUT_OF_DESC);
2100 status &= ~SPS_O_OUT_OF_DESC;
2101 if (status == 0)
2102 return;
2103 }
2104
2105 if ((status & SPS_O_RST_ERROR) && enhd_pipe) {
2106 SPS_ERR(dev, "sps:bam %pa ;pipe 0x%x irq status=0x%x.\n"
2107 "sps: BAM_PIPE_IRQ_RST_ERROR\n",
2108 BAM_ID(dev), pipe_index, status);
2109 bam_output_register_content(&dev->base, dev->props.ee);
2110 pipe_handler_generic(dev, pipe,
2111 SPS_EVENT_RST_ERROR);
2112 status &= ~SPS_O_RST_ERROR;
2113 if (status == 0)
2114 return;
2115 }
2116
2117 if ((status & SPS_O_HRESP_ERROR) && enhd_pipe) {
2118 SPS_ERR(dev, "sps:bam %pa ;pipe 0x%x irq status=0x%x.\n"
2119 "sps: BAM_PIPE_IRQ_HRESP_ERROR\n",
2120 BAM_ID(dev), pipe_index, status);
2121 bam_output_register_content(&dev->base, dev->props.ee);
2122 pipe_handler_generic(dev, pipe,
2123 SPS_EVENT_HRESP_ERROR);
2124 status &= ~SPS_O_HRESP_ERROR;
2125 if (status == 0)
2126 return;
2127 }
2128
2129 if ((status & SPS_EVENT_ERROR))
2130 pipe_handler_generic(dev, pipe, SPS_EVENT_ERROR);
2131}
2132
2133/**
2134 * Get a BAM pipe event
2135 *
2136 */
2137int sps_bam_pipe_get_event(struct sps_bam *dev,
2138 u32 pipe_index, struct sps_event_notify *notify)
2139{
2140 struct sps_pipe *pipe = dev->pipes[pipe_index];
2141 struct sps_q_event *event_queue;
2142
2143 if (pipe->sys.no_queue) {
2144 SPS_ERR(dev,
Jishnu Prakash120aa392017-11-14 18:59:34 +05302145 "sps:Invalid connection for event: BAM %pa pipe %d context 0x%pK\n",
Yan Heaabe3fc2016-11-14 17:04:53 -08002146 BAM_ID(dev), pipe_index, pipe);
2147 notify->event_id = SPS_EVENT_INVALID;
2148 return SPS_ERROR;
2149 }
2150
2151 /* If pipe is polled, perform polling operation */
2152 if (pipe->polled && (pipe->state & BAM_STATE_BAM2BAM) == 0)
2153 pipe_handler_eot(dev, pipe);
2154
2155 /* Pull an event off the synchronous event queue */
2156 if (list_empty(&pipe->sys.events_q)) {
2157 event_queue = NULL;
2158 SPS_DBG(dev, "sps:events_q of bam %pa is empty.\n",
2159 BAM_ID(dev));
2160 } else {
2161 SPS_DBG(dev, "sps:events_q of bam %pa is not empty.\n",
2162 BAM_ID(dev));
2163 event_queue =
2164 list_first_entry(&pipe->sys.events_q, struct sps_q_event,
2165 list);
2166 list_del(&event_queue->list);
2167 }
2168
2169 /* Update client's event buffer */
2170 if (event_queue == NULL) {
2171 /* No event queued, so set client's event to "invalid" */
2172 notify->event_id = SPS_EVENT_INVALID;
2173 } else {
2174 /*
2175 * Copy event into client's buffer and return the event
2176 * to the pool
2177 */
2178 *notify = event_queue->notify;
2179 kfree(event_queue);
2180#ifdef SPS_BAM_STATISTICS
2181 pipe->sys.get_events++;
2182#endif /* SPS_BAM_STATISTICS */
2183 }
2184
2185 return 0;
2186}
2187
2188/**
2189 * Get processed I/O vector
2190 */
2191int sps_bam_pipe_get_iovec(struct sps_bam *dev, u32 pipe_index,
2192 struct sps_iovec *iovec)
2193{
2194 struct sps_pipe *pipe = dev->pipes[pipe_index];
2195 struct sps_iovec *desc;
2196 u32 read_offset;
2197
2198 /* Is this a valid pipe configured for get_iovec use? */
2199 if (!pipe->sys.ack_xfers ||
2200 (pipe->state & BAM_STATE_BAM2BAM) != 0 ||
2201 (pipe->state & BAM_STATE_REMOTE)) {
2202 return SPS_ERROR;
2203 }
2204
2205 /* If pipe is polled and queue is enabled, perform polling operation */
2206 if ((pipe->polled || pipe->hybrid) && !pipe->sys.no_queue) {
2207 SPS_DBG(dev,
2208 "sps:%s; BAM: %pa; pipe index:%d; polled is %d; hybrid is %d.\n",
2209 __func__, BAM_ID(dev), pipe_index,
2210 pipe->polled, pipe->hybrid);
2211 pipe_handler_eot(dev, pipe);
2212 }
2213
2214 /* Is there a completed descriptor? */
2215 if (pipe->sys.no_queue)
2216 read_offset =
2217 bam_pipe_get_desc_read_offset(&dev->base, pipe_index);
2218 else
2219 read_offset = pipe->sys.cache_offset;
2220
2221 if (read_offset == pipe->sys.acked_offset) {
2222 /* No, so clear the iovec to indicate FIFO is empty */
2223 memset(iovec, 0, sizeof(*iovec));
2224 SPS_DBG(dev,
2225 "sps:%s; BAM: %pa; pipe index:%d; no iovec to process.\n",
2226 __func__, BAM_ID(dev), pipe_index);
2227 return 0;
2228 }
2229
2230 /* Fetch next descriptor */
2231 desc = (struct sps_iovec *) (pipe->sys.desc_buf +
2232 pipe->sys.acked_offset);
2233 *iovec = *desc;
2234#ifdef SPS_BAM_STATISTICS
2235 pipe->sys.get_iovecs++;
2236#endif /* SPS_BAM_STATISTICS */
2237
2238 /* Update read/ACK offset */
2239 pipe->sys.acked_offset += sizeof(struct sps_iovec);
2240 if (pipe->sys.acked_offset >= pipe->desc_size)
2241 pipe->sys.acked_offset = 0;
2242
2243 SPS_DBG(dev,
Jishnu Prakash71524642019-03-13 18:12:26 +05302244 "sps:%s; pipe index:%d; iovec addr:0x%pK; size:0x%x; flags:0x%x; acked_offset:0x%x.\n",
2245 __func__, pipe->pipe_index, (void *)(long)desc->addr,
Yan Heaabe3fc2016-11-14 17:04:53 -08002246 desc->size, desc->flags, pipe->sys.acked_offset);
2247
2248 return 0;
2249}
2250
2251/**
2252 * Determine whether a BAM pipe descriptor FIFO is empty
2253 *
2254 */
2255int sps_bam_pipe_is_empty(struct sps_bam *dev, u32 pipe_index,
2256 u32 *empty)
2257{
2258 struct sps_pipe *pipe = dev->pipes[pipe_index];
2259 u32 end_offset;
2260 u32 acked_offset;
2261
2262 /* Is this a satellite connection? */
2263 if ((pipe->state & BAM_STATE_REMOTE)) {
2264 SPS_ERR(dev, "sps:Is empty on remote: BAM %pa pipe %d\n",
2265 BAM_ID(dev), pipe_index);
2266 return SPS_ERROR;
2267 }
2268
2269 /* Get offset of last descriptor completed by the pipe */
2270 end_offset = bam_pipe_get_desc_read_offset(&dev->base, pipe_index);
2271
2272 if ((pipe->state & BAM_STATE_BAM2BAM) == 0)
2273 /* System mode */
2274 acked_offset = pipe->sys.acked_offset;
2275 else
2276 /* BAM-to-BAM */
2277 acked_offset = bam_pipe_get_desc_write_offset(&dev->base,
2278 pipe_index);
2279
2280
2281 /* Determine descriptor FIFO state */
2282 if (end_offset == acked_offset) {
2283 *empty = true;
2284 } else {
2285 if ((pipe->state & BAM_STATE_BAM2BAM) == 0) {
2286 *empty = false;
2287 SPS_DBG1(dev,
2288 "sps:%s; pipe index:%d; this sys2bam pipe is NOT empty.\n",
2289 __func__, pipe->pipe_index);
2290 return 0;
2291 }
2292 if (bam_pipe_check_zlt(&dev->base, pipe_index)) {
2293 bool p_idc;
2294 u32 next_write;
2295
2296 p_idc = bam_pipe_check_pipe_empty(&dev->base,
2297 pipe_index);
2298
2299 next_write = acked_offset + sizeof(struct sps_iovec);
2300 if (next_write >= pipe->desc_size)
2301 next_write = 0;
2302
2303 if (next_write == end_offset) {
2304 *empty = true;
2305 if (!p_idc)
2306 SPS_DBG3(dev,
2307 "sps:BAM %pa pipe %d pipe empty checking for ZLT.\n",
2308 BAM_ID(dev), pipe_index);
2309 } else {
2310 *empty = false;
2311 }
2312 } else {
2313 *empty = false;
2314 }
2315 }
2316
2317 SPS_DBG1(dev,
2318 "sps:%s; pipe index:%d; this pipe is %s empty.\n",
2319 __func__, pipe->pipe_index, *empty ? "" : "NOT");
2320
2321 return 0;
2322}
2323
2324/**
2325 * Get number of free slots in a BAM pipe descriptor FIFO
2326 *
2327 */
2328int sps_bam_get_free_count(struct sps_bam *dev, u32 pipe_index,
2329 u32 *count)
2330{
2331 struct sps_pipe *pipe = dev->pipes[pipe_index];
2332 u32 next_write;
2333 u32 free;
2334
2335 /* Is this a BAM-to-BAM or satellite connection? */
2336 if ((pipe->state & (BAM_STATE_BAM2BAM | BAM_STATE_REMOTE))) {
2337 SPS_ERR(dev,
2338 "sps:Free count on BAM-to-BAM or remote: BAM %pa pipe %d\n",
2339 BAM_ID(dev), pipe_index);
2340 *count = 0;
2341 return SPS_ERROR;
2342 }
2343
2344 /* Determine descriptor FIFO state */
2345 next_write = pipe->sys.desc_offset + sizeof(struct sps_iovec);
2346 if (next_write >= pipe->desc_size)
2347 next_write = 0;
2348
2349 if (pipe->sys.acked_offset >= next_write)
2350 free = pipe->sys.acked_offset - next_write;
2351 else
2352 free = pipe->desc_size - next_write + pipe->sys.acked_offset;
2353
2354 free /= sizeof(struct sps_iovec);
2355 *count = free;
2356
2357 return 0;
2358}
2359
2360/**
2361 * Set BAM pipe to satellite ownership
2362 *
2363 */
2364int sps_bam_set_satellite(struct sps_bam *dev, u32 pipe_index)
2365{
2366 struct sps_pipe *pipe = dev->pipes[pipe_index];
2367
2368 /*
2369 * Switch to satellite control is only supported on processor
2370 * that controls the BAM global config on multi-EE BAMs
2371 */
2372 if ((dev->props.manage & SPS_BAM_MGR_MULTI_EE) == 0 ||
2373 (dev->props.manage & SPS_BAM_MGR_DEVICE_REMOTE)) {
2374 SPS_ERR(dev,
2375 "sps:Cannot grant satellite control to BAM %pa pipe %d\n",
2376 BAM_ID(dev), pipe_index);
2377 return SPS_ERROR;
2378 }
2379
2380 /* Is this pipe locally controlled? */
2381 if ((dev->pipe_active_mask & (1UL << pipe_index)) == 0) {
2382 SPS_ERR(dev, "sps:BAM %pa pipe %d not local and active\n",
2383 BAM_ID(dev), pipe_index);
2384 return SPS_ERROR;
2385 }
2386
2387 /* Disable local interrupts for this pipe */
2388 if (!pipe->polled)
2389 bam_pipe_set_irq(&dev->base, pipe_index, BAM_DISABLE,
2390 pipe->irq_mask, dev->props.ee);
2391
2392 if (BAM_VERSION_MTI_SUPPORT(dev->version)) {
2393 /*
2394 * Set pipe to MTI interrupt mode.
2395 * Must be performed after IRQ disable,
2396 * because it is necessary to re-enable the IRQ to enable
2397 * MTI generation.
2398 * Set both pipe IRQ mask and MTI dest address to zero.
2399 */
2400 if ((pipe->state & BAM_STATE_MTI) == 0 || pipe->polled) {
2401 bam_pipe_satellite_mti(&dev->base, pipe_index, 0,
2402 dev->props.ee);
2403 pipe->state |= BAM_STATE_MTI;
2404 }
2405 }
2406
2407 /* Indicate satellite control */
2408 list_del(&pipe->list);
2409 dev->pipe_active_mask &= ~(1UL << pipe_index);
2410 dev->pipe_remote_mask |= pipe->pipe_index_mask;
2411 pipe->state |= BAM_STATE_REMOTE;
2412
2413 return 0;
2414}
2415
2416/**
2417 * Perform BAM pipe timer control
2418 *
2419 */
2420int sps_bam_pipe_timer_ctrl(struct sps_bam *dev,
2421 u32 pipe_index,
2422 struct sps_timer_ctrl *timer_ctrl,
2423 struct sps_timer_result *timer_result)
2424{
2425 enum bam_pipe_timer_mode mode;
2426 int result = 0;
2427
2428 /* Is this pipe locally controlled? */
2429 if ((dev->pipe_active_mask & (1UL << pipe_index)) == 0) {
2430 SPS_ERR(dev, "sps:BAM %pa pipe %d not local and active\n",
2431 BAM_ID(dev), pipe_index);
2432 return SPS_ERROR;
2433 }
2434
2435 /* Perform the timer operation */
2436 switch (timer_ctrl->op) {
2437 case SPS_TIMER_OP_CONFIG:
2438 mode = (timer_ctrl->mode == SPS_TIMER_MODE_ONESHOT) ?
2439 BAM_PIPE_TIMER_ONESHOT :
2440 BAM_PIPE_TIMER_PERIODIC;
2441 bam_pipe_timer_config(&dev->base, pipe_index, mode,
2442 timer_ctrl->timeout_msec * 8);
2443 break;
2444 case SPS_TIMER_OP_RESET:
2445 bam_pipe_timer_reset(&dev->base, pipe_index);
2446 break;
2447 case SPS_TIMER_OP_READ:
2448 break;
2449 default:
2450 result = SPS_ERROR;
2451 break;
2452 }
2453
2454 /* Provide the current timer value */
2455 if (timer_result != NULL)
2456 timer_result->current_timer =
2457 bam_pipe_timer_get_count(&dev->base, pipe_index);
2458
2459 return result;
2460}
2461
2462/**
2463 * Get the number of unused descriptors in the descriptor FIFO
2464 * of a pipe
2465 */
2466int sps_bam_pipe_get_unused_desc_num(struct sps_bam *dev, u32 pipe_index,
2467 u32 *desc_num)
2468{
2469 u32 sw_offset, peer_offset, fifo_size;
2470 u32 desc_size = sizeof(struct sps_iovec);
2471 struct sps_pipe *pipe = dev->pipes[pipe_index];
2472
2473 if (pipe == NULL)
2474 return SPS_ERROR;
2475
2476 fifo_size = pipe->desc_size;
2477
2478 sw_offset = bam_pipe_get_desc_read_offset(&dev->base, pipe_index);
2479 if ((dev->props.options & SPS_BAM_CACHED_WP) &&
2480 !(pipe->state & BAM_STATE_BAM2BAM)) {
2481 peer_offset = pipe->sys.desc_offset;
2482 SPS_DBG(dev,
2483 "sps:BAM %pa pipe %d: peer offset in cache:0x%x\n",
2484 BAM_ID(dev), pipe_index, peer_offset);
2485 } else {
2486 peer_offset = bam_pipe_get_desc_write_offset(&dev->base,
2487 pipe_index);
2488 }
2489
2490 if (sw_offset <= peer_offset)
2491 *desc_num = (peer_offset - sw_offset) / desc_size;
2492 else
2493 *desc_num = (peer_offset + fifo_size - sw_offset) / desc_size;
2494
2495 return 0;
2496}
2497
2498/*
2499 * Check if a pipe of a BAM has any pending descriptor
2500 */
2501bool sps_bam_pipe_pending_desc(struct sps_bam *dev, u32 pipe_index)
2502{
2503 u32 sw_offset, peer_offset;
2504
2505 sw_offset = bam_pipe_get_desc_read_offset(&dev->base, pipe_index);
2506 peer_offset = bam_pipe_get_desc_write_offset(&dev->base, pipe_index);
2507
2508 if (sw_offset == peer_offset)
2509 return false;
2510 else
2511 return true;
2512}