summaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDeepak Nibade <dnibade@nvidia.com>2017-05-16 09:33:02 -0400
committermobile promotions <svcmobile_promotions@nvidia.com>2017-05-24 07:55:53 -0400
commit6d2d3a3d9345661bc14af06a8b4462495205b743 (patch)
tree0d8317f78658296c3ecb85027dc3529918516222 /drivers/gpu
parent1eace20876b4136a1edf8287a9f37a693218efa8 (diff)
gpu: nvgpu: move linux clk calls to tegra specific file
clk_gm20b.c has number of calls specific to linux and tegra-soc environment In order to unify the driver, move all of those calls to tegra/linux specific file tegra/linux/clk.c All the clk_*() and tegra_dvfs_*() calls are now abstracted behind GPU's clock operations and shoule be accessed using g->ops.clk.<API> format Remove <linux/clk.h> and <soc/tegra/tegra-dvfs.h> from clk_gm20b.c Remove <linux/version.h> from clk_gm20b.c too since we only support k4.4 and higher version only Jira NVGPU-49 Change-Id: Ib26811e0423bbd3868b9a46e662b80a8ca088dc5 Signed-off-by: Deepak Nibade <dnibade@nvidia.com> Reviewed-on: http://git-master/r/1483092 Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/nvgpu/gk20a/gk20a.h7
-rw-r--r--drivers/gpu/nvgpu/gm20b/clk_gm20b.c39
-rw-r--r--drivers/gpu/nvgpu/tegra/linux/clk.c55
3 files changed, 69 insertions, 32 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/gk20a.h b/drivers/gpu/nvgpu/gk20a/gk20a.h
index 217b1186..cca414a2 100644
--- a/drivers/gpu/nvgpu/gk20a/gk20a.h
+++ b/drivers/gpu/nvgpu/gk20a/gk20a.h
@@ -762,6 +762,13 @@ struct gpu_ops {
762 unsigned long (*measure_freq)(struct gk20a *g, u32 api_domain); 762 unsigned long (*measure_freq)(struct gk20a *g, u32 api_domain);
763 unsigned long (*get_rate)(struct gk20a *g, u32 api_domain); 763 unsigned long (*get_rate)(struct gk20a *g, u32 api_domain);
764 int (*set_rate)(struct gk20a *g, u32 api_domain, unsigned long rate); 764 int (*set_rate)(struct gk20a *g, u32 api_domain, unsigned long rate);
765 unsigned long (*get_fmax_at_vmin_safe)(struct clk_gk20a *clk);
766 u32 (*get_ref_clock_rate)(struct gk20a *g);
767 int (*predict_mv_at_hz_cur_tfloor)(struct clk_gk20a *clk,
768 unsigned long rate);
769 unsigned long (*get_maxrate)(struct clk_gk20a *clk);
770 int (*prepare_enable)(struct clk_gk20a *clk);
771 void (*disable_unprepare)(struct clk_gk20a *clk);
765 } clk; 772 } clk;
766 struct { 773 struct {
767 u32 (*get_arbiter_clk_domains)(struct gk20a *g); 774 u32 (*get_arbiter_clk_domains)(struct gk20a *g);
diff --git a/drivers/gpu/nvgpu/gm20b/clk_gm20b.c b/drivers/gpu/nvgpu/gm20b/clk_gm20b.c
index 31ec419a..44ac4dd0 100644
--- a/drivers/gpu/nvgpu/gm20b/clk_gm20b.c
+++ b/drivers/gpu/nvgpu/gm20b/clk_gm20b.c
@@ -16,16 +16,11 @@
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/version.h>
20#include <linux/clk.h>
21#ifdef CONFIG_DEBUG_FS 19#ifdef CONFIG_DEBUG_FS
22#include <linux/debugfs.h> 20#include <linux/debugfs.h>
23#include <linux/uaccess.h> 21#include <linux/uaccess.h>
24#endif 22#endif
25#include <soc/tegra/fuse.h> 23#include <soc/tegra/fuse.h>
26#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
27#include <soc/tegra/tegra-dvfs.h>
28#endif
29 24
30#include "gk20a/gk20a.h" 25#include "gk20a/gk20a.h"
31#include "gk20a/platform_gk20a.h" 26#include "gk20a/platform_gk20a.h"
@@ -266,7 +261,6 @@ found_match:
266 261
267/* GPCPLL NA/DVFS mode methods */ 262/* GPCPLL NA/DVFS mode methods */
268 263
269#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0))
270#define FUSE_RESERVED_CALIB 0x204 264#define FUSE_RESERVED_CALIB 0x204
271 265
272static inline int fuse_get_gpcpll_adc_rev(u32 val) 266static inline int fuse_get_gpcpll_adc_rev(u32 val)
@@ -309,7 +303,6 @@ static bool tegra_fuse_can_use_na_gpcpll(void)
309 return tegra_sku_info.gpu_speedo_id; 303 return tegra_sku_info.gpu_speedo_id;
310} 304}
311#endif 305#endif
312#endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 4, 0)) */
313 306
314/* 307/*
315 * Read ADC characteristic parmeters from fuses. 308 * Read ADC characteristic parmeters from fuses.
@@ -396,12 +389,8 @@ static void clk_config_dvfs_ndiv(int mv, u32 n_eff, struct na_dvfs *d)
396static void clk_config_dvfs(struct gk20a *g, struct pll *gpll) 389static void clk_config_dvfs(struct gk20a *g, struct pll *gpll)
397{ 390{
398 struct na_dvfs *d = &gpll->dvfs; 391 struct na_dvfs *d = &gpll->dvfs;
399 struct clk* clk;
400
401 clk = g->clk.tegra_clk;
402 clk = clk_get_parent(clk);
403 392
404 d->mv = tegra_dvfs_predict_mv_at_hz_cur_tfloor(clk, 393 d->mv = g->ops.clk.predict_mv_at_hz_cur_tfloor(&g->clk,
405 rate_gpc2clk_to_gpu(gpll->freq)); 394 rate_gpc2clk_to_gpu(gpll->freq));
406 395
407 clk_config_dvfs_detection(d->mv, d); 396 clk_config_dvfs_detection(d->mv, d);
@@ -1135,7 +1124,6 @@ int gm20b_init_clk_setup_sw(struct gk20a *g)
1135{ 1124{
1136 struct clk_gk20a *clk = &g->clk; 1125 struct clk_gk20a *clk = &g->clk;
1137 unsigned long safe_rate; 1126 unsigned long safe_rate;
1138 struct clk *ref = NULL, *c;
1139 int err; 1127 int err;
1140 1128
1141 gk20a_dbg_fn(""); 1129 gk20a_dbg_fn("");
@@ -1164,28 +1152,14 @@ int gm20b_init_clk_setup_sw(struct gk20a *g)
1164 goto fail; 1152 goto fail;
1165 } 1153 }
1166 1154
1167 /* 1155 clk->gpc_pll.clk_in = g->ops.clk.get_ref_clock_rate(g) / KHZ;
1168 * On Tegra GPU clock exposed to frequency governor is a shared user on
1169 * GPCPLL bus (gbus). The latter can be accessed as GPU clock parent.
1170 * Respectively the grandparent is PLL reference clock.
1171 */
1172 c = clk_get_parent(clk->tegra_clk);
1173
1174 ref = clk_get_sys("gpu_ref", "gpu_ref");
1175 if (IS_ERR(ref)) {
1176 nvgpu_err(g, "failed to get GPCPLL reference clock");
1177 err = -EINVAL;
1178 goto fail;
1179 }
1180
1181 clk->gpc_pll.clk_in = clk_get_rate(ref) / KHZ;
1182 if (clk->gpc_pll.clk_in == 0) { 1156 if (clk->gpc_pll.clk_in == 0) {
1183 nvgpu_err(g, "GPCPLL reference clock is zero"); 1157 nvgpu_err(g, "GPCPLL reference clock is zero");
1184 err = -EINVAL; 1158 err = -EINVAL;
1185 goto fail; 1159 goto fail;
1186 } 1160 }
1187 1161
1188 safe_rate = tegra_dvfs_get_fmax_at_vmin_safe_t(c); 1162 safe_rate = g->ops.clk.get_fmax_at_vmin_safe(clk);
1189 safe_rate = safe_rate * (100 - DVFS_SAFE_MARGIN) / 100; 1163 safe_rate = safe_rate * (100 - DVFS_SAFE_MARGIN) / 100;
1190 dvfs_safe_max_freq = rate_gpu_to_gpc2clk(safe_rate); 1164 dvfs_safe_max_freq = rate_gpu_to_gpc2clk(safe_rate);
1191 clk->gpc_pll.PL = (dvfs_safe_max_freq == 0) ? 0 : 1165 clk->gpc_pll.PL = (dvfs_safe_max_freq == 0) ? 0 :
@@ -1286,8 +1260,9 @@ long gm20b_round_rate(struct clk_gk20a *clk, unsigned long rate,
1286 u32 freq; 1260 u32 freq;
1287 struct pll tmp_pll; 1261 struct pll tmp_pll;
1288 unsigned long maxrate; 1262 unsigned long maxrate;
1263 struct gk20a *g = clk->g;
1289 1264
1290 maxrate = tegra_dvfs_get_maxrate(clk_get_parent(clk->tegra_clk)); 1265 maxrate = g->ops.clk.get_maxrate(clk);
1291 if (rate > maxrate) 1266 if (rate > maxrate)
1292 rate = maxrate; 1267 rate = maxrate;
1293 1268
@@ -1426,7 +1401,7 @@ static int gm20b_init_clk_support(struct gk20a *g)
1426 return err; 1401 return err;
1427 1402
1428 /* FIXME: this effectively prevents host level clock gating */ 1403 /* FIXME: this effectively prevents host level clock gating */
1429 err = clk_prepare_enable(g->clk.tegra_clk); 1404 err = g->ops.clk.prepare_enable(&g->clk);
1430 if (err) 1405 if (err)
1431 return err; 1406 return err;
1432 1407
@@ -1451,7 +1426,7 @@ static int gm20b_suspend_clk_support(struct gk20a *g)
1451{ 1426{
1452 int ret = 0; 1427 int ret = 0;
1453 1428
1454 clk_disable_unprepare(g->clk.tegra_clk); 1429 g->ops.clk.disable_unprepare(&g->clk);
1455 1430
1456 /* The prev call may not disable PLL if gbus is unbalanced - force it */ 1431 /* The prev call may not disable PLL if gbus is unbalanced - force it */
1457 nvgpu_mutex_acquire(&g->clk.clk_mutex); 1432 nvgpu_mutex_acquire(&g->clk.clk_mutex);
diff --git a/drivers/gpu/nvgpu/tegra/linux/clk.c b/drivers/gpu/nvgpu/tegra/linux/clk.c
index a82076c7..775e5661 100644
--- a/drivers/gpu/nvgpu/tegra/linux/clk.c
+++ b/drivers/gpu/nvgpu/tegra/linux/clk.c
@@ -17,6 +17,9 @@
17 */ 17 */
18 18
19#include <linux/clk.h> 19#include <linux/clk.h>
20#include <linux/version.h>
21
22#include <soc/tegra/tegra-dvfs.h>
20 23
21#include "clk.h" 24#include "clk.h"
22#include "gk20a/gk20a.h" 25#include "gk20a/gk20a.h"
@@ -71,8 +74,60 @@ static int nvgpu_linux_clk_set_rate(struct gk20a *g,
71 return ret; 74 return ret;
72} 75}
73 76
77static unsigned long nvgpu_linux_get_fmax_at_vmin_safe(struct clk_gk20a *clk)
78{
79 /*
80 * On Tegra GPU clock exposed to frequency governor is a shared user on
81 * GPCPLL bus (gbus). The latter can be accessed as GPU clock parent.
82 * Respectively the grandparent is PLL reference clock.
83 */
84 return tegra_dvfs_get_fmax_at_vmin_safe_t(
85 clk_get_parent(clk->tegra_clk));
86}
87
88static u32 nvgpu_linux_get_ref_clock_rate(struct gk20a *g)
89{
90 struct clk *c;
91
92 c = clk_get_sys("gpu_ref", "gpu_ref");
93 if (IS_ERR(c)) {
94 nvgpu_err(g, "failed to get GPCPLL reference clock");
95 return 0;
96 }
97
98 return clk_get_rate(c);
99}
100
101static int nvgpu_linux_predict_mv_at_hz_cur_tfloor(struct clk_gk20a *clk,
102 unsigned long rate)
103{
104 return tegra_dvfs_predict_mv_at_hz_cur_tfloor(
105 clk_get_parent(clk->tegra_clk), rate);
106}
107
108static unsigned long nvgpu_linux_get_maxrate(struct clk_gk20a *clk)
109{
110 return tegra_dvfs_get_maxrate(clk_get_parent(clk->tegra_clk));
111}
112
113static int nvgpu_linux_prepare_enable(struct clk_gk20a *clk)
114{
115 return clk_prepare_enable(clk->tegra_clk);
116}
117
118static void nvgpu_linux_disable_unprepare(struct clk_gk20a *clk)
119{
120 clk_disable_unprepare(clk->tegra_clk);
121}
122
74void nvgpu_linux_init_clk_support(struct gk20a *g) 123void nvgpu_linux_init_clk_support(struct gk20a *g)
75{ 124{
76 g->ops.clk.get_rate = nvgpu_linux_clk_get_rate; 125 g->ops.clk.get_rate = nvgpu_linux_clk_get_rate;
77 g->ops.clk.set_rate = nvgpu_linux_clk_set_rate; 126 g->ops.clk.set_rate = nvgpu_linux_clk_set_rate;
127 g->ops.clk.get_fmax_at_vmin_safe = nvgpu_linux_get_fmax_at_vmin_safe;
128 g->ops.clk.get_ref_clock_rate = nvgpu_linux_get_ref_clock_rate;
129 g->ops.clk.predict_mv_at_hz_cur_tfloor = nvgpu_linux_predict_mv_at_hz_cur_tfloor;
130 g->ops.clk.get_maxrate = nvgpu_linux_get_maxrate;
131 g->ops.clk.prepare_enable = nvgpu_linux_prepare_enable;
132 g->ops.clk.disable_unprepare = nvgpu_linux_disable_unprepare;
78} 133}