mei: me: add cannon point device ids
[linux/fpc-iii.git] / drivers / soc / mediatek / mtk-scpsys.c
blobe570b6af2e6ffbddccf1fe76075375d4e39e3e0c
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 void init_clks(struct platform_device *pdev, struct clk **clk)
366 int i;
368 for (i = CLK_NONE + 1; i < CLK_MAX; i++)
369 clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
372 static struct scp *init_scp(struct platform_device *pdev,
373 const struct scp_domain_data *scp_domain_data, int num,
374 const struct scp_ctrl_reg *scp_ctrl_reg)
376 struct genpd_onecell_data *pd_data;
377 struct resource *res;
378 int i, j;
379 struct scp *scp;
380 struct clk *clk[CLK_MAX];
382 scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
383 if (!scp)
384 return ERR_PTR(-ENOMEM);
386 scp->ctrl_reg.pwr_sta_offs = scp_ctrl_reg->pwr_sta_offs;
387 scp->ctrl_reg.pwr_sta2nd_offs = scp_ctrl_reg->pwr_sta2nd_offs;
389 scp->dev = &pdev->dev;
391 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
392 scp->base = devm_ioremap_resource(&pdev->dev, res);
393 if (IS_ERR(scp->base))
394 return ERR_CAST(scp->base);
396 scp->domains = devm_kzalloc(&pdev->dev,
397 sizeof(*scp->domains) * num, GFP_KERNEL);
398 if (!scp->domains)
399 return ERR_PTR(-ENOMEM);
401 pd_data = &scp->pd_data;
403 pd_data->domains = devm_kzalloc(&pdev->dev,
404 sizeof(*pd_data->domains) * num, GFP_KERNEL);
405 if (!pd_data->domains)
406 return ERR_PTR(-ENOMEM);
408 scp->infracfg = syscon_regmap_lookup_by_phandle(pdev->dev.of_node,
409 "infracfg");
410 if (IS_ERR(scp->infracfg)) {
411 dev_err(&pdev->dev, "Cannot find infracfg controller: %ld\n",
412 PTR_ERR(scp->infracfg));
413 return ERR_CAST(scp->infracfg);
416 for (i = 0; i < num; i++) {
417 struct scp_domain *scpd = &scp->domains[i];
418 const struct scp_domain_data *data = &scp_domain_data[i];
420 scpd->supply = devm_regulator_get_optional(&pdev->dev, data->name);
421 if (IS_ERR(scpd->supply)) {
422 if (PTR_ERR(scpd->supply) == -ENODEV)
423 scpd->supply = NULL;
424 else
425 return ERR_CAST(scpd->supply);
429 pd_data->num_domains = num;
431 init_clks(pdev, clk);
433 for (i = 0; i < num; i++) {
434 struct scp_domain *scpd = &scp->domains[i];
435 struct generic_pm_domain *genpd = &scpd->genpd;
436 const struct scp_domain_data *data = &scp_domain_data[i];
438 pd_data->domains[i] = genpd;
439 scpd->scp = scp;
441 scpd->data = data;
443 for (j = 0; j < MAX_CLKS && data->clk_id[j]; j++) {
444 struct clk *c = clk[data->clk_id[j]];
446 if (IS_ERR(c)) {
447 dev_err(&pdev->dev, "%s: clk unavailable\n",
448 data->name);
449 return ERR_CAST(c);
452 scpd->clk[j] = c;
455 genpd->name = data->name;
456 genpd->power_off = scpsys_power_off;
457 genpd->power_on = scpsys_power_on;
458 if (scpd->data->active_wakeup)
459 genpd->flags |= GENPD_FLAG_ACTIVE_WAKEUP;
462 return scp;
465 static void mtk_register_power_domains(struct platform_device *pdev,
466 struct scp *scp, int num)
468 struct genpd_onecell_data *pd_data;
469 int i, ret;
471 for (i = 0; i < num; i++) {
472 struct scp_domain *scpd = &scp->domains[i];
473 struct generic_pm_domain *genpd = &scpd->genpd;
476 * Initially turn on all domains to make the domains usable
477 * with !CONFIG_PM and to get the hardware in sync with the
478 * software. The unused domains will be switched off during
479 * late_init time.
481 genpd->power_on(genpd);
483 pm_genpd_init(genpd, NULL, false);
487 * We are not allowed to fail here since there is no way to unregister
488 * a power domain. Once registered above we have to keep the domains
489 * valid.
492 pd_data = &scp->pd_data;
494 ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
495 if (ret)
496 dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
500 * MT2701 power domain support
503 static const struct scp_domain_data scp_domain_data_mt2701[] = {
504 [MT2701_POWER_DOMAIN_CONN] = {
505 .name = "conn",
506 .sta_mask = PWR_STATUS_CONN,
507 .ctl_offs = SPM_CONN_PWR_CON,
508 .bus_prot_mask = 0x0104,
509 .clk_id = {CLK_NONE},
510 .active_wakeup = true,
512 [MT2701_POWER_DOMAIN_DISP] = {
513 .name = "disp",
514 .sta_mask = PWR_STATUS_DISP,
515 .ctl_offs = SPM_DIS_PWR_CON,
516 .sram_pdn_bits = GENMASK(11, 8),
517 .clk_id = {CLK_MM},
518 .bus_prot_mask = 0x0002,
519 .active_wakeup = true,
521 [MT2701_POWER_DOMAIN_MFG] = {
522 .name = "mfg",
523 .sta_mask = PWR_STATUS_MFG,
524 .ctl_offs = SPM_MFG_PWR_CON,
525 .sram_pdn_bits = GENMASK(11, 8),
526 .sram_pdn_ack_bits = GENMASK(12, 12),
527 .clk_id = {CLK_MFG},
528 .active_wakeup = true,
530 [MT2701_POWER_DOMAIN_VDEC] = {
531 .name = "vdec",
532 .sta_mask = PWR_STATUS_VDEC,
533 .ctl_offs = SPM_VDE_PWR_CON,
534 .sram_pdn_bits = GENMASK(11, 8),
535 .sram_pdn_ack_bits = GENMASK(12, 12),
536 .clk_id = {CLK_MM},
537 .active_wakeup = true,
539 [MT2701_POWER_DOMAIN_ISP] = {
540 .name = "isp",
541 .sta_mask = PWR_STATUS_ISP,
542 .ctl_offs = SPM_ISP_PWR_CON,
543 .sram_pdn_bits = GENMASK(11, 8),
544 .sram_pdn_ack_bits = GENMASK(13, 12),
545 .clk_id = {CLK_MM},
546 .active_wakeup = true,
548 [MT2701_POWER_DOMAIN_BDP] = {
549 .name = "bdp",
550 .sta_mask = PWR_STATUS_BDP,
551 .ctl_offs = SPM_BDP_PWR_CON,
552 .sram_pdn_bits = GENMASK(11, 8),
553 .clk_id = {CLK_NONE},
554 .active_wakeup = true,
556 [MT2701_POWER_DOMAIN_ETH] = {
557 .name = "eth",
558 .sta_mask = PWR_STATUS_ETH,
559 .ctl_offs = SPM_ETH_PWR_CON,
560 .sram_pdn_bits = GENMASK(11, 8),
561 .sram_pdn_ack_bits = GENMASK(15, 12),
562 .clk_id = {CLK_ETHIF},
563 .active_wakeup = true,
565 [MT2701_POWER_DOMAIN_HIF] = {
566 .name = "hif",
567 .sta_mask = PWR_STATUS_HIF,
568 .ctl_offs = SPM_HIF_PWR_CON,
569 .sram_pdn_bits = GENMASK(11, 8),
570 .sram_pdn_ack_bits = GENMASK(15, 12),
571 .clk_id = {CLK_ETHIF},
572 .active_wakeup = true,
574 [MT2701_POWER_DOMAIN_IFR_MSC] = {
575 .name = "ifr_msc",
576 .sta_mask = PWR_STATUS_IFR_MSC,
577 .ctl_offs = SPM_IFR_MSC_PWR_CON,
578 .clk_id = {CLK_NONE},
579 .active_wakeup = true,
584 * MT6797 power domain support
587 static const struct scp_domain_data scp_domain_data_mt6797[] = {
588 [MT6797_POWER_DOMAIN_VDEC] = {
589 .name = "vdec",
590 .sta_mask = BIT(7),
591 .ctl_offs = 0x300,
592 .sram_pdn_bits = GENMASK(8, 8),
593 .sram_pdn_ack_bits = GENMASK(12, 12),
594 .clk_id = {CLK_VDEC},
596 [MT6797_POWER_DOMAIN_VENC] = {
597 .name = "venc",
598 .sta_mask = BIT(21),
599 .ctl_offs = 0x304,
600 .sram_pdn_bits = GENMASK(11, 8),
601 .sram_pdn_ack_bits = GENMASK(15, 12),
602 .clk_id = {CLK_NONE},
604 [MT6797_POWER_DOMAIN_ISP] = {
605 .name = "isp",
606 .sta_mask = BIT(5),
607 .ctl_offs = 0x308,
608 .sram_pdn_bits = GENMASK(9, 8),
609 .sram_pdn_ack_bits = GENMASK(13, 12),
610 .clk_id = {CLK_NONE},
612 [MT6797_POWER_DOMAIN_MM] = {
613 .name = "mm",
614 .sta_mask = BIT(3),
615 .ctl_offs = 0x30C,
616 .sram_pdn_bits = GENMASK(8, 8),
617 .sram_pdn_ack_bits = GENMASK(12, 12),
618 .clk_id = {CLK_MM},
619 .bus_prot_mask = (BIT(1) | BIT(2)),
621 [MT6797_POWER_DOMAIN_AUDIO] = {
622 .name = "audio",
623 .sta_mask = BIT(24),
624 .ctl_offs = 0x314,
625 .sram_pdn_bits = GENMASK(11, 8),
626 .sram_pdn_ack_bits = GENMASK(15, 12),
627 .clk_id = {CLK_NONE},
629 [MT6797_POWER_DOMAIN_MFG_ASYNC] = {
630 .name = "mfg_async",
631 .sta_mask = BIT(13),
632 .ctl_offs = 0x334,
633 .sram_pdn_bits = 0,
634 .sram_pdn_ack_bits = 0,
635 .clk_id = {CLK_MFG},
637 [MT6797_POWER_DOMAIN_MJC] = {
638 .name = "mjc",
639 .sta_mask = BIT(20),
640 .ctl_offs = 0x310,
641 .sram_pdn_bits = GENMASK(8, 8),
642 .sram_pdn_ack_bits = GENMASK(12, 12),
643 .clk_id = {CLK_NONE},
647 #define SPM_PWR_STATUS_MT6797 0x0180
648 #define SPM_PWR_STATUS_2ND_MT6797 0x0184
650 static const struct scp_subdomain scp_subdomain_mt6797[] = {
651 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VDEC},
652 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_ISP},
653 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_VENC},
654 {MT6797_POWER_DOMAIN_MM, MT6797_POWER_DOMAIN_MJC},
658 * MT7622 power domain support
661 static const struct scp_domain_data scp_domain_data_mt7622[] = {
662 [MT7622_POWER_DOMAIN_ETHSYS] = {
663 .name = "ethsys",
664 .sta_mask = PWR_STATUS_ETHSYS,
665 .ctl_offs = SPM_ETHSYS_PWR_CON,
666 .sram_pdn_bits = GENMASK(11, 8),
667 .sram_pdn_ack_bits = GENMASK(15, 12),
668 .clk_id = {CLK_NONE},
669 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_ETHSYS,
670 .active_wakeup = true,
672 [MT7622_POWER_DOMAIN_HIF0] = {
673 .name = "hif0",
674 .sta_mask = PWR_STATUS_HIF0,
675 .ctl_offs = SPM_HIF0_PWR_CON,
676 .sram_pdn_bits = GENMASK(11, 8),
677 .sram_pdn_ack_bits = GENMASK(15, 12),
678 .clk_id = {CLK_HIFSEL},
679 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_HIF0,
680 .active_wakeup = true,
682 [MT7622_POWER_DOMAIN_HIF1] = {
683 .name = "hif1",
684 .sta_mask = PWR_STATUS_HIF1,
685 .ctl_offs = SPM_HIF1_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_HIF1,
690 .active_wakeup = true,
692 [MT7622_POWER_DOMAIN_WB] = {
693 .name = "wb",
694 .sta_mask = PWR_STATUS_WB,
695 .ctl_offs = SPM_WB_PWR_CON,
696 .sram_pdn_bits = 0,
697 .sram_pdn_ack_bits = 0,
698 .clk_id = {CLK_NONE},
699 .bus_prot_mask = MT7622_TOP_AXI_PROT_EN_WB,
700 .active_wakeup = true,
705 * MT8173 power domain support
708 static const struct scp_domain_data scp_domain_data_mt8173[] = {
709 [MT8173_POWER_DOMAIN_VDEC] = {
710 .name = "vdec",
711 .sta_mask = PWR_STATUS_VDEC,
712 .ctl_offs = SPM_VDE_PWR_CON,
713 .sram_pdn_bits = GENMASK(11, 8),
714 .sram_pdn_ack_bits = GENMASK(12, 12),
715 .clk_id = {CLK_MM},
717 [MT8173_POWER_DOMAIN_VENC] = {
718 .name = "venc",
719 .sta_mask = PWR_STATUS_VENC,
720 .ctl_offs = SPM_VEN_PWR_CON,
721 .sram_pdn_bits = GENMASK(11, 8),
722 .sram_pdn_ack_bits = GENMASK(15, 12),
723 .clk_id = {CLK_MM, CLK_VENC},
725 [MT8173_POWER_DOMAIN_ISP] = {
726 .name = "isp",
727 .sta_mask = PWR_STATUS_ISP,
728 .ctl_offs = SPM_ISP_PWR_CON,
729 .sram_pdn_bits = GENMASK(11, 8),
730 .sram_pdn_ack_bits = GENMASK(13, 12),
731 .clk_id = {CLK_MM},
733 [MT8173_POWER_DOMAIN_MM] = {
734 .name = "mm",
735 .sta_mask = PWR_STATUS_DISP,
736 .ctl_offs = SPM_DIS_PWR_CON,
737 .sram_pdn_bits = GENMASK(11, 8),
738 .sram_pdn_ack_bits = GENMASK(12, 12),
739 .clk_id = {CLK_MM},
740 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
741 MT8173_TOP_AXI_PROT_EN_MM_M1,
743 [MT8173_POWER_DOMAIN_VENC_LT] = {
744 .name = "venc_lt",
745 .sta_mask = PWR_STATUS_VENC_LT,
746 .ctl_offs = SPM_VEN2_PWR_CON,
747 .sram_pdn_bits = GENMASK(11, 8),
748 .sram_pdn_ack_bits = GENMASK(15, 12),
749 .clk_id = {CLK_MM, CLK_VENC_LT},
751 [MT8173_POWER_DOMAIN_AUDIO] = {
752 .name = "audio",
753 .sta_mask = PWR_STATUS_AUDIO,
754 .ctl_offs = SPM_AUDIO_PWR_CON,
755 .sram_pdn_bits = GENMASK(11, 8),
756 .sram_pdn_ack_bits = GENMASK(15, 12),
757 .clk_id = {CLK_NONE},
759 [MT8173_POWER_DOMAIN_USB] = {
760 .name = "usb",
761 .sta_mask = PWR_STATUS_USB,
762 .ctl_offs = SPM_USB_PWR_CON,
763 .sram_pdn_bits = GENMASK(11, 8),
764 .sram_pdn_ack_bits = GENMASK(15, 12),
765 .clk_id = {CLK_NONE},
766 .active_wakeup = true,
768 [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
769 .name = "mfg_async",
770 .sta_mask = PWR_STATUS_MFG_ASYNC,
771 .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
772 .sram_pdn_bits = GENMASK(11, 8),
773 .sram_pdn_ack_bits = 0,
774 .clk_id = {CLK_MFG},
776 [MT8173_POWER_DOMAIN_MFG_2D] = {
777 .name = "mfg_2d",
778 .sta_mask = PWR_STATUS_MFG_2D,
779 .ctl_offs = SPM_MFG_2D_PWR_CON,
780 .sram_pdn_bits = GENMASK(11, 8),
781 .sram_pdn_ack_bits = GENMASK(13, 12),
782 .clk_id = {CLK_NONE},
784 [MT8173_POWER_DOMAIN_MFG] = {
785 .name = "mfg",
786 .sta_mask = PWR_STATUS_MFG,
787 .ctl_offs = SPM_MFG_PWR_CON,
788 .sram_pdn_bits = GENMASK(13, 8),
789 .sram_pdn_ack_bits = GENMASK(21, 16),
790 .clk_id = {CLK_NONE},
791 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
792 MT8173_TOP_AXI_PROT_EN_MFG_M0 |
793 MT8173_TOP_AXI_PROT_EN_MFG_M1 |
794 MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
798 static const struct scp_subdomain scp_subdomain_mt8173[] = {
799 {MT8173_POWER_DOMAIN_MFG_ASYNC, MT8173_POWER_DOMAIN_MFG_2D},
800 {MT8173_POWER_DOMAIN_MFG_2D, MT8173_POWER_DOMAIN_MFG},
803 static const struct scp_soc_data mt2701_data = {
804 .domains = scp_domain_data_mt2701,
805 .num_domains = ARRAY_SIZE(scp_domain_data_mt2701),
806 .regs = {
807 .pwr_sta_offs = SPM_PWR_STATUS,
808 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
812 static const struct scp_soc_data mt6797_data = {
813 .domains = scp_domain_data_mt6797,
814 .num_domains = ARRAY_SIZE(scp_domain_data_mt6797),
815 .subdomains = scp_subdomain_mt6797,
816 .num_subdomains = ARRAY_SIZE(scp_subdomain_mt6797),
817 .regs = {
818 .pwr_sta_offs = SPM_PWR_STATUS_MT6797,
819 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND_MT6797
823 static const struct scp_soc_data mt7622_data = {
824 .domains = scp_domain_data_mt7622,
825 .num_domains = ARRAY_SIZE(scp_domain_data_mt7622),
826 .regs = {
827 .pwr_sta_offs = SPM_PWR_STATUS,
828 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
832 static const struct scp_soc_data mt8173_data = {
833 .domains = scp_domain_data_mt8173,
834 .num_domains = ARRAY_SIZE(scp_domain_data_mt8173),
835 .subdomains = scp_subdomain_mt8173,
836 .num_subdomains = ARRAY_SIZE(scp_subdomain_mt8173),
837 .regs = {
838 .pwr_sta_offs = SPM_PWR_STATUS,
839 .pwr_sta2nd_offs = SPM_PWR_STATUS_2ND
844 * scpsys driver init
847 static const struct of_device_id of_scpsys_match_tbl[] = {
849 .compatible = "mediatek,mt2701-scpsys",
850 .data = &mt2701_data,
851 }, {
852 .compatible = "mediatek,mt6797-scpsys",
853 .data = &mt6797_data,
854 }, {
855 .compatible = "mediatek,mt7622-scpsys",
856 .data = &mt7622_data,
857 }, {
858 .compatible = "mediatek,mt8173-scpsys",
859 .data = &mt8173_data,
860 }, {
861 /* sentinel */
865 static int scpsys_probe(struct platform_device *pdev)
867 const struct of_device_id *match;
868 const struct scp_subdomain *sd;
869 const struct scp_soc_data *soc;
870 struct scp *scp;
871 struct genpd_onecell_data *pd_data;
872 int i, ret;
874 match = of_match_device(of_scpsys_match_tbl, &pdev->dev);
875 soc = (const struct scp_soc_data *)match->data;
877 scp = init_scp(pdev, soc->domains, soc->num_domains, &soc->regs);
878 if (IS_ERR(scp))
879 return PTR_ERR(scp);
881 mtk_register_power_domains(pdev, scp, soc->num_domains);
883 pd_data = &scp->pd_data;
885 for (i = 0, sd = soc->subdomains ; i < soc->num_subdomains ; i++) {
886 ret = pm_genpd_add_subdomain(pd_data->domains[sd->origin],
887 pd_data->domains[sd->subdomain]);
888 if (ret && IS_ENABLED(CONFIG_PM))
889 dev_err(&pdev->dev, "Failed to add subdomain: %d\n",
890 ret);
893 return 0;
896 static struct platform_driver scpsys_drv = {
897 .probe = scpsys_probe,
898 .driver = {
899 .name = "mtk-scpsys",
900 .suppress_bind_attrs = true,
901 .owner = THIS_MODULE,
902 .of_match_table = of_match_ptr(of_scpsys_match_tbl),
905 builtin_platform_driver(scpsys_drv);