diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/platform_gk20a_generic.c | 83 |
1 files changed, 81 insertions, 2 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a_generic.c b/drivers/gpu/nvgpu/gk20a/platform_gk20a_generic.c index 7b750df6..5000db7f 100644 --- a/drivers/gpu/nvgpu/gk20a/platform_gk20a_generic.c +++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a_generic.c | |||
@@ -18,18 +18,97 @@ | |||
18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/tegra-powergate.h> | ||
22 | #include <linux/tegra_pm_domains.h> | ||
23 | #include <linux/clk.h> | ||
24 | |||
21 | #include "platform_gk20a.h" | 25 | #include "platform_gk20a.h" |
26 | #include "hal_gk20a.h" | ||
27 | #include "gk20a.h" | ||
28 | |||
29 | /* | ||
30 | * gk20a_generic_railgate() | ||
31 | * | ||
32 | * Gate (disable) gk20a power rail | ||
33 | */ | ||
34 | |||
35 | static int gk20a_generic_railgate(struct platform_device *pdev) | ||
36 | { | ||
37 | if (tegra_powergate_is_powered(TEGRA_POWERGATE_GPU)) | ||
38 | tegra_powergate_partition(TEGRA_POWERGATE_GPU); | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | /* | ||
43 | * gk20a_generic_unrailgate() | ||
44 | * | ||
45 | * Ungate (enable) gk20a power rail | ||
46 | */ | ||
47 | |||
48 | static int gk20a_generic_unrailgate(struct platform_device *pdev) | ||
49 | { | ||
50 | tegra_unpowergate_partition(TEGRA_POWERGATE_GPU); | ||
51 | return 0; | ||
52 | } | ||
53 | |||
54 | /* | ||
55 | * gk20a_generic_get_clocks() | ||
56 | * | ||
57 | * This function finds clocks in tegra platform and populates | ||
58 | * the clock information to gk20a platform data. | ||
59 | */ | ||
60 | |||
61 | static int gk20a_generic_get_clocks(struct platform_device *pdev) | ||
62 | { | ||
63 | struct gk20a_platform *platform = platform_get_drvdata(pdev); | ||
64 | |||
65 | platform->clk[0] = clk_get_sys("tegra_gk20a.0", "PLLG_ref"); | ||
66 | platform->clk[1] = clk_get_sys("tegra_gk20a.0", "pwr"); | ||
67 | platform->clk[2] = clk_get_sys("tegra_gk20a.0", "emc"); | ||
68 | platform->num_clks = 3; | ||
69 | |||
70 | if (IS_ERR(platform->clk[0]) || | ||
71 | IS_ERR(platform->clk[1]) || | ||
72 | IS_ERR(platform->clk[2])) | ||
73 | goto err_get_clock; | ||
74 | |||
75 | clk_set_rate(platform->clk[0], UINT_MAX); | ||
76 | clk_set_rate(platform->clk[1], 204000000); | ||
77 | clk_set_rate(platform->clk[2], UINT_MAX); | ||
78 | |||
79 | return 0; | ||
80 | |||
81 | err_get_clock: | ||
82 | if (!IS_ERR_OR_NULL(platform->clk[0])) | ||
83 | clk_put(platform->clk[0]); | ||
84 | if (!IS_ERR_OR_NULL(platform->clk[1])) | ||
85 | clk_put(platform->clk[1]); | ||
86 | if (!IS_ERR_OR_NULL(platform->clk[2])) | ||
87 | clk_put(platform->clk[2]); | ||
88 | return -ENODEV; | ||
89 | } | ||
22 | 90 | ||
23 | static int gk20a_generic_probe(struct platform_device *dev) | 91 | static int gk20a_generic_probe(struct platform_device *dev) |
24 | { | 92 | { |
93 | gk20a_generic_get_clocks(dev); | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static int gk20a_generic_late_probe(struct platform_device *dev) | ||
99 | { | ||
25 | struct gk20a_platform *platform = gk20a_get_platform(dev); | 100 | struct gk20a_platform *platform = gk20a_get_platform(dev); |
26 | 101 | ||
27 | /* TODO: Initialize clocks and power */ | 102 | /* Make gk20a power domain a subdomain of mc */ |
28 | (void)platform; | 103 | tegra_pd_add_sd(&platform->g->pd); |
29 | 104 | ||
30 | return 0; | 105 | return 0; |
31 | } | 106 | } |
32 | 107 | ||
33 | struct gk20a_platform gk20a_generic_platform = { | 108 | struct gk20a_platform gk20a_generic_platform = { |
109 | .railgate = gk20a_generic_railgate, | ||
110 | .unrailgate = gk20a_generic_unrailgate, | ||
111 | |||
34 | .probe = gk20a_generic_probe, | 112 | .probe = gk20a_generic_probe, |
113 | .late_probe = gk20a_generic_late_probe, | ||
35 | }; | 114 | }; |