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