forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/drivers/clk/tegra/clk-super.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/kernel.h>
....@@ -38,6 +27,9 @@
3827 #define super_state(s) (BIT(s) << SUPER_STATE_SHIFT)
3928 #define super_state_to_src_shift(m, s) ((m->width * s))
4029 #define super_state_to_src_mask(m) (((1 << m->width) - 1))
30
+
31
+#define CCLK_SRC_PLLP_OUT0 4
32
+#define CCLK_SRC_PLLP_OUT4 5
4133
4234 static u8 clk_super_get_parent(struct clk_hw *hw)
4335 {
....@@ -108,11 +100,22 @@
108100 if (index == mux->div2_index)
109101 index = mux->pllx_index;
110102 }
103
+
104
+ /* enable PLLP branches to CPU before selecting PLLP source */
105
+ if ((mux->flags & TEGRA210_CPU_CLK) &&
106
+ (index == CCLK_SRC_PLLP_OUT0 || index == CCLK_SRC_PLLP_OUT4))
107
+ tegra_clk_set_pllp_out_cpu(true);
108
+
111109 val &= ~((super_state_to_src_mask(mux)) << shift);
112110 val |= (index & (super_state_to_src_mask(mux))) << shift;
113111
114112 writel_relaxed(val, mux->reg);
115113 udelay(2);
114
+
115
+ /* disable PLLP branches to CPU if not used */
116
+ if ((mux->flags & TEGRA210_CPU_CLK) &&
117
+ index != CCLK_SRC_PLLP_OUT0 && index != CCLK_SRC_PLLP_OUT4)
118
+ tegra_clk_set_pllp_out_cpu(false);
116119
117120 out:
118121 if (mux->lock)
....@@ -121,9 +124,21 @@
121124 return err;
122125 }
123126
124
-const struct clk_ops tegra_clk_super_mux_ops = {
127
+static void clk_super_mux_restore_context(struct clk_hw *hw)
128
+{
129
+ int parent_id;
130
+
131
+ parent_id = clk_hw_get_parent_index(hw);
132
+ if (WARN_ON(parent_id < 0))
133
+ return;
134
+
135
+ clk_super_set_parent(hw, parent_id);
136
+}
137
+
138
+static const struct clk_ops tegra_clk_super_mux_ops = {
125139 .get_parent = clk_super_get_parent,
126140 .set_parent = clk_super_set_parent,
141
+ .restore_context = clk_super_mux_restore_context,
127142 };
128143
129144 static long clk_super_round_rate(struct clk_hw *hw, unsigned long rate,
....@@ -159,12 +174,27 @@
159174 return super->div_ops->set_rate(div_hw, rate, parent_rate);
160175 }
161176
177
+static void clk_super_restore_context(struct clk_hw *hw)
178
+{
179
+ struct tegra_clk_super_mux *super = to_clk_super_mux(hw);
180
+ struct clk_hw *div_hw = &super->frac_div.hw;
181
+ int parent_id;
182
+
183
+ parent_id = clk_hw_get_parent_index(hw);
184
+ if (WARN_ON(parent_id < 0))
185
+ return;
186
+
187
+ super->div_ops->restore_context(div_hw);
188
+ clk_super_set_parent(hw, parent_id);
189
+}
190
+
162191 const struct clk_ops tegra_clk_super_ops = {
163192 .get_parent = clk_super_get_parent,
164193 .set_parent = clk_super_set_parent,
165194 .set_rate = clk_super_set_rate,
166195 .round_rate = clk_super_round_rate,
167196 .recalc_rate = clk_super_recalc_rate,
197
+ .restore_context = clk_super_restore_context,
168198 };
169199
170200 struct clk *tegra_clk_register_super_mux(const char *name,
....@@ -174,7 +204,7 @@
174204 {
175205 struct tegra_clk_super_mux *super;
176206 struct clk *clk;
177
- struct clk_init_data init = {};
207
+ struct clk_init_data init;
178208
179209 super = kzalloc(sizeof(*super), GFP_KERNEL);
180210 if (!super)
....@@ -210,7 +240,7 @@
210240 {
211241 struct tegra_clk_super_mux *super;
212242 struct clk *clk;
213
- struct clk_init_data init = {};
243
+ struct clk_init_data init;
214244
215245 super = kzalloc(sizeof(*super), GFP_KERNEL);
216246 if (!super)