diff options
author | Debarshi Dutta <ddutta@nvidia.com> | 2018-09-04 01:25:33 -0400 |
---|---|---|
committer | mobile promotions <svcmobile_promotions@nvidia.com> | 2018-09-20 13:50:12 -0400 |
commit | 519948a9c664020fd0b37118749faad2dfd73d97 (patch) | |
tree | 1eb57dc393075670331ca89cf366a093d75d3f47 /drivers/gpu/nvgpu/clk/clk_arb.c | |
parent | 1c7258411da89aea5279e9a8d117479928f8bf64 (diff) |
gpu: nvgpu: add igpu support for clk_arbiter.
This patch constructs clk_arbiter specific code for gp10b as well as
gv11b and does the necessary plumbing in the clk_arbiter code. The
changes made are as follows.
1) Constructed clk_arb_gp10b.* files which add support for clk_arb
related HALS including the nvgpu_clk_arb_init and nvgpu_clk_arb_cb.
This doesn't have support for debugfs nor the VFUpdateEvent yet and
consequently no support for arb->notifications.
2) Added gpcclk specific variables corresponding to every gpc2clk in
a given clk_arb related struct.
3) Linux specific support_clk_freq_controller is assigned true in
platform_gp10b.c and platform_gv11b.c files.
4) Incremented the clk_arb_worker.put atomic variable during
worker_deinit so as to allow the worker thread to be stopped.
5) Added the flag clk_arb_events_supported as part of struct
nvgpu_clk_arb. This flag is used to selectively account for the extra
refcounting present in OS specific code i.e.
nvgpu_clk_arb_commit_request_fd. For igpus, the extra refcount is
reduced during nvgpu_clk_arb_release_completion_dev.
Bug 2061372
Change-Id: Id00acb106db2b46e55aa0324034a16a73723c078
Signed-off-by: Debarshi Dutta <ddutta@nvidia.com>
Reviewed-on: https://git-master.nvidia.com/r/1774281
Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com>
Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/clk/clk_arb.c')
-rw-r--r-- | drivers/gpu/nvgpu/clk/clk_arb.c | 38 |
1 files changed, 30 insertions, 8 deletions
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) / |