diff options
Diffstat (limited to 'arch/arm/mach-tegra/tegra30_clocks.c')
-rw-r--r-- | arch/arm/mach-tegra/tegra30_clocks.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/tegra30_clocks.c b/arch/arm/mach-tegra/tegra30_clocks.c index 63615dadfbb2..5cd502c27163 100644 --- a/arch/arm/mach-tegra/tegra30_clocks.c +++ b/arch/arm/mach-tegra/tegra30_clocks.c | |||
@@ -35,6 +35,7 @@ | |||
35 | 35 | ||
36 | #include "clock.h" | 36 | #include "clock.h" |
37 | #include "fuse.h" | 37 | #include "fuse.h" |
38 | #include "tegra_cpu_car.h" | ||
38 | 39 | ||
39 | #define USE_PLL_LOCK_BITS 0 | 40 | #define USE_PLL_LOCK_BITS 0 |
40 | 41 | ||
@@ -299,6 +300,16 @@ | |||
299 | /* FIXME: recommended safety delay after lock is detected */ | 300 | /* FIXME: recommended safety delay after lock is detected */ |
300 | #define PLL_POST_LOCK_DELAY 100 | 301 | #define PLL_POST_LOCK_DELAY 100 |
301 | 302 | ||
303 | /* Tegra CPU clock and reset control regs */ | ||
304 | #define TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX 0x4c | ||
305 | #define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET 0x340 | ||
306 | #define TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR 0x344 | ||
307 | #define TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR 0x34c | ||
308 | #define TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 | ||
309 | |||
310 | #define CPU_CLOCK(cpu) (0x1 << (8 + cpu)) | ||
311 | #define CPU_RESET(cpu) (0x1111ul << (cpu)) | ||
312 | |||
302 | /** | 313 | /** |
303 | * Structure defining the fields for USB UTMI clocks Parameters. | 314 | * Structure defining the fields for USB UTMI clocks Parameters. |
304 | */ | 315 | */ |
@@ -2221,3 +2232,64 @@ struct clk_ops tegra_cml_clk_ops = { | |||
2221 | struct clk_ops tegra_pciex_clk_ops = { | 2232 | struct clk_ops tegra_pciex_clk_ops = { |
2222 | .recalc_rate = tegra30_clk_fixed_recalc_rate, | 2233 | .recalc_rate = tegra30_clk_fixed_recalc_rate, |
2223 | }; | 2234 | }; |
2235 | |||
2236 | /* Tegra30 CPU clock and reset control functions */ | ||
2237 | static void tegra30_wait_cpu_in_reset(u32 cpu) | ||
2238 | { | ||
2239 | unsigned int reg; | ||
2240 | |||
2241 | do { | ||
2242 | reg = readl(reg_clk_base + | ||
2243 | TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS); | ||
2244 | cpu_relax(); | ||
2245 | } while (!(reg & (1 << cpu))); /* check CPU been reset or not */ | ||
2246 | |||
2247 | return; | ||
2248 | } | ||
2249 | |||
2250 | static void tegra30_put_cpu_in_reset(u32 cpu) | ||
2251 | { | ||
2252 | writel(CPU_RESET(cpu), | ||
2253 | reg_clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_SET); | ||
2254 | dmb(); | ||
2255 | } | ||
2256 | |||
2257 | static void tegra30_cpu_out_of_reset(u32 cpu) | ||
2258 | { | ||
2259 | writel(CPU_RESET(cpu), | ||
2260 | reg_clk_base + TEGRA_CLK_RST_CONTROLLER_RST_CPU_CMPLX_CLR); | ||
2261 | wmb(); | ||
2262 | } | ||
2263 | |||
2264 | static void tegra30_enable_cpu_clock(u32 cpu) | ||
2265 | { | ||
2266 | unsigned int reg; | ||
2267 | |||
2268 | writel(CPU_CLOCK(cpu), | ||
2269 | reg_clk_base + TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR); | ||
2270 | reg = readl(reg_clk_base + | ||
2271 | TEGRA30_CLK_RST_CONTROLLER_CLK_CPU_CMPLX_CLR); | ||
2272 | } | ||
2273 | |||
2274 | static void tegra30_disable_cpu_clock(u32 cpu) | ||
2275 | { | ||
2276 | |||
2277 | unsigned int reg; | ||
2278 | |||
2279 | reg = readl(reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); | ||
2280 | writel(reg | CPU_CLOCK(cpu), | ||
2281 | reg_clk_base + TEGRA_CLK_RST_CONTROLLER_CLK_CPU_CMPLX); | ||
2282 | } | ||
2283 | |||
2284 | static struct tegra_cpu_car_ops tegra30_cpu_car_ops = { | ||
2285 | .wait_for_reset = tegra30_wait_cpu_in_reset, | ||
2286 | .put_in_reset = tegra30_put_cpu_in_reset, | ||
2287 | .out_of_reset = tegra30_cpu_out_of_reset, | ||
2288 | .enable_clock = tegra30_enable_cpu_clock, | ||
2289 | .disable_clock = tegra30_disable_cpu_clock, | ||
2290 | }; | ||
2291 | |||
2292 | void __init tegra30_cpu_car_ops_init(void) | ||
2293 | { | ||
2294 | tegra_cpu_car_ops = &tegra30_cpu_car_ops; | ||
2295 | } | ||