diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | 94 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/hw_timer_gk20a.h | 10 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gm20b/hw_timer_gm20b.h | 10 |
3 files changed, 112 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c index 11790f4a..b2ae224f 100644 --- a/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/ctrl_gk20a.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "hw_gr_gk20a.h" | 29 | #include "hw_gr_gk20a.h" |
30 | #include "hw_fb_gk20a.h" | 30 | #include "hw_fb_gk20a.h" |
31 | #include "hw_proj_gk20a.h" | 31 | #include "hw_proj_gk20a.h" |
32 | #include "hw_timer_gk20a.h" | ||
32 | 33 | ||
33 | int gk20a_ctrl_dev_open(struct inode *inode, struct file *filp) | 34 | int gk20a_ctrl_dev_open(struct inode *inode, struct file *filp) |
34 | { | 35 | { |
@@ -530,6 +531,94 @@ static int gk20a_ctrl_get_buffer_info( | |||
530 | &args->out.id, &args->out.length); | 531 | &args->out.id, &args->out.length); |
531 | } | 532 | } |
532 | 533 | ||
534 | static inline u64 get_cpu_timestamp_tsc(void) | ||
535 | { | ||
536 | return ((u64) get_cycles()); | ||
537 | } | ||
538 | |||
539 | static inline u64 get_cpu_timestamp_jiffies(void) | ||
540 | { | ||
541 | return (get_jiffies_64() - INITIAL_JIFFIES); | ||
542 | } | ||
543 | |||
544 | static inline u64 get_cpu_timestamp_timeofday(void) | ||
545 | { | ||
546 | struct timeval tv; | ||
547 | |||
548 | do_gettimeofday(&tv); | ||
549 | return timeval_to_jiffies(&tv); | ||
550 | } | ||
551 | |||
552 | static inline int get_timestamps_zipper(struct gk20a *g, | ||
553 | u64 (*get_cpu_timestamp)(void), | ||
554 | struct nvgpu_gpu_get_cpu_time_correlation_info_args *args) | ||
555 | { | ||
556 | int err = 0; | ||
557 | int i = 0; | ||
558 | u32 gpu_timestamp_hi_new = 0; | ||
559 | u32 gpu_timestamp_hi_old = 0; | ||
560 | |||
561 | if (gk20a_busy(g->dev)) { | ||
562 | gk20a_err(dev_from_gk20a(g), "GPU not powered on\n"); | ||
563 | err = -EINVAL; | ||
564 | goto end; | ||
565 | } | ||
566 | |||
567 | /* get zipper reads of gpu and cpu counter values */ | ||
568 | gpu_timestamp_hi_old = gk20a_readl(g, timer_time_1_r()); | ||
569 | for (i = 0; i < args->count; i++) { | ||
570 | u32 gpu_timestamp_lo = 0; | ||
571 | u32 gpu_timestamp_hi = 0; | ||
572 | |||
573 | gpu_timestamp_lo = gk20a_readl(g, timer_time_0_r()); | ||
574 | args->samples[i].cpu_timestamp = get_cpu_timestamp(); | ||
575 | rmb(); /* maintain zipper read order */ | ||
576 | gpu_timestamp_hi_new = gk20a_readl(g, timer_time_1_r()); | ||
577 | |||
578 | /* pick the appropriate gpu counter hi bits */ | ||
579 | gpu_timestamp_hi = (gpu_timestamp_lo & (1L << 31)) ? | ||
580 | gpu_timestamp_hi_old : gpu_timestamp_hi_new; | ||
581 | |||
582 | args->samples[i].gpu_timestamp = | ||
583 | ((u64)gpu_timestamp_hi << 32) | (u64)gpu_timestamp_lo; | ||
584 | |||
585 | gpu_timestamp_hi_old = gpu_timestamp_hi_new; | ||
586 | } | ||
587 | |||
588 | end: | ||
589 | gk20a_idle(g->dev); | ||
590 | return err; | ||
591 | } | ||
592 | |||
593 | static int nvgpu_gpu_get_cpu_time_correlation_info( | ||
594 | struct gk20a *g, | ||
595 | struct nvgpu_gpu_get_cpu_time_correlation_info_args *args) | ||
596 | { | ||
597 | int err = 0; | ||
598 | u64 (*get_cpu_timestamp)(void) = NULL; | ||
599 | |||
600 | if (args->count > NVGPU_GPU_GET_CPU_TIME_CORRELATION_INFO_MAX_COUNT) | ||
601 | return -EINVAL; | ||
602 | |||
603 | switch (args->source_id) { | ||
604 | case NVGPU_GPU_GET_CPU_TIME_CORRELATION_INFO_SRC_ID_TSC: | ||
605 | get_cpu_timestamp = get_cpu_timestamp_tsc; | ||
606 | break; | ||
607 | case NVGPU_GPU_GET_CPU_TIME_CORRELATION_INFO_SRC_ID_JIFFIES: | ||
608 | get_cpu_timestamp = get_cpu_timestamp_jiffies; | ||
609 | break; | ||
610 | case NVGPU_GPU_GET_CPU_TIME_CORRELATION_INFO_SRC_ID_TIMEOFDAY: | ||
611 | get_cpu_timestamp = get_cpu_timestamp_timeofday; | ||
612 | break; | ||
613 | default: | ||
614 | gk20a_err(dev_from_gk20a(g), "invalid cpu clock source id\n"); | ||
615 | return -EINVAL; | ||
616 | } | ||
617 | |||
618 | err = get_timestamps_zipper(g, get_cpu_timestamp, args); | ||
619 | return err; | ||
620 | } | ||
621 | |||
533 | long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) | 622 | long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) |
534 | { | 623 | { |
535 | struct platform_device *dev = filp->private_data; | 624 | struct platform_device *dev = filp->private_data; |
@@ -762,6 +851,11 @@ long gk20a_ctrl_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg | |||
762 | (struct nvgpu_gpu_get_buffer_info_args *)buf); | 851 | (struct nvgpu_gpu_get_buffer_info_args *)buf); |
763 | break; | 852 | break; |
764 | 853 | ||
854 | case NVGPU_GPU_IOCTL_GET_CPU_TIME_CORRELATION_INFO: | ||
855 | err = nvgpu_gpu_get_cpu_time_correlation_info(g, | ||
856 | (struct nvgpu_gpu_get_cpu_time_correlation_info_args *)buf); | ||
857 | break; | ||
858 | |||
765 | default: | 859 | default: |
766 | dev_dbg(dev_from_gk20a(g), "unrecognized gpu ioctl cmd: 0x%x", cmd); | 860 | dev_dbg(dev_from_gk20a(g), "unrecognized gpu ioctl cmd: 0x%x", cmd); |
767 | err = -ENOTTY; | 861 | err = -ENOTTY; |
diff --git a/drivers/gpu/nvgpu/gk20a/hw_timer_gk20a.h b/drivers/gpu/nvgpu/gk20a/hw_timer_gk20a.h index 22bc50ac..dbbc914f 100644 --- a/drivers/gpu/nvgpu/gk20a/hw_timer_gk20a.h +++ b/drivers/gpu/nvgpu/gk20a/hw_timer_gk20a.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved. | 2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms and conditions of the GNU General Public License, | 5 | * under the terms and conditions of the GNU General Public License, |
@@ -98,4 +98,12 @@ static inline u32 timer_pri_timeout_fecs_errcode_r(void) | |||
98 | { | 98 | { |
99 | return 0x0000908c; | 99 | return 0x0000908c; |
100 | } | 100 | } |
101 | static inline u32 timer_time_0_r(void) | ||
102 | { | ||
103 | return 0x00009400; | ||
104 | } | ||
105 | static inline u32 timer_time_1_r(void) | ||
106 | { | ||
107 | return 0x00009410; | ||
108 | } | ||
101 | #endif | 109 | #endif |
diff --git a/drivers/gpu/nvgpu/gm20b/hw_timer_gm20b.h b/drivers/gpu/nvgpu/gm20b/hw_timer_gm20b.h index 126f7c8c..06d02522 100644 --- a/drivers/gpu/nvgpu/gm20b/hw_timer_gm20b.h +++ b/drivers/gpu/nvgpu/gm20b/hw_timer_gm20b.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. | 2 | * Copyright (c) 2016, NVIDIA CORPORATION. All rights reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 4 | * This program is free software; you can redistribute it and/or modify it |
5 | * under the terms and conditions of the GNU General Public License, | 5 | * under the terms and conditions of the GNU General Public License, |
@@ -98,4 +98,12 @@ static inline u32 timer_pri_timeout_fecs_errcode_r(void) | |||
98 | { | 98 | { |
99 | return 0x0000908c; | 99 | return 0x0000908c; |
100 | } | 100 | } |
101 | static inline u32 timer_time_0_r(void) | ||
102 | { | ||
103 | return 0x00009400; | ||
104 | } | ||
105 | static inline u32 timer_time_1_r(void) | ||
106 | { | ||
107 | return 0x00009410; | ||
108 | } | ||
101 | #endif | 109 | #endif |