]> nv-tegra.nvidia Code Review - linux-2.6.git/blob - arch/arm/mach-tegra/clock-common.c
ARM: tegra3: pm315/beaver: enable Realtek ALC5640 audio codec support
[linux-2.6.git] / arch / arm / mach-tegra / clock-common.c
1 /*
2  * Copyright (C) 2010-2012 NVIDIA Corporation
3  *
4  * This software is licensed under the terms of the GNU General Public
5  * License version 2, as published by the Free Software Foundation, and
6  * may be copied, distributed, and modified under those terms.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  *
13  */
14
15 #include <linux/kernel.h>
16 #include <linux/clk.h>
17 #include <linux/clkdev.h>
18 #include <linux/io.h>
19
20 #include <mach/clk.h>
21 #include <mach/iomap.h>
22
23 #include "clock.h"
24
25 #define clk_writel(value, reg) \
26         __raw_writel(value, (u32)reg_clk_base + (reg))
27 #define clk_readl(reg) \
28         __raw_readl((u32)reg_clk_base + (reg))
29
30 #define OSC_FREQ_DET                    0x58
31 #define OSC_FREQ_DET_TRIG               (1<<31)
32
33 #define OSC_FREQ_DET_STATUS             0x5C
34 #define OSC_FREQ_DET_BUSY               (1<<31)
35 #define OSC_FREQ_DET_CNT_MASK           0xFFFF
36
37 static void __iomem *reg_clk_base = IO_ADDRESS(TEGRA_CLK_RESET_BASE);
38 static unsigned long osc_input_freq;
39
40 unsigned long tegra_clk_measure_input_freq(void)
41 {
42         u32 clock_autodetect;
43
44         if (osc_input_freq)
45                 return osc_input_freq;
46
47         clk_writel(OSC_FREQ_DET_TRIG | 1, OSC_FREQ_DET);
48         do {} while (clk_readl(OSC_FREQ_DET_STATUS) & OSC_FREQ_DET_BUSY);
49         clock_autodetect = clk_readl(OSC_FREQ_DET_STATUS);
50
51         if (clock_autodetect >= 732 - 3 && clock_autodetect <= 732 + 3)
52                 osc_input_freq = 12000000;
53         else if (clock_autodetect >= 794 - 3 && clock_autodetect <= 794 + 3)
54                 osc_input_freq = 13000000;
55         else if (clock_autodetect >= 1172 - 3 && clock_autodetect <= 1172 + 3)
56                 osc_input_freq = 19200000;
57         else if (clock_autodetect >= 1587 - 3 && clock_autodetect <= 1587 + 3)
58                 osc_input_freq = 26000000;
59 #ifndef CONFIG_ARCH_TEGRA_2x_SOC
60         else if (clock_autodetect >= 1025 - 3 && clock_autodetect <= 1025 + 3)
61                 osc_input_freq = 16800000;
62         else if (clock_autodetect >= 2344 - 3 && clock_autodetect <= 2344 + 3)
63                 osc_input_freq = 38400000;
64         else if (clock_autodetect >= 2928 - 3 && clock_autodetect <= 2928 + 3)
65                 osc_input_freq = 48000000;
66 #endif
67         else {
68                 pr_err("%s: Unexpected clock autodetect value %d", __func__,
69                         clock_autodetect);
70                 BUG();
71         }
72         return osc_input_freq;
73 }