summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/clock.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/clock.c')
-rw-r--r--arch/arm/mach-tegra/clock.c53
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
/*