1 /*****************************************************************************
2 * Copyright 2003 - 2008 Broadcom Corporation.  All rights reserved.
3 *
4 * Unless you and Broadcom execute a separate written software license
5 * agreement governing use of this software, this software is licensed to you
6 * under the terms of the GNU General Public License version 2, available at
7 * http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
8 *
9 * Notwithstanding the above, under no circumstances may you combine this
10 * software in any way with any other Broadcom software provided under a
11 * license other than the GPL, without Broadcom's express prior written
12 * consent.
13 *****************************************************************************/
14 
15 /****************************************************************************/
16 /**
17 *  @file    reg.h
18 *
19 *  @brief   Generic register definitions used in CSP
20 */
21 /****************************************************************************/
22 
23 #ifndef CSP_REG_H
24 #define CSP_REG_H
25 
26 /* ---- Include Files ---------------------------------------------------- */
27 
28 #include <csp/stdint.h>
29 
30 /* ---- Public Constants and Types --------------------------------------- */
31 
32 #define __REG32(x)      (*((volatile uint32_t *)(x)))
33 #define __REG16(x)      (*((volatile uint16_t *)(x)))
34 #define __REG8(x)       (*((volatile uint8_t *) (x)))
35 
36 /* Macros used to define a sequence of reserved registers. The start / end */
37 /* are byte offsets in the particular register definition, with the "end" */
38 /* being the offset of the next un-reserved register. E.g. if offsets */
39 /* 0x10 through to 0x1f are reserved, then this reserved area could be */
40 /* specified as follows. */
41 /*  typedef struct */
42 /*  { */
43 /*      uint32_t reg1;           offset 0x00 */
44 /*      uint32_t reg2;           offset 0x04 */
45 /*      uint32_t reg3;           offset 0x08 */
46 /*      uint32_t reg4;           offset 0x0c */
47 /*      REG32_RSVD(0x10, 0x20); */
48 /*      uint32_t reg5;           offset 0x20 */
49 /*      ... */
50 /*  } EXAMPLE_REG_t; */
51 #define REG8_RSVD(start, end)   uint8_t rsvd_##start[(end - start) / sizeof(uint8_t)]
52 #define REG16_RSVD(start, end)  uint16_t rsvd_##start[(end - start) / sizeof(uint16_t)]
53 #define REG32_RSVD(start, end)  uint32_t rsvd_##start[(end - start) / sizeof(uint32_t)]
54 
55 /* ---- Public Variable Externs ------------------------------------------ */
56 /* ---- Public Function Prototypes --------------------------------------- */
57 
58 /* Note: When protecting multiple statements, the REG_LOCAL_IRQ_SAVE and */
59 /* REG_LOCAL_IRQ_RESTORE must be enclosed in { } to allow the  */
60 /* flags variable to be declared locally. */
61 /* e.g. */
62 /*    statement1; */
63 /*    { */
64 /*       REG_LOCAL_IRQ_SAVE; */
65 /*       <multiple statements here> */
66 /*       REG_LOCAL_IRQ_RESTORE; */
67 /*    } */
68 /*    statement2; */
69 /*  */
70 
71 #if defined(__KERNEL__) && !defined(STANDALONE)
72 #include <mach/hardware.h>
73 #include <linux/interrupt.h>
74 
75 #define REG_LOCAL_IRQ_SAVE      HW_DECLARE_SPINLOCK(reg32) \
76 	unsigned long flags; HW_IRQ_SAVE(reg32, flags)
77 
78 #define REG_LOCAL_IRQ_RESTORE   HW_IRQ_RESTORE(reg32, flags)
79 
80 #else
81 
82 #define REG_LOCAL_IRQ_SAVE
83 #define REG_LOCAL_IRQ_RESTORE
84 
85 #endif
86 
reg32_modify_and(volatile uint32_t * reg,uint32_t value)87 static inline void reg32_modify_and(volatile uint32_t *reg, uint32_t value)
88 {
89 	REG_LOCAL_IRQ_SAVE;
90 	*reg &= value;
91 	REG_LOCAL_IRQ_RESTORE;
92 }
93 
reg32_modify_or(volatile uint32_t * reg,uint32_t value)94 static inline void reg32_modify_or(volatile uint32_t *reg, uint32_t value)
95 {
96 	REG_LOCAL_IRQ_SAVE;
97 	*reg |= value;
98 	REG_LOCAL_IRQ_RESTORE;
99 }
100 
reg32_modify_mask(volatile uint32_t * reg,uint32_t mask,uint32_t value)101 static inline void reg32_modify_mask(volatile uint32_t *reg, uint32_t mask,
102 				     uint32_t value)
103 {
104 	REG_LOCAL_IRQ_SAVE;
105 	*reg = (*reg & mask) | value;
106 	REG_LOCAL_IRQ_RESTORE;
107 }
108 
reg32_write(volatile uint32_t * reg,uint32_t value)109 static inline void reg32_write(volatile uint32_t *reg, uint32_t value)
110 {
111 	*reg = value;
112 }
113 
114 #endif /* CSP_REG_H */
115