summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Williams <scwilliams@nvidia.com>2012-02-13 17:51:06 -0800
committerSimone Willett <swillett@nvidia.com>2012-02-15 15:41:44 -0800
commit0b042c720db13bbd042dace487e2e918386a45d4 (patch)
tree47cb5b5b3040c68aa71ea7dcf40645735e65dc75
parent54c4f5a5a87c2ea56f4b2677fe22dde39e6918b3 (diff)
ARM: tegra: clocks: Consolidate input frequency measurements
Consolidate the functions used to measure the input frequency into a single implementation and perform the measurement only once. Change-Id: I3d13e608a7256d154373542ca001cbda9c03c21b Signed-off-by: Scott Williams <scwilliams@nvidia.com> Reviewed-on: http://git-master/r/83613 Reviewed-by: Simone Willett <swillett@nvidia.com> Tested-by: Simone Willett <swillett@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/Makefile1
-rw-r--r--arch/arm/mach-tegra/clock-common.c73
-rw-r--r--arch/arm/mach-tegra/clock.h2
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c30
-rw-r--r--arch/arm/mach-tegra/tegra3_clocks.c36
-rw-r--r--arch/arm/mach-tegra/timer-t2.c2
-rw-r--r--arch/arm/mach-tegra/timer-t3.c2
7 files changed, 79 insertions, 67 deletions
diff --git a/arch/arm/mach-tegra/Makefile b/arch/arm/mach-tegra/Makefile
index b89d656a75f6..7400ee9ae6ec 100644
--- a/arch/arm/mach-tegra/Makefile
+++ b/arch/arm/mach-tegra/Makefile
@@ -9,6 +9,7 @@ obj-y += io.o
obj-y += irq.o
obj-$(CONFIG_TEGRA_GRHOST) += syncpt.o
obj-y += clock.o
+obj-y += clock-common.o
obj-y += timer.o
ifeq ($(CONFIG_ARCH_TEGRA_2x_SOC),y)
obj-y += tegra2_clocks.o
diff --git a/arch/arm/mach-tegra/clock-common.c b/arch/arm/mach-tegra/clock-common.c
new file mode 100644
index 000000000000..67c5d51378ae
--- /dev/null
+++ b/arch/arm/mach-tegra/clock-common.c
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2010-2012 NVIDIA Corporation
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/io.h>
+
+#include <mach/clk.h>
+#include <mach/iomap.h>
+
+#include "clock.h"
+
+#define clk_writel(value, reg) \
+ __raw_writel(value, (u32)reg_clk_base + (reg))
+#define clk_readl(reg) \
+ __raw_readl((u32)reg_clk_base + (reg))
+
+#define OSC_FREQ_DET 0x58
+#define OSC_FREQ_DET_TRIG (1<<31)
+
+#define OSC_FREQ_DET_STATUS 0x5C
+#define OSC_FREQ_DET_BUSY (1<<31)
+#define OSC_FREQ_DET_CNT_MASK 0xFFFF
+
+static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
+static unsigned long osc_input_freq;
+
+unsigned long tegra_clk_measure_input_freq(void)
+{
+ u32 clock_autodetect;
+
+ if (osc_input_freq)
+ return osc_input_freq;
+
+ clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
+ do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
+ clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
+
+ if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3)
+ osc_input_freq = 12000000;
+ else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3)
+ osc_input_freq = 13000000;
+ else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3)
+ osc_input_freq = 19200000;
+ else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3)
+ osc_input_freq = 26000000;
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+ else if (clock_autodetect >= 1025 - 3 && clock_autodetect <= 1025 + 3)
+ osc_input_freq = 16800000;
+ else if (clock_autodetect >= 2344 - 3 && clock_autodetect <= 2344 + 3)
+ osc_input_freq = 38400000;
+ else if (clock_autodetect >= 2928 - 3 && clock_autodetect <= 2928 + 3)
+ osc_input_freq = 48000000;
+#endif
+ else {
+ pr_err("%s: Unexpected clock autodetect value %d", __func__,
+ clock_autodetect);
+ BUG();
+ }
+ return osc_input_freq;
+}
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
index 36ca521fd2ce..dde9e07292a7 100644
--- a/arch/arm/mach-tegra/clock.h
+++ b/arch/arm/mach-tegra/clock.h
@@ -231,7 +231,7 @@ void tegra_soc_init_clocks(void);
void tegra_init_max_rate(struct clk *c, unsigned long max_rate);
void clk_init(struct clk *clk);
struct clk *tegra_get_clock_by_name(const char *name);
-unsigned long clk_measure_input_freq(void);
+unsigned long tegra_clk_measure_input_freq(void);
int clk_reparent(struct clk *c, struct clk *parent);
void tegra_clk_init_from_table(struct tegra_clk_init_table *table);
void clk_set_cansleep(struct clk *c);
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index a3d0585dff0d..e526c4c46e2e 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -59,13 +59,6 @@
#define OSC_CTRL_OSC_FREQ_26MHZ (3<<30)
#define OSC_CTRL_MASK (0x3f2 | OSC_CTRL_OSC_FREQ_MASK)
-#define OSC_FREQ_DET 0x58
-#define OSC_FREQ_DET_TRIG (1<<31)
-
-#define OSC_FREQ_DET_STATUS 0x5C
-#define OSC_FREQ_DET_BUSY (1<<31)
-#define OSC_FREQ_DET_CNT_MASK 0xFFFF
-
#define PERIPH_CLK_SOURCE_I2S1 0x100
#define PERIPH_CLK_SOURCE_EMC 0x19c
#define PERIPH_CLK_SOURCE_OSC 0x1fc
@@ -190,27 +183,6 @@ static int tegra_periph_clk_enable_refcount[3 * 32];
#define chipid_readl() \
__raw_readl((u32)misc_gp_hidrev_base + MISC_GP_HIDREV)
-unsigned long clk_measure_input_freq(void)
-{
- u32 clock_autodetect;
- clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
- do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
- clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
- if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
- return 12000000;
- } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
- return 13000000;
- } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
- return 19200000;
- } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
- return 26000000;
- } else {
- pr_err("%s: Unexpected clock autodetect value %d", __func__, clock_autodetect);
- BUG();
- return 0;
- }
-}
-
static int clk_div71_get_divider(unsigned long parent_rate, unsigned long rate)
{
s64 divider_u71 = parent_rate * 2;
@@ -253,7 +225,7 @@ static unsigned long tegra2_clk_m_autodetect_rate(struct clk *c)
{
u32 auto_clock_control = clk_readl(OSC_CTRL) & ~OSC_CTRL_OSC_FREQ_MASK;
- c->rate = clk_measure_input_freq();
+ c->rate = tegra_clk_measure_input_freq();
switch (c->rate) {
case 12000000:
auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
diff --git a/arch/arm/mach-tegra/tegra3_clocks.c b/arch/arm/mach-tegra/tegra3_clocks.c
index 4a54386c73dc..bbdf191ccd6d 100644
--- a/arch/arm/mach-tegra/tegra3_clocks.c
+++ b/arch/arm/mach-tegra/tegra3_clocks.c
@@ -100,13 +100,6 @@
#define OSC_CTRL_PLL_REF_DIV_2 (1<<26)
#define OSC_CTRL_PLL_REF_DIV_4 (2<<26)
-#define OSC_FREQ_DET 0x58
-#define OSC_FREQ_DET_TRIG (1<<31)
-
-#define OSC_FREQ_DET_STATUS 0x5C
-#define OSC_FREQ_DET_BUSY (1<<31)
-#define OSC_FREQ_DET_CNT_MASK 0xFFFF
-
#define PERIPH_CLK_SOURCE_I2S1 0x100
#define PERIPH_CLK_SOURCE_EMC 0x19c
#define PERIPH_CLK_SOURCE_OSC 0x1fc
@@ -405,33 +398,6 @@ static inline u32 periph_clk_to_reg(
return reg;
}
-unsigned long clk_measure_input_freq(void)
-{
- u32 clock_autodetect;
- clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
- do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
- clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
- if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3) {
- return 12000000;
- } else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3) {
- return 13000000;
- } else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3) {
- return 19200000;
- } else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3) {
- return 26000000;
- } else if (clock_autodetect >= 1025 - 3 && clock_autodetect <= 1025 + 3) {
- return 16800000;
- } else if (clock_autodetect >= 2344 - 3 && clock_autodetect <= 2344 + 3) {
- return 38400000;
- } else if (clock_autodetect >= 2928 - 3 && clock_autodetect <= 2928 + 3) {
- return 48000000;
- } else {
- pr_err("%s: Unexpected clock autodetect value %d", __func__, clock_autodetect);
- BUG();
- return 0;
- }
-}
-
static int clk_div_x1_get_divider(unsigned long parent_rate, unsigned long rate,
u32 max_x, u32 flags, u32 round_mode)
{
@@ -498,7 +464,7 @@ static unsigned long tegra3_clk_m_autodetect_rate(struct clk *c)
u32 auto_clock_control = osc_ctrl & ~OSC_CTRL_OSC_FREQ_MASK;
u32 pll_ref_div = osc_ctrl & OSC_CTRL_PLL_REF_DIV_MASK;
- c->rate = clk_measure_input_freq();
+ c->rate = tegra_clk_measure_input_freq();
switch (c->rate) {
case 12000000:
auto_clock_control |= OSC_CTRL_OSC_FREQ_12MHZ;
diff --git a/arch/arm/mach-tegra/timer-t2.c b/arch/arm/mach-tegra/timer-t2.c
index dff9abb76272..2d515abef16b 100644
--- a/arch/arm/mach-tegra/timer-t2.c
+++ b/arch/arm/mach-tegra/timer-t2.c
@@ -95,7 +95,7 @@ unsigned long tegra2_lp2_timer_remain(void)
void __init tegra2_init_timer(u32 *offset, int *irq)
{
- unsigned long rate = clk_measure_input_freq();
+ unsigned long rate = tegra_clk_measure_input_freq();
int ret;
switch (rate) {
diff --git a/arch/arm/mach-tegra/timer-t3.c b/arch/arm/mach-tegra/timer-t3.c
index cc8d540bcdca..0f6afc831dd5 100644
--- a/arch/arm/mach-tegra/timer-t3.c
+++ b/arch/arm/mach-tegra/timer-t3.c
@@ -221,7 +221,7 @@ unsigned long tegra3_lp2_timer_remain(void)
void __init tegra3_init_timer(u32 *offset, int *irq)
{
- unsigned long rate = clk_measure_input_freq();
+ unsigned long rate = tegra_clk_measure_input_freq();
switch (rate) {
case 12000000: