yuezonghe | 824eb0c | 2024-06-27 02:32:26 -0700 | [diff] [blame] | 1 | /*
|
| 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)
|
| 46 | static DEFINE_MUTEX(zspinlock_mutex);
|
| 47 | static unsigned long s_hwSpinlockMsr;
|
| 48 | /****************************************************************************
|
| 49 | * Types
|
| 50 | ****************************************************************************/
|
| 51 | struct zte_softlock_desc {
|
| 52 | unsigned long used;
|
| 53 | unsigned long owner;
|
| 54 | };
|
| 55 | /**************************************************************************
|
| 56 | * Global Variables *
|
| 57 | **************************************************************************/
|
| 58 | static volatile struct zte_softlock_desc *softlock_desc[MACH_NR_SFLOCKS];
|
| 59 |
|
| 60 | static 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 |
|
| 68 | extern 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 | ********************************************************************************/
|
| 110 | static 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 | ********************************************************************************/
|
| 138 | void 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 | ********************************************************************************/
|
| 156 | void 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 | ********************************************************************************/
|
| 174 | void soft_spin_lock(emsf_lock_id sfid)
|
| 175 | {
|
| 176 | static unsigned long lock_count = 0;
|
| 177 |
|
| 178 | softlock_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 | ********************************************************************************/
|
| 243 | void soft_spin_lock_psm(emsf_lock_id sfid)
|
| 244 | {
|
| 245 | softlock_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 | ********************************************************************************/
|
| 277 | void 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 | ********************************************************************************/
|
| 294 | void 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 | ********************************************************************************/
|
| 332 | int 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
|
| 348 | int softspinlock_init(void){return 0;}
|
| 349 | void reg_spin_lock(void){}
|
| 350 | void reg_spin_unlock(void){}
|
| 351 | void soft_spin_lock(emsf_lock_id sfid){}
|
| 352 | void soft_spin_unlock(emsf_lock_id sfid){}
|
| 353 | void soft_spin_lock_psm(emsf_lock_id sfid){}
|
| 354 | void soft_spin_unlock_psm(emsf_lock_id sfid){}
|
| 355 | void hw_spin_lock(emhw_lock_id hwid){}
|
| 356 | void hw_spin_unlock(emhw_lock_id hwid){}
|
| 357 | #endif
|