[PATCH v3 02/15] clk: tegra: Add library for the DFLL clock source (open-loop mode)

2014-08-18 Thread Tuomas Tynkkynen
From: Tuomas Tynkkynen 

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 .

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 
Signed-off-by: Tuomas Tynkkynen 
---
v3: Fix incorrect order of arguments to dfll_scale_dvco_rate call
---
 drivers/clk/tegra/Makefile   |1 +
 drivers/clk/tegra/clk-dfll.c | 1085 ++
 drivers/clk/tegra/clk-dfll.h |   55 +++
 3 files changed, 1141 insertions(+)
 create mode 100644 drivers/clk/tegra/clk-dfll.c
 create mode 100644 drivers/clk/tegra/clk-dfll.h

diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
index f7dfb72..47320ca 100644
--- a/drivers/clk/tegra/Makefile
+++ b/drivers/clk/tegra/Makefile
@@ -1,5 +1,6 @@
 obj-y  += clk.o
 obj-y  += clk-audio-sync.o
+obj-y  += clk-dfll.o
 obj-y  += clk-divider.o
 obj-y  += clk-periph.o
 obj-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 000..f60ef54
--- /dev/null
+++ b/drivers/clk/tegra/clk-dfll.c
@@ -0,0 +1,1085 @@
+/*
+ * clk-dfll.c - Tegra DFLL clock source common code
+ *
+ * Copyright (C) 2012-2014 NVIDIA Corporation. All rights reserved.
+ *
+ * Aleksandr Frid 
+ * Paul Walmsley 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * This library is for the DVCO and DFLL IP blocks on the Tegra124
+ * SoC. These IP blocks together are also known at NVIDIA as
+ * "CL-DVFS". To try to avoid confusion, this code refers to them
+ * collectively as the "DFLL."
+ *
+ * The DFLL is a root clocksource which tolerates some amount of
+ * supply voltage noise. Tegra124 uses it to clock the fast CPU
+ * complex when the target CPU speed is above a particular rate. The
+ * DFLL can be operated in either open-loop mode or closed-loop mode.
+ * In open-loop mode, the DFLL generates an output clock appropriate
+ * to the supply voltage. In closed-loop mode, when configured with a
+ * target frequency, the DFLL minimizes supply voltage while
+ * delivering an average frequency equal to the target.
+ *
+ * Devices clocked by the DFLL must be able to tolerate frequency
+ * variation. In the case of the CPU, it's important to note that the
+ * CPU cycle time will vary. This has implications for
+ * performance-measurement code and any code that relies on the CPU
+ * cycle time to delay for a certain length of time.
+ *
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "clk-dfll.h"
+
+/*
+ * DFLL control registers - access via dfll_{readl,writel}
+ */
+
+/* DFLL_CTRL: DFLL control register */
+#define DFLL_CTRL  0x00
+#define DFLL_CTRL_MODE_MASK0x03
+
+/* DFLL_CONFIG: DFLL sample rate control */
+#define DFLL_CONFIG0x04
+#define DFLL_CONFIG_DIV_MASK   0xff
+#define DFLL_CONFIG_DIV_PRESCALE   32
+
+/* DFLL_PARAMS: tuning coefficients for closed loop integrator */
+#define DFLL_PARAMS0x08
+#define DFLL_PARAMS_CG_SCALE   (0x1 << 24)
+#define DFLL_PARAMS_FORCE_MODE_SHIFT   22
+#define DFLL_PARAMS_FORCE_MODE_MASK(0x3 << DFLL_PARAMS_FORCE_MODE_SHIFT)
+#define DFLL_PARAMS_CF_PARAM_SHIFT 16
+#define DFLL_PARAMS_CF_PARAM_MASK  (0x3f << DFLL_PARAMS_CF_PARAM_SHIFT)
+#define DFLL_PARAMS_CI_PARAM_SHIFT 8
+#define DFLL_PARAMS_CI_PARAM_MASK  (0x7 << DFLL_PARAMS_CI_PARAM_SHIFT)
+#define DFLL_PARAMS_CG_PARAM_SHIFT 0
+#define DFLL_PARAMS_CG_PARAM_MASK  (0xff << DFLL_PARAMS_CG_PARAM_SHIFT)
+
+/* DFLL_TUNE0: delay line configuration register 0 */
+#define DFLL_TUNE0 0x0c
+
+/* DFLL_TUNE1: delay line configuration register 1 */
+#define DFLL_TUNE1 0x10
+
+/* DFLL_FREQ_REQ: target DFLL frequency control */
+#define DFLL_FREQ_REQ  0x14
+#define 

[PATCH v3 02/15] clk: tegra: Add library for the DFLL clock source (open-loop mode)

2014-08-18 Thread Tuomas Tynkkynen
From: Tuomas Tynkkynen ttynkky...@nvidia.com

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 af...@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 pwalms...@nvidia.com
Signed-off-by: Tuomas Tynkkynen ttynkky...@nvidia.com
---
v3: Fix incorrect order of arguments to dfll_scale_dvco_rate call
---
 drivers/clk/tegra/Makefile   |1 +
 drivers/clk/tegra/clk-dfll.c | 1085 ++
 drivers/clk/tegra/clk-dfll.h |   55 +++
 3 files changed, 1141 insertions(+)
 create mode 100644 drivers/clk/tegra/clk-dfll.c
 create mode 100644 drivers/clk/tegra/clk-dfll.h

diff --git a/drivers/clk/tegra/Makefile b/drivers/clk/tegra/Makefile
index f7dfb72..47320ca 100644
--- a/drivers/clk/tegra/Makefile
+++ b/drivers/clk/tegra/Makefile
@@ -1,5 +1,6 @@
 obj-y  += clk.o
 obj-y  += clk-audio-sync.o
+obj-y  += clk-dfll.o
 obj-y  += clk-divider.o
 obj-y  += clk-periph.o
 obj-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 000..f60ef54
--- /dev/null
+++ b/drivers/clk/tegra/clk-dfll.c
@@ -0,0 +1,1085 @@
+/*
+ * clk-dfll.c - Tegra DFLL clock source common code
+ *
+ * Copyright (C) 2012-2014 NVIDIA Corporation. All rights reserved.
+ *
+ * Aleksandr Frid af...@nvidia.com
+ * Paul Walmsley pwalms...@nvidia.com
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * This library is for the DVCO and DFLL IP blocks on the Tegra124
+ * SoC. These IP blocks together are also known at NVIDIA as
+ * CL-DVFS. To try to avoid confusion, this code refers to them
+ * collectively as the DFLL.
+ *
+ * The DFLL is a root clocksource which tolerates some amount of
+ * supply voltage noise. Tegra124 uses it to clock the fast CPU
+ * complex when the target CPU speed is above a particular rate. The
+ * DFLL can be operated in either open-loop mode or closed-loop mode.
+ * In open-loop mode, the DFLL generates an output clock appropriate
+ * to the supply voltage. In closed-loop mode, when configured with a
+ * target frequency, the DFLL minimizes supply voltage while
+ * delivering an average frequency equal to the target.
+ *
+ * Devices clocked by the DFLL must be able to tolerate frequency
+ * variation. In the case of the CPU, it's important to note that the
+ * CPU cycle time will vary. This has implications for
+ * performance-measurement code and any code that relies on the CPU
+ * cycle time to delay for a certain length of time.
+ *
+ */
+
+#include linux/clk.h
+#include linux/clk-provider.h
+#include linux/debugfs.h
+#include linux/device.h
+#include linux/err.h
+#include linux/i2c.h
+#include linux/io.h
+#include linux/kernel.h
+#include linux/module.h
+#include linux/of.h
+#include linux/pm_opp.h
+#include linux/pm_runtime.h
+#include linux/regmap.h
+#include linux/regulator/consumer.h
+#include linux/seq_file.h
+
+#include clk-dfll.h
+
+/*
+ * DFLL control registers - access via dfll_{readl,writel}
+ */
+
+/* DFLL_CTRL: DFLL control register */
+#define DFLL_CTRL  0x00
+#define DFLL_CTRL_MODE_MASK0x03
+
+/* DFLL_CONFIG: DFLL sample rate control */
+#define DFLL_CONFIG0x04
+#define DFLL_CONFIG_DIV_MASK   0xff
+#define DFLL_CONFIG_DIV_PRESCALE   32
+
+/* DFLL_PARAMS: tuning coefficients for closed loop integrator */
+#define DFLL_PARAMS0x08
+#define DFLL_PARAMS_CG_SCALE   (0x1  24)
+#define DFLL_PARAMS_FORCE_MODE_SHIFT   22
+#define DFLL_PARAMS_FORCE_MODE_MASK(0x3  DFLL_PARAMS_FORCE_MODE_SHIFT)
+#define DFLL_PARAMS_CF_PARAM_SHIFT 16
+#define DFLL_PARAMS_CF_PARAM_MASK  (0x3f  DFLL_PARAMS_CF_PARAM_SHIFT)
+#define DFLL_PARAMS_CI_PARAM_SHIFT 8
+#define DFLL_PARAMS_CI_PARAM_MASK  (0x7  DFLL_PARAMS_CI_PARAM_SHIFT)
+#define DFLL_PARAMS_CG_PARAM_SHIFT 0
+#define DFLL_PARAMS_CG_PARAM_MASK  (0xff  DFLL_PARAMS_CG_PARAM_SHIFT)
+
+/* DFLL_TUNE0: