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