summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/os/linux/vgpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/os/linux/vgpu')
-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