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