162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Common timebase prototypes and such for all ppc machines. 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#ifndef _ASM_POWERPC_VDSO_TIMEBASE_H 762306a36Sopenharmony_ci#define _ASM_POWERPC_VDSO_TIMEBASE_H 862306a36Sopenharmony_ci 962306a36Sopenharmony_ci#include <asm/reg.h> 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci/* 1262306a36Sopenharmony_ci * We use __powerpc64__ here because we want the compat VDSO to use the 32-bit 1362306a36Sopenharmony_ci * version below in the else case of the ifdef. 1462306a36Sopenharmony_ci */ 1562306a36Sopenharmony_ci#if defined(__powerpc64__) && (defined(CONFIG_PPC_CELL) || defined(CONFIG_PPC_E500)) 1662306a36Sopenharmony_ci#define mftb() ({unsigned long rval; \ 1762306a36Sopenharmony_ci asm volatile( \ 1862306a36Sopenharmony_ci "90: mfspr %0, %2;\n" \ 1962306a36Sopenharmony_ci ASM_FTR_IFSET( \ 2062306a36Sopenharmony_ci "97: cmpwi %0,0;\n" \ 2162306a36Sopenharmony_ci " beq- 90b;\n", "", %1) \ 2262306a36Sopenharmony_ci : "=r" (rval) \ 2362306a36Sopenharmony_ci : "i" (CPU_FTR_CELL_TB_BUG), "i" (SPRN_TBRL) : "cr0"); \ 2462306a36Sopenharmony_ci rval;}) 2562306a36Sopenharmony_ci#elif defined(CONFIG_PPC_8xx) 2662306a36Sopenharmony_ci#define mftb() ({unsigned long rval; \ 2762306a36Sopenharmony_ci asm volatile("mftbl %0" : "=r" (rval)); rval;}) 2862306a36Sopenharmony_ci#else 2962306a36Sopenharmony_ci#define mftb() ({unsigned long rval; \ 3062306a36Sopenharmony_ci asm volatile("mfspr %0, %1" : \ 3162306a36Sopenharmony_ci "=r" (rval) : "i" (SPRN_TBRL)); rval;}) 3262306a36Sopenharmony_ci#endif /* !CONFIG_PPC_CELL */ 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci#if defined(CONFIG_PPC_8xx) 3562306a36Sopenharmony_ci#define mftbu() ({unsigned long rval; \ 3662306a36Sopenharmony_ci asm volatile("mftbu %0" : "=r" (rval)); rval;}) 3762306a36Sopenharmony_ci#else 3862306a36Sopenharmony_ci#define mftbu() ({unsigned long rval; \ 3962306a36Sopenharmony_ci asm volatile("mfspr %0, %1" : "=r" (rval) : \ 4062306a36Sopenharmony_ci "i" (SPRN_TBRU)); rval;}) 4162306a36Sopenharmony_ci#endif 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#define mttbl(v) asm volatile("mttbl %0":: "r"(v)) 4462306a36Sopenharmony_ci#define mttbu(v) asm volatile("mttbu %0":: "r"(v)) 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_cistatic __always_inline u64 get_tb(void) 4762306a36Sopenharmony_ci{ 4862306a36Sopenharmony_ci unsigned int tbhi, tblo, tbhi2; 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci /* 5162306a36Sopenharmony_ci * We use __powerpc64__ here not CONFIG_PPC64 because we want the compat 5262306a36Sopenharmony_ci * VDSO to use the 32-bit compatible version in the while loop below. 5362306a36Sopenharmony_ci */ 5462306a36Sopenharmony_ci if (__is_defined(__powerpc64__)) 5562306a36Sopenharmony_ci return mftb(); 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci do { 5862306a36Sopenharmony_ci tbhi = mftbu(); 5962306a36Sopenharmony_ci tblo = mftb(); 6062306a36Sopenharmony_ci tbhi2 = mftbu(); 6162306a36Sopenharmony_ci } while (tbhi != tbhi2); 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci return ((u64)tbhi << 32) | tblo; 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_cistatic inline void set_tb(unsigned int upper, unsigned int lower) 6762306a36Sopenharmony_ci{ 6862306a36Sopenharmony_ci mtspr(SPRN_TBWL, 0); 6962306a36Sopenharmony_ci mtspr(SPRN_TBWU, upper); 7062306a36Sopenharmony_ci mtspr(SPRN_TBWL, lower); 7162306a36Sopenharmony_ci} 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci#endif /* _ASM_POWERPC_VDSO_TIMEBASE_H */ 74