blob: 5deaecfdf7852fb0a5a18fc056f59e694584c1fd [file] [log] [blame]
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07001/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
2 *
Deepa Dinamani9d470af2012-06-29 18:27:17 -07003 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
Deepa Dinamani0bf2f442012-10-19 11:41:06 -07006 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
Deepa Dinamani9d470af2012-06-29 18:27:17 -070015 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <bam.h>
30#include <reg.h>
31#include <debug.h>
32#include <stdlib.h>
Deepa Dinamani62df2c72012-12-19 17:17:58 -080033#include <arch/ops.h>
Deepa Dinamani0bf2f442012-10-19 11:41:06 -070034#include <platform.h>
Deepa Dinamani9d470af2012-06-29 18:27:17 -070035#include <platform/interrupts.h>
36#include <platform/iomap.h>
37#include <platform/irqs.h>
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -070038#include <pow2.h>
Deepa Dinamani9d470af2012-06-29 18:27:17 -070039
40#define HLOS_EE_INDEX 0
41
42/* Reset BAM registers and pipes */
43static void bam_reset(struct bam_instance *bam)
44{
45 /* Initiate SW reset */
46 writel(BAM_SW_RST_BIT_MASK, BAM_CTRL_REG(bam->base));
47
48 /* No delay required */
49
50 /* Disable SW reset */
51 writel(~BAM_SW_RST_BIT_MASK, BAM_CTRL_REG(bam->base));
52}
53
54/* Resets pipe registers and state machines */
Deepa Dinamani87feab82012-10-04 14:28:05 -070055void bam_pipe_reset(struct bam_instance *bam,
56 uint8_t pipe_num)
Deepa Dinamani9d470af2012-06-29 18:27:17 -070057{
58 /* Start sw reset of the pipe to be allocated */
59 writel(1, BAM_P_RSTn(bam->pipe[pipe_num].pipe_num, bam->base));
60
61 /* No delay required */
62
63 /* Stop sw reset of the pipe to be allocated */
64 writel(0, BAM_P_RSTn(bam->pipe[pipe_num].pipe_num, bam->base));
65}
66
67static enum handler_return bam_interrupt_handler(void* arg)
68{
69 return 0;
70}
71
72/* A blocking function that waits till an interrupt is signalled.
73 * bam : BAM instance for the descriptors to be queued.
74 * pipe_num : pipe number for the descriptors to be queued.
75 * interrupt: interrupt to wait for.
76 */
77int bam_wait_for_interrupt(struct bam_instance *bam,
78 uint8_t pipe_num,
79 enum p_int_type interrupt)
80{
81 uint32_t val;
Sundarajan Srinivasan802a9ec2013-07-11 16:02:57 -070082 uint32_t bamsts;
Deepa Dinamani9d470af2012-06-29 18:27:17 -070083
84 while (1)
85 {
86 /* Wait for a interrupt on the right pipe */
87 do{
88 /* Determine the pipe causing the interrupt */
Deepa Dinamanie9ded132012-11-27 15:03:38 -080089 val = readl(BAM_IRQ_SRCS(bam->base, bam->ee));
Deepa Dinamani9d470af2012-06-29 18:27:17 -070090 /* Flush out the right most global interrupt bit */
91 } while (!((val & 0x7FFF) & (1 << bam->pipe[pipe_num].pipe_num)));
92
93 /* Check the reason for this BAM interrupt */
Sundarajan Srinivasan802a9ec2013-07-11 16:02:57 -070094 bamsts = readl(BAM_IRQ_STTS(bam->base));
95 if (bamsts)
96 {
97 dprintf(CRITICAL,"ERROR:BAM_IRQ_STTS %u \n", bamsts);
Deepa Dinamani9d470af2012-06-29 18:27:17 -070098 goto bam_wait_int_error;
Sundarajan Srinivasan802a9ec2013-07-11 16:02:57 -070099 }
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700100
101 /* Check the interrupt type */
102 /* Read interrupt status register */
103 val = readl(BAM_P_IRQ_STTSn(bam->pipe[pipe_num].pipe_num, bam->base));
104
105 /* Check for error */
106 if (val & P_ERR_EN_MASK)
107 goto bam_wait_int_error;
108
109 if (val & interrupt)
110 {
111 /* Correct interrupt was fired. */
112 /* Clear the other interrupts */
113 val = P_OUT_OF_DESC_EN_MASK | P_PRCSD_DESC_EN_MASK | P_TRNSFR_END_EN_MASK;
114 writel (val, BAM_P_IRQ_CLRn(bam->pipe[pipe_num].pipe_num, bam->base));
115 return BAM_RESULT_SUCCESS;
116 }
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700117 }
118
119bam_wait_int_error:
120
Sundarajan Srinivasan802a9ec2013-07-11 16:02:57 -0700121 dprintf(CRITICAL, "Unexpected interrupt : val %u\n", val);
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700122 return BAM_RESULT_FAILURE;
123}
124
125/* Enable BAM and pipe level interrupts */
126void bam_enable_interrupts(struct bam_instance *bam, uint8_t pipe_num)
127{
128
129 uint32_t int_mask = P_ERR_EN_MASK | P_OUT_OF_DESC_EN_MASK |
Sundarajan Srinivasan802a9ec2013-07-11 16:02:57 -0700130 P_PRCSD_DESC_EN_MASK;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700131 uint32_t val;
132
Deepa Dinamani5f68e842013-05-14 16:46:08 -0700133 /* Leave BAM error interrupts disabled. */
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700134 /* Enable the interrupts for the pipe by enabling the relevant bits
135 * in the BAM_PIPE_INTERRUPT_ENABLE register.
136 */
137 writel(int_mask,
138 BAM_P_IRQ_ENn(bam->pipe[pipe_num].pipe_num, bam->base));
139
140 /* Enable pipe interrups */
141 /* Do read-modify-write */
Deepa Dinamanie9ded132012-11-27 15:03:38 -0800142 val = readl(BAM_IRQ_SRCS_MSK(bam->base, bam->ee));
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700143 writel((1 << bam->pipe[pipe_num].pipe_num) | val,
Deepa Dinamanie9ded132012-11-27 15:03:38 -0800144 BAM_IRQ_SRCS_MSK(bam->base, bam->ee));
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700145
146 /* Unmask the QGIC interrupts only in the case of
147 * interrupt based transfer.
148 * Use polling othwerwise.
149 */
150 if (bam->pipe[pipe_num].int_mode)
151 {
152 /* Register interrupt handler */
153 register_int_handler(bam->pipe[pipe_num].spi_num, bam_interrupt_handler, 0);
154
155 /* Unmask the interrupt */
156 unmask_interrupt(bam->pipe[pipe_num].spi_num);
157 }
158}
159
160/* Reset and initialize the bam module */
161void bam_init(struct bam_instance *bam)
162{
163 uint32_t val = 0;
164
Deepa Dinamani87feab82012-10-04 14:28:05 -0700165// bam_reset(bam);
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700166
167 /* Check for only one pipe's direction.
168 * The other is assumed to be the opposite system
169 * transaction.
170 */
171 if (bam->pipe[0].trans_type == SYS2BAM ||
172 bam->pipe[0].trans_type == BAM2SYS)
173 {
174 /* Program the threshold count */
175 writel(bam->threshold, BAM_DESC_CNT_TRSHLD_REG(bam->base));
176 }
177
178 /* Program config register for H/W bug fixes */
179 val = 0xffffffff & ~(1 << 11);
180 writel(val, BAM_CNFG_BITS(bam->base));
181
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700182 /* Enable the BAM */
183 writel(BAM_ENABLE_BIT_MASK, BAM_CTRL_REG(bam->base));
184}
185
186/* Funtion to setup a simple fifo structure.
187 * Note: Addr should be 8 byte aligned.
188 * bam : BAM instance for the descriptors to be queued.
189 * pipe_num : pipe number for the descriptors to be queued.
190 */
191int bam_pipe_fifo_init(struct bam_instance *bam,
192 uint8_t pipe_num)
193{
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700194 if (bam->pipe[pipe_num].fifo.size > 0x7FFF)
195 {
196 dprintf(CRITICAL,
197 "Size exceeds max size for a descriptor(0x7FFF)\n");
198 return BAM_RESULT_FAILURE;
199 }
200
201 /* Check if fifo start is 8-byte alligned */
Deepa Dinamani0bf2f442012-10-19 11:41:06 -0700202 ASSERT(!((uint32_t)PA((addr_t)bam->pipe[pipe_num].fifo.head & 0x7)));
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700203
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700204 /* Check if fifo size is a power of 2.
205 * The circular fifo logic in lk expects this.
206 */
207 ASSERT(ispow2(bam->pipe[pipe_num].fifo.size));
208
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700209 bam->pipe[pipe_num].fifo.current = bam->pipe[pipe_num].fifo.head;
210
211 /* Set the descriptor buffer size. Must be a multiple of 8 */
212 writel(bam->pipe[pipe_num].fifo.size * BAM_DESC_SIZE,
213 BAM_P_FIFO_SIZESn(bam->pipe[pipe_num].pipe_num, bam->base));
214
215 /* Write descriptors FIFO base addr must be 8-byte aligned */
Deepa Dinamani0bf2f442012-10-19 11:41:06 -0700216 /* Needs a physical address conversion as we are setting up
217 * the base of the FIFO for the BAM state machine.
218 */
219 writel((uint32_t)PA((addr_t)bam->pipe[pipe_num].fifo.head),
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700220 BAM_P_DESC_FIFO_ADDRn(bam->pipe[pipe_num].pipe_num, bam->base));
221
222 /* Initialize FIFO offset for the first read */
223 bam->pipe[pipe_num].fifo.offset = BAM_DESC_SIZE;
224
Deepa Dinamania0407ea2013-07-09 12:51:45 -0700225 writel(P_ENABLE | readl(BAM_P_CTRLn(bam->pipe[pipe_num].pipe_num, bam->base)),
226 BAM_P_CTRLn(bam->pipe[pipe_num].pipe_num, bam->base));
227
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700228 /* Everything is set.
229 * Flag pipe init done.
230 */
231 bam->pipe[pipe_num].initialized = 1;
232
233 return BAM_RESULT_SUCCESS;
234}
235
236void bam_sys_pipe_init(struct bam_instance *bam,
237 uint8_t pipe_num)
238{
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700239 /* Reset the pipe to be allocated */
240 bam_pipe_reset(bam, pipe_num);
241
242 /* Enable minimal interrupts */
243 bam_enable_interrupts(bam, pipe_num);
244
245 /* Pipe event threshold register is not relevant in sys modes */
246
247 /* Enable pipe in system mode and set the direction */
Deepa Dinamania0407ea2013-07-09 12:51:45 -0700248 writel(P_SYS_MODE_MASK | bam->pipe[pipe_num].lock_grp << P_LOCK_GRP_SHIFT |
249 (bam->pipe[pipe_num].trans_type << P_DIRECTION_SHIFT),
250 BAM_P_CTRLn(bam->pipe[pipe_num].pipe_num, bam->base));
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700251
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700252 /* Mark the pipe FIFO as uninitialized. */
253 bam->pipe[pipe_num].initialized = 0;
254}
255
256/* Function to notify written descriptors to BAM.
257 * bam : BAM instance for the descriptors to be queued.
258 * pipe_num : pipe number for the descriptors to be queued.
259 * num_desc : number of the descriptors.
260 * fifo : Circular FIFO used for the descriptors.
261 */
262void bam_sys_gen_event(struct bam_instance *bam,
263 uint8_t pipe_num,
264 unsigned int num_desc)
265{
266 uint32_t val = 0;
267
268 if (num_desc >= bam->pipe[pipe_num].fifo.size) {
269 dprintf(CRITICAL,
270 "Max allowed desc is one less than the fifo length\n");
271 return;
272 }
273
274 /* Update the fifo peer offset */
275 val = (num_desc - 1) * BAM_DESC_SIZE;
276 val += bam->pipe[pipe_num].fifo.offset;
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700277 val &= (bam->pipe[pipe_num].fifo.size * BAM_DESC_SIZE - 1);
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700278
279 writel(val, BAM_P_EVNT_REGn(bam->pipe[pipe_num].pipe_num, bam->base));
280}
281
282/* Function to read the updates for FIFO offsets.
283 * bam : BAM that uses the FIFO.
284 * pipe : BAM pipe that uses the FIFO.
285 * return : FIFO offset where the next descriptor should be written.
286 * Note : S/W maintains the circular properties of the FIFO and updates
287 * the offsets accordingly.
288 */
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700289void bam_read_offset_update(struct bam_instance *bam, unsigned int pipe_num)
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700290{
291 uint32_t offset;
292
293 offset = readl(BAM_P_SW_OFSTSn(bam->pipe[pipe_num].pipe_num, bam->base));
294 offset &= 0xFFFF;
295
Deepa Dinamani9c59ac62012-12-03 10:51:59 -0800296 dprintf(SPEW, "Offset value is %d \n", offset);
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700297
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700298 /* Save the next offset to be written to. */
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700299 bam->pipe[pipe_num].fifo.current = (struct bam_desc*)
300 ((uint32_t)bam->pipe[pipe_num].fifo.head + offset);
301
302 bam->pipe[pipe_num].fifo.offset = offset + BAM_DESC_SIZE ;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700303}
304
305/* Function to get the next desc address.
306 * Keeps track of circular properties of the FIFO
307 * and returns the appropriate address.
308 */
309static struct bam_desc* fifo_getnext(struct bam_desc_fifo *fifo,
310 struct bam_desc* desc)
311{
312 uint16_t offset;
313
314 offset = desc - fifo->head;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700315
316 if (offset == (fifo->size - 1))
317 return fifo->head;
318 else
319 return desc + 1;
320}
321
322/* Function to add BAM descriptors for a given fifo.
323 * bam : BAM instance to be used.
324 * data_ptr : Memory address for data transfer.
325 * data_len : Length of the data_ptr.
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700326 * flags : Flags to be set on the last desc added.
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700327 *
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700328 * Note: This function also notifies the BAM about the added descriptors.
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700329 */
330int bam_add_desc(struct bam_instance *bam,
331 unsigned int pipe_num,
332 unsigned char *data_ptr,
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700333 unsigned int data_len,
334 unsigned flags)
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700335{
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700336 int bam_ret = BAM_RESULT_SUCCESS;
337 unsigned int len = data_len;
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700338 unsigned int desc_len;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700339 unsigned int n = 0;
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700340 unsigned int desc_flags;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700341
Deepa Dinamani9c59ac62012-12-03 10:51:59 -0800342 dprintf(SPEW, "Data length for BAM transfer is %u\n", data_len);
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700343
344 if (data_ptr == NULL || len == 0)
345 {
346 dprintf(CRITICAL, "Wrong params for BAM transfer \n");
347 bam_ret = BAM_RESULT_FAILURE;
348 goto bam_add_desc_error;
349 }
350
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700351 /* Check if we have enough space in FIFO */
Deepa Dinamanie9ded132012-11-27 15:03:38 -0800352 if (len > (unsigned)bam->pipe[pipe_num].fifo.size * bam->max_desc_len)
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700353 {
354 dprintf(CRITICAL, "Data transfer exceeds desc fifo length.\n");
355 bam_ret = BAM_RESULT_FAILURE;
356 goto bam_add_desc_error;
357 }
358
359 while (len)
360 {
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700361
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700362 /* There are only 16 bits to write data length.
363 * If more bits are needed, create more
364 * descriptors.
365 */
Deepa Dinamanie9ded132012-11-27 15:03:38 -0800366 if (len > bam->max_desc_len)
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700367 {
Deepa Dinamanie9ded132012-11-27 15:03:38 -0800368 desc_len = bam->max_desc_len;
369 len -= bam->max_desc_len;
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700370 desc_flags = 0;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700371 }
372 else
373 {
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700374 desc_len = len;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700375 len = 0;
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700376 /* Set correct flags on the last desc. */
377 desc_flags = flags;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700378 }
379
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700380 /* Write descriptor */
381 bam_add_one_desc(bam, pipe_num, data_ptr, desc_len, desc_flags);
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700382
Deepa Dinamanie9ded132012-11-27 15:03:38 -0800383 data_ptr += bam->max_desc_len;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700384 n++;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700385 }
386
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700387
388 /* Create a read/write event to notify the periperal of the added desc. */
389 bam_sys_gen_event(bam, pipe_num, n);
390
391bam_add_desc_error:
392
393 return bam_ret;
394}
395
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700396/* Function to add a BAM descriptor for a given fifo.
397 * bam : BAM instance to be used.
398 * data_ptr : Memory address for data transfer.
399 * data_len : Length of the data_ptr.
400 * flags : Flags to be set on the desc added.
401 *
402 * Note: This function does not notify the BAM about the added descriptor.
403 */
404int bam_add_one_desc(struct bam_instance *bam,
405 unsigned int pipe_num,
406 unsigned char* data_ptr,
407 uint32_t len,
408 uint8_t flags)
409{
410
411 struct bam_desc *desc = bam->pipe[pipe_num].fifo.current;
412 int bam_ret = BAM_RESULT_SUCCESS;
413
414 if (data_ptr == NULL || len == 0)
415 {
416 dprintf(CRITICAL, "Wrong params for BAM transfer \n");
417 bam_ret = BAM_RESULT_FAILURE;
418 goto bam_add_one_desc_error;
419 }
420
421 /* Check if the FIFO is allocated for the pipe */
422 if (!bam->pipe[pipe_num].initialized)
423 {
424 dprintf(CRITICAL, "Please allocate the FIFO for the BAM pipe %d\n",
425 bam->pipe[pipe_num].pipe_num);
426 bam_ret = BAM_RESULT_FAILURE;
427 goto bam_add_one_desc_error;
428 }
429
430 if ((flags & BAM_DESC_LOCK_FLAG) && (flags & BAM_DESC_UNLOCK_FLAG))
431 {
432 dprintf(CRITICAL, "Can't lock and unlock in the same desc\n");
433 bam_ret = BAM_RESULT_FAILURE;
434 goto bam_add_one_desc_error;
435 }
436
437 /* Setting EOT flag on a CMD desc is not valid */
438 if ((flags & BAM_DESC_EOT_FLAG) && (flags & BAM_DESC_CMD_FLAG))
439 {
440 dprintf(CRITICAL, "EOT flag set on the CMD desc\n");
441 bam_ret = BAM_RESULT_FAILURE;
442 goto bam_add_one_desc_error;
443 }
444
445 /* Check for the length of the desc. */
Deepa Dinamanie9ded132012-11-27 15:03:38 -0800446 if (len > bam->max_desc_len)
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700447 {
448 dprintf(CRITICAL, "len of the desc exceeds max length"
Deepa Dinamanie9ded132012-11-27 15:03:38 -0800449 " %d > %d\n", len, bam->max_desc_len);
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700450 bam_ret = BAM_RESULT_FAILURE;
451 goto bam_add_one_desc_error;
452 }
453
Deepa Dinamani62df2c72012-12-19 17:17:58 -0800454 desc->flags = flags;
455 desc->addr = (uint32_t)data_ptr;
456 desc->size = (uint16_t)len;
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700457 desc->reserved = 0;
458
Deepa Dinamani62df2c72012-12-19 17:17:58 -0800459 arch_clean_invalidate_cache_range((addr_t) desc, BAM_DESC_SIZE);
460
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700461 /* Update the FIFO to point to the head */
462 bam->pipe[pipe_num].fifo.current = fifo_getnext(&bam->pipe[pipe_num].fifo, desc);
463
464bam_add_one_desc_error:
465 return bam_ret;
466}
467
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700468struct cmd_element* bam_add_cmd_element(struct cmd_element *ptr,
469 uint32_t reg_addr,
470 uint32_t value,
471 enum bam_ce_cmd_t cmd_type)
472{
473 /* Write cmd type.
474 * Also, write the register address.
475 */
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700476 ptr->addr_n_cmd = (reg_addr & ~(0xFF000000)) | (cmd_type << 24);
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700477
478 /* Do not mask any of the addr bits by default */
479 ptr->reg_mask = 0xFFFFFFFF;
480
481 /* Write the value to be written */
482 ptr->reg_data = value;
483
484 /* Return the address to add the next element to */
485 return ptr + 1;
486}