forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/drivers/soc/mediatek/mtk-scpsys.c
....@@ -1,14 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
3
- *
4
- * This program is free software; you can redistribute it and/or modify
5
- * it under the terms of the GNU General Public License version 2 as
6
- * published by the Free Software Foundation.
7
- *
8
- * This program is distributed in the hope that it will be useful,
9
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- * GNU General Public License for more details.
124 */
135 #include <linux/clk.h>
146 #include <linux/init.h>
....@@ -29,7 +21,7 @@
2921 #include <dt-bindings/power/mt8173-power.h>
3022
3123 #define MTK_POLL_DELAY_US 10
32
-#define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ))
24
+#define MTK_POLL_TIMEOUT USEC_PER_SEC
3325
3426 #define MTK_SCPD_ACTIVE_WAKEUP BIT(0)
3527 #define MTK_SCPD_FWAIT_SRAM BIT(1)
....@@ -116,6 +108,17 @@
116108
117109 #define MAX_CLKS 3
118110
111
+/**
112
+ * struct scp_domain_data - scp domain data for power on/off flow
113
+ * @name: The domain name.
114
+ * @sta_mask: The mask for power on/off status bit.
115
+ * @ctl_offs: The offset for main power control register.
116
+ * @sram_pdn_bits: The mask for sram power control bits.
117
+ * @sram_pdn_ack_bits: The mask for sram power control acked bits.
118
+ * @bus_prot_mask: The mask for single step bus protection.
119
+ * @clk_id: The basic clocks required by this power domain.
120
+ * @caps: The flag for active wake-up action.
121
+ */
119122 struct scp_domain_data {
120123 const char *name;
121124 u32 sta_mask;
....@@ -188,32 +191,132 @@
188191 return -EINVAL;
189192 }
190193
194
+static int scpsys_regulator_enable(struct scp_domain *scpd)
195
+{
196
+ if (!scpd->supply)
197
+ return 0;
198
+
199
+ return regulator_enable(scpd->supply);
200
+}
201
+
202
+static int scpsys_regulator_disable(struct scp_domain *scpd)
203
+{
204
+ if (!scpd->supply)
205
+ return 0;
206
+
207
+ return regulator_disable(scpd->supply);
208
+}
209
+
210
+static void scpsys_clk_disable(struct clk *clk[], int max_num)
211
+{
212
+ int i;
213
+
214
+ for (i = max_num - 1; i >= 0; i--)
215
+ clk_disable_unprepare(clk[i]);
216
+}
217
+
218
+static int scpsys_clk_enable(struct clk *clk[], int max_num)
219
+{
220
+ int i, ret = 0;
221
+
222
+ for (i = 0; i < max_num && clk[i]; i++) {
223
+ ret = clk_prepare_enable(clk[i]);
224
+ if (ret) {
225
+ scpsys_clk_disable(clk, i);
226
+ break;
227
+ }
228
+ }
229
+
230
+ return ret;
231
+}
232
+
233
+static int scpsys_sram_enable(struct scp_domain *scpd, void __iomem *ctl_addr)
234
+{
235
+ u32 val;
236
+ u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
237
+ int tmp;
238
+
239
+ val = readl(ctl_addr);
240
+ val &= ~scpd->data->sram_pdn_bits;
241
+ writel(val, ctl_addr);
242
+
243
+ /* Either wait until SRAM_PDN_ACK all 0 or have a force wait */
244
+ if (MTK_SCPD_CAPS(scpd, MTK_SCPD_FWAIT_SRAM)) {
245
+ /*
246
+ * Currently, MTK_SCPD_FWAIT_SRAM is necessary only for
247
+ * MT7622_POWER_DOMAIN_WB and thus just a trivial setup
248
+ * is applied here.
249
+ */
250
+ usleep_range(12000, 12100);
251
+ } else {
252
+ /* Either wait until SRAM_PDN_ACK all 1 or 0 */
253
+ int ret = readl_poll_timeout(ctl_addr, tmp,
254
+ (tmp & pdn_ack) == 0,
255
+ MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
256
+ if (ret < 0)
257
+ return ret;
258
+ }
259
+
260
+ return 0;
261
+}
262
+
263
+static int scpsys_sram_disable(struct scp_domain *scpd, void __iomem *ctl_addr)
264
+{
265
+ u32 val;
266
+ u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
267
+ int tmp;
268
+
269
+ val = readl(ctl_addr);
270
+ val |= scpd->data->sram_pdn_bits;
271
+ writel(val, ctl_addr);
272
+
273
+ /* Either wait until SRAM_PDN_ACK all 1 or 0 */
274
+ return readl_poll_timeout(ctl_addr, tmp,
275
+ (tmp & pdn_ack) == pdn_ack,
276
+ MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
277
+}
278
+
279
+static int scpsys_bus_protect_enable(struct scp_domain *scpd)
280
+{
281
+ struct scp *scp = scpd->scp;
282
+
283
+ if (!scpd->data->bus_prot_mask)
284
+ return 0;
285
+
286
+ return mtk_infracfg_set_bus_protection(scp->infracfg,
287
+ scpd->data->bus_prot_mask,
288
+ scp->bus_prot_reg_update);
289
+}
290
+
291
+static int scpsys_bus_protect_disable(struct scp_domain *scpd)
292
+{
293
+ struct scp *scp = scpd->scp;
294
+
295
+ if (!scpd->data->bus_prot_mask)
296
+ return 0;
297
+
298
+ return mtk_infracfg_clear_bus_protection(scp->infracfg,
299
+ scpd->data->bus_prot_mask,
300
+ scp->bus_prot_reg_update);
301
+}
302
+
191303 static int scpsys_power_on(struct generic_pm_domain *genpd)
192304 {
193305 struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
194306 struct scp *scp = scpd->scp;
195307 void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
196
- u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
197308 u32 val;
198309 int ret, tmp;
199
- int i;
200310
201
- if (scpd->supply) {
202
- ret = regulator_enable(scpd->supply);
203
- if (ret)
204
- return ret;
205
- }
311
+ ret = scpsys_regulator_enable(scpd);
312
+ if (ret < 0)
313
+ return ret;
206314
207
- for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) {
208
- ret = clk_prepare_enable(scpd->clk[i]);
209
- if (ret) {
210
- for (--i; i >= 0; i--)
211
- clk_disable_unprepare(scpd->clk[i]);
315
+ ret = scpsys_clk_enable(scpd->clk, MAX_CLKS);
316
+ if (ret)
317
+ goto err_clk;
212318
213
- goto err_clk;
214
- }
215
- }
216
-
319
+ /* subsys power on */
217320 val = readl(ctl_addr);
218321 val |= PWR_ON_BIT;
219322 writel(val, ctl_addr);
....@@ -235,43 +338,20 @@
235338 val |= PWR_RST_B_BIT;
236339 writel(val, ctl_addr);
237340
238
- val &= ~scpd->data->sram_pdn_bits;
239
- writel(val, ctl_addr);
341
+ ret = scpsys_sram_enable(scpd, ctl_addr);
342
+ if (ret < 0)
343
+ goto err_pwr_ack;
240344
241
- /* Either wait until SRAM_PDN_ACK all 0 or have a force wait */
242
- if (MTK_SCPD_CAPS(scpd, MTK_SCPD_FWAIT_SRAM)) {
243
- /*
244
- * Currently, MTK_SCPD_FWAIT_SRAM is necessary only for
245
- * MT7622_POWER_DOMAIN_WB and thus just a trivial setup is
246
- * applied here.
247
- */
248
- usleep_range(12000, 12100);
249
-
250
- } else {
251
- ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == 0,
252
- MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
253
- if (ret < 0)
254
- goto err_pwr_ack;
255
- }
256
-
257
- if (scpd->data->bus_prot_mask) {
258
- ret = mtk_infracfg_clear_bus_protection(scp->infracfg,
259
- scpd->data->bus_prot_mask,
260
- scp->bus_prot_reg_update);
261
- if (ret)
262
- goto err_pwr_ack;
263
- }
345
+ ret = scpsys_bus_protect_disable(scpd);
346
+ if (ret < 0)
347
+ goto err_pwr_ack;
264348
265349 return 0;
266350
267351 err_pwr_ack:
268
- for (i = MAX_CLKS - 1; i >= 0; i--) {
269
- if (scpd->clk[i])
270
- clk_disable_unprepare(scpd->clk[i]);
271
- }
352
+ scpsys_clk_disable(scpd->clk, MAX_CLKS);
272353 err_clk:
273
- if (scpd->supply)
274
- regulator_disable(scpd->supply);
354
+ scpsys_regulator_disable(scpd);
275355
276356 dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
277357
....@@ -283,29 +363,19 @@
283363 struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
284364 struct scp *scp = scpd->scp;
285365 void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
286
- u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
287366 u32 val;
288367 int ret, tmp;
289
- int i;
290368
291
- if (scpd->data->bus_prot_mask) {
292
- ret = mtk_infracfg_set_bus_protection(scp->infracfg,
293
- scpd->data->bus_prot_mask,
294
- scp->bus_prot_reg_update);
295
- if (ret)
296
- goto out;
297
- }
298
-
299
- val = readl(ctl_addr);
300
- val |= scpd->data->sram_pdn_bits;
301
- writel(val, ctl_addr);
302
-
303
- /* wait until SRAM_PDN_ACK all 1 */
304
- ret = readl_poll_timeout(ctl_addr, tmp, (tmp & pdn_ack) == pdn_ack,
305
- MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
369
+ ret = scpsys_bus_protect_enable(scpd);
306370 if (ret < 0)
307371 goto out;
308372
373
+ ret = scpsys_sram_disable(scpd, ctl_addr);
374
+ if (ret < 0)
375
+ goto out;
376
+
377
+ /* subsys power off */
378
+ val = readl(ctl_addr);
309379 val |= PWR_ISO_BIT;
310380 writel(val, ctl_addr);
311381
....@@ -327,11 +397,11 @@
327397 if (ret < 0)
328398 goto out;
329399
330
- for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++)
331
- clk_disable_unprepare(scpd->clk[i]);
400
+ scpsys_clk_disable(scpd->clk, MAX_CLKS);
332401
333
- if (scpd->supply)
334
- regulator_disable(scpd->supply);
402
+ ret = scpsys_regulator_disable(scpd);
403
+ if (ret < 0)
404
+ goto out;
335405
336406 return 0;
337407