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