diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/nvgpu/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/Makefile.sources | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/boardobj/boardobj.h | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk_arb.c | 38 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/gk20a.c | 3 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gp106/clk_arb_gp106.c | 9 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gp106/clk_arb_gp106.h | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gp106/hal_gp106.c | 1 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gp10b/clk_arb_gp10b.c | 417 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gp10b/clk_arb_gp10b.h | 39 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gp10b/hal_gp10b.c | 11 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/gv11b/hal_gv11b.c | 11 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/clk_arb.h | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/include/nvgpu/gk20a.h | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/ioctl_clk_arb.c | 11 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c | 2 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/os/linux/platform_gv11b_tegra.c | 2 |
17 files changed, 544 insertions, 9 deletions
diff --git a/drivers/gpu/nvgpu/Makefile b/drivers/gpu/nvgpu/Makefile index d59c3f74..926ce056 100644 --- a/drivers/gpu/nvgpu/Makefile +++ b/drivers/gpu/nvgpu/Makefile | |||
@@ -287,6 +287,7 @@ nvgpu-$(CONFIG_GK20A_CYCLE_STATS) += \ | |||
287 | 287 | ||
288 | nvgpu-y += \ | 288 | nvgpu-y += \ |
289 | gp10b/gr_gp10b.o \ | 289 | gp10b/gr_gp10b.o \ |
290 | gp10b/clk_arb_gp10b.o \ | ||
290 | gp10b/gr_ctx_gp10b.o \ | 291 | gp10b/gr_ctx_gp10b.o \ |
291 | gp10b/ce_gp10b.o \ | 292 | gp10b/ce_gp10b.o \ |
292 | gp10b/fifo_gp10b.o \ | 293 | gp10b/fifo_gp10b.o \ |
diff --git a/drivers/gpu/nvgpu/Makefile.sources b/drivers/gpu/nvgpu/Makefile.sources index fce8ea71..a26f827d 100644 --- a/drivers/gpu/nvgpu/Makefile.sources +++ b/drivers/gpu/nvgpu/Makefile.sources | |||
@@ -176,6 +176,7 @@ srcs := os/posix/nvgpu.c \ | |||
176 | gp10b/pmu_gp10b.c \ | 176 | gp10b/pmu_gp10b.c \ |
177 | gp10b/hal_gp10b.c \ | 177 | gp10b/hal_gp10b.c \ |
178 | gp10b/regops_gp10b.c \ | 178 | gp10b/regops_gp10b.c \ |
179 | gp10b/clk_arb_gp10b.c \ | ||
179 | gp10b/fecs_trace_gp10b.c \ | 180 | gp10b/fecs_trace_gp10b.c \ |
180 | gp10b/gp10b.c \ | 181 | gp10b/gp10b.c \ |
181 | gp10b/ecc_gp10b.c \ | 182 | gp10b/ecc_gp10b.c \ |
diff --git a/drivers/gpu/nvgpu/boardobj/boardobj.h b/drivers/gpu/nvgpu/boardobj/boardobj.h index 4df14aaa..b2ab990c 100644 --- a/drivers/gpu/nvgpu/boardobj/boardobj.h +++ b/drivers/gpu/nvgpu/boardobj/boardobj.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #ifndef _BOARDOBJ_H_ | 23 | #ifndef _BOARDOBJ_H_ |
24 | #define _BOARDOBJ_H_ | 24 | #define _BOARDOBJ_H_ |
25 | 25 | ||
26 | #include <nvgpu/list.h> | ||
26 | #include <nvgpu/pmuif/nvgpu_gpmu_cmdif.h> | 27 | #include <nvgpu/pmuif/nvgpu_gpmu_cmdif.h> |
27 | 28 | ||
28 | #include "ctrl/ctrlboardobj.h" | 29 | #include "ctrl/ctrlboardobj.h" |
diff --git a/drivers/gpu/nvgpu/clk/clk_arb.c b/drivers/gpu/nvgpu/clk/clk_arb.c index 81220c6e..452d9de3 100644 --- a/drivers/gpu/nvgpu/clk/clk_arb.c +++ b/drivers/gpu/nvgpu/clk/clk_arb.c | |||
@@ -56,10 +56,12 @@ int nvgpu_clk_notification_queue_alloc(struct gk20a *g, | |||
56 | 56 | ||
57 | void nvgpu_clk_notification_queue_free(struct gk20a *g, | 57 | void nvgpu_clk_notification_queue_free(struct gk20a *g, |
58 | struct nvgpu_clk_notification_queue *queue) { | 58 | struct nvgpu_clk_notification_queue *queue) { |
59 | nvgpu_kfree(g, queue->notifications); | 59 | if (queue->size > 0) { |
60 | queue->size = 0; | 60 | nvgpu_kfree(g, queue->notifications); |
61 | nvgpu_atomic_set(&queue->head, 0); | 61 | queue->size = 0; |
62 | nvgpu_atomic_set(&queue->tail, 0); | 62 | nvgpu_atomic_set(&queue->head, 0); |
63 | nvgpu_atomic_set(&queue->tail, 0); | ||
64 | } | ||
63 | } | 65 | } |
64 | 66 | ||
65 | static void nvgpu_clk_arb_queue_notification(struct gk20a *g, | 67 | static void nvgpu_clk_arb_queue_notification(struct gk20a *g, |
@@ -651,6 +653,10 @@ static int nvgpu_clk_arb_poll_worker(void *arg) | |||
651 | &worker->wq, | 653 | &worker->wq, |
652 | nvgpu_clk_arb_worker_pending(g, get), 0); | 654 | nvgpu_clk_arb_worker_pending(g, get), 0); |
653 | 655 | ||
656 | if (nvgpu_thread_should_stop(&worker->poll_task)) { | ||
657 | break; | ||
658 | } | ||
659 | |||
654 | if (ret == 0) | 660 | if (ret == 0) |
655 | nvgpu_clk_arb_worker_process(g, &get); | 661 | nvgpu_clk_arb_worker_process(g, &get); |
656 | } | 662 | } |
@@ -782,6 +788,8 @@ void nvgpu_clk_arb_schedule_alarm(struct gk20a *g, u32 alarm) | |||
782 | 788 | ||
783 | static void nvgpu_clk_arb_worker_deinit(struct gk20a *g) | 789 | static void nvgpu_clk_arb_worker_deinit(struct gk20a *g) |
784 | { | 790 | { |
791 | nvgpu_atomic_inc(&g->clk_arb_worker.put); | ||
792 | |||
785 | nvgpu_mutex_acquire(&g->clk_arb_worker.start_lock); | 793 | nvgpu_mutex_acquire(&g->clk_arb_worker.start_lock); |
786 | nvgpu_thread_stop(&g->clk_arb_worker.poll_task); | 794 | nvgpu_thread_stop(&g->clk_arb_worker.poll_task); |
787 | nvgpu_mutex_release(&g->clk_arb_worker.start_lock); | 795 | nvgpu_mutex_release(&g->clk_arb_worker.start_lock); |
@@ -847,6 +855,8 @@ void nvgpu_clk_arb_free_fd(struct nvgpu_ref *refcount) | |||
847 | struct nvgpu_clk_dev, refcount); | 855 | struct nvgpu_clk_dev, refcount); |
848 | struct nvgpu_clk_session *session = dev->session; | 856 | struct nvgpu_clk_session *session = dev->session; |
849 | 857 | ||
858 | nvgpu_clk_notification_queue_free(session->g, &dev->queue); | ||
859 | |||
850 | nvgpu_kfree(session->g, dev); | 860 | nvgpu_kfree(session->g, dev); |
851 | } | 861 | } |
852 | 862 | ||
@@ -964,16 +974,16 @@ int nvgpu_clk_arb_get_arbiter_clk_f_points(struct gk20a *g, | |||
964 | 974 | ||
965 | switch (api_domain) { | 975 | switch (api_domain) { |
966 | case NVGPU_CLK_DOMAIN_GPCCLK: | 976 | case NVGPU_CLK_DOMAIN_GPCCLK: |
967 | err = g->ops.clk.clk_domain_get_f_points(g, | 977 | err = g->ops.clk_arb.get_arbiter_f_points(g, |
968 | CTRL_CLK_DOMAIN_GPC2CLK, max_points, fpoints); | 978 | CTRL_CLK_DOMAIN_GPC2CLK, max_points, fpoints); |
969 | if (err || !fpoints) | 979 | if (err || !fpoints) |
970 | return err; | 980 | return err; |
971 | for (i = 0; i < *max_points; i++) | 981 | for (i = 0; i < *max_points; i++) |
972 | fpoints[i] /= 2; | 982 | fpoints[i] /= 2; |
973 | return 0; | 983 | return 0; |
974 | case NVGPU_CLK_DOMAIN_MCLK: | 984 | case NVGPU_CLK_DOMAIN_MCLK: |
975 | return g->ops.clk.clk_domain_get_f_points(g, | 985 | return g->ops.clk_arb.get_arbiter_f_points(g, |
976 | CTRL_CLK_DOMAIN_MCLK, max_points, fpoints); | 986 | CTRL_CLK_DOMAIN_MCLK, max_points, fpoints); |
977 | default: | 987 | default: |
978 | return -EINVAL; | 988 | return -EINVAL; |
979 | } | 989 | } |
@@ -985,6 +995,10 @@ int nvgpu_clk_arb_get_session_target_mhz(struct nvgpu_clk_session *session, | |||
985 | int err = 0; | 995 | int err = 0; |
986 | struct nvgpu_clk_arb_target *target = session->target; | 996 | struct nvgpu_clk_arb_target *target = session->target; |
987 | 997 | ||
998 | if (!nvgpu_clk_arb_is_valid_domain(session->g, api_domain)) { | ||
999 | return -EINVAL; | ||
1000 | } | ||
1001 | |||
988 | switch (api_domain) { | 1002 | switch (api_domain) { |
989 | case NVGPU_CLK_DOMAIN_MCLK: | 1003 | case NVGPU_CLK_DOMAIN_MCLK: |
990 | *freq_mhz = target->mclk; | 1004 | *freq_mhz = target->mclk; |
@@ -1008,6 +1022,10 @@ int nvgpu_clk_arb_get_arbiter_actual_mhz(struct gk20a *g, | |||
1008 | int err = 0; | 1022 | int err = 0; |
1009 | struct nvgpu_clk_arb_target *actual = arb->actual; | 1023 | struct nvgpu_clk_arb_target *actual = arb->actual; |
1010 | 1024 | ||
1025 | if (!nvgpu_clk_arb_is_valid_domain(g, api_domain)) { | ||
1026 | return -EINVAL; | ||
1027 | } | ||
1028 | |||
1011 | switch (api_domain) { | 1029 | switch (api_domain) { |
1012 | case NVGPU_CLK_DOMAIN_MCLK: | 1030 | case NVGPU_CLK_DOMAIN_MCLK: |
1013 | *freq_mhz = actual->mclk; | 1031 | *freq_mhz = actual->mclk; |
@@ -1027,6 +1045,10 @@ int nvgpu_clk_arb_get_arbiter_actual_mhz(struct gk20a *g, | |||
1027 | int nvgpu_clk_arb_get_arbiter_effective_mhz(struct gk20a *g, | 1045 | int nvgpu_clk_arb_get_arbiter_effective_mhz(struct gk20a *g, |
1028 | u32 api_domain, u16 *freq_mhz) | 1046 | u32 api_domain, u16 *freq_mhz) |
1029 | { | 1047 | { |
1048 | if (!nvgpu_clk_arb_is_valid_domain(g, api_domain)) { | ||
1049 | return -EINVAL; | ||
1050 | } | ||
1051 | |||
1030 | switch (api_domain) { | 1052 | switch (api_domain) { |
1031 | case NVGPU_CLK_DOMAIN_MCLK: | 1053 | case NVGPU_CLK_DOMAIN_MCLK: |
1032 | *freq_mhz = g->ops.clk.measure_freq(g, CTRL_CLK_DOMAIN_MCLK) / | 1054 | *freq_mhz = g->ops.clk.measure_freq(g, CTRL_CLK_DOMAIN_MCLK) / |
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.c b/drivers/gpu/nvgpu/gk20a/gk20a.c index 74fc991d..1caa1dcf 100644 --- a/drivers/gpu/nvgpu/gk20a/gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/gk20a.c | |||
@@ -486,7 +486,8 @@ int gk20a_init_gpu_characteristics(struct gk20a *g) | |||
486 | __nvgpu_set_enabled(g, NVGPU_SUPPORT_USERSPACE_MANAGED_AS, true); | 486 | __nvgpu_set_enabled(g, NVGPU_SUPPORT_USERSPACE_MANAGED_AS, true); |
487 | __nvgpu_set_enabled(g, NVGPU_SUPPORT_TSG, true); | 487 | __nvgpu_set_enabled(g, NVGPU_SUPPORT_TSG, true); |
488 | 488 | ||
489 | if (g->ops.clk_arb.get_arbiter_clk_domains) { | 489 | if (g->ops.clk_arb.get_arbiter_clk_domains != NULL && |
490 | g->ops.clk.support_clk_freq_controller) { | ||
490 | __nvgpu_set_enabled(g, NVGPU_SUPPORT_CLOCK_CONTROLS, true); | 491 | __nvgpu_set_enabled(g, NVGPU_SUPPORT_CLOCK_CONTROLS, true); |
491 | } | 492 | } |
492 | 493 | ||
diff --git a/drivers/gpu/nvgpu/gp106/clk_arb_gp106.c b/drivers/gpu/nvgpu/gp106/clk_arb_gp106.c index 001f2bfc..87fc6a1f 100644 --- a/drivers/gpu/nvgpu/gp106/clk_arb_gp106.c +++ b/drivers/gpu/nvgpu/gp106/clk_arb_gp106.c | |||
@@ -31,6 +31,13 @@ u32 gp106_get_arbiter_clk_domains(struct gk20a *g) | |||
31 | return (CTRL_CLK_DOMAIN_MCLK|CTRL_CLK_DOMAIN_GPC2CLK); | 31 | return (CTRL_CLK_DOMAIN_MCLK|CTRL_CLK_DOMAIN_GPC2CLK); |
32 | } | 32 | } |
33 | 33 | ||
34 | int gp106_get_arbiter_f_points(struct gk20a *g,u32 api_domain, | ||
35 | u32 *num_points, u16 *freqs_in_mhz) | ||
36 | { | ||
37 | return g->ops.clk.clk_domain_get_f_points(g, | ||
38 | api_domain, num_points, freqs_in_mhz); | ||
39 | } | ||
40 | |||
34 | int gp106_get_arbiter_clk_range(struct gk20a *g, u32 api_domain, | 41 | int gp106_get_arbiter_clk_range(struct gk20a *g, u32 api_domain, |
35 | u16 *min_mhz, u16 *max_mhz) | 42 | u16 *min_mhz, u16 *max_mhz) |
36 | { | 43 | { |
@@ -129,6 +136,8 @@ int gp106_init_clk_arbiter(struct gk20a *g) | |||
129 | if (!arb) | 136 | if (!arb) |
130 | return -ENOMEM; | 137 | return -ENOMEM; |
131 | 138 | ||
139 | arb->clk_arb_events_supported = true; | ||
140 | |||
132 | err = nvgpu_mutex_init(&arb->pstate_lock); | 141 | err = nvgpu_mutex_init(&arb->pstate_lock); |
133 | if (err) | 142 | if (err) |
134 | goto mutex_fail; | 143 | goto mutex_fail; |
diff --git a/drivers/gpu/nvgpu/gp106/clk_arb_gp106.h b/drivers/gpu/nvgpu/gp106/clk_arb_gp106.h index e2b2834c..4c1257e1 100644 --- a/drivers/gpu/nvgpu/gp106/clk_arb_gp106.h +++ b/drivers/gpu/nvgpu/gp106/clk_arb_gp106.h | |||
@@ -26,6 +26,8 @@ struct nvgpu_clk_session; | |||
26 | struct nvgpu_clk_arb; | 26 | struct nvgpu_clk_arb; |
27 | 27 | ||
28 | u32 gp106_get_arbiter_clk_domains(struct gk20a *g); | 28 | u32 gp106_get_arbiter_clk_domains(struct gk20a *g); |
29 | int gp106_get_arbiter_f_points(struct gk20a *g,u32 api_domain, | ||
30 | u32 *num_points, u16 *freqs_in_mhz); | ||
29 | int gp106_get_arbiter_clk_range(struct gk20a *g, u32 api_domain, | 31 | int gp106_get_arbiter_clk_range(struct gk20a *g, u32 api_domain, |
30 | u16 *min_mhz, u16 *max_mhz); | 32 | u16 *min_mhz, u16 *max_mhz); |
31 | int gp106_get_arbiter_clk_default(struct gk20a *g, u32 api_domain, | 33 | int gp106_get_arbiter_clk_default(struct gk20a *g, u32 api_domain, |
diff --git a/drivers/gpu/nvgpu/gp106/hal_gp106.c b/drivers/gpu/nvgpu/gp106/hal_gp106.c index ef66be56..d3804f0e 100644 --- a/drivers/gpu/nvgpu/gp106/hal_gp106.c +++ b/drivers/gpu/nvgpu/gp106/hal_gp106.c | |||
@@ -679,6 +679,7 @@ static const struct gpu_ops gp106_ops = { | |||
679 | }, | 679 | }, |
680 | .clk_arb = { | 680 | .clk_arb = { |
681 | .get_arbiter_clk_domains = gp106_get_arbiter_clk_domains, | 681 | .get_arbiter_clk_domains = gp106_get_arbiter_clk_domains, |
682 | .get_arbiter_f_points = gp106_get_arbiter_f_points, | ||
682 | .get_arbiter_clk_range = gp106_get_arbiter_clk_range, | 683 | .get_arbiter_clk_range = gp106_get_arbiter_clk_range, |
683 | .get_arbiter_clk_default = gp106_get_arbiter_clk_default, | 684 | .get_arbiter_clk_default = gp106_get_arbiter_clk_default, |
684 | .get_current_pstate = nvgpu_clk_arb_get_current_pstate, | 685 | .get_current_pstate = nvgpu_clk_arb_get_current_pstate, |
diff --git a/drivers/gpu/nvgpu/gp10b/clk_arb_gp10b.c b/drivers/gpu/nvgpu/gp10b/clk_arb_gp10b.c new file mode 100644 index 00000000..4dcc3ca5 --- /dev/null +++ b/drivers/gpu/nvgpu/gp10b/clk_arb_gp10b.c | |||
@@ -0,0 +1,417 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | * DEALINGS IN THE SOFTWARE. | ||
21 | */ | ||
22 | |||
23 | #include "gk20a/gk20a.h" | ||
24 | #include <nvgpu/clk_arb.h> | ||
25 | |||
26 | #include "clk_arb_gp10b.h" | ||
27 | |||
28 | u32 gp10b_get_arbiter_clk_domains(struct gk20a *g) | ||
29 | { | ||
30 | (void)g; | ||
31 | clk_arb_dbg(g, " "); | ||
32 | return CTRL_CLK_DOMAIN_GPC2CLK; | ||
33 | } | ||
34 | |||
35 | int gp10b_get_arbiter_f_points(struct gk20a *g,u32 api_domain, | ||
36 | u32 *num_points, u16 *freqs_in_mhz) | ||
37 | { | ||
38 | int ret = 0; | ||
39 | u32 i; | ||
40 | bool is_freq_list_available = false; | ||
41 | |||
42 | if (*num_points != 0U) { | ||
43 | is_freq_list_available = true; | ||
44 | } | ||
45 | |||
46 | clk_arb_dbg(g, " "); | ||
47 | |||
48 | switch (api_domain) { | ||
49 | case CTRL_CLK_DOMAIN_GPC2CLK: | ||
50 | ret = g->ops.clk.clk_domain_get_f_points(g, CTRL_CLK_DOMAIN_GPCCLK, | ||
51 | num_points, freqs_in_mhz); | ||
52 | |||
53 | /* multiply by 2 for GPC2CLK */ | ||
54 | if (ret == 0 && is_freq_list_available) { | ||
55 | for (i = 0U; i < *num_points; i++) { | ||
56 | freqs_in_mhz[i] *= 2U; | ||
57 | } | ||
58 | } | ||
59 | break; | ||
60 | default: | ||
61 | ret = -EINVAL; | ||
62 | break; | ||
63 | } | ||
64 | |||
65 | return ret; | ||
66 | } | ||
67 | |||
68 | int gp10b_get_arbiter_clk_range(struct gk20a *g, u32 api_domain, | ||
69 | u16 *min_mhz, u16 *max_mhz) | ||
70 | { | ||
71 | int ret = 0; | ||
72 | |||
73 | clk_arb_dbg(g, " "); | ||
74 | |||
75 | switch (api_domain) { | ||
76 | case CTRL_CLK_DOMAIN_GPC2CLK: | ||
77 | ret = g->ops.clk.get_clk_range(g, CTRL_CLK_DOMAIN_GPCCLK, | ||
78 | min_mhz, max_mhz); | ||
79 | |||
80 | if (ret == 0) { | ||
81 | *min_mhz *= 2U; | ||
82 | *max_mhz *= 2U; | ||
83 | } | ||
84 | break; | ||
85 | |||
86 | default: | ||
87 | ret = -EINVAL; | ||
88 | break; | ||
89 | } | ||
90 | |||
91 | return ret; | ||
92 | } | ||
93 | |||
94 | int gp10b_get_arbiter_clk_default(struct gk20a *g, u32 api_domain, | ||
95 | u16 *default_mhz) | ||
96 | { | ||
97 | int ret = 0; | ||
98 | u16 min_mhz, max_mhz; | ||
99 | |||
100 | clk_arb_dbg(g, " "); | ||
101 | |||
102 | switch (api_domain) { | ||
103 | case CTRL_CLK_DOMAIN_GPC2CLK: | ||
104 | ret = gp10b_get_arbiter_clk_range(g, api_domain, | ||
105 | &min_mhz, &max_mhz); | ||
106 | |||
107 | if (ret == 0) { | ||
108 | *default_mhz = min_mhz; | ||
109 | } | ||
110 | break; | ||
111 | |||
112 | default: | ||
113 | ret = -EINVAL; | ||
114 | break; | ||
115 | } | ||
116 | |||
117 | return ret; | ||
118 | } | ||
119 | |||
120 | int gp10b_init_clk_arbiter(struct gk20a *g) | ||
121 | { | ||
122 | struct nvgpu_clk_arb *arb = NULL; | ||
123 | u16 default_mhz; | ||
124 | int err; | ||
125 | int index; | ||
126 | struct nvgpu_clk_vf_table *table; | ||
127 | |||
128 | clk_arb_dbg(g, " "); | ||
129 | |||
130 | if(g->clk_arb != NULL) { | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | arb = nvgpu_kzalloc(g, sizeof(struct nvgpu_clk_arb)); | ||
135 | if (arb == NULL) { | ||
136 | return -ENOMEM; | ||
137 | } | ||
138 | |||
139 | arb->clk_arb_events_supported = false; | ||
140 | |||
141 | err = nvgpu_mutex_init(&arb->pstate_lock); | ||
142 | if (err != 0) { | ||
143 | goto mutex_fail; | ||
144 | } | ||
145 | |||
146 | nvgpu_spinlock_init(&arb->sessions_lock); | ||
147 | nvgpu_spinlock_init(&arb->users_lock); | ||
148 | nvgpu_spinlock_init(&arb->requests_lock); | ||
149 | |||
150 | arb->gpc2clk_f_points = nvgpu_kcalloc(g, MAX_F_POINTS, sizeof(u16)); | ||
151 | if (arb->gpc2clk_f_points == NULL) { | ||
152 | err = -ENOMEM; | ||
153 | goto init_fail; | ||
154 | } | ||
155 | |||
156 | for (index = 0; index < 2; index++) { | ||
157 | table = &arb->vf_table_pool[index]; | ||
158 | table->gpc2clk_num_points = MAX_F_POINTS; | ||
159 | |||
160 | table->gpc2clk_points = (struct nvgpu_clk_vf_point *) | ||
161 | nvgpu_kcalloc(g, MAX_F_POINTS, | ||
162 | sizeof(struct nvgpu_clk_vf_point)); | ||
163 | if (table->gpc2clk_points == NULL) { | ||
164 | err = -ENOMEM; | ||
165 | goto init_fail; | ||
166 | } | ||
167 | } | ||
168 | |||
169 | g->clk_arb = arb; | ||
170 | arb->g = g; | ||
171 | |||
172 | err = g->ops.clk_arb.get_arbiter_clk_default(g, | ||
173 | CTRL_CLK_DOMAIN_GPC2CLK, &default_mhz); | ||
174 | if (err < 0) { | ||
175 | err = -EINVAL; | ||
176 | goto init_fail; | ||
177 | } | ||
178 | |||
179 | arb->gpc2clk_default_mhz = default_mhz; | ||
180 | |||
181 | err = g->ops.clk_arb.get_arbiter_clk_range(g, CTRL_CLK_DOMAIN_GPC2CLK, | ||
182 | &arb->gpc2clk_min, &arb->gpc2clk_max); | ||
183 | |||
184 | if (err < 0) { | ||
185 | err = -EINVAL; | ||
186 | goto init_fail; | ||
187 | } | ||
188 | |||
189 | arb->actual = &arb->actual_pool[0]; | ||
190 | |||
191 | nvgpu_atomic_set(&arb->req_nr, 0); | ||
192 | |||
193 | nvgpu_atomic64_set(&arb->alarm_mask, 0); | ||
194 | err = nvgpu_clk_notification_queue_alloc(g, &arb->notification_queue, | ||
195 | DEFAULT_EVENT_NUMBER); | ||
196 | if (err < 0) { | ||
197 | goto init_fail; | ||
198 | } | ||
199 | |||
200 | nvgpu_init_list_node(&arb->users); | ||
201 | nvgpu_init_list_node(&arb->sessions); | ||
202 | nvgpu_init_list_node(&arb->requests); | ||
203 | |||
204 | err = nvgpu_cond_init(&arb->request_wq); | ||
205 | if (err < 0) { | ||
206 | goto init_fail; | ||
207 | } | ||
208 | |||
209 | nvgpu_init_list_node(&arb->update_arb_work_item.worker_item); | ||
210 | arb->update_arb_work_item.arb = arb; | ||
211 | arb->update_arb_work_item.item_type = CLK_ARB_WORK_UPDATE_ARB; | ||
212 | |||
213 | err = nvgpu_clk_arb_worker_init(g); | ||
214 | if (err < 0) { | ||
215 | goto init_fail; | ||
216 | } | ||
217 | |||
218 | nvgpu_clk_arb_worker_enqueue(g, &arb->update_arb_work_item); | ||
219 | |||
220 | do { | ||
221 | /* Check that first run is completed */ | ||
222 | nvgpu_smp_mb(); | ||
223 | NVGPU_COND_WAIT_INTERRUPTIBLE(&arb->request_wq, | ||
224 | nvgpu_atomic_read(&arb->req_nr) != 0, 0); | ||
225 | } while (nvgpu_atomic_read(&arb->req_nr) == 0); | ||
226 | |||
227 | |||
228 | return arb->status; | ||
229 | |||
230 | init_fail: | ||
231 | nvgpu_kfree(g, arb->gpc2clk_f_points); | ||
232 | |||
233 | for (index = 0; index < 2; index++) { | ||
234 | nvgpu_kfree(g, arb->vf_table_pool[index].gpc2clk_points); | ||
235 | } | ||
236 | |||
237 | nvgpu_mutex_destroy(&arb->pstate_lock); | ||
238 | |||
239 | mutex_fail: | ||
240 | nvgpu_kfree(g, arb); | ||
241 | |||
242 | return err; | ||
243 | } | ||
244 | |||
245 | void gp10b_clk_arb_run_arbiter_cb(struct nvgpu_clk_arb *arb) | ||
246 | { | ||
247 | struct nvgpu_clk_session *session; | ||
248 | struct nvgpu_clk_dev *dev; | ||
249 | struct nvgpu_clk_dev *tmp; | ||
250 | struct nvgpu_clk_arb_target *target, *actual; | ||
251 | struct gk20a *g = arb->g; | ||
252 | |||
253 | bool gpc2clk_set; | ||
254 | |||
255 | int status = 0; | ||
256 | unsigned long rounded_rate = 0; | ||
257 | |||
258 | u16 gpc2clk_target, gpc2clk_session_target; | ||
259 | |||
260 | clk_arb_dbg(g, " "); | ||
261 | |||
262 | /* Only one arbiter should be running */ | ||
263 | gpc2clk_target = 0; | ||
264 | |||
265 | nvgpu_spinlock_acquire(&arb->sessions_lock); | ||
266 | nvgpu_list_for_each_entry(session, &arb->sessions, | ||
267 | nvgpu_clk_session, link) { | ||
268 | if (session->zombie) { | ||
269 | continue; | ||
270 | } | ||
271 | gpc2clk_set = false; | ||
272 | target = (session->target == &session->target_pool[0] ? | ||
273 | &session->target_pool[1] : | ||
274 | &session->target_pool[0]); | ||
275 | nvgpu_spinlock_acquire(&session->session_lock); | ||
276 | if (nvgpu_list_empty(&session->targets) == 0) { | ||
277 | /* Copy over state */ | ||
278 | target->gpc2clk = session->target->gpc2clk; | ||
279 | /* Query the latest committed request */ | ||
280 | nvgpu_list_for_each_entry_safe(dev, tmp, &session->targets, | ||
281 | nvgpu_clk_dev, node) { | ||
282 | if (!gpc2clk_set && | ||
283 | dev->gpc2clk_target_mhz != (u16)0) { | ||
284 | target->gpc2clk = | ||
285 | dev->gpc2clk_target_mhz; | ||
286 | gpc2clk_set = true; | ||
287 | } | ||
288 | nvgpu_ref_get(&dev->refcount); | ||
289 | nvgpu_list_del(&dev->node); | ||
290 | nvgpu_spinlock_acquire(&arb->requests_lock); | ||
291 | nvgpu_list_add(&dev->node, &arb->requests); | ||
292 | nvgpu_spinlock_release(&arb->requests_lock); | ||
293 | } | ||
294 | session->target = target; | ||
295 | } | ||
296 | nvgpu_spinlock_release(&session->session_lock); | ||
297 | |||
298 | gpc2clk_target = | ||
299 | gpc2clk_target > session->target->gpc2clk ? | ||
300 | gpc2clk_target : session->target->gpc2clk; | ||
301 | } | ||
302 | nvgpu_spinlock_release(&arb->sessions_lock); | ||
303 | |||
304 | gpc2clk_target = (gpc2clk_target > (u16)0) ? gpc2clk_target : | ||
305 | arb->gpc2clk_default_mhz; | ||
306 | |||
307 | if (gpc2clk_target < arb->gpc2clk_min) { | ||
308 | gpc2clk_target = arb->gpc2clk_min; | ||
309 | } | ||
310 | |||
311 | if (gpc2clk_target > arb->gpc2clk_max) { | ||
312 | gpc2clk_target = arb->gpc2clk_max; | ||
313 | } | ||
314 | |||
315 | gpc2clk_session_target = gpc2clk_target; | ||
316 | |||
317 | if (arb->actual->gpc2clk == gpc2clk_target) { | ||
318 | nvgpu_atomic_inc(&arb->req_nr); | ||
319 | nvgpu_cond_signal_interruptible(&arb->request_wq); | ||
320 | goto exit_arb; | ||
321 | } | ||
322 | |||
323 | nvgpu_mutex_acquire(&arb->pstate_lock); | ||
324 | |||
325 | /* get the rounded_rate in terms of Hz for igpu | ||
326 | * pass (gpcclk) freq = (gpc2clk) freq / 2 | ||
327 | */ | ||
328 | status = g->ops.clk.clk_get_round_rate(g, | ||
329 | CTRL_CLK_DOMAIN_GPCCLK, (gpc2clk_session_target/2) * 1000000UL, &rounded_rate); | ||
330 | |||
331 | clk_arb_dbg(g, "rounded_rate: %lu\n", | ||
332 | rounded_rate); | ||
333 | |||
334 | if (status < 0) { | ||
335 | arb->status = status; | ||
336 | nvgpu_mutex_release(&arb->pstate_lock); | ||
337 | |||
338 | /* make status visible */ | ||
339 | nvgpu_smp_mb(); | ||
340 | nvgpu_atomic_inc(&arb->req_nr); | ||
341 | nvgpu_cond_signal_interruptible(&arb->request_wq); | ||
342 | goto exit_arb; | ||
343 | } | ||
344 | |||
345 | /* the igpu set_rate accepts freq in Hz */ | ||
346 | status = g->ops.clk.set_rate(g, CTRL_CLK_DOMAIN_GPCCLK, rounded_rate); | ||
347 | |||
348 | if (status < 0) { | ||
349 | arb->status = status; | ||
350 | nvgpu_mutex_release(&arb->pstate_lock); | ||
351 | |||
352 | /* make status visible */ | ||
353 | nvgpu_smp_mb(); | ||
354 | nvgpu_atomic_inc(&arb->req_nr); | ||
355 | nvgpu_cond_signal_interruptible(&arb->request_wq); | ||
356 | goto exit_arb; | ||
357 | } | ||
358 | |||
359 | actual = ((NV_ACCESS_ONCE(arb->actual)) == &arb->actual_pool[0] ? | ||
360 | &arb->actual_pool[1] : &arb->actual_pool[0]); | ||
361 | |||
362 | /* do not reorder this pointer */ | ||
363 | nvgpu_smp_rmb(); | ||
364 | actual->gpc2clk = gpc2clk_target; | ||
365 | arb->status = 0; | ||
366 | |||
367 | /* Make changes visible to other threads */ | ||
368 | nvgpu_smp_wmb(); | ||
369 | arb->actual = actual; | ||
370 | |||
371 | /* status must be visible before atomic inc */ | ||
372 | nvgpu_smp_wmb(); | ||
373 | nvgpu_atomic_inc(&arb->req_nr); | ||
374 | |||
375 | /* Unlock pstate change for PG */ | ||
376 | nvgpu_mutex_release(&arb->pstate_lock); | ||
377 | |||
378 | nvgpu_cond_signal_interruptible(&arb->request_wq); | ||
379 | |||
380 | exit_arb: | ||
381 | if (status < 0) { | ||
382 | nvgpu_err(g, "Error in arbiter update"); | ||
383 | } | ||
384 | |||
385 | /* notify completion for all requests */ | ||
386 | nvgpu_spinlock_acquire(&arb->requests_lock); | ||
387 | nvgpu_list_for_each_entry_safe(dev, tmp, &arb->requests, | ||
388 | nvgpu_clk_dev, node) { | ||
389 | nvgpu_atomic_set(&dev->poll_mask, NVGPU_POLLIN | NVGPU_POLLRDNORM); | ||
390 | nvgpu_clk_arb_event_post_event(dev); | ||
391 | nvgpu_ref_put(&dev->refcount, nvgpu_clk_arb_free_fd); | ||
392 | nvgpu_list_del(&dev->node); | ||
393 | } | ||
394 | nvgpu_spinlock_release(&arb->requests_lock); | ||
395 | |||
396 | clk_arb_dbg(g, "done"); | ||
397 | } | ||
398 | |||
399 | void gp10b_clk_arb_cleanup(struct nvgpu_clk_arb *arb) | ||
400 | { | ||
401 | struct gk20a *g = arb->g; | ||
402 | int index; | ||
403 | |||
404 | nvgpu_kfree(g, arb->gpc2clk_f_points); | ||
405 | nvgpu_kfree(g, arb->mclk_f_points); | ||
406 | |||
407 | for (index = 0; index < 2; index++) { | ||
408 | nvgpu_kfree(g, | ||
409 | arb->vf_table_pool[index].gpc2clk_points); | ||
410 | nvgpu_kfree(g, arb->vf_table_pool[index].mclk_points); | ||
411 | } | ||
412 | |||
413 | nvgpu_mutex_destroy(&g->clk_arb->pstate_lock); | ||
414 | nvgpu_kfree(g, g->clk_arb); | ||
415 | |||
416 | g->clk_arb = NULL; | ||
417 | } \ No newline at end of file | ||
diff --git a/drivers/gpu/nvgpu/gp10b/clk_arb_gp10b.h b/drivers/gpu/nvgpu/gp10b/clk_arb_gp10b.h new file mode 100644 index 00000000..6b9966c5 --- /dev/null +++ b/drivers/gpu/nvgpu/gp10b/clk_arb_gp10b.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
20 | * DEALINGS IN THE SOFTWARE. | ||
21 | */ | ||
22 | #ifndef CLK_ARB_GP10B_H | ||
23 | #define CLK_ARB_GP10B_H | ||
24 | |||
25 | struct nvgpu_clk_session; | ||
26 | struct nvgpu_clk_arb; | ||
27 | |||
28 | u32 gp10b_get_arbiter_clk_domains(struct gk20a *g); | ||
29 | int gp10b_get_arbiter_f_points(struct gk20a *g,u32 api_domain, | ||
30 | u32 *num_points, u16 *freqs_in_mhz); | ||
31 | int gp10b_get_arbiter_clk_range(struct gk20a *g, u32 api_domain, | ||
32 | u16 *min_mhz, u16 *max_mhz); | ||
33 | int gp10b_get_arbiter_clk_default(struct gk20a *g, u32 api_domain, | ||
34 | u16 *default_mhz); | ||
35 | int gp10b_init_clk_arbiter(struct gk20a *g); | ||
36 | void gp10b_clk_arb_run_arbiter_cb(struct nvgpu_clk_arb *arb); | ||
37 | void gp10b_clk_arb_cleanup(struct nvgpu_clk_arb *arb); | ||
38 | |||
39 | #endif /* CLK_ARB_GP106_H */ | ||
diff --git a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c index 769cab74..1f9e84d3 100644 --- a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c +++ b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c | |||
@@ -68,6 +68,7 @@ | |||
68 | #include "gp10b/fifo_gp10b.h" | 68 | #include "gp10b/fifo_gp10b.h" |
69 | #include "gp10b/regops_gp10b.h" | 69 | #include "gp10b/regops_gp10b.h" |
70 | #include "gp10b/ecc_gp10b.h" | 70 | #include "gp10b/ecc_gp10b.h" |
71 | #include "gp10b/clk_arb_gp10b.h" | ||
71 | 72 | ||
72 | #include "gm20b/gr_gm20b.h" | 73 | #include "gm20b/gr_gm20b.h" |
73 | #include "gm20b/fifo_gm20b.h" | 74 | #include "gm20b/fifo_gm20b.h" |
@@ -611,6 +612,15 @@ static const struct gpu_ops gp10b_ops = { | |||
611 | .get_irqdest = gk20a_pmu_get_irqdest, | 612 | .get_irqdest = gk20a_pmu_get_irqdest, |
612 | .is_debug_mode_enabled = gm20b_pmu_is_debug_mode_en, | 613 | .is_debug_mode_enabled = gm20b_pmu_is_debug_mode_en, |
613 | }, | 614 | }, |
615 | .clk_arb = { | ||
616 | .get_arbiter_clk_domains = gp10b_get_arbiter_clk_domains, | ||
617 | .get_arbiter_f_points = gp10b_get_arbiter_f_points, | ||
618 | .get_arbiter_clk_range = gp10b_get_arbiter_clk_range, | ||
619 | .get_arbiter_clk_default = gp10b_get_arbiter_clk_default, | ||
620 | .arbiter_clk_init = gp10b_init_clk_arbiter, | ||
621 | .clk_arb_run_arbiter_cb = gp10b_clk_arb_run_arbiter_cb, | ||
622 | .clk_arb_cleanup = gp10b_clk_arb_cleanup, | ||
623 | }, | ||
614 | .regops = { | 624 | .regops = { |
615 | .exec_regops = exec_regops_gk20a, | 625 | .exec_regops = exec_regops_gk20a, |
616 | .get_global_whitelist_ranges = | 626 | .get_global_whitelist_ranges = |
@@ -735,6 +745,7 @@ int gp10b_init_hal(struct gk20a *g) | |||
735 | gops->pramin = gp10b_ops.pramin; | 745 | gops->pramin = gp10b_ops.pramin; |
736 | gops->therm = gp10b_ops.therm; | 746 | gops->therm = gp10b_ops.therm; |
737 | gops->pmu = gp10b_ops.pmu; | 747 | gops->pmu = gp10b_ops.pmu; |
748 | gops->clk_arb = gp10b_ops.clk_arb; | ||
738 | gops->regops = gp10b_ops.regops; | 749 | gops->regops = gp10b_ops.regops; |
739 | gops->mc = gp10b_ops.mc; | 750 | gops->mc = gp10b_ops.mc; |
740 | gops->debug = gp10b_ops.debug; | 751 | gops->debug = gp10b_ops.debug; |
diff --git a/drivers/gpu/nvgpu/gv11b/hal_gv11b.c b/drivers/gpu/nvgpu/gv11b/hal_gv11b.c index 591a7786..9444002b 100644 --- a/drivers/gpu/nvgpu/gv11b/hal_gv11b.c +++ b/drivers/gpu/nvgpu/gv11b/hal_gv11b.c | |||
@@ -67,6 +67,7 @@ | |||
67 | #include "gp10b/mm_gp10b.h" | 67 | #include "gp10b/mm_gp10b.h" |
68 | #include "gp10b/pmu_gp10b.h" | 68 | #include "gp10b/pmu_gp10b.h" |
69 | #include "gp10b/gr_gp10b.h" | 69 | #include "gp10b/gr_gp10b.h" |
70 | #include "gp10b/clk_arb_gp10b.h" | ||
70 | 71 | ||
71 | #include "gp106/pmu_gp106.h" | 72 | #include "gp106/pmu_gp106.h" |
72 | #include "gp106/acr_gp106.h" | 73 | #include "gp106/acr_gp106.h" |
@@ -708,6 +709,15 @@ static const struct gpu_ops gv11b_ops = { | |||
708 | .handle_ext_irq = gv11b_pmu_handle_ext_irq, | 709 | .handle_ext_irq = gv11b_pmu_handle_ext_irq, |
709 | .is_debug_mode_enabled = gm20b_pmu_is_debug_mode_en, | 710 | .is_debug_mode_enabled = gm20b_pmu_is_debug_mode_en, |
710 | }, | 711 | }, |
712 | .clk_arb = { | ||
713 | .get_arbiter_clk_domains = gp10b_get_arbiter_clk_domains, | ||
714 | .get_arbiter_f_points = gp10b_get_arbiter_f_points, | ||
715 | .get_arbiter_clk_range = gp10b_get_arbiter_clk_range, | ||
716 | .get_arbiter_clk_default = gp10b_get_arbiter_clk_default, | ||
717 | .arbiter_clk_init = gp10b_init_clk_arbiter, | ||
718 | .clk_arb_run_arbiter_cb = gp10b_clk_arb_run_arbiter_cb, | ||
719 | .clk_arb_cleanup = gp10b_clk_arb_cleanup, | ||
720 | }, | ||
711 | .regops = { | 721 | .regops = { |
712 | .exec_regops = exec_regops_gk20a, | 722 | .exec_regops = exec_regops_gk20a, |
713 | .get_global_whitelist_ranges = | 723 | .get_global_whitelist_ranges = |
@@ -847,6 +857,7 @@ int gv11b_init_hal(struct gk20a *g) | |||
847 | gops->falcon = gv11b_ops.falcon; | 857 | gops->falcon = gv11b_ops.falcon; |
848 | gops->priv_ring = gv11b_ops.priv_ring; | 858 | gops->priv_ring = gv11b_ops.priv_ring; |
849 | gops->fuse = gv11b_ops.fuse; | 859 | gops->fuse = gv11b_ops.fuse; |
860 | gops->clk_arb = gv11b_ops.clk_arb; | ||
850 | 861 | ||
851 | /* Lone functions */ | 862 | /* Lone functions */ |
852 | gops->chip_init_gpu_characteristics = | 863 | gops->chip_init_gpu_characteristics = |
diff --git a/drivers/gpu/nvgpu/include/nvgpu/clk_arb.h b/drivers/gpu/nvgpu/include/nvgpu/clk_arb.h index 46952f1c..81b1df1b 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/clk_arb.h +++ b/drivers/gpu/nvgpu/include/nvgpu/clk_arb.h | |||
@@ -217,6 +217,8 @@ struct nvgpu_clk_arb { | |||
217 | u16 *gpc2clk_f_points; | 217 | u16 *gpc2clk_f_points; |
218 | u32 gpc2clk_f_numpoints; | 218 | u32 gpc2clk_f_numpoints; |
219 | 219 | ||
220 | bool clk_arb_events_supported; | ||
221 | |||
220 | nvgpu_atomic64_t alarm_mask; | 222 | nvgpu_atomic64_t alarm_mask; |
221 | struct nvgpu_clk_notification_queue notification_queue; | 223 | struct nvgpu_clk_notification_queue notification_queue; |
222 | 224 | ||
diff --git a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h index 5821f742..b8ca5754 100644 --- a/drivers/gpu/nvgpu/include/nvgpu/gk20a.h +++ b/drivers/gpu/nvgpu/include/nvgpu/gk20a.h | |||
@@ -1117,6 +1117,8 @@ struct gpu_ops { | |||
1117 | struct { | 1117 | struct { |
1118 | int (*arbiter_clk_init)(struct gk20a *g); | 1118 | int (*arbiter_clk_init)(struct gk20a *g); |
1119 | u32 (*get_arbiter_clk_domains)(struct gk20a *g); | 1119 | u32 (*get_arbiter_clk_domains)(struct gk20a *g); |
1120 | int (*get_arbiter_f_points)(struct gk20a *g,u32 api_domain, | ||
1121 | u32 *num_points, u16 *freqs_in_mhz); | ||
1120 | int (*get_arbiter_clk_range)(struct gk20a *g, u32 api_domain, | 1122 | int (*get_arbiter_clk_range)(struct gk20a *g, u32 api_domain, |
1121 | u16 *min_mhz, u16 *max_mhz); | 1123 | u16 *min_mhz, u16 *max_mhz); |
1122 | int (*get_arbiter_clk_default)(struct gk20a *g, u32 api_domain, | 1124 | int (*get_arbiter_clk_default)(struct gk20a *g, u32 api_domain, |
diff --git a/drivers/gpu/nvgpu/os/linux/ioctl_clk_arb.c b/drivers/gpu/nvgpu/os/linux/ioctl_clk_arb.c index 501b5f93..2d9946b1 100644 --- a/drivers/gpu/nvgpu/os/linux/ioctl_clk_arb.c +++ b/drivers/gpu/nvgpu/os/linux/ioctl_clk_arb.c | |||
@@ -55,6 +55,13 @@ static int nvgpu_clk_arb_release_completion_dev(struct inode *inode, | |||
55 | 55 | ||
56 | clk_arb_dbg(session->g, " "); | 56 | clk_arb_dbg(session->g, " "); |
57 | 57 | ||
58 | /* This is done to account for the extra refcount taken in | ||
59 | * nvgpu_clk_arb_commit_request_fd without events support in iGPU | ||
60 | */ | ||
61 | if (!session->g->clk_arb->clk_arb_events_supported) { | ||
62 | nvgpu_ref_put(&dev->refcount, nvgpu_clk_arb_free_fd); | ||
63 | } | ||
64 | |||
58 | nvgpu_ref_put(&session->refcount, nvgpu_clk_arb_free_session); | 65 | nvgpu_ref_put(&session->refcount, nvgpu_clk_arb_free_session); |
59 | nvgpu_ref_put(&dev->refcount, nvgpu_clk_arb_free_fd); | 66 | nvgpu_ref_put(&dev->refcount, nvgpu_clk_arb_free_fd); |
60 | return 0; | 67 | return 0; |
@@ -425,6 +432,10 @@ int nvgpu_clk_arb_commit_request_fd(struct gk20a *g, | |||
425 | err = -EINVAL; | 432 | err = -EINVAL; |
426 | goto fdput_fd; | 433 | goto fdput_fd; |
427 | } | 434 | } |
435 | |||
436 | clk_arb_dbg(g, "requested target = %u\n", | ||
437 | (u32)dev->gpc2clk_target_mhz); | ||
438 | |||
428 | nvgpu_ref_get(&dev->refcount); | 439 | nvgpu_ref_get(&dev->refcount); |
429 | nvgpu_spinlock_acquire(&session->session_lock); | 440 | nvgpu_spinlock_acquire(&session->session_lock); |
430 | nvgpu_list_add(&dev->node, &session->targets); | 441 | nvgpu_list_add(&dev->node, &session->targets); |
diff --git a/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c b/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c index 5fdcb05c..a792bfcb 100644 --- a/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c +++ b/drivers/gpu/nvgpu/os/linux/platform_gp10b_tegra.c | |||
@@ -171,6 +171,8 @@ static int gp10b_tegra_probe(struct device *dev) | |||
171 | 171 | ||
172 | nvgpu_mutex_init(&platform->clk_get_freq_lock); | 172 | nvgpu_mutex_init(&platform->clk_get_freq_lock); |
173 | 173 | ||
174 | platform->g->ops.clk.support_clk_freq_controller = true; | ||
175 | |||
174 | return 0; | 176 | return 0; |
175 | } | 177 | } |
176 | 178 | ||
diff --git a/drivers/gpu/nvgpu/os/linux/platform_gv11b_tegra.c b/drivers/gpu/nvgpu/os/linux/platform_gv11b_tegra.c index b055eb6e..ec93b4c3 100644 --- a/drivers/gpu/nvgpu/os/linux/platform_gv11b_tegra.c +++ b/drivers/gpu/nvgpu/os/linux/platform_gv11b_tegra.c | |||
@@ -99,6 +99,8 @@ static int gv11b_tegra_probe(struct device *dev) | |||
99 | 99 | ||
100 | nvgpu_mutex_init(&platform->clk_get_freq_lock); | 100 | nvgpu_mutex_init(&platform->clk_get_freq_lock); |
101 | 101 | ||
102 | platform->g->ops.clk.support_clk_freq_controller = true; | ||
103 | |||
102 | return 0; | 104 | return 0; |
103 | } | 105 | } |
104 | 106 | ||