| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Copyright (c) 2012-2014 NVIDIA CORPORATION. All rights reserved. |
|---|
| 3 | | - * |
|---|
| 4 | | - * This program is free software; you can redistribute it and/or modify it |
|---|
| 5 | | - * under the terms and conditions of the GNU General Public License, |
|---|
| 6 | | - * version 2, as published by the Free Software Foundation. |
|---|
| 7 | | - * |
|---|
| 8 | | - * This program is distributed in the hope it will be useful, but WITHOUT |
|---|
| 9 | | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|---|
| 10 | | - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
|---|
| 11 | | - * more details. |
|---|
| 12 | | - * |
|---|
| 13 | | - * You should have received a copy of the GNU General Public License |
|---|
| 14 | | - * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|---|
| 15 | 4 | */ |
|---|
| 16 | 5 | |
|---|
| 17 | 6 | #include <linux/io.h> |
|---|
| .. | .. |
|---|
| 20 | 9 | #include <linux/clkdev.h> |
|---|
| 21 | 10 | #include <linux/of.h> |
|---|
| 22 | 11 | #include <linux/of_address.h> |
|---|
| 12 | +#include <linux/syscore_ops.h> |
|---|
| 23 | 13 | #include <linux/delay.h> |
|---|
| 24 | 14 | #include <linux/export.h> |
|---|
| 25 | 15 | #include <linux/mutex.h> |
|---|
| 26 | 16 | #include <linux/clk/tegra.h> |
|---|
| 27 | 17 | #include <dt-bindings/clock/tegra210-car.h> |
|---|
| 28 | 18 | #include <dt-bindings/reset/tegra210-car.h> |
|---|
| 29 | | -#include <linux/iopoll.h> |
|---|
| 19 | +#include <linux/sizes.h> |
|---|
| 30 | 20 | #include <soc/tegra/pmc.h> |
|---|
| 31 | 21 | |
|---|
| 32 | 22 | #include "clk.h" |
|---|
| .. | .. |
|---|
| 43 | 33 | #define CLK_SOURCE_CSITE 0x1d4 |
|---|
| 44 | 34 | #define CLK_SOURCE_EMC 0x19c |
|---|
| 45 | 35 | #define CLK_SOURCE_SOR1 0x410 |
|---|
| 36 | +#define CLK_SOURCE_SOR0 0x414 |
|---|
| 46 | 37 | #define CLK_SOURCE_LA 0x1f8 |
|---|
| 47 | 38 | #define CLK_SOURCE_SDMMC2 0x154 |
|---|
| 48 | 39 | #define CLK_SOURCE_SDMMC4 0x164 |
|---|
| 40 | +#define CLK_SOURCE_EMC_DLL 0x664 |
|---|
| 49 | 41 | |
|---|
| 50 | 42 | #define PLLC_BASE 0x80 |
|---|
| 51 | 43 | #define PLLC_OUT 0x84 |
|---|
| .. | .. |
|---|
| 230 | 222 | #define CLK_M_DIVISOR_SHIFT 2 |
|---|
| 231 | 223 | #define CLK_M_DIVISOR_MASK 0x3 |
|---|
| 232 | 224 | |
|---|
| 225 | +#define CLK_MASK_ARM 0x44 |
|---|
| 226 | +#define MISC_CLK_ENB 0x48 |
|---|
| 227 | + |
|---|
| 233 | 228 | #define RST_DFLL_DVCO 0x2f4 |
|---|
| 234 | 229 | #define DVFS_DFLL_RESET_SHIFT 0 |
|---|
| 235 | 230 | |
|---|
| 231 | +#define CLK_RST_CONTROLLER_CLK_OUT_ENB_X_SET 0x284 |
|---|
| 232 | +#define CLK_RST_CONTROLLER_CLK_OUT_ENB_X_CLR 0x288 |
|---|
| 233 | +#define CLK_OUT_ENB_X_CLK_ENB_EMC_DLL BIT(14) |
|---|
| 234 | + |
|---|
| 236 | 235 | #define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8 |
|---|
| 237 | 236 | #define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac |
|---|
| 237 | +#define CPU_SOFTRST_CTRL 0x380 |
|---|
| 238 | 238 | |
|---|
| 239 | 239 | #define LVL2_CLK_GATE_OVRA 0xf8 |
|---|
| 240 | 240 | #define LVL2_CLK_GATE_OVRC 0x3a0 |
|---|
| .. | .. |
|---|
| 308 | 308 | static DEFINE_SPINLOCK(pll_e_lock); |
|---|
| 309 | 309 | static DEFINE_SPINLOCK(pll_re_lock); |
|---|
| 310 | 310 | static DEFINE_SPINLOCK(pll_u_lock); |
|---|
| 311 | +static DEFINE_SPINLOCK(sor0_lock); |
|---|
| 311 | 312 | static DEFINE_SPINLOCK(sor1_lock); |
|---|
| 312 | 313 | static DEFINE_SPINLOCK(emc_lock); |
|---|
| 313 | 314 | static DEFINE_MUTEX(lvl2_ovr_lock); |
|---|
| .. | .. |
|---|
| 317 | 318 | [5] = 38400000, |
|---|
| 318 | 319 | [8] = 12000000, |
|---|
| 319 | 320 | }; |
|---|
| 320 | | - |
|---|
| 321 | | -static const char *mux_pllmcp_clkm[] = { |
|---|
| 322 | | - "pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_mb", "pll_mb", |
|---|
| 323 | | - "pll_p", |
|---|
| 324 | | -}; |
|---|
| 325 | | -#define mux_pllmcp_clkm_idx NULL |
|---|
| 326 | 321 | |
|---|
| 327 | 322 | #define PLL_ENABLE (1 << 30) |
|---|
| 328 | 323 | |
|---|
| .. | .. |
|---|
| 558 | 553 | writel_relaxed(val, clk_base + SATA_PLL_CFG0); |
|---|
| 559 | 554 | } |
|---|
| 560 | 555 | EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw); |
|---|
| 556 | + |
|---|
| 557 | +void tegra210_clk_emc_dll_enable(bool flag) |
|---|
| 558 | +{ |
|---|
| 559 | + u32 offset = flag ? CLK_RST_CONTROLLER_CLK_OUT_ENB_X_SET : |
|---|
| 560 | + CLK_RST_CONTROLLER_CLK_OUT_ENB_X_CLR; |
|---|
| 561 | + |
|---|
| 562 | + writel_relaxed(CLK_OUT_ENB_X_CLK_ENB_EMC_DLL, clk_base + offset); |
|---|
| 563 | +} |
|---|
| 564 | +EXPORT_SYMBOL_GPL(tegra210_clk_emc_dll_enable); |
|---|
| 565 | + |
|---|
| 566 | +void tegra210_clk_emc_dll_update_setting(u32 emc_dll_src_value) |
|---|
| 567 | +{ |
|---|
| 568 | + writel_relaxed(emc_dll_src_value, clk_base + CLK_SOURCE_EMC_DLL); |
|---|
| 569 | +} |
|---|
| 570 | +EXPORT_SYMBOL_GPL(tegra210_clk_emc_dll_update_setting); |
|---|
| 571 | + |
|---|
| 572 | +void tegra210_clk_emc_update_setting(u32 emc_src_value) |
|---|
| 573 | +{ |
|---|
| 574 | + writel_relaxed(emc_src_value, clk_base + CLK_SOURCE_EMC); |
|---|
| 575 | +} |
|---|
| 576 | +EXPORT_SYMBOL_GPL(tegra210_clk_emc_update_setting); |
|---|
| 561 | 577 | |
|---|
| 562 | 578 | static void tegra210_generic_mbist_war(struct tegra210_domain_mbist_war *mbist) |
|---|
| 563 | 579 | { |
|---|
| .. | .. |
|---|
| 994 | 1010 | pllre->params->defaults_set = true; |
|---|
| 995 | 1011 | |
|---|
| 996 | 1012 | if (val & PLL_ENABLE) { |
|---|
| 997 | | - pr_warn("PLL_RE already enabled. Postponing set full defaults\n"); |
|---|
| 998 | | - |
|---|
| 999 | 1013 | /* |
|---|
| 1000 | 1014 | * PLL is ON: check if defaults already set, then set those |
|---|
| 1001 | 1015 | * that can be updated in flight. |
|---|
| .. | .. |
|---|
| 1015 | 1029 | _pll_misc_chk_default(clk_base, pllre->params, 0, val, |
|---|
| 1016 | 1030 | ~mask & PLLRE_MISC0_WRITE_MASK); |
|---|
| 1017 | 1031 | |
|---|
| 1018 | | - /* Enable lock detect */ |
|---|
| 1032 | + /* The PLL doesn't work if it's in IDDQ. */ |
|---|
| 1019 | 1033 | val = readl_relaxed(clk_base + pllre->params->ext_misc_reg[0]); |
|---|
| 1034 | + if (val & PLLRE_MISC0_IDDQ) |
|---|
| 1035 | + pr_warn("unexpected IDDQ bit set for enabled clock\n"); |
|---|
| 1036 | + |
|---|
| 1037 | + /* Enable lock detect */ |
|---|
| 1020 | 1038 | val &= ~mask; |
|---|
| 1021 | 1039 | val |= PLLRE_MISC0_DEFAULT_VALUE & mask; |
|---|
| 1022 | 1040 | writel_relaxed(val, clk_base + pllre->params->ext_misc_reg[0]); |
|---|
| 1023 | 1041 | udelay(1); |
|---|
| 1042 | + |
|---|
| 1043 | + if (!pllre->params->defaults_set) |
|---|
| 1044 | + pr_warn("PLL_RE already enabled. Postponing set full defaults\n"); |
|---|
| 1024 | 1045 | |
|---|
| 1025 | 1046 | return; |
|---|
| 1026 | 1047 | } |
|---|
| .. | .. |
|---|
| 2309 | 2330 | [tegra_clk_i2c2] = { .dt_id = TEGRA210_CLK_I2C2, .present = true }, |
|---|
| 2310 | 2331 | [tegra_clk_uartc_8] = { .dt_id = TEGRA210_CLK_UARTC, .present = true }, |
|---|
| 2311 | 2332 | [tegra_clk_mipi_cal] = { .dt_id = TEGRA210_CLK_MIPI_CAL, .present = true }, |
|---|
| 2312 | | - [tegra_clk_emc] = { .dt_id = TEGRA210_CLK_EMC, .present = true }, |
|---|
| 2313 | 2333 | [tegra_clk_usb2] = { .dt_id = TEGRA210_CLK_USB2, .present = true }, |
|---|
| 2314 | 2334 | [tegra_clk_bsev] = { .dt_id = TEGRA210_CLK_BSEV, .present = true }, |
|---|
| 2315 | 2335 | [tegra_clk_uartd_8] = { .dt_id = TEGRA210_CLK_UARTD, .present = true }, |
|---|
| .. | .. |
|---|
| 2356 | 2376 | [tegra_clk_dpaux] = { .dt_id = TEGRA210_CLK_DPAUX, .present = true }, |
|---|
| 2357 | 2377 | [tegra_clk_dpaux1] = { .dt_id = TEGRA210_CLK_DPAUX1, .present = true }, |
|---|
| 2358 | 2378 | [tegra_clk_sor0] = { .dt_id = TEGRA210_CLK_SOR0, .present = true }, |
|---|
| 2359 | | - [tegra_clk_sor0_lvds] = { .dt_id = TEGRA210_CLK_SOR0_LVDS, .present = true }, |
|---|
| 2379 | + [tegra_clk_sor0_out] = { .dt_id = TEGRA210_CLK_SOR0_OUT, .present = true }, |
|---|
| 2360 | 2380 | [tegra_clk_sor1] = { .dt_id = TEGRA210_CLK_SOR1, .present = true }, |
|---|
| 2361 | | - [tegra_clk_sor1_src] = { .dt_id = TEGRA210_CLK_SOR1_SRC, .present = true }, |
|---|
| 2381 | + [tegra_clk_sor1_out] = { .dt_id = TEGRA210_CLK_SOR1_OUT, .present = true }, |
|---|
| 2362 | 2382 | [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true }, |
|---|
| 2363 | 2383 | [tegra_clk_pll_g_ref] = { .dt_id = TEGRA210_CLK_PLL_G_REF, .present = true, }, |
|---|
| 2364 | 2384 | [tegra_clk_uartb_8] = { .dt_id = TEGRA210_CLK_UARTB, .present = true }, |
|---|
| .. | .. |
|---|
| 2370 | 2390 | [tegra_clk_fuse_burn] = { .dt_id = TEGRA210_CLK_FUSE_BURN, .present = true }, |
|---|
| 2371 | 2391 | [tegra_clk_clk_32k] = { .dt_id = TEGRA210_CLK_CLK_32K, .present = true }, |
|---|
| 2372 | 2392 | [tegra_clk_clk_m] = { .dt_id = TEGRA210_CLK_CLK_M, .present = true }, |
|---|
| 2373 | | - [tegra_clk_clk_m_div2] = { .dt_id = TEGRA210_CLK_CLK_M_DIV2, .present = true }, |
|---|
| 2374 | | - [tegra_clk_clk_m_div4] = { .dt_id = TEGRA210_CLK_CLK_M_DIV4, .present = true }, |
|---|
| 2393 | + [tegra_clk_osc] = { .dt_id = TEGRA210_CLK_OSC, .present = true }, |
|---|
| 2394 | + [tegra_clk_osc_div2] = { .dt_id = TEGRA210_CLK_OSC_DIV2, .present = true }, |
|---|
| 2395 | + [tegra_clk_osc_div4] = { .dt_id = TEGRA210_CLK_OSC_DIV4, .present = true }, |
|---|
| 2375 | 2396 | [tegra_clk_pll_ref] = { .dt_id = TEGRA210_CLK_PLL_REF, .present = true }, |
|---|
| 2376 | 2397 | [tegra_clk_pll_c] = { .dt_id = TEGRA210_CLK_PLL_C, .present = true }, |
|---|
| 2377 | 2398 | [tegra_clk_pll_c_out1] = { .dt_id = TEGRA210_CLK_PLL_C_OUT1, .present = true }, |
|---|
| .. | .. |
|---|
| 2416 | 2437 | [tegra_clk_audio3] = { .dt_id = TEGRA210_CLK_AUDIO3, .present = true }, |
|---|
| 2417 | 2438 | [tegra_clk_audio4] = { .dt_id = TEGRA210_CLK_AUDIO4, .present = true }, |
|---|
| 2418 | 2439 | [tegra_clk_spdif] = { .dt_id = TEGRA210_CLK_SPDIF, .present = true }, |
|---|
| 2419 | | - [tegra_clk_clk_out_1] = { .dt_id = TEGRA210_CLK_CLK_OUT_1, .present = true }, |
|---|
| 2420 | | - [tegra_clk_clk_out_2] = { .dt_id = TEGRA210_CLK_CLK_OUT_2, .present = true }, |
|---|
| 2421 | | - [tegra_clk_clk_out_3] = { .dt_id = TEGRA210_CLK_CLK_OUT_3, .present = true }, |
|---|
| 2422 | | - [tegra_clk_blink] = { .dt_id = TEGRA210_CLK_BLINK, .present = true }, |
|---|
| 2423 | 2440 | [tegra_clk_xusb_gate] = { .dt_id = TEGRA210_CLK_XUSB_GATE, .present = true }, |
|---|
| 2424 | 2441 | [tegra_clk_xusb_host_src_8] = { .dt_id = TEGRA210_CLK_XUSB_HOST_SRC, .present = true }, |
|---|
| 2425 | 2442 | [tegra_clk_xusb_falcon_src_8] = { .dt_id = TEGRA210_CLK_XUSB_FALCON_SRC, .present = true }, |
|---|
| .. | .. |
|---|
| 2451 | 2468 | [tegra_clk_audio3_mux] = { .dt_id = TEGRA210_CLK_AUDIO3_MUX, .present = true }, |
|---|
| 2452 | 2469 | [tegra_clk_audio4_mux] = { .dt_id = TEGRA210_CLK_AUDIO4_MUX, .present = true }, |
|---|
| 2453 | 2470 | [tegra_clk_spdif_mux] = { .dt_id = TEGRA210_CLK_SPDIF_MUX, .present = true }, |
|---|
| 2454 | | - [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA210_CLK_CLK_OUT_1_MUX, .present = true }, |
|---|
| 2455 | | - [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA210_CLK_CLK_OUT_2_MUX, .present = true }, |
|---|
| 2456 | | - [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA210_CLK_CLK_OUT_3_MUX, .present = true }, |
|---|
| 2457 | 2471 | [tegra_clk_maud] = { .dt_id = TEGRA210_CLK_MAUD, .present = true }, |
|---|
| 2458 | 2472 | [tegra_clk_mipibif] = { .dt_id = TEGRA210_CLK_MIPIBIF, .present = true }, |
|---|
| 2459 | 2473 | [tegra_clk_qspi] = { .dt_id = TEGRA210_CLK_QSPI, .present = true }, |
|---|
| .. | .. |
|---|
| 2496 | 2510 | { .con_id = "clk_m", .dt_id = TEGRA210_CLK_CLK_M }, |
|---|
| 2497 | 2511 | { .con_id = "pll_ref", .dt_id = TEGRA210_CLK_PLL_REF }, |
|---|
| 2498 | 2512 | { .con_id = "clk_32k", .dt_id = TEGRA210_CLK_CLK_32K }, |
|---|
| 2499 | | - { .con_id = "clk_m_div2", .dt_id = TEGRA210_CLK_CLK_M_DIV2 }, |
|---|
| 2500 | | - { .con_id = "clk_m_div4", .dt_id = TEGRA210_CLK_CLK_M_DIV4 }, |
|---|
| 2513 | + { .con_id = "osc", .dt_id = TEGRA210_CLK_OSC }, |
|---|
| 2514 | + { .con_id = "osc_div2", .dt_id = TEGRA210_CLK_OSC_DIV2 }, |
|---|
| 2515 | + { .con_id = "osc_div4", .dt_id = TEGRA210_CLK_OSC_DIV4 }, |
|---|
| 2501 | 2516 | { .con_id = "pll_c", .dt_id = TEGRA210_CLK_PLL_C }, |
|---|
| 2502 | 2517 | { .con_id = "pll_c_out1", .dt_id = TEGRA210_CLK_PLL_C_OUT1 }, |
|---|
| 2503 | 2518 | { .con_id = "pll_c2", .dt_id = TEGRA210_CLK_PLL_C2 }, |
|---|
| .. | .. |
|---|
| 2539 | 2554 | { .con_id = "audio4", .dt_id = TEGRA210_CLK_AUDIO4 }, |
|---|
| 2540 | 2555 | { .con_id = "spdif", .dt_id = TEGRA210_CLK_SPDIF }, |
|---|
| 2541 | 2556 | { .con_id = "spdif_2x", .dt_id = TEGRA210_CLK_SPDIF_2X }, |
|---|
| 2542 | | - { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA210_CLK_EXTERN1 }, |
|---|
| 2543 | | - { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA210_CLK_EXTERN2 }, |
|---|
| 2544 | | - { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA210_CLK_EXTERN3 }, |
|---|
| 2545 | | - { .con_id = "blink", .dt_id = TEGRA210_CLK_BLINK }, |
|---|
| 2557 | + { .con_id = "extern1", .dt_id = TEGRA210_CLK_EXTERN1 }, |
|---|
| 2558 | + { .con_id = "extern2", .dt_id = TEGRA210_CLK_EXTERN2 }, |
|---|
| 2559 | + { .con_id = "extern3", .dt_id = TEGRA210_CLK_EXTERN3 }, |
|---|
| 2546 | 2560 | { .con_id = "cclk_g", .dt_id = TEGRA210_CLK_CCLK_G }, |
|---|
| 2547 | 2561 | { .con_id = "cclk_lp", .dt_id = TEGRA210_CLK_CCLK_LP }, |
|---|
| 2548 | 2562 | { .con_id = "sclk", .dt_id = TEGRA210_CLK_SCLK }, |
|---|
| .. | .. |
|---|
| 2556 | 2570 | { .con_id = "pll_c4_out2", .dt_id = TEGRA210_CLK_PLL_C4_OUT2 }, |
|---|
| 2557 | 2571 | { .con_id = "pll_c4_out3", .dt_id = TEGRA210_CLK_PLL_C4_OUT3 }, |
|---|
| 2558 | 2572 | { .con_id = "dpaux", .dt_id = TEGRA210_CLK_DPAUX }, |
|---|
| 2559 | | - { .con_id = "sor0", .dt_id = TEGRA210_CLK_SOR0 }, |
|---|
| 2560 | 2573 | }; |
|---|
| 2561 | 2574 | |
|---|
| 2562 | 2575 | static struct tegra_audio_clk_info tegra210_audio_plls[] = { |
|---|
| .. | .. |
|---|
| 2830 | 2843 | struct tegra_clk_pll_freq_table *fentry; |
|---|
| 2831 | 2844 | struct tegra_clk_pll pllu; |
|---|
| 2832 | 2845 | u32 reg; |
|---|
| 2846 | + int ret; |
|---|
| 2833 | 2847 | |
|---|
| 2834 | 2848 | for (fentry = pll_u_freq_table; fentry->input_rate; fentry++) { |
|---|
| 2835 | 2849 | if (fentry->input_rate == pll_ref_freq) |
|---|
| .. | .. |
|---|
| 2846 | 2860 | reg = readl_relaxed(clk_base + pllu.params->ext_misc_reg[0]); |
|---|
| 2847 | 2861 | reg &= ~BIT(pllu.params->iddq_bit_idx); |
|---|
| 2848 | 2862 | writel_relaxed(reg, clk_base + pllu.params->ext_misc_reg[0]); |
|---|
| 2849 | | - udelay(5); |
|---|
| 2863 | + fence_udelay(5, clk_base); |
|---|
| 2850 | 2864 | |
|---|
| 2851 | 2865 | reg = readl_relaxed(clk_base + PLLU_BASE); |
|---|
| 2852 | 2866 | reg &= ~GENMASK(20, 0); |
|---|
| .. | .. |
|---|
| 2854 | 2868 | reg |= fentry->n << 8; |
|---|
| 2855 | 2869 | reg |= fentry->p << 16; |
|---|
| 2856 | 2870 | writel(reg, clk_base + PLLU_BASE); |
|---|
| 2857 | | - udelay(1); |
|---|
| 2871 | + fence_udelay(1, clk_base); |
|---|
| 2858 | 2872 | reg |= PLL_ENABLE; |
|---|
| 2859 | 2873 | writel(reg, clk_base + PLLU_BASE); |
|---|
| 2860 | 2874 | |
|---|
| 2861 | | - readl_relaxed_poll_timeout_atomic(clk_base + PLLU_BASE, reg, |
|---|
| 2862 | | - reg & PLL_BASE_LOCK, 2, 1000); |
|---|
| 2863 | | - if (!(reg & PLL_BASE_LOCK)) { |
|---|
| 2875 | + /* |
|---|
| 2876 | + * During clocks resume, same PLLU init and enable sequence get |
|---|
| 2877 | + * executed. So, readx_poll_timeout_atomic can't be used here as it |
|---|
| 2878 | + * uses ktime_get() and timekeeping resume doesn't happen by that |
|---|
| 2879 | + * time. So, using tegra210_wait_for_mask for PLL LOCK. |
|---|
| 2880 | + */ |
|---|
| 2881 | + ret = tegra210_wait_for_mask(&pllu, PLLU_BASE, PLL_BASE_LOCK); |
|---|
| 2882 | + if (ret) { |
|---|
| 2864 | 2883 | pr_err("Timed out waiting for PLL_U to lock\n"); |
|---|
| 2865 | 2884 | return -ETIMEDOUT; |
|---|
| 2866 | 2885 | } |
|---|
| .. | .. |
|---|
| 2900 | 2919 | reg = readl_relaxed(clk_base + XUSB_PLL_CFG0); |
|---|
| 2901 | 2920 | reg &= ~XUSB_PLL_CFG0_PLLU_LOCK_DLY_MASK; |
|---|
| 2902 | 2921 | writel_relaxed(reg, clk_base + XUSB_PLL_CFG0); |
|---|
| 2903 | | - udelay(1); |
|---|
| 2922 | + fence_udelay(1, clk_base); |
|---|
| 2904 | 2923 | |
|---|
| 2905 | 2924 | reg = readl_relaxed(clk_base + PLLU_HW_PWRDN_CFG0); |
|---|
| 2906 | 2925 | reg |= PLLU_HW_PWRDN_CFG0_SEQ_ENABLE; |
|---|
| 2907 | 2926 | writel_relaxed(reg, clk_base + PLLU_HW_PWRDN_CFG0); |
|---|
| 2908 | | - udelay(1); |
|---|
| 2927 | + fence_udelay(1, clk_base); |
|---|
| 2909 | 2928 | |
|---|
| 2910 | 2929 | reg = readl_relaxed(clk_base + PLLU_BASE); |
|---|
| 2911 | 2930 | reg &= ~PLLU_BASE_CLKENABLE_USB; |
|---|
| .. | .. |
|---|
| 2920 | 2939 | return 0; |
|---|
| 2921 | 2940 | } |
|---|
| 2922 | 2941 | |
|---|
| 2923 | | -static const char * const sor1_out_parents[] = { |
|---|
| 2924 | | - /* |
|---|
| 2925 | | - * Bit 0 of the mux selects sor1_pad_clkout, irrespective of bit 1, so |
|---|
| 2926 | | - * the sor1_pad_clkout parent appears twice in the list below. This is |
|---|
| 2927 | | - * merely to support clk_get_parent() if firmware happened to set |
|---|
| 2928 | | - * these bits to 0b11. While not an invalid setting, code should |
|---|
| 2929 | | - * always set the bits to 0b01 to select sor1_pad_clkout. |
|---|
| 2930 | | - */ |
|---|
| 2931 | | - "sor_safe", "sor1_pad_clkout", "sor1", "sor1_pad_clkout", |
|---|
| 2942 | +/* |
|---|
| 2943 | + * The SOR hardware blocks are driven by two clocks: a module clock that is |
|---|
| 2944 | + * used to access registers and a pixel clock that is sourced from the same |
|---|
| 2945 | + * pixel clock that also drives the head attached to the SOR. The module |
|---|
| 2946 | + * clock is typically called sorX (with X being the SOR instance) and the |
|---|
| 2947 | + * pixel clock is called sorX_out. The source for the SOR pixel clock is |
|---|
| 2948 | + * referred to as the "parent" clock. |
|---|
| 2949 | + * |
|---|
| 2950 | + * On Tegra186 and newer, clocks are provided by the BPMP. Unfortunately the |
|---|
| 2951 | + * BPMP implementation for the SOR clocks doesn't exactly match the above in |
|---|
| 2952 | + * some aspects. For example, the SOR module is really clocked by the pad or |
|---|
| 2953 | + * sor_safe clocks, but BPMP models the sorX clock as being sourced by the |
|---|
| 2954 | + * pixel clocks. Conversely the sorX_out clock is sourced by the sor_safe or |
|---|
| 2955 | + * pad clocks on BPMP. |
|---|
| 2956 | + * |
|---|
| 2957 | + * In order to allow the display driver to deal with all SoC generations in |
|---|
| 2958 | + * a unified way, implement the BPMP semantics in this driver. |
|---|
| 2959 | + */ |
|---|
| 2960 | + |
|---|
| 2961 | +static const char * const sor0_parents[] = { |
|---|
| 2962 | + "pll_d_out0", |
|---|
| 2963 | +}; |
|---|
| 2964 | + |
|---|
| 2965 | +static const char * const sor0_out_parents[] = { |
|---|
| 2966 | + "sor_safe", "sor0_pad_clkout", |
|---|
| 2932 | 2967 | }; |
|---|
| 2933 | 2968 | |
|---|
| 2934 | 2969 | static const char * const sor1_parents[] = { |
|---|
| .. | .. |
|---|
| 2937 | 2972 | |
|---|
| 2938 | 2973 | static u32 sor1_parents_idx[] = { 0, 2, 5, 6 }; |
|---|
| 2939 | 2974 | |
|---|
| 2975 | +static const struct clk_div_table mc_div_table_tegra210[] = { |
|---|
| 2976 | + { .val = 0, .div = 2 }, |
|---|
| 2977 | + { .val = 1, .div = 4 }, |
|---|
| 2978 | + { .val = 2, .div = 1 }, |
|---|
| 2979 | + { .val = 3, .div = 2 }, |
|---|
| 2980 | + { .val = 0, .div = 0 }, |
|---|
| 2981 | +}; |
|---|
| 2982 | + |
|---|
| 2983 | +static void tegra210_clk_register_mc(const char *name, |
|---|
| 2984 | + const char *parent_name) |
|---|
| 2985 | +{ |
|---|
| 2986 | + struct clk *clk; |
|---|
| 2987 | + |
|---|
| 2988 | + clk = clk_register_divider_table(NULL, name, parent_name, |
|---|
| 2989 | + CLK_IS_CRITICAL, |
|---|
| 2990 | + clk_base + CLK_SOURCE_EMC, |
|---|
| 2991 | + 15, 2, CLK_DIVIDER_READ_ONLY, |
|---|
| 2992 | + mc_div_table_tegra210, &emc_lock); |
|---|
| 2993 | + clks[TEGRA210_CLK_MC] = clk; |
|---|
| 2994 | +} |
|---|
| 2995 | + |
|---|
| 2996 | +static const char * const sor1_out_parents[] = { |
|---|
| 2997 | + /* |
|---|
| 2998 | + * Bit 0 of the mux selects sor1_pad_clkout, irrespective of bit 1, so |
|---|
| 2999 | + * the sor1_pad_clkout parent appears twice in the list below. This is |
|---|
| 3000 | + * merely to support clk_get_parent() if firmware happened to set |
|---|
| 3001 | + * these bits to 0b11. While not an invalid setting, code should |
|---|
| 3002 | + * always set the bits to 0b01 to select sor1_pad_clkout. |
|---|
| 3003 | + */ |
|---|
| 3004 | + "sor_safe", "sor1_pad_clkout", "sor1_out", "sor1_pad_clkout", |
|---|
| 3005 | +}; |
|---|
| 3006 | + |
|---|
| 2940 | 3007 | static struct tegra_periph_init_data tegra210_periph[] = { |
|---|
| 3008 | + /* |
|---|
| 3009 | + * On Tegra210, the sor0 clock doesn't have a mux it bitfield 31:29, |
|---|
| 3010 | + * but it is hardwired to the pll_d_out0 clock. |
|---|
| 3011 | + */ |
|---|
| 3012 | + TEGRA_INIT_DATA_TABLE("sor0", NULL, NULL, sor0_parents, |
|---|
| 3013 | + CLK_SOURCE_SOR0, 29, 0x0, 0, 0, 0, 0, |
|---|
| 3014 | + 0, 182, 0, tegra_clk_sor0, NULL, 0, |
|---|
| 3015 | + &sor0_lock), |
|---|
| 3016 | + TEGRA_INIT_DATA_TABLE("sor0_out", NULL, NULL, sor0_out_parents, |
|---|
| 3017 | + CLK_SOURCE_SOR0, 14, 0x1, 0, 0, 0, 0, |
|---|
| 3018 | + 0, 0, TEGRA_PERIPH_NO_GATE, tegra_clk_sor0_out, |
|---|
| 3019 | + NULL, 0, &sor0_lock), |
|---|
| 2941 | 3020 | TEGRA_INIT_DATA_TABLE("sor1", NULL, NULL, sor1_parents, |
|---|
| 2942 | 3021 | CLK_SOURCE_SOR1, 29, 0x7, 0, 0, 8, 1, |
|---|
| 2943 | | - TEGRA_DIVIDER_ROUND_UP, 183, 0, tegra_clk_sor1, |
|---|
| 2944 | | - sor1_parents_idx, 0, &sor1_lock), |
|---|
| 3022 | + TEGRA_DIVIDER_ROUND_UP, 183, 0, |
|---|
| 3023 | + tegra_clk_sor1, sor1_parents_idx, 0, |
|---|
| 3024 | + &sor1_lock), |
|---|
| 3025 | + TEGRA_INIT_DATA_TABLE("sor1_out", NULL, NULL, sor1_out_parents, |
|---|
| 3026 | + CLK_SOURCE_SOR1, 14, 0x3, 0, 0, 0, 0, |
|---|
| 3027 | + 0, 0, TEGRA_PERIPH_NO_GATE, |
|---|
| 3028 | + tegra_clk_sor1_out, NULL, 0, &sor1_lock), |
|---|
| 2945 | 3029 | }; |
|---|
| 2946 | 3030 | |
|---|
| 2947 | 3031 | static const char * const la_parents[] = { |
|---|
| .. | .. |
|---|
| 2949 | 3033 | }; |
|---|
| 2950 | 3034 | |
|---|
| 2951 | 3035 | static struct tegra_clk_periph tegra210_la = |
|---|
| 2952 | | - TEGRA_CLK_PERIPH(29, 7, 9, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, 76, 0, NULL, 0); |
|---|
| 3036 | + TEGRA_CLK_PERIPH(29, 7, 9, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP, 76, 0, NULL, NULL); |
|---|
| 2953 | 3037 | |
|---|
| 2954 | | -static __init void tegra210_periph_clk_init(void __iomem *clk_base, |
|---|
| 3038 | +static __init void tegra210_periph_clk_init(struct device_node *np, |
|---|
| 3039 | + void __iomem *clk_base, |
|---|
| 2955 | 3040 | void __iomem *pmc_base) |
|---|
| 2956 | 3041 | { |
|---|
| 2957 | 3042 | struct clk *clk; |
|---|
| .. | .. |
|---|
| 2974 | 3059 | 1, 17, 207); |
|---|
| 2975 | 3060 | clks[TEGRA210_CLK_DPAUX1] = clk; |
|---|
| 2976 | 3061 | |
|---|
| 2977 | | - clk = clk_register_mux_table(NULL, "sor1_out", sor1_out_parents, |
|---|
| 2978 | | - ARRAY_SIZE(sor1_out_parents), 0, |
|---|
| 2979 | | - clk_base + CLK_SOURCE_SOR1, 14, 0x3, |
|---|
| 2980 | | - 0, NULL, &sor1_lock); |
|---|
| 2981 | | - clks[TEGRA210_CLK_SOR1_OUT] = clk; |
|---|
| 2982 | | - |
|---|
| 2983 | 3062 | /* pll_d_dsi_out */ |
|---|
| 2984 | 3063 | clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0, |
|---|
| 2985 | 3064 | clk_base + PLLD_MISC0, 21, 0, &pll_d_lock); |
|---|
| .. | .. |
|---|
| 2997 | 3076 | periph_clk_enb_refcnt); |
|---|
| 2998 | 3077 | clks[TEGRA210_CLK_DSIB] = clk; |
|---|
| 2999 | 3078 | |
|---|
| 3079 | + /* csi_tpg */ |
|---|
| 3080 | + clk = clk_register_gate(NULL, "csi_tpg", "pll_d", |
|---|
| 3081 | + CLK_SET_RATE_PARENT, clk_base + PLLD_BASE, |
|---|
| 3082 | + 23, 0, &pll_d_lock); |
|---|
| 3083 | + clk_register_clkdev(clk, "csi_tpg", NULL); |
|---|
| 3084 | + clks[TEGRA210_CLK_CSI_TPG] = clk; |
|---|
| 3085 | + |
|---|
| 3000 | 3086 | /* la */ |
|---|
| 3001 | 3087 | clk = tegra_clk_register_periph("la", la_parents, |
|---|
| 3002 | 3088 | ARRAY_SIZE(la_parents), &tegra210_la, clk_base, |
|---|
| 3003 | 3089 | CLK_SOURCE_LA, 0); |
|---|
| 3004 | 3090 | clks[TEGRA210_CLK_LA] = clk; |
|---|
| 3005 | | - |
|---|
| 3006 | | - /* emc mux */ |
|---|
| 3007 | | - clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm, |
|---|
| 3008 | | - ARRAY_SIZE(mux_pllmcp_clkm), 0, |
|---|
| 3009 | | - clk_base + CLK_SOURCE_EMC, |
|---|
| 3010 | | - 29, 3, 0, &emc_lock); |
|---|
| 3011 | | - |
|---|
| 3012 | | - clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC, |
|---|
| 3013 | | - &emc_lock); |
|---|
| 3014 | | - clks[TEGRA210_CLK_MC] = clk; |
|---|
| 3015 | 3091 | |
|---|
| 3016 | 3092 | /* cml0 */ |
|---|
| 3017 | 3093 | clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX, |
|---|
| .. | .. |
|---|
| 3055 | 3131 | } |
|---|
| 3056 | 3132 | |
|---|
| 3057 | 3133 | tegra_periph_clk_init(clk_base, pmc_base, tegra210_clks, &pll_p_params); |
|---|
| 3134 | + |
|---|
| 3135 | + /* emc */ |
|---|
| 3136 | + clk = tegra210_clk_register_emc(np, clk_base); |
|---|
| 3137 | + clks[TEGRA210_CLK_EMC] = clk; |
|---|
| 3138 | + |
|---|
| 3139 | + /* mc */ |
|---|
| 3140 | + tegra210_clk_register_mc("mc", "emc"); |
|---|
| 3058 | 3141 | } |
|---|
| 3059 | 3142 | |
|---|
| 3060 | 3143 | static void __init tegra210_pll_init(void __iomem *clk_base, |
|---|
| .. | .. |
|---|
| 3114 | 3197 | CLK_SET_RATE_PARENT, 1, 1); |
|---|
| 3115 | 3198 | clk_register_clkdev(clk, "pll_m_ud", NULL); |
|---|
| 3116 | 3199 | clks[TEGRA210_CLK_PLL_M_UD] = clk; |
|---|
| 3200 | + |
|---|
| 3201 | + /* PLLMB_UD */ |
|---|
| 3202 | + clk = clk_register_fixed_factor(NULL, "pll_mb_ud", "pll_mb", |
|---|
| 3203 | + CLK_SET_RATE_PARENT, 1, 1); |
|---|
| 3204 | + clk_register_clkdev(clk, "pll_mb_ud", NULL); |
|---|
| 3205 | + clks[TEGRA210_CLK_PLL_MB_UD] = clk; |
|---|
| 3206 | + |
|---|
| 3207 | + /* PLLP_UD */ |
|---|
| 3208 | + clk = clk_register_fixed_factor(NULL, "pll_p_ud", "pll_p", |
|---|
| 3209 | + 0, 1, 1); |
|---|
| 3210 | + clks[TEGRA210_CLK_PLL_P_UD] = clk; |
|---|
| 3117 | 3211 | |
|---|
| 3118 | 3212 | /* PLLU_VCO */ |
|---|
| 3119 | 3213 | if (!tegra210_init_pllu()) { |
|---|
| .. | .. |
|---|
| 3292 | 3386 | } |
|---|
| 3293 | 3387 | |
|---|
| 3294 | 3388 | #ifdef CONFIG_PM_SLEEP |
|---|
| 3389 | +#define car_readl(_base, _off) readl_relaxed(clk_base + (_base) + ((_off) * 4)) |
|---|
| 3390 | +#define car_writel(_val, _base, _off) \ |
|---|
| 3391 | + writel_relaxed(_val, clk_base + (_base) + ((_off) * 4)) |
|---|
| 3392 | + |
|---|
| 3393 | +static u32 spare_reg_ctx, misc_clk_enb_ctx, clk_msk_arm_ctx; |
|---|
| 3394 | +static u32 cpu_softrst_ctx[3]; |
|---|
| 3395 | + |
|---|
| 3396 | +static int tegra210_clk_suspend(void) |
|---|
| 3397 | +{ |
|---|
| 3398 | + unsigned int i; |
|---|
| 3399 | + |
|---|
| 3400 | + clk_save_context(); |
|---|
| 3401 | + |
|---|
| 3402 | + /* |
|---|
| 3403 | + * Save the bootloader configured clock registers SPARE_REG0, |
|---|
| 3404 | + * MISC_CLK_ENB, CLK_MASK_ARM, CPU_SOFTRST_CTRL. |
|---|
| 3405 | + */ |
|---|
| 3406 | + spare_reg_ctx = readl_relaxed(clk_base + SPARE_REG0); |
|---|
| 3407 | + misc_clk_enb_ctx = readl_relaxed(clk_base + MISC_CLK_ENB); |
|---|
| 3408 | + clk_msk_arm_ctx = readl_relaxed(clk_base + CLK_MASK_ARM); |
|---|
| 3409 | + |
|---|
| 3410 | + for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++) |
|---|
| 3411 | + cpu_softrst_ctx[i] = car_readl(CPU_SOFTRST_CTRL, i); |
|---|
| 3412 | + |
|---|
| 3413 | + tegra_clk_periph_suspend(); |
|---|
| 3414 | + return 0; |
|---|
| 3415 | +} |
|---|
| 3416 | + |
|---|
| 3417 | +static void tegra210_clk_resume(void) |
|---|
| 3418 | +{ |
|---|
| 3419 | + unsigned int i; |
|---|
| 3420 | + |
|---|
| 3421 | + tegra_clk_osc_resume(clk_base); |
|---|
| 3422 | + |
|---|
| 3423 | + /* |
|---|
| 3424 | + * Restore the bootloader configured clock registers SPARE_REG0, |
|---|
| 3425 | + * MISC_CLK_ENB, CLK_MASK_ARM, CPU_SOFTRST_CTRL from saved context. |
|---|
| 3426 | + */ |
|---|
| 3427 | + writel_relaxed(spare_reg_ctx, clk_base + SPARE_REG0); |
|---|
| 3428 | + writel_relaxed(misc_clk_enb_ctx, clk_base + MISC_CLK_ENB); |
|---|
| 3429 | + writel_relaxed(clk_msk_arm_ctx, clk_base + CLK_MASK_ARM); |
|---|
| 3430 | + |
|---|
| 3431 | + for (i = 0; i < ARRAY_SIZE(cpu_softrst_ctx); i++) |
|---|
| 3432 | + car_writel(cpu_softrst_ctx[i], CPU_SOFTRST_CTRL, i); |
|---|
| 3433 | + |
|---|
| 3434 | + /* |
|---|
| 3435 | + * Tegra clock programming sequence recommends peripheral clock to |
|---|
| 3436 | + * be enabled prior to changing its clock source and divider to |
|---|
| 3437 | + * prevent glitchless frequency switch. |
|---|
| 3438 | + * So, enable all peripheral clocks before restoring their source |
|---|
| 3439 | + * and dividers. |
|---|
| 3440 | + */ |
|---|
| 3441 | + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_L, clk_base + CLK_OUT_ENB_L); |
|---|
| 3442 | + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_H, clk_base + CLK_OUT_ENB_H); |
|---|
| 3443 | + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_U, clk_base + CLK_OUT_ENB_U); |
|---|
| 3444 | + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_V, clk_base + CLK_OUT_ENB_V); |
|---|
| 3445 | + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_W, clk_base + CLK_OUT_ENB_W); |
|---|
| 3446 | + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_X, clk_base + CLK_OUT_ENB_X); |
|---|
| 3447 | + writel_relaxed(TEGRA210_CLK_ENB_VLD_MSK_Y, clk_base + CLK_OUT_ENB_Y); |
|---|
| 3448 | + |
|---|
| 3449 | + /* wait for all writes to happen to have all the clocks enabled */ |
|---|
| 3450 | + fence_udelay(2, clk_base); |
|---|
| 3451 | + |
|---|
| 3452 | + /* restore PLLs and all peripheral clock rates */ |
|---|
| 3453 | + tegra210_init_pllu(); |
|---|
| 3454 | + clk_restore_context(); |
|---|
| 3455 | + |
|---|
| 3456 | + /* restore saved context of peripheral clocks and reset state */ |
|---|
| 3457 | + tegra_clk_periph_resume(); |
|---|
| 3458 | +} |
|---|
| 3459 | + |
|---|
| 3295 | 3460 | static void tegra210_cpu_clock_suspend(void) |
|---|
| 3296 | 3461 | { |
|---|
| 3297 | 3462 | /* switch coresite to clk_m, save off original source */ |
|---|
| .. | .. |
|---|
| 3306 | 3471 | clk_base + CLK_SOURCE_CSITE); |
|---|
| 3307 | 3472 | } |
|---|
| 3308 | 3473 | #endif |
|---|
| 3474 | + |
|---|
| 3475 | +static struct syscore_ops tegra_clk_syscore_ops = { |
|---|
| 3476 | +#ifdef CONFIG_PM_SLEEP |
|---|
| 3477 | + .suspend = tegra210_clk_suspend, |
|---|
| 3478 | + .resume = tegra210_clk_resume, |
|---|
| 3479 | +#endif |
|---|
| 3480 | +}; |
|---|
| 3309 | 3481 | |
|---|
| 3310 | 3482 | static struct tegra_cpu_car_ops tegra210_cpu_car_ops = { |
|---|
| 3311 | 3483 | .wait_for_reset = tegra210_wait_cpu_in_reset, |
|---|
| .. | .. |
|---|
| 3326 | 3498 | { TEGRA210_CLK_UARTB, TEGRA210_CLK_PLL_P, 408000000, 0 }, |
|---|
| 3327 | 3499 | { TEGRA210_CLK_UARTC, TEGRA210_CLK_PLL_P, 408000000, 0 }, |
|---|
| 3328 | 3500 | { TEGRA210_CLK_UARTD, TEGRA210_CLK_PLL_P, 408000000, 0 }, |
|---|
| 3329 | | - { TEGRA210_CLK_PLL_A, TEGRA210_CLK_CLK_MAX, 564480000, 1 }, |
|---|
| 3330 | | - { TEGRA210_CLK_PLL_A_OUT0, TEGRA210_CLK_CLK_MAX, 11289600, 1 }, |
|---|
| 3331 | | - { TEGRA210_CLK_EXTERN1, TEGRA210_CLK_PLL_A_OUT0, 0, 1 }, |
|---|
| 3332 | | - { TEGRA210_CLK_CLK_OUT_1_MUX, TEGRA210_CLK_EXTERN1, 0, 1 }, |
|---|
| 3333 | | - { TEGRA210_CLK_CLK_OUT_1, TEGRA210_CLK_CLK_MAX, 0, 1 }, |
|---|
| 3501 | + { TEGRA210_CLK_PLL_A, TEGRA210_CLK_CLK_MAX, 564480000, 0 }, |
|---|
| 3502 | + { TEGRA210_CLK_PLL_A_OUT0, TEGRA210_CLK_CLK_MAX, 11289600, 0 }, |
|---|
| 3334 | 3503 | { TEGRA210_CLK_I2S0, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 }, |
|---|
| 3335 | 3504 | { TEGRA210_CLK_I2S1, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 }, |
|---|
| 3336 | 3505 | { TEGRA210_CLK_I2S2, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 }, |
|---|
| .. | .. |
|---|
| 3342 | 3511 | { TEGRA210_CLK_DFLL_SOC, TEGRA210_CLK_PLL_P, 51000000, 1 }, |
|---|
| 3343 | 3512 | { TEGRA210_CLK_DFLL_REF, TEGRA210_CLK_PLL_P, 51000000, 1 }, |
|---|
| 3344 | 3513 | { TEGRA210_CLK_SBC4, TEGRA210_CLK_PLL_P, 12000000, 1 }, |
|---|
| 3345 | | - { TEGRA210_CLK_PLL_RE_VCO, TEGRA210_CLK_CLK_MAX, 672000000, 1 }, |
|---|
| 3346 | 3514 | { TEGRA210_CLK_PLL_U_OUT1, TEGRA210_CLK_CLK_MAX, 48000000, 1 }, |
|---|
| 3347 | 3515 | { TEGRA210_CLK_XUSB_GATE, TEGRA210_CLK_CLK_MAX, 0, 1 }, |
|---|
| 3348 | 3516 | { TEGRA210_CLK_XUSB_SS_SRC, TEGRA210_CLK_PLL_U_480M, 120000000, 0 }, |
|---|
| .. | .. |
|---|
| 3529 | 3697 | } |
|---|
| 3530 | 3698 | |
|---|
| 3531 | 3699 | pmc_base = of_iomap(node, 0); |
|---|
| 3700 | + of_node_put(node); |
|---|
| 3532 | 3701 | if (!pmc_base) { |
|---|
| 3533 | 3702 | pr_err("Can't map pmc registers\n"); |
|---|
| 3534 | 3703 | WARN_ON(1); |
|---|
| .. | .. |
|---|
| 3558 | 3727 | if (!clks) |
|---|
| 3559 | 3728 | return; |
|---|
| 3560 | 3729 | |
|---|
| 3561 | | - value = clk_readl(clk_base + SPARE_REG0) >> CLK_M_DIVISOR_SHIFT; |
|---|
| 3730 | + value = readl(clk_base + SPARE_REG0) >> CLK_M_DIVISOR_SHIFT; |
|---|
| 3562 | 3731 | clk_m_div = (value & CLK_M_DIVISOR_MASK) + 1; |
|---|
| 3563 | 3732 | |
|---|
| 3564 | 3733 | if (tegra_osc_clk_init(clk_base, tegra210_clks, tegra210_input_freq, |
|---|
| .. | .. |
|---|
| 3568 | 3737 | |
|---|
| 3569 | 3738 | tegra_fixed_clk_init(tegra210_clks); |
|---|
| 3570 | 3739 | tegra210_pll_init(clk_base, pmc_base); |
|---|
| 3571 | | - tegra210_periph_clk_init(clk_base, pmc_base); |
|---|
| 3740 | + tegra210_periph_clk_init(np, clk_base, pmc_base); |
|---|
| 3572 | 3741 | tegra_audio_clk_init(clk_base, pmc_base, tegra210_clks, |
|---|
| 3573 | 3742 | tegra210_audio_plls, |
|---|
| 3574 | 3743 | ARRAY_SIZE(tegra210_audio_plls), 24576000); |
|---|
| 3575 | | - tegra_pmc_clk_init(pmc_base, tegra210_clks); |
|---|
| 3576 | 3744 | |
|---|
| 3577 | 3745 | /* For Tegra210, PLLD is the only source for DSIA & DSIB */ |
|---|
| 3578 | | - value = clk_readl(clk_base + PLLD_BASE); |
|---|
| 3746 | + value = readl(clk_base + PLLD_BASE); |
|---|
| 3579 | 3747 | value &= ~BIT(25); |
|---|
| 3580 | | - clk_writel(value, clk_base + PLLD_BASE); |
|---|
| 3748 | + writel(value, clk_base + PLLD_BASE); |
|---|
| 3581 | 3749 | |
|---|
| 3582 | 3750 | tegra_clk_apply_init_table = tegra210_clock_apply_init_table; |
|---|
| 3583 | 3751 | |
|---|
| .. | .. |
|---|
| 3592 | 3760 | tegra210_mbist_clk_init(); |
|---|
| 3593 | 3761 | |
|---|
| 3594 | 3762 | tegra_cpu_car_ops = &tegra210_cpu_car_ops; |
|---|
| 3763 | + |
|---|
| 3764 | + register_syscore_ops(&tegra_clk_syscore_ops); |
|---|
| 3595 | 3765 | } |
|---|
| 3596 | 3766 | CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init); |
|---|