aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTuomas Tynkkynen <ttynkkynen@nvidia.com>2015-05-13 10:58:36 -0400
committerThierry Reding <treding@nvidia.com>2015-07-16 03:32:44 -0400
commitd8d7a08fa82ff7c241c74c2461f342c5685dda27 (patch)
tree297830915eb9d7e0ec578bf80656324498d0dc33
parent0c59d26770333cf605d9119a78dd6c1ebebc6a61 (diff)
clk: tegra: Add library for the DFLL clock source (open-loop mode)
Add shared code to support the Tegra DFLL clocksource in open-loop mode. This root clocksource is present on the Tegra124 SoCs. The DFLL is the intended primary clock source for the fast CPU cluster. This code is very closely based on a patch by Paul Walmsley from December (http://comments.gmane.org/gmane.linux.ports.tegra/15273), which in turn comes from the internal driver by originally created by Aleksandr Frid <afrid@nvidia.com>. Subsequent patches will add support for closed loop mode and drivers for the Tegra124 fast CPU cluster DFLL devices, which rely on this code. Signed-off-by: Paul Walmsley <pwalmsley@nvidia.com> Signed-off-by: Tuomas Tynkkynen <ttynkkynen@nvidia.com> Signed-off-by: Mikko Perttunen <mikko.perttunen@kapsi.fi> Acked-by: Peter De Schrijver <pdeschrijver@nvidia.com> Acked-by: Michael Turquette <mturquette@linaro.org> Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/clk/tegra/Makefile1
-rw-r--r--drivers/clk/tegra/clk-dfll.c1095
-rw-r--r--drivers/clk/tegra/clk-dfll.h54
3 files changed, 1150 insertions, 0 deletions
diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
index aec862ba7a17..ec2e5163e1ae 100644
--- a/drivers/clk/tegra/Makefile
+++ b/drivers/clk/tegra/Makefile
@@ -1,5 +1,6 @@
1obj-y += clk.o 1obj-y += clk.o
2obj-y += clk-audio-sync.o 2obj-y += clk-audio-sync.o
3obj-y += clk-dfll.o
3obj-y += clk-divider.o 4obj-y += clk-divider.o
4obj-y += clk-periph.o 5obj-y += clk-periph.o
5obj-y += clk-periph-gate.o 6obj-y += clk-periph-gate.o
diff --git a/drivers/clk/tegra/clk-dfll.c b/drivers/clk/tegra/clk-dfll.c
new file mode 100644
index 000000000000..fb138bfa0af2
--- /dev/null
+++ b/drivers/clk/tegra/clk-dfll.c
@@ -0,0 +1,1095 @@
1/*
2 * clk-dfll.c - Tegra DFLL clock source common code
3 *
4 * Copyright (C) 2012-2014 NVIDIA Corporation. All rights reserved.
5 *
6 * Aleksandr Frid <afrid@nvidia.com>
7 * Paul Walmsley <pwalmsley@nvidia.com>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License version 2 as
11 * published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope that it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * This library is for the DVCO and DFLL IP blocks on the Tegra124
19 * SoC. These IP blocks together are also known at NVIDIA as
20 * "CL-DVFS". To try to avoid confusion, this code refers to them
21 * collectively as the "DFLL."
22 *
23 * The DFLL is a root clocksource which tolerates some amount of
24 * supply voltage noise. Tegra124 uses it to clock the fast CPU
25 * complex when the target CPU speed is above a particular rate. The
26 * DFLL can be operated in either open-loop mode or closed-loop mode.
27 * In open-loop mode, the DFLL generates an output clock appropriate
28 * to the supply voltage. In closed-loop mode, when configured with a
29 * target frequency, the DFLL minimizes supply voltage while
30 * delivering an average frequency equal to the target.
31 *
32 * Devices clocked by the DFLL must be able to tolerate frequency
33 * variation. In the case of the CPU, it's important to note that the
34 * CPU cycle time will vary. This has implications for
35 * performance-measurement code and any code that relies on the CPU
36 * cycle time to delay for a certain length of time.
37 *
38 */
39
40#include <linux/clk.h>
41#include <linux/clk-provider.h>
42#include <linux/debugfs.h>
43#include <linux/device.h>
44#include <linux/err.h>
45#include <linux/i2c.h>
46#include <linux/io.h>
47#include <linux/kernel.h>
48#include <linux/module.h>
49#include <linux/of.h>
50#include <linux/pm_opp.h>
51#include <linux/pm_runtime.h>
52#include <linux/regmap.h>
53#include <linux/regulator/consumer.h>
54#include <linux/reset.h>
55#include <linux/seq_file.h>
56
57#include "clk-dfll.h"
58
59/*
60 * DFLL control registers - access via dfll_{readl,writel}
61 */
62
63/* DFLL_CTRL: DFLL control register */
64#define DFLL_CTRL 0x00
65#define DFLL_CTRL_MODE_MASK 0x03
66
67/* DFLL_CONFIG: DFLL sample rate control */
68#define DFLL_CONFIG 0x04
69#define DFLL_CONFIG_DIV_MASK 0xff
70#define DFLL_CONFIG_DIV_PRESCALE 32
71
72/* DFLL_PARAMS: tuning coefficients for closed loop integrator */
73#define DFLL_PARAMS 0x08
74#define DFLL_PARAMS_CG_SCALE (0x1 << 24)
75#define DFLL_PARAMS_FORCE_MODE_SHIFT 22
76#define DFLL_PARAMS_FORCE_MODE_MASK (0x3 << DFLL_PARAMS_FORCE_MODE_SHIFT)
77#define DFLL_PARAMS_CF_PARAM_SHIFT 16
78#define DFLL_PARAMS_CF_PARAM_MASK (0x3f << DFLL_PARAMS_CF_PARAM_SHIFT)
79#define DFLL_PARAMS_CI_PARAM_SHIFT 8
80#define DFLL_PARAMS_CI_PARAM_MASK (0x7 << DFLL_PARAMS_CI_PARAM_SHIFT)
81#define DFLL_PARAMS_CG_PARAM_SHIFT 0
82#define DFLL_PARAMS_CG_PARAM_MASK (0xff << DFLL_PARAMS_CG_PARAM_SHIFT)
83
84/* DFLL_TUNE0: delay line configuration register 0 */
85#define DFLL_TUNE0 0x0c
86
87/* DFLL_TUNE1: delay line configuration register 1 */
88#define DFLL_TUNE1 0x10
89
90/* DFLL_FREQ_REQ: target DFLL frequency control */
91#define DFLL_FREQ_REQ 0x14
92#define DFLL_FREQ_REQ_FORCE_ENABLE (0x1 << 28)
93#define DFLL_FREQ_REQ_FORCE_SHIFT 16
94#define DFLL_FREQ_REQ_FORCE_MASK (0xfff << DFLL_FREQ_REQ_FORCE_SHIFT)
95#define FORCE_MAX 2047
96#define FORCE_MIN -2048
97#define DFLL_FREQ_REQ_SCALE_SHIFT 8
98#define DFLL_FREQ_REQ_SCALE_MASK (0xff << DFLL_FREQ_REQ_SCALE_SHIFT)
99#define DFLL_FREQ_REQ_SCALE_MAX 256
100#define DFLL_FREQ_REQ_FREQ_VALID (0x1 << 7)
101#define DFLL_FREQ_REQ_MULT_SHIFT 0
102#define DFLL_FREQ_REG_MULT_MASK (0x7f << DFLL_FREQ_REQ_MULT_SHIFT)
103#define FREQ_MAX 127
104
105/* DFLL_DROOP_CTRL: droop prevention control */
106#define DFLL_DROOP_CTRL 0x1c
107
108/* DFLL_OUTPUT_CFG: closed loop mode control registers */
109/* NOTE: access via dfll_i2c_{readl,writel} */
110#define DFLL_OUTPUT_CFG 0x20
111#define DFLL_OUTPUT_CFG_I2C_ENABLE (0x1 << 30)
112#define OUT_MASK 0x3f
113#define DFLL_OUTPUT_CFG_SAFE_SHIFT 24
114#define DFLL_OUTPUT_CFG_SAFE_MASK \
115 (OUT_MASK << DFLL_OUTPUT_CFG_SAFE_SHIFT)
116#define DFLL_OUTPUT_CFG_MAX_SHIFT 16
117#define DFLL_OUTPUT_CFG_MAX_MASK \
118 (OUT_MASK << DFLL_OUTPUT_CFG_MAX_SHIFT)
119#define DFLL_OUTPUT_CFG_MIN_SHIFT 8
120#define DFLL_OUTPUT_CFG_MIN_MASK \
121 (OUT_MASK << DFLL_OUTPUT_CFG_MIN_SHIFT)
122#define DFLL_OUTPUT_CFG_PWM_DELTA (0x1 << 7)
123#define DFLL_OUTPUT_CFG_PWM_ENABLE (0x1 << 6)
124#define DFLL_OUTPUT_CFG_PWM_DIV_SHIFT 0
125#define DFLL_OUTPUT_CFG_PWM_DIV_MASK \
126 (OUT_MASK << DFLL_OUTPUT_CFG_PWM_DIV_SHIFT)
127
128/* DFLL_OUTPUT_FORCE: closed loop mode voltage forcing control */
129#define DFLL_OUTPUT_FORCE 0x24
130#define DFLL_OUTPUT_FORCE_ENABLE (0x1 << 6)
131#define DFLL_OUTPUT_FORCE_VALUE_SHIFT 0
132#define DFLL_OUTPUT_FORCE_VALUE_MASK \
133 (OUT_MASK << DFLL_OUTPUT_FORCE_VALUE_SHIFT)
134
135/* DFLL_MONITOR_CTRL: internal monitor data source control */
136#define DFLL_MONITOR_CTRL 0x28
137#define DFLL_MONITOR_CTRL_FREQ 6
138
139/* DFLL_MONITOR_DATA: internal monitor data output */
140#define DFLL_MONITOR_DATA 0x2c
141#define DFLL_MONITOR_DATA_NEW_MASK (0x1 << 16)
142#define DFLL_MONITOR_DATA_VAL_SHIFT 0
143#define DFLL_MONITOR_DATA_VAL_MASK (0xFFFF << DFLL_MONITOR_DATA_VAL_SHIFT)
144
145/*
146 * I2C output control registers - access via dfll_i2c_{readl,writel}
147 */
148
149/* DFLL_I2C_CFG: I2C controller configuration register */
150#define DFLL_I2C_CFG 0x40
151#define DFLL_I2C_CFG_ARB_ENABLE (0x1 << 20)
152#define DFLL_I2C_CFG_HS_CODE_SHIFT 16
153#define DFLL_I2C_CFG_HS_CODE_MASK (0x7 << DFLL_I2C_CFG_HS_CODE_SHIFT)
154#define DFLL_I2C_CFG_PACKET_ENABLE (0x1 << 15)
155#define DFLL_I2C_CFG_SIZE_SHIFT 12
156#define DFLL_I2C_CFG_SIZE_MASK (0x7 << DFLL_I2C_CFG_SIZE_SHIFT)
157#define DFLL_I2C_CFG_SLAVE_ADDR_10 (0x1 << 10)
158#define DFLL_I2C_CFG_SLAVE_ADDR_SHIFT_7BIT 1
159#define DFLL_I2C_CFG_SLAVE_ADDR_SHIFT_10BIT 0
160
161/* DFLL_I2C_VDD_REG_ADDR: PMIC I2C address for closed loop mode */
162#define DFLL_I2C_VDD_REG_ADDR 0x44
163
164/* DFLL_I2C_STS: I2C controller status */
165#define DFLL_I2C_STS 0x48
166#define DFLL_I2C_STS_I2C_LAST_SHIFT 1
167#define DFLL_I2C_STS_I2C_REQ_PENDING 0x1
168
169/* DFLL_INTR_STS: DFLL interrupt status register */
170#define DFLL_INTR_STS 0x5c
171
172/* DFLL_INTR_EN: DFLL interrupt enable register */
173#define DFLL_INTR_EN 0x60
174#define DFLL_INTR_MIN_MASK 0x1
175#define DFLL_INTR_MAX_MASK 0x2
176
177/*
178 * Integrated I2C controller registers - relative to td->i2c_controller_base
179 */
180
181/* DFLL_I2C_CLK_DIVISOR: I2C controller clock divisor */
182#define DFLL_I2C_CLK_DIVISOR 0x6c
183#define DFLL_I2C_CLK_DIVISOR_MASK 0xffff
184#define DFLL_I2C_CLK_DIVISOR_FS_SHIFT 16
185#define DFLL_I2C_CLK_DIVISOR_HS_SHIFT 0
186#define DFLL_I2C_CLK_DIVISOR_PREDIV 8
187#define DFLL_I2C_CLK_DIVISOR_HSMODE_PREDIV 12
188
189/*
190 * Other constants
191 */
192
193/* MAX_DFLL_VOLTAGES: number of LUT entries in the DFLL IP block */
194#define MAX_DFLL_VOLTAGES 33
195
196/*
197 * REF_CLK_CYC_PER_DVCO_SAMPLE: the number of ref_clk cycles that the hardware
198 * integrates the DVCO counter over - used for debug rate monitoring and
199 * droop control
200 */
201#define REF_CLK_CYC_PER_DVCO_SAMPLE 4
202
203/*
204 * REF_CLOCK_RATE: the DFLL reference clock rate currently supported by this
205 * driver, in Hz
206 */
207#define REF_CLOCK_RATE 51000000UL
208
209
210/**
211 * enum dfll_ctrl_mode - DFLL hardware operating mode
212 * @DFLL_UNINITIALIZED: (uninitialized state - not in hardware bitfield)
213 * @DFLL_DISABLED: DFLL not generating an output clock
214 * @DFLL_OPEN_LOOP: DVCO running, but DFLL not adjusting voltage
215 *
216 * The integer corresponding to the last two states, minus one, is
217 * written to the DFLL hardware to change operating modes.
218 */
219enum dfll_ctrl_mode {
220 DFLL_UNINITIALIZED = 0,
221 DFLL_DISABLED = 1,
222 DFLL_OPEN_LOOP = 2,
223};
224
225/**
226 * enum dfll_tune_range - voltage range that the driver believes it's in
227 * @DFLL_TUNE_UNINITIALIZED: DFLL tuning not yet programmed
228 * @DFLL_TUNE_LOW: DFLL in the low-voltage range (or open-loop mode)
229 *
230 * Some DFLL tuning parameters may need to change depending on the
231 * DVCO's voltage; these states represent the ranges that the driver
232 * supports. These are software states; these values are never
233 * written into registers.
234 */
235enum dfll_tune_range {
236 DFLL_TUNE_UNINITIALIZED = 0,
237 DFLL_TUNE_LOW = 1,
238};
239
240struct tegra_dfll {
241 struct device *dev;
242 struct tegra_dfll_soc_data *soc;
243
244 void __iomem *base;
245 void __iomem *i2c_base;
246 void __iomem *i2c_controller_base;
247 void __iomem *lut_base;
248
249 struct regulator *vdd_reg;
250 struct clk *soc_clk;
251 struct clk *ref_clk;
252 struct clk *i2c_clk;
253 struct clk *dfll_clk;
254 struct reset_control *dvco_rst;
255 unsigned long ref_rate;
256 unsigned long i2c_clk_rate;
257 unsigned long dvco_rate_min;
258
259 enum dfll_ctrl_mode mode;
260 enum dfll_tune_range tune_range;
261 struct dentry *debugfs_dir;
262 struct clk_hw dfll_clk_hw;
263 const char *output_clock_name;
264
265 /* Parameters from DT */
266 u32 droop_ctrl;
267};
268
269#define clk_hw_to_dfll(_hw) container_of(_hw, struct tegra_dfll, dfll_clk_hw)
270
271/* mode_name: map numeric DFLL modes to names for friendly console messages */
272static const char * const mode_name[] = {
273 [DFLL_UNINITIALIZED] = "uninitialized",
274 [DFLL_DISABLED] = "disabled",
275 [DFLL_OPEN_LOOP] = "open_loop",
276};
277
278/*
279 * Register accessors
280 */
281
282static inline u32 dfll_readl(struct tegra_dfll *td, u32 offs)
283{
284 return __raw_readl(td->base + offs);
285}
286
287static inline void dfll_writel(struct tegra_dfll *td, u32 val, u32 offs)
288{
289 WARN_ON(offs >= DFLL_I2C_CFG);
290 __raw_writel(val, td->base + offs);
291}
292
293static inline void dfll_wmb(struct tegra_dfll *td)
294{
295 dfll_readl(td, DFLL_CTRL);
296}
297
298/* I2C output control registers - for addresses above DFLL_I2C_CFG */
299
300static inline u32 dfll_i2c_readl(struct tegra_dfll *td, u32 offs)
301{
302 return __raw_readl(td->i2c_base + offs);
303}
304
305static inline void dfll_i2c_writel(struct tegra_dfll *td, u32 val, u32 offs)
306{
307 __raw_writel(val, td->i2c_base + offs);
308}
309
310static inline void dfll_i2c_wmb(struct tegra_dfll *td)
311{
312 dfll_i2c_readl(td, DFLL_I2C_CFG);
313}
314
315/**
316 * dfll_is_running - is the DFLL currently generating a clock?
317 * @td: DFLL instance
318 *
319 * If the DFLL is currently generating an output clock signal, return
320 * true; otherwise return false.
321 */
322static bool dfll_is_running(struct tegra_dfll *td)
323{
324 return td->mode >= DFLL_OPEN_LOOP;
325}
326
327/*
328 * Runtime PM suspend/resume callbacks
329 */
330
331/**
332 * tegra_dfll_runtime_resume - enable all clocks needed by the DFLL
333 * @dev: DFLL device *
334 *
335 * Enable all clocks needed by the DFLL. Assumes that clk_prepare()
336 * has already been called on all the clocks.
337 *
338 * XXX Should also handle context restore when returning from off.
339 */
340int tegra_dfll_runtime_resume(struct device *dev)
341{
342 struct tegra_dfll *td = dev_get_drvdata(dev);
343 int ret;
344
345 ret = clk_enable(td->ref_clk);
346 if (ret) {
347 dev_err(dev, "could not enable ref clock: %d\n", ret);
348 return ret;
349 }
350
351 ret = clk_enable(td->soc_clk);
352 if (ret) {
353 dev_err(dev, "could not enable register clock: %d\n", ret);
354 clk_disable(td->ref_clk);
355 return ret;
356 }
357
358 ret = clk_enable(td->i2c_clk);
359 if (ret) {
360 dev_err(dev, "could not enable i2c clock: %d\n", ret);
361 clk_disable(td->soc_clk);
362 clk_disable(td->ref_clk);
363 return ret;
364 }
365
366 return 0;
367}
368EXPORT_SYMBOL(tegra_dfll_runtime_resume);
369
370/**
371 * tegra_dfll_runtime_suspend - disable all clocks needed by the DFLL
372 * @dev: DFLL device *
373 *
374 * Disable all clocks needed by the DFLL. Assumes that other code
375 * will later call clk_unprepare().
376 */
377int tegra_dfll_runtime_suspend(struct device *dev)
378{
379 struct tegra_dfll *td = dev_get_drvdata(dev);
380
381 clk_disable(td->ref_clk);
382 clk_disable(td->soc_clk);
383 clk_disable(td->i2c_clk);
384
385 return 0;
386}
387EXPORT_SYMBOL(tegra_dfll_runtime_suspend);
388
389/*
390 * DFLL tuning operations (per-voltage-range tuning settings)
391 */
392
393/**
394 * dfll_tune_low - tune to DFLL and CPU settings valid for any voltage
395 * @td: DFLL instance
396 *
397 * Tune the DFLL oscillator parameters and the CPU clock shaper for
398 * the low-voltage range. These settings are valid for any voltage,
399 * but may not be optimal.
400 */
401static void dfll_tune_low(struct tegra_dfll *td)
402{
403 td->tune_range = DFLL_TUNE_LOW;
404
405 dfll_writel(td, td->soc->tune0_low, DFLL_TUNE0);
406 dfll_writel(td, td->soc->tune1, DFLL_TUNE1);
407 dfll_wmb(td);
408
409 if (td->soc->set_clock_trimmers_low)
410 td->soc->set_clock_trimmers_low();
411}
412
413/*
414 * Output clock scaler helpers
415 */
416
417/**
418 * dfll_scale_dvco_rate - calculate scaled rate from the DVCO rate
419 * @scale_bits: clock scaler value (bits in the DFLL_FREQ_REQ_SCALE field)
420 * @dvco_rate: the DVCO rate
421 *
422 * Apply the same scaling formula that the DFLL hardware uses to scale
423 * the DVCO rate.
424 */
425static unsigned long dfll_scale_dvco_rate(int scale_bits,
426 unsigned long dvco_rate)
427{
428 return (u64)dvco_rate * (scale_bits + 1) / DFLL_FREQ_REQ_SCALE_MAX;
429}
430
431/*
432 * Monitor control
433 */
434
435/**
436 * dfll_calc_monitored_rate - convert DFLL_MONITOR_DATA_VAL rate into real freq
437 * @monitor_data: value read from the DFLL_MONITOR_DATA_VAL bitfield
438 * @ref_rate: DFLL reference clock rate
439 *
440 * Convert @monitor_data from DFLL_MONITOR_DATA_VAL units into cycles
441 * per second. Returns the converted value.
442 */
443static u64 dfll_calc_monitored_rate(u32 monitor_data,
444 unsigned long ref_rate)
445{
446 return monitor_data * (ref_rate / REF_CLK_CYC_PER_DVCO_SAMPLE);
447}
448
449/**
450 * dfll_read_monitor_rate - return the DFLL's output rate from internal monitor
451 * @td: DFLL instance
452 *
453 * If the DFLL is enabled, return the last rate reported by the DFLL's
454 * internal monitoring hardware. This works in both open-loop and
455 * closed-loop mode, and takes the output scaler setting into account.
456 * Assumes that the monitor was programmed to monitor frequency before
457 * the sample period started. If the driver believes that the DFLL is
458 * currently uninitialized or disabled, it will return 0, since
459 * otherwise the DFLL monitor data register will return the last
460 * measured rate from when the DFLL was active.
461 */
462static u64 dfll_read_monitor_rate(struct tegra_dfll *td)
463{
464 u32 v, s;
465 u64 pre_scaler_rate, post_scaler_rate;
466
467 if (!dfll_is_running(td))
468 return 0;
469
470 v = dfll_readl(td, DFLL_MONITOR_DATA);
471 v = (v & DFLL_MONITOR_DATA_VAL_MASK) >> DFLL_MONITOR_DATA_VAL_SHIFT;
472 pre_scaler_rate = dfll_calc_monitored_rate(v, td->ref_rate);
473
474 s = dfll_readl(td, DFLL_FREQ_REQ);
475 s = (s & DFLL_FREQ_REQ_SCALE_MASK) >> DFLL_FREQ_REQ_SCALE_SHIFT;
476 post_scaler_rate = dfll_scale_dvco_rate(s, pre_scaler_rate);
477
478 return post_scaler_rate;
479}
480
481/*
482 * DFLL mode switching
483 */
484
485/**
486 * dfll_set_mode - change the DFLL control mode
487 * @td: DFLL instance
488 * @mode: DFLL control mode (see enum dfll_ctrl_mode)
489 *
490 * Change the DFLL's operating mode between disabled, open-loop mode,
491 * and closed-loop mode, or vice versa.
492 */
493static void dfll_set_mode(struct tegra_dfll *td,
494 enum dfll_ctrl_mode mode)
495{
496 td->mode = mode;
497 dfll_writel(td, mode - 1, DFLL_CTRL);
498 dfll_wmb(td);
499}
500
501/*
502 * DFLL enable/disable & open-loop <-> closed-loop transitions
503 */
504
505/**
506 * dfll_disable - switch from open-loop mode to disabled mode
507 * @td: DFLL instance
508 *
509 * Switch from OPEN_LOOP state to DISABLED state. Returns 0 upon success
510 * or -EPERM if the DFLL is not currently in open-loop mode.
511 */
512static int dfll_disable(struct tegra_dfll *td)
513{
514 if (td->mode != DFLL_OPEN_LOOP) {
515 dev_err(td->dev, "cannot disable DFLL in %s mode\n",
516 mode_name[td->mode]);
517 return -EINVAL;
518 }
519
520 dfll_set_mode(td, DFLL_DISABLED);
521 pm_runtime_put_sync(td->dev);
522
523 return 0;
524}
525
526/**
527 * dfll_enable - switch a disabled DFLL to open-loop mode
528 * @td: DFLL instance
529 *
530 * Switch from DISABLED state to OPEN_LOOP state. Returns 0 upon success
531 * or -EPERM if the DFLL is not currently disabled.
532 */
533static int dfll_enable(struct tegra_dfll *td)
534{
535 if (td->mode != DFLL_DISABLED) {
536 dev_err(td->dev, "cannot enable DFLL in %s mode\n",
537 mode_name[td->mode]);
538 return -EPERM;
539 }
540
541 pm_runtime_get_sync(td->dev);
542 dfll_set_mode(td, DFLL_OPEN_LOOP);
543
544 return 0;
545}
546
547/**
548 * dfll_set_open_loop_config - prepare to switch to open-loop mode
549 * @td: DFLL instance
550 *
551 * Prepare to switch the DFLL to open-loop mode. This switches the
552 * DFLL to the low-voltage tuning range, ensures that I2C output
553 * forcing is disabled, and disables the output clock rate scaler.
554 * The DFLL's low-voltage tuning range parameters must be
555 * characterized to keep the downstream device stable at any DVCO
556 * input voltage. No return value.
557 */
558static void dfll_set_open_loop_config(struct tegra_dfll *td)
559{
560 u32 val;
561
562 /* always tune low (safe) in open loop */
563 if (td->tune_range != DFLL_TUNE_LOW)
564 dfll_tune_low(td);
565
566 val = dfll_readl(td, DFLL_FREQ_REQ);
567 val |= DFLL_FREQ_REQ_SCALE_MASK;
568 val &= ~DFLL_FREQ_REQ_FORCE_ENABLE;
569 dfll_writel(td, val, DFLL_FREQ_REQ);
570 dfll_wmb(td);
571}
572
573/*
574 * Clock framework integration
575 */
576
577static int dfll_clk_is_enabled(struct clk_hw *hw)
578{
579 struct tegra_dfll *td = clk_hw_to_dfll(hw);
580
581 return dfll_is_running(td);
582}
583
584static int dfll_clk_enable(struct clk_hw *hw)
585{
586 struct tegra_dfll *td = clk_hw_to_dfll(hw);
587
588 return dfll_enable(td);
589}
590
591static void dfll_clk_disable(struct clk_hw *hw)
592{
593 struct tegra_dfll *td = clk_hw_to_dfll(hw);
594
595 dfll_disable(td);
596}
597
598static const struct clk_ops dfll_clk_ops = {
599 .is_enabled = dfll_clk_is_enabled,
600 .enable = dfll_clk_enable,
601 .disable = dfll_clk_disable,
602};
603
604static struct clk_init_data dfll_clk_init_data = {
605 .flags = CLK_IS_ROOT,
606 .ops = &dfll_clk_ops,
607 .num_parents = 0,
608};
609
610/**
611 * dfll_register_clk - register the DFLL output clock with the clock framework
612 * @td: DFLL instance
613 *
614 * Register the DFLL's output clock with the Linux clock framework and register
615 * the DFLL driver as an OF clock provider. Returns 0 upon success or -EINVAL
616 * or -ENOMEM upon failure.
617 */
618static int dfll_register_clk(struct tegra_dfll *td)
619{
620 int ret;
621
622 dfll_clk_init_data.name = td->output_clock_name;
623 td->dfll_clk_hw.init = &dfll_clk_init_data;
624
625 td->dfll_clk = clk_register(td->dev, &td->dfll_clk_hw);
626 if (IS_ERR(td->dfll_clk)) {
627 dev_err(td->dev, "DFLL clock registration error\n");
628 return -EINVAL;
629 }
630
631 ret = of_clk_add_provider(td->dev->of_node, of_clk_src_simple_get,
632 td->dfll_clk);
633 if (ret) {
634 dev_err(td->dev, "of_clk_add_provider() failed\n");
635
636 clk_unregister(td->dfll_clk);
637 return ret;
638 }
639
640 return 0;
641}
642
643/**
644 * dfll_unregister_clk - unregister the DFLL output clock
645 * @td: DFLL instance
646 *
647 * Unregister the DFLL's output clock from the Linux clock framework
648 * and from clkdev. No return value.
649 */
650static void dfll_unregister_clk(struct tegra_dfll *td)
651{
652 of_clk_del_provider(td->dev->of_node);
653 clk_unregister(td->dfll_clk);
654 td->dfll_clk = NULL;
655}
656
657/*
658 * Debugfs interface
659 */
660
661#ifdef CONFIG_DEBUG_FS
662
663static int attr_enable_get(void *data, u64 *val)
664{
665 struct tegra_dfll *td = data;
666
667 *val = dfll_is_running(td);
668
669 return 0;
670}
671static int attr_enable_set(void *data, u64 val)
672{
673 struct tegra_dfll *td = data;
674
675 return val ? dfll_enable(td) : dfll_disable(td);
676}
677DEFINE_SIMPLE_ATTRIBUTE(enable_fops, attr_enable_get, attr_enable_set,
678 "%llu\n");
679
680static int attr_rate_get(void *data, u64 *val)
681{
682 struct tegra_dfll *td = data;
683
684 *val = dfll_read_monitor_rate(td);
685
686 return 0;
687}
688DEFINE_SIMPLE_ATTRIBUTE(rate_fops, attr_rate_get, NULL, "%llu\n");
689
690static int attr_registers_show(struct seq_file *s, void *data)
691{
692 u32 val, offs;
693 struct tegra_dfll *td = s->private;
694
695 seq_puts(s, "CONTROL REGISTERS:\n");
696 for (offs = 0; offs <= DFLL_MONITOR_DATA; offs += 4) {
697 if (offs == DFLL_OUTPUT_CFG)
698 val = dfll_i2c_readl(td, offs);
699 else
700 val = dfll_readl(td, offs);
701 seq_printf(s, "[0x%02x] = 0x%08x\n", offs, val);
702 }
703
704 seq_puts(s, "\nI2C and INTR REGISTERS:\n");
705 for (offs = DFLL_I2C_CFG; offs <= DFLL_I2C_STS; offs += 4)
706 seq_printf(s, "[0x%02x] = 0x%08x\n", offs,
707 dfll_i2c_readl(td, offs));
708 for (offs = DFLL_INTR_STS; offs <= DFLL_INTR_EN; offs += 4)
709 seq_printf(s, "[0x%02x] = 0x%08x\n", offs,
710 dfll_i2c_readl(td, offs));
711
712 seq_puts(s, "\nINTEGRATED I2C CONTROLLER REGISTERS:\n");
713 offs = DFLL_I2C_CLK_DIVISOR;
714 seq_printf(s, "[0x%02x] = 0x%08x\n", offs,
715 __raw_readl(td->i2c_controller_base + offs));
716
717 seq_puts(s, "\nLUT:\n");
718 for (offs = 0; offs < 4 * MAX_DFLL_VOLTAGES; offs += 4)
719 seq_printf(s, "[0x%02x] = 0x%08x\n", offs,
720 __raw_readl(td->lut_base + offs));
721
722 return 0;
723}
724
725static int attr_registers_open(struct inode *inode, struct file *file)
726{
727 return single_open(file, attr_registers_show, inode->i_private);
728}
729
730static const struct file_operations attr_registers_fops = {
731 .open = attr_registers_open,
732 .read = seq_read,
733 .llseek = seq_lseek,
734 .release = single_release,
735};
736
737static int dfll_debug_init(struct tegra_dfll *td)
738{
739 int ret;
740
741 if (!td || (td->mode == DFLL_UNINITIALIZED))
742 return 0;
743
744 td->debugfs_dir = debugfs_create_dir("tegra_dfll_fcpu", NULL);
745 if (!td->debugfs_dir)
746 return -ENOMEM;
747
748 ret = -ENOMEM;
749
750 if (!debugfs_create_file("enable", S_IRUGO | S_IWUSR,
751 td->debugfs_dir, td, &enable_fops))
752 goto err_out;
753
754 if (!debugfs_create_file("rate", S_IRUGO,
755 td->debugfs_dir, td, &rate_fops))
756 goto err_out;
757
758 if (!debugfs_create_file("registers", S_IRUGO,
759 td->debugfs_dir, td, &attr_registers_fops))
760 goto err_out;
761
762 return 0;
763
764err_out:
765 debugfs_remove_recursive(td->debugfs_dir);
766 return ret;
767}
768
769#endif /* CONFIG_DEBUG_FS */
770
771/*
772 * DFLL initialization
773 */
774
775/**
776 * dfll_set_default_params - program non-output related DFLL parameters
777 * @td: DFLL instance
778 *
779 * During DFLL driver initialization or resume from context loss,
780 * program parameters for the closed loop integrator, DVCO tuning,
781 * voltage droop control and monitor control.
782 */
783static void dfll_set_default_params(struct tegra_dfll *td)
784{
785 dfll_tune_low(td);
786 dfll_writel(td, td->droop_ctrl, DFLL_DROOP_CTRL);
787 dfll_writel(td, DFLL_MONITOR_CTRL_FREQ, DFLL_MONITOR_CTRL);
788}
789
790/**
791 * dfll_init_clks - clk_get() the DFLL source clocks
792 * @td: DFLL instance
793 *
794 * Call clk_get() on the DFLL source clocks and save the pointers for later
795 * use. Returns 0 upon success or error (see devm_clk_get) if one or more
796 * of the clocks couldn't be looked up.
797 */
798static int dfll_init_clks(struct tegra_dfll *td)
799{
800 td->ref_clk = devm_clk_get(td->dev, "ref");
801 if (IS_ERR(td->ref_clk)) {
802 dev_err(td->dev, "missing ref clock\n");
803 return PTR_ERR(td->ref_clk);
804 }
805
806 td->soc_clk = devm_clk_get(td->dev, "soc");
807 if (IS_ERR(td->soc_clk)) {
808 dev_err(td->dev, "missing soc clock\n");
809 return PTR_ERR(td->soc_clk);
810 }
811
812 td->i2c_clk = devm_clk_get(td->dev, "i2c");
813 if (IS_ERR(td->i2c_clk)) {
814 dev_err(td->dev, "missing i2c clock\n");
815 return PTR_ERR(td->i2c_clk);
816 }
817 td->i2c_clk_rate = clk_get_rate(td->i2c_clk);
818
819 return 0;
820}
821
822/**
823 * dfll_init - Prepare the DFLL IP block for use
824 * @td: DFLL instance
825 *
826 * Do everything necessary to prepare the DFLL IP block for use. The
827 * DFLL will be left in DISABLED state. Called by dfll_probe().
828 * Returns 0 upon success, or passes along the error from whatever
829 * function returned it.
830 */
831static int dfll_init(struct tegra_dfll *td)
832{
833 int ret;
834
835 td->ref_rate = clk_get_rate(td->ref_clk);
836 if (td->ref_rate != REF_CLOCK_RATE) {
837 dev_err(td->dev, "unexpected ref clk rate %lu, expecting %lu",
838 td->ref_rate, REF_CLOCK_RATE);
839 return -EINVAL;
840 }
841
842 reset_control_deassert(td->dvco_rst);
843
844 ret = clk_prepare(td->ref_clk);
845 if (ret) {
846 dev_err(td->dev, "failed to prepare ref_clk\n");
847 return ret;
848 }
849
850 ret = clk_prepare(td->soc_clk);
851 if (ret) {
852 dev_err(td->dev, "failed to prepare soc_clk\n");
853 goto di_err1;
854 }
855
856 ret = clk_prepare(td->i2c_clk);
857 if (ret) {
858 dev_err(td->dev, "failed to prepare i2c_clk\n");
859 goto di_err2;
860 }
861
862 pm_runtime_enable(td->dev);
863 pm_runtime_get_sync(td->dev);
864
865 dfll_set_mode(td, DFLL_DISABLED);
866 dfll_set_default_params(td);
867
868 if (td->soc->init_clock_trimmers)
869 td->soc->init_clock_trimmers();
870
871 dfll_set_open_loop_config(td);
872
873 pm_runtime_put_sync(td->dev);
874
875 return 0;
876
877di_err2:
878 clk_unprepare(td->soc_clk);
879di_err1:
880 clk_unprepare(td->ref_clk);
881
882 reset_control_assert(td->dvco_rst);
883
884 return ret;
885}
886
887/*
888 * DT data fetch
889 */
890
891/**
892 * read_dt_param - helper function for reading required parameters from the DT
893 * @td: DFLL instance
894 * @param: DT property name
895 * @dest: output pointer for the value read
896 *
897 * Read a required numeric parameter from the DFLL device node, or complain
898 * if the property doesn't exist. Returns a boolean indicating success for
899 * easy chaining of multiple calls to this function.
900 */
901static bool read_dt_param(struct tegra_dfll *td, const char *param, u32 *dest)
902{
903 int err = of_property_read_u32(td->dev->of_node, param, dest);
904
905 if (err < 0) {
906 dev_err(td->dev, "failed to read DT parameter %s: %d\n",
907 param, err);
908 return false;
909 }
910
911 return true;
912}
913
914/**
915 * dfll_fetch_common_params - read DFLL parameters from the device tree
916 * @td: DFLL instance
917 *
918 * Read all the DT parameters that are common to both I2C and PWM operation.
919 * Returns 0 on success or -EINVAL on any failure.
920 */
921static int dfll_fetch_common_params(struct tegra_dfll *td)
922{
923 bool ok = true;
924
925 ok &= read_dt_param(td, "nvidia,droop-ctrl", &td->droop_ctrl);
926
927 if (of_property_read_string(td->dev->of_node, "clock-output-names",
928 &td->output_clock_name)) {
929 dev_err(td->dev, "missing clock-output-names property\n");
930 ok = false;
931 }
932
933 return ok ? 0 : -EINVAL;
934}
935
936/*
937 * API exported to per-SoC platform drivers
938 */
939
940/**
941 * tegra_dfll_register - probe a Tegra DFLL device
942 * @pdev: DFLL platform_device *
943 * @soc: Per-SoC integration and characterization data for this DFLL instance
944 *
945 * Probe and initialize a DFLL device instance. Intended to be called
946 * by a SoC-specific shim driver that passes in per-SoC integration
947 * and configuration data via @soc. Returns 0 on success or -err on failure.
948 */
949int tegra_dfll_register(struct platform_device *pdev,
950 struct tegra_dfll_soc_data *soc)
951{
952 struct resource *mem;
953 struct tegra_dfll *td;
954 int ret;
955
956 if (!soc) {
957 dev_err(&pdev->dev, "no tegra_dfll_soc_data provided\n");
958 return -EINVAL;
959 }
960
961 td = devm_kzalloc(&pdev->dev, sizeof(*td), GFP_KERNEL);
962 if (!td)
963 return -ENOMEM;
964 td->dev = &pdev->dev;
965 platform_set_drvdata(pdev, td);
966
967 td->soc = soc;
968
969 td->vdd_reg = devm_regulator_get(td->dev, "vdd-cpu");
970 if (IS_ERR(td->vdd_reg)) {
971 dev_err(td->dev, "couldn't get vdd_cpu regulator\n");
972 return PTR_ERR(td->vdd_reg);
973 }
974
975 td->dvco_rst = devm_reset_control_get(td->dev, "dvco");
976 if (IS_ERR(td->dvco_rst)) {
977 dev_err(td->dev, "couldn't get dvco reset\n");
978 return PTR_ERR(td->dvco_rst);
979 }
980
981 ret = dfll_fetch_common_params(td);
982 if (ret) {
983 dev_err(td->dev, "couldn't parse device tree parameters\n");
984 return ret;
985 }
986
987 mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
988 if (!mem) {
989 dev_err(td->dev, "no control register resource\n");
990 return -ENODEV;
991 }
992
993 td->base = devm_ioremap(td->dev, mem->start, resource_size(mem));
994 if (!td->base) {
995 dev_err(td->dev, "couldn't ioremap DFLL control registers\n");
996 return -ENODEV;
997 }
998
999 mem = platform_get_resource(pdev, IORESOURCE_MEM, 1);
1000 if (!mem) {
1001 dev_err(td->dev, "no i2c_base resource\n");
1002 return -ENODEV;
1003 }
1004
1005 td->i2c_base = devm_ioremap(td->dev, mem->start, resource_size(mem));
1006 if (!td->i2c_base) {
1007 dev_err(td->dev, "couldn't ioremap i2c_base resource\n");
1008 return -ENODEV;
1009 }
1010
1011 mem = platform_get_resource(pdev, IORESOURCE_MEM, 2);
1012 if (!mem) {
1013 dev_err(td->dev, "no i2c_controller_base resource\n");
1014 return -ENODEV;
1015 }
1016
1017 td->i2c_controller_base = devm_ioremap(td->dev, mem->start,
1018 resource_size(mem));
1019 if (!td->i2c_controller_base) {
1020 dev_err(td->dev,
1021 "couldn't ioremap i2c_controller_base resource\n");
1022 return -ENODEV;
1023 }
1024
1025 mem = platform_get_resource(pdev, IORESOURCE_MEM, 3);
1026 if (!mem) {
1027 dev_err(td->dev, "no lut_base resource\n");
1028 return -ENODEV;
1029 }
1030
1031 td->lut_base = devm_ioremap(td->dev, mem->start, resource_size(mem));
1032 if (!td->lut_base) {
1033 dev_err(td->dev,
1034 "couldn't ioremap lut_base resource\n");
1035 return -ENODEV;
1036 }
1037
1038 ret = dfll_init_clks(td);
1039 if (ret) {
1040 dev_err(&pdev->dev, "DFLL clock init error\n");
1041 return ret;
1042 }
1043
1044 /* Enable the clocks and set the device up */
1045 ret = dfll_init(td);
1046 if (ret)
1047 return ret;
1048
1049 ret = dfll_register_clk(td);
1050 if (ret) {
1051 dev_err(&pdev->dev, "DFLL clk registration failed\n");
1052 return ret;
1053 }
1054
1055#ifdef CONFIG_DEBUG_FS
1056 dfll_debug_init(td);
1057#endif
1058
1059 return 0;
1060}
1061EXPORT_SYMBOL(tegra_dfll_register);
1062
1063/**
1064 * tegra_dfll_unregister - release all of the DFLL driver resources for a device
1065 * @pdev: DFLL platform_device *
1066 *
1067 * Unbind this driver from the DFLL hardware device represented by
1068 * @pdev. The DFLL must be disabled for this to succeed. Returns 0
1069 * upon success or -EBUSY if the DFLL is still active.
1070 */
1071int tegra_dfll_unregister(struct platform_device *pdev)
1072{
1073 struct tegra_dfll *td = platform_get_drvdata(pdev);
1074
1075 /* Try to prevent removal while the DFLL is active */
1076 if (td->mode != DFLL_DISABLED) {
1077 dev_err(&pdev->dev,
1078 "must disable DFLL before removing driver\n");
1079 return -EBUSY;
1080 }
1081
1082 debugfs_remove_recursive(td->debugfs_dir);
1083
1084 dfll_unregister_clk(td);
1085 pm_runtime_disable(&pdev->dev);
1086
1087 clk_unprepare(td->ref_clk);
1088 clk_unprepare(td->soc_clk);
1089 clk_unprepare(td->i2c_clk);
1090
1091 reset_control_assert(td->dvco_rst);
1092
1093 return 0;
1094}
1095EXPORT_SYMBOL(tegra_dfll_unregister);
diff --git a/drivers/clk/tegra/clk-dfll.h b/drivers/clk/tegra/clk-dfll.h
new file mode 100644
index 000000000000..b5d1fd47684e
--- /dev/null
+++ b/drivers/clk/tegra/clk-dfll.h
@@ -0,0 +1,54 @@
1/*
2 * clk-dfll.h - prototypes and macros for the Tegra DFLL clocksource driver
3 * Copyright (C) 2013 NVIDIA Corporation. All rights reserved.
4 *
5 * Aleksandr Frid <afrid@nvidia.com>
6 * Paul Walmsley <pwalmsley@nvidia.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 */
17
18#ifndef __DRIVERS_CLK_TEGRA_CLK_DFLL_H
19#define __DRIVERS_CLK_TEGRA_CLK_DFLL_H
20
21#include <linux/platform_device.h>
22#include <linux/reset.h>
23#include <linux/types.h>
24
25/**
26 * struct tegra_dfll_soc_data - SoC-specific hooks/integration for the DFLL driver
27 * @opp_dev: struct device * that holds the OPP table for the DFLL
28 * @min_millivolts: minimum voltage (in mV) that the DFLL can operate
29 * @tune0_low: DFLL tuning register 0 (low voltage range)
30 * @tune0_high: DFLL tuning register 0 (high voltage range)
31 * @tune1: DFLL tuning register 1
32 * @assert_dvco_reset: fn ptr to place the DVCO in reset
33 * @deassert_dvco_reset: fn ptr to release the DVCO reset
34 * @set_clock_trimmers_high: fn ptr to tune clock trimmers for high voltage
35 * @set_clock_trimmers_low: fn ptr to tune clock trimmers for low voltage
36 */
37struct tegra_dfll_soc_data {
38 struct device *opp_dev;
39 unsigned int min_millivolts;
40 u32 tune0_low;
41 u32 tune0_high;
42 u32 tune1;
43 void (*init_clock_trimmers)(void);
44 void (*set_clock_trimmers_high)(void);
45 void (*set_clock_trimmers_low)(void);
46};
47
48int tegra_dfll_register(struct platform_device *pdev,
49 struct tegra_dfll_soc_data *soc);
50int tegra_dfll_unregister(struct platform_device *pdev);
51int tegra_dfll_runtime_suspend(struct device *dev);
52int tegra_dfll_runtime_resume(struct device *dev);
53
54#endif /* __DRIVERS_CLK_TEGRA_CLK_DFLL_H */