1 /*
2 * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 *
8 * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 *
11 * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the
14 * distribution.
15 *
16 * Neither the name of Texas Instruments Incorporated nor the names of
17 * its contributors may be used to endorse or promote products derived
18 * from this software without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33 //*****************************************************************************
34 //
35 // hwspinlock.c
36 //
37 // Driver for the Apps-NWP spinlock
38 //
39 //*****************************************************************************
40
41 //*****************************************************************************
42 //
43 //! \addtogroup HwSpinLock_api
44 //! @{
45 //
46 //*****************************************************************************
47
48 #include <stdbool.h>
49 #include <stdint.h>
50 #include "inc/hw_types.h"
51 #include "inc/hw_memmap.h"
52 #include "inc/hw_ints.h"
53 #include "inc/hw_common_reg.h"
54 #include "hwspinlock.h"
55
56 //*****************************************************************************
57 // Global semaphore register list
58 //*****************************************************************************
59 static const uint32_t HwSpinLock_RegLst[]=
60 {
61 COMMON_REG_BASE + COMMON_REG_O_SPI_Properties_Register
62 };
63
64 //*****************************************************************************
65 //
66 //! Acquire specified spin lock.
67 //!
68 //! \param ui32LockID is one of the valid spin lock.
69 //!
70 //! This function acquires specified spin lock and will not retun util the
71 //! specified lock is acquired.
72 //!
73 //! The parameter \e ui32LockID should \b HWSPINLOCK_MCSPIS0.
74 //!
75 //! return None.
76 //
77 //*****************************************************************************
HwSpinLockAcquire(uint32_t ui32LockID)78 void HwSpinLockAcquire(uint32_t ui32LockID)
79 {
80 uint32_t ui32BitPos;
81 uint32_t ui32SemVal;
82 uint32_t ui32RegAddr;
83
84 //
85 // Extract the bit position from the
86 // LockID
87 //
88 ui32BitPos = ((ui32LockID >> 16) & 0x0FFF);
89 ui32RegAddr = HwSpinLock_RegLst[ui32LockID & 0xF];
90
91 //
92 // Set the corresponding
93 // ownership bits to 'b01
94 //
95 ui32SemVal = (0xFFFFFFFF ^ (0x2 << ui32BitPos));
96
97 //
98 // Retry untill we succeed
99 //
100 do
101 {
102 HWREG(ui32RegAddr) = ui32SemVal;
103 }
104 while( !(HWREG(ui32RegAddr) & (1 << ui32BitPos )) );
105
106 }
107
108 //*****************************************************************************
109 //
110 //! Try to acquire specified spin lock.
111 //!
112 //! \param ui32LockID is one of the valid spin lock.
113 //! \param ui32Retry is the number of reties.
114 //!
115 //! This function tries acquire specified spin lock in \e ui32Retry retries.
116 //!
117 //! The parameter \e ui32Retry can be any value between 0 and 2^32.
118 //!
119 //! return Returns 0 on success, -1 otherwise.
120 //
121 //*****************************************************************************
HwSpinLockTryAcquire(uint32_t ui32LockID,uint32_t ui32Retry)122 int32_t HwSpinLockTryAcquire(uint32_t ui32LockID, uint32_t ui32Retry)
123 {
124 uint32_t ui32BitPos;
125 uint32_t ui32SemVal;
126 uint32_t ui32RegAddr;
127
128 //
129 // Extract the bit position from the
130 // LockID
131 //
132 ui32BitPos = ((ui32LockID >> 16) & 0x0FFF);
133 ui32RegAddr = HwSpinLock_RegLst[ui32LockID & 0xF];
134
135 //
136 // Set the corresponding
137 // ownership bits to 'b01
138 //
139 ui32SemVal = (0xFFFFFFFF ^ (0x2 << ui32BitPos));
140
141 //
142 // Check for 0 retry.
143 //
144 if(ui32Retry == 0)
145 {
146 ui32Retry = 1;
147 }
148
149 //
150 // Retry the number of times specified
151 //
152 do
153 {
154 HWREG(ui32RegAddr) = ui32SemVal;
155 ui32Retry--;
156 }
157 while( !(HWREG(ui32RegAddr) & (1 << ui32BitPos )) && ui32Retry );
158
159
160 //
161 // Check the semaphore status
162 //
163 if(HWREG(ui32RegAddr) & (1 << ui32BitPos ))
164 {
165 return 0;
166 }
167 else
168 {
169 return -1;
170 }
171 }
172
173 //*****************************************************************************
174 //
175 //! Release a previously owned spin lock
176 //!
177 //! \param ui32LockID is one of the valid spin lock.
178 //!
179 //! This function releases previously owned spin lock.
180 //!
181 //! \return None.
182 //
183 //*****************************************************************************
HwSpinLockRelease(uint32_t ui32LockID)184 void HwSpinLockRelease(uint32_t ui32LockID)
185 {
186 uint32_t ui32BitPos;
187 uint32_t ui32SemVal;
188
189 //
190 // Extract the bit position from the
191 // lock id.
192 //
193 ui32BitPos = ((ui32LockID >> 16) & 0x00FF);
194
195 //
196 // Release the spin lock, only if already owned
197 //
198 if(HWREG(HwSpinLock_RegLst[ui32LockID & 0xF]) & (1 << ui32BitPos ))
199 {
200 ui32SemVal = (0xFFFFFFFF & ~(0x3 << ui32BitPos));
201 HWREG(HwSpinLock_RegLst[ui32LockID & 0xF]) = ui32SemVal;
202 }
203 }
204
205 //*****************************************************************************
206 //
207 //! Get the current or previous ownership status.
208 //!
209 //! \param ui32LockID is one of the valid spin lock.
210 //! \param bCurrentStatus is \b true for current status, \b flase otherwise
211 //!
212 //! This function gets the current or previous ownership status of the
213 //! specified spin lock based on \e bCurrentStatus parameter.
214 //!
215 //! \return Returns \b HWSPINLOCK_OWNER_APPS, \b HWSPINLOCK_OWNER_NWP or
216 //! \b HWSPINLOCK_OWNER_NONE.
217 //
218 //*****************************************************************************
HwSpinLockTest(uint32_t ui32LockID,bool bCurrentStatus)219 uint32_t HwSpinLockTest(uint32_t ui32LockID, bool bCurrentStatus)
220 {
221 uint32_t ui32BitPos;
222 uint32_t ui32SemVal;
223
224 if(bCurrentStatus)
225 {
226 //
227 // Extract the bit position from the
228 // lock id.
229 //
230 ui32BitPos = ((ui32LockID >> 16) & 0x00FF);
231
232 //
233 // return semaphore
234 //
235 return((HWREG(HwSpinLock_RegLst[ui32LockID & 0xF]) >> ui32BitPos ) & 0x3 );
236 }
237 else
238 {
239 //
240 // Extract the bit position
241 //
242 ui32BitPos = ((ui32LockID >> 24) & 0xFF);
243
244 //
245 // Identify which register to read
246 //
247 if((ui32LockID & 0xF) > 4)
248 {
249 ui32SemVal = ((HWREG(COMMON_REG_BASE +
250 COMMON_REG_O_SEMAPHORE_PREV_OWNER1) >> ui32BitPos ) & 0x3);
251 }
252 else
253 {
254 ui32SemVal = ((HWREG(COMMON_REG_BASE +
255 COMMON_REG_O_SEMAPHORE_PREV_OWNER2) >> ui32BitPos ) & 0x3);
256 }
257
258 //
259 // return the owner
260 //
261 return ui32SemVal;
262 }
263 }
264
265 //*****************************************************************************
266 //
267 // Close the Doxygen group.
268 //! @}
269 //
270 //*****************************************************************************
271