summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
authorVarun Wadekar <vwadekar@nvidia.com>2012-07-02 20:16:34 +0530
committerVarun Wadekar <vwadekar@nvidia.com>2012-07-02 20:26:20 +0530
commitfc621d4eea5a4d40f74aa30e34f4b50c1da98b96 (patch)
tree47fbf01ab14e412a243011fd71d3e186272d9378 /arch/arm
parentd081769dba3e865e95f4e4704b3f715af44dc67e (diff)
ARM: tegra: add common tegra_clk_measure_input_freq instead of the per chip version
Change-Id: I56536a96e0427bdfe46bd8ea253a45be1e824cb4 Signed-off-by: Varun Wadekar <vwadekar@nvidia.com>
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-tegra/clock.c53
-rw-r--r--arch/arm/mach-tegra/clock.h1
-rw-r--r--arch/arm/mach-tegra/tegra2_clocks.c30
-rw-r--r--arch/arm/mach-tegra/tegra30_clocks.c36
4 files changed, 56 insertions, 64 deletions
diff --git a/arch/arm/mach-tegra/clock.c b/arch/arm/mach-tegra/clock.c
index 0878444f1536..e74a11c37c73 100644
--- a/arch/arm/mach-tegra/clock.c
+++ b/arch/arm/mach-tegra/clock.c
@@ -29,9 +29,15 @@
#include <linux/seq_file.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
+#include <linux/bitops.h>
+#include <linux/io.h>
+#include <linux/bug.h>
#include <trace/events/power.h>
#include <mach/clk.h>
+#include <mach/iomap.h>
+#include <mach/io.h>
+#include <mach/hardware.h>
#include "board.h"
#include "clock.h"
@@ -813,6 +819,53 @@ void tegra_unregister_clk_rate_notifier(
clk_unlock_restore(c, &flags);
}
+#define OSC_FREQ_DET 0x58
+#define OSC_FREQ_DET_TRIG BIT(31)
+
+#define OSC_FREQ_DET_STATUS 0x5C
+#define OSC_FREQ_DET_BUSY BIT(31)
+#define OSC_FREQ_DET_CNT_MASK 0xFFFF
+
+unsigned long tegra_clk_measure_input_freq(void)
+{
+ u32 clock_autodetect;
+ void __iomem *clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
+
+ writel(OSC_FREQ_DET_TRIG | 1, (u32)clk_base + OSC_FREQ_DET);
+ do {} while (readl((u32)clk_base + OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
+
+ clock_autodetect = readl((u32)clk_base + 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;
+#ifndef CONFIG_ARCH_TEGRA_2x_SOC
+ } 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;
+#ifdef CONFIG_ARCH_TEGRA_11x_SOC
+ } else if (tegra_revision == TEGRA_REVISION_QT) {
+ if (clock_autodetect >= 2 && clock_autodetect <= 9)
+ return 115200;
+ else if (clock_autodetect >= 13 && clock_autodetect <= 15)
+ return 230400;
+#endif
+#endif
+ } else {
+ pr_err("%s: Unexpected clock autodetect value %d", __func__, clock_autodetect);
+ }
+
+ BUG();
+ return 0;
+}
+
#ifdef CONFIG_DEBUG_FS
/*
diff --git a/arch/arm/mach-tegra/clock.h b/arch/arm/mach-tegra/clock.h
index ccf8a03a5442..aebdf66aaefb 100644
--- a/arch/arm/mach-tegra/clock.h
+++ b/arch/arm/mach-tegra/clock.h
@@ -269,6 +269,7 @@ int tegra_emc_set_rate(unsigned long rate);
long tegra_emc_round_rate(unsigned long rate);
struct clk *tegra_emc_predict_parent(unsigned long rate, u32 *div_value);
void tegra_emc_timing_invalidate(void);
+unsigned long tegra_clk_measure_input_freq(void);
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
static inline bool tegra_clk_is_parent_allowed(struct clk *c, struct clk *p)
{ return true; }
diff --git a/arch/arm/mach-tegra/tegra2_clocks.c b/arch/arm/mach-tegra/tegra2_clocks.c
index 7fd96ade8e2a..cc9b0462fc2e 100644
--- a/arch/arm/mach-tegra/tegra2_clocks.c
+++ b/arch/arm/mach-tegra/tegra2_clocks.c
@@ -60,13 +60,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
@@ -192,27 +185,6 @@ static int tegra_periph_clk_enable_refcount[3 * 32];
#define chipid_readl() \
__raw_readl(misc_gp_hidrev_base + MISC_GP_HIDREV)
-static 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;
@@ -255,7 +227,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/tegra30_clocks.c b/arch/arm/mach-tegra/tegra30_clocks.c
index 0340424085a3..652846d0205c 100644
--- a/arch/arm/mach-tegra/tegra30_clocks.c
+++ b/arch/arm/mach-tegra/tegra30_clocks.c
@@ -101,13 +101,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
@@ -406,33 +399,6 @@ static inline u32 periph_clk_to_reg(
return reg;
}
-static 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)
{
@@ -499,7 +465,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;