summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu
diff options
context:
space:
mode:
authorTerje Bergstrom <tbergstrom@nvidia.com>2017-02-02 16:24:21 -0500
committermobile promotions <svcmobile_promotions@nvidia.com>2017-03-16 14:48:29 -0400
commit589d6385b19a357cf566b75ded9355f9b8053ad7 (patch)
tree6453c1d3525c6a53b7b749a39b51e4a598680a64 /drivers/gpu/nvgpu
parent686c3b701fb1db75a0b416a25c288c04a396df31 (diff)
gpu: nvgpu: Implement get_rate/set_rate as GPU op
Move clock APIs from gk20a_platform to gpu_ops. At the same time allow use of internal get_rate/set_rate for querying both GPCCLK and PWRCLK on iGPU. At the same time we can replace calls to clk framework with the new HAL and drop direct dependency to clk framework. gp10b ops were replaced as a whole at HAL initialization. That replaces anything set in platform probe stage, so reduce that to touch only clock gating regs. Change-Id: Iaf219b1f000d362dbf397d45832f52d25463b31c Signed-off-by: Terje Bergstrom <tbergstrom@nvidia.com> Reviewed-on: http://git-master/r/1300113 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu/nvgpu')
-rw-r--r--drivers/gpu/nvgpu/Makefile.nvgpu1
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h2
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a_scale.c14
-rw-r--r--drivers/gpu/nvgpu/gk20a/hal_gk20a.c2
-rw-r--r--drivers/gpu/nvgpu/gk20a/platform_gk20a.h3
-rw-r--r--drivers/gpu/nvgpu/gk20a/pmu_gk20a.c4
-rw-r--r--drivers/gpu/nvgpu/gm20b/acr_gm20b.c4
-rw-r--r--drivers/gpu/nvgpu/gm20b/hal_gm20b.c2
-rw-r--r--drivers/gpu/nvgpu/gp106/acr_gp106.c1
-rw-r--r--drivers/gpu/nvgpu/gp106/clk_gp106.c2
-rw-r--r--drivers/gpu/nvgpu/gp106/hal_gp106.c2
-rw-r--r--drivers/gpu/nvgpu/gp10b/gr_gp10b.c4
-rw-r--r--drivers/gpu/nvgpu/gp10b/hal_gp10b.c2
-rw-r--r--drivers/gpu/nvgpu/tegra/linux/clk.c76
-rw-r--r--drivers/gpu/nvgpu/tegra/linux/clk.h22
-rw-r--r--drivers/gpu/nvgpu/tegra/linux/platform_gk20a_tegra.c24
-rw-r--r--drivers/gpu/nvgpu/tegra/linux/platform_gp10b_tegra.c20
17 files changed, 120 insertions, 65 deletions
diff --git a/drivers/gpu/nvgpu/Makefile.nvgpu b/drivers/gpu/nvgpu/Makefile.nvgpu
index 00b4a291..abb9b785 100644
--- a/drivers/gpu/nvgpu/Makefile.nvgpu
+++ b/drivers/gpu/nvgpu/Makefile.nvgpu
@@ -116,6 +116,7 @@ nvgpu-$(CONFIG_TEGRA_GR_VIRTUALIZATION) += \
116nvgpu-$(CONFIG_TEGRA_CLK_FRAMEWORK) += gk20a/clk_gk20a.o 116nvgpu-$(CONFIG_TEGRA_CLK_FRAMEWORK) += gk20a/clk_gk20a.o
117ifneq (,$filter y,$(CONFIG_TEGRA_CLK_FRAMEWORK),$(CONFIG_COMMON_CLK)) 117ifneq (,$filter y,$(CONFIG_TEGRA_CLK_FRAMEWORK),$(CONFIG_COMMON_CLK))
118nvgpu-y += \ 118nvgpu-y += \
119 tegra/linux/clk.o \
119 clk/clk_common.o \ 120 clk/clk_common.o \
120 gm20b/clk_gm20b.o 121 gm20b/clk_gm20b.o
121endif 122endif
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 5a4eaf39..695d2d1a 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -691,6 +691,8 @@ struct gpu_ops {
691 int (*suspend_clk_support)(struct gk20a *g); 691 int (*suspend_clk_support)(struct gk20a *g);
692 u32 (*get_crystal_clk_hz)(struct gk20a *g); 692 u32 (*get_crystal_clk_hz)(struct gk20a *g);
693 unsigned long (*measure_freq)(struct gk20a *g, u32 api_domain); 693 unsigned long (*measure_freq)(struct gk20a *g, u32 api_domain);
694 unsigned long (*get_rate)(struct gk20a *g, u32 api_domain);
695 int (*set_rate)(struct gk20a *g, u32 api_domain, unsigned long rate);
694 } clk; 696 } clk;
695 struct { 697 struct {
696 u32 (*get_arbiter_clk_domains)(struct gk20a *g); 698 u32 (*get_arbiter_clk_domains)(struct gk20a *g);
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a_scale.c b/drivers/gpu/nvgpu/gk20a/gk20a_scale.c
index edf92de6..b9e92f15 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a_scale.c
+++ b/drivers/gpu/nvgpu/gk20a/gk20a_scale.c
@@ -19,10 +19,8 @@
19#include <linux/devfreq.h> 19#include <linux/devfreq.h>
20#include <linux/debugfs.h> 20#include <linux/debugfs.h>
21#include <linux/types.h> 21#include <linux/types.h>
22#include <linux/clk.h>
23#include <linux/export.h> 22#include <linux/export.h>
24#include <linux/slab.h> 23#include <linux/slab.h>
25#include <linux/clk/tegra.h>
26#include <soc/tegra/chip-id.h> 24#include <soc/tegra/chip-id.h>
27#include <linux/platform_data/tegra_edp.h> 25#include <linux/platform_data/tegra_edp.h>
28#include <linux/pm_qos.h> 26#include <linux/pm_qos.h>
@@ -188,11 +186,11 @@ static int gk20a_scale_target(struct device *dev, unsigned long *freq,
188 if (rounded_rate == g->last_freq) 186 if (rounded_rate == g->last_freq)
189 return 0; 187 return 0;
190 188
191 if (platform->clk_get_rate(dev) == rounded_rate) 189 if (g->ops.clk.get_rate(g, CTRL_CLK_DOMAIN_GPCCLK) == rounded_rate)
192 *freq = rounded_rate; 190 *freq = rounded_rate;
193 else { 191 else {
194 platform->clk_set_rate(dev, rounded_rate); 192 g->ops.clk.set_rate(g, CTRL_CLK_DOMAIN_GPCCLK, rounded_rate);
195 *freq = platform->clk_get_rate(dev); 193 *freq = g->ops.clk.get_rate(g, CTRL_CLK_DOMAIN_GPCCLK);
196 } 194 }
197 195
198 g->last_freq = *freq; 196 g->last_freq = *freq;
@@ -321,7 +319,7 @@ static int gk20a_scale_get_dev_status(struct device *dev,
321 319
322 /* Make sure there are correct values for the current frequency */ 320 /* Make sure there are correct values for the current frequency */
323 profile->dev_stat.current_frequency = 321 profile->dev_stat.current_frequency =
324 platform->clk_get_rate(profile->dev); 322 g->ops.clk.get_rate(g, CTRL_CLK_DOMAIN_GPCCLK);
325 323
326 /* Update load estimate */ 324 /* Update load estimate */
327 update_load_estimate_gpmu(dev); 325 update_load_estimate_gpmu(dev);
@@ -344,8 +342,8 @@ static int gk20a_scale_get_dev_status(struct device *dev,
344 342
345static int get_cur_freq(struct device *dev, unsigned long *freq) 343static int get_cur_freq(struct device *dev, unsigned long *freq)
346{ 344{
347 struct gk20a_platform *platform = dev_get_drvdata(dev); 345 struct gk20a *g = get_gk20a(dev);
348 *freq = platform->clk_get_rate(dev); 346 *freq = g->ops.clk.get_rate(g, CTRL_CLK_DOMAIN_GPCCLK);
349 return 0; 347 return 0;
350} 348}
351 349
diff --git a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c
index 9eb8e835..23725b8b 100644
--- a/drivers/gpu/nvgpu/gk20a/hal_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/hal_gk20a.c
@@ -143,7 +143,7 @@ int gk20a_init_hal(struct gk20a *g)
143 struct gpu_ops *gops = &g->ops; 143 struct gpu_ops *gops = &g->ops;
144 struct nvgpu_gpu_characteristics *c = &g->gpu_characteristics; 144 struct nvgpu_gpu_characteristics *c = &g->gpu_characteristics;
145 145
146 *gops = gk20a_ops; 146 gops->clock_gating = gk20a_ops.clock_gating;
147 gops->privsecurity = 0; 147 gops->privsecurity = 0;
148 gops->securegpccs = 0; 148 gops->securegpccs = 0;
149 gops->pmupstate = false; 149 gops->pmupstate = false;
diff --git a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
index 42be2271..b23d0091 100644
--- a/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/platform_gk20a.h
@@ -196,11 +196,8 @@ struct gk20a_platform {
196 unsigned long **freqs, int *num_freqs); 196 unsigned long **freqs, int *num_freqs);
197 197
198 /* clk related supported functions */ 198 /* clk related supported functions */
199 unsigned long (*clk_get_rate)(struct device *dev);
200 long (*clk_round_rate)(struct device *dev, 199 long (*clk_round_rate)(struct device *dev,
201 unsigned long rate); 200 unsigned long rate);
202 int (*clk_set_rate)(struct device *dev,
203 unsigned long rate);
204 201
205 /* Called to register GPCPLL with common clk framework */ 202 /* Called to register GPCPLL with common clk framework */
206 int (*clk_register)(struct gk20a *g); 203 int (*clk_register)(struct gk20a *g);
diff --git a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
index 7e37762c..c7e68f44 100644
--- a/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/pmu_gk20a.c
@@ -18,7 +18,6 @@
18 18
19#include <linux/delay.h> /* for mdelay */ 19#include <linux/delay.h> /* for mdelay */
20#include <linux/firmware.h> 20#include <linux/firmware.h>
21#include <linux/clk.h>
22#include <linux/module.h> 21#include <linux/module.h>
23#include <linux/debugfs.h> 22#include <linux/debugfs.h>
24#include <linux/dma-mapping.h> 23#include <linux/dma-mapping.h>
@@ -2474,7 +2473,6 @@ int pmu_reset(struct pmu_gk20a *pmu)
2474int pmu_bootstrap(struct pmu_gk20a *pmu) 2473int pmu_bootstrap(struct pmu_gk20a *pmu)
2475{ 2474{
2476 struct gk20a *g = gk20a_from_pmu(pmu); 2475 struct gk20a *g = gk20a_from_pmu(pmu);
2477 struct gk20a_platform *platform = dev_get_drvdata(g->dev);
2478 struct mm_gk20a *mm = &g->mm; 2476 struct mm_gk20a *mm = &g->mm;
2479 struct pmu_ucode_desc *desc = pmu->desc; 2477 struct pmu_ucode_desc *desc = pmu->desc;
2480 u64 addr_code, addr_data, addr_load; 2478 u64 addr_code, addr_data, addr_load;
@@ -2499,7 +2497,7 @@ int pmu_bootstrap(struct pmu_gk20a *pmu)
2499 pmu, GK20A_PMU_DMAIDX_VIRT); 2497 pmu, GK20A_PMU_DMAIDX_VIRT);
2500 2498
2501 g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq(pmu, 2499 g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq(pmu,
2502 clk_get_rate(platform->clk[1])); 2500 g->ops.clk.get_rate(g, CTRL_CLK_DOMAIN_PWRCLK));
2503 2501
2504 addr_args = (pwr_falcon_hwcfg_dmem_size_v( 2502 addr_args = (pwr_falcon_hwcfg_dmem_size_v(
2505 gk20a_readl(g, pwr_falcon_hwcfg_r())) 2503 gk20a_readl(g, pwr_falcon_hwcfg_r()))
diff --git a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
index ed144c0f..2d932b67 100644
--- a/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/acr_gm20b.c
@@ -13,7 +13,6 @@
13 13
14#include <linux/delay.h> /* for mdelay */ 14#include <linux/delay.h> /* for mdelay */
15#include <linux/firmware.h> 15#include <linux/firmware.h>
16#include <linux/clk.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/debugfs.h> 17#include <linux/debugfs.h>
19#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
@@ -1317,7 +1316,6 @@ static int gm20b_init_pmu_setup_hw1(struct gk20a *g,
1317 1316
1318 struct pmu_gk20a *pmu = &g->pmu; 1317 struct pmu_gk20a *pmu = &g->pmu;
1319 int err; 1318 int err;
1320 struct gk20a_platform *platform = dev_get_drvdata(g->dev);
1321 1319
1322 gk20a_dbg_fn(""); 1320 gk20a_dbg_fn("");
1323 1321
@@ -1345,7 +1343,7 @@ static int gm20b_init_pmu_setup_hw1(struct gk20a *g,
1345 1343
1346 /*Copying pmu cmdline args*/ 1344 /*Copying pmu cmdline args*/
1347 g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq(pmu, 1345 g->ops.pmu_ver.set_pmu_cmdline_args_cpu_freq(pmu,
1348 clk_get_rate(platform->clk[1])); 1346 g->ops.clk.get_rate(g, CTRL_CLK_DOMAIN_PWRCLK));
1349 g->ops.pmu_ver.set_pmu_cmdline_args_secure_mode(pmu, 1); 1347 g->ops.pmu_ver.set_pmu_cmdline_args_secure_mode(pmu, 1);
1350 g->ops.pmu_ver.set_pmu_cmdline_args_trace_size( 1348 g->ops.pmu_ver.set_pmu_cmdline_args_trace_size(
1351 pmu, GK20A_PMU_TRACE_BUFSIZE); 1349 pmu, GK20A_PMU_TRACE_BUFSIZE);
diff --git a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c
index d9fb2c53..ad041f67 100644
--- a/drivers/gpu/nvgpu/gm20b/hal_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/hal_gm20b.c
@@ -185,7 +185,7 @@ int gm20b_init_hal(struct gk20a *g)
185 struct gk20a_platform *platform = dev_get_drvdata(g->dev); 185 struct gk20a_platform *platform = dev_get_drvdata(g->dev);
186 u32 val; 186 u32 val;
187 187
188 *gops = gm20b_ops; 188 gops->clock_gating = gm20b_ops.clock_gating;
189 gops->securegpccs = false; 189 gops->securegpccs = false;
190 gops->pmupstate = false; 190 gops->pmupstate = false;
191#ifdef CONFIG_TEGRA_ACR 191#ifdef CONFIG_TEGRA_ACR
diff --git a/drivers/gpu/nvgpu/gp106/acr_gp106.c b/drivers/gpu/nvgpu/gp106/acr_gp106.c
index 37a3d152..8c744a73 100644
--- a/drivers/gpu/nvgpu/gp106/acr_gp106.c
+++ b/drivers/gpu/nvgpu/gp106/acr_gp106.c
@@ -13,7 +13,6 @@
13 13
14#include <linux/delay.h> /* for mdelay */ 14#include <linux/delay.h> /* for mdelay */
15#include <linux/firmware.h> 15#include <linux/firmware.h>
16#include <linux/clk.h>
17#include <linux/module.h> 16#include <linux/module.h>
18#include <linux/debugfs.h> 17#include <linux/debugfs.h>
19#include <linux/dma-mapping.h> 18#include <linux/dma-mapping.h>
diff --git a/drivers/gpu/nvgpu/gp106/clk_gp106.c b/drivers/gpu/nvgpu/gp106/clk_gp106.c
index 6bc4f3b0..487ba3c3 100644
--- a/drivers/gpu/nvgpu/gp106/clk_gp106.c
+++ b/drivers/gpu/nvgpu/gp106/clk_gp106.c
@@ -16,12 +16,10 @@
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19#include <linux/clk.h>
20#include <linux/delay.h> /* for mdelay */ 19#include <linux/delay.h> /* for mdelay */
21#include <linux/module.h> 20#include <linux/module.h>
22#include <linux/debugfs.h> 21#include <linux/debugfs.h>
23#include <linux/uaccess.h> 22#include <linux/uaccess.h>
24#include <linux/clk/tegra.h>
25#include <soc/tegra/fuse.h> 23#include <soc/tegra/fuse.h>
26 24
27#include "gk20a/gk20a.h" 25#include "gk20a/gk20a.h"
diff --git a/drivers/gpu/nvgpu/gp106/hal_gp106.c b/drivers/gpu/nvgpu/gp106/hal_gp106.c
index d07223c9..a05b71ab 100644
--- a/drivers/gpu/nvgpu/gp106/hal_gp106.c
+++ b/drivers/gpu/nvgpu/gp106/hal_gp106.c
@@ -218,7 +218,7 @@ int gp106_init_hal(struct gk20a *g)
218 218
219 gk20a_dbg_fn(""); 219 gk20a_dbg_fn("");
220 220
221 *gops = gp106_ops; 221 gops->clock_gating = gp106_ops.clock_gating;
222 222
223 gops->privsecurity = 1; 223 gops->privsecurity = 1;
224 gops->securegpccs = 1; 224 gops->securegpccs = 1;
diff --git a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
index 96919d2e..c4d097a7 100644
--- a/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/gr_gp10b.c
@@ -13,7 +13,6 @@
13 * more details. 13 * more details.
14 */ 14 */
15 15
16#include <linux/clk.h>
17#include <linux/delay.h> 16#include <linux/delay.h>
18#include <linux/version.h> 17#include <linux/version.h>
19#include <linux/vmalloc.h> 18#include <linux/vmalloc.h>
@@ -2255,12 +2254,11 @@ static int gp10b_gr_fuse_override(struct gk20a *g)
2255 2254
2256static int gr_gp10b_init_preemption_state(struct gk20a *g) 2255static int gr_gp10b_init_preemption_state(struct gk20a *g)
2257{ 2256{
2258 struct gk20a_platform *platform = gk20a_get_platform(g->dev);
2259 u32 debug_2; 2257 u32 debug_2;
2260 u64 sysclk_rate; 2258 u64 sysclk_rate;
2261 u32 sysclk_cycles; 2259 u32 sysclk_cycles;
2262 2260
2263 sysclk_rate = platform->clk_get_rate(g->dev); 2261 sysclk_rate = g->ops.clk.get_rate(g, CTRL_CLK_DOMAIN_GPCCLK);
2264 sysclk_cycles = (u32)((sysclk_rate * NVGPU_GFXP_WFI_TIMEOUT_US) / 1000000ULL); 2262 sysclk_cycles = (u32)((sysclk_rate * NVGPU_GFXP_WFI_TIMEOUT_US) / 1000000ULL);
2265 gk20a_writel(g, gr_fe_gfxp_wfi_timeout_r(), 2263 gk20a_writel(g, gr_fe_gfxp_wfi_timeout_r(),
2266 gr_fe_gfxp_wfi_timeout_count_f(sysclk_cycles)); 2264 gr_fe_gfxp_wfi_timeout_count_f(sysclk_cycles));
diff --git a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c
index b57fcb5f..18e1ffdc 100644
--- a/drivers/gpu/nvgpu/gp10b/hal_gp10b.c
+++ b/drivers/gpu/nvgpu/gp10b/hal_gp10b.c
@@ -193,7 +193,7 @@ int gp10b_init_hal(struct gk20a *g)
193 struct gk20a_platform *platform = dev_get_drvdata(g->dev); 193 struct gk20a_platform *platform = dev_get_drvdata(g->dev);
194 u32 val; 194 u32 val;
195 195
196 *gops = gp10b_ops; 196 gops->clock_gating = gp10b_ops.clock_gating;
197 gops->pmupstate = false; 197 gops->pmupstate = false;
198#ifdef CONFIG_TEGRA_ACR 198#ifdef CONFIG_TEGRA_ACR
199 if (platform->is_fmodel) { 199 if (platform->is_fmodel) {
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
23static 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
47static 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
72void 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
19struct gk20a;
20void 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)
978static 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
987static long gk20a_round_clk_rate(struct device *dev, unsigned long rate) 981static 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
995static 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
1003static int gk20a_clk_get_freqs(struct device *dev, 989static 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
332static 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
340static long gp10b_round_clk_rate(struct device *dev, unsigned long rate) 335static 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
355static 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
362static int gp10b_clk_get_freqs(struct device *dev, 350static 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 */