]> Git Repo - linux.git/blob - drivers/soc/mediatek/mtk-scpsys.c
sched/deadline: Move DL related code from sched/core.c to sched/deadline.c
[linux.git] / drivers / soc / mediatek / mtk-scpsys.c
1 /*
2  * Copyright (c) 2015 Pengutronix, Sascha Hauer <[email protected]>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU General Public License for more details.
12  */
13 #include <linux/clk.h>
14 #include <linux/init.h>
15 #include <linux/io.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/of_device.h>
18 #include <linux/platform_device.h>
19 #include <linux/pm_domain.h>
20 #include <linux/regulator/consumer.h>
21 #include <linux/soc/mediatek/infracfg.h>
22
23 #include <dt-bindings/power/mt2701-power.h>
24 #include <dt-bindings/power/mt8173-power.h>
25
26 #define SPM_VDE_PWR_CON                 0x0210
27 #define SPM_MFG_PWR_CON                 0x0214
28 #define SPM_VEN_PWR_CON                 0x0230
29 #define SPM_ISP_PWR_CON                 0x0238
30 #define SPM_DIS_PWR_CON                 0x023c
31 #define SPM_CONN_PWR_CON                0x0280
32 #define SPM_VEN2_PWR_CON                0x0298
33 #define SPM_AUDIO_PWR_CON               0x029c  /* MT8173 */
34 #define SPM_BDP_PWR_CON                 0x029c  /* MT2701 */
35 #define SPM_ETH_PWR_CON                 0x02a0
36 #define SPM_HIF_PWR_CON                 0x02a4
37 #define SPM_IFR_MSC_PWR_CON             0x02a8
38 #define SPM_MFG_2D_PWR_CON              0x02c0
39 #define SPM_MFG_ASYNC_PWR_CON           0x02c4
40 #define SPM_USB_PWR_CON                 0x02cc
41
42 #define SPM_PWR_STATUS                  0x060c
43 #define SPM_PWR_STATUS_2ND              0x0610
44
45 #define PWR_RST_B_BIT                   BIT(0)
46 #define PWR_ISO_BIT                     BIT(1)
47 #define PWR_ON_BIT                      BIT(2)
48 #define PWR_ON_2ND_BIT                  BIT(3)
49 #define PWR_CLK_DIS_BIT                 BIT(4)
50
51 #define PWR_STATUS_CONN                 BIT(1)
52 #define PWR_STATUS_DISP                 BIT(3)
53 #define PWR_STATUS_MFG                  BIT(4)
54 #define PWR_STATUS_ISP                  BIT(5)
55 #define PWR_STATUS_VDEC                 BIT(7)
56 #define PWR_STATUS_BDP                  BIT(14)
57 #define PWR_STATUS_ETH                  BIT(15)
58 #define PWR_STATUS_HIF                  BIT(16)
59 #define PWR_STATUS_IFR_MSC              BIT(17)
60 #define PWR_STATUS_VENC_LT              BIT(20)
61 #define PWR_STATUS_VENC                 BIT(21)
62 #define PWR_STATUS_MFG_2D               BIT(22)
63 #define PWR_STATUS_MFG_ASYNC            BIT(23)
64 #define PWR_STATUS_AUDIO                BIT(24)
65 #define PWR_STATUS_USB                  BIT(25)
66
67 enum clk_id {
68         CLK_NONE,
69         CLK_MM,
70         CLK_MFG,
71         CLK_VENC,
72         CLK_VENC_LT,
73         CLK_ETHIF,
74         CLK_MAX,
75 };
76
77 static const char * const clk_names[] = {
78         NULL,
79         "mm",
80         "mfg",
81         "venc",
82         "venc_lt",
83         "ethif",
84         NULL,
85 };
86
87 #define MAX_CLKS        2
88
89 struct scp_domain_data {
90         const char *name;
91         u32 sta_mask;
92         int ctl_offs;
93         u32 sram_pdn_bits;
94         u32 sram_pdn_ack_bits;
95         u32 bus_prot_mask;
96         enum clk_id clk_id[MAX_CLKS];
97         bool active_wakeup;
98 };
99
100 struct scp;
101
102 struct scp_domain {
103         struct generic_pm_domain genpd;
104         struct scp *scp;
105         struct clk *clk[MAX_CLKS];
106         const struct scp_domain_data *data;
107         struct regulator *supply;
108 };
109
110 struct scp {
111         struct scp_domain *domains;
112         struct genpd_onecell_data pd_data;
113         struct device *dev;
114         void __iomem *base;
115         struct regmap *infracfg;
116 };
117
118 static int scpsys_domain_is_on(struct scp_domain *scpd)
119 {
120         struct scp *scp = scpd->scp;
121
122         u32 status = readl(scp->base + SPM_PWR_STATUS) & scpd->data->sta_mask;
123         u32 status2 = readl(scp->base + SPM_PWR_STATUS_2ND) &
124                                 scpd->data->sta_mask;
125
126         /*
127          * A domain is on when both status bits are set. If only one is set
128          * return an error. This happens while powering up a domain
129          */
130
131         if (status && status2)
132                 return true;
133         if (!status && !status2)
134                 return false;
135
136         return -EINVAL;
137 }
138
139 static int scpsys_power_on(struct generic_pm_domain *genpd)
140 {
141         struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
142         struct scp *scp = scpd->scp;
143         unsigned long timeout;
144         bool expired;
145         void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
146         u32 sram_pdn_ack = scpd->data->sram_pdn_ack_bits;
147         u32 val;
148         int ret;
149         int i;
150
151         if (scpd->supply) {
152                 ret = regulator_enable(scpd->supply);
153                 if (ret)
154                         return ret;
155         }
156
157         for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++) {
158                 ret = clk_prepare_enable(scpd->clk[i]);
159                 if (ret) {
160                         for (--i; i >= 0; i--)
161                                 clk_disable_unprepare(scpd->clk[i]);
162
163                         goto err_clk;
164                 }
165         }
166
167         val = readl(ctl_addr);
168         val |= PWR_ON_BIT;
169         writel(val, ctl_addr);
170         val |= PWR_ON_2ND_BIT;
171         writel(val, ctl_addr);
172
173         /* wait until PWR_ACK = 1 */
174         timeout = jiffies + HZ;
175         expired = false;
176         while (1) {
177                 ret = scpsys_domain_is_on(scpd);
178                 if (ret > 0)
179                         break;
180
181                 if (expired) {
182                         ret = -ETIMEDOUT;
183                         goto err_pwr_ack;
184                 }
185
186                 cpu_relax();
187
188                 if (time_after(jiffies, timeout))
189                         expired = true;
190         }
191
192         val &= ~PWR_CLK_DIS_BIT;
193         writel(val, ctl_addr);
194
195         val &= ~PWR_ISO_BIT;
196         writel(val, ctl_addr);
197
198         val |= PWR_RST_B_BIT;
199         writel(val, ctl_addr);
200
201         val &= ~scpd->data->sram_pdn_bits;
202         writel(val, ctl_addr);
203
204         /* wait until SRAM_PDN_ACK all 0 */
205         timeout = jiffies + HZ;
206         expired = false;
207         while (sram_pdn_ack && (readl(ctl_addr) & sram_pdn_ack)) {
208
209                 if (expired) {
210                         ret = -ETIMEDOUT;
211                         goto err_pwr_ack;
212                 }
213
214                 cpu_relax();
215
216                 if (time_after(jiffies, timeout))
217                         expired = true;
218         }
219
220         if (scpd->data->bus_prot_mask) {
221                 ret = mtk_infracfg_clear_bus_protection(scp->infracfg,
222                                 scpd->data->bus_prot_mask);
223                 if (ret)
224                         goto err_pwr_ack;
225         }
226
227         return 0;
228
229 err_pwr_ack:
230         for (i = MAX_CLKS - 1; i >= 0; i--) {
231                 if (scpd->clk[i])
232                         clk_disable_unprepare(scpd->clk[i]);
233         }
234 err_clk:
235         if (scpd->supply)
236                 regulator_disable(scpd->supply);
237
238         dev_err(scp->dev, "Failed to power on domain %s\n", genpd->name);
239
240         return ret;
241 }
242
243 static int scpsys_power_off(struct generic_pm_domain *genpd)
244 {
245         struct scp_domain *scpd = container_of(genpd, struct scp_domain, genpd);
246         struct scp *scp = scpd->scp;
247         unsigned long timeout;
248         bool expired;
249         void __iomem *ctl_addr = scp->base + scpd->data->ctl_offs;
250         u32 pdn_ack = scpd->data->sram_pdn_ack_bits;
251         u32 val;
252         int ret;
253         int i;
254
255         if (scpd->data->bus_prot_mask) {
256                 ret = mtk_infracfg_set_bus_protection(scp->infracfg,
257                                 scpd->data->bus_prot_mask);
258                 if (ret)
259                         goto out;
260         }
261
262         val = readl(ctl_addr);
263         val |= scpd->data->sram_pdn_bits;
264         writel(val, ctl_addr);
265
266         /* wait until SRAM_PDN_ACK all 1 */
267         timeout = jiffies + HZ;
268         expired = false;
269         while (pdn_ack && (readl(ctl_addr) & pdn_ack) != pdn_ack) {
270                 if (expired) {
271                         ret = -ETIMEDOUT;
272                         goto out;
273                 }
274
275                 cpu_relax();
276
277                 if (time_after(jiffies, timeout))
278                         expired = true;
279         }
280
281         val |= PWR_ISO_BIT;
282         writel(val, ctl_addr);
283
284         val &= ~PWR_RST_B_BIT;
285         writel(val, ctl_addr);
286
287         val |= PWR_CLK_DIS_BIT;
288         writel(val, ctl_addr);
289
290         val &= ~PWR_ON_BIT;
291         writel(val, ctl_addr);
292
293         val &= ~PWR_ON_2ND_BIT;
294         writel(val, ctl_addr);
295
296         /* wait until PWR_ACK = 0 */
297         timeout = jiffies + HZ;
298         expired = false;
299         while (1) {
300                 ret = scpsys_domain_is_on(scpd);
301                 if (ret == 0)
302                         break;
303
304                 if (expired) {
305                         ret = -ETIMEDOUT;
306                         goto out;
307                 }
308
309                 cpu_relax();
310
311                 if (time_after(jiffies, timeout))
312                         expired = true;
313         }
314
315         for (i = 0; i < MAX_CLKS && scpd->clk[i]; i++)
316                 clk_disable_unprepare(scpd->clk[i]);
317
318         if (scpd->supply)
319                 regulator_disable(scpd->supply);
320
321         return 0;
322
323 out:
324         dev_err(scp->dev, "Failed to power off domain %s\n", genpd->name);
325
326         return ret;
327 }
328
329 static bool scpsys_active_wakeup(struct device *dev)
330 {
331         struct generic_pm_domain *genpd;
332         struct scp_domain *scpd;
333
334         genpd = pd_to_genpd(dev->pm_domain);
335         scpd = container_of(genpd, struct scp_domain, genpd);
336
337         return scpd->data->active_wakeup;
338 }
339
340 static void init_clks(struct platform_device *pdev, struct clk **clk)
341 {
342         int i;
343
344         for (i = CLK_NONE + 1; i < CLK_MAX; i++)
345                 clk[i] = devm_clk_get(&pdev->dev, clk_names[i]);
346 }
347
348 static struct scp *init_scp(struct platform_device *pdev,
349                         const struct scp_domain_data *scp_domain_data, int num)
350 {
351         struct genpd_onecell_data *pd_data;
352         struct resource *res;
353         int i, j;
354         struct scp *scp;
355         struct clk *clk[CLK_MAX];
356
357         scp = devm_kzalloc(&pdev->dev, sizeof(*scp), GFP_KERNEL);
358         if (!scp)
359                 return ERR_PTR(-ENOMEM);
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                 genpd->dev_ops.active_wakeup = scpsys_active_wakeup;
431         }
432
433         return scp;
434 }
435
436 static void mtk_register_power_domains(struct platform_device *pdev,
437                                 struct scp *scp, int num)
438 {
439         struct genpd_onecell_data *pd_data;
440         int i, ret;
441
442         for (i = 0; i < num; i++) {
443                 struct scp_domain *scpd = &scp->domains[i];
444                 struct generic_pm_domain *genpd = &scpd->genpd;
445
446                 /*
447                  * Initially turn on all domains to make the domains usable
448                  * with !CONFIG_PM and to get the hardware in sync with the
449                  * software.  The unused domains will be switched off during
450                  * late_init time.
451                  */
452                 genpd->power_on(genpd);
453
454                 pm_genpd_init(genpd, NULL, false);
455         }
456
457         /*
458          * We are not allowed to fail here since there is no way to unregister
459          * a power domain. Once registered above we have to keep the domains
460          * valid.
461          */
462
463         pd_data = &scp->pd_data;
464
465         ret = of_genpd_add_provider_onecell(pdev->dev.of_node, pd_data);
466         if (ret)
467                 dev_err(&pdev->dev, "Failed to add OF provider: %d\n", ret);
468 }
469
470 /*
471  * MT2701 power domain support
472  */
473
474 static const struct scp_domain_data scp_domain_data_mt2701[] = {
475         [MT2701_POWER_DOMAIN_CONN] = {
476                 .name = "conn",
477                 .sta_mask = PWR_STATUS_CONN,
478                 .ctl_offs = SPM_CONN_PWR_CON,
479                 .bus_prot_mask = 0x0104,
480                 .clk_id = {CLK_NONE},
481                 .active_wakeup = true,
482         },
483         [MT2701_POWER_DOMAIN_DISP] = {
484                 .name = "disp",
485                 .sta_mask = PWR_STATUS_DISP,
486                 .ctl_offs = SPM_DIS_PWR_CON,
487                 .sram_pdn_bits = GENMASK(11, 8),
488                 .clk_id = {CLK_MM},
489                 .bus_prot_mask = 0x0002,
490                 .active_wakeup = true,
491         },
492         [MT2701_POWER_DOMAIN_MFG] = {
493                 .name = "mfg",
494                 .sta_mask = PWR_STATUS_MFG,
495                 .ctl_offs = SPM_MFG_PWR_CON,
496                 .sram_pdn_bits = GENMASK(11, 8),
497                 .sram_pdn_ack_bits = GENMASK(12, 12),
498                 .clk_id = {CLK_MFG},
499                 .active_wakeup = true,
500         },
501         [MT2701_POWER_DOMAIN_VDEC] = {
502                 .name = "vdec",
503                 .sta_mask = PWR_STATUS_VDEC,
504                 .ctl_offs = SPM_VDE_PWR_CON,
505                 .sram_pdn_bits = GENMASK(11, 8),
506                 .sram_pdn_ack_bits = GENMASK(12, 12),
507                 .clk_id = {CLK_MM},
508                 .active_wakeup = true,
509         },
510         [MT2701_POWER_DOMAIN_ISP] = {
511                 .name = "isp",
512                 .sta_mask = PWR_STATUS_ISP,
513                 .ctl_offs = SPM_ISP_PWR_CON,
514                 .sram_pdn_bits = GENMASK(11, 8),
515                 .sram_pdn_ack_bits = GENMASK(13, 12),
516                 .clk_id = {CLK_MM},
517                 .active_wakeup = true,
518         },
519         [MT2701_POWER_DOMAIN_BDP] = {
520                 .name = "bdp",
521                 .sta_mask = PWR_STATUS_BDP,
522                 .ctl_offs = SPM_BDP_PWR_CON,
523                 .sram_pdn_bits = GENMASK(11, 8),
524                 .clk_id = {CLK_NONE},
525                 .active_wakeup = true,
526         },
527         [MT2701_POWER_DOMAIN_ETH] = {
528                 .name = "eth",
529                 .sta_mask = PWR_STATUS_ETH,
530                 .ctl_offs = SPM_ETH_PWR_CON,
531                 .sram_pdn_bits = GENMASK(11, 8),
532                 .sram_pdn_ack_bits = GENMASK(15, 12),
533                 .clk_id = {CLK_ETHIF},
534                 .active_wakeup = true,
535         },
536         [MT2701_POWER_DOMAIN_HIF] = {
537                 .name = "hif",
538                 .sta_mask = PWR_STATUS_HIF,
539                 .ctl_offs = SPM_HIF_PWR_CON,
540                 .sram_pdn_bits = GENMASK(11, 8),
541                 .sram_pdn_ack_bits = GENMASK(15, 12),
542                 .clk_id = {CLK_ETHIF},
543                 .active_wakeup = true,
544         },
545         [MT2701_POWER_DOMAIN_IFR_MSC] = {
546                 .name = "ifr_msc",
547                 .sta_mask = PWR_STATUS_IFR_MSC,
548                 .ctl_offs = SPM_IFR_MSC_PWR_CON,
549                 .clk_id = {CLK_NONE},
550                 .active_wakeup = true,
551         },
552 };
553
554 #define NUM_DOMAINS_MT2701      ARRAY_SIZE(scp_domain_data_mt2701)
555
556 static int __init scpsys_probe_mt2701(struct platform_device *pdev)
557 {
558         struct scp *scp;
559
560         scp = init_scp(pdev, scp_domain_data_mt2701, NUM_DOMAINS_MT2701);
561         if (IS_ERR(scp))
562                 return PTR_ERR(scp);
563
564         mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT2701);
565
566         return 0;
567 }
568
569 /*
570  * MT8173 power domain support
571  */
572
573 static const struct scp_domain_data scp_domain_data_mt8173[] = {
574         [MT8173_POWER_DOMAIN_VDEC] = {
575                 .name = "vdec",
576                 .sta_mask = PWR_STATUS_VDEC,
577                 .ctl_offs = SPM_VDE_PWR_CON,
578                 .sram_pdn_bits = GENMASK(11, 8),
579                 .sram_pdn_ack_bits = GENMASK(12, 12),
580                 .clk_id = {CLK_MM},
581         },
582         [MT8173_POWER_DOMAIN_VENC] = {
583                 .name = "venc",
584                 .sta_mask = PWR_STATUS_VENC,
585                 .ctl_offs = SPM_VEN_PWR_CON,
586                 .sram_pdn_bits = GENMASK(11, 8),
587                 .sram_pdn_ack_bits = GENMASK(15, 12),
588                 .clk_id = {CLK_MM, CLK_VENC},
589         },
590         [MT8173_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         },
598         [MT8173_POWER_DOMAIN_MM] = {
599                 .name = "mm",
600                 .sta_mask = PWR_STATUS_DISP,
601                 .ctl_offs = SPM_DIS_PWR_CON,
602                 .sram_pdn_bits = GENMASK(11, 8),
603                 .sram_pdn_ack_bits = GENMASK(12, 12),
604                 .clk_id = {CLK_MM},
605                 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MM_M0 |
606                         MT8173_TOP_AXI_PROT_EN_MM_M1,
607         },
608         [MT8173_POWER_DOMAIN_VENC_LT] = {
609                 .name = "venc_lt",
610                 .sta_mask = PWR_STATUS_VENC_LT,
611                 .ctl_offs = SPM_VEN2_PWR_CON,
612                 .sram_pdn_bits = GENMASK(11, 8),
613                 .sram_pdn_ack_bits = GENMASK(15, 12),
614                 .clk_id = {CLK_MM, CLK_VENC_LT},
615         },
616         [MT8173_POWER_DOMAIN_AUDIO] = {
617                 .name = "audio",
618                 .sta_mask = PWR_STATUS_AUDIO,
619                 .ctl_offs = SPM_AUDIO_PWR_CON,
620                 .sram_pdn_bits = GENMASK(11, 8),
621                 .sram_pdn_ack_bits = GENMASK(15, 12),
622                 .clk_id = {CLK_NONE},
623         },
624         [MT8173_POWER_DOMAIN_USB] = {
625                 .name = "usb",
626                 .sta_mask = PWR_STATUS_USB,
627                 .ctl_offs = SPM_USB_PWR_CON,
628                 .sram_pdn_bits = GENMASK(11, 8),
629                 .sram_pdn_ack_bits = GENMASK(15, 12),
630                 .clk_id = {CLK_NONE},
631                 .active_wakeup = true,
632         },
633         [MT8173_POWER_DOMAIN_MFG_ASYNC] = {
634                 .name = "mfg_async",
635                 .sta_mask = PWR_STATUS_MFG_ASYNC,
636                 .ctl_offs = SPM_MFG_ASYNC_PWR_CON,
637                 .sram_pdn_bits = GENMASK(11, 8),
638                 .sram_pdn_ack_bits = 0,
639                 .clk_id = {CLK_MFG},
640         },
641         [MT8173_POWER_DOMAIN_MFG_2D] = {
642                 .name = "mfg_2d",
643                 .sta_mask = PWR_STATUS_MFG_2D,
644                 .ctl_offs = SPM_MFG_2D_PWR_CON,
645                 .sram_pdn_bits = GENMASK(11, 8),
646                 .sram_pdn_ack_bits = GENMASK(13, 12),
647                 .clk_id = {CLK_NONE},
648         },
649         [MT8173_POWER_DOMAIN_MFG] = {
650                 .name = "mfg",
651                 .sta_mask = PWR_STATUS_MFG,
652                 .ctl_offs = SPM_MFG_PWR_CON,
653                 .sram_pdn_bits = GENMASK(13, 8),
654                 .sram_pdn_ack_bits = GENMASK(21, 16),
655                 .clk_id = {CLK_NONE},
656                 .bus_prot_mask = MT8173_TOP_AXI_PROT_EN_MFG_S |
657                         MT8173_TOP_AXI_PROT_EN_MFG_M0 |
658                         MT8173_TOP_AXI_PROT_EN_MFG_M1 |
659                         MT8173_TOP_AXI_PROT_EN_MFG_SNOOP_OUT,
660         },
661 };
662
663 #define NUM_DOMAINS_MT8173      ARRAY_SIZE(scp_domain_data_mt8173)
664
665 static int __init scpsys_probe_mt8173(struct platform_device *pdev)
666 {
667         struct scp *scp;
668         struct genpd_onecell_data *pd_data;
669         int ret;
670
671         scp = init_scp(pdev, scp_domain_data_mt8173, NUM_DOMAINS_MT8173);
672         if (IS_ERR(scp))
673                 return PTR_ERR(scp);
674
675         mtk_register_power_domains(pdev, scp, NUM_DOMAINS_MT8173);
676
677         pd_data = &scp->pd_data;
678
679         ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_ASYNC],
680                 pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D]);
681         if (ret && IS_ENABLED(CONFIG_PM))
682                 dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
683
684         ret = pm_genpd_add_subdomain(pd_data->domains[MT8173_POWER_DOMAIN_MFG_2D],
685                 pd_data->domains[MT8173_POWER_DOMAIN_MFG]);
686         if (ret && IS_ENABLED(CONFIG_PM))
687                 dev_err(&pdev->dev, "Failed to add subdomain: %d\n", ret);
688
689         return 0;
690 }
691
692 /*
693  * scpsys driver init
694  */
695
696 static const struct of_device_id of_scpsys_match_tbl[] = {
697         {
698                 .compatible = "mediatek,mt2701-scpsys",
699                 .data = scpsys_probe_mt2701,
700         }, {
701                 .compatible = "mediatek,mt8173-scpsys",
702                 .data = scpsys_probe_mt8173,
703         }, {
704                 /* sentinel */
705         }
706 };
707
708 static int scpsys_probe(struct platform_device *pdev)
709 {
710         int (*probe)(struct platform_device *);
711         const struct of_device_id *of_id;
712
713         of_id = of_match_node(of_scpsys_match_tbl, pdev->dev.of_node);
714         if (!of_id || !of_id->data)
715                 return -EINVAL;
716
717         probe = of_id->data;
718
719         return probe(pdev);
720 }
721
722 static struct platform_driver scpsys_drv = {
723         .probe = scpsys_probe,
724         .driver = {
725                 .name = "mtk-scpsys",
726                 .suppress_bind_attrs = true,
727                 .owner = THIS_MODULE,
728                 .of_match_table = of_match_ptr(of_scpsys_match_tbl),
729         },
730 };
731 builtin_platform_driver(scpsys_drv);
This page took 0.074258 seconds and 4 git commands to generate.