1*6c9f99dfSJanosch 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 */ 1165b436f2SPierre Morel #ifndef ASM_S390X_TIME_H 1265b436f2SPierre Morel #define ASM_S390X_TIME_H 1365b436f2SPierre Morel 144cb1ee8fSPierre Morel #define STCK_SHIFT_US (63 - 51) 154cb1ee8fSPierre Morel #define STCK_MAX ((1UL << 52) - 1) 164cb1ee8fSPierre Morel 174cb1ee8fSPierre Morel static inline uint64_t get_clock_us(void) 1865b436f2SPierre Morel { 1965b436f2SPierre Morel uint64_t clk; 2065b436f2SPierre Morel 2165b436f2SPierre Morel asm volatile(" stck %0 " : : "Q"(clk) : "memory"); 2265b436f2SPierre Morel 234cb1ee8fSPierre Morel return clk >> STCK_SHIFT_US; 244cb1ee8fSPierre Morel } 254cb1ee8fSPierre Morel 264cb1ee8fSPierre Morel static inline uint64_t get_clock_ms(void) 274cb1ee8fSPierre Morel { 284cb1ee8fSPierre Morel return get_clock_us() / 1000; 294cb1ee8fSPierre Morel } 304cb1ee8fSPierre Morel 314cb1ee8fSPierre Morel static inline void udelay(unsigned long us) 324cb1ee8fSPierre Morel { 334cb1ee8fSPierre Morel unsigned long startclk = get_clock_us(); 344cb1ee8fSPierre Morel unsigned long c; 354cb1ee8fSPierre Morel 364cb1ee8fSPierre Morel do { 374cb1ee8fSPierre Morel c = get_clock_us(); 384cb1ee8fSPierre Morel if (c < startclk) 394cb1ee8fSPierre Morel c += STCK_MAX; 404cb1ee8fSPierre Morel } while (c < startclk + us); 414cb1ee8fSPierre Morel } 424cb1ee8fSPierre Morel 434cb1ee8fSPierre Morel static inline void mdelay(unsigned long ms) 444cb1ee8fSPierre Morel { 454cb1ee8fSPierre Morel udelay(ms * 1000); 4665b436f2SPierre Morel } 4765b436f2SPierre Morel 4865b436f2SPierre Morel #endif 49