hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/clk/tegra/clk-tegra124.c
....@@ -1,17 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * 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/>.
154 */
165
176 #include <linux/io.h>
....@@ -38,6 +27,7 @@
3827
3928 #define CLK_SOURCE_CSITE 0x1d4
4029 #define CLK_SOURCE_EMC 0x19c
30
+#define CLK_SOURCE_SOR0 0x414
4131
4232 #define RST_DFLL_DVCO 0x2f4
4333 #define DVFS_DFLL_RESET_SHIFT 0
....@@ -102,6 +92,22 @@
10292 /* Tegra CPU clock and reset control regs */
10393 #define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470
10494
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
+
105111 #ifdef CONFIG_PM_SLEEP
106112 static struct cpu_clk_suspend_context {
107113 u32 clk_csite_src;
....@@ -121,6 +127,7 @@
121127 static DEFINE_SPINLOCK(pll_re_lock);
122128 static DEFINE_SPINLOCK(pll_u_lock);
123129 static DEFINE_SPINLOCK(emc_lock);
130
+static DEFINE_SPINLOCK(sor0_lock);
124131
125132 /* possible OSC frequencies in Hz */
126133 static unsigned long tegra124_input_freq[] = {
....@@ -413,7 +420,6 @@
413420 .base_reg = PLLM_BASE,
414421 .misc_reg = PLLM_MISC,
415422 .lock_mask = PLL_BASE_LOCK,
416
- .lock_enable_bit_idx = PLL_MISC_LOCK_ENABLE,
417423 .lock_delay = 300,
418424 .max_p = 5,
419425 .pdiv_tohw = pllm_p,
....@@ -421,7 +427,7 @@
421427 .pmc_divnm_reg = PMC_PLLM_WB0_OVERRIDE,
422428 .pmc_divp_reg = PMC_PLLM_WB0_OVERRIDE_2,
423429 .freq_table = pll_m_freq_table,
424
- .flags = TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
430
+ .flags = TEGRA_PLL_USE_LOCK,
425431 };
426432
427433 static struct tegra_clk_pll_freq_table pll_e_freq_table[] = {
....@@ -841,7 +847,7 @@
841847 [tegra_clk_adx1] = { .dt_id = TEGRA124_CLK_ADX1, .present = true },
842848 [tegra_clk_dpaux] = { .dt_id = TEGRA124_CLK_DPAUX, .present = true },
843849 [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 },
845851 [tegra_clk_gpu] = { .dt_id = TEGRA124_CLK_GPU, .present = true },
846852 [tegra_clk_amx1] = { .dt_id = TEGRA124_CLK_AMX1, .present = true },
847853 [tegra_clk_uartb] = { .dt_id = TEGRA124_CLK_UARTB, .present = true },
....@@ -854,8 +860,9 @@
854860 [tegra_clk_fuse_burn] = { .dt_id = TEGRA124_CLK_FUSE_BURN, .present = true },
855861 [tegra_clk_clk_32k] = { .dt_id = TEGRA124_CLK_CLK_32K, .present = true },
856862 [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 },
859866 [tegra_clk_pll_ref] = { .dt_id = TEGRA124_CLK_PLL_REF, .present = true },
860867 [tegra_clk_pll_c] = { .dt_id = TEGRA124_CLK_PLL_C, .present = true },
861868 [tegra_clk_pll_c_out1] = { .dt_id = TEGRA124_CLK_PLL_C_OUT1, .present = true },
....@@ -896,10 +903,6 @@
896903 [tegra_clk_audio3] = { .dt_id = TEGRA124_CLK_AUDIO3, .present = true },
897904 [tegra_clk_audio4] = { .dt_id = TEGRA124_CLK_AUDIO4, .present = true },
898905 [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 },
903906 [tegra_clk_xusb_host_src] = { .dt_id = TEGRA124_CLK_XUSB_HOST_SRC, .present = true },
904907 [tegra_clk_xusb_falcon_src] = { .dt_id = TEGRA124_CLK_XUSB_FALCON_SRC, .present = true },
905908 [tegra_clk_xusb_fs_src] = { .dt_id = TEGRA124_CLK_XUSB_FS_SRC, .present = true },
....@@ -925,9 +928,6 @@
925928 [tegra_clk_audio3_mux] = { .dt_id = TEGRA124_CLK_AUDIO3_MUX, .present = true },
926929 [tegra_clk_audio4_mux] = { .dt_id = TEGRA124_CLK_AUDIO4_MUX, .present = true },
927930 [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 },
931931 [tegra_clk_cec] = { .dt_id = TEGRA124_CLK_CEC, .present = true },
932932 };
933933
....@@ -935,8 +935,9 @@
935935 { .con_id = "clk_m", .dt_id = TEGRA124_CLK_CLK_M },
936936 { .con_id = "pll_ref", .dt_id = TEGRA124_CLK_PLL_REF },
937937 { .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 },
940941 { .con_id = "pll_c", .dt_id = TEGRA124_CLK_PLL_C },
941942 { .con_id = "pll_c_out1", .dt_id = TEGRA124_CLK_PLL_C_OUT1 },
942943 { .con_id = "pll_c2", .dt_id = TEGRA124_CLK_PLL_C2 },
....@@ -982,10 +983,9 @@
982983 { .con_id = "audio3_2x", .dt_id = TEGRA124_CLK_AUDIO3_2X },
983984 { .con_id = "audio4_2x", .dt_id = TEGRA124_CLK_AUDIO4_2X },
984985 { .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 },
989989 { .con_id = "cclk_g", .dt_id = TEGRA124_CLK_CCLK_G },
990990 { .con_id = "cclk_lp", .dt_id = TEGRA124_CLK_CCLK_LP },
991991 { .con_id = "sclk", .dt_id = TEGRA124_CLK_SCLK },
....@@ -999,12 +999,33 @@
999999 { .con_id = "hda2hdmi", .dt_id = TEGRA124_CLK_HDA2HDMI },
10001000 };
10011001
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
+
10021022 static struct clk **clks;
10031023
10041024 static __init void tegra124_periph_clk_init(void __iomem *clk_base,
10051025 void __iomem *pmc_base)
10061026 {
10071027 struct clk *clk;
1028
+ unsigned int i;
10081029
10091030 /* xusb_ss_div2 */
10101031 clk = clk_register_fixed_factor(NULL, "xusb_ss_div2", "xusb_ss_src", 0,
....@@ -1044,6 +1065,20 @@
10441065 1, 0, &pll_e_lock);
10451066 clk_register_clkdev(clk, "cml1", NULL);
10461067 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
+ }
10471082
10481083 tegra_periph_clk_init(clk_base, pmc_base, tegra124_clks, &pll_p_params);
10491084 }
....@@ -1257,11 +1292,8 @@
12571292 { TEGRA124_CLK_UARTB, TEGRA124_CLK_PLL_P, 408000000, 0 },
12581293 { TEGRA124_CLK_UARTC, TEGRA124_CLK_PLL_P, 408000000, 0 },
12591294 { 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 },
12651297 { TEGRA124_CLK_I2S0, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 },
12661298 { TEGRA124_CLK_I2S1, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 },
12671299 { TEGRA124_CLK_I2S2, TEGRA124_CLK_PLL_A_OUT0, 11289600, 0 },
....@@ -1416,11 +1448,9 @@
14161448 * tegra124_132_clock_init_pre - clock initialization preamble for T124/T132
14171449 * @np: struct device_node * of the DT node for the SoC CAR IP block
14181450 *
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.
14241454 */
14251455 static void __init tegra124_132_clock_init_pre(struct device_node *np)
14261456 {
....@@ -1463,23 +1493,22 @@
14631493 tegra_audio_clk_init(clk_base, pmc_base, tegra124_clks,
14641494 tegra124_audio_plls,
14651495 ARRAY_SIZE(tegra124_audio_plls), 24576000);
1466
- tegra_pmc_clk_init(pmc_base, tegra124_clks);
14671496
14681497 /* 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);
14701499 plld_base &= ~BIT(25);
1471
- clk_writel(plld_base, clk_base + PLLD_BASE);
1500
+ writel(plld_base, clk_base + PLLD_BASE);
14721501 }
14731502
14741503 /**
14751504 * tegra124_132_clock_init_post - clock initialization postamble for T124/T132
14761505 * @np: struct device_node * of the DT node for the SoC CAR IP block
14771506 *
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
14801509 * 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.
14831512 */
14841513 static void __init tegra124_132_clock_init_post(struct device_node *np)
14851514 {