forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/drivers/clk/tegra/clk-tegra30.c
....@@ -1,17 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2012, 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>
....@@ -162,7 +151,6 @@
162151
163152 static DEFINE_SPINLOCK(cml_lock);
164153 static DEFINE_SPINLOCK(pll_d_lock);
165
-static DEFINE_SPINLOCK(emc_lock);
166154
167155 #define TEGRA_INIT_DATA_MUX(_name, _parents, _offset, \
168156 _clk_num, _gate_flags, _clk_id) \
....@@ -511,6 +499,8 @@
511499 .freq_table = pll_x_freq_table,
512500 .flags = TEGRA_PLL_HAS_CPCON | TEGRA_PLL_SET_DCCON |
513501 TEGRA_PLL_USE_LOCK | TEGRA_PLL_HAS_LOCK_ENABLE,
502
+ .pre_rate_change = tegra_cclk_pre_pllx_rate_change,
503
+ .post_rate_change = tegra_cclk_post_pllx_rate_change,
514504 };
515505
516506 static struct tegra_clk_pll_params pll_e_params __ro_after_init = {
....@@ -581,10 +571,9 @@
581571 { .con_id = "audio3_2x", .dt_id = TEGRA30_CLK_AUDIO3_2X },
582572 { .con_id = "audio4_2x", .dt_id = TEGRA30_CLK_AUDIO4_2X },
583573 { .con_id = "spdif_2x", .dt_id = TEGRA30_CLK_SPDIF_2X },
584
- { .con_id = "extern1", .dev_id = "clk_out_1", .dt_id = TEGRA30_CLK_EXTERN1 },
585
- { .con_id = "extern2", .dev_id = "clk_out_2", .dt_id = TEGRA30_CLK_EXTERN2 },
586
- { .con_id = "extern3", .dev_id = "clk_out_3", .dt_id = TEGRA30_CLK_EXTERN3 },
587
- { .con_id = "blink", .dt_id = TEGRA30_CLK_BLINK },
574
+ { .con_id = "extern1", .dt_id = TEGRA30_CLK_EXTERN1 },
575
+ { .con_id = "extern2", .dt_id = TEGRA30_CLK_EXTERN2 },
576
+ { .con_id = "extern3", .dt_id = TEGRA30_CLK_EXTERN3 },
588577 { .con_id = "cclk_g", .dt_id = TEGRA30_CLK_CCLK_G },
589578 { .con_id = "cclk_lp", .dt_id = TEGRA30_CLK_CCLK_LP },
590579 { .con_id = "sclk", .dt_id = TEGRA30_CLK_SCLK },
....@@ -593,8 +582,9 @@
593582 { .con_id = "twd", .dt_id = TEGRA30_CLK_TWD },
594583 { .con_id = "emc", .dt_id = TEGRA30_CLK_EMC },
595584 { .con_id = "clk_32k", .dt_id = TEGRA30_CLK_CLK_32K },
596
- { .con_id = "clk_m_div2", .dt_id = TEGRA30_CLK_CLK_M_DIV2 },
597
- { .con_id = "clk_m_div4", .dt_id = TEGRA30_CLK_CLK_M_DIV4 },
585
+ { .con_id = "osc", .dt_id = TEGRA30_CLK_OSC },
586
+ { .con_id = "osc_div2", .dt_id = TEGRA30_CLK_OSC_DIV2 },
587
+ { .con_id = "osc_div4", .dt_id = TEGRA30_CLK_OSC_DIV4 },
598588 { .con_id = "cml0", .dt_id = TEGRA30_CLK_CML0 },
599589 { .con_id = "cml1", .dt_id = TEGRA30_CLK_CML1 },
600590 { .con_id = "clk_m", .dt_id = TEGRA30_CLK_CLK_M },
....@@ -695,8 +685,9 @@
695685 static struct tegra_clk tegra30_clks[tegra_clk_max] __initdata = {
696686 [tegra_clk_clk_32k] = { .dt_id = TEGRA30_CLK_CLK_32K, .present = true },
697687 [tegra_clk_clk_m] = { .dt_id = TEGRA30_CLK_CLK_M, .present = true },
698
- [tegra_clk_clk_m_div2] = { .dt_id = TEGRA30_CLK_CLK_M_DIV2, .present = true },
699
- [tegra_clk_clk_m_div4] = { .dt_id = TEGRA30_CLK_CLK_M_DIV4, .present = true },
688
+ [tegra_clk_osc] = { .dt_id = TEGRA30_CLK_OSC, .present = true },
689
+ [tegra_clk_osc_div2] = { .dt_id = TEGRA30_CLK_OSC_DIV2, .present = true },
690
+ [tegra_clk_osc_div4] = { .dt_id = TEGRA30_CLK_OSC_DIV4, .present = true },
700691 [tegra_clk_pll_ref] = { .dt_id = TEGRA30_CLK_PLL_REF, .present = true },
701692 [tegra_clk_spdif_in_sync] = { .dt_id = TEGRA30_CLK_SPDIF_IN_SYNC, .present = true },
702693 [tegra_clk_i2s0_sync] = { .dt_id = TEGRA30_CLK_I2S0_SYNC, .present = true },
....@@ -723,13 +714,6 @@
723714 [tegra_clk_audio3_2x] = { .dt_id = TEGRA30_CLK_AUDIO3_2X, .present = true },
724715 [tegra_clk_audio4_2x] = { .dt_id = TEGRA30_CLK_AUDIO4_2X, .present = true },
725716 [tegra_clk_spdif_2x] = { .dt_id = TEGRA30_CLK_SPDIF_2X, .present = true },
726
- [tegra_clk_clk_out_1] = { .dt_id = TEGRA30_CLK_CLK_OUT_1, .present = true },
727
- [tegra_clk_clk_out_2] = { .dt_id = TEGRA30_CLK_CLK_OUT_2, .present = true },
728
- [tegra_clk_clk_out_3] = { .dt_id = TEGRA30_CLK_CLK_OUT_3, .present = true },
729
- [tegra_clk_blink] = { .dt_id = TEGRA30_CLK_BLINK, .present = true },
730
- [tegra_clk_clk_out_1_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_1_MUX, .present = true },
731
- [tegra_clk_clk_out_2_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_2_MUX, .present = true },
732
- [tegra_clk_clk_out_3_mux] = { .dt_id = TEGRA30_CLK_CLK_OUT_3_MUX, .present = true },
733717 [tegra_clk_hclk] = { .dt_id = TEGRA30_CLK_HCLK, .present = true },
734718 [tegra_clk_pclk] = { .dt_id = TEGRA30_CLK_PCLK, .present = true },
735719 [tegra_clk_i2s0] = { .dt_id = TEGRA30_CLK_I2S0, .present = true },
....@@ -819,7 +803,7 @@
819803 [tegra_clk_pll_a] = { .dt_id = TEGRA30_CLK_PLL_A, .present = true },
820804 [tegra_clk_pll_a_out0] = { .dt_id = TEGRA30_CLK_PLL_A_OUT0, .present = true },
821805 [tegra_clk_cec] = { .dt_id = TEGRA30_CLK_CEC, .present = true },
822
- [tegra_clk_emc] = { .dt_id = TEGRA30_CLK_EMC, .present = true },
806
+ [tegra_clk_emc] = { .dt_id = TEGRA30_CLK_EMC, .present = false },
823807 };
824808
825809 static const char *pll_e_parents[] = { "pll_ref", "pll_p" };
....@@ -944,11 +928,11 @@
944928 clk_register_clkdev(clk, "pll_p_out4_cclkg", NULL);
945929
946930 /* CCLKG */
947
- clk = tegra_clk_register_super_mux("cclk_g", cclk_g_parents,
931
+ clk = tegra_clk_register_super_cclk("cclk_g", cclk_g_parents,
948932 ARRAY_SIZE(cclk_g_parents),
949933 CLK_SET_RATE_PARENT,
950934 clk_base + CCLKG_BURST_POLICY,
951
- 0, 4, 0, 0, NULL);
935
+ 0, NULL);
952936 clks[TEGRA30_CLK_CCLK_G] = clk;
953937
954938 /*
....@@ -1006,7 +990,6 @@
1006990 static const char *mux_pllacp_clkm[] = { "pll_a_out0", "unused", "pll_p",
1007991 "clk_m" };
1008992 static const char *mux_pllpcm_clkm[] = { "pll_p", "pll_c", "pll_m", "clk_m" };
1009
-static const char *mux_pllmcp_clkm[] = { "pll_m", "pll_c", "pll_p", "clk_m" };
1010993 static const char *spdif_out_parents[] = { "pll_a_out0", "spdif_2x", "pll_p",
1011994 "clk_m" };
1012995 static const char *mux_pllmcpa[] = { "pll_m", "pll_c", "pll_p", "pll_a_out0" };
....@@ -1055,14 +1038,12 @@
10551038 clks[TEGRA30_CLK_AFI] = clk;
10561039
10571040 /* emc */
1058
- clk = clk_register_mux(NULL, "emc_mux", mux_pllmcp_clkm,
1059
- ARRAY_SIZE(mux_pllmcp_clkm),
1060
- CLK_SET_RATE_NO_REPARENT,
1061
- clk_base + CLK_SOURCE_EMC,
1062
- 30, 2, 0, &emc_lock);
1041
+ clk = tegra20_clk_register_emc(clk_base + CLK_SOURCE_EMC, true);
10631042
1064
- clk = tegra_clk_register_mc("mc", "emc_mux", clk_base + CLK_SOURCE_EMC,
1065
- &emc_lock);
1043
+ clks[TEGRA30_CLK_EMC] = clk;
1044
+
1045
+ clk = tegra_clk_register_mc("mc", "emc", clk_base + CLK_SOURCE_EMC,
1046
+ NULL);
10661047 clks[TEGRA30_CLK_MC] = clk;
10671048
10681049 /* cml0 */
....@@ -1148,9 +1129,9 @@
11481129
11491130 cpu_rst_status = readl(clk_base +
11501131 TEGRA30_CLK_RST_CONTROLLER_CPU_CMPLX_STATUS);
1151
- cpu_pwr_status = tegra_powergate_is_powered(TEGRA_POWERGATE_CPU1) ||
1152
- tegra_powergate_is_powered(TEGRA_POWERGATE_CPU2) ||
1153
- tegra_powergate_is_powered(TEGRA_POWERGATE_CPU3);
1132
+ cpu_pwr_status = tegra_pmc_cpu_is_powered(1) ||
1133
+ tegra_pmc_cpu_is_powered(2) ||
1134
+ tegra_pmc_cpu_is_powered(3);
11541135
11551136 if (((cpu_rst_status & 0xE) != 0xE) || cpu_pwr_status)
11561137 return false;
....@@ -1178,6 +1159,7 @@
11781159 static void tegra30_cpu_clock_resume(void)
11791160 {
11801161 unsigned int reg, policy;
1162
+ u32 misc, base;
11811163
11821164 /* Is CPU complex already running on PLLX? */
11831165 reg = readl(clk_base + CLK_RESET_CCLK_BURST);
....@@ -1191,15 +1173,21 @@
11911173 BUG();
11921174
11931175 if (reg != CLK_RESET_CCLK_BURST_POLICY_PLLX) {
1194
- /* restore PLLX settings if CPU is on different PLL */
1195
- writel(tegra30_cpu_clk_sctx.pllx_misc,
1196
- clk_base + CLK_RESET_PLLX_MISC);
1197
- writel(tegra30_cpu_clk_sctx.pllx_base,
1198
- clk_base + CLK_RESET_PLLX_BASE);
1176
+ misc = readl_relaxed(clk_base + CLK_RESET_PLLX_MISC);
1177
+ base = readl_relaxed(clk_base + CLK_RESET_PLLX_BASE);
11991178
1200
- /* wait for PLL stabilization if PLLX was enabled */
1201
- if (tegra30_cpu_clk_sctx.pllx_base & (1 << 30))
1202
- udelay(300);
1179
+ if (misc != tegra30_cpu_clk_sctx.pllx_misc ||
1180
+ base != tegra30_cpu_clk_sctx.pllx_base) {
1181
+ /* restore PLLX settings if CPU is on different PLL */
1182
+ writel(tegra30_cpu_clk_sctx.pllx_misc,
1183
+ clk_base + CLK_RESET_PLLX_MISC);
1184
+ writel(tegra30_cpu_clk_sctx.pllx_base,
1185
+ clk_base + CLK_RESET_PLLX_BASE);
1186
+
1187
+ /* wait for PLL stabilization if PLLX was enabled */
1188
+ if (tegra30_cpu_clk_sctx.pllx_base & (1 << 30))
1189
+ udelay(300);
1190
+ }
12031191 }
12041192
12051193 /*
....@@ -1235,12 +1223,8 @@
12351223 { TEGRA30_CLK_UARTC, TEGRA30_CLK_PLL_P, 408000000, 0 },
12361224 { TEGRA30_CLK_UARTD, TEGRA30_CLK_PLL_P, 408000000, 0 },
12371225 { TEGRA30_CLK_UARTE, TEGRA30_CLK_PLL_P, 408000000, 0 },
1238
- { TEGRA30_CLK_PLL_A, TEGRA30_CLK_CLK_MAX, 564480000, 1 },
1239
- { TEGRA30_CLK_PLL_A_OUT0, TEGRA30_CLK_CLK_MAX, 11289600, 1 },
1240
- { TEGRA30_CLK_EXTERN1, TEGRA30_CLK_PLL_A_OUT0, 0, 1 },
1241
- { TEGRA30_CLK_CLK_OUT_1_MUX, TEGRA30_CLK_EXTERN1, 0, 0 },
1242
- { TEGRA30_CLK_CLK_OUT_1, TEGRA30_CLK_CLK_MAX, 0, 1 },
1243
- { TEGRA30_CLK_BLINK, TEGRA30_CLK_CLK_MAX, 0, 1 },
1226
+ { TEGRA30_CLK_PLL_A, TEGRA30_CLK_CLK_MAX, 564480000, 0 },
1227
+ { TEGRA30_CLK_PLL_A_OUT0, TEGRA30_CLK_CLK_MAX, 11289600, 0 },
12441228 { TEGRA30_CLK_I2S0, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0 },
12451229 { TEGRA30_CLK_I2S1, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0 },
12461230 { TEGRA30_CLK_I2S2, TEGRA30_CLK_PLL_A_OUT0, 11289600, 0 },
....@@ -1259,14 +1243,12 @@
12591243 { TEGRA30_CLK_SBC6, TEGRA30_CLK_PLL_P, 100000000, 0 },
12601244 { TEGRA30_CLK_PLL_C, TEGRA30_CLK_CLK_MAX, 600000000, 0 },
12611245 { TEGRA30_CLK_HOST1X, TEGRA30_CLK_PLL_C, 150000000, 0 },
1262
- { TEGRA30_CLK_DISP1, TEGRA30_CLK_PLL_P, 600000000, 0 },
1263
- { TEGRA30_CLK_DISP2, TEGRA30_CLK_PLL_P, 600000000, 0 },
12641246 { TEGRA30_CLK_TWD, TEGRA30_CLK_CLK_MAX, 0, 1 },
12651247 { TEGRA30_CLK_GR2D, TEGRA30_CLK_PLL_C, 300000000, 0 },
12661248 { TEGRA30_CLK_GR3D, TEGRA30_CLK_PLL_C, 300000000, 0 },
12671249 { TEGRA30_CLK_GR3D2, TEGRA30_CLK_PLL_C, 300000000, 0 },
12681250 { TEGRA30_CLK_PLL_U, TEGRA30_CLK_CLK_MAX, 480000000, 0 },
1269
- { TEGRA30_CLK_VDE, TEGRA30_CLK_CLK_MAX, 600000000, 0 },
1251
+ { TEGRA30_CLK_VDE, TEGRA30_CLK_PLL_C, 300000000, 0 },
12701252 { TEGRA30_CLK_SPDIF_IN_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 },
12711253 { TEGRA30_CLK_I2S0_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 },
12721254 { TEGRA30_CLK_I2S1_SYNC, TEGRA30_CLK_CLK_MAX, 24000000, 0 },
....@@ -1315,6 +1297,26 @@
13151297 { "pll_a", &pll_a_params, tegra_clk_pll_a, "pll_p_out1" },
13161298 };
13171299
1300
+static struct clk *tegra30_clk_src_onecell_get(struct of_phandle_args *clkspec,
1301
+ void *data)
1302
+{
1303
+ struct clk_hw *hw;
1304
+ struct clk *clk;
1305
+
1306
+ clk = of_clk_src_onecell_get(clkspec, data);
1307
+ if (IS_ERR(clk))
1308
+ return clk;
1309
+
1310
+ hw = __clk_get_hw(clk);
1311
+
1312
+ if (clkspec->args[0] == TEGRA30_CLK_EMC) {
1313
+ if (!tegra20_clk_emc_driver_available(hw))
1314
+ return ERR_PTR(-EPROBE_DEFER);
1315
+ }
1316
+
1317
+ return clk;
1318
+}
1319
+
13181320 static void __init tegra30_clock_init(struct device_node *np)
13191321 {
13201322 struct device_node *node;
....@@ -1354,11 +1356,10 @@
13541356 tegra_audio_clk_init(clk_base, pmc_base, tegra30_clks,
13551357 tegra30_audio_plls,
13561358 ARRAY_SIZE(tegra30_audio_plls), 24000000);
1357
- tegra_pmc_clk_init(pmc_base, tegra30_clks);
13581359
13591360 tegra_init_dup_clks(tegra_clk_duplicates, clks, TEGRA30_CLK_CLK_MAX);
13601361
1361
- tegra_add_of_provider(np, of_clk_src_onecell_get);
1362
+ tegra_add_of_provider(np, tegra30_clk_src_onecell_get);
13621363 tegra_register_devclks(devclks, ARRAY_SIZE(devclks));
13631364
13641365 tegra_clk_apply_init_table = tegra30_clock_apply_init_table;