]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/soc/mediatek/mtk-scpsys.c
2080c8f3ea1e24ecf4413d0292a19b15a142aa2e
[linux.git] / drivers / soc / mediatek / mtk-scpsys.c
1 /*
2  * 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.
12  */
13 #include <linux/clk.h>
14 #include <linux/init.h>
15 #include <linux/io.h>
16 #include <linux/iopoll.h>
17 #include <linux/mfd/syscon.h>
18 #include <linux/of_device.h>
19 #include <linux/platform_device.h>
20 #include <linux/pm_domain.h>
21 #include <linux/regulator/consumer.h>
22 #include <linux/soc/mediatek/infracfg.h>
23
24 #include <dt-bindings/power/mt2701-power.h>
25 #include <dt-bindings/power/mt2712-power.h>
26 #include <dt-bindings/power/mt6797-power.h>
27 #include <dt-bindings/power/mt7622-power.h>
28 #include <dt-bindings/power/mt7623a-power.h>
29 #include <dt-bindings/power/mt8173-power.h>
30
31 #define MTK_POLL_DELAY_US   10
32 #define MTK_POLL_TIMEOUT    (jiffies_to_usecs(HZ))
33
34 #define MTK_SCPD_ACTIVE_WAKEUP          BIT(0)
35 #define MTK_SCPD_FWAIT_SRAM             BIT(1)
36 #define MTK_SCPD_CAPS(_scpd, _x)        ((_scpd)->data->caps & (_x))
37
38 #define SPM_VDE_PWR_CON                 0x0210
39 #define SPM_MFG_PWR_CON                 0x0214
40 #define SPM_VEN_PWR_CON                 0x0230
41 #define SPM_ISP_PWR_CON                 0x0238
42 #define SPM_DIS_PWR_CON                 0x023c
43 #define SPM_CONN_PWR_CON                0x0280
44 #define SPM_VEN2_PWR_CON                0x0298
45 #define SPM_AUDIO_PWR_CON               0x029c  /* MT8173, MT2712 */
46 #define SPM_BDP_PWR_CON                 0x029c  /* MT2701 */
47 #define SPM_ETH_PWR_CON                 0x02a0
48 #define SPM_HIF_PWR_CON                 0x02a4
49 #define SPM_IFR_MSC_PWR_CON             0x02a8
50 #define SPM_MFG_2D_PWR_CON              0x02c0
51 #define SPM_MFG_ASYNC_PWR_CON           0x02c4
52 #define SPM_USB_PWR_CON                 0x02cc
53 #define SPM_USB2_PWR_CON                0x02d4  /* MT2712 */
54 #define SPM_ETHSYS_PWR_CON              0x02e0  /* MT7622 */
55 #define SPM_HIF0_PWR_CON                0x02e4  /* MT7622 */
56 #define SPM_HIF1_PWR_CON                0x02e8  /* MT7622 */
57 #define SPM_WB_PWR_CON                  0x02ec  /* MT7622 */
58
59 #define SPM_PWR_STATUS                  0x060c
60 #define SPM_PWR_STATUS_2ND              0x0610
61
62 #define PWR_RST_B_BIT                   BIT(0)
63 #define PWR_ISO_BIT                     BIT(1)
64 #define PWR_ON_BIT                      BIT(2)
65 #define PWR_ON_2ND_BIT                  BIT(3)
66 #define PWR_CLK_DIS_BIT                 BIT(4)
67
68 #define PWR_STATUS_CONN                 BIT(1)
69 #define PWR_STATUS_DISP                 BIT(3)
70 #define PWR_STATUS_MFG                  BIT(4)
71 #define PWR_STATUS_ISP                  BIT(5)
72 #define PWR_STATUS_VDEC                 BIT(7)
73 #define PWR_STATUS_BDP                  BIT(14)
74 #define PWR_STATUS_ETH                  BIT(15)
75 #define PWR_STATUS_HIF                  BIT(16)
76 #define PWR_STATUS_IFR_MSC              BIT(17)
77 #define PWR_STATUS_USB2                 BIT(19) /* MT2712 */
78 #define PWR_STATUS_VENC_LT              BIT(20)
79 #define PWR_STATUS_VENC                 BIT(21)
80 #define PWR_STATUS_MFG_2D               BIT(22) /* MT8173 */
81 #define PWR_STATUS_MFG_ASYNC            BIT(23) /* MT8173 */
82 #define PWR_STATUS_AUDIO                BIT(24) /* MT8173, MT2712 */
83 #define PWR_STATUS_USB                  BIT(25) /* MT8173, MT2712 */
84 #define PWR_STATUS_ETHSYS               BIT(24) /* MT7622 */
85 #define PWR_STATUS_HIF0                 BIT(25) /* MT7622 */
86 #define PWR_STATUS_HIF1                 BIT(26) /* MT7622 */
87 #define PWR_STATUS_WB                   BIT(27) /* MT7622 */
88
89 enum clk_id {
90         CLK_NONE,
91         CLK_MM,
92         CLK_MFG,
93         CLK_VENC,
94         CLK_VENC_LT,
95         CLK_ETHIF,
96         CLK_VDEC,
97         CLK_HIFSEL,
98         CLK_JPGDEC,
99         CLK_AUDIO,
100         CLK_MAX,
101 };
102
103 static const char * const clk_names[] = {
104         NULL,
105         "mm",
106         "mfg",
107         "venc",
108         "venc_lt",
109         "ethif",
110         "vdec",
111         "hif_sel",
112         "jpgdec",
113         "audio",
114         NULL,
115 };
116
117 #define MAX_CLKS        3
118
119 struct scp_domain_data {
120         const char *name;
121         u32 sta_mask;
122         int ctl_offs;
123         u32 sram_pdn_bits;
124         u32 sram_pdn_ack_bits;
125         u32 bus_prot_mask;
126         enum clk_id clk_id[MAX_CLKS];
127         u8 caps;
128 };
129
130 struct scp;
131
132 struct scp_domain {
133         struct generic_pm_domain genpd;
134         struct scp *scp;
135         struct clk *clk[MAX_CLKS];
136         const struct scp_domain_data *data;
137         struct regulator *supply;
138 };
139
140 struct scp_ctrl_reg {
141         int pwr_sta_offs;
142         int pwr_sta2nd_offs;
143 };
144
145 struct scp {
146         struct scp_domain *domains;
147         struct genpd_onecell_data pd_data;
148         struct device *dev;
149         void __iomem *base;
150         struct regmap *infracfg;
151         struct scp_ctrl_reg ctrl_reg;
152         bool bus_prot_reg_update;
153 };
154
155 struct scp_subdomain {
156         int origin;
157         int subdomain;
158 };
159
160 struct scp_soc_data {
161         const struct scp_domain_data *domains;
162         int num_domains;
163         const struct scp_subdomain *subdomains;
164         int num_subdomains;
165         const struct scp_ctrl_reg regs;
166         bool bus_prot_reg_update;
167 };
168
169 static int scpsys_domain_is_on(struct scp_domain *scpd)
170 {
171         struct scp *scp = scpd->scp;
172
173         u32 status = readl(scp->base + scp->ctrl_reg.pwr_sta_offs) &
174                                                 scpd->data->sta_mask;
175         u32 status2 = readl(scp->base + scp->ctrl_reg.pwr_sta2nd_offs) &
176                                                 scpd->data->sta_mask;
177
178         /*
179          * A domain is on when both status bits are set. If only one is set
180          * return an error. This happens while powering up a domain
181          */
182
183         if (status && status2)
184                 return true;
185         if (!status && !status2)
186                 return false;
187
188         return -EINVAL;
189 }
190
191 static int scpsys_power_on(struct generic_pm_domain *genpd)
192 {
193         struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
194         struct scp *scp = scpd->scp;
195         void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
196         u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
197         u32 val;
198         int ret, tmp;
199         int i;
200
201         if (scpd->supply) {
202                 ret = regulator_enable(scpd->supply);
203                 if (ret)
204                         return ret;
205         }
206
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]);
212
213                         goto err_clk;
214                 }
215         }
216
217         val = readl(ctl_addr);
218         val |= PWR_ON_BIT;
219         writel(val, ctl_addr);
220         val |= PWR_ON_2ND_BIT;
221         writel(val, ctl_addr);
222
223         /* wait until PWR_ACK = 1 */
224         ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp > 0,
225                                  MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
226         if (ret < 0)
227                 goto err_pwr_ack;
228
229         val &= ~PWR_CLK_DIS_BIT;
230         writel(val, ctl_addr);
231
232         val &= ~PWR_ISO_BIT;
233         writel(val, ctl_addr);
234
235         val |= PWR_RST_B_BIT;
236         writel(val, ctl_addr);
237
238         val &= ~scpd->data->sram_pdn_bits;
239         writel(val, ctl_addr);
240
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         }
264
265         return 0;
266
267 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         }
272 err_clk:
273         if (scpd->supply)
274                 regulator_disable(scpd->supply);
275
276         dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
277
278         return ret;
279 }
280
281 static int scpsys_power_off(struct generic_pm_domain *genpd)
282 {
283         struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
284         struct scp *scp = scpd->scp;
285         void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
286         u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
287         u32 val;
288         int ret, tmp;
289         int i;
290
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);
306         if (ret < 0)
307                 goto out;
308
309         val |= PWR_ISO_BIT;
310         writel(val, ctl_addr);
311
312         val &= ~PWR_RST_B_BIT;
313         writel(val, ctl_addr);
314
315         val |= PWR_CLK_DIS_BIT;
316         writel(val, ctl_addr);
317
318         val &= ~PWR_ON_BIT;
319         writel(val, ctl_addr);
320
321         val &= ~PWR_ON_2ND_BIT;
322         writel(val, ctl_addr);
323
324         /* wait until PWR_ACK = 0 */
325         ret = readx_poll_timeout(scpsys_domain_is_on, scpd, tmp, tmp == 0,
326                                  MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
327         if (ret < 0)
328                 goto out;
329
330         for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++)
331                 clk_disable_unprepare(scpd->clk[i]);
332
333         if (scpd->supply)
334                 regulator_disable(scpd->supply);
335
336         return 0;
337
338 out:
339         dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name);
340
341         return ret;
342 }
343
344 static void init_clks(struct platform_device *pdev, struct clk **clk)
345 {
346         int i;
347
348         for (i = CLK_NONE + 1; i < CLK_MAX; i++)
349                 clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
350 }
351
352 static struct scp *init_scp(struct platform_device *pdev,
353                         const struct scp_domain_data *scp_domain_data, int num,
354                         const struct scp_ctrl_reg *scp_ctrl_reg,
355                         bool bus_prot_reg_update)
356 {
357         struct genpd_onecell_data *pd_data;
358         struct resource *res;
359         int i, j;
360         struct scp *scp;
361         struct clk *clk[CLK_MAX];
362
363         scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
364         if (!scp)
365                 return ERR_PTR(-ENOMEM);
366
367         scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs;
368         scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs;
369
370         scp->bus_prot_reg_update = bus_prot_reg_update;
371
372         scp->dev = &pdev->dev;
373
374         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
375         scp->base = devm_ioremap_resource(&pdev->dev, res);
376         if (IS_ERR(scp->base))
377                 return ERR_CAST(scp->base);
378
379         scp->domains = devm_kzalloc(&pdev->dev,
380                                 sizeof(*scp->domains) * num, GFP_KERNEL);
381         if (!scp->domains)
382                 return ERR_PTR(-ENOMEM);
383
384         pd_data = &scp->pd_data;
385
386         pd_data->domains = devm_kzalloc(&pdev->dev,
387                         sizeof(*pd_data->domains) * num, GFP_KERNEL);
388         if (!pd_data->domains)
389                 return ERR_PTR(-ENOMEM);
390
391         scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
392                         "infracfg");
393         if (IS_ERR(scp->infracfg)) {
394                 dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n",
395                                 PTR_ERR(scp->infracfg));
396                 return ERR_CAST(scp->infracfg);
397         }
398
399         for (i = 0; i < num; i++) {
400                 struct scp_domain *scpd = &scp->domains[i];
401                 const struct scp_domain_data *data = &scp_domain_data[i];
402
403                 scpd->supply = devm_regulator_get_optional(&pdev->dev, data->name);
404                 if (IS_ERR(scpd->supply)) {
405                         if (PTR_ERR(scpd->supply) == -ENODEV)
406                                 scpd->supply = NULL;
407                         else
408                                 return ERR_CAST(scpd->supply);
409                 }
410         }
411
412         pd_data->num_domains = num;
413
414         init_clks(pdev, clk);
415
416         for (i = 0; i < num; i++) {
417                 struct scp_domain *scpd = &scp->domains[i];
418                 struct generic_pm_domain *genpd = &scpd->genpd;
419                 const struct scp_domain_data *data = &scp_domain_data[i];
420
421                 pd_data->domains[i] = genpd;
422                 scpd->scp = scp;
423
424                 scpd->data = data;
425
426                 for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) {
427                         struct clk *c = clk[data->clk_id[j]];
428
429                         if (IS_ERR(c)) {
430                                 dev_err(&pdev->dev, "%s: clk unavailable\n",
431                                         data->name);
432                                 return ERR_CAST(c);
433                         }
434
435                         scpd->clk[j] = c;
436                 }
437
438                 genpd->name = data->name;
439                 genpd->power_off = scpsys_power_off;
440                 genpd->power_on = scpsys_power_on;
441                 if (MTK_SCPD_CAPS(scpd, MTK_SCPD_ACTIVE_WAKEUP))
442                         genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP;
443         }
444
445         return scp;
446 }
447
448 static void mtk_register_power_domains(struct platform_device *pdev,
449                                 struct scp *scp, int num)
450 {
451         struct genpd_onecell_data *pd_data;
452         int i, ret;
453
454         for (i = 0; i < num; i++) {
455                 struct scp_domain *scpd = &scp->domains[i];
456                 struct generic_pm_domain *genpd = &scpd->genpd;
457
458                 /*
459                  * Initially turn on all domains to make the domains usable
460                  * with !CONFIG_PM and to get the hardware in sync with the
461                  * software.  The unused domains will be switched off during
462                  * late_init time.
463                  */
464                 genpd->power_on(genpd);
465
466                 pm_genpd_init(genpd, NULL, false);
467         }
468
469         /*
470          * We are not allowed to fail here since there is no way to unregister
471          * a power domain. Once registered above we have to keep the domains
472          * valid.
473          */
474
475         pd_data = &scp->pd_data;
476
477         ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
478         if (ret)
479                 dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
480 }
481
482 /*
483  * MT2701 power domain support
484  */
485
486 static const struct scp_domain_data scp_domain_data_mt2701[] = {
487         [MT2701_POWER_DOMAIN_CONN] = {
488                 .name = "conn",
489                 .sta_mask = PWR_STATUS_CONN,
490                 .ctl_offs = SPM_CONN_PWR_CON,
491                 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M |
492                                  MT2701_TOP_AXI_PROT_EN_CONN_S,
493                 .clk_id = {CLK_NONE},
494                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
495         },
496         [MT2701_POWER_DOMAIN_DISP] = {
497                 .name = "disp",
498                 .sta_mask = PWR_STATUS_DISP,
499                 .ctl_offs = SPM_DIS_PWR_CON,
500                 .sram_pdn_bits = GENMASK(11, 8),
501                 .clk_id = {CLK_MM},
502                 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_MM_M0,
503                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
504         },
505         [MT2701_POWER_DOMAIN_MFG] = {
506                 .name = "mfg",
507                 .sta_mask = PWR_STATUS_MFG,
508                 .ctl_offs = SPM_MFG_PWR_CON,
509                 .sram_pdn_bits = GENMASK(11, 8),
510                 .sram_pdn_ack_bits = GENMASK(12, 12),
511                 .clk_id = {CLK_MFG},
512                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
513         },
514         [MT2701_POWER_DOMAIN_VDEC] = {
515                 .name = "vdec",
516                 .sta_mask = PWR_STATUS_VDEC,
517                 .ctl_offs = SPM_VDE_PWR_CON,
518                 .sram_pdn_bits = GENMASK(11, 8),
519                 .sram_pdn_ack_bits = GENMASK(12, 12),
520                 .clk_id = {CLK_MM},
521                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
522         },
523         [MT2701_POWER_DOMAIN_ISP] = {
524                 .name = "isp",
525                 .sta_mask = PWR_STATUS_ISP,
526                 .ctl_offs = SPM_ISP_PWR_CON,
527                 .sram_pdn_bits = GENMASK(11, 8),
528                 .sram_pdn_ack_bits = GENMASK(13, 12),
529                 .clk_id = {CLK_MM},
530                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
531         },
532         [MT2701_POWER_DOMAIN_BDP] = {
533                 .name = "bdp",
534                 .sta_mask = PWR_STATUS_BDP,
535                 .ctl_offs = SPM_BDP_PWR_CON,
536                 .sram_pdn_bits = GENMASK(11, 8),
537                 .clk_id = {CLK_NONE},
538                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
539         },
540         [MT2701_POWER_DOMAIN_ETH] = {
541                 .name = "eth",
542                 .sta_mask = PWR_STATUS_ETH,
543                 .ctl_offs = SPM_ETH_PWR_CON,
544                 .sram_pdn_bits = GENMASK(11, 8),
545                 .sram_pdn_ack_bits = GENMASK(15, 12),
546                 .clk_id = {CLK_ETHIF},
547                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
548         },
549         [MT2701_POWER_DOMAIN_HIF] = {
550                 .name = "hif",
551                 .sta_mask = PWR_STATUS_HIF,
552                 .ctl_offs = SPM_HIF_PWR_CON,
553                 .sram_pdn_bits = GENMASK(11, 8),
554                 .sram_pdn_ack_bits = GENMASK(15, 12),
555                 .clk_id = {CLK_ETHIF},
556                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
557         },
558         [MT2701_POWER_DOMAIN_IFR_MSC] = {
559                 .name = "ifr_msc",
560                 .sta_mask = PWR_STATUS_IFR_MSC,
561                 .ctl_offs = SPM_IFR_MSC_PWR_CON,
562                 .clk_id = {CLK_NONE},
563                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
564         },
565 };
566
567 /*
568  * MT2712 power domain support
569  */
570 static const struct scp_domain_data scp_domain_data_mt2712[] = {
571         [MT2712_POWER_DOMAIN_MM] = {
572                 .name = "mm",
573                 .sta_mask = PWR_STATUS_DISP,
574                 .ctl_offs = SPM_DIS_PWR_CON,
575                 .sram_pdn_bits = GENMASK(8, 8),
576                 .sram_pdn_ack_bits = GENMASK(12, 12),
577                 .clk_id = {CLK_MM},
578                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
579         },
580         [MT2712_POWER_DOMAIN_VDEC] = {
581                 .name = "vdec",
582                 .sta_mask = PWR_STATUS_VDEC,
583                 .ctl_offs = SPM_VDE_PWR_CON,
584                 .sram_pdn_bits = GENMASK(8, 8),
585                 .sram_pdn_ack_bits = GENMASK(12, 12),
586                 .clk_id = {CLK_MM, CLK_VDEC},
587                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
588         },
589         [MT2712_POWER_DOMAIN_VENC] = {
590                 .name = "venc",
591                 .sta_mask = PWR_STATUS_VENC,
592                 .ctl_offs = SPM_VEN_PWR_CON,
593                 .sram_pdn_bits = GENMASK(11, 8),
594                 .sram_pdn_ack_bits = GENMASK(15, 12),
595                 .clk_id = {CLK_MM, CLK_VENC, CLK_JPGDEC},
596                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
597         },
598         [MT2712_POWER_DOMAIN_ISP] = {
599                 .name = "isp",
600                 .sta_mask = PWR_STATUS_ISP,
601                 .ctl_offs = SPM_ISP_PWR_CON,
602                 .sram_pdn_bits = GENMASK(11, 8),
603                 .sram_pdn_ack_bits = GENMASK(13, 12),
604                 .clk_id = {CLK_MM},
605                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
606         },
607         [MT2712_POWER_DOMAIN_AUDIO] = {
608                 .name = "audio",
609                 .sta_mask = PWR_STATUS_AUDIO,
610                 .ctl_offs = SPM_AUDIO_PWR_CON,
611                 .sram_pdn_bits = GENMASK(11, 8),
612                 .sram_pdn_ack_bits = GENMASK(15, 12),
613                 .clk_id = {CLK_AUDIO},
614                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
615         },
616         [MT2712_POWER_DOMAIN_USB] = {
617                 .name = "usb",
618                 .sta_mask = PWR_STATUS_USB,
619                 .ctl_offs = SPM_USB_PWR_CON,
620                 .sram_pdn_bits = GENMASK(10, 8),
621                 .sram_pdn_ack_bits = GENMASK(14, 12),
622                 .clk_id = {CLK_NONE},
623                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
624         },
625         [MT2712_POWER_DOMAIN_USB2] = {
626                 .name = "usb2",
627                 .sta_mask = PWR_STATUS_USB2,
628                 .ctl_offs = SPM_USB2_PWR_CON,
629                 .sram_pdn_bits = GENMASK(10, 8),
630                 .sram_pdn_ack_bits = GENMASK(14, 12),
631                 .clk_id = {CLK_NONE},
632                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
633         },
634         [MT2712_POWER_DOMAIN_MFG] = {
635                 .name = "mfg",
636                 .sta_mask = PWR_STATUS_MFG,
637                 .ctl_offs = SPM_MFG_PWR_CON,
638                 .sram_pdn_bits = GENMASK(8, 8),
639                 .sram_pdn_ack_bits = GENMASK(16, 16),
640                 .clk_id = {CLK_MFG},
641                 .bus_prot_mask = BIT(14) | BIT(21) | BIT(23),
642                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
643         },
644         [MT2712_POWER_DOMAIN_MFG_SC1] = {
645                 .name = "mfg_sc1",
646                 .sta_mask = BIT(22),
647                 .ctl_offs = 0x02c0,
648                 .sram_pdn_bits = GENMASK(8, 8),
649                 .sram_pdn_ack_bits = GENMASK(16, 16),
650                 .clk_id = {CLK_NONE},
651                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
652         },
653         [MT2712_POWER_DOMAIN_MFG_SC2] = {
654                 .name = "mfg_sc2",
655                 .sta_mask = BIT(23),
656                 .ctl_offs = 0x02c4,
657                 .sram_pdn_bits = GENMASK(8, 8),
658                 .sram_pdn_ack_bits = GENMASK(16, 16),
659                 .clk_id = {CLK_NONE},
660                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
661         },
662         [MT2712_POWER_DOMAIN_MFG_SC3] = {
663                 .name = "mfg_sc3",
664                 .sta_mask = BIT(30),
665                 .ctl_offs = 0x01f8,
666                 .sram_pdn_bits = GENMASK(8, 8),
667                 .sram_pdn_ack_bits = GENMASK(16, 16),
668                 .clk_id = {CLK_NONE},
669                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
670         },
671 };
672
673 static const struct scp_subdomain scp_subdomain_mt2712[] = {
674         {MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_VDEC},
675         {MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_VENC},
676         {MT2712_POWER_DOMAIN_MM, MT2712_POWER_DOMAIN_ISP},
677         {MT2712_POWER_DOMAIN_MFG, MT2712_POWER_DOMAIN_MFG_SC1},
678         {MT2712_POWER_DOMAIN_MFG_SC1, MT2712_POWER_DOMAIN_MFG_SC2},
679         {MT2712_POWER_DOMAIN_MFG_SC2, MT2712_POWER_DOMAIN_MFG_SC3},
680 };
681
682 /*
683  * MT6797 power domain support
684  */
685
686 static const struct scp_domain_data scp_domain_data_mt6797[] = {
687         [MT6797_POWER_DOMAIN_VDEC] = {
688                 .name = "vdec",
689                 .sta_mask = BIT(7),
690                 .ctl_offs = 0x300,
691                 .sram_pdn_bits = GENMASK(8, 8),
692                 .sram_pdn_ack_bits = GENMASK(12, 12),
693                 .clk_id = {CLK_VDEC},
694         },
695         [MT6797_POWER_DOMAIN_VENC] = {
696                 .name = "venc",
697                 .sta_mask = BIT(21),
698                 .ctl_offs = 0x304,
699                 .sram_pdn_bits = GENMASK(11, 8),
700                 .sram_pdn_ack_bits = GENMASK(15, 12),
701                 .clk_id = {CLK_NONE},
702         },
703         [MT6797_POWER_DOMAIN_ISP] = {
704                 .name = "isp",
705                 .sta_mask = BIT(5),
706                 .ctl_offs = 0x308,
707                 .sram_pdn_bits = GENMASK(9, 8),
708                 .sram_pdn_ack_bits = GENMASK(13, 12),
709                 .clk_id = {CLK_NONE},
710         },
711         [MT6797_POWER_DOMAIN_MM] = {
712                 .name = "mm",
713                 .sta_mask = BIT(3),
714                 .ctl_offs = 0x30C,
715                 .sram_pdn_bits = GENMASK(8, 8),
716                 .sram_pdn_ack_bits = GENMASK(12, 12),
717                 .clk_id = {CLK_MM},
718                 .bus_prot_mask = (BIT(1) | BIT(2)),
719         },
720         [MT6797_POWER_DOMAIN_AUDIO] = {
721                 .name = "audio",
722                 .sta_mask = BIT(24),
723                 .ctl_offs = 0x314,
724                 .sram_pdn_bits = GENMASK(11, 8),
725                 .sram_pdn_ack_bits = GENMASK(15, 12),
726                 .clk_id = {CLK_NONE},
727         },
728         [MT6797_POWER_DOMAIN_MFG_ASYNC] = {
729                 .name = "mfg_async",
730                 .sta_mask = BIT(13),
731                 .ctl_offs = 0x334,
732                 .sram_pdn_bits = 0,
733                 .sram_pdn_ack_bits = 0,
734                 .clk_id = {CLK_MFG},
735         },
736         [MT6797_POWER_DOMAIN_MJC] = {
737                 .name = "mjc",
738                 .sta_mask = BIT(20),
739                 .ctl_offs = 0x310,
740                 .sram_pdn_bits = GENMASK(8, 8),
741                 .sram_pdn_ack_bits = GENMASK(12, 12),
742                 .clk_id = {CLK_NONE},
743         },
744 };
745
746 #define SPM_PWR_STATUS_MT6797           0x0180
747 #define SPM_PWR_STATUS_2ND_MT6797       0x0184
748
749 static const struct scp_subdomain scp_subdomain_mt6797[] = {
750         {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VDEC},
751         {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_ISP},
752         {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VENC},
753         {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_MJC},
754 };
755
756 /*
757  * MT7622 power domain support
758  */
759
760 static const struct scp_domain_data scp_domain_data_mt7622[] = {
761         [MT7622_POWER_DOMAIN_ETHSYS] = {
762                 .name = "ethsys",
763                 .sta_mask = PWR_STATUS_ETHSYS,
764                 .ctl_offs = SPM_ETHSYS_PWR_CON,
765                 .sram_pdn_bits = GENMASK(11, 8),
766                 .sram_pdn_ack_bits = GENMASK(15, 12),
767                 .clk_id = {CLK_NONE},
768                 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS,
769                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
770         },
771         [MT7622_POWER_DOMAIN_HIF0] = {
772                 .name = "hif0",
773                 .sta_mask = PWR_STATUS_HIF0,
774                 .ctl_offs = SPM_HIF0_PWR_CON,
775                 .sram_pdn_bits = GENMASK(11, 8),
776                 .sram_pdn_ack_bits = GENMASK(15, 12),
777                 .clk_id = {CLK_HIFSEL},
778                 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0,
779                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
780         },
781         [MT7622_POWER_DOMAIN_HIF1] = {
782                 .name = "hif1",
783                 .sta_mask = PWR_STATUS_HIF1,
784                 .ctl_offs = SPM_HIF1_PWR_CON,
785                 .sram_pdn_bits = GENMASK(11, 8),
786                 .sram_pdn_ack_bits = GENMASK(15, 12),
787                 .clk_id = {CLK_HIFSEL},
788                 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1,
789                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
790         },
791         [MT7622_POWER_DOMAIN_WB] = {
792                 .name = "wb",
793                 .sta_mask = PWR_STATUS_WB,
794                 .ctl_offs = SPM_WB_PWR_CON,
795                 .sram_pdn_bits = 0,
796                 .sram_pdn_ack_bits = 0,
797                 .clk_id = {CLK_NONE},
798                 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB,
799                 .caps = MTK_SCPD_ACTIVE_WAKEUP | MTK_SCPD_FWAIT_SRAM,
800         },
801 };
802
803 /*
804  * MT7623A power domain support
805  */
806
807 static const struct scp_domain_data scp_domain_data_mt7623a[] = {
808         [MT7623A_POWER_DOMAIN_CONN] = {
809                 .name = "conn",
810                 .sta_mask = PWR_STATUS_CONN,
811                 .ctl_offs = SPM_CONN_PWR_CON,
812                 .bus_prot_mask = MT2701_TOP_AXI_PROT_EN_CONN_M |
813                                  MT2701_TOP_AXI_PROT_EN_CONN_S,
814                 .clk_id = {CLK_NONE},
815                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
816         },
817         [MT7623A_POWER_DOMAIN_ETH] = {
818                 .name = "eth",
819                 .sta_mask = PWR_STATUS_ETH,
820                 .ctl_offs = SPM_ETH_PWR_CON,
821                 .sram_pdn_bits = GENMASK(11, 8),
822                 .sram_pdn_ack_bits = GENMASK(15, 12),
823                 .clk_id = {CLK_ETHIF},
824                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
825         },
826         [MT7623A_POWER_DOMAIN_HIF] = {
827                 .name = "hif",
828                 .sta_mask = PWR_STATUS_HIF,
829                 .ctl_offs = SPM_HIF_PWR_CON,
830                 .sram_pdn_bits = GENMASK(11, 8),
831                 .sram_pdn_ack_bits = GENMASK(15, 12),
832                 .clk_id = {CLK_ETHIF},
833                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
834         },
835         [MT7623A_POWER_DOMAIN_IFR_MSC] = {
836                 .name = "ifr_msc",
837                 .sta_mask = PWR_STATUS_IFR_MSC,
838                 .ctl_offs = SPM_IFR_MSC_PWR_CON,
839                 .clk_id = {CLK_NONE},
840                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
841         },
842 };
843
844 /*
845  * MT8173 power domain support
846  */
847
848 static const struct scp_domain_data scp_domain_data_mt8173[] = {
849         [MT8173_POWER_DOMAIN_VDEC] = {
850                 .name = "vdec",
851                 .sta_mask = PWR_STATUS_VDEC,
852                 .ctl_offs = SPM_VDE_PWR_CON,
853                 .sram_pdn_bits = GENMASK(11, 8),
854                 .sram_pdn_ack_bits = GENMASK(12, 12),
855                 .clk_id = {CLK_MM},
856         },
857         [MT8173_POWER_DOMAIN_VENC] = {
858                 .name = "venc",
859                 .sta_mask = PWR_STATUS_VENC,
860                 .ctl_offs = SPM_VEN_PWR_CON,
861                 .sram_pdn_bits = GENMASK(11, 8),
862                 .sram_pdn_ack_bits = GENMASK(15, 12),
863                 .clk_id = {CLK_MM, CLK_VENC},
864         },
865         [MT8173_POWER_DOMAIN_ISP] = {
866                 .name = "isp",
867                 .sta_mask = PWR_STATUS_ISP,
868                 .ctl_offs = SPM_ISP_PWR_CON,
869                 .sram_pdn_bits = GENMASK(11, 8),
870                 .sram_pdn_ack_bits = GENMASK(13, 12),
871                 .clk_id = {CLK_MM},
872         },
873         [MT8173_POWER_DOMAIN_MM] = {
874                 .name = "mm",
875                 .sta_mask = PWR_STATUS_DISP,
876                 .ctl_offs = SPM_DIS_PWR_CON,
877                 .sram_pdn_bits = GENMASK(11, 8),
878                 .sram_pdn_ack_bits = GENMASK(12, 12),
879                 .clk_id = {CLK_MM},
880                 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
881                         MT8173_TOP_AXI_PROT_EN_MM_M1,
882         },
883         [MT8173_POWER_DOMAIN_VENC_LT] = {
884                 .name = "venc_lt",
885                 .sta_mask = PWR_STATUS_VENC_LT,
886                 .ctl_offs = SPM_VEN2_PWR_CON,
887                 .sram_pdn_bits = GENMASK(11, 8),
888                 .sram_pdn_ack_bits = GENMASK(15, 12),
889                 .clk_id = {CLK_MM, CLK_VENC_LT},
890         },
891         [MT8173_POWER_DOMAIN_AUDIO] = {
892                 .name = "audio",
893                 .sta_mask = PWR_STATUS_AUDIO,
894                 .ctl_offs = SPM_AUDIO_PWR_CON,
895                 .sram_pdn_bits = GENMASK(11, 8),
896                 .sram_pdn_ack_bits = GENMASK(15, 12),
897                 .clk_id = {CLK_NONE},
898         },
899         [MT8173_POWER_DOMAIN_USB] = {
900                 .name = "usb",
901                 .sta_mask = PWR_STATUS_USB,
902                 .ctl_offs = SPM_USB_PWR_CON,
903                 .sram_pdn_bits = GENMASK(11, 8),
904                 .sram_pdn_ack_bits = GENMASK(15, 12),
905                 .clk_id = {CLK_NONE},
906                 .caps = MTK_SCPD_ACTIVE_WAKEUP,
907         },
908         [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
909                 .name = "mfg_async",
910                 .sta_mask = PWR_STATUS_MFG_ASYNC,
911                 .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
912                 .sram_pdn_bits = GENMASK(11, 8),
913                 .sram_pdn_ack_bits = 0,
914                 .clk_id = {CLK_MFG},
915         },
916         [MT8173_POWER_DOMAIN_MFG_2D] = {
917                 .name = "mfg_2d",
918                 .sta_mask = PWR_STATUS_MFG_2D,
919                 .ctl_offs = SPM_MFG_2D_PWR_CON,
920                 .sram_pdn_bits = GENMASK(11, 8),
921                 .sram_pdn_ack_bits = GENMASK(13, 12),
922                 .clk_id = {CLK_NONE},
923         },
924         [MT8173_POWER_DOMAIN_MFG] = {
925                 .name = "mfg",
926                 .sta_mask = PWR_STATUS_MFG,
927                 .ctl_offs = SPM_MFG_PWR_CON,
928                 .sram_pdn_bits = GENMASK(13, 8),
929                 .sram_pdn_ack_bits = GENMASK(21, 16),
930                 .clk_id = {CLK_NONE},
931                 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
932                         MT8173_TOP_AXI_PROT_EN_MFG_M0 |
933                         MT8173_TOP_AXI_PROT_EN_MFG_M1 |
934                         MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
935         },
936 };
937
938 static const struct scp_subdomain scp_subdomain_mt8173[] = {
939         {MT8173_POWER_DOMAIN_MFG_ASYNC, MT8173_POWER_DOMAIN_MFG_2D},
940         {MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG},
941 };
942
943 static const struct scp_soc_data mt2701_data = {
944         .domains = scp_domain_data_mt2701,
945         .num_domains = ARRAY_SIZE(scp_domain_data_mt2701),
946         .regs = {
947                 .pwr_sta_offs = SPM_PWR_STATUS,
948                 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
949         },
950         .bus_prot_reg_update = true,
951 };
952
953 static const struct scp_soc_data mt2712_data = {
954         .domains = scp_domain_data_mt2712,
955         .num_domains = ARRAY_SIZE(scp_domain_data_mt2712),
956         .subdomains = scp_subdomain_mt2712,
957         .num_subdomains = ARRAY_SIZE(scp_subdomain_mt2712),
958         .regs = {
959                 .pwr_sta_offs = SPM_PWR_STATUS,
960                 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
961         },
962         .bus_prot_reg_update = false,
963 };
964
965 static const struct scp_soc_data mt6797_data = {
966         .domains = scp_domain_data_mt6797,
967         .num_domains = ARRAY_SIZE(scp_domain_data_mt6797),
968         .subdomains = scp_subdomain_mt6797,
969         .num_subdomains = ARRAY_SIZE(scp_subdomain_mt6797),
970         .regs = {
971                 .pwr_sta_offs = SPM_PWR_STATUS_MT6797,
972                 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797
973         },
974         .bus_prot_reg_update = true,
975 };
976
977 static const struct scp_soc_data mt7622_data = {
978         .domains = scp_domain_data_mt7622,
979         .num_domains = ARRAY_SIZE(scp_domain_data_mt7622),
980         .regs = {
981                 .pwr_sta_offs = SPM_PWR_STATUS,
982                 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
983         },
984         .bus_prot_reg_update = true,
985 };
986
987 static const struct scp_soc_data mt7623a_data = {
988         .domains = scp_domain_data_mt7623a,
989         .num_domains = ARRAY_SIZE(scp_domain_data_mt7623a),
990         .regs = {
991                 .pwr_sta_offs = SPM_PWR_STATUS,
992                 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
993         },
994         .bus_prot_reg_update = true,
995 };
996
997 static const struct scp_soc_data mt8173_data = {
998         .domains = scp_domain_data_mt8173,
999         .num_domains = ARRAY_SIZE(scp_domain_data_mt8173),
1000         .subdomains = scp_subdomain_mt8173,
1001         .num_subdomains = ARRAY_SIZE(scp_subdomain_mt8173),
1002         .regs = {
1003                 .pwr_sta_offs = SPM_PWR_STATUS,
1004                 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
1005         },
1006         .bus_prot_reg_update = true,
1007 };
1008
1009 /*
1010  * scpsys driver init
1011  */
1012
1013 static const struct of_device_id of_scpsys_match_tbl[] = {
1014         {
1015                 .compatible = "mediatek,mt2701-scpsys",
1016                 .data = &mt2701_data,
1017         }, {
1018                 .compatible = "mediatek,mt2712-scpsys",
1019                 .data = &mt2712_data,
1020         }, {
1021                 .compatible = "mediatek,mt6797-scpsys",
1022                 .data = &mt6797_data,
1023         }, {
1024                 .compatible = "mediatek,mt7622-scpsys",
1025                 .data = &mt7622_data,
1026         }, {
1027                 .compatible = "mediatek,mt7623a-scpsys",
1028                 .data = &mt7623a_data,
1029         }, {
1030                 .compatible = "mediatek,mt8173-scpsys",
1031                 .data = &mt8173_data,
1032         }, {
1033                 /* sentinel */
1034         }
1035 };
1036
1037 static int scpsys_probe(struct platform_device *pdev)
1038 {
1039         const struct scp_subdomain *sd;
1040         const struct scp_soc_data *soc;
1041         struct scp *scp;
1042         struct genpd_onecell_data *pd_data;
1043         int i, ret;
1044
1045         soc = of_device_get_match_data(&pdev->dev);
1046
1047         scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs,
1048                         soc->bus_prot_reg_update);
1049         if (IS_ERR(scp))
1050                 return PTR_ERR(scp);
1051
1052         mtk_register_power_domains(pdev, scp, soc->num_domains);
1053
1054         pd_data = &scp->pd_data;
1055
1056         for (i = 0, sd = soc->subdomains; i < soc->num_subdomains; i++, sd++) {
1057                 ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin],
1058                                              pd_data->domains[sd->subdomain]);
1059                 if (ret && IS_ENABLED(CONFIG_PM))
1060                         dev_err(&pdev->dev, "Failed to add subdomain: %d\n",
1061                                 ret);
1062         }
1063
1064         return 0;
1065 }
1066
1067 static struct platform_driver scpsys_drv = {
1068         .probe = scpsys_probe,
1069         .driver = {
1070                 .name = "mtk-scpsys",
1071                 .suppress_bind_attrs = true,
1072                 .owner = THIS_MODULE,
1073                 .of_match_table = of_match_ptr(of_scpsys_match_tbl),
1074         },
1075 };
1076 builtin_platform_driver(scpsys_drv);