.. | .. |
---|
| 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> |
---|
.. | .. |
---|
38 | 27 | |
---|
39 | 28 | #define CLK_SOURCE_CSITE 0x1d4 |
---|
40 | 29 | #define CLK_SOURCE_EMC 0x19c |
---|
| 30 | +#define CLK_SOURCE_SOR0 0x414 |
---|
41 | 31 | |
---|
42 | 32 | #define RST_DFLL_DVCO 0x2f4 |
---|
43 | 33 | #define DVFS_DFLL_RESET_SHIFT 0 |
---|
.. | .. |
---|
102 | 92 | /* Tegra CPU clock and reset control regs */ |
---|
103 | 93 | #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470 |
---|
104 | 94 | |
---|
| 95 | +#define MASK(x) (BIT(x) - 1) |
---|
| 96 | + |
---|
| 97 | +#define MUX8_NOGATE_LOCK(_name, _parents, _offset, _clk_id, _lock) \ |
---|
| 98 | + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset, \ |
---|
| 99 | + 29, MASK(3), 0, 0, 8, 1, TEGRA_DIVIDER_ROUND_UP,\ |
---|
| 100 | + 0, TEGRA_PERIPH_NO_GATE, _clk_id,\ |
---|
| 101 | + _parents##_idx, 0, _lock) |
---|
| 102 | + |
---|
| 103 | +#define NODIV(_name, _parents, _offset, \ |
---|
| 104 | + _mux_shift, _mux_mask, _clk_num, \ |
---|
| 105 | + _gate_flags, _clk_id, _lock) \ |
---|
| 106 | + TEGRA_INIT_DATA_TABLE(_name, NULL, NULL, _parents, _offset,\ |
---|
| 107 | + _mux_shift, _mux_mask, 0, 0, 0, 0, 0,\ |
---|
| 108 | + _clk_num, (_gate_flags) | TEGRA_PERIPH_NO_DIV,\ |
---|
| 109 | + _clk_id, _parents##_idx, 0, _lock) |
---|
| 110 | + |
---|
105 | 111 | #ifdef CONFIG_PM_SLEEP |
---|
106 | 112 | static struct cpu_clk_suspend_context { |
---|
107 | 113 | u32 clk_csite_src; |
---|
.. | .. |
---|
121 | 127 | static DEFINE_SPINLOCK(pll_re_lock); |
---|
122 | 128 | static DEFINE_SPINLOCK(pll_u_lock); |
---|
123 | 129 | static DEFINE_SPINLOCK(emc_lock); |
---|
| 130 | +static DEFINE_SPINLOCK(sor0_lock); |
---|
124 | 131 | |
---|
125 | 132 | /* possible OSC frequencies in Hz */ |
---|
126 | 133 | static unsigned long tegra124_input_freq[] = { |
---|
.. | .. |
---|
413 | 420 | .base_reg = PLLM_BASE, |
---|
414 | 421 | .misc_reg = PLLM_MISC, |
---|
415 | 422 | .lock_mask = PLL_BASE_LOCK, |
---|
416 | | - .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE, |
---|
417 | 423 | .lock_delay = 300, |
---|
418 | 424 | .max_p = 5, |
---|
419 | 425 | .pdiv_tohw = pllm_p, |
---|
.. | .. |
---|
421 | 427 | .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE, |
---|
422 | 428 | .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2, |
---|
423 | 429 | .freq_table = pll_m_freq_table, |
---|
424 | | - .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE, |
---|
| 430 | + .flags = TEGRA_PLL_USE_LOCK, |
---|
425 | 431 | }; |
---|
426 | 432 | |
---|
427 | 433 | static struct tegra_clk_pll_freq_table pll_e_freq_table[] = { |
---|
.. | .. |
---|
841 | 847 | [tegra_clk_adx1] = { .dt_id = TEGRA124_CLK_ADX1, .present = true }, |
---|
842 | 848 | [tegra_clk_dpaux] = { .dt_id = TEGRA124_CLK_DPAUX, .present = true }, |
---|
843 | 849 | [tegra_clk_sor0] = { .dt_id = TEGRA124_CLK_SOR0, .present = true }, |
---|
844 | | - [tegra_clk_sor0_lvds] = { .dt_id = TEGRA124_CLK_SOR0_LVDS, .present = true }, |
---|
| 850 | + [tegra_clk_sor0_out] = { .dt_id = TEGRA124_CLK_SOR0_OUT, .present = true }, |
---|
845 | 851 | [tegra_clk_gpu] = { .dt_id = TEGRA124_CLK_GPU, .present = true }, |
---|
846 | 852 | [tegra_clk_amx1] = { .dt_id = TEGRA124_CLK_AMX1, .present = true }, |
---|
847 | 853 | [tegra_clk_uartb] = { .dt_id = TEGRA124_CLK_UARTB, .present = true }, |
---|
.. | .. |
---|
854 | 860 | [tegra_clk_fuse_burn] = { .dt_id = TEGRA124_CLK_FUSE_BURN, .present = true }, |
---|
855 | 861 | [tegra_clk_clk_32k] = { .dt_id = TEGRA124_CLK_CLK_32K, .present = true }, |
---|
856 | 862 | [tegra_clk_clk_m] = { .dt_id = TEGRA124_CLK_CLK_M, .present = true }, |
---|
857 | | - [tegra_clk_clk_m_div2] = { .dt_id = TEGRA124_CLK_CLK_M_DIV2, .present = true }, |
---|
858 | | - [tegra_clk_clk_m_div4] = { .dt_id = TEGRA124_CLK_CLK_M_DIV4, .present = true }, |
---|
| 863 | + [tegra_clk_osc] = { .dt_id = TEGRA124_CLK_OSC, .present = true }, |
---|
| 864 | + [tegra_clk_osc_div2] = { .dt_id = TEGRA124_CLK_OSC_DIV2, .present = true }, |
---|
| 865 | + [tegra_clk_osc_div4] = { .dt_id = TEGRA124_CLK_OSC_DIV4, .present = true }, |
---|
859 | 866 | [tegra_clk_pll_ref] = { .dt_id = TEGRA124_CLK_PLL_REF, .present = true }, |
---|
860 | 867 | [tegra_clk_pll_c] = { .dt_id = TEGRA124_CLK_PLL_C, .present = true }, |
---|
861 | 868 | [tegra_clk_pll_c_out1] = { .dt_id = TEGRA124_CLK_PLL_C_OUT1, .present = true }, |
---|
.. | .. |
---|
896 | 903 | [tegra_clk_audio3] = { .dt_id = TEGRA124_CLK_AUDIO3, .present = true }, |
---|
897 | 904 | [tegra_clk_audio4] = { .dt_id = TEGRA124_CLK_AUDIO4, .present = true }, |
---|
898 | 905 | [tegra_clk_spdif] = { .dt_id = TEGRA124_CLK_SPDIF, .present = true }, |
---|
899 | | - [tegra_clk_clk_out_1] = { .dt_id = TEGRA124_CLK_CLK_OUT_1, .present = true }, |
---|
900 | | - [tegra_clk_clk_out_2] = { .dt_id = TEGRA124_CLK_CLK_OUT_2, .present = true }, |
---|
901 | | - [tegra_clk_clk_out_3] = { .dt_id = TEGRA124_CLK_CLK_OUT_3, .present = true }, |
---|
902 | | - [tegra_clk_blink] = { .dt_id = TEGRA124_CLK_BLINK, .present = true }, |
---|
903 | 906 | [tegra_clk_xusb_host_src] = { .dt_id = TEGRA124_CLK_XUSB_HOST_SRC, .present = true }, |
---|
904 | 907 | [tegra_clk_xusb_falcon_src] = { .dt_id = TEGRA124_CLK_XUSB_FALCON_SRC, .present = true }, |
---|
905 | 908 | [tegra_clk_xusb_fs_src] = { .dt_id = TEGRA124_CLK_XUSB_FS_SRC, .present = true }, |
---|
.. | .. |
---|
925 | 928 | [tegra_clk_audio3_mux] = { .dt_id = TEGRA124_CLK_AUDIO3_MUX, .present = true }, |
---|
926 | 929 | [tegra_clk_audio4_mux] = { .dt_id = TEGRA124_CLK_AUDIO4_MUX, .present = true }, |
---|
927 | 930 | [tegra_clk_spdif_mux] = { .dt_id = TEGRA124_CLK_SPDIF_MUX, .present = true }, |
---|
928 | | - [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_1_MUX, .present = true }, |
---|
929 | | - [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_2_MUX, .present = true }, |
---|
930 | | - [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA124_CLK_CLK_OUT_3_MUX, .present = true }, |
---|
931 | 931 | [tegra_clk_cec] = { .dt_id = TEGRA124_CLK_CEC, .present = true }, |
---|
932 | 932 | }; |
---|
933 | 933 | |
---|
.. | .. |
---|
935 | 935 | { .con_id = "clk_m", .dt_id = TEGRA124_CLK_CLK_M }, |
---|
936 | 936 | { .con_id = "pll_ref", .dt_id = TEGRA124_CLK_PLL_REF }, |
---|
937 | 937 | { .con_id = "clk_32k", .dt_id = TEGRA124_CLK_CLK_32K }, |
---|
938 | | - { .con_id = "clk_m_div2", .dt_id = TEGRA124_CLK_CLK_M_DIV2 }, |
---|
939 | | - { .con_id = "clk_m_div4", .dt_id = TEGRA124_CLK_CLK_M_DIV4 }, |
---|
| 938 | + { .con_id = "osc", .dt_id = TEGRA124_CLK_OSC }, |
---|
| 939 | + { .con_id = "osc_div2", .dt_id = TEGRA124_CLK_OSC_DIV2 }, |
---|
| 940 | + { .con_id = "osc_div4", .dt_id = TEGRA124_CLK_OSC_DIV4 }, |
---|
940 | 941 | { .con_id = "pll_c", .dt_id = TEGRA124_CLK_PLL_C }, |
---|
941 | 942 | { .con_id = "pll_c_out1", .dt_id = TEGRA124_CLK_PLL_C_OUT1 }, |
---|
942 | 943 | { .con_id = "pll_c2", .dt_id = TEGRA124_CLK_PLL_C2 }, |
---|
.. | .. |
---|
982 | 983 | { .con_id = "audio3_2x", .dt_id = TEGRA124_CLK_AUDIO3_2X }, |
---|
983 | 984 | { .con_id = "audio4_2x", .dt_id = TEGRA124_CLK_AUDIO4_2X }, |
---|
984 | 985 | { .con_id = "spdif_2x", .dt_id = TEGRA124_CLK_SPDIF_2X }, |
---|
985 | | - { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA124_CLK_EXTERN1 }, |
---|
986 | | - { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA124_CLK_EXTERN2 }, |
---|
987 | | - { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA124_CLK_EXTERN3 }, |
---|
988 | | - { .con_id = "blink", .dt_id = TEGRA124_CLK_BLINK }, |
---|
| 986 | + { .con_id = "extern1", .dt_id = TEGRA124_CLK_EXTERN1 }, |
---|
| 987 | + { .con_id = "extern2", .dt_id = TEGRA124_CLK_EXTERN2 }, |
---|
| 988 | + { .con_id = "extern3", .dt_id = TEGRA124_CLK_EXTERN3 }, |
---|
989 | 989 | { .con_id = "cclk_g", .dt_id = TEGRA124_CLK_CCLK_G }, |
---|
990 | 990 | { .con_id = "cclk_lp", .dt_id = TEGRA124_CLK_CCLK_LP }, |
---|
991 | 991 | { .con_id = "sclk", .dt_id = TEGRA124_CLK_SCLK }, |
---|
.. | .. |
---|
999 | 999 | { .con_id = "hda2hdmi", .dt_id = TEGRA124_CLK_HDA2HDMI }, |
---|
1000 | 1000 | }; |
---|
1001 | 1001 | |
---|
| 1002 | +static const char * const sor0_parents[] = { |
---|
| 1003 | + "pll_p_out0", "pll_m_out0", "pll_d_out0", "pll_a_out0", "pll_c_out0", |
---|
| 1004 | + "pll_d2_out0", "clk_m", |
---|
| 1005 | +}; |
---|
| 1006 | + |
---|
| 1007 | +static const char * const sor0_out_parents[] = { |
---|
| 1008 | + "clk_m", "sor0_pad_clkout", |
---|
| 1009 | +}; |
---|
| 1010 | + |
---|
| 1011 | +static struct tegra_periph_init_data tegra124_periph[] = { |
---|
| 1012 | + TEGRA_INIT_DATA_TABLE("sor0", NULL, NULL, sor0_parents, |
---|
| 1013 | + CLK_SOURCE_SOR0, 29, 0x7, 0, 0, 0, 0, |
---|
| 1014 | + 0, 182, 0, tegra_clk_sor0, NULL, 0, |
---|
| 1015 | + &sor0_lock), |
---|
| 1016 | + TEGRA_INIT_DATA_TABLE("sor0_out", NULL, NULL, sor0_out_parents, |
---|
| 1017 | + CLK_SOURCE_SOR0, 14, 0x1, 0, 0, 0, 0, |
---|
| 1018 | + 0, 0, TEGRA_PERIPH_NO_GATE, tegra_clk_sor0_out, |
---|
| 1019 | + NULL, 0, &sor0_lock), |
---|
| 1020 | +}; |
---|
| 1021 | + |
---|
1002 | 1022 | static struct clk **clks; |
---|
1003 | 1023 | |
---|
1004 | 1024 | static __init void tegra124_periph_clk_init(void __iomem *clk_base, |
---|
1005 | 1025 | void __iomem *pmc_base) |
---|
1006 | 1026 | { |
---|
1007 | 1027 | struct clk *clk; |
---|
| 1028 | + unsigned int i; |
---|
1008 | 1029 | |
---|
1009 | 1030 | /* xusb_ss_div2 */ |
---|
1010 | 1031 | clk = clk_register_fixed_factor(NULL, "xusb_ss_div2", "xusb_ss_src", 0, |
---|
.. | .. |
---|
1044 | 1065 | 1, 0, &pll_e_lock); |
---|
1045 | 1066 | clk_register_clkdev(clk, "cml1", NULL); |
---|
1046 | 1067 | clks[TEGRA124_CLK_CML1] = clk; |
---|
| 1068 | + |
---|
| 1069 | + for (i = 0; i < ARRAY_SIZE(tegra124_periph); i++) { |
---|
| 1070 | + struct tegra_periph_init_data *init = &tegra124_periph[i]; |
---|
| 1071 | + struct clk **clkp; |
---|
| 1072 | + |
---|
| 1073 | + clkp = tegra_lookup_dt_id(init->clk_id, tegra124_clks); |
---|
| 1074 | + if (!clkp) { |
---|
| 1075 | + pr_warn("clock %u not found\n", init->clk_id); |
---|
| 1076 | + continue; |
---|
| 1077 | + } |
---|
| 1078 | + |
---|
| 1079 | + clk = tegra_clk_register_periph_data(clk_base, init); |
---|
| 1080 | + *clkp = clk; |
---|
| 1081 | + } |
---|
1047 | 1082 | |
---|
1048 | 1083 | tegra_periph_clk_init(clk_base, pmc_base, tegra124_clks, &pll_p_params); |
---|
1049 | 1084 | } |
---|
.. | .. |
---|
1257 | 1292 | { TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 408000000, 0 }, |
---|
1258 | 1293 | { TEGRA124_CLK_UARTC, TEGRA124_CLK_PLL_P, 408000000, 0 }, |
---|
1259 | 1294 | { TEGRA124_CLK_UARTD, TEGRA124_CLK_PLL_P, 408000000, 0 }, |
---|
1260 | | - { TEGRA124_CLK_PLL_A, TEGRA124_CLK_CLK_MAX, 564480000, 1 }, |
---|
1261 | | - { TEGRA124_CLK_PLL_A_OUT0, TEGRA124_CLK_CLK_MAX, 11289600, 1 }, |
---|
1262 | | - { TEGRA124_CLK_EXTERN1, TEGRA124_CLK_PLL_A_OUT0, 0, 1 }, |
---|
1263 | | - { TEGRA124_CLK_CLK_OUT_1_MUX, TEGRA124_CLK_EXTERN1, 0, 1 }, |
---|
1264 | | - { TEGRA124_CLK_CLK_OUT_1, TEGRA124_CLK_CLK_MAX, 0, 1 }, |
---|
| 1295 | + { TEGRA124_CLK_PLL_A, TEGRA124_CLK_CLK_MAX, 282240000, 0 }, |
---|
| 1296 | + { TEGRA124_CLK_PLL_A_OUT0, TEGRA124_CLK_CLK_MAX, 11289600, 0 }, |
---|
1265 | 1297 | { TEGRA124_CLK_I2S0, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, |
---|
1266 | 1298 | { TEGRA124_CLK_I2S1, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, |
---|
1267 | 1299 | { TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 }, |
---|
.. | .. |
---|
1416 | 1448 | * tegra124_132_clock_init_pre - clock initialization preamble for T124/T132 |
---|
1417 | 1449 | * @np: struct device_node * of the DT node for the SoC CAR IP block |
---|
1418 | 1450 | * |
---|
1419 | | - * Register most of the clocks controlled by the CAR IP block, along |
---|
1420 | | - * with a few clocks controlled by the PMC IP block. Everything in |
---|
1421 | | - * this function should be common to Tegra124 and Tegra132. XXX The |
---|
1422 | | - * PMC clock initialization should probably be moved to PMC-specific |
---|
1423 | | - * driver code. No return value. |
---|
| 1451 | + * Register most of the clocks controlled by the CAR IP block. |
---|
| 1452 | + * Everything in this function should be common to Tegra124 and Tegra132. |
---|
| 1453 | + * No return value. |
---|
1424 | 1454 | */ |
---|
1425 | 1455 | static void __init tegra124_132_clock_init_pre(struct device_node *np) |
---|
1426 | 1456 | { |
---|
.. | .. |
---|
1463 | 1493 | tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks, |
---|
1464 | 1494 | tegra124_audio_plls, |
---|
1465 | 1495 | ARRAY_SIZE(tegra124_audio_plls), 24576000); |
---|
1466 | | - tegra_pmc_clk_init(pmc_base, tegra124_clks); |
---|
1467 | 1496 | |
---|
1468 | 1497 | /* For Tegra124 & Tegra132, PLLD is the only source for DSIA & DSIB */ |
---|
1469 | | - plld_base = clk_readl(clk_base + PLLD_BASE); |
---|
| 1498 | + plld_base = readl(clk_base + PLLD_BASE); |
---|
1470 | 1499 | plld_base &= ~BIT(25); |
---|
1471 | | - clk_writel(plld_base, clk_base + PLLD_BASE); |
---|
| 1500 | + writel(plld_base, clk_base + PLLD_BASE); |
---|
1472 | 1501 | } |
---|
1473 | 1502 | |
---|
1474 | 1503 | /** |
---|
1475 | 1504 | * tegra124_132_clock_init_post - clock initialization postamble for T124/T132 |
---|
1476 | 1505 | * @np: struct device_node * of the DT node for the SoC CAR IP block |
---|
1477 | 1506 | * |
---|
1478 | | - * Register most of the along with a few clocks controlled by the PMC |
---|
1479 | | - * IP block. Everything in this function should be common to Tegra124 |
---|
| 1507 | + * Register most of the clocks controlled by the CAR IP block. |
---|
| 1508 | + * Everything in this function should be common to Tegra124 |
---|
1480 | 1509 | * and Tegra132. This function must be called after |
---|
1481 | | - * tegra124_132_clock_init_pre(), otherwise clk_base and pmc_base will |
---|
1482 | | - * not be set. No return value. |
---|
| 1510 | + * tegra124_132_clock_init_pre(), otherwise clk_base will not be set. |
---|
| 1511 | + * No return value. |
---|
1483 | 1512 | */ |
---|
1484 | 1513 | static void __init tegra124_132_clock_init_post(struct device_node *np) |
---|
1485 | 1514 | { |
---|