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