16c9f99dfSJanosch Frank /* SPDX-License-Identifier: GPL-2.0-only */ 265b436f2SPierre Morel /* 365b436f2SPierre Morel * Clock utilities for s390 465b436f2SPierre Morel * 565b436f2SPierre Morel * Authors: 665b436f2SPierre Morel * Thomas Huth <thuth@redhat.com> 765b436f2SPierre Morel * 865b436f2SPierre Morel * Copied from the s390/intercept test by: 965b436f2SPierre Morel * Pierre Morel <pmorel@linux.ibm.com> 1065b436f2SPierre Morel */ 11eb5a1bbaSCornelia Huck #ifndef _ASMS390X_TIME_H_ 12eb5a1bbaSCornelia Huck #define _ASMS390X_TIME_H_ 1365b436f2SPierre Morel 14*08a584f7SNico Boehr #define S390_CLOCK_SHIFT_US (63 - 51) 15*08a584f7SNico Boehr 16*08a584f7SNico Boehr #define STCK_SHIFT_US S390_CLOCK_SHIFT_US 174cb1ee8fSPierre Morel #define STCK_MAX ((1UL << 52) - 1) 184cb1ee8fSPierre Morel 19*08a584f7SNico Boehr #define CPU_TIMER_SHIFT_US S390_CLOCK_SHIFT_US 20*08a584f7SNico Boehr 214cb1ee8fSPierre Morel static inline uint64_t get_clock_us(void) 2265b436f2SPierre Morel { 2365b436f2SPierre Morel uint64_t clk; 2465b436f2SPierre Morel 2565b436f2SPierre Morel asm volatile(" stck %0 " : : "Q"(clk) : "memory"); 2665b436f2SPierre Morel 274cb1ee8fSPierre Morel return clk >> STCK_SHIFT_US; 284cb1ee8fSPierre Morel } 294cb1ee8fSPierre Morel 304cb1ee8fSPierre Morel static inline uint64_t get_clock_ms(void) 314cb1ee8fSPierre Morel { 324cb1ee8fSPierre Morel return get_clock_us() / 1000; 334cb1ee8fSPierre Morel } 344cb1ee8fSPierre Morel 354cb1ee8fSPierre Morel static inline void udelay(unsigned long us) 364cb1ee8fSPierre Morel { 374cb1ee8fSPierre Morel unsigned long startclk = get_clock_us(); 384cb1ee8fSPierre Morel unsigned long c; 394cb1ee8fSPierre Morel 404cb1ee8fSPierre Morel do { 414cb1ee8fSPierre Morel c = get_clock_us(); 424cb1ee8fSPierre Morel if (c < startclk) 434cb1ee8fSPierre Morel c += STCK_MAX; 444cb1ee8fSPierre Morel } while (c < startclk + us); 454cb1ee8fSPierre Morel } 464cb1ee8fSPierre Morel 474cb1ee8fSPierre Morel static inline void mdelay(unsigned long ms) 484cb1ee8fSPierre Morel { 494cb1ee8fSPierre Morel udelay(ms * 1000); 5065b436f2SPierre Morel } 5165b436f2SPierre Morel 52*08a584f7SNico Boehr static inline void cpu_timer_set_ms(int64_t timeout_ms) 53*08a584f7SNico Boehr { 54*08a584f7SNico Boehr int64_t timer_value = (timeout_ms * 1000) << CPU_TIMER_SHIFT_US; 55*08a584f7SNico Boehr 56*08a584f7SNico Boehr asm volatile ( 57*08a584f7SNico Boehr "spt %[timer_value]\n" 58*08a584f7SNico Boehr : 59*08a584f7SNico Boehr : [timer_value] "Q" (timer_value) 60*08a584f7SNico Boehr ); 61*08a584f7SNico Boehr } 62*08a584f7SNico Boehr 6365b436f2SPierre Morel #endif 64