diff options
Diffstat (limited to 'arch/arm/mach-tegra/clock.c')
-rw-r--r-- | arch/arm/mach-tegra/clock.c | 53 |
1 files changed, 53 insertions, 0 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 /* |