watchdog/core: Rename some softlockup_* functions
[linux/fpc-iii.git] / drivers / soc / mediatek / mtk-scpsys.c
blobe1ce8b1b5090aa0a7b91b6abcd73ad7fa0760261
1 /*
2 * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
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.
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.
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>
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>
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 */
49 #define SPM_PWR_STATUS 0x060c
50 #define SPM_PWR_STATUS_2ND 0x0610
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)
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 */
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,
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,
102 #define MAX_CLKS 2
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;
115 struct scp;
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;
125 struct scp_ctrl_reg {
126 int pwr_sta_offs;
127 int pwr_sta2nd_offs;
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;
139 struct scp_subdomain {
140 int origin;
141 int subdomain;
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;
152 static int scpsys_domain_is_on(struct scp_domain *scpd)
154 struct scp *scp = scpd->scp;
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;
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
166 if (status && status2)
167 return true;
168 if (!status && !status2)
169 return false;
171 return -EINVAL;
174 static int scpsys_power_on(struct generic_pm_domain *genpd)
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;
186 if (scpd->supply) {
187 ret = regulator_enable(scpd->supply);
188 if (ret)
189 return ret;
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]);
198 goto err_clk;
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);
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;
216 if (expired) {
217 ret = -ETIMEDOUT;
218 goto err_pwr_ack;
221 cpu_relax();
223 if (time_after(jiffies, timeout))
224 expired = true;
227 val &= ~PWR_CLK_DIS_BIT;
228 writel(val, ctl_addr);
230 val &= ~PWR_ISO_BIT;
231 writel(val, ctl_addr);
233 val |= PWR_RST_B_BIT;
234 writel(val, ctl_addr);
236 val &= ~scpd->data->sram_pdn_bits;
237 writel(val, ctl_addr);
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)) {
244 if (expired) {
245 ret = -ETIMEDOUT;
246 goto err_pwr_ack;
249 cpu_relax();
251 if (time_after(jiffies, timeout))
252 expired = true;
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;
262 return 0;
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]);
269 err_clk:
270 if (scpd->supply)
271 regulator_disable(scpd->supply);
273 dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
275 return ret;
278 static int scpsys_power_off(struct generic_pm_domain *genpd)
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;
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;
297 val = readl(ctl_addr);
298 val |= scpd->data->sram_pdn_bits;
299 writel(val, ctl_addr);
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;
310 cpu_relax();
312 if (time_after(jiffies, timeout))
313 expired = true;
316 val |= PWR_ISO_BIT;
317 writel(val, ctl_addr);
319 val &= ~PWR_RST_B_BIT;
320 writel(val, ctl_addr);
322 val |= PWR_CLK_DIS_BIT;
323 writel(val, ctl_addr);
325 val &= ~PWR_ON_BIT;
326 writel(val, ctl_addr);
328 val &= ~PWR_ON_2ND_BIT;
329 writel(val, ctl_addr);
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;
339 if (expired) {
340 ret = -ETIMEDOUT;
341 goto out;
344 cpu_relax();
346 if (time_after(jiffies, timeout))
347 expired = true;
350 for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++)
351 clk_disable_unprepare(scpd->clk[i]);
353 if (scpd->supply)
354 regulator_disable(scpd->supply);
356 return 0;
358 out:
359 dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name);
361 return ret;
364 static bool scpsys_active_wakeup(struct device *dev)
366 struct generic_pm_domain *genpd;
367 struct scp_domain *scpd;
369 genpd = pd_to_genpd(dev->pm_domain);
370 scpd = container_of(genpd, struct scp_domain, genpd);
372 return scpd->data->active_wakeup;
375 static void init_clks(struct platform_device *pdev, struct clk **clk)
377 int i;
379 for (i = CLK_NONE + 1; i < CLK_MAX; i++)
380 clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
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)
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];
393 scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
394 if (!scp)
395 return ERR_PTR(-ENOMEM);
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;
400 scp->dev = &pdev->dev;
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);
407 scp->domains = devm_kzalloc(&pdev->dev,
408 sizeof(*scp->domains) * num, GFP_KERNEL);
409 if (!scp->domains)
410 return ERR_PTR(-ENOMEM);
412 pd_data = &scp->pd_data;
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);
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);
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];
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);
440 pd_data->num_domains = num;
442 init_clks(pdev, clk);
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];
449 pd_data->domains[i] = genpd;
450 scpd->scp = scp;
452 scpd->data = data;
454 for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) {
455 struct clk *c = clk[data->clk_id[j]];
457 if (IS_ERR(c)) {
458 dev_err(&pdev->dev, "%s: clk unavailable\n",
459 data->name);
460 return ERR_CAST(c);
463 scpd->clk[j] = c;
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;
472 return scp;
475 static void mtk_register_power_domains(struct platform_device *pdev,
476 struct scp *scp, int num)
478 struct genpd_onecell_data *pd_data;
479 int i, ret;
481 for (i = 0; i < num; i++) {
482 struct scp_domain *scpd = &scp->domains[i];
483 struct generic_pm_domain *genpd = &scpd->genpd;
486 * Initially turn on all domains to make the domains usable
487 * with !CONFIG_PM and to get the hardware in sync with the
488 * software. The unused domains will be switched off during
489 * late_init time.
491 genpd->power_on(genpd);
493 pm_genpd_init(genpd, NULL, false);
497 * We are not allowed to fail here since there is no way to unregister
498 * a power domain. Once registered above we have to keep the domains
499 * valid.
502 pd_data = &scp->pd_data;
504 ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
505 if (ret)
506 dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
510 * MT2701 power domain support
513 static const struct scp_domain_data scp_domain_data_mt2701[] = {
514 [MT2701_POWER_DOMAIN_CONN] = {
515 .name = "conn",
516 .sta_mask = PWR_STATUS_CONN,
517 .ctl_offs = SPM_CONN_PWR_CON,
518 .bus_prot_mask = 0x0104,
519 .clk_id = {CLK_NONE},
520 .active_wakeup = true,
522 [MT2701_POWER_DOMAIN_DISP] = {
523 .name = "disp",
524 .sta_mask = PWR_STATUS_DISP,
525 .ctl_offs = SPM_DIS_PWR_CON,
526 .sram_pdn_bits = GENMASK(11, 8),
527 .clk_id = {CLK_MM},
528 .bus_prot_mask = 0x0002,
529 .active_wakeup = true,
531 [MT2701_POWER_DOMAIN_MFG] = {
532 .name = "mfg",
533 .sta_mask = PWR_STATUS_MFG,
534 .ctl_offs = SPM_MFG_PWR_CON,
535 .sram_pdn_bits = GENMASK(11, 8),
536 .sram_pdn_ack_bits = GENMASK(12, 12),
537 .clk_id = {CLK_MFG},
538 .active_wakeup = true,
540 [MT2701_POWER_DOMAIN_VDEC] = {
541 .name = "vdec",
542 .sta_mask = PWR_STATUS_VDEC,
543 .ctl_offs = SPM_VDE_PWR_CON,
544 .sram_pdn_bits = GENMASK(11, 8),
545 .sram_pdn_ack_bits = GENMASK(12, 12),
546 .clk_id = {CLK_MM},
547 .active_wakeup = true,
549 [MT2701_POWER_DOMAIN_ISP] = {
550 .name = "isp",
551 .sta_mask = PWR_STATUS_ISP,
552 .ctl_offs = SPM_ISP_PWR_CON,
553 .sram_pdn_bits = GENMASK(11, 8),
554 .sram_pdn_ack_bits = GENMASK(13, 12),
555 .clk_id = {CLK_MM},
556 .active_wakeup = true,
558 [MT2701_POWER_DOMAIN_BDP] = {
559 .name = "bdp",
560 .sta_mask = PWR_STATUS_BDP,
561 .ctl_offs = SPM_BDP_PWR_CON,
562 .sram_pdn_bits = GENMASK(11, 8),
563 .clk_id = {CLK_NONE},
564 .active_wakeup = true,
566 [MT2701_POWER_DOMAIN_ETH] = {
567 .name = "eth",
568 .sta_mask = PWR_STATUS_ETH,
569 .ctl_offs = SPM_ETH_PWR_CON,
570 .sram_pdn_bits = GENMASK(11, 8),
571 .sram_pdn_ack_bits = GENMASK(15, 12),
572 .clk_id = {CLK_ETHIF},
573 .active_wakeup = true,
575 [MT2701_POWER_DOMAIN_HIF] = {
576 .name = "hif",
577 .sta_mask = PWR_STATUS_HIF,
578 .ctl_offs = SPM_HIF_PWR_CON,
579 .sram_pdn_bits = GENMASK(11, 8),
580 .sram_pdn_ack_bits = GENMASK(15, 12),
581 .clk_id = {CLK_ETHIF},
582 .active_wakeup = true,
584 [MT2701_POWER_DOMAIN_IFR_MSC] = {
585 .name = "ifr_msc",
586 .sta_mask = PWR_STATUS_IFR_MSC,
587 .ctl_offs = SPM_IFR_MSC_PWR_CON,
588 .clk_id = {CLK_NONE},
589 .active_wakeup = true,
594 * MT6797 power domain support
597 static const struct scp_domain_data scp_domain_data_mt6797[] = {
598 [MT6797_POWER_DOMAIN_VDEC] = {
599 .name = "vdec",
600 .sta_mask = BIT(7),
601 .ctl_offs = 0x300,
602 .sram_pdn_bits = GENMASK(8, 8),
603 .sram_pdn_ack_bits = GENMASK(12, 12),
604 .clk_id = {CLK_VDEC},
606 [MT6797_POWER_DOMAIN_VENC] = {
607 .name = "venc",
608 .sta_mask = BIT(21),
609 .ctl_offs = 0x304,
610 .sram_pdn_bits = GENMASK(11, 8),
611 .sram_pdn_ack_bits = GENMASK(15, 12),
612 .clk_id = {CLK_NONE},
614 [MT6797_POWER_DOMAIN_ISP] = {
615 .name = "isp",
616 .sta_mask = BIT(5),
617 .ctl_offs = 0x308,
618 .sram_pdn_bits = GENMASK(9, 8),
619 .sram_pdn_ack_bits = GENMASK(13, 12),
620 .clk_id = {CLK_NONE},
622 [MT6797_POWER_DOMAIN_MM] = {
623 .name = "mm",
624 .sta_mask = BIT(3),
625 .ctl_offs = 0x30C,
626 .sram_pdn_bits = GENMASK(8, 8),
627 .sram_pdn_ack_bits = GENMASK(12, 12),
628 .clk_id = {CLK_MM},
629 .bus_prot_mask = (BIT(1) | BIT(2)),
631 [MT6797_POWER_DOMAIN_AUDIO] = {
632 .name = "audio",
633 .sta_mask = BIT(24),
634 .ctl_offs = 0x314,
635 .sram_pdn_bits = GENMASK(11, 8),
636 .sram_pdn_ack_bits = GENMASK(15, 12),
637 .clk_id = {CLK_NONE},
639 [MT6797_POWER_DOMAIN_MFG_ASYNC] = {
640 .name = "mfg_async",
641 .sta_mask = BIT(13),
642 .ctl_offs = 0x334,
643 .sram_pdn_bits = 0,
644 .sram_pdn_ack_bits = 0,
645 .clk_id = {CLK_MFG},
647 [MT6797_POWER_DOMAIN_MJC] = {
648 .name = "mjc",
649 .sta_mask = BIT(20),
650 .ctl_offs = 0x310,
651 .sram_pdn_bits = GENMASK(8, 8),
652 .sram_pdn_ack_bits = GENMASK(12, 12),
653 .clk_id = {CLK_NONE},
657 #define SPM_PWR_STATUS_MT6797 0x0180
658 #define SPM_PWR_STATUS_2ND_MT6797 0x0184
660 static const struct scp_subdomain scp_subdomain_mt6797[] = {
661 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VDEC},
662 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_ISP},
663 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VENC},
664 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_MJC},
668 * MT7622 power domain support
671 static const struct scp_domain_data scp_domain_data_mt7622[] = {
672 [MT7622_POWER_DOMAIN_ETHSYS] = {
673 .name = "ethsys",
674 .sta_mask = PWR_STATUS_ETHSYS,
675 .ctl_offs = SPM_ETHSYS_PWR_CON,
676 .sram_pdn_bits = GENMASK(11, 8),
677 .sram_pdn_ack_bits = GENMASK(15, 12),
678 .clk_id = {CLK_NONE},
679 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS,
680 .active_wakeup = true,
682 [MT7622_POWER_DOMAIN_HIF0] = {
683 .name = "hif0",
684 .sta_mask = PWR_STATUS_HIF0,
685 .ctl_offs = SPM_HIF0_PWR_CON,
686 .sram_pdn_bits = GENMASK(11, 8),
687 .sram_pdn_ack_bits = GENMASK(15, 12),
688 .clk_id = {CLK_HIFSEL},
689 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0,
690 .active_wakeup = true,
692 [MT7622_POWER_DOMAIN_HIF1] = {
693 .name = "hif1",
694 .sta_mask = PWR_STATUS_HIF1,
695 .ctl_offs = SPM_HIF1_PWR_CON,
696 .sram_pdn_bits = GENMASK(11, 8),
697 .sram_pdn_ack_bits = GENMASK(15, 12),
698 .clk_id = {CLK_HIFSEL},
699 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF1,
700 .active_wakeup = true,
702 [MT7622_POWER_DOMAIN_WB] = {
703 .name = "wb",
704 .sta_mask = PWR_STATUS_WB,
705 .ctl_offs = SPM_WB_PWR_CON,
706 .sram_pdn_bits = 0,
707 .sram_pdn_ack_bits = 0,
708 .clk_id = {CLK_NONE},
709 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB,
710 .active_wakeup = true,
715 * MT8173 power domain support
718 static const struct scp_domain_data scp_domain_data_mt8173[] = {
719 [MT8173_POWER_DOMAIN_VDEC] = {
720 .name = "vdec",
721 .sta_mask = PWR_STATUS_VDEC,
722 .ctl_offs = SPM_VDE_PWR_CON,
723 .sram_pdn_bits = GENMASK(11, 8),
724 .sram_pdn_ack_bits = GENMASK(12, 12),
725 .clk_id = {CLK_MM},
727 [MT8173_POWER_DOMAIN_VENC] = {
728 .name = "venc",
729 .sta_mask = PWR_STATUS_VENC,
730 .ctl_offs = SPM_VEN_PWR_CON,
731 .sram_pdn_bits = GENMASK(11, 8),
732 .sram_pdn_ack_bits = GENMASK(15, 12),
733 .clk_id = {CLK_MM, CLK_VENC},
735 [MT8173_POWER_DOMAIN_ISP] = {
736 .name = "isp",
737 .sta_mask = PWR_STATUS_ISP,
738 .ctl_offs = SPM_ISP_PWR_CON,
739 .sram_pdn_bits = GENMASK(11, 8),
740 .sram_pdn_ack_bits = GENMASK(13, 12),
741 .clk_id = {CLK_MM},
743 [MT8173_POWER_DOMAIN_MM] = {
744 .name = "mm",
745 .sta_mask = PWR_STATUS_DISP,
746 .ctl_offs = SPM_DIS_PWR_CON,
747 .sram_pdn_bits = GENMASK(11, 8),
748 .sram_pdn_ack_bits = GENMASK(12, 12),
749 .clk_id = {CLK_MM},
750 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
751 MT8173_TOP_AXI_PROT_EN_MM_M1,
753 [MT8173_POWER_DOMAIN_VENC_LT] = {
754 .name = "venc_lt",
755 .sta_mask = PWR_STATUS_VENC_LT,
756 .ctl_offs = SPM_VEN2_PWR_CON,
757 .sram_pdn_bits = GENMASK(11, 8),
758 .sram_pdn_ack_bits = GENMASK(15, 12),
759 .clk_id = {CLK_MM, CLK_VENC_LT},
761 [MT8173_POWER_DOMAIN_AUDIO] = {
762 .name = "audio",
763 .sta_mask = PWR_STATUS_AUDIO,
764 .ctl_offs = SPM_AUDIO_PWR_CON,
765 .sram_pdn_bits = GENMASK(11, 8),
766 .sram_pdn_ack_bits = GENMASK(15, 12),
767 .clk_id = {CLK_NONE},
769 [MT8173_POWER_DOMAIN_USB] = {
770 .name = "usb",
771 .sta_mask = PWR_STATUS_USB,
772 .ctl_offs = SPM_USB_PWR_CON,
773 .sram_pdn_bits = GENMASK(11, 8),
774 .sram_pdn_ack_bits = GENMASK(15, 12),
775 .clk_id = {CLK_NONE},
776 .active_wakeup = true,
778 [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
779 .name = "mfg_async",
780 .sta_mask = PWR_STATUS_MFG_ASYNC,
781 .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
782 .sram_pdn_bits = GENMASK(11, 8),
783 .sram_pdn_ack_bits = 0,
784 .clk_id = {CLK_MFG},
786 [MT8173_POWER_DOMAIN_MFG_2D] = {
787 .name = "mfg_2d",
788 .sta_mask = PWR_STATUS_MFG_2D,
789 .ctl_offs = SPM_MFG_2D_PWR_CON,
790 .sram_pdn_bits = GENMASK(11, 8),
791 .sram_pdn_ack_bits = GENMASK(13, 12),
792 .clk_id = {CLK_NONE},
794 [MT8173_POWER_DOMAIN_MFG] = {
795 .name = "mfg",
796 .sta_mask = PWR_STATUS_MFG,
797 .ctl_offs = SPM_MFG_PWR_CON,
798 .sram_pdn_bits = GENMASK(13, 8),
799 .sram_pdn_ack_bits = GENMASK(21, 16),
800 .clk_id = {CLK_NONE},
801 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
802 MT8173_TOP_AXI_PROT_EN_MFG_M0 |
803 MT8173_TOP_AXI_PROT_EN_MFG_M1 |
804 MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
808 static const struct scp_subdomain scp_subdomain_mt8173[] = {
809 {MT8173_POWER_DOMAIN_MFG_ASYNC, MT8173_POWER_DOMAIN_MFG_2D},
810 {MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG},
813 static const struct scp_soc_data mt2701_data = {
814 .domains = scp_domain_data_mt2701,
815 .num_domains = ARRAY_SIZE(scp_domain_data_mt2701),
816 .regs = {
817 .pwr_sta_offs = SPM_PWR_STATUS,
818 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
822 static const struct scp_soc_data mt6797_data = {
823 .domains = scp_domain_data_mt6797,
824 .num_domains = ARRAY_SIZE(scp_domain_data_mt6797),
825 .subdomains = scp_subdomain_mt6797,
826 .num_subdomains = ARRAY_SIZE(scp_subdomain_mt6797),
827 .regs = {
828 .pwr_sta_offs = SPM_PWR_STATUS_MT6797,
829 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797
833 static const struct scp_soc_data mt7622_data = {
834 .domains = scp_domain_data_mt7622,
835 .num_domains = ARRAY_SIZE(scp_domain_data_mt7622),
836 .regs = {
837 .pwr_sta_offs = SPM_PWR_STATUS,
838 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
842 static const struct scp_soc_data mt8173_data = {
843 .domains = scp_domain_data_mt8173,
844 .num_domains = ARRAY_SIZE(scp_domain_data_mt8173),
845 .subdomains = scp_subdomain_mt8173,
846 .num_subdomains = ARRAY_SIZE(scp_subdomain_mt8173),
847 .regs = {
848 .pwr_sta_offs = SPM_PWR_STATUS,
849 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
854 * scpsys driver init
857 static const struct of_device_id of_scpsys_match_tbl[] = {
859 .compatible = "mediatek,mt2701-scpsys",
860 .data = &mt2701_data,
861 }, {
862 .compatible = "mediatek,mt6797-scpsys",
863 .data = &mt6797_data,
864 }, {
865 .compatible = "mediatek,mt7622-scpsys",
866 .data = &mt7622_data,
867 }, {
868 .compatible = "mediatek,mt8173-scpsys",
869 .data = &mt8173_data,
870 }, {
871 /* sentinel */
875 static int scpsys_probe(struct platform_device *pdev)
877 const struct of_device_id *match;
878 const struct scp_subdomain *sd;
879 const struct scp_soc_data *soc;
880 struct scp *scp;
881 struct genpd_onecell_data *pd_data;
882 int i, ret;
884 match = of_match_device(of_scpsys_match_tbl, &pdev->dev);
885 soc = (const struct scp_soc_data *)match->data;
887 scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs);
888 if (IS_ERR(scp))
889 return PTR_ERR(scp);
891 mtk_register_power_domains(pdev, scp, soc->num_domains);
893 pd_data = &scp->pd_data;
895 for (i = 0, sd = soc->subdomains ; i < soc->num_subdomains ; i++) {
896 ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin],
897 pd_data->domains[sd->subdomain]);
898 if (ret && IS_ENABLED(CONFIG_PM))
899 dev_err(&pdev->dev, "Failed to add subdomain: %d\n",
900 ret);
903 return 0;
906 static struct platform_driver scpsys_drv = {
907 .probe = scpsys_probe,
908 .driver = {
909 .name = "mtk-scpsys",
910 .suppress_bind_attrs = true,
911 .owner = THIS_MODULE,
912 .of_match_table = of_match_ptr(of_scpsys_match_tbl),
915 builtin_platform_driver(scpsys_drv);