blob: bd4b7517aa83c5ad6bb4ae9ca6d88c68ce7f89c9 [file] [log] [blame]
yuezonghe824eb0c2024-06-27 02:32:26 -07001/*
2 * arch/arm/mach-zx297520v2/zx297520v2-clock.c
3 *
4 * Copyright (C) 2015 ZTE-TSP
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 */
12
13#include <linux/kernel.h>
14#include <mach/board.h>
15#include <mach/iomap.h>
16#include <mach/debug.h>
17#include <linux/io.h>
18#include <mach/spinlock.h>
19#include <mach/pcu.h>
20//#include <mach/rpmsg.h>
21#include <linux/mutex.h>
22
23#define USE_HW_SPINLOCK 1
24
25#if USE_HW_SPINLOCK
26
27#define MACH_NR_SFLOCKS SFLOCK_NUM
28#define MACH_NR_HWLOCKS HWLOCK_NUM
29
30
31#define SELF_CORE_ID CORE_ID_AP
32
33/* now use 8*MACH_NR_SFLOCKS bytes */
34#define SOFTLOCK_DESC_BASE (SPINLOCK_SOFTLOCK_BASE)
35
36#define SPINLOCK_DEBUG 1
37
38#if SPINLOCK_DEBUG
39#define zspinlock_debug(fmt, ...) \
40 printk(KERN_INFO fmt, ##__VA_ARGS__)
41#else
42#define zspinlock_debug(fmt, ...)
43#endif
44
45#define zspinlock_assert(_EXP) ZDRV_ASSERT(_EXP)
46static DEFINE_MUTEX(zspinlock_mutex);
47static unsigned long s_hwSpinlockMsr;
48/****************************************************************************
49* Types
50****************************************************************************/
51struct zte_softlock_desc {
52 unsigned long used;
53 unsigned long owner;
54};
55/**************************************************************************
56 * Global Variables *
57 **************************************************************************/
58static volatile struct zte_softlock_desc *softlock_desc[MACH_NR_SFLOCKS];
59
60static const void __iomem __force *hwlock_regs[MACH_NR_HWLOCKS] =
61{
62 SHARED_DEVICE_REG1,
63 SHARED_DEVICE_REG2,
64 SHARED_DEVICE_REG3,
65 SHARED_DEVICE_REG4
66};
67
68extern void msleep(unsigned int msecs);
69
70 /*******************************************************************************
71 * Function: _hw_spin_lock
72 * Description:»ñȡӲ¼þËø£¬id 0~3
73 * Parameters:
74 * Input:
75 *
76 * Output:
77 *
78 * Returns:
79 *
80 *
81 * Others:
82 ********************************************************************************/
83 static void _hw_spin_lock(unsigned long hwid)
84{
85 unsigned long tmp;
86 unsigned long msr;
87 local_irq_save(msr);
88 s_hwSpinlockMsr = msr;
89
90 while(ioread32(hwlock_regs[hwid])&0x1);
91 tmp = ioread32(hwlock_regs[hwid]);
92 tmp &= 0x00ffffff;
93 tmp |= (SELF_CORE_ID&0xff)<<24;
94 iowrite32(tmp, hwlock_regs[hwid]);
95
96}
97/*******************************************************************************
98 * Function: _hw_spin_unlock
99 * Description:ÊÍ·ÅÓ²¼þËø£¬id 0~3
100 * Parameters:
101 * Input:
102 *
103 * Output:
104 *
105 * Returns:
106 *
107 *
108 * Others:
109 ********************************************************************************/
110static void _hw_spin_unlock(unsigned long hwid)
111{
112 unsigned long tmp;
113
114
115 if(SELF_CORE_ID != (ioread32(hwlock_regs[hwid])&0xff000000)>>24){
116 zspinlock_assert(0);
117 }
118 tmp = ioread32(hwlock_regs[hwid]);
119 tmp &= 0x00fffffe;
120 iowrite32(tmp, hwlock_regs[hwid]);
121
122 local_irq_restore(s_hwSpinlockMsr);
123}
124/*******************************************************************************
125 * Function: hw_spin_lock
126 * Description:»ñȡӲ¼þËø£¬id 0~2£¬
127 * id 3±£Áô¸øÈí¼þËøÊ¹Óã¬ÍⲿÇý¶¯²»¿ÉÓá£
128 * Parameters:
129 * Input:
130 *
131 * Output:
132 *
133 * Returns:
134 *
135 *
136 * Others:
137 ********************************************************************************/
138void hw_spin_lock(emhw_lock_id hwid)
139{
140 _hw_spin_lock(hwid);
141// zspinlock_debug("cpu %d gets %d hardware lock!/n",SELF_CORE_ID,hwid);
142}
143/*******************************************************************************
144 * Function: hw_spin_unlock
145 * Description:Çý¶¯ÊÍ·ÅÓ²¼þËø£¬id 0~2
146 * Parameters:
147 * Input:
148 *
149 * Output:
150 *
151 * Returns:
152 *
153 *
154 * Others:
155 ********************************************************************************/
156void hw_spin_unlock(emhw_lock_id hwid)
157{
158 _hw_spin_unlock(hwid);
159// zspinlock_debug("cpu %d releases %d hardware lock!/n",SELF_CORE_ID,hwid);
160}
161/*******************************************************************************
162 * Function: soft_spin_lock
163 * Description:Çý¶¯»ñµÃÈí¼þËø½Ó¿Ú
164 * Parameters:
165 * Input: sfid: Èí¼þËøid¡£
166 * coreid: ±£³ÖidºÅΪsfidÈí¼þËøµÄcpuid¡£
167 * Output:
168 *
169 * Returns:
170 *
171 *
172 * Others:
173 ********************************************************************************/
174void soft_spin_lock(emsf_lock_id sfid)
175{
176 static unsigned long lock_count = 0;
177
178softlock_loop:
179 while(softlock_desc[sfid]->owner != SELF_CORE_ID && softlock_desc[sfid]->used)
180 {
181 lock_count++;
182 if(lock_count == 1000)
183 {
184 lock_count = 0;
185 msleep(5);
186 }
187 }
188
189 _hw_spin_lock(SOFTLOCK_HWLOCK);
190 if(softlock_desc[sfid]->owner != SELF_CORE_ID && softlock_desc[sfid]->used)
191 {
192 _hw_spin_unlock(SOFTLOCK_HWLOCK);
193 goto softlock_loop;
194 }
195 softlock_desc[sfid]->used ++;
196 softlock_desc[sfid]->owner = SELF_CORE_ID;
197 _hw_spin_unlock(SOFTLOCK_HWLOCK);
198 //zspinlock_debug("cpu %d releases %d software lock!/n",SELF_CORE_ID,sfid);
199
200}
201/*******************************************************************************
202 * Function: soft_spin_unlock
203 * Description:Óësoft_spin_lock¶ÔÓ¦µÄÊÍ·ÅÈí¼þËø½Ó¿Ú¡£
204 * Parameters:
205 * Input:
206 *
207 * Output:
208 *
209 * Returns:
210 *
211 *
212 * Others:
213 ********************************************************************************/
214 void soft_spin_unlock(emsf_lock_id sfid)
215{
216 if(softlock_desc[sfid]->used){
217 if(SELF_CORE_ID != softlock_desc[sfid]->owner){
218 zspinlock_assert(0);
219 }
220 _hw_spin_lock(SOFTLOCK_HWLOCK);
221 softlock_desc[sfid]->used --;
222 if(softlock_desc[sfid]->used == 0) {
223 softlock_desc[sfid]->owner = 0x0;
224 }
225 _hw_spin_unlock(SOFTLOCK_HWLOCK);
226 //zspinlock_debug("cpu %d releases %d software lock!/n",SELF_CORE_ID,sfid);
227 }
228}
229
230/*******************************************************************************
231 * Function: soft_spin_lock_psm
232 * Description:Çý¶¯»ñµÃÈí¼þËø½Ó¿Ú
233 * Parameters:
234 * Input: sfid: Èí¼þËøid¡£
235 * coreid: ±£³ÖidºÅΪsfidÈí¼þËøµÄcpuid¡£
236 * Output:
237 *
238 * Returns:
239 *
240 *
241 * Others:
242 ********************************************************************************/
243void soft_spin_lock_psm(emsf_lock_id sfid)
244{
245softlock_loop:
246 while(softlock_desc[sfid]->owner != SELF_CORE_ID && softlock_desc[sfid]->used)
247 {
248
249 }
250
251 _hw_spin_lock(SOFTLOCK_HWLOCK);
252 if(softlock_desc[sfid]->owner != SELF_CORE_ID && softlock_desc[sfid]->used)
253 {
254 _hw_spin_unlock(SOFTLOCK_HWLOCK);
255 goto softlock_loop;
256 }
257 softlock_desc[sfid]->used ++;
258 softlock_desc[sfid]->owner = SELF_CORE_ID;
259 _hw_spin_unlock(SOFTLOCK_HWLOCK);
260 //zspinlock_debug("cpu %d releases %d software lock!/n",SELF_CORE_ID,sfid);
261
262}
263
264/*******************************************************************************
265 * Function: soft_spin_unlock_psm
266 * Description:Óësoft_spin_lock_psm¶ÔÓ¦µÄÊÍ·ÅÈí¼þËø½Ó¿Ú¡£
267 * Parameters:
268 * Input:
269 *
270 * Output:
271 *
272 * Returns:
273 *
274 *
275 * Others:
276 ********************************************************************************/
277void soft_spin_unlock_psm(emsf_lock_id sfid)
278{
279 soft_spin_unlock(sfid);
280}
281
282/*******************************************************************************
283 * Function: reg_spin_lock
284 * Description:Çý¶¯»ñµÃ¼Ä´æÆ÷Ëø½Ó¿Ú
285 * Parameters:
286 * Input:
287 * Output:
288 *
289 * Returns:
290 *
291 *
292 * Others:
293 ********************************************************************************/
294void reg_spin_lock(void)
295{
296 _hw_spin_lock(REGLOCK_HWLOCK);
297 softlock_desc[REG_SFLOCK]->owner = SELF_CORE_ID;
298}
299/*******************************************************************************
300 * Function: reg_spin_unlock
301 * Description:Óëreg_spin_lock¶ÔÓ¦µÄÊͷżĴæÆ÷Ëø½Ó¿Ú¡£
302 * Parameters:
303 * Input:
304 *
305 * Output:
306 *
307 * Returns:
308 *
309 *
310 * Others:
311 ********************************************************************************/
312 void reg_spin_unlock(void)
313{
314 softlock_desc[REG_SFLOCK]->owner = 0x0;
315 _hw_spin_unlock(REGLOCK_HWLOCK);
316
317}
318
319/*******************************************************************************
320 * Function: softspinlock_init
321 * Description:Èí¼þËø³õʼ»¯¡£
322 * Parameters:
323 * Input:
324 *
325 * Output:
326 *
327 * Returns:
328 *
329 *
330 * Others:
331 ********************************************************************************/
332int softspinlock_init(void)
333{
334 int i;
335
336 for(i = 0; i<MACH_NR_SFLOCKS; i++){
337 softlock_desc[i] =
338 (struct zte_softlock_desc *)(SOFTLOCK_DESC_BASE +i*sizeof(struct zte_softlock_desc));
339 //softlock_desc[i]->used = 0;
340 //softlock_desc[i]->owner= CORE_ID_NUM;
341 }
342 zspinlock_debug("softspinlock init success base=0x%x!",(int)SOFTLOCK_DESC_BASE);
343 return 0;
344}
345
346//arch_initcall(softspinlock_init);
347#else
348int softspinlock_init(void){return 0;}
349void reg_spin_lock(void){}
350void reg_spin_unlock(void){}
351void soft_spin_lock(emsf_lock_id sfid){}
352void soft_spin_unlock(emsf_lock_id sfid){}
353void soft_spin_lock_psm(emsf_lock_id sfid){}
354void soft_spin_unlock_psm(emsf_lock_id sfid){}
355void hw_spin_lock(emhw_lock_id hwid){}
356void hw_spin_unlock(emhw_lock_id hwid){}
357#endif