hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/clk/tegra/clk-tegra210.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>
....@@ -20,13 +9,14 @@
209 #include <linux/clkdev.h>
2110 #include <linux/of.h>
2211 #include <linux/of_address.h>
12
+#include <linux/syscore_ops.h>
2313 #include <linux/delay.h>
2414 #include <linux/export.h>
2515 #include <linux/mutex.h>
2616 #include <linux/clk/tegra.h>
2717 #include <dt-bindings/clock/tegra210-car.h>
2818 #include <dt-bindings/reset/tegra210-car.h>
29
-#include <linux/iopoll.h>
19
+#include <linux/sizes.h>
3020 #include <soc/tegra/pmc.h>
3121
3222 #include "clk.h"
....@@ -43,9 +33,11 @@
4333 #define CLK_SOURCE_CSITE 0x1d4
4434 #define CLK_SOURCE_EMC 0x19c
4535 #define CLK_SOURCE_SOR1 0x410
36
+#define CLK_SOURCE_SOR0 0x414
4637 #define CLK_SOURCE_LA 0x1f8
4738 #define CLK_SOURCE_SDMMC2 0x154
4839 #define CLK_SOURCE_SDMMC4 0x164
40
+#define CLK_SOURCE_EMC_DLL 0x664
4941
5042 #define PLLC_BASE 0x80
5143 #define PLLC_OUT 0x84
....@@ -230,11 +222,19 @@
230222 #define CLK_M_DIVISOR_SHIFT 2
231223 #define CLK_M_DIVISOR_MASK 0x3
232224
225
+#define CLK_MASK_ARM 0x44
226
+#define MISC_CLK_ENB 0x48
227
+
233228 #define RST_DFLL_DVCO 0x2f4
234229 #define DVFS_DFLL_RESET_SHIFT 0
235230
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
+
236235 #define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8
237236 #define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac
237
+#define CPU_SOFTRST_CTRL 0x380
238238
239239 #define LVL2_CLK_GATE_OVRA 0xf8
240240 #define LVL2_CLK_GATE_OVRC 0x3a0
....@@ -308,6 +308,7 @@
308308 static DEFINE_SPINLOCK(pll_e_lock);
309309 static DEFINE_SPINLOCK(pll_re_lock);
310310 static DEFINE_SPINLOCK(pll_u_lock);
311
+static DEFINE_SPINLOCK(sor0_lock);
311312 static DEFINE_SPINLOCK(sor1_lock);
312313 static DEFINE_SPINLOCK(emc_lock);
313314 static DEFINE_MUTEX(lvl2_ovr_lock);
....@@ -317,12 +318,6 @@
317318 [5] = 38400000,
318319 [8] = 12000000,
319320 };
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
326321
327322 #define PLL_ENABLE (1 << 30)
328323
....@@ -558,6 +553,27 @@
558553 writel_relaxed(val, clk_base + SATA_PLL_CFG0);
559554 }
560555 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);
561577
562578 static void tegra210_generic_mbist_war(struct tegra210_domain_mbist_war *mbist)
563579 {
....@@ -994,8 +1010,6 @@
9941010 pllre->params->defaults_set = true;
9951011
9961012 if (val & PLL_ENABLE) {
997
- pr_warn("PLL_RE already enabled. Postponing set full defaults\n");
998
-
9991013 /*
10001014 * PLL is ON: check if defaults already set, then set those
10011015 * that can be updated in flight.
....@@ -1015,12 +1029,19 @@
10151029 _pll_misc_chk_default(clk_base, pllre->params, 0, val,
10161030 ~mask & PLLRE_MISC0_WRITE_MASK);
10171031
1018
- /* Enable lock detect */
1032
+ /* The PLL doesn't work if it's in IDDQ. */
10191033 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 */
10201038 val &= ~mask;
10211039 val |= PLLRE_MISC0_DEFAULT_VALUE & mask;
10221040 writel_relaxed(val, clk_base + pllre->params->ext_misc_reg[0]);
10231041 udelay(1);
1042
+
1043
+ if (!pllre->params->defaults_set)
1044
+ pr_warn("PLL_RE already enabled. Postponing set full defaults\n");
10241045
10251046 return;
10261047 }
....@@ -2309,7 +2330,6 @@
23092330 [tegra_clk_i2c2] = { .dt_id = TEGRA210_CLK_I2C2, .present = true },
23102331 [tegra_clk_uartc_8] = { .dt_id = TEGRA210_CLK_UARTC, .present = true },
23112332 [tegra_clk_mipi_cal] = { .dt_id = TEGRA210_CLK_MIPI_CAL, .present = true },
2312
- [tegra_clk_emc] = { .dt_id = TEGRA210_CLK_EMC, .present = true },
23132333 [tegra_clk_usb2] = { .dt_id = TEGRA210_CLK_USB2, .present = true },
23142334 [tegra_clk_bsev] = { .dt_id = TEGRA210_CLK_BSEV, .present = true },
23152335 [tegra_clk_uartd_8] = { .dt_id = TEGRA210_CLK_UARTD, .present = true },
....@@ -2356,9 +2376,9 @@
23562376 [tegra_clk_dpaux] = { .dt_id = TEGRA210_CLK_DPAUX, .present = true },
23572377 [tegra_clk_dpaux1] = { .dt_id = TEGRA210_CLK_DPAUX1, .present = true },
23582378 [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 },
23602380 [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 },
23622382 [tegra_clk_gpu] = { .dt_id = TEGRA210_CLK_GPU, .present = true },
23632383 [tegra_clk_pll_g_ref] = { .dt_id = TEGRA210_CLK_PLL_G_REF, .present = true, },
23642384 [tegra_clk_uartb_8] = { .dt_id = TEGRA210_CLK_UARTB, .present = true },
....@@ -2370,8 +2390,9 @@
23702390 [tegra_clk_fuse_burn] = { .dt_id = TEGRA210_CLK_FUSE_BURN, .present = true },
23712391 [tegra_clk_clk_32k] = { .dt_id = TEGRA210_CLK_CLK_32K, .present = true },
23722392 [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 },
23752396 [tegra_clk_pll_ref] = { .dt_id = TEGRA210_CLK_PLL_REF, .present = true },
23762397 [tegra_clk_pll_c] = { .dt_id = TEGRA210_CLK_PLL_C, .present = true },
23772398 [tegra_clk_pll_c_out1] = { .dt_id = TEGRA210_CLK_PLL_C_OUT1, .present = true },
....@@ -2416,10 +2437,6 @@
24162437 [tegra_clk_audio3] = { .dt_id = TEGRA210_CLK_AUDIO3, .present = true },
24172438 [tegra_clk_audio4] = { .dt_id = TEGRA210_CLK_AUDIO4, .present = true },
24182439 [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 },
24232440 [tegra_clk_xusb_gate] = { .dt_id = TEGRA210_CLK_XUSB_GATE, .present = true },
24242441 [tegra_clk_xusb_host_src_8] = { .dt_id = TEGRA210_CLK_XUSB_HOST_SRC, .present = true },
24252442 [tegra_clk_xusb_falcon_src_8] = { .dt_id = TEGRA210_CLK_XUSB_FALCON_SRC, .present = true },
....@@ -2451,9 +2468,6 @@
24512468 [tegra_clk_audio3_mux] = { .dt_id = TEGRA210_CLK_AUDIO3_MUX, .present = true },
24522469 [tegra_clk_audio4_mux] = { .dt_id = TEGRA210_CLK_AUDIO4_MUX, .present = true },
24532470 [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 },
24572471 [tegra_clk_maud] = { .dt_id = TEGRA210_CLK_MAUD, .present = true },
24582472 [tegra_clk_mipibif] = { .dt_id = TEGRA210_CLK_MIPIBIF, .present = true },
24592473 [tegra_clk_qspi] = { .dt_id = TEGRA210_CLK_QSPI, .present = true },
....@@ -2496,8 +2510,9 @@
24962510 { .con_id = "clk_m", .dt_id = TEGRA210_CLK_CLK_M },
24972511 { .con_id = "pll_ref", .dt_id = TEGRA210_CLK_PLL_REF },
24982512 { .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 },
25012516 { .con_id = "pll_c", .dt_id = TEGRA210_CLK_PLL_C },
25022517 { .con_id = "pll_c_out1", .dt_id = TEGRA210_CLK_PLL_C_OUT1 },
25032518 { .con_id = "pll_c2", .dt_id = TEGRA210_CLK_PLL_C2 },
....@@ -2539,10 +2554,9 @@
25392554 { .con_id = "audio4", .dt_id = TEGRA210_CLK_AUDIO4 },
25402555 { .con_id = "spdif", .dt_id = TEGRA210_CLK_SPDIF },
25412556 { .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 },
25462560 { .con_id = "cclk_g", .dt_id = TEGRA210_CLK_CCLK_G },
25472561 { .con_id = "cclk_lp", .dt_id = TEGRA210_CLK_CCLK_LP },
25482562 { .con_id = "sclk", .dt_id = TEGRA210_CLK_SCLK },
....@@ -2556,7 +2570,6 @@
25562570 { .con_id = "pll_c4_out2", .dt_id = TEGRA210_CLK_PLL_C4_OUT2 },
25572571 { .con_id = "pll_c4_out3", .dt_id = TEGRA210_CLK_PLL_C4_OUT3 },
25582572 { .con_id = "dpaux", .dt_id = TEGRA210_CLK_DPAUX },
2559
- { .con_id = "sor0", .dt_id = TEGRA210_CLK_SOR0 },
25602573 };
25612574
25622575 static struct tegra_audio_clk_info tegra210_audio_plls[] = {
....@@ -2830,6 +2843,7 @@
28302843 struct tegra_clk_pll_freq_table *fentry;
28312844 struct tegra_clk_pll pllu;
28322845 u32 reg;
2846
+ int ret;
28332847
28342848 for (fentry = pll_u_freq_table; fentry->input_rate; fentry++) {
28352849 if (fentry->input_rate == pll_ref_freq)
....@@ -2846,7 +2860,7 @@
28462860 reg = readl_relaxed(clk_base + pllu.params->ext_misc_reg[0]);
28472861 reg &= ~BIT(pllu.params->iddq_bit_idx);
28482862 writel_relaxed(reg, clk_base + pllu.params->ext_misc_reg[0]);
2849
- udelay(5);
2863
+ fence_udelay(5, clk_base);
28502864
28512865 reg = readl_relaxed(clk_base + PLLU_BASE);
28522866 reg &= ~GENMASK(20, 0);
....@@ -2854,13 +2868,18 @@
28542868 reg |= fentry->n << 8;
28552869 reg |= fentry->p << 16;
28562870 writel(reg, clk_base + PLLU_BASE);
2857
- udelay(1);
2871
+ fence_udelay(1, clk_base);
28582872 reg |= PLL_ENABLE;
28592873 writel(reg, clk_base + PLLU_BASE);
28602874
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) {
28642883 pr_err("Timed out waiting for PLL_U to lock\n");
28652884 return -ETIMEDOUT;
28662885 }
....@@ -2900,12 +2919,12 @@
29002919 reg = readl_relaxed(clk_base + XUSB_PLL_CFG0);
29012920 reg &= ~XUSB_PLL_CFG0_PLLU_LOCK_DLY_MASK;
29022921 writel_relaxed(reg, clk_base + XUSB_PLL_CFG0);
2903
- udelay(1);
2922
+ fence_udelay(1, clk_base);
29042923
29052924 reg = readl_relaxed(clk_base + PLLU_HW_PWRDN_CFG0);
29062925 reg |= PLLU_HW_PWRDN_CFG0_SEQ_ENABLE;
29072926 writel_relaxed(reg, clk_base + PLLU_HW_PWRDN_CFG0);
2908
- udelay(1);
2927
+ fence_udelay(1, clk_base);
29092928
29102929 reg = readl_relaxed(clk_base + PLLU_BASE);
29112930 reg &= ~PLLU_BASE_CLKENABLE_USB;
....@@ -2920,15 +2939,31 @@
29202939 return 0;
29212940 }
29222941
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",
29322967 };
29332968
29342969 static const char * const sor1_parents[] = {
....@@ -2937,11 +2972,60 @@
29372972
29382973 static u32 sor1_parents_idx[] = { 0, 2, 5, 6 };
29392974
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
+
29403007 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),
29413020 TEGRA_INIT_DATA_TABLE("sor1", NULL, NULL, sor1_parents,
29423021 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),
29453029 };
29463030
29473031 static const char * const la_parents[] = {
....@@ -2949,9 +3033,10 @@
29493033 };
29503034
29513035 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);
29533037
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,
29553040 void __iomem *pmc_base)
29563041 {
29573042 struct clk *clk;
....@@ -2974,12 +3059,6 @@
29743059 1, 17, 207);
29753060 clks[TEGRA210_CLK_DPAUX1] = clk;
29763061
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
-
29833062 /* pll_d_dsi_out */
29843063 clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0,
29853064 clk_base + PLLD_MISC0, 21, 0, &pll_d_lock);
....@@ -2997,21 +3076,18 @@
29973076 periph_clk_enb_refcnt);
29983077 clks[TEGRA210_CLK_DSIB] = clk;
29993078
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
+
30003086 /* la */
30013087 clk = tegra_clk_register_periph("la", la_parents,
30023088 ARRAY_SIZE(la_parents), &tegra210_la, clk_base,
30033089 CLK_SOURCE_LA, 0);
30043090 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;
30153091
30163092 /* cml0 */
30173093 clk = clk_register_gate(NULL, "cml0", "pll_e", 0, clk_base + PLLE_AUX,
....@@ -3055,6 +3131,13 @@
30553131 }
30563132
30573133 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");
30583141 }
30593142
30603143 static void __init tegra210_pll_init(void __iomem *clk_base,
....@@ -3114,6 +3197,17 @@
31143197 CLK_SET_RATE_PARENT, 1, 1);
31153198 clk_register_clkdev(clk, "pll_m_ud", NULL);
31163199 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;
31173211
31183212 /* PLLU_VCO */
31193213 if (!tegra210_init_pllu()) {
....@@ -3292,6 +3386,77 @@
32923386 }
32933387
32943388 #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
+
32953460 static void tegra210_cpu_clock_suspend(void)
32963461 {
32973462 /* switch coresite to clk_m, save off original source */
....@@ -3306,6 +3471,13 @@
33063471 clk_base + CLK_SOURCE_CSITE);
33073472 }
33083473 #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
+};
33093481
33103482 static struct tegra_cpu_car_ops tegra210_cpu_car_ops = {
33113483 .wait_for_reset = tegra210_wait_cpu_in_reset,
....@@ -3326,11 +3498,8 @@
33263498 { TEGRA210_CLK_UARTB, TEGRA210_CLK_PLL_P, 408000000, 0 },
33273499 { TEGRA210_CLK_UARTC, TEGRA210_CLK_PLL_P, 408000000, 0 },
33283500 { 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 },
33343503 { TEGRA210_CLK_I2S0, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 },
33353504 { TEGRA210_CLK_I2S1, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 },
33363505 { TEGRA210_CLK_I2S2, TEGRA210_CLK_PLL_A_OUT0, 11289600, 0 },
....@@ -3342,7 +3511,6 @@
33423511 { TEGRA210_CLK_DFLL_SOC, TEGRA210_CLK_PLL_P, 51000000, 1 },
33433512 { TEGRA210_CLK_DFLL_REF, TEGRA210_CLK_PLL_P, 51000000, 1 },
33443513 { TEGRA210_CLK_SBC4, TEGRA210_CLK_PLL_P, 12000000, 1 },
3345
- { TEGRA210_CLK_PLL_RE_VCO, TEGRA210_CLK_CLK_MAX, 672000000, 1 },
33463514 { TEGRA210_CLK_PLL_U_OUT1, TEGRA210_CLK_CLK_MAX, 48000000, 1 },
33473515 { TEGRA210_CLK_XUSB_GATE, TEGRA210_CLK_CLK_MAX, 0, 1 },
33483516 { TEGRA210_CLK_XUSB_SS_SRC, TEGRA210_CLK_PLL_U_480M, 120000000, 0 },
....@@ -3529,6 +3697,7 @@
35293697 }
35303698
35313699 pmc_base = of_iomap(node, 0);
3700
+ of_node_put(node);
35323701 if (!pmc_base) {
35333702 pr_err("Can't map pmc registers\n");
35343703 WARN_ON(1);
....@@ -3558,7 +3727,7 @@
35583727 if (!clks)
35593728 return;
35603729
3561
- value = clk_readl(clk_base + SPARE_REG0) >> CLK_M_DIVISOR_SHIFT;
3730
+ value = readl(clk_base + SPARE_REG0) >> CLK_M_DIVISOR_SHIFT;
35623731 clk_m_div = (value & CLK_M_DIVISOR_MASK) + 1;
35633732
35643733 if (tegra_osc_clk_init(clk_base, tegra210_clks, tegra210_input_freq,
....@@ -3568,16 +3737,15 @@
35683737
35693738 tegra_fixed_clk_init(tegra210_clks);
35703739 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);
35723741 tegra_audio_clk_init(clk_base, pmc_base, tegra210_clks,
35733742 tegra210_audio_plls,
35743743 ARRAY_SIZE(tegra210_audio_plls), 24576000);
3575
- tegra_pmc_clk_init(pmc_base, tegra210_clks);
35763744
35773745 /* 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);
35793747 value &= ~BIT(25);
3580
- clk_writel(value, clk_base + PLLD_BASE);
3748
+ writel(value, clk_base + PLLD_BASE);
35813749
35823750 tegra_clk_apply_init_table = tegra210_clock_apply_init_table;
35833751
....@@ -3592,5 +3760,7 @@
35923760 tegra210_mbist_clk_init();
35933761
35943762 tegra_cpu_car_ops = &tegra210_cpu_car_ops;
3763
+
3764
+ register_syscore_ops(&tegra_clk_syscore_ops);
35953765 }
35963766 CLK_OF_DECLARE(tegra210, "nvidia,tegra210-car", tegra210_clock_init);