1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 /* 3 * Clock utilities for s390 4 * 5 * Authors: 6 * Thomas Huth <thuth@redhat.com> 7 * 8 * Copied from the s390/intercept test by: 9 * Pierre Morel <pmorel@linux.ibm.com> 10 */ 11 #ifndef _ASMS390X_TIME_H_ 12 #define _ASMS390X_TIME_H_ 13 14 #define S390_CLOCK_SHIFT_US (63 - 51) 15 16 #define STCK_SHIFT_US S390_CLOCK_SHIFT_US 17 #define STCK_MAX ((1UL << 52) - 1) 18 19 #define CPU_TIMER_SHIFT_US S390_CLOCK_SHIFT_US 20 21 static inline uint64_t get_clock_us(void) 22 { 23 uint64_t clk; 24 25 asm volatile(" stck %0 " : : "Q"(clk) : "memory"); 26 27 return clk >> STCK_SHIFT_US; 28 } 29 30 static inline uint64_t get_clock_ms(void) 31 { 32 return get_clock_us() / 1000; 33 } 34 35 static inline void udelay(unsigned long us) 36 { 37 unsigned long startclk = get_clock_us(); 38 unsigned long c; 39 40 do { 41 c = get_clock_us(); 42 if (c < startclk) 43 c += STCK_MAX; 44 } while (c < startclk + us); 45 } 46 47 static inline void mdelay(unsigned long ms) 48 { 49 udelay(ms * 1000); 50 } 51 52 static inline void cpu_timer_set_ms(int64_t timeout_ms) 53 { 54 int64_t timer_value = (timeout_ms * 1000) << CPU_TIMER_SHIFT_US; 55 56 asm volatile ( 57 "spt %[timer_value]\n" 58 : 59 : [timer_value] "Q" (timer_value) 60 ); 61 } 62 63 #endif 64