diff options
Diffstat (limited to 'drivers/gpu/nvgpu/tegra')
-rw-r--r-- | drivers/gpu/nvgpu/tegra/linux/clk.c | 76 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/tegra/linux/clk.h | 22 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c | 24 | ||||
-rw-r--r-- | drivers/gpu/nvgpu/tegra/linux/platform_gp10b_tegra.c | 20 |
4 files changed, 104 insertions, 38 deletions
diff --git a/drivers/gpu/nvgpu/tegra/linux/clk.c b/drivers/gpu/nvgpu/tegra/linux/clk.c new file mode 100644 index 00000000..3982054c --- /dev/null +++ b/drivers/gpu/nvgpu/tegra/linux/clk.c | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * Linux clock support | ||
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 | * 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/clk.h> | ||
20 | |||
21 | #include "gk20a/gk20a.h" | ||
22 | |||
23 | static unsigned long nvgpu_linux_clk_get_rate(struct gk20a *g, u32 api_domain) | ||
24 | { | ||
25 | struct gk20a_platform *platform = gk20a_get_platform(g->dev); | ||
26 | unsigned long ret; | ||
27 | |||
28 | switch (api_domain) { | ||
29 | case CTRL_CLK_DOMAIN_GPCCLK: | ||
30 | if (g->clk.tegra_clk) | ||
31 | ret = clk_get_rate(g->clk.tegra_clk); | ||
32 | else | ||
33 | ret = clk_get_rate(platform->clk[0]); | ||
34 | break; | ||
35 | case CTRL_CLK_DOMAIN_PWRCLK: | ||
36 | ret = clk_get_rate(platform->clk[1]); | ||
37 | break; | ||
38 | default: | ||
39 | gk20a_err(g->dev, "unknown clock: %u", api_domain); | ||
40 | ret = 0; | ||
41 | break; | ||
42 | } | ||
43 | |||
44 | return ret; | ||
45 | } | ||
46 | |||
47 | static int nvgpu_linux_clk_set_rate(struct gk20a *g, | ||
48 | u32 api_domain, unsigned long rate) | ||
49 | { | ||
50 | struct gk20a_platform *platform = gk20a_get_platform(g->dev); | ||
51 | int ret; | ||
52 | |||
53 | switch (api_domain) { | ||
54 | case CTRL_CLK_DOMAIN_GPCCLK: | ||
55 | if (g->clk.tegra_clk) | ||
56 | ret = clk_set_rate(g->clk.tegra_clk, rate); | ||
57 | else | ||
58 | ret = clk_set_rate(platform->clk[0], rate); | ||
59 | break; | ||
60 | case CTRL_CLK_DOMAIN_PWRCLK: | ||
61 | ret = clk_set_rate(platform->clk[1], rate); | ||
62 | break; | ||
63 | default: | ||
64 | gk20a_err(g->dev, "unknown clock: %u", api_domain); | ||
65 | ret = -EINVAL; | ||
66 | break; | ||
67 | } | ||
68 | |||
69 | return ret; | ||
70 | } | ||
71 | |||
72 | void nvgpu_linux_init_clk_support(struct gk20a *g) | ||
73 | { | ||
74 | g->ops.clk.get_rate = nvgpu_linux_clk_get_rate; | ||
75 | g->ops.clk.set_rate = nvgpu_linux_clk_set_rate; | ||
76 | } | ||
diff --git a/drivers/gpu/nvgpu/tegra/linux/clk.h b/drivers/gpu/nvgpu/tegra/linux/clk.h new file mode 100644 index 00000000..614a7fd7 --- /dev/null +++ b/drivers/gpu/nvgpu/tegra/linux/clk.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms and conditions of the GNU General Public License, | ||
6 | * version 2, as published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
11 | * more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License | ||
14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | #ifndef NVGPU_COMMON_LINUX_CLK_H | ||
18 | |||
19 | struct gk20a; | ||
20 | void nvgpu_linux_init_clk_support(struct gk20a *g); | ||
21 | |||
22 | #endif | ||
diff --git a/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c index 56ba1ecd..1b40702a 100644 --- a/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c +++ b/drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c | |||
@@ -49,6 +49,8 @@ | |||
49 | #include "gk20a/gk20a_scale.h" | 49 | #include "gk20a/gk20a_scale.h" |
50 | #include "gm20b/clk_gm20b.h" | 50 | #include "gm20b/clk_gm20b.h" |
51 | 51 | ||
52 | #include "clk.h" | ||
53 | |||
52 | #define TEGRA_GK20A_BW_PER_FREQ 32 | 54 | #define TEGRA_GK20A_BW_PER_FREQ 32 |
53 | #define TEGRA_GM20B_BW_PER_FREQ 64 | 55 | #define TEGRA_GM20B_BW_PER_FREQ 64 |
54 | #define TEGRA_DDR3_BW_PER_FREQ 16 | 56 | #define TEGRA_DDR3_BW_PER_FREQ 16 |
@@ -938,6 +940,7 @@ static int gk20a_tegra_probe(struct device *dev) | |||
938 | platform->g->mm.vidmem_is_vidmem = platform->vidmem_is_vidmem; | 940 | platform->g->mm.vidmem_is_vidmem = platform->vidmem_is_vidmem; |
939 | 941 | ||
940 | gk20a_tegra_get_clocks(dev); | 942 | gk20a_tegra_get_clocks(dev); |
943 | nvgpu_linux_init_clk_support(platform->g); | ||
941 | 944 | ||
942 | if (platform->clk_register) { | 945 | if (platform->clk_register) { |
943 | ret = platform->clk_register(platform->g); | 946 | ret = platform->clk_register(platform->g); |
@@ -975,15 +978,6 @@ static int gk20a_tegra_suspend(struct device *dev) | |||
975 | } | 978 | } |
976 | 979 | ||
977 | #if defined(CONFIG_TEGRA_CLK_FRAMEWORK) || defined(CONFIG_COMMON_CLK) | 980 | #if defined(CONFIG_TEGRA_CLK_FRAMEWORK) || defined(CONFIG_COMMON_CLK) |
978 | static unsigned long gk20a_get_clk_rate(struct device *dev) | ||
979 | { | ||
980 | struct gk20a_platform *platform = gk20a_get_platform(dev); | ||
981 | struct gk20a *g = platform->g; | ||
982 | |||
983 | return gk20a_clk_get_rate(g); | ||
984 | |||
985 | } | ||
986 | |||
987 | static long gk20a_round_clk_rate(struct device *dev, unsigned long rate) | 981 | static long gk20a_round_clk_rate(struct device *dev, unsigned long rate) |
988 | { | 982 | { |
989 | struct gk20a_platform *platform = gk20a_get_platform(dev); | 983 | struct gk20a_platform *platform = gk20a_get_platform(dev); |
@@ -992,14 +986,6 @@ static long gk20a_round_clk_rate(struct device *dev, unsigned long rate) | |||
992 | return gk20a_clk_round_rate(g, rate); | 986 | return gk20a_clk_round_rate(g, rate); |
993 | } | 987 | } |
994 | 988 | ||
995 | static int gk20a_set_clk_rate(struct device *dev, unsigned long rate) | ||
996 | { | ||
997 | struct gk20a_platform *platform = gk20a_get_platform(dev); | ||
998 | struct gk20a *g = platform->g; | ||
999 | |||
1000 | return gk20a_clk_set_rate(g, rate); | ||
1001 | } | ||
1002 | |||
1003 | static int gk20a_clk_get_freqs(struct device *dev, | 989 | static int gk20a_clk_get_freqs(struct device *dev, |
1004 | unsigned long **freqs, int *num_freqs) | 990 | unsigned long **freqs, int *num_freqs) |
1005 | { | 991 | { |
@@ -1056,9 +1042,7 @@ struct gk20a_platform gk20a_tegra_platform = { | |||
1056 | .reset_deassert = gk20a_tegra_reset_deassert, | 1042 | .reset_deassert = gk20a_tegra_reset_deassert, |
1057 | 1043 | ||
1058 | #ifdef CONFIG_TEGRA_CLK_FRAMEWORK | 1044 | #ifdef CONFIG_TEGRA_CLK_FRAMEWORK |
1059 | .clk_get_rate = gk20a_get_clk_rate, | ||
1060 | .clk_round_rate = gk20a_round_clk_rate, | 1045 | .clk_round_rate = gk20a_round_clk_rate, |
1061 | .clk_set_rate = gk20a_set_clk_rate, | ||
1062 | .get_clk_freqs = gk20a_clk_get_freqs, | 1046 | .get_clk_freqs = gk20a_clk_get_freqs, |
1063 | #endif | 1047 | #endif |
1064 | 1048 | ||
@@ -1124,9 +1108,7 @@ struct gk20a_platform gm20b_tegra_platform = { | |||
1124 | #endif | 1108 | #endif |
1125 | 1109 | ||
1126 | #if defined(CONFIG_TEGRA_CLK_FRAMEWORK) || defined(CONFIG_COMMON_CLK) | 1110 | #if defined(CONFIG_TEGRA_CLK_FRAMEWORK) || defined(CONFIG_COMMON_CLK) |
1127 | .clk_get_rate = gk20a_get_clk_rate, | ||
1128 | .clk_round_rate = gk20a_round_clk_rate, | 1111 | .clk_round_rate = gk20a_round_clk_rate, |
1129 | .clk_set_rate = gk20a_set_clk_rate, | ||
1130 | .get_clk_freqs = gk20a_clk_get_freqs, | 1112 | .get_clk_freqs = gk20a_clk_get_freqs, |
1131 | #endif | 1113 | #endif |
1132 | 1114 | ||
diff --git a/drivers/gpu/nvgpu/tegra/linux/platform_gp10b_tegra.c b/drivers/gpu/nvgpu/tegra/linux/platform_gp10b_tegra.c index f0c3640a..27db9c12 100644 --- a/drivers/gpu/nvgpu/tegra/linux/platform_gp10b_tegra.c +++ b/drivers/gpu/nvgpu/tegra/linux/platform_gp10b_tegra.c | |||
@@ -29,6 +29,8 @@ | |||
29 | 29 | ||
30 | #include <soc/tegra/tegra_bpmp.h> | 30 | #include <soc/tegra/tegra_bpmp.h> |
31 | 31 | ||
32 | #include "clk.h" | ||
33 | |||
32 | #include "gk20a/platform_gk20a.h" | 34 | #include "gk20a/platform_gk20a.h" |
33 | #include "gk20a/gk20a.h" | 35 | #include "gk20a/gk20a.h" |
34 | #include "gk20a/gk20a_scale.h" | 36 | #include "gk20a/gk20a_scale.h" |
@@ -173,6 +175,7 @@ static int gp10b_tegra_probe(struct device *dev) | |||
173 | platform->g->mm.vidmem_is_vidmem = platform->vidmem_is_vidmem; | 175 | platform->g->mm.vidmem_is_vidmem = platform->vidmem_is_vidmem; |
174 | 176 | ||
175 | gp10b_tegra_get_clocks(dev); | 177 | gp10b_tegra_get_clocks(dev); |
178 | nvgpu_linux_init_clk_support(platform->g); | ||
176 | 179 | ||
177 | return 0; | 180 | return 0; |
178 | } | 181 | } |
@@ -329,14 +332,6 @@ static void gp10b_tegra_postscale(struct device *pdev, | |||
329 | gk20a_dbg_fn("done"); | 332 | gk20a_dbg_fn("done"); |
330 | } | 333 | } |
331 | 334 | ||
332 | static unsigned long gp10b_get_clk_rate(struct device *dev) | ||
333 | { | ||
334 | struct gk20a_platform *platform = gk20a_get_platform(dev); | ||
335 | |||
336 | return clk_get_rate(platform->clk[0]); | ||
337 | |||
338 | } | ||
339 | |||
340 | static long gp10b_round_clk_rate(struct device *dev, unsigned long rate) | 335 | static long gp10b_round_clk_rate(struct device *dev, unsigned long rate) |
341 | { | 336 | { |
342 | struct gk20a *g = get_gk20a(dev); | 337 | struct gk20a *g = get_gk20a(dev); |
@@ -352,13 +347,6 @@ static long gp10b_round_clk_rate(struct device *dev, unsigned long rate) | |||
352 | return freq_table[max_states - 1]; | 347 | return freq_table[max_states - 1]; |
353 | } | 348 | } |
354 | 349 | ||
355 | static int gp10b_set_clk_rate(struct device *dev, unsigned long rate) | ||
356 | { | ||
357 | struct gk20a_platform *platform = gk20a_get_platform(dev); | ||
358 | |||
359 | return clk_set_rate(platform->clk[0], rate); | ||
360 | } | ||
361 | |||
362 | static int gp10b_clk_get_freqs(struct device *dev, | 350 | static int gp10b_clk_get_freqs(struct device *dev, |
363 | unsigned long **freqs, int *num_freqs) | 351 | unsigned long **freqs, int *num_freqs) |
364 | { | 352 | { |
@@ -440,9 +428,7 @@ struct gk20a_platform gp10b_tegra_platform = { | |||
440 | 428 | ||
441 | .has_ce = true, | 429 | .has_ce = true, |
442 | 430 | ||
443 | .clk_get_rate = gp10b_get_clk_rate, | ||
444 | .clk_round_rate = gp10b_round_clk_rate, | 431 | .clk_round_rate = gp10b_round_clk_rate, |
445 | .clk_set_rate = gp10b_set_clk_rate, | ||
446 | .get_clk_freqs = gp10b_clk_get_freqs, | 432 | .get_clk_freqs = gp10b_clk_get_freqs, |
447 | 433 | ||
448 | /* frequency scaling configuration */ | 434 | /* frequency scaling configuration */ |