hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/sound/soc/tegra/tegra_asoc_utils.c
....@@ -1,23 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * tegra_asoc_utils.c - Harmony machine ASoC driver
34 *
45 * Author: Stephen Warren <swarren@nvidia.com>
56 * Copyright (C) 2010,2012 - NVIDIA, Inc.
6
- *
7
- * This program is free software; you can redistribute it and/or
8
- * modify it under the terms of the GNU General Public License
9
- * version 2 as published by the Free Software Foundation.
10
- *
11
- * This program is distributed in the hope that it will be useful, but
12
- * WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
- * General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License
17
- * along with this program; if not, write to the Free Software
18
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
19
- * 02110-1301 USA
20
- *
217 */
228
239 #include <linux/clk.h>
....@@ -74,8 +60,6 @@
7460 data->set_mclk = 0;
7561
7662 clk_disable_unprepare(data->clk_cdev1);
77
- clk_disable_unprepare(data->clk_pll_a_out0);
78
- clk_disable_unprepare(data->clk_pll_a);
7963
8064 err = clk_set_rate(data->clk_pll_a, new_baseclock);
8165 if (err) {
....@@ -90,18 +74,6 @@
9074 }
9175
9276 /* Don't set cdev1/extern1 rate; it's locked to pll_a_out0 */
93
-
94
- err = clk_prepare_enable(data->clk_pll_a);
95
- if (err) {
96
- dev_err(data->dev, "Can't enable pll_a: %d\n", err);
97
- return err;
98
- }
99
-
100
- err = clk_prepare_enable(data->clk_pll_a_out0);
101
- if (err) {
102
- dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err);
103
- return err;
104
- }
10577
10678 err = clk_prepare_enable(data->clk_cdev1);
10779 if (err) {
....@@ -123,8 +95,6 @@
12395 int err;
12496
12597 clk_disable_unprepare(data->clk_cdev1);
126
- clk_disable_unprepare(data->clk_pll_a_out0);
127
- clk_disable_unprepare(data->clk_pll_a);
12898
12999 /*
130100 * AC97 rate is fixed at 24.576MHz and is used for both the host
....@@ -144,18 +114,6 @@
144114
145115 /* Don't set cdev1/extern1 rate; it's locked to pll_a_out0 */
146116
147
- err = clk_prepare_enable(data->clk_pll_a);
148
- if (err) {
149
- dev_err(data->dev, "Can't enable pll_a: %d\n", err);
150
- return err;
151
- }
152
-
153
- err = clk_prepare_enable(data->clk_pll_a_out0);
154
- if (err) {
155
- dev_err(data->dev, "Can't enable pll_a_out0: %d\n", err);
156
- return err;
157
- }
158
-
159117 err = clk_prepare_enable(data->clk_cdev1);
160118 if (err) {
161119 dev_err(data->dev, "Can't enable cdev1: %d\n", err);
....@@ -172,6 +130,7 @@
172130 int tegra_asoc_utils_init(struct tegra_asoc_utils_data *data,
173131 struct device *dev)
174132 {
133
+ struct clk *clk_out_1, *clk_extern1;
175134 int ret;
176135
177136 data->dev = dev;
....@@ -189,51 +148,77 @@
189148 return -EINVAL;
190149 }
191150
192
- data->clk_pll_a = clk_get(dev, "pll_a");
151
+ data->clk_pll_a = devm_clk_get(dev, "pll_a");
193152 if (IS_ERR(data->clk_pll_a)) {
194153 dev_err(data->dev, "Can't retrieve clk pll_a\n");
195
- ret = PTR_ERR(data->clk_pll_a);
196
- goto err;
154
+ return PTR_ERR(data->clk_pll_a);
197155 }
198156
199
- data->clk_pll_a_out0 = clk_get(dev, "pll_a_out0");
157
+ data->clk_pll_a_out0 = devm_clk_get(dev, "pll_a_out0");
200158 if (IS_ERR(data->clk_pll_a_out0)) {
201159 dev_err(data->dev, "Can't retrieve clk pll_a_out0\n");
202
- ret = PTR_ERR(data->clk_pll_a_out0);
203
- goto err_put_pll_a;
160
+ return PTR_ERR(data->clk_pll_a_out0);
204161 }
205162
206
- data->clk_cdev1 = clk_get(dev, "mclk");
163
+ data->clk_cdev1 = devm_clk_get(dev, "mclk");
207164 if (IS_ERR(data->clk_cdev1)) {
208165 dev_err(data->dev, "Can't retrieve clk cdev1\n");
209
- ret = PTR_ERR(data->clk_cdev1);
210
- goto err_put_pll_a_out0;
166
+ return PTR_ERR(data->clk_cdev1);
211167 }
212168
213
- ret = tegra_asoc_utils_set_rate(data, 44100, 256 * 44100);
214
- if (ret)
215
- goto err_put_cdev1;
169
+ /*
170
+ * If clock parents are not set in DT, configure here to use clk_out_1
171
+ * as mclk and extern1 as parent for Tegra30 and higher.
172
+ */
173
+ if (!of_find_property(dev->of_node, "assigned-clock-parents", NULL) &&
174
+ data->soc > TEGRA_ASOC_UTILS_SOC_TEGRA20) {
175
+ dev_warn(data->dev,
176
+ "Configuring clocks for a legacy device-tree\n");
177
+ dev_warn(data->dev,
178
+ "Please update DT to use assigned-clock-parents\n");
179
+ clk_extern1 = devm_clk_get(dev, "extern1");
180
+ if (IS_ERR(clk_extern1)) {
181
+ dev_err(data->dev, "Can't retrieve clk extern1\n");
182
+ return PTR_ERR(clk_extern1);
183
+ }
184
+
185
+ ret = clk_set_parent(clk_extern1, data->clk_pll_a_out0);
186
+ if (ret < 0) {
187
+ dev_err(data->dev,
188
+ "Set parent failed for clk extern1\n");
189
+ return ret;
190
+ }
191
+
192
+ clk_out_1 = devm_clk_get(dev, "pmc_clk_out_1");
193
+ if (IS_ERR(clk_out_1)) {
194
+ dev_err(data->dev, "Can't retrieve pmc_clk_out_1\n");
195
+ return PTR_ERR(clk_out_1);
196
+ }
197
+
198
+ ret = clk_set_parent(clk_out_1, clk_extern1);
199
+ if (ret < 0) {
200
+ dev_err(data->dev,
201
+ "Set parent failed for pmc_clk_out_1\n");
202
+ return ret;
203
+ }
204
+
205
+ data->clk_cdev1 = clk_out_1;
206
+ }
207
+
208
+ /*
209
+ * FIXME: There is some unknown dependency between audio mclk disable
210
+ * and suspend-resume functionality on Tegra30, although audio mclk is
211
+ * only needed for audio.
212
+ */
213
+ ret = clk_prepare_enable(data->clk_cdev1);
214
+ if (ret) {
215
+ dev_err(data->dev, "Can't enable cdev1: %d\n", ret);
216
+ return ret;
217
+ }
216218
217219 return 0;
218
-
219
-err_put_cdev1:
220
- clk_put(data->clk_cdev1);
221
-err_put_pll_a_out0:
222
- clk_put(data->clk_pll_a_out0);
223
-err_put_pll_a:
224
- clk_put(data->clk_pll_a);
225
-err:
226
- return ret;
227220 }
228221 EXPORT_SYMBOL_GPL(tegra_asoc_utils_init);
229
-
230
-void tegra_asoc_utils_fini(struct tegra_asoc_utils_data *data)
231
-{
232
- clk_put(data->clk_cdev1);
233
- clk_put(data->clk_pll_a_out0);
234
- clk_put(data->clk_pll_a);
235
-}
236
-EXPORT_SYMBOL_GPL(tegra_asoc_utils_fini);
237222
238223 MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
239224 MODULE_DESCRIPTION("Tegra ASoC utility code");