summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/os
diff options
context:
space:
mode:
authorAparna Das <aparnad@nvidia.com>2018-09-11 16:23:40 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-09-20 13:52:18 -0400
commit46477494b2f5d566a0c133746af00a3da4ee6b90 (patch)
treecf5b7e30d26bb493fe291a40fc95614ccab998f7 /drivers/gpu/nvgpu/os
parentc28e73ee2f92d1d287637a22d40d170b42771f96 (diff)
gpu: nvgpu: vgpu: restructure vgpu clk implementation
Move OS agnostic parts of vgpu clk code out of os/linux specific path. This includes implementation sending rpc commands to RM Server. Move Linux specific vgpu clk code to platform vgpu files keeping it consistent with native implementation. Bug 2363882 Jira EVLR-3254 Change-Id: I0aae014ef16415bb356c81e9bfd76bc65206d9fd Signed-off-by: Aparna Das <aparnad@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1820674 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/os')
-rw-r--r--drivers/gpu/nvgpu/os/linux/vgpu/clk_vgpu.c168
-rw-r--r--drivers/gpu/nvgpu/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c7
-rw-r--r--drivers/gpu/nvgpu/os/linux/vgpu/platform_vgpu_tegra.c29
-rw-r--r--drivers/gpu/nvgpu/os/linux/vgpu/platform_vgpu_tegra.h (renamed from drivers/gpu/nvgpu/os/linux/vgpu/clk_vgpu.h)17
-rw-r--r--drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c8
5 files changed, 42 insertions, 187 deletions
diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/clk_vgpu.c b/drivers/gpu/nvgpu/os/linux/vgpu/clk_vgpu.c
deleted file mode 100644
index 9f6017d3..00000000
--- a/drivers/gpu/nvgpu/os/linux/vgpu/clk_vgpu.c
+++ /dev/null
@@ -1,168 +0,0 @@
1/*
2 * Virtualized GPU Clock Interface
3 *
4 * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License,
8 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <nvgpu/vgpu/vgpu.h>
20
21#include "gk20a/gk20a.h"
22#include "clk_vgpu.h"
23#include "ctrl/ctrlclk.h"
24#include "os/linux/platform_gk20a.h"
25
26static unsigned long
27vgpu_freq_table[TEGRA_VGPU_GPU_FREQ_TABLE_SIZE];
28
29static unsigned long vgpu_clk_get_rate(struct gk20a *g, u32 api_domain)
30{
31 struct tegra_vgpu_cmd_msg msg = {};
32 struct tegra_vgpu_gpu_clk_rate_params *p = &msg.params.gpu_clk_rate;
33 int err;
34 unsigned long ret = 0;
35
36 nvgpu_log_fn(g, " ");
37
38 switch (api_domain) {
39 case CTRL_CLK_DOMAIN_GPCCLK:
40 msg.cmd = TEGRA_VGPU_CMD_GET_GPU_CLK_RATE;
41 msg.handle = vgpu_get_handle(g);
42 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
43 err = err ? err : msg.ret;
44 if (err)
45 nvgpu_err(g, "%s failed - %d", __func__, err);
46 else
47 /* return frequency in Hz */
48 ret = p->rate * 1000;
49 break;
50 case CTRL_CLK_DOMAIN_PWRCLK:
51 nvgpu_err(g, "unsupported clock: %u", api_domain);
52 break;
53 default:
54 nvgpu_err(g, "unknown clock: %u", api_domain);
55 break;
56 }
57
58 return ret;
59}
60
61static int vgpu_clk_set_rate(struct gk20a *g,
62 u32 api_domain, unsigned long rate)
63{
64 struct tegra_vgpu_cmd_msg msg = {};
65 struct tegra_vgpu_gpu_clk_rate_params *p = &msg.params.gpu_clk_rate;
66 int err = -EINVAL;
67
68 nvgpu_log_fn(g, " ");
69
70 switch (api_domain) {
71 case CTRL_CLK_DOMAIN_GPCCLK:
72 msg.cmd = TEGRA_VGPU_CMD_SET_GPU_CLK_RATE;
73 msg.handle = vgpu_get_handle(g);
74
75 /* server dvfs framework requires frequency in kHz */
76 p->rate = (u32)(rate / 1000);
77 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
78 err = err ? err : msg.ret;
79 if (err)
80 nvgpu_err(g, "%s failed - %d", __func__, err);
81 break;
82 case CTRL_CLK_DOMAIN_PWRCLK:
83 nvgpu_err(g, "unsupported clock: %u", api_domain);
84 break;
85 default:
86 nvgpu_err(g, "unknown clock: %u", api_domain);
87 break;
88 }
89
90 return err;
91}
92
93static unsigned long vgpu_clk_get_maxrate(struct gk20a *g, u32 api_domain)
94{
95 struct vgpu_priv_data *priv = vgpu_get_priv_data(g);
96
97 return priv->constants.max_freq;
98}
99
100void vgpu_init_clk_support(struct gk20a *g)
101{
102 g->ops.clk.get_rate = vgpu_clk_get_rate;
103 g->ops.clk.set_rate = vgpu_clk_set_rate;
104 g->ops.clk.get_maxrate = vgpu_clk_get_maxrate;
105}
106
107long vgpu_clk_round_rate(struct device *dev, unsigned long rate)
108{
109 /* server will handle frequency rounding */
110 return rate;
111}
112
113int vgpu_clk_get_freqs(struct device *dev,
114 unsigned long **freqs, int *num_freqs)
115{
116 struct gk20a_platform *platform = gk20a_get_platform(dev);
117 struct gk20a *g = platform->g;
118 struct tegra_vgpu_cmd_msg msg = {};
119 struct tegra_vgpu_get_gpu_freq_table_params *p =
120 &msg.params.get_gpu_freq_table;
121 unsigned int i;
122 int err;
123
124 nvgpu_log_fn(g, " ");
125
126 msg.cmd = TEGRA_VGPU_CMD_GET_GPU_FREQ_TABLE;
127 msg.handle = vgpu_get_handle(g);
128
129 p->num_freqs = TEGRA_VGPU_GPU_FREQ_TABLE_SIZE;
130 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
131 err = err ? err : msg.ret;
132 if (err) {
133 nvgpu_err(g, "%s failed - %d", __func__, err);
134 return err;
135 }
136
137 /* return frequency in Hz */
138 for (i = 0; i < p->num_freqs; i++)
139 vgpu_freq_table[i] = p->freqs[i] * 1000;
140
141 *freqs = vgpu_freq_table;
142 *num_freqs = p->num_freqs;
143
144 return 0;
145}
146
147int vgpu_clk_cap_rate(struct device *dev, unsigned long rate)
148{
149 struct gk20a_platform *platform = gk20a_get_platform(dev);
150 struct gk20a *g = platform->g;
151 struct tegra_vgpu_cmd_msg msg = {};
152 struct tegra_vgpu_gpu_clk_rate_params *p = &msg.params.gpu_clk_rate;
153 int err = 0;
154
155 nvgpu_log_fn(g, " ");
156
157 msg.cmd = TEGRA_VGPU_CMD_CAP_GPU_CLK_RATE;
158 msg.handle = vgpu_get_handle(g);
159 p->rate = (u32)rate;
160 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
161 err = err ? err : msg.ret;
162 if (err) {
163 nvgpu_err(g, "%s failed - %d", __func__, err);
164 return err;
165 }
166
167 return 0;
168}
diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c b/drivers/gpu/nvgpu/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c
index 8eada9df..e662877d 100644
--- a/drivers/gpu/nvgpu/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c
+++ b/drivers/gpu/nvgpu/os/linux/vgpu/gv11b/platform_gv11b_vgpu_tegra.c
@@ -19,10 +19,11 @@
19#include <nvgpu/nvhost.h> 19#include <nvgpu/nvhost.h>
20 20
21#include "gk20a/gk20a.h" 21#include "gk20a/gk20a.h"
22#include "os/linux/vgpu/clk_vgpu.h" 22#include "vgpu/clk_vgpu.h"
23#include "os/linux/platform_gk20a.h" 23#include "os/linux/platform_gk20a.h"
24#include "os/linux/os_linux.h" 24#include "os/linux/os_linux.h"
25#include "os/linux/vgpu/vgpu_linux.h" 25#include "os/linux/vgpu/vgpu_linux.h"
26#include "os/linux/vgpu/platform_vgpu_tegra.h"
26 27
27static int gv11b_vgpu_probe(struct device *dev) 28static int gv11b_vgpu_probe(struct device *dev)
28{ 29{
@@ -88,8 +89,8 @@ struct gk20a_platform gv11b_vgpu_tegra_platform = {
88 89
89 .probe = gv11b_vgpu_probe, 90 .probe = gv11b_vgpu_probe,
90 91
91 .clk_round_rate = vgpu_clk_round_rate, 92 .clk_round_rate = vgpu_plat_clk_round_rate,
92 .get_clk_freqs = vgpu_clk_get_freqs, 93 .get_clk_freqs = vgpu_plat_clk_get_freqs,
93 94
94 /* frequency scaling configuration */ 95 /* frequency scaling configuration */
95 .devfreq_governor = "userspace", 96 .devfreq_governor = "userspace",
diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/platform_vgpu_tegra.c b/drivers/gpu/nvgpu/os/linux/vgpu/platform_vgpu_tegra.c
index 44879a45..25b76988 100644
--- a/drivers/gpu/nvgpu/os/linux/vgpu/platform_vgpu_tegra.c
+++ b/drivers/gpu/nvgpu/os/linux/vgpu/platform_vgpu_tegra.c
@@ -20,7 +20,7 @@
20 20
21#include "gk20a/gk20a.h" 21#include "gk20a/gk20a.h"
22#include "os/linux/platform_gk20a.h" 22#include "os/linux/platform_gk20a.h"
23#include "clk_vgpu.h" 23#include "vgpu/clk_vgpu.h"
24#include "vgpu_linux.h" 24#include "vgpu_linux.h"
25 25
26static int gk20a_tegra_probe(struct device *dev) 26static int gk20a_tegra_probe(struct device *dev)
@@ -40,6 +40,29 @@ static int gk20a_tegra_probe(struct device *dev)
40#endif 40#endif
41} 41}
42 42
43long vgpu_plat_clk_round_rate(struct device *dev, unsigned long rate)
44{
45 /* server will handle frequency rounding */
46 return rate;
47}
48
49int vgpu_plat_clk_get_freqs(struct device *dev, unsigned long **freqs,
50 int *num_freqs)
51{
52 struct gk20a_platform *platform = gk20a_get_platform(dev);
53 struct gk20a *g = platform->g;
54
55 return vgpu_clk_get_freqs(g, freqs, num_freqs);
56}
57
58int vgpu_plat_clk_cap_rate(struct device *dev, unsigned long rate)
59{
60 struct gk20a_platform *platform = gk20a_get_platform(dev);
61 struct gk20a *g = platform->g;
62
63 return vgpu_clk_cap_rate(g, rate);
64}
65
43struct gk20a_platform vgpu_tegra_platform = { 66struct gk20a_platform vgpu_tegra_platform = {
44 .has_syncpoints = true, 67 .has_syncpoints = true,
45 .aggressive_sync_destroy_thresh = 64, 68 .aggressive_sync_destroy_thresh = 64,
@@ -60,8 +83,8 @@ struct gk20a_platform vgpu_tegra_platform = {
60 83
61 .probe = gk20a_tegra_probe, 84 .probe = gk20a_tegra_probe,
62 85
63 .clk_round_rate = vgpu_clk_round_rate, 86 .clk_round_rate = vgpu_plat_clk_round_rate,
64 .get_clk_freqs = vgpu_clk_get_freqs, 87 .get_clk_freqs = vgpu_plat_clk_get_freqs,
65 88
66 /* frequency scaling configuration */ 89 /* frequency scaling configuration */
67 .devfreq_governor = "userspace", 90 .devfreq_governor = "userspace",
diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/clk_vgpu.h b/drivers/gpu/nvgpu/os/linux/vgpu/platform_vgpu_tegra.h
index 8d477643..fef346d0 100644
--- a/drivers/gpu/nvgpu/os/linux/vgpu/clk_vgpu.h
+++ b/drivers/gpu/nvgpu/os/linux/vgpu/platform_vgpu_tegra.h
@@ -1,7 +1,5 @@
1/* 1/*
2 * Virtualized GPU Clock Interface 2 * Copyright (c) 2018, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
5 * 3 *
6 * 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
7 * under the terms and conditions of the GNU General Public License, 5 * under the terms and conditions of the GNU General Public License,
@@ -16,12 +14,11 @@
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 15 */
18 16
19#ifndef _CLK_VIRT_H_ 17#ifndef _VGPU_PLATFORM_H_
20#define _CLK_VIRT_H_ 18#define _VGPU_PLATFORM_H_
21 19
22void vgpu_init_clk_support(struct gk20a *g); 20long vgpu_plat_clk_round_rate(struct device *dev, unsigned long rate);
23long vgpu_clk_round_rate(struct device *dev, unsigned long rate); 21int vgpu_plat_clk_get_freqs(struct device *dev, unsigned long **freqs,
24int vgpu_clk_get_freqs(struct device *dev, 22 int *num_freqs);
25 unsigned long **freqs, int *num_freqs); 23int vgpu_plat_clk_cap_rate(struct device *dev, unsigned long rate);
26int vgpu_clk_cap_rate(struct device *dev, unsigned long rate);
27#endif 24#endif
diff --git a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c
index 7cf22d9d..f5628bc1 100644
--- a/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c
+++ b/drivers/gpu/nvgpu/os/linux/vgpu/vgpu_linux.c
@@ -35,7 +35,7 @@
35 35
36#include "vgpu_linux.h" 36#include "vgpu_linux.h"
37#include "vgpu/fecs_trace_vgpu.h" 37#include "vgpu/fecs_trace_vgpu.h"
38#include "clk_vgpu.h" 38#include "vgpu/clk_vgpu.h"
39#include "gk20a/tsg_gk20a.h" 39#include "gk20a/tsg_gk20a.h"
40#include "gk20a/regops_gk20a.h" 40#include "gk20a/regops_gk20a.h"
41#include "gm20b/hal_gm20b.h" 41#include "gm20b/hal_gm20b.h"
@@ -46,6 +46,7 @@
46#include "os/linux/scale.h" 46#include "os/linux/scale.h"
47#include "os/linux/driver_common.h" 47#include "os/linux/driver_common.h"
48#include "os/linux/platform_gk20a.h" 48#include "os/linux/platform_gk20a.h"
49#include "os/linux/vgpu/platform_vgpu_tegra.h"
49 50
50struct vgpu_priv_data *vgpu_get_priv_data(struct gk20a *g) 51struct vgpu_priv_data *vgpu_get_priv_data(struct gk20a *g)
51{ 52{
@@ -244,7 +245,7 @@ static int vgpu_qos_notify(struct notifier_block *nb,
244 nvgpu_log_fn(g, " "); 245 nvgpu_log_fn(g, " ");
245 246
246 max_freq = (u32)pm_qos_read_max_bound(PM_QOS_GPU_FREQ_BOUNDS); 247 max_freq = (u32)pm_qos_read_max_bound(PM_QOS_GPU_FREQ_BOUNDS);
247 err = vgpu_clk_cap_rate(profile->dev, max_freq); 248 err = vgpu_plat_clk_cap_rate(profile->dev, max_freq);
248 if (err) 249 if (err)
249 nvgpu_err(g, "%s failed, err=%d", __func__, err); 250 nvgpu_err(g, "%s failed, err=%d", __func__, err);
250 251
@@ -286,6 +287,7 @@ static void vgpu_pm_qos_remove(struct device *dev)
286static int vgpu_pm_init(struct device *dev) 287static int vgpu_pm_init(struct device *dev)
287{ 288{
288 struct gk20a *g = get_gk20a(dev); 289 struct gk20a *g = get_gk20a(dev);
290 struct gk20a_platform *platform = gk20a_get_platform(dev);
289 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g); 291 struct nvgpu_os_linux *l = nvgpu_os_linux_from_gk20a(g);
290 unsigned long *freqs; 292 unsigned long *freqs;
291 int num_freqs; 293 int num_freqs;
@@ -303,7 +305,7 @@ static int vgpu_pm_init(struct device *dev)
303 305
304 if (l->devfreq) { 306 if (l->devfreq) {
305 /* set min/max frequency based on frequency table */ 307 /* set min/max frequency based on frequency table */
306 err = vgpu_clk_get_freqs(dev, &freqs, &num_freqs); 308 err = platform->get_clk_freqs(dev, &freqs, &num_freqs);
307 if (err) 309 if (err)
308 return err; 310 return err;
309 311