aboutsummaryrefslogtreecommitdiffstats
path: root/include/os/linux/platform_gv11b_tegra.c
diff options
context:
space:
mode:
Diffstat (limited to 'include/os/linux/platform_gv11b_tegra.c')
-rw-r--r--include/os/linux/platform_gv11b_tegra.c331
1 files changed, 331 insertions, 0 deletions
diff --git a/include/os/linux/platform_gv11b_tegra.c b/include/os/linux/platform_gv11b_tegra.c
new file mode 100644
index 0000000..6c9d0f5
--- /dev/null
+++ b/include/os/linux/platform_gv11b_tegra.c
@@ -0,0 +1,331 @@
1/*
2 * GV11B Tegra Platform Interface
3 *
4 * Copyright (c) 2016-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 <linux/of_platform.h>
20#include <linux/debugfs.h>
21#include <linux/dma-buf.h>
22#include <linux/nvmap.h>
23#include <linux/reset.h>
24#include <linux/hashtable.h>
25#include <linux/clk.h>
26#include <linux/platform/tegra/emc_bwmgr.h>
27
28#include <nvgpu/gk20a.h>
29#include <nvgpu/nvhost.h>
30
31#include <uapi/linux/nvgpu.h>
32
33#include <soc/tegra/tegra_bpmp.h>
34#include <soc/tegra/tegra_powergate.h>
35
36#include "platform_gk20a.h"
37#include "clk.h"
38#include "scale.h"
39
40#include "platform_gp10b.h"
41#include "platform_gp10b_tegra.h"
42
43#include "os_linux.h"
44#include "platform_gk20a_tegra.h"
45#include "gv11b/gr_gv11b.h"
46
47#define EMC3D_GV11B_RATIO 500
48
49void gv11b_tegra_scale_init(struct device *dev)
50{
51 struct gk20a_platform *platform = gk20a_get_platform(dev);
52 struct gk20a_scale_profile *profile = platform->g->scale_profile;
53
54 if (!profile)
55 return;
56
57 platform->g->emc3d_ratio = EMC3D_GV11B_RATIO;
58
59 gp10b_tegra_scale_init(dev);
60}
61
62static void gv11b_tegra_scale_exit(struct device *dev)
63{
64 struct gk20a_platform *platform = gk20a_get_platform(dev);
65 struct gk20a_scale_profile *profile = platform->g->scale_profile;
66
67 if (profile)
68 tegra_bwmgr_unregister(
69 (struct tegra_bwmgr_client *)profile->private_data);
70}
71
72static int gv11b_tegra_probe(struct device *dev)
73{
74 struct gk20a_platform *platform = dev_get_drvdata(dev);
75 int err;
76 bool joint_xpu_rail = false;
77 struct gk20a *g = platform->g;
78
79 err = nvgpu_nvhost_syncpt_init(platform->g);
80 if (err) {
81 if (err != -ENOSYS)
82 return err;
83 }
84
85 err = gk20a_tegra_init_secure_alloc(platform);
86 if (err)
87 return err;
88
89 platform->disable_bigpage = !device_is_iommuable(dev);
90
91 platform->g->gr.ctx_vars.dump_ctxsw_stats_on_channel_close
92 = false;
93 platform->g->gr.ctx_vars.dump_ctxsw_stats_on_channel_close
94 = false;
95
96 platform->g->gr.ctx_vars.force_preemption_gfxp = false;
97 platform->g->gr.ctx_vars.force_preemption_cilp = false;
98
99#ifdef CONFIG_OF
100 joint_xpu_rail = of_property_read_bool(of_chosen,
101 "nvidia,tegra-joint_xpu_rail");
102#endif
103
104 if (joint_xpu_rail) {
105 nvgpu_log_info(g, "XPU rails are joint\n");
106 platform->can_railgate_init = false;
107 __nvgpu_set_enabled(g, NVGPU_CAN_RAILGATE, false);
108 }
109
110 gp10b_tegra_get_clocks(dev);
111 nvgpu_linux_init_clk_support(platform->g);
112
113 nvgpu_mutex_init(&platform->clk_get_freq_lock);
114
115 platform->g->ops.clk.support_clk_freq_controller = true;
116
117 return 0;
118}
119
120static int gv11b_tegra_late_probe(struct device *dev)
121{
122 return 0;
123}
124
125
126static int gv11b_tegra_remove(struct device *dev)
127{
128 struct gk20a_platform *platform = gk20a_get_platform(dev);
129
130 gv11b_tegra_scale_exit(dev);
131
132#ifdef CONFIG_TEGRA_GK20A_NVHOST
133 nvgpu_free_nvhost_dev(get_gk20a(dev));
134#endif
135
136 nvgpu_mutex_destroy(&platform->clk_get_freq_lock);
137
138 return 0;
139}
140
141static bool gv11b_tegra_is_railgated(struct device *dev)
142{
143 bool ret = false;
144#ifdef TEGRA194_POWER_DOMAIN_GPU
145 struct gk20a *g = get_gk20a(dev);
146
147 if (tegra_bpmp_running()) {
148 nvgpu_log(g, gpu_dbg_info, "bpmp running");
149 ret = !tegra_powergate_is_powered(TEGRA194_POWER_DOMAIN_GPU);
150
151 nvgpu_log(g, gpu_dbg_info, "railgated? %s", ret ? "yes" : "no");
152 } else {
153 nvgpu_log(g, gpu_dbg_info, "bpmp not running");
154 }
155#endif
156 return ret;
157}
158
159static int gv11b_tegra_railgate(struct device *dev)
160{
161#ifdef TEGRA194_POWER_DOMAIN_GPU
162 struct gk20a_platform *platform = gk20a_get_platform(dev);
163 struct gk20a_scale_profile *profile = platform->g->scale_profile;
164 struct gk20a *g = get_gk20a(dev);
165 int i;
166
167 /* remove emc frequency floor */
168 if (profile)
169 tegra_bwmgr_set_emc(
170 (struct tegra_bwmgr_client *)profile->private_data,
171 0, TEGRA_BWMGR_SET_EMC_FLOOR);
172
173 if (tegra_bpmp_running()) {
174 nvgpu_log(g, gpu_dbg_info, "bpmp running");
175 if (!tegra_powergate_is_powered(TEGRA194_POWER_DOMAIN_GPU)) {
176 nvgpu_log(g, gpu_dbg_info, "powergate is not powered");
177 return 0;
178 }
179 nvgpu_log(g, gpu_dbg_info, "clk_disable_unprepare");
180 for (i = 0; i < platform->num_clks; i++) {
181 if (platform->clk[i])
182 clk_disable_unprepare(platform->clk[i]);
183 }
184 nvgpu_log(g, gpu_dbg_info, "powergate_partition");
185 tegra_powergate_partition(TEGRA194_POWER_DOMAIN_GPU);
186 } else {
187 nvgpu_log(g, gpu_dbg_info, "bpmp not running");
188 }
189#endif
190 return 0;
191}
192
193static int gv11b_tegra_unrailgate(struct device *dev)
194{
195 int ret = 0;
196#ifdef TEGRA194_POWER_DOMAIN_GPU
197 struct gk20a_platform *platform = gk20a_get_platform(dev);
198 struct gk20a *g = get_gk20a(dev);
199 struct gk20a_scale_profile *profile = platform->g->scale_profile;
200 int i;
201
202 if (tegra_bpmp_running()) {
203 nvgpu_log(g, gpu_dbg_info, "bpmp running");
204 ret = tegra_unpowergate_partition(TEGRA194_POWER_DOMAIN_GPU);
205 if (ret) {
206 nvgpu_log(g, gpu_dbg_info,
207 "unpowergate partition failed");
208 return ret;
209 }
210 nvgpu_log(g, gpu_dbg_info, "clk_prepare_enable");
211 for (i = 0; i < platform->num_clks; i++) {
212 if (platform->clk[i])
213 clk_prepare_enable(platform->clk[i]);
214 }
215 } else {
216 nvgpu_log(g, gpu_dbg_info, "bpmp not running");
217 }
218
219 /* to start with set emc frequency floor to max rate*/
220 if (profile)
221 tegra_bwmgr_set_emc(
222 (struct tegra_bwmgr_client *)profile->private_data,
223 tegra_bwmgr_get_max_emc_rate(),
224 TEGRA_BWMGR_SET_EMC_FLOOR);
225#endif
226 return ret;
227}
228
229static int gv11b_tegra_suspend(struct device *dev)
230{
231 return 0;
232}
233
234static bool is_tpc_mask_valid(struct gk20a_platform *platform, u32 tpc_pg_mask)
235{
236 u32 i;
237 bool valid = false;
238
239 for (i = 0; i < MAX_TPC_PG_CONFIGS; i++) {
240 if (tpc_pg_mask == platform->valid_tpc_mask[i]) {
241 valid = true;
242 break;
243 }
244 }
245 return valid;
246}
247
248static void gv11b_tegra_set_tpc_pg_mask(struct device *dev, u32 tpc_pg_mask)
249{
250 struct gk20a_platform *platform = gk20a_get_platform(dev);
251 struct gk20a *g = get_gk20a(dev);
252
253 if (is_tpc_mask_valid(platform, tpc_pg_mask)) {
254 g->tpc_pg_mask = tpc_pg_mask;
255 }
256
257}
258
259struct gk20a_platform gv11b_tegra_platform = {
260 .has_syncpoints = true,
261
262 /* ptimer src frequency in hz*/
263 .ptimer_src_freq = 31250000,
264
265 .ch_wdt_timeout_ms = 5000,
266
267 .probe = gv11b_tegra_probe,
268 .late_probe = gv11b_tegra_late_probe,
269 .remove = gv11b_tegra_remove,
270 .railgate_delay_init = 500,
271 .can_railgate_init = true,
272
273 .can_tpc_powergate = true,
274 .valid_tpc_mask[0] = 0x0,
275 .valid_tpc_mask[1] = 0x1,
276 .valid_tpc_mask[2] = 0x2,
277 .valid_tpc_mask[3] = 0x4,
278 .valid_tpc_mask[4] = 0x8,
279 .valid_tpc_mask[5] = 0x5,
280 .valid_tpc_mask[6] = 0x6,
281 .valid_tpc_mask[7] = 0x9,
282 .valid_tpc_mask[8] = 0xa,
283
284 .set_tpc_pg_mask = gv11b_tegra_set_tpc_pg_mask,
285
286 .can_slcg = true,
287 .can_blcg = true,
288 .can_elcg = true,
289 .enable_slcg = true,
290 .enable_blcg = true,
291 .enable_elcg = true,
292 .enable_perfmon = true,
293
294 /* power management configuration */
295 .enable_elpg = true,
296 .can_elpg_init = true,
297 .enable_aelpg = true,
298
299 /* power management callbacks */
300 .suspend = gv11b_tegra_suspend,
301 .railgate = gv11b_tegra_railgate,
302 .unrailgate = gv11b_tegra_unrailgate,
303 .is_railgated = gv11b_tegra_is_railgated,
304
305 .busy = gk20a_tegra_busy,
306 .idle = gk20a_tegra_idle,
307
308 .clk_round_rate = gp10b_round_clk_rate,
309 .get_clk_freqs = gp10b_clk_get_freqs,
310
311 /* frequency scaling configuration */
312 .initscale = gv11b_tegra_scale_init,
313 .prescale = gp10b_tegra_prescale,
314 .postscale = gp10b_tegra_postscale,
315 .devfreq_governor = "nvhost_podgov",
316
317 .qos_notify = gk20a_scale_qos_notify,
318
319 .dump_platform_dependencies = gk20a_tegra_debug_dump,
320
321 .soc_name = "tegra19x",
322
323 .honors_aperture = true,
324 .unified_memory = true,
325 .dma_mask = DMA_BIT_MASK(36),
326
327 .reset_assert = gp10b_tegra_reset_assert,
328 .reset_deassert = gp10b_tegra_reset_deassert,
329
330 .secure_buffer_size = 667648,
331};