diff --git a/drivers/gpu/nvgpu/Makefile.sources b/drivers/gpu/nvgpu/Makefile.sources index eb98d1f25..465a6086a 100644 --- a/drivers/gpu/nvgpu/Makefile.sources +++ b/drivers/gpu/nvgpu/Makefile.sources @@ -31,7 +31,6 @@ srcs += os/posix/nvgpu.c \ os/posix/posix-nvgpu_mem.c \ os/posix/posix-dma.c \ os/posix/posix-vm.c \ - os/posix/timers.c \ os/posix/posix-comptags.c \ os/posix/firmware.c \ os/posix/soc.c \ @@ -53,6 +52,7 @@ endif # POSIX sources shared between the POSIX and QNX builds. srcs += os/posix/bug.c \ os/posix/rwsem.c \ + os/posix/timers.c \ os/posix/cond.c \ os/posix/lock.c \ os/posix/thread.c \ diff --git a/drivers/gpu/nvgpu/include/nvgpu/soc.h b/drivers/gpu/nvgpu/include/nvgpu/soc.h index 729d8af4f..8074c1c63 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/soc.h +++ b/drivers/gpu/nvgpu/include/nvgpu/soc.h @@ -33,5 +33,6 @@ bool nvgpu_is_hypervisor_mode(struct gk20a *g); bool nvgpu_is_bpmp_running(struct gk20a *g); bool nvgpu_is_soc_t194_a01(struct gk20a *g); int nvgpu_init_soc_vars(struct gk20a *g); +void nvgpu_delay_usecs(unsigned int usecs); #endif /* NVGPU_SOC_H */ diff --git a/drivers/gpu/nvgpu/os/posix/soc.c b/drivers/gpu/nvgpu/os/posix/soc.c index 2346d61e0..41e9e8bf7 100644 --- a/drivers/gpu/nvgpu/os/posix/soc.c +++ b/drivers/gpu/nvgpu/os/posix/soc.c @@ -51,3 +51,7 @@ bool nvgpu_is_soc_t194_a01(struct gk20a *g) { return false; } + +void nvgpu_delay_usecs(unsigned int usecs) +{ +} diff --git a/drivers/gpu/nvgpu/os/posix/timers.c b/drivers/gpu/nvgpu/os/posix/timers.c index 871054b3c..f24b5886b 100644 --- a/drivers/gpu/nvgpu/os/posix/timers.c +++ b/drivers/gpu/nvgpu/os/posix/timers.c @@ -21,14 +21,45 @@ */ #include +#include #include #include #include +#include -static s64 now(void) +#define MSEC_PER_SEC 1000 +#define USEC_PER_MSEC 1000 +#define NSEC_PER_USEC 1000 +#define NSEC_PER_MSEC 1000000 +#define NSEC_PER_SEC 1000000000 + +static inline s64 __nvgpu_current_time_us(void) { - return nvgpu_current_time_ms(); + struct timeval now; + s64 time_now; + int ret; + + ret = gettimeofday(&now, NULL); + if (ret != 0) { + BUG(); + } + + time_now = ((s64)now.tv_sec * (s64)1000000) + (s64)now.tv_usec; + + return time_now; +} + +static s64 get_time_ns(void) +{ + struct timespec ts; + s64 t_ns; + + (void) clock_gettime(CLOCK_MONOTONIC, &ts); + + t_ns = ts.tv_sec * 1000000000 + ts.tv_nsec; + + return t_ns; } /* @@ -36,12 +67,14 @@ static s64 now(void) */ static bool time_after(s64 a, s64 b) { - return a - b > 0; + return ((a - b) > 0); } int nvgpu_timeout_init(struct gk20a *g, struct nvgpu_timeout *timeout, u32 duration, unsigned long flags) { + s64 duration_ns; + if ((flags & ~NVGPU_TIMER_FLAG_MASK) != 0U) { return -EINVAL; } @@ -49,12 +82,14 @@ int nvgpu_timeout_init(struct gk20a *g, struct nvgpu_timeout *timeout, (void) memset(timeout, 0, sizeof(*timeout)); timeout->g = g; - timeout->flags = flags; + timeout->flags = (unsigned int)flags; if ((flags & NVGPU_TIMER_RETRY_TIMER) != 0U) { timeout->retries.max = duration; } else { - timeout->time = nvgpu_current_time_ms() + (s64)duration; + duration_ns = (s64)duration; + duration_ns *= NSEC_PER_MSEC; + timeout->time = nvgpu_current_time_ns() + duration_ns; } return 0; @@ -66,8 +101,8 @@ static int __nvgpu_timeout_expired_msg_cpu(struct nvgpu_timeout *timeout, { struct gk20a *g = timeout->g; - if (time_after(now(), timeout->time)) { - if (!(timeout->flags & NVGPU_TIMER_SILENT_TIMEOUT)) { + if (get_time_ns() >= timeout->time) { + if ((timeout->flags & NVGPU_TIMER_SILENT_TIMEOUT) == 0U) { char buf[128]; (void) vsnprintf(buf, sizeof(buf), fmt, args); @@ -88,7 +123,7 @@ static int __nvgpu_timeout_expired_msg_retry(struct nvgpu_timeout *timeout, struct gk20a *g = timeout->g; if (timeout->retries.attempted >= timeout->retries.max) { - if (!(timeout->flags & NVGPU_TIMER_SILENT_TIMEOUT)) { + if ((timeout->flags & NVGPU_TIMER_SILENT_TIMEOUT) == 0U) { char buf[128]; (void) vsnprintf(buf, sizeof(buf), fmt, args); @@ -126,49 +161,70 @@ int __nvgpu_timeout_expired_msg(struct nvgpu_timeout *timeout, int nvgpu_timeout_peek_expired(struct nvgpu_timeout *timeout) { if ((timeout->flags & NVGPU_TIMER_RETRY_TIMER) != 0U) { - return timeout->retries.attempted >= timeout->retries.max; + return (int) (timeout->retries.attempted >= + timeout->retries.max); } else { - return time_after(now(), timeout->time); + return (int) (time_after(get_time_ns(), timeout->time)); } } +static void nvgpu_usleep(unsigned int usecs) +{ + struct timespec rqtp; + s64 t_currentns, t_ns; + + t_currentns = get_time_ns(); + t_ns = (s64)usecs; + t_ns *= 1000; + t_ns += t_currentns; + + rqtp.tv_sec = t_ns / 1000000000; + rqtp.tv_nsec = t_ns % 1000000000; + + (void) clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &rqtp, NULL); +} + void nvgpu_udelay(unsigned int usecs) { - BUG(); + if (usecs >= (unsigned int) 1000) { + nvgpu_usleep(usecs); + } else { + nvgpu_delay_usecs(usecs); + } } void nvgpu_usleep_range(unsigned int min_us, unsigned int max_us) { - BUG(); + nvgpu_udelay(min_us); } void nvgpu_msleep(unsigned int msecs) { - BUG(); -} + struct timespec rqtp; + s64 t_currentns, t_ns; -static inline s64 __nvgpu_current_time_us(void) -{ - struct timeval now; - s64 time_now; - int ret; + t_currentns = get_time_ns(); + t_ns = (s64)msecs; + t_ns *= 1000000; + t_ns += t_currentns; - ret = gettimeofday(&now, NULL); - if (ret != 0) { - BUG(); - } + rqtp.tv_sec = t_ns / 1000000000; + rqtp.tv_nsec = t_ns % 1000000000; - time_now = ((s64)now.tv_sec * (s64)1000000) + (s64)now.tv_usec; - - return time_now; + (void) clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &rqtp, NULL); } s64 nvgpu_current_time_ms(void) { - return __nvgpu_current_time_us() / (s64)1000; + return (s64)(get_time_ns() / NSEC_PER_MSEC); +} + +s64 nvgpu_current_time_ns(void) +{ + return get_time_ns(); } u64 nvgpu_hr_timestamp(void) { - return __nvgpu_current_time_us(); + return (u64)__nvgpu_current_time_us(); }