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