diff options
author | Varun Wadekar <vwadekar@nvidia.com> | 2012-07-02 20:16:34 +0530 |
---|---|---|
committer | Varun Wadekar <vwadekar@nvidia.com> | 2012-07-02 20:26:20 +0530 |
commit | fc621d4eea5a4d40f74aa30e34f4b50c1da98b96 (patch) | |
tree | 47fbf01ab14e412a243011fd71d3e186272d9378 /arch/arm | |
parent | d081769dba3e865e95f4e4704b3f715af44dc67e (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.c | 53 | ||||
-rw-r--r-- | arch/arm/mach-tegra/clock.h | 1 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra2_clocks.c | 30 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra30_clocks.c | 36 |
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; |