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