blob: bd7a595f5e1649402da79fa40de83abdc60e58bc [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;
82
83 while (1)
84 {
85 /* Wait for a interrupt on the right pipe */
86 do{
87 /* Determine the pipe causing the interrupt */
Deepa Dinamanie9ded132012-11-27 15:03:38 -080088 val = readl(BAM_IRQ_SRCS(bam->base, bam->ee));
Deepa Dinamani9d470af2012-06-29 18:27:17 -070089 /* Flush out the right most global interrupt bit */
90 } while (!((val & 0x7FFF) & (1 << bam->pipe[pipe_num].pipe_num)));
91
92 /* Check the reason for this BAM interrupt */
93 if (readl(BAM_IRQ_STTS(bam->base)))
94 goto bam_wait_int_error;
95
96 /* Check the interrupt type */
97 /* Read interrupt status register */
98 val = readl(BAM_P_IRQ_STTSn(bam->pipe[pipe_num].pipe_num, bam->base));
99
100 /* Check for error */
101 if (val & P_ERR_EN_MASK)
102 goto bam_wait_int_error;
103
104 if (val & interrupt)
105 {
106 /* Correct interrupt was fired. */
107 /* Clear the other interrupts */
108 val = P_OUT_OF_DESC_EN_MASK | P_PRCSD_DESC_EN_MASK | P_TRNSFR_END_EN_MASK;
109 writel (val, BAM_P_IRQ_CLRn(bam->pipe[pipe_num].pipe_num, bam->base));
110 return BAM_RESULT_SUCCESS;
111 }
112 else if (val & P_TRNSFR_END_EN_MASK)
113 {
114 dprintf(CRITICAL,
115 "Trasfer end signalled before the last descc was processed\n");
116 goto bam_wait_int_error;
117 }
118 }
119
120bam_wait_int_error:
121
122 dprintf(CRITICAL, "Unexpected interrupt\n");
123 return BAM_RESULT_FAILURE;
124}
125
126/* Enable BAM and pipe level interrupts */
127void bam_enable_interrupts(struct bam_instance *bam, uint8_t pipe_num)
128{
129
130 uint32_t int_mask = P_ERR_EN_MASK | P_OUT_OF_DESC_EN_MASK |
131 P_PRCSD_DESC_EN_MASK | P_TRNSFR_END_EN_MASK;
132 uint32_t val;
133
Deepa Dinamani5f68e842013-05-14 16:46:08 -0700134 /* Leave BAM error interrupts disabled. */
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700135 /* Enable the interrupts for the pipe by enabling the relevant bits
136 * in the BAM_PIPE_INTERRUPT_ENABLE register.
137 */
138 writel(int_mask,
139 BAM_P_IRQ_ENn(bam->pipe[pipe_num].pipe_num, bam->base));
140
141 /* Enable pipe interrups */
142 /* Do read-modify-write */
Deepa Dinamanie9ded132012-11-27 15:03:38 -0800143 val = readl(BAM_IRQ_SRCS_MSK(bam->base, bam->ee));
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700144 writel((1 << bam->pipe[pipe_num].pipe_num) | val,
Deepa Dinamanie9ded132012-11-27 15:03:38 -0800145 BAM_IRQ_SRCS_MSK(bam->base, bam->ee));
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700146
147 /* Unmask the QGIC interrupts only in the case of
148 * interrupt based transfer.
149 * Use polling othwerwise.
150 */
151 if (bam->pipe[pipe_num].int_mode)
152 {
153 /* Register interrupt handler */
154 register_int_handler(bam->pipe[pipe_num].spi_num, bam_interrupt_handler, 0);
155
156 /* Unmask the interrupt */
157 unmask_interrupt(bam->pipe[pipe_num].spi_num);
158 }
159}
160
161/* Reset and initialize the bam module */
162void bam_init(struct bam_instance *bam)
163{
164 uint32_t val = 0;
165
Deepa Dinamani87feab82012-10-04 14:28:05 -0700166// bam_reset(bam);
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700167
168 /* Check for only one pipe's direction.
169 * The other is assumed to be the opposite system
170 * transaction.
171 */
172 if (bam->pipe[0].trans_type == SYS2BAM ||
173 bam->pipe[0].trans_type == BAM2SYS)
174 {
175 /* Program the threshold count */
176 writel(bam->threshold, BAM_DESC_CNT_TRSHLD_REG(bam->base));
177 }
178
179 /* Program config register for H/W bug fixes */
180 val = 0xffffffff & ~(1 << 11);
181 writel(val, BAM_CNFG_BITS(bam->base));
182
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700183 /* Enable the BAM */
184 writel(BAM_ENABLE_BIT_MASK, BAM_CTRL_REG(bam->base));
185}
186
187/* Funtion to setup a simple fifo structure.
188 * Note: Addr should be 8 byte aligned.
189 * bam : BAM instance for the descriptors to be queued.
190 * pipe_num : pipe number for the descriptors to be queued.
191 */
192int bam_pipe_fifo_init(struct bam_instance *bam,
193 uint8_t pipe_num)
194{
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700195 if (bam->pipe[pipe_num].fifo.size > 0x7FFF)
196 {
197 dprintf(CRITICAL,
198 "Size exceeds max size for a descriptor(0x7FFF)\n");
199 return BAM_RESULT_FAILURE;
200 }
201
202 /* Check if fifo start is 8-byte alligned */
Deepa Dinamani0bf2f442012-10-19 11:41:06 -0700203 ASSERT(!((uint32_t)PA((addr_t)bam->pipe[pipe_num].fifo.head & 0x7)));
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700204
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700205 /* Check if fifo size is a power of 2.
206 * The circular fifo logic in lk expects this.
207 */
208 ASSERT(ispow2(bam->pipe[pipe_num].fifo.size));
209
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700210 bam->pipe[pipe_num].fifo.current = bam->pipe[pipe_num].fifo.head;
211
212 /* Set the descriptor buffer size. Must be a multiple of 8 */
213 writel(bam->pipe[pipe_num].fifo.size * BAM_DESC_SIZE,
214 BAM_P_FIFO_SIZESn(bam->pipe[pipe_num].pipe_num, bam->base));
215
216 /* Write descriptors FIFO base addr must be 8-byte aligned */
Deepa Dinamani0bf2f442012-10-19 11:41:06 -0700217 /* Needs a physical address conversion as we are setting up
218 * the base of the FIFO for the BAM state machine.
219 */
220 writel((uint32_t)PA((addr_t)bam->pipe[pipe_num].fifo.head),
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700221 BAM_P_DESC_FIFO_ADDRn(bam->pipe[pipe_num].pipe_num, bam->base));
222
223 /* Initialize FIFO offset for the first read */
224 bam->pipe[pipe_num].fifo.offset = BAM_DESC_SIZE;
225
226 /* Everything is set.
227 * Flag pipe init done.
228 */
229 bam->pipe[pipe_num].initialized = 1;
230
231 return BAM_RESULT_SUCCESS;
232}
233
234void bam_sys_pipe_init(struct bam_instance *bam,
235 uint8_t pipe_num)
236{
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700237 /* Reset the pipe to be allocated */
238 bam_pipe_reset(bam, pipe_num);
239
240 /* Enable minimal interrupts */
241 bam_enable_interrupts(bam, pipe_num);
242
243 /* Pipe event threshold register is not relevant in sys modes */
244
245 /* Enable pipe in system mode and set the direction */
246 writel(P_SYS_MODE_MASK | P_ENABLE |
247 (bam->pipe[pipe_num].trans_type << P_DIRECTION_SHIFT),
248 BAM_P_CTRLn(bam->pipe[pipe_num].pipe_num, bam->base));
249
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700250 /* Mark the pipe FIFO as uninitialized. */
251 bam->pipe[pipe_num].initialized = 0;
252}
253
254/* Function to notify written descriptors to BAM.
255 * bam : BAM instance for the descriptors to be queued.
256 * pipe_num : pipe number for the descriptors to be queued.
257 * num_desc : number of the descriptors.
258 * fifo : Circular FIFO used for the descriptors.
259 */
260void bam_sys_gen_event(struct bam_instance *bam,
261 uint8_t pipe_num,
262 unsigned int num_desc)
263{
264 uint32_t val = 0;
265
266 if (num_desc >= bam->pipe[pipe_num].fifo.size) {
267 dprintf(CRITICAL,
268 "Max allowed desc is one less than the fifo length\n");
269 return;
270 }
271
272 /* Update the fifo peer offset */
273 val = (num_desc - 1) * BAM_DESC_SIZE;
274 val += bam->pipe[pipe_num].fifo.offset;
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700275 val &= (bam->pipe[pipe_num].fifo.size * BAM_DESC_SIZE - 1);
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700276
277 writel(val, BAM_P_EVNT_REGn(bam->pipe[pipe_num].pipe_num, bam->base));
278}
279
280/* Function to read the updates for FIFO offsets.
281 * bam : BAM that uses the FIFO.
282 * pipe : BAM pipe that uses the FIFO.
283 * return : FIFO offset where the next descriptor should be written.
284 * Note : S/W maintains the circular properties of the FIFO and updates
285 * the offsets accordingly.
286 */
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700287void bam_read_offset_update(struct bam_instance *bam, unsigned int pipe_num)
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700288{
289 uint32_t offset;
290
291 offset = readl(BAM_P_SW_OFSTSn(bam->pipe[pipe_num].pipe_num, bam->base));
292 offset &= 0xFFFF;
293
Deepa Dinamani9c59ac62012-12-03 10:51:59 -0800294 dprintf(SPEW, "Offset value is %d \n", offset);
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700295
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700296 /* Save the next offset to be written to. */
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700297 bam->pipe[pipe_num].fifo.current = (struct bam_desc*)
298 ((uint32_t)bam->pipe[pipe_num].fifo.head + offset);
299
300 bam->pipe[pipe_num].fifo.offset = offset + BAM_DESC_SIZE ;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700301}
302
303/* Function to get the next desc address.
304 * Keeps track of circular properties of the FIFO
305 * and returns the appropriate address.
306 */
307static struct bam_desc* fifo_getnext(struct bam_desc_fifo *fifo,
308 struct bam_desc* desc)
309{
310 uint16_t offset;
311
312 offset = desc - fifo->head;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700313
314 if (offset == (fifo->size - 1))
315 return fifo->head;
316 else
317 return desc + 1;
318}
319
320/* Function to add BAM descriptors for a given fifo.
321 * bam : BAM instance to be used.
322 * data_ptr : Memory address for data transfer.
323 * data_len : Length of the data_ptr.
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700324 * flags : Flags to be set on the last desc added.
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700325 *
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700326 * Note: This function also notifies the BAM about the added descriptors.
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700327 */
328int bam_add_desc(struct bam_instance *bam,
329 unsigned int pipe_num,
330 unsigned char *data_ptr,
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700331 unsigned int data_len,
332 unsigned flags)
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700333{
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700334 int bam_ret = BAM_RESULT_SUCCESS;
335 unsigned int len = data_len;
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700336 unsigned int desc_len;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700337 unsigned int n = 0;
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700338 unsigned int desc_flags;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700339
Deepa Dinamani9c59ac62012-12-03 10:51:59 -0800340 dprintf(SPEW, "Data length for BAM transfer is %u\n", data_len);
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700341
342 if (data_ptr == NULL || len == 0)
343 {
344 dprintf(CRITICAL, "Wrong params for BAM transfer \n");
345 bam_ret = BAM_RESULT_FAILURE;
346 goto bam_add_desc_error;
347 }
348
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700349 /* Check if we have enough space in FIFO */
Deepa Dinamanie9ded132012-11-27 15:03:38 -0800350 if (len > (unsigned)bam->pipe[pipe_num].fifo.size * bam->max_desc_len)
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700351 {
352 dprintf(CRITICAL, "Data transfer exceeds desc fifo length.\n");
353 bam_ret = BAM_RESULT_FAILURE;
354 goto bam_add_desc_error;
355 }
356
357 while (len)
358 {
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700359
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700360 /* There are only 16 bits to write data length.
361 * If more bits are needed, create more
362 * descriptors.
363 */
Deepa Dinamanie9ded132012-11-27 15:03:38 -0800364 if (len > bam->max_desc_len)
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700365 {
Deepa Dinamanie9ded132012-11-27 15:03:38 -0800366 desc_len = bam->max_desc_len;
367 len -= bam->max_desc_len;
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700368 desc_flags = 0;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700369 }
370 else
371 {
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700372 desc_len = len;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700373 len = 0;
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700374 /* Set correct flags on the last desc. */
375 desc_flags = flags;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700376 }
377
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700378 /* Write descriptor */
379 bam_add_one_desc(bam, pipe_num, data_ptr, desc_len, desc_flags);
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700380
Deepa Dinamanie9ded132012-11-27 15:03:38 -0800381 data_ptr += bam->max_desc_len;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700382 n++;
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700383 }
384
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700385
386 /* Create a read/write event to notify the periperal of the added desc. */
387 bam_sys_gen_event(bam, pipe_num, n);
388
389bam_add_desc_error:
390
391 return bam_ret;
392}
393
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700394/* Function to add a BAM descriptor for a given fifo.
395 * bam : BAM instance to be used.
396 * data_ptr : Memory address for data transfer.
397 * data_len : Length of the data_ptr.
398 * flags : Flags to be set on the desc added.
399 *
400 * Note: This function does not notify the BAM about the added descriptor.
401 */
402int bam_add_one_desc(struct bam_instance *bam,
403 unsigned int pipe_num,
404 unsigned char* data_ptr,
405 uint32_t len,
406 uint8_t flags)
407{
408
409 struct bam_desc *desc = bam->pipe[pipe_num].fifo.current;
410 int bam_ret = BAM_RESULT_SUCCESS;
411
412 if (data_ptr == NULL || len == 0)
413 {
414 dprintf(CRITICAL, "Wrong params for BAM transfer \n");
415 bam_ret = BAM_RESULT_FAILURE;
416 goto bam_add_one_desc_error;
417 }
418
419 /* Check if the FIFO is allocated for the pipe */
420 if (!bam->pipe[pipe_num].initialized)
421 {
422 dprintf(CRITICAL, "Please allocate the FIFO for the BAM pipe %d\n",
423 bam->pipe[pipe_num].pipe_num);
424 bam_ret = BAM_RESULT_FAILURE;
425 goto bam_add_one_desc_error;
426 }
427
428 if ((flags & BAM_DESC_LOCK_FLAG) && (flags & BAM_DESC_UNLOCK_FLAG))
429 {
430 dprintf(CRITICAL, "Can't lock and unlock in the same desc\n");
431 bam_ret = BAM_RESULT_FAILURE;
432 goto bam_add_one_desc_error;
433 }
434
435 /* Setting EOT flag on a CMD desc is not valid */
436 if ((flags & BAM_DESC_EOT_FLAG) && (flags & BAM_DESC_CMD_FLAG))
437 {
438 dprintf(CRITICAL, "EOT flag set on the CMD desc\n");
439 bam_ret = BAM_RESULT_FAILURE;
440 goto bam_add_one_desc_error;
441 }
442
443 /* Check for the length of the desc. */
Deepa Dinamanie9ded132012-11-27 15:03:38 -0800444 if (len > bam->max_desc_len)
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700445 {
446 dprintf(CRITICAL, "len of the desc exceeds max length"
Deepa Dinamanie9ded132012-11-27 15:03:38 -0800447 " %d > %d\n", len, bam->max_desc_len);
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700448 bam_ret = BAM_RESULT_FAILURE;
449 goto bam_add_one_desc_error;
450 }
451
Deepa Dinamani62df2c72012-12-19 17:17:58 -0800452 desc->flags = flags;
453 desc->addr = (uint32_t)data_ptr;
454 desc->size = (uint16_t)len;
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700455 desc->reserved = 0;
456
Deepa Dinamani62df2c72012-12-19 17:17:58 -0800457 arch_clean_invalidate_cache_range((addr_t) desc, BAM_DESC_SIZE);
458
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700459 /* Update the FIFO to point to the head */
460 bam->pipe[pipe_num].fifo.current = fifo_getnext(&bam->pipe[pipe_num].fifo, desc);
461
462bam_add_one_desc_error:
463 return bam_ret;
464}
465
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700466struct cmd_element* bam_add_cmd_element(struct cmd_element *ptr,
467 uint32_t reg_addr,
468 uint32_t value,
469 enum bam_ce_cmd_t cmd_type)
470{
471 /* Write cmd type.
472 * Also, write the register address.
473 */
Deepa Dinamanie5ccd6c2012-08-16 11:41:06 -0700474 ptr->addr_n_cmd = (reg_addr & ~(0xFF000000)) | (cmd_type << 24);
Deepa Dinamani9d470af2012-06-29 18:27:17 -0700475
476 /* Do not mask any of the addr bits by default */
477 ptr->reg_mask = 0xFFFFFFFF;
478
479 /* Write the value to be written */
480 ptr->reg_data = value;
481
482 /* Return the address to add the next element to */
483 return ptr + 1;
484}