forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/drivers/clk/tegra/clk.c
....@@ -1,23 +1,13 @@
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/clkdev.h>
187 #include <linux/clk.h>
198 #include <linux/clk-provider.h>
209 #include <linux/delay.h>
10
+#include <linux/io.h>
2111 #include <linux/of.h>
2212 #include <linux/clk/tegra.h>
2313 #include <linux/reset-controller.h>
....@@ -26,56 +16,13 @@
2616
2717 #include "clk.h"
2818
29
-#define CLK_OUT_ENB_L 0x010
30
-#define CLK_OUT_ENB_H 0x014
31
-#define CLK_OUT_ENB_U 0x018
32
-#define CLK_OUT_ENB_V 0x360
33
-#define CLK_OUT_ENB_W 0x364
34
-#define CLK_OUT_ENB_X 0x280
35
-#define CLK_OUT_ENB_Y 0x298
36
-#define CLK_OUT_ENB_SET_L 0x320
37
-#define CLK_OUT_ENB_CLR_L 0x324
38
-#define CLK_OUT_ENB_SET_H 0x328
39
-#define CLK_OUT_ENB_CLR_H 0x32c
40
-#define CLK_OUT_ENB_SET_U 0x330
41
-#define CLK_OUT_ENB_CLR_U 0x334
42
-#define CLK_OUT_ENB_SET_V 0x440
43
-#define CLK_OUT_ENB_CLR_V 0x444
44
-#define CLK_OUT_ENB_SET_W 0x448
45
-#define CLK_OUT_ENB_CLR_W 0x44c
46
-#define CLK_OUT_ENB_SET_X 0x284
47
-#define CLK_OUT_ENB_CLR_X 0x288
48
-#define CLK_OUT_ENB_SET_Y 0x29c
49
-#define CLK_OUT_ENB_CLR_Y 0x2a0
50
-
51
-#define RST_DEVICES_L 0x004
52
-#define RST_DEVICES_H 0x008
53
-#define RST_DEVICES_U 0x00C
54
-#define RST_DEVICES_V 0x358
55
-#define RST_DEVICES_W 0x35C
56
-#define RST_DEVICES_X 0x28C
57
-#define RST_DEVICES_Y 0x2a4
58
-#define RST_DEVICES_SET_L 0x300
59
-#define RST_DEVICES_CLR_L 0x304
60
-#define RST_DEVICES_SET_H 0x308
61
-#define RST_DEVICES_CLR_H 0x30c
62
-#define RST_DEVICES_SET_U 0x310
63
-#define RST_DEVICES_CLR_U 0x314
64
-#define RST_DEVICES_SET_V 0x430
65
-#define RST_DEVICES_CLR_V 0x434
66
-#define RST_DEVICES_SET_W 0x438
67
-#define RST_DEVICES_CLR_W 0x43c
68
-#define RST_DEVICES_SET_X 0x290
69
-#define RST_DEVICES_CLR_X 0x294
70
-#define RST_DEVICES_SET_Y 0x2a8
71
-#define RST_DEVICES_CLR_Y 0x2ac
72
-
7319 /* Global data of Tegra CPU CAR ops */
7420 static struct tegra_cpu_car_ops dummy_car_ops;
7521 struct tegra_cpu_car_ops *tegra_cpu_car_ops = &dummy_car_ops;
7622
7723 int *periph_clk_enb_refcnt;
7824 static int periph_banks;
25
+static u32 *periph_state_ctx;
7926 static struct clk **clks;
8027 static int clk_num;
8128 static struct clk_onecell_data clk_data;
....@@ -209,6 +156,65 @@
209156 }
210157 }
211158
159
+void tegra_clk_set_pllp_out_cpu(bool enable)
160
+{
161
+ u32 val;
162
+
163
+ val = readl_relaxed(clk_base + CLK_OUT_ENB_Y);
164
+ if (enable)
165
+ val |= CLK_ENB_PLLP_OUT_CPU;
166
+ else
167
+ val &= ~CLK_ENB_PLLP_OUT_CPU;
168
+
169
+ writel_relaxed(val, clk_base + CLK_OUT_ENB_Y);
170
+}
171
+
172
+void tegra_clk_periph_suspend(void)
173
+{
174
+ unsigned int i, idx;
175
+
176
+ idx = 0;
177
+ for (i = 0; i < periph_banks; i++, idx++)
178
+ periph_state_ctx[idx] =
179
+ readl_relaxed(clk_base + periph_regs[i].enb_reg);
180
+
181
+ for (i = 0; i < periph_banks; i++, idx++)
182
+ periph_state_ctx[idx] =
183
+ readl_relaxed(clk_base + periph_regs[i].rst_reg);
184
+}
185
+
186
+void tegra_clk_periph_resume(void)
187
+{
188
+ unsigned int i, idx;
189
+
190
+ idx = 0;
191
+ for (i = 0; i < periph_banks; i++, idx++)
192
+ writel_relaxed(periph_state_ctx[idx],
193
+ clk_base + periph_regs[i].enb_reg);
194
+ /*
195
+ * All non-boot peripherals will be in reset state on resume.
196
+ * Wait for 5us of reset propagation delay before de-asserting
197
+ * the peripherals based on the saved context.
198
+ */
199
+ fence_udelay(5, clk_base);
200
+
201
+ for (i = 0; i < periph_banks; i++, idx++)
202
+ writel_relaxed(periph_state_ctx[idx],
203
+ clk_base + periph_regs[i].rst_reg);
204
+
205
+ fence_udelay(2, clk_base);
206
+}
207
+
208
+static int tegra_clk_periph_ctx_init(int banks)
209
+{
210
+ periph_state_ctx = kcalloc(2 * banks, sizeof(*periph_state_ctx),
211
+ GFP_KERNEL);
212
+ if (!periph_state_ctx)
213
+ return -ENOMEM;
214
+
215
+ return 0;
216
+}
217
+
212218 struct clk ** __init tegra_clk_init(void __iomem *regs, int num, int banks)
213219 {
214220 clk_base = regs;
....@@ -225,11 +231,21 @@
225231 periph_banks = banks;
226232
227233 clks = kcalloc(num, sizeof(struct clk *), GFP_KERNEL);
228
- if (!clks)
234
+ if (!clks) {
229235 kfree(periph_clk_enb_refcnt);
236
+ return NULL;
237
+ }
230238
231239 clk_num = num;
232240
241
+ if (IS_ENABLED(CONFIG_PM_SLEEP)) {
242
+ if (tegra_clk_periph_ctx_init(banks)) {
243
+ kfree(periph_clk_enb_refcnt);
244
+ kfree(clks);
245
+ return NULL;
246
+ }
247
+ }
248
+
233249 return clks;
234250 }
235251