gpu: nvgpu: Fork GM20B clock from GK20A clock
[linux-3.10.git] / drivers / gpu / nvgpu / gm20b / clk_gm20b.c
1 /*
2  * GM20B Clocks
3  *
4  * Copyright (c) 2014, 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 #include <linux/delay.h>        /* for mdelay */
21 #include <linux/module.h>
22 #include <linux/debugfs.h>
23 #include <linux/clk/tegra.h>
24 #include <mach/thermal.h>
25
26 #include "gk20a/gk20a.h"
27 #include "gk20a/hw_trim_gk20a.h"
28 #include "gk20a/hw_timer_gk20a.h"
29 #include "clk_gm20b.h"
30
31 #define gk20a_dbg_clk(fmt, arg...) \
32         gk20a_dbg(gpu_dbg_clk, fmt, ##arg)
33
34 /* from vbios PLL info table */
35 static struct pll_parms gpc_pll_params = {
36         144000, 2064000,        /* freq */
37         1000000, 2064000,       /* vco */
38         12000, 38000,           /* u */
39         1, 255,                 /* M */
40         8, 255,                 /* N */
41         1, 32,                  /* PL */
42 };
43
44 #ifdef CONFIG_DEBUG_FS
45 static int clk_gm20b_debugfs_init(struct gk20a *g);
46 #endif
47
48 static u8 pl_to_div[] = {
49 /* PL:   0, 1, 2, 3, 4, 5, 6,  7,  8,  9, 10, 11, 12, 13, 14 */
50 /* p: */ 1, 2, 3, 4, 5, 6, 8, 10, 12, 16, 12, 16, 20, 24, 32 };
51
52 /* Calculate and update M/N/PL as well as pll->freq
53     ref_clk_f = clk_in_f / src_div = clk_in_f; (src_div = 1 on gk20a)
54     u_f = ref_clk_f / M;
55     PLL output = vco_f = u_f * N = ref_clk_f * N / M;
56     gpc2clk = target clock frequency = vco_f / PL;
57     gpcclk = gpc2clk / 2; */
58 static int clk_config_pll(struct clk_gk20a *clk, struct pll *pll,
59         struct pll_parms *pll_params, u32 *target_freq, bool best_fit)
60 {
61         u32 min_vco_f, max_vco_f;
62         u32 best_M, best_N;
63         u32 low_PL, high_PL, best_PL;
64         u32 m, n, n2;
65         u32 target_vco_f, vco_f;
66         u32 ref_clk_f, target_clk_f, u_f;
67         u32 delta, lwv, best_delta = ~0;
68         int pl;
69
70         BUG_ON(target_freq == NULL);
71
72         gk20a_dbg_fn("request target freq %d MHz", *target_freq);
73
74         ref_clk_f = pll->clk_in;
75         target_clk_f = *target_freq;
76         max_vco_f = pll_params->max_vco;
77         min_vco_f = pll_params->min_vco;
78         best_M = pll_params->max_M;
79         best_N = pll_params->min_N;
80         best_PL = pll_params->min_PL;
81
82         target_vco_f = target_clk_f + target_clk_f / 50;
83         if (max_vco_f < target_vco_f)
84                 max_vco_f = target_vco_f;
85
86         high_PL = (max_vco_f + target_vco_f - 1) / target_vco_f;
87         high_PL = min(high_PL, pll_params->max_PL);
88         high_PL = max(high_PL, pll_params->min_PL);
89
90         low_PL = min_vco_f / target_vco_f;
91         low_PL = min(low_PL, pll_params->max_PL);
92         low_PL = max(low_PL, pll_params->min_PL);
93
94         /* Find Indices of high_PL and low_PL */
95         for (pl = 0; pl < 14; pl++) {
96                 if (pl_to_div[pl] >= low_PL) {
97                         low_PL = pl;
98                         break;
99                 }
100         }
101         for (pl = 0; pl < 14; pl++) {
102                 if (pl_to_div[pl] >= high_PL) {
103                         high_PL = pl;
104                         break;
105                 }
106         }
107         gk20a_dbg_info("low_PL %d(div%d), high_PL %d(div%d)",
108                         low_PL, pl_to_div[low_PL], high_PL, pl_to_div[high_PL]);
109
110         for (pl = low_PL; pl <= high_PL; pl++) {
111                 target_vco_f = target_clk_f * pl_to_div[pl];
112
113                 for (m = pll_params->min_M; m <= pll_params->max_M; m++) {
114                         u_f = ref_clk_f / m;
115
116                         if (u_f < pll_params->min_u)
117                                 break;
118                         if (u_f > pll_params->max_u)
119                                 continue;
120
121                         n = (target_vco_f * m) / ref_clk_f;
122                         n2 = ((target_vco_f * m) + (ref_clk_f - 1)) / ref_clk_f;
123
124                         if (n > pll_params->max_N)
125                                 break;
126
127                         for (; n <= n2; n++) {
128                                 if (n < pll_params->min_N)
129                                         continue;
130                                 if (n > pll_params->max_N)
131                                         break;
132
133                                 vco_f = ref_clk_f * n / m;
134
135                                 if (vco_f >= min_vco_f && vco_f <= max_vco_f) {
136                                         lwv = (vco_f + (pl_to_div[pl] / 2))
137                                                 / pl_to_div[pl];
138                                         delta = abs(lwv - target_clk_f);
139
140                                         if (delta < best_delta) {
141                                                 best_delta = delta;
142                                                 best_M = m;
143                                                 best_N = n;
144                                                 best_PL = pl;
145
146                                                 if (best_delta == 0 ||
147                                                     /* 0.45% for non best fit */
148                                                     (!best_fit && (vco_f / best_delta > 218))) {
149                                                         goto found_match;
150                                                 }
151
152                                                 gk20a_dbg_info("delta %d @ M %d, N %d, PL %d",
153                                                         delta, m, n, pl);
154                                         }
155                                 }
156                         }
157                 }
158         }
159
160 found_match:
161         BUG_ON(best_delta == ~0);
162
163         if (best_fit && best_delta != 0)
164                 gk20a_dbg_clk("no best match for target @ %dMHz on gpc_pll",
165                         target_clk_f);
166
167         pll->M = best_M;
168         pll->N = best_N;
169         pll->PL = best_PL;
170
171         /* save current frequency */
172         pll->freq = ref_clk_f * pll->N / (pll->M * pl_to_div[pll->PL]);
173
174         *target_freq = pll->freq;
175
176         gk20a_dbg_clk("actual target freq %d MHz, M %d, N %d, PL %d(div%d)",
177                 *target_freq, pll->M, pll->N, pll->PL, pl_to_div[pll->PL]);
178
179         gk20a_dbg_fn("done");
180
181         return 0;
182 }
183
184 static int clk_slide_gpc_pll(struct gk20a *g, u32 n)
185 {
186         u32 data, coeff;
187         u32 nold;
188         int ramp_timeout = 500;
189
190         /* get old coefficients */
191         coeff = gk20a_readl(g, trim_sys_gpcpll_coeff_r());
192         nold = trim_sys_gpcpll_coeff_ndiv_v(coeff);
193
194         /* do nothing if NDIV is same */
195         if (n == nold)
196                 return 0;
197
198         /* setup */
199         data = gk20a_readl(g, trim_sys_gpcpll_cfg2_r());
200         data = set_field(data, trim_sys_gpcpll_cfg2_pll_stepa_m(),
201                         trim_sys_gpcpll_cfg2_pll_stepa_f(0x2b));
202         gk20a_writel(g, trim_sys_gpcpll_cfg2_r(), data);
203         data = gk20a_readl(g, trim_sys_gpcpll_cfg3_r());
204         data = set_field(data, trim_sys_gpcpll_cfg3_pll_stepb_m(),
205                         trim_sys_gpcpll_cfg3_pll_stepb_f(0xb));
206         gk20a_writel(g, trim_sys_gpcpll_cfg3_r(), data);
207
208         /* pll slowdown mode */
209         data = gk20a_readl(g, trim_sys_gpcpll_ndiv_slowdown_r());
210         data = set_field(data,
211                         trim_sys_gpcpll_ndiv_slowdown_slowdown_using_pll_m(),
212                         trim_sys_gpcpll_ndiv_slowdown_slowdown_using_pll_yes_f());
213         gk20a_writel(g, trim_sys_gpcpll_ndiv_slowdown_r(), data);
214
215         /* new ndiv ready for ramp */
216         coeff = gk20a_readl(g, trim_sys_gpcpll_coeff_r());
217         coeff = set_field(coeff, trim_sys_gpcpll_coeff_ndiv_m(),
218                         trim_sys_gpcpll_coeff_ndiv_f(n));
219         udelay(1);
220         gk20a_writel(g, trim_sys_gpcpll_coeff_r(), coeff);
221
222         /* dynamic ramp to new ndiv */
223         data = gk20a_readl(g, trim_sys_gpcpll_ndiv_slowdown_r());
224         data = set_field(data,
225                         trim_sys_gpcpll_ndiv_slowdown_en_dynramp_m(),
226                         trim_sys_gpcpll_ndiv_slowdown_en_dynramp_yes_f());
227         udelay(1);
228         gk20a_writel(g, trim_sys_gpcpll_ndiv_slowdown_r(), data);
229
230         do {
231                 udelay(1);
232                 ramp_timeout--;
233                 data = gk20a_readl(
234                         g, trim_gpc_bcast_gpcpll_ndiv_slowdown_debug_r());
235                 if (trim_gpc_bcast_gpcpll_ndiv_slowdown_debug_pll_dynramp_done_synced_v(data))
236                         break;
237         } while (ramp_timeout > 0);
238
239         /* exit slowdown mode */
240         data = gk20a_readl(g, trim_sys_gpcpll_ndiv_slowdown_r());
241         data = set_field(data,
242                         trim_sys_gpcpll_ndiv_slowdown_slowdown_using_pll_m(),
243                         trim_sys_gpcpll_ndiv_slowdown_slowdown_using_pll_no_f());
244         data = set_field(data,
245                         trim_sys_gpcpll_ndiv_slowdown_en_dynramp_m(),
246                         trim_sys_gpcpll_ndiv_slowdown_en_dynramp_no_f());
247         gk20a_writel(g, trim_sys_gpcpll_ndiv_slowdown_r(), data);
248         gk20a_readl(g, trim_sys_gpcpll_ndiv_slowdown_r());
249
250         if (ramp_timeout <= 0) {
251                 gk20a_err(dev_from_gk20a(g), "gpcpll dynamic ramp timeout");
252                 return -ETIMEDOUT;
253         }
254         return 0;
255 }
256
257 static int clk_program_gpc_pll(struct gk20a *g, struct clk_gk20a *clk,
258                         int allow_slide)
259 {
260         u32 data, cfg, coeff, timeout;
261         u32 m, n, pl;
262         u32 nlo;
263
264         gk20a_dbg_fn("");
265
266         if (!tegra_platform_is_silicon())
267                 return 0;
268
269         /* get old coefficients */
270         coeff = gk20a_readl(g, trim_sys_gpcpll_coeff_r());
271         m = trim_sys_gpcpll_coeff_mdiv_v(coeff);
272         n = trim_sys_gpcpll_coeff_ndiv_v(coeff);
273         pl = trim_sys_gpcpll_coeff_pldiv_v(coeff);
274
275         /* do NDIV slide if there is no change in M and PL */
276         cfg = gk20a_readl(g, trim_sys_gpcpll_cfg_r());
277         if (allow_slide && clk->gpc_pll.M == m && clk->gpc_pll.PL == pl
278                 && trim_sys_gpcpll_cfg_enable_v(cfg)) {
279                 return clk_slide_gpc_pll(g, clk->gpc_pll.N);
280         }
281
282         /* slide down to NDIV_LO */
283         nlo = DIV_ROUND_UP(m * gpc_pll_params.min_vco, clk->gpc_pll.clk_in);
284         if (allow_slide && trim_sys_gpcpll_cfg_enable_v(cfg)) {
285                 int ret = clk_slide_gpc_pll(g, nlo);
286                 if (ret)
287                         return ret;
288         }
289
290         /* split FO-to-bypass jump in halfs by setting out divider 1:2 */
291         data = gk20a_readl(g, trim_sys_gpc2clk_out_r());
292         data = set_field(data, trim_sys_gpc2clk_out_vcodiv_m(),
293                 trim_sys_gpc2clk_out_vcodiv_f(2));
294         gk20a_writel(g, trim_sys_gpc2clk_out_r(), data);
295
296         /* put PLL in bypass before programming it */
297         data = gk20a_readl(g, trim_sys_sel_vco_r());
298         data = set_field(data, trim_sys_sel_vco_gpc2clk_out_m(),
299                 trim_sys_sel_vco_gpc2clk_out_bypass_f());
300         udelay(2);
301         gk20a_writel(g, trim_sys_sel_vco_r(), data);
302
303         /* get out from IDDQ */
304         cfg = gk20a_readl(g, trim_sys_gpcpll_cfg_r());
305         if (trim_sys_gpcpll_cfg_iddq_v(cfg)) {
306                 cfg = set_field(cfg, trim_sys_gpcpll_cfg_iddq_m(),
307                                 trim_sys_gpcpll_cfg_iddq_power_on_v());
308                 gk20a_writel(g, trim_sys_gpcpll_cfg_r(), cfg);
309                 gk20a_readl(g, trim_sys_gpcpll_cfg_r());
310                 udelay(2);
311         }
312
313         /* disable PLL before changing coefficients */
314         cfg = gk20a_readl(g, trim_sys_gpcpll_cfg_r());
315         cfg = set_field(cfg, trim_sys_gpcpll_cfg_enable_m(),
316                         trim_sys_gpcpll_cfg_enable_no_f());
317         gk20a_writel(g, trim_sys_gpcpll_cfg_r(), cfg);
318         gk20a_readl(g, trim_sys_gpcpll_cfg_r());
319
320         /* change coefficients */
321         nlo = DIV_ROUND_UP(clk->gpc_pll.M * gpc_pll_params.min_vco,
322                         clk->gpc_pll.clk_in);
323         coeff = trim_sys_gpcpll_coeff_mdiv_f(clk->gpc_pll.M) |
324                 trim_sys_gpcpll_coeff_ndiv_f(allow_slide ?
325                                              nlo : clk->gpc_pll.N) |
326                 trim_sys_gpcpll_coeff_pldiv_f(clk->gpc_pll.PL);
327         gk20a_writel(g, trim_sys_gpcpll_coeff_r(), coeff);
328
329         /* enable PLL after changing coefficients */
330         cfg = gk20a_readl(g, trim_sys_gpcpll_cfg_r());
331         cfg = set_field(cfg, trim_sys_gpcpll_cfg_enable_m(),
332                         trim_sys_gpcpll_cfg_enable_yes_f());
333         gk20a_writel(g, trim_sys_gpcpll_cfg_r(), cfg);
334
335         /* lock pll */
336         cfg = gk20a_readl(g, trim_sys_gpcpll_cfg_r());
337         if (cfg & trim_sys_gpcpll_cfg_enb_lckdet_power_off_f()){
338                 cfg = set_field(cfg, trim_sys_gpcpll_cfg_enb_lckdet_m(),
339                         trim_sys_gpcpll_cfg_enb_lckdet_power_on_f());
340                 gk20a_writel(g, trim_sys_gpcpll_cfg_r(), cfg);
341         }
342
343         /* wait pll lock */
344         timeout = clk->pll_delay / 2 + 1;
345         do {
346                 cfg = gk20a_readl(g, trim_sys_gpcpll_cfg_r());
347                 if (cfg & trim_sys_gpcpll_cfg_pll_lock_true_f())
348                         goto pll_locked;
349                 udelay(2);
350         } while (--timeout > 0);
351
352         /* PLL is messed up. What can we do here? */
353         BUG();
354         return -EBUSY;
355
356 pll_locked:
357         /* put PLL back on vco */
358         data = gk20a_readl(g, trim_sys_sel_vco_r());
359         data = set_field(data, trim_sys_sel_vco_gpc2clk_out_m(),
360                 trim_sys_sel_vco_gpc2clk_out_vco_f());
361         gk20a_writel(g, trim_sys_sel_vco_r(), data);
362         clk->gpc_pll.enabled = true;
363
364         /* restore out divider 1:1 */
365         data = gk20a_readl(g, trim_sys_gpc2clk_out_r());
366         data = set_field(data, trim_sys_gpc2clk_out_vcodiv_m(),
367                 trim_sys_gpc2clk_out_vcodiv_by1_f());
368         udelay(2);
369         gk20a_writel(g, trim_sys_gpc2clk_out_r(), data);
370
371         /* slide up to target NDIV */
372         return clk_slide_gpc_pll(g, clk->gpc_pll.N);
373 }
374
375 static int clk_disable_gpcpll(struct gk20a *g, int allow_slide)
376 {
377         u32 cfg, coeff, m, nlo;
378         struct clk_gk20a *clk = &g->clk;
379
380         /* slide to VCO min */
381         cfg = gk20a_readl(g, trim_sys_gpcpll_cfg_r());
382         if (allow_slide && trim_sys_gpcpll_cfg_enable_v(cfg)) {
383                 coeff = gk20a_readl(g, trim_sys_gpcpll_coeff_r());
384                 m = trim_sys_gpcpll_coeff_mdiv_v(coeff);
385                 nlo = DIV_ROUND_UP(m * gpc_pll_params.min_vco,
386                                    clk->gpc_pll.clk_in);
387                 clk_slide_gpc_pll(g, nlo);
388         }
389
390         /* put PLL in bypass before disabling it */
391         cfg = gk20a_readl(g, trim_sys_sel_vco_r());
392         cfg = set_field(cfg, trim_sys_sel_vco_gpc2clk_out_m(),
393                         trim_sys_sel_vco_gpc2clk_out_bypass_f());
394         gk20a_writel(g, trim_sys_sel_vco_r(), cfg);
395
396         /* disable PLL */
397         cfg = gk20a_readl(g, trim_sys_gpcpll_cfg_r());
398         cfg = set_field(cfg, trim_sys_gpcpll_cfg_enable_m(),
399                         trim_sys_gpcpll_cfg_enable_no_f());
400         gk20a_writel(g, trim_sys_gpcpll_cfg_r(), cfg);
401         gk20a_readl(g, trim_sys_gpcpll_cfg_r());
402
403         clk->gpc_pll.enabled = false;
404         return 0;
405 }
406
407 static int gm20b_init_clk_reset_enable_hw(struct gk20a *g)
408 {
409         gk20a_dbg_fn("");
410         return 0;
411 }
412
413 struct clk *gm20b_clk_get(struct gk20a *g)
414 {
415         if (!g->clk.tegra_clk) {
416                 struct clk *clk;
417
418                 clk = clk_get_sys("tegra_gk20a", "gpu");
419                 if (IS_ERR(clk)) {
420                         gk20a_err(dev_from_gk20a(g),
421                                 "fail to get tegra gpu clk tegra_gk20a/gpu");
422                         return NULL;
423                 }
424                 g->clk.tegra_clk = clk;
425         }
426
427         return g->clk.tegra_clk;
428 }
429
430 static int gm20b_init_clk_setup_sw(struct gk20a *g)
431 {
432         struct clk_gk20a *clk = &g->clk;
433         static int initialized;
434         struct clk *ref;
435         unsigned long ref_rate;
436
437         gk20a_dbg_fn("");
438
439         if (clk->sw_ready) {
440                 gk20a_dbg_fn("skip init");
441                 return 0;
442         }
443
444         if (!gk20a_clk_get(g))
445                 return -EINVAL;
446
447         ref = clk_get_parent(clk_get_parent(clk->tegra_clk));
448         if (IS_ERR(ref)) {
449                 gk20a_err(dev_from_gk20a(g),
450                         "failed to get GPCPLL reference clock");
451                 return -EINVAL;
452         }
453         ref_rate = clk_get_rate(ref);
454
455         clk->pll_delay = 300; /* usec */
456
457         clk->gpc_pll.id = GK20A_GPC_PLL;
458         clk->gpc_pll.clk_in = ref_rate / KHZ;
459
460         /* Decide initial frequency */
461         if (!initialized) {
462                 initialized = 1;
463                 clk->gpc_pll.M = 1;
464                 clk->gpc_pll.N = DIV_ROUND_UP(gpc_pll_params.min_vco,
465                                         clk->gpc_pll.clk_in);
466                 clk->gpc_pll.PL = 1;
467                 clk->gpc_pll.freq = clk->gpc_pll.clk_in * clk->gpc_pll.N;
468                 clk->gpc_pll.freq /= pl_to_div[clk->gpc_pll.PL];
469         }
470
471         mutex_init(&clk->clk_mutex);
472
473         clk->sw_ready = true;
474
475         gk20a_dbg_fn("done");
476         return 0;
477 }
478
479 static int gm20b_init_clk_setup_hw(struct gk20a *g)
480 {
481         u32 data;
482
483         gk20a_dbg_fn("");
484
485         data = gk20a_readl(g, trim_sys_gpc2clk_out_r());
486         data = set_field(data,
487                         trim_sys_gpc2clk_out_sdiv14_m() |
488                         trim_sys_gpc2clk_out_vcodiv_m() |
489                         trim_sys_gpc2clk_out_bypdiv_m(),
490                         trim_sys_gpc2clk_out_sdiv14_indiv4_mode_f() |
491                         trim_sys_gpc2clk_out_vcodiv_by1_f() |
492                         trim_sys_gpc2clk_out_bypdiv_f(0));
493         gk20a_writel(g, trim_sys_gpc2clk_out_r(), data);
494
495         return 0;
496 }
497
498 static int set_pll_target(struct gk20a *g, u32 freq, u32 old_freq)
499 {
500         struct clk_gk20a *clk = &g->clk;
501
502         if (freq > gpc_pll_params.max_freq)
503                 freq = gpc_pll_params.max_freq;
504         else if (freq < gpc_pll_params.min_freq)
505                 freq = gpc_pll_params.min_freq;
506
507         if (freq != old_freq) {
508                 /* gpc_pll.freq is changed to new value here */
509                 if (clk_config_pll(clk, &clk->gpc_pll, &gpc_pll_params,
510                                    &freq, true)) {
511                         gk20a_err(dev_from_gk20a(g),
512                                    "failed to set pll target for %d", freq);
513                         return -EINVAL;
514                 }
515         }
516         return 0;
517 }
518
519 static int set_pll_freq(struct gk20a *g, u32 freq, u32 old_freq)
520 {
521         struct clk_gk20a *clk = &g->clk;
522         int err = 0;
523
524         gk20a_dbg_fn("curr freq: %dMHz, target freq %dMHz", old_freq, freq);
525
526         if ((freq == old_freq) && clk->gpc_pll.enabled)
527                 return 0;
528
529         /* change frequency only if power is on */
530         if (g->clk.clk_hw_on) {
531                 err = clk_program_gpc_pll(g, clk, 1);
532                 if (err)
533                         err = clk_program_gpc_pll(g, clk, 0);
534         }
535
536         /* Just report error but not restore PLL since dvfs could already change
537             voltage even when it returns error. */
538         if (err)
539                 gk20a_err(dev_from_gk20a(g),
540                         "failed to set pll to %d", freq);
541         return err;
542 }
543
544 static int gm20b_clk_export_set_rate(void *data, unsigned long *rate)
545 {
546         u32 old_freq;
547         int ret = -ENODATA;
548         struct gk20a *g = data;
549         struct clk_gk20a *clk = &g->clk;
550
551         if (rate) {
552                 mutex_lock(&clk->clk_mutex);
553                 old_freq = clk->gpc_pll.freq;
554                 ret = set_pll_target(g, rate_gpu_to_gpc2clk(*rate), old_freq);
555                 if (!ret && clk->gpc_pll.enabled)
556                         ret = set_pll_freq(g, clk->gpc_pll.freq, old_freq);
557                 if (!ret)
558                         *rate = rate_gpc2clk_to_gpu(clk->gpc_pll.freq);
559                 mutex_unlock(&clk->clk_mutex);
560         }
561         return ret;
562 }
563
564 static int gm20b_clk_export_enable(void *data)
565 {
566         int ret;
567         struct gk20a *g = data;
568         struct clk_gk20a *clk = &g->clk;
569
570         mutex_lock(&clk->clk_mutex);
571         ret = set_pll_freq(g, clk->gpc_pll.freq, clk->gpc_pll.freq);
572         mutex_unlock(&clk->clk_mutex);
573         return ret;
574 }
575
576 static void gm20b_clk_export_disable(void *data)
577 {
578         struct gk20a *g = data;
579         struct clk_gk20a *clk = &g->clk;
580
581         mutex_lock(&clk->clk_mutex);
582         if (g->clk.clk_hw_on)
583                 clk_disable_gpcpll(g, 1);
584         mutex_unlock(&clk->clk_mutex);
585 }
586
587 static void gm20b_clk_export_init(void *data, unsigned long *rate, bool *state)
588 {
589         struct gk20a *g = data;
590         struct clk_gk20a *clk = &g->clk;
591
592         mutex_lock(&clk->clk_mutex);
593         if (state)
594                 *state = clk->gpc_pll.enabled;
595         if (rate)
596                 *rate = rate_gpc2clk_to_gpu(clk->gpc_pll.freq);
597         mutex_unlock(&clk->clk_mutex);
598 }
599
600 static struct tegra_clk_export_ops gm20b_clk_export_ops = {
601         .init = gm20b_clk_export_init,
602         .enable = gm20b_clk_export_enable,
603         .disable = gm20b_clk_export_disable,
604         .set_rate = gm20b_clk_export_set_rate,
605 };
606
607 static int gm20b_clk_register_export_ops(struct gk20a *g)
608 {
609         int ret;
610         struct clk *c;
611
612         if (gm20b_clk_export_ops.data)
613                 return 0;
614
615         gm20b_clk_export_ops.data = (void *)g;
616         c = g->clk.tegra_clk;
617         if (!c || !clk_get_parent(c))
618                 return -ENOSYS;
619
620         ret = tegra_clk_register_export_ops(clk_get_parent(c),
621                                             &gm20b_clk_export_ops);
622
623         return ret;
624 }
625
626 int gm20b_init_clk_support(struct gk20a *g)
627 {
628         struct clk_gk20a *clk = &g->clk;
629         u32 err;
630
631         gk20a_dbg_fn("");
632
633         clk->g = g;
634
635         err = gm20b_init_clk_reset_enable_hw(g);
636         if (err)
637                 return err;
638
639         err = gm20b_init_clk_setup_sw(g);
640         if (err)
641                 return err;
642
643         mutex_lock(&clk->clk_mutex);
644         clk->clk_hw_on = true;
645
646         err = gm20b_init_clk_setup_hw(g);
647         mutex_unlock(&clk->clk_mutex);
648         if (err)
649                 return err;
650
651         err = gm20b_clk_register_export_ops(g);
652         if (err)
653                 return err;
654
655         /* FIXME: this effectively prevents host level clock gating */
656         err = clk_enable(g->clk.tegra_clk);
657         if (err)
658                 return err;
659
660         /* The prev call may not enable PLL if gbus is unbalanced - force it */
661         mutex_lock(&clk->clk_mutex);
662         err = set_pll_freq(g, clk->gpc_pll.freq, clk->gpc_pll.freq);
663         mutex_unlock(&clk->clk_mutex);
664         if (err)
665                 return err;
666
667 #ifdef CONFIG_DEBUG_FS
668         if (!clk->debugfs_set) {
669                 if (!clk_gm20b_debugfs_init(g))
670                         clk->debugfs_set = true;
671         }
672 #endif
673         return err;
674 }
675
676 void gm20b_init_clk_ops(struct gpu_ops *gops)
677 {
678         gops->clk.init_clk_support = gm20b_init_clk_support;
679         gops->clk.suspend_clk_support = gm20b_suspend_clk_support;
680 }
681
682 int gm20b_suspend_clk_support(struct gk20a *g)
683 {
684         int ret;
685
686         clk_disable(g->clk.tegra_clk);
687
688         /* The prev call may not disable PLL if gbus is unbalanced - force it */
689         mutex_lock(&g->clk.clk_mutex);
690         ret = clk_disable_gpcpll(g, 1);
691         g->clk.clk_hw_on = false;
692         mutex_unlock(&g->clk.clk_mutex);
693         return ret;
694 }
695
696 #ifdef CONFIG_DEBUG_FS
697
698 static int rate_get(void *data, u64 *val)
699 {
700         struct gk20a *g = (struct gk20a *)data;
701         *val = (u64)gk20a_clk_get_rate(g);
702         return 0;
703 }
704 static int rate_set(void *data, u64 val)
705 {
706         struct gk20a *g = (struct gk20a *)data;
707         return gk20a_clk_set_rate(g, (u32)val);
708 }
709 DEFINE_SIMPLE_ATTRIBUTE(rate_fops, rate_get, rate_set, "%llu\n");
710
711 static int pll_reg_show(struct seq_file *s, void *data)
712 {
713         struct gk20a *g = s->private;
714         u32 reg, m, n, pl, f;
715
716         mutex_lock(&g->clk.clk_mutex);
717         if (!g->clk.clk_hw_on) {
718                 seq_printf(s, "gk20a powered down - no access to registers\n");
719                 mutex_unlock(&g->clk.clk_mutex);
720                 return 0;
721         }
722
723         reg = gk20a_readl(g, trim_sys_gpcpll_cfg_r());
724         seq_printf(s, "cfg  = 0x%x : %s : %s\n", reg,
725                    trim_sys_gpcpll_cfg_enable_v(reg) ? "enabled" : "disabled",
726                    trim_sys_gpcpll_cfg_pll_lock_v(reg) ? "locked" : "unlocked");
727
728         reg = gk20a_readl(g, trim_sys_gpcpll_coeff_r());
729         m = trim_sys_gpcpll_coeff_mdiv_v(reg);
730         n = trim_sys_gpcpll_coeff_ndiv_v(reg);
731         pl = trim_sys_gpcpll_coeff_pldiv_v(reg);
732         f = g->clk.gpc_pll.clk_in * n / (m * pl_to_div[pl]);
733         seq_printf(s, "coef = 0x%x : m = %u : n = %u : pl = %u", reg, m, n, pl);
734         seq_printf(s, " : pll_f(gpu_f) = %u(%u) kHz\n", f, f/2);
735         mutex_unlock(&g->clk.clk_mutex);
736         return 0;
737 }
738
739 static int pll_reg_open(struct inode *inode, struct file *file)
740 {
741         return single_open(file, pll_reg_show, inode->i_private);
742 }
743
744 static const struct file_operations pll_reg_fops = {
745         .open           = pll_reg_open,
746         .read           = seq_read,
747         .llseek         = seq_lseek,
748         .release        = single_release,
749 };
750
751 static int monitor_get(void *data, u64 *val)
752 {
753         struct gk20a *g = (struct gk20a *)data;
754         struct clk_gk20a *clk = &g->clk;
755         int err;
756
757         u32 ncycle = 100; /* count GPCCLK for ncycle of clkin */
758         u64 freq = clk->gpc_pll.clk_in;
759         u32 count1, count2;
760
761         err = gk20a_busy(g->dev);
762         if (err)
763                 return err;
764
765         gk20a_writel(g, trim_gpc_clk_cntr_ncgpcclk_cfg_r(0),
766                      trim_gpc_clk_cntr_ncgpcclk_cfg_reset_asserted_f());
767         gk20a_writel(g, trim_gpc_clk_cntr_ncgpcclk_cfg_r(0),
768                      trim_gpc_clk_cntr_ncgpcclk_cfg_enable_asserted_f() |
769                      trim_gpc_clk_cntr_ncgpcclk_cfg_write_en_asserted_f() |
770                      trim_gpc_clk_cntr_ncgpcclk_cfg_noofipclks_f(ncycle));
771         /* start */
772
773         /* It should take about 8us to finish 100 cycle of 12MHz.
774            But longer than 100us delay is required here. */
775         gk20a_readl(g, trim_gpc_clk_cntr_ncgpcclk_cfg_r(0));
776         udelay(2000);
777
778         count1 = gk20a_readl(g, trim_gpc_clk_cntr_ncgpcclk_cnt_r(0));
779         udelay(100);
780         count2 = gk20a_readl(g, trim_gpc_clk_cntr_ncgpcclk_cnt_r(0));
781         freq *= trim_gpc_clk_cntr_ncgpcclk_cnt_value_v(count2);
782         do_div(freq, ncycle);
783         *val = freq;
784
785         gk20a_idle(g->dev);
786
787         if (count1 != count2)
788                 return -EBUSY;
789         return 0;
790 }
791 DEFINE_SIMPLE_ATTRIBUTE(monitor_fops, monitor_get, NULL, "%llu\n");
792
793 static int clk_gm20b_debugfs_init(struct gk20a *g)
794 {
795         struct dentry *d;
796         struct gk20a_platform *platform = platform_get_drvdata(g->dev);
797
798         d = debugfs_create_file(
799                 "rate", S_IRUGO|S_IWUSR, platform->debugfs, g, &rate_fops);
800         if (!d)
801                 goto err_out;
802
803         d = debugfs_create_file(
804                 "pll_reg", S_IRUGO, platform->debugfs, g, &pll_reg_fops);
805         if (!d)
806                 goto err_out;
807
808         d = debugfs_create_file(
809                 "monitor", S_IRUGO, platform->debugfs, g, &monitor_fops);
810         if (!d)
811                 goto err_out;
812
813         return 0;
814
815 err_out:
816         pr_err("%s: Failed to make debugfs node\n", __func__);
817         debugfs_remove_recursive(platform->debugfs);
818         return -ENOMEM;
819 }
820
821 #endif /* CONFIG_DEBUG_FS */