summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2018-04-18 15:59:00 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2018-06-15 20:47:31 -0400
commit2a2c16af5f9f1ccfc93a13e820d5381e5c881e92 (patch)
tree2e5d7b042270a649978e5bb540857012c85fb5b5 /drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
parent98d996f4ffb0137d119b5849cae46d7b7e5693e1 (diff)
gpu: nvgpu: Move Linux files away from common
Move all Linux source code files to drivers/gpu/nvgpu/os/linux from drivers/gpu/nvgpu/common/linux. This changes the meaning of common to be OS independent. JIRA NVGPU-598 JIRA NVGPU-601 Change-Id: Ib7f2a43d3688bb0d0b7dcc48469a6783fd988ce9 Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: https://git-master.nvidia.com/r/1747714 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c')
-rw-r--r--drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c607
1 files changed, 0 insertions, 607 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c b/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
deleted file mode 100644
index fce16653..00000000
--- a/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
+++ /dev/null
@@ -1,607 +0,0 @@
1/*
2 * GP10B Tegra Platform Interface
3 *
4 * Copyright (c) 2014-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
16#include <linux/of_platform.h>
17#include <linux/debugfs.h>
18#include <linux/dma-buf.h>
19#include <linux/nvmap.h>
20#include <linux/reset.h>
21#include <linux/platform/tegra/emc_bwmgr.h>
22
23#include <uapi/linux/nvgpu.h>
24
25#include <soc/tegra/tegra_bpmp.h>
26#include <soc/tegra/tegra_powergate.h>
27#include <soc/tegra/tegra-bpmp-dvfs.h>
28
29#include <dt-bindings/memory/tegra-swgroup.h>
30
31#include <nvgpu/kmem.h>
32#include <nvgpu/bug.h>
33#include <nvgpu/enabled.h>
34#include <nvgpu/hashtable.h>
35#include <nvgpu/nvhost.h>
36
37#include "os_linux.h"
38
39#include "clk.h"
40
41#include "gk20a/gk20a.h"
42
43#include "platform_gk20a.h"
44#include "platform_ecc_sysfs.h"
45#include "platform_gk20a_tegra.h"
46#include "gp10b/platform_gp10b.h"
47#include "platform_gp10b_tegra.h"
48#include "scale.h"
49
50/* Select every GP10B_FREQ_SELECT_STEP'th frequency from h/w table */
51#define GP10B_FREQ_SELECT_STEP 8
52/* Max number of freq supported in h/w */
53#define GP10B_MAX_SUPPORTED_FREQS 120
54static unsigned long
55gp10b_freq_table[GP10B_MAX_SUPPORTED_FREQS / GP10B_FREQ_SELECT_STEP];
56
57#define TEGRA_GP10B_BW_PER_FREQ 64
58#define TEGRA_DDR4_BW_PER_FREQ 16
59
60#define EMC_BW_RATIO (TEGRA_GP10B_BW_PER_FREQ / TEGRA_DDR4_BW_PER_FREQ)
61
62#define GPCCLK_INIT_RATE 1000000000
63
64static struct {
65 char *name;
66 unsigned long default_rate;
67} tegra_gp10b_clocks[] = {
68 {"gpu", GPCCLK_INIT_RATE},
69 {"gpu_sys", 204000000} };
70
71/*
72 * gp10b_tegra_get_clocks()
73 *
74 * This function finds clocks in tegra platform and populates
75 * the clock information to gp10b platform data.
76 */
77
78int gp10b_tegra_get_clocks(struct device *dev)
79{
80 struct gk20a_platform *platform = dev_get_drvdata(dev);
81 unsigned int i;
82
83 platform->num_clks = 0;
84 for (i = 0; i < ARRAY_SIZE(tegra_gp10b_clocks); i++) {
85 long rate = tegra_gp10b_clocks[i].default_rate;
86 struct clk *c;
87
88 c = clk_get(dev, tegra_gp10b_clocks[i].name);
89 if (IS_ERR(c)) {
90 nvgpu_err(platform->g, "cannot get clock %s",
91 tegra_gp10b_clocks[i].name);
92 } else {
93 clk_set_rate(c, rate);
94 platform->clk[i] = c;
95 if (i == 0)
96 platform->cached_rate = rate;
97 }
98 }
99 platform->num_clks = i;
100
101 if (platform->clk[0]) {
102 i = tegra_bpmp_dvfs_get_clk_id(dev->of_node,
103 tegra_gp10b_clocks[0].name);
104 if (i > 0)
105 platform->maxmin_clk_id = i;
106 }
107
108 return 0;
109}
110
111void gp10b_tegra_scale_init(struct device *dev)
112{
113 struct gk20a_platform *platform = gk20a_get_platform(dev);
114 struct gk20a_scale_profile *profile = platform->g->scale_profile;
115 struct tegra_bwmgr_client *bwmgr_handle;
116
117 if (!profile)
118 return;
119
120 if ((struct tegra_bwmgr_client *)profile->private_data)
121 return;
122
123 bwmgr_handle = tegra_bwmgr_register(TEGRA_BWMGR_CLIENT_GPU);
124 if (!bwmgr_handle)
125 return;
126
127 profile->private_data = (void *)bwmgr_handle;
128}
129
130static void gp10b_tegra_scale_exit(struct device *dev)
131{
132 struct gk20a_platform *platform = gk20a_get_platform(dev);
133 struct gk20a_scale_profile *profile = platform->g->scale_profile;
134
135 if (profile)
136 tegra_bwmgr_unregister(
137 (struct tegra_bwmgr_client *)profile->private_data);
138}
139
140static int gp10b_tegra_probe(struct device *dev)
141{
142 struct gk20a_platform *platform = dev_get_drvdata(dev);
143#ifdef CONFIG_TEGRA_GK20A_NVHOST
144 int ret;
145
146 ret = nvgpu_get_nvhost_dev(platform->g);
147 if (ret)
148 return ret;
149#endif
150
151 ret = gk20a_tegra_init_secure_alloc(platform);
152 if (ret)
153 return ret;
154
155 platform->disable_bigpage = !device_is_iommuable(dev);
156
157 platform->g->gr.ctx_vars.dump_ctxsw_stats_on_channel_close
158 = false;
159 platform->g->gr.ctx_vars.dump_ctxsw_stats_on_channel_close
160 = false;
161
162 platform->g->gr.ctx_vars.force_preemption_gfxp = false;
163 platform->g->gr.ctx_vars.force_preemption_cilp = false;
164
165 gp10b_tegra_get_clocks(dev);
166 nvgpu_linux_init_clk_support(platform->g);
167
168 return 0;
169}
170
171static int gp10b_tegra_late_probe(struct device *dev)
172{
173 return 0;
174}
175
176static int gp10b_tegra_remove(struct device *dev)
177{
178 struct gk20a *g = get_gk20a(dev);
179
180 if (g->ops.gr.remove_gr_sysfs)
181 g->ops.gr.remove_gr_sysfs(g);
182
183 /* deinitialise tegra specific scaling quirks */
184 gp10b_tegra_scale_exit(dev);
185
186#ifdef CONFIG_TEGRA_GK20A_NVHOST
187 nvgpu_free_nvhost_dev(get_gk20a(dev));
188#endif
189
190 return 0;
191}
192
193static bool gp10b_tegra_is_railgated(struct device *dev)
194{
195 bool ret = false;
196
197 if (tegra_bpmp_running())
198 ret = !tegra_powergate_is_powered(TEGRA186_POWER_DOMAIN_GPU);
199
200 return ret;
201}
202
203static int gp10b_tegra_railgate(struct device *dev)
204{
205 struct gk20a_platform *platform = gk20a_get_platform(dev);
206 struct gk20a_scale_profile *profile = platform->g->scale_profile;
207
208 /* remove emc frequency floor */
209 if (profile)
210 tegra_bwmgr_set_emc(
211 (struct tegra_bwmgr_client *)profile->private_data,
212 0, TEGRA_BWMGR_SET_EMC_FLOOR);
213
214 if (tegra_bpmp_running() &&
215 tegra_powergate_is_powered(TEGRA186_POWER_DOMAIN_GPU)) {
216 int i;
217 for (i = 0; i < platform->num_clks; i++) {
218 if (platform->clk[i])
219 clk_disable_unprepare(platform->clk[i]);
220 }
221 tegra_powergate_partition(TEGRA186_POWER_DOMAIN_GPU);
222 }
223 return 0;
224}
225
226static int gp10b_tegra_unrailgate(struct device *dev)
227{
228 int ret = 0;
229 struct gk20a_platform *platform = gk20a_get_platform(dev);
230 struct gk20a_scale_profile *profile = platform->g->scale_profile;
231
232 if (tegra_bpmp_running()) {
233 int i;
234 ret = tegra_unpowergate_partition(TEGRA186_POWER_DOMAIN_GPU);
235 for (i = 0; i < platform->num_clks; i++) {
236 if (platform->clk[i])
237 clk_prepare_enable(platform->clk[i]);
238 }
239 }
240
241 /* to start with set emc frequency floor to max rate*/
242 if (profile)
243 tegra_bwmgr_set_emc(
244 (struct tegra_bwmgr_client *)profile->private_data,
245 tegra_bwmgr_get_max_emc_rate(),
246 TEGRA_BWMGR_SET_EMC_FLOOR);
247 return ret;
248}
249
250static int gp10b_tegra_suspend(struct device *dev)
251{
252 return 0;
253}
254
255int gp10b_tegra_reset_assert(struct device *dev)
256{
257 struct gk20a_platform *platform = gk20a_get_platform(dev);
258 int ret = 0;
259
260 if (!platform->reset_control)
261 return -EINVAL;
262
263 ret = reset_control_assert(platform->reset_control);
264
265 return ret;
266}
267
268int gp10b_tegra_reset_deassert(struct device *dev)
269{
270 struct gk20a_platform *platform = gk20a_get_platform(dev);
271 int ret = 0;
272
273 if (!platform->reset_control)
274 return -EINVAL;
275
276 ret = reset_control_deassert(platform->reset_control);
277
278 return ret;
279}
280
281void gp10b_tegra_prescale(struct device *dev)
282{
283 struct gk20a *g = get_gk20a(dev);
284 u32 avg = 0;
285
286 nvgpu_log_fn(g, " ");
287
288 nvgpu_pmu_load_norm(g, &avg);
289
290 nvgpu_log_fn(g, "done");
291}
292
293void gp10b_tegra_postscale(struct device *pdev,
294 unsigned long freq)
295{
296 struct gk20a_platform *platform = gk20a_get_platform(pdev);
297 struct gk20a_scale_profile *profile = platform->g->scale_profile;
298 struct gk20a *g = get_gk20a(pdev);
299 unsigned long emc_rate;
300
301 nvgpu_log_fn(g, " ");
302 if (profile && !platform->is_railgated(pdev)) {
303 unsigned long emc_scale;
304
305 if (freq <= gp10b_freq_table[0])
306 emc_scale = 0;
307 else
308 emc_scale = g->emc3d_ratio;
309
310 emc_rate = (freq * EMC_BW_RATIO * emc_scale) / 1000;
311
312 if (emc_rate > tegra_bwmgr_get_max_emc_rate())
313 emc_rate = tegra_bwmgr_get_max_emc_rate();
314
315 tegra_bwmgr_set_emc(
316 (struct tegra_bwmgr_client *)profile->private_data,
317 emc_rate, TEGRA_BWMGR_SET_EMC_FLOOR);
318 }
319 nvgpu_log_fn(g, "done");
320}
321
322long gp10b_round_clk_rate(struct device *dev, unsigned long rate)
323{
324 struct gk20a *g = get_gk20a(dev);
325 struct gk20a_scale_profile *profile = g->scale_profile;
326 unsigned long *freq_table = profile->devfreq_profile.freq_table;
327 int max_states = profile->devfreq_profile.max_state;
328 int i;
329
330 for (i = 0; i < max_states; ++i)
331 if (freq_table[i] >= rate)
332 return freq_table[i];
333
334 return freq_table[max_states - 1];
335}
336
337int gp10b_clk_get_freqs(struct device *dev,
338 unsigned long **freqs, int *num_freqs)
339{
340 struct gk20a_platform *platform = gk20a_get_platform(dev);
341 struct gk20a *g = platform->g;
342 unsigned long max_rate;
343 unsigned long new_rate = 0, prev_rate = 0;
344 int i = 0, freq_counter = 0;
345
346 max_rate = clk_round_rate(platform->clk[0], (UINT_MAX - 1));
347
348 /*
349 * Walk the h/w frequency table and only select
350 * GP10B_FREQ_SELECT_STEP'th frequencies and
351 * add MAX freq to last
352 */
353 for (; i < GP10B_MAX_SUPPORTED_FREQS; ++i) {
354 prev_rate = new_rate;
355 new_rate = clk_round_rate(platform->clk[0], prev_rate + 1);
356
357 if (i % GP10B_FREQ_SELECT_STEP == 0 ||
358 new_rate == max_rate) {
359 gp10b_freq_table[freq_counter++] = new_rate;
360
361 if (new_rate == max_rate)
362 break;
363 }
364 }
365
366 WARN_ON(i == GP10B_MAX_SUPPORTED_FREQS);
367
368 /* Fill freq table */
369 *freqs = gp10b_freq_table;
370 *num_freqs = freq_counter;
371
372 nvgpu_log_info(g, "min rate: %ld max rate: %ld num_of_freq %d\n",
373 gp10b_freq_table[0], max_rate, *num_freqs);
374
375 return 0;
376}
377
378struct gk20a_platform gp10b_tegra_platform = {
379 .has_syncpoints = true,
380
381 /* power management configuration */
382 .railgate_delay_init = 500,
383
384 /* ldiv slowdown factor */
385 .ldiv_slowdown_factor_init = SLOWDOWN_FACTOR_FPDIV_BY16,
386
387 /* power management configuration */
388 .can_railgate_init = true,
389 .enable_elpg = true,
390 .can_elpg_init = true,
391 .enable_blcg = true,
392 .enable_slcg = true,
393 .enable_elcg = true,
394 .can_slcg = true,
395 .can_blcg = true,
396 .can_elcg = true,
397 .enable_aelpg = true,
398 .enable_perfmon = true,
399
400 /* ptimer src frequency in hz*/
401 .ptimer_src_freq = 31250000,
402
403 .ch_wdt_timeout_ms = 5000,
404
405 .probe = gp10b_tegra_probe,
406 .late_probe = gp10b_tegra_late_probe,
407 .remove = gp10b_tegra_remove,
408
409 /* power management callbacks */
410 .suspend = gp10b_tegra_suspend,
411 .railgate = gp10b_tegra_railgate,
412 .unrailgate = gp10b_tegra_unrailgate,
413 .is_railgated = gp10b_tegra_is_railgated,
414
415 .busy = gk20a_tegra_busy,
416 .idle = gk20a_tegra_idle,
417
418 .dump_platform_dependencies = gk20a_tegra_debug_dump,
419
420#ifdef CONFIG_NVGPU_SUPPORT_CDE
421 .has_cde = true,
422#endif
423
424 .clk_round_rate = gp10b_round_clk_rate,
425 .get_clk_freqs = gp10b_clk_get_freqs,
426
427 /* frequency scaling configuration */
428 .initscale = gp10b_tegra_scale_init,
429 .prescale = gp10b_tegra_prescale,
430 .postscale = gp10b_tegra_postscale,
431 .devfreq_governor = "nvhost_podgov",
432
433 .qos_notify = gk20a_scale_qos_notify,
434
435 .reset_assert = gp10b_tegra_reset_assert,
436 .reset_deassert = gp10b_tegra_reset_deassert,
437
438 .force_reset_in_do_idle = false,
439
440 .soc_name = "tegra18x",
441
442 .unified_memory = true,
443 .dma_mask = DMA_BIT_MASK(36),
444
445 .ltc_streamid = TEGRA_SID_GPUB,
446
447 .secure_buffer_size = 401408,
448};
449
450void gr_gp10b_create_sysfs(struct gk20a *g)
451{
452 int error = 0;
453 struct device *dev = dev_from_gk20a(g);
454
455 /* This stat creation function is called on GR init. GR can get
456 initialized multiple times but we only need to create the ECC
457 stats once. Therefore, add the following check to avoid
458 creating duplicate stat sysfs nodes. */
459 if (g->ecc.gr.sm_lrf_single_err_count.counters != NULL)
460 return;
461
462 error |= nvgpu_gr_ecc_stat_create(dev,
463 0,
464 "sm_lrf_ecc_single_err_count",
465 &g->ecc.gr.sm_lrf_single_err_count);
466
467 error |= nvgpu_gr_ecc_stat_create(dev,
468 0,
469 "sm_lrf_ecc_double_err_count",
470 &g->ecc.gr.sm_lrf_double_err_count);
471
472 error |= nvgpu_gr_ecc_stat_create(dev,
473 0,
474 "sm_shm_ecc_sec_count",
475 &g->ecc.gr.sm_shm_sec_count);
476
477 error |= nvgpu_gr_ecc_stat_create(dev,
478 0,
479 "sm_shm_ecc_sed_count",
480 &g->ecc.gr.sm_shm_sed_count);
481
482 error |= nvgpu_gr_ecc_stat_create(dev,
483 0,
484 "sm_shm_ecc_ded_count",
485 &g->ecc.gr.sm_shm_ded_count);
486
487 error |= nvgpu_gr_ecc_stat_create(dev,
488 0,
489 "tex_ecc_total_sec_pipe0_count",
490 &g->ecc.gr.tex_total_sec_pipe0_count);
491
492 error |= nvgpu_gr_ecc_stat_create(dev,
493 0,
494 "tex_ecc_total_ded_pipe0_count",
495 &g->ecc.gr.tex_total_ded_pipe0_count);
496
497 error |= nvgpu_gr_ecc_stat_create(dev,
498 0,
499 "tex_ecc_unique_sec_pipe0_count",
500 &g->ecc.gr.tex_unique_sec_pipe0_count);
501
502 error |= nvgpu_gr_ecc_stat_create(dev,
503 0,
504 "tex_ecc_unique_ded_pipe0_count",
505 &g->ecc.gr.tex_unique_ded_pipe0_count);
506
507 error |= nvgpu_gr_ecc_stat_create(dev,
508 0,
509 "tex_ecc_total_sec_pipe1_count",
510 &g->ecc.gr.tex_total_sec_pipe1_count);
511
512 error |= nvgpu_gr_ecc_stat_create(dev,
513 0,
514 "tex_ecc_total_ded_pipe1_count",
515 &g->ecc.gr.tex_total_ded_pipe1_count);
516
517 error |= nvgpu_gr_ecc_stat_create(dev,
518 0,
519 "tex_ecc_unique_sec_pipe1_count",
520 &g->ecc.gr.tex_unique_sec_pipe1_count);
521
522 error |= nvgpu_gr_ecc_stat_create(dev,
523 0,
524 "tex_ecc_unique_ded_pipe1_count",
525 &g->ecc.gr.tex_unique_ded_pipe1_count);
526
527 error |= nvgpu_gr_ecc_stat_create(dev,
528 2,
529 "ecc_sec_count",
530 &g->ecc.ltc.l2_sec_count);
531
532 error |= nvgpu_gr_ecc_stat_create(dev,
533 2,
534 "ecc_ded_count",
535 &g->ecc.ltc.l2_ded_count);
536
537 if (error)
538 dev_err(dev, "Failed to create sysfs attributes!\n");
539}
540
541void gr_gp10b_remove_sysfs(struct gk20a *g)
542{
543 struct device *dev = dev_from_gk20a(g);
544
545 if (!g->ecc.gr.sm_lrf_single_err_count.counters)
546 return;
547
548 nvgpu_gr_ecc_stat_remove(dev,
549 0,
550 &g->ecc.gr.sm_lrf_single_err_count);
551
552 nvgpu_gr_ecc_stat_remove(dev,
553 0,
554 &g->ecc.gr.sm_lrf_double_err_count);
555
556 nvgpu_gr_ecc_stat_remove(dev,
557 0,
558 &g->ecc.gr.sm_shm_sec_count);
559
560 nvgpu_gr_ecc_stat_remove(dev,
561 0,
562 &g->ecc.gr.sm_shm_sed_count);
563
564 nvgpu_gr_ecc_stat_remove(dev,
565 0,
566 &g->ecc.gr.sm_shm_ded_count);
567
568 nvgpu_gr_ecc_stat_remove(dev,
569 0,
570 &g->ecc.gr.tex_total_sec_pipe0_count);
571
572 nvgpu_gr_ecc_stat_remove(dev,
573 0,
574 &g->ecc.gr.tex_total_ded_pipe0_count);
575
576 nvgpu_gr_ecc_stat_remove(dev,
577 0,
578 &g->ecc.gr.tex_unique_sec_pipe0_count);
579
580 nvgpu_gr_ecc_stat_remove(dev,
581 0,
582 &g->ecc.gr.tex_unique_ded_pipe0_count);
583
584 nvgpu_gr_ecc_stat_remove(dev,
585 0,
586 &g->ecc.gr.tex_total_sec_pipe1_count);
587
588 nvgpu_gr_ecc_stat_remove(dev,
589 0,
590 &g->ecc.gr.tex_total_ded_pipe1_count);
591
592 nvgpu_gr_ecc_stat_remove(dev,
593 0,
594 &g->ecc.gr.tex_unique_sec_pipe1_count);
595
596 nvgpu_gr_ecc_stat_remove(dev,
597 0,
598 &g->ecc.gr.tex_unique_ded_pipe1_count);
599
600 nvgpu_gr_ecc_stat_remove(dev,
601 2,
602 &g->ecc.ltc.l2_sec_count);
603
604 nvgpu_gr_ecc_stat_remove(dev,
605 2,
606 &g->ecc.ltc.l2_ded_count);
607}