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