summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/vgpu/clk_vgpu.c
diff options
context:
space:
mode:
authorSachit Kadle <skadle@nvidia.com>2017-01-24 13:22:13 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-06-19 19:36:26 -0400
commitb3a7c2b305ec6f895dc236f0c5f163bd4cbeb248 (patch)
treea1df93a947d7f5d60a9e57a69d0058d430844c92 /drivers/gpu/nvgpu/vgpu/clk_vgpu.c
parent2535c81c6c916f9f2e1224e17e80d240df569e49 (diff)
gpu: nvgpu: vgpu: add devfreq support
Add devfreq governor support in order to allow frequency scaling in virtualization config. GPU clock frequency operations are re-directed to the server over RPC. Bug 200237433 Change-Id: I1c8e565a4fff36d3456dc72ebb20795b7822650e Signed-off-by: Sachit Kadle <skadle@nvidia.com> Reviewed-on: http://git-master/r/1295542 (cherry picked from commit d5c956fc06697eda3829c67cb22987e538213b29) Reviewed-on: http://git-master/r/1280968 (cherry picked from commit 25e2b3cf7cb5559a6849c0024d42c157564a9be2) Reviewed-on: http://git-master/r/1321835 (cherry picked from commit f871b52fd3f553d6b6375a3c848fbca272ed8e29) Reviewed-on: http://git-master/r/1313468 Tested-by: Aparna Das <aparnad@nvidia.com> Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-by: Richard Zhao <rizhao@nvidia.com> GVS: Gerrit_Virtual_Submit
Diffstat (limited to 'drivers/gpu/nvgpu/vgpu/clk_vgpu.c')
-rw-r--r--drivers/gpu/nvgpu/vgpu/clk_vgpu.c130
1 files changed, 130 insertions, 0 deletions
diff --git a/drivers/gpu/nvgpu/vgpu/clk_vgpu.c b/drivers/gpu/nvgpu/vgpu/clk_vgpu.c
new file mode 100644
index 00000000..fe5533b6
--- /dev/null
+++ b/drivers/gpu/nvgpu/vgpu/clk_vgpu.c
@@ -0,0 +1,130 @@
1/*
2 * Virtualized GPU Clock Interface
3 *
4 * Copyright (c) 2017, 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
16#include "vgpu/vgpu.h"
17#include "vgpu/clk_vgpu.h"
18
19static unsigned long
20vgpu_freq_table[TEGRA_VGPU_GPU_FREQ_TABLE_SIZE];
21
22static unsigned long vgpu_clk_get_rate(struct gk20a *g, u32 api_domain)
23{
24 struct tegra_vgpu_cmd_msg msg = {};
25 struct tegra_vgpu_gpu_clk_rate_params *p = &msg.params.gpu_clk_rate;
26 int err;
27 unsigned long ret = 0;
28
29 gk20a_dbg_fn("");
30
31 switch (api_domain) {
32 case CTRL_CLK_DOMAIN_GPCCLK:
33 msg.cmd = TEGRA_VGPU_CMD_GET_GPU_CLK_RATE;
34 msg.handle = vgpu_get_handle(g);
35 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
36 err = err ? err : msg.ret;
37 if (err)
38 nvgpu_err(g, "%s failed - %d", __func__, err);
39 else
40 /* return frequency in Hz */
41 ret = p->rate * 1000;
42 break;
43 case CTRL_CLK_DOMAIN_PWRCLK:
44 nvgpu_err(g, "unsupported clock: %u", api_domain);
45 break;
46 default:
47 nvgpu_err(g, "unknown clock: %u", api_domain);
48 break;
49 }
50
51 return ret;
52}
53
54static int vgpu_clk_set_rate(struct gk20a *g,
55 u32 api_domain, unsigned long rate)
56{
57 struct tegra_vgpu_cmd_msg msg = {};
58 struct tegra_vgpu_gpu_clk_rate_params *p = &msg.params.gpu_clk_rate;
59 int err = -EINVAL;
60
61 gk20a_dbg_fn("");
62
63 switch (api_domain) {
64 case CTRL_CLK_DOMAIN_GPCCLK:
65 msg.cmd = TEGRA_VGPU_CMD_SET_GPU_CLK_RATE;
66 msg.handle = vgpu_get_handle(g);
67
68 /* server dvfs framework requires frequency in kHz */
69 p->rate = (u32)(rate / 1000);
70 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
71 err = err ? err : msg.ret;
72 if (err)
73 nvgpu_err(g, "%s failed - %d", __func__, err);
74 break;
75 case CTRL_CLK_DOMAIN_PWRCLK:
76 nvgpu_err(g, "unsupported clock: %u", api_domain);
77 break;
78 default:
79 nvgpu_err(g, "unknown clock: %u", api_domain);
80 break;
81 }
82
83 return err;
84}
85
86void vgpu_init_clk_support(struct gk20a *g)
87{
88 g->ops.clk.get_rate = vgpu_clk_get_rate;
89 g->ops.clk.set_rate = vgpu_clk_set_rate;
90}
91
92long vgpu_clk_round_rate(struct device *dev, unsigned long rate)
93{
94 /* server will handle frequency rounding */
95 return rate;
96}
97
98int vgpu_clk_get_freqs(struct device *dev,
99 unsigned long **freqs, int *num_freqs)
100{
101 struct gk20a_platform *platform = gk20a_get_platform(dev);
102 struct gk20a *g = platform->g;
103 struct tegra_vgpu_cmd_msg msg = {};
104 struct tegra_vgpu_get_gpu_freq_table_params *p =
105 &msg.params.get_gpu_freq_table;
106 unsigned int i;
107 int err;
108
109 gk20a_dbg_fn("");
110
111 msg.cmd = TEGRA_VGPU_CMD_GET_GPU_FREQ_TABLE;
112 msg.handle = vgpu_get_handle(g);
113
114 p->num_freqs = TEGRA_VGPU_GPU_FREQ_TABLE_SIZE;
115 err = vgpu_comm_sendrecv(&msg, sizeof(msg), sizeof(msg));
116 err = err ? err : msg.ret;
117 if (err) {
118 nvgpu_err(g, "%s failed - %d", __func__, err);
119 return err;
120 }
121
122 /* return frequency in Hz */
123 for (i = 0; i < p->num_freqs; i++)
124 vgpu_freq_table[i] = p->freqs[i] * 1000;
125
126 *freqs = vgpu_freq_table;
127 *num_freqs = p->num_freqs;
128
129 return 0;
130}