1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright 2017 NXP
4  */
5 
6 #include <common.h>
7 #include <clk.h>
8 #include <dm.h>
9 #include <malloc.h>
10 #include <power-domain-uclass.h>
11 #include <asm/global_data.h>
12 #include <asm/io.h>
13 #include <asm/mach-imx/sys_proto.h>
14 #include <dm/device-internal.h>
15 #include <dm/device.h>
16 #include <dm/device_compat.h>
17 #include <imx_sip.h>
18 #include <linux/bitmap.h>
19 #include <wait_bit.h>
20 
21 #include <dt-bindings/power/imx8mm-power.h>
22 #include <dt-bindings/power/imx8mn-power.h>
23 #include <dt-bindings/power/imx8mp-power.h>
24 #include <dt-bindings/power/imx8mq-power.h>
25 
26 DECLARE_GLOBAL_DATA_PTR;
27 
28 #define GPC_PGC_CPU_MAPPING			0x0ec
29 #define IMX8MP_GPC_PGC_CPU_MAPPING		0x1cc
30 
31 #define IMX8M_PCIE2_A53_DOMAIN			BIT(15)
32 #define IMX8M_OTG2_A53_DOMAIN			BIT(5)
33 #define IMX8M_OTG1_A53_DOMAIN			BIT(4)
34 #define IMX8M_PCIE1_A53_DOMAIN			BIT(3)
35 
36 #define IMX8MM_OTG2_A53_DOMAIN			BIT(5)
37 #define IMX8MM_OTG1_A53_DOMAIN			BIT(4)
38 #define IMX8MM_PCIE_A53_DOMAIN			BIT(3)
39 
40 #define IMX8MN_OTG1_A53_DOMAIN			BIT(4)
41 #define IMX8MN_MIPI_A53_DOMAIN			BIT(2)
42 
43 #define IMX8MP_HSIOMIX_A53_DOMAIN		BIT(19)
44 #define IMX8MP_USB2_PHY_A53_DOMAIN		BIT(5)
45 #define IMX8MP_USB1_PHY_A53_DOMAIN		BIT(4)
46 #define IMX8MP_PCIE_PHY_A53_DOMAIN		BIT(3)
47 
48 #define IMX8MP_GPC_PU_PGC_SW_PUP_REQ		0x0d8
49 #define IMX8MP_GPC_PU_PGC_SW_PDN_REQ		0x0e4
50 
51 #define GPC_PU_PGC_SW_PUP_REQ			0x0f8
52 #define GPC_PU_PGC_SW_PDN_REQ			0x104
53 
54 #define IMX8M_PCIE2_SW_Pxx_REQ			BIT(13)
55 #define IMX8M_OTG2_SW_Pxx_REQ			BIT(3)
56 #define IMX8M_OTG1_SW_Pxx_REQ			BIT(2)
57 #define IMX8M_PCIE1_SW_Pxx_REQ			BIT(1)
58 
59 #define IMX8MM_OTG2_SW_Pxx_REQ			BIT(3)
60 #define IMX8MM_OTG1_SW_Pxx_REQ			BIT(2)
61 #define IMX8MM_PCIE_SW_Pxx_REQ			BIT(1)
62 
63 #define IMX8MN_OTG1_SW_Pxx_REQ			BIT(2)
64 #define IMX8MN_MIPI_SW_Pxx_REQ			BIT(0)
65 
66 #define IMX8MP_HSIOMIX_Pxx_REQ			BIT(17)
67 #define IMX8MP_USB2_PHY_Pxx_REQ			BIT(3)
68 #define IMX8MP_USB1_PHY_Pxx_REQ			BIT(2)
69 #define IMX8MP_PCIE_PHY_SW_Pxx_REQ		BIT(1)
70 
71 #define GPC_M4_PU_PDN_FLG			0x1bc
72 
73 #define IMX8MP_GPC_PU_PWRHSK			0x190
74 #define GPC_PU_PWRHSK				0x1fc
75 
76 #define IMX8MM_HSIO_HSK_PWRDNACKN		(BIT(23) | BIT(24))
77 #define IMX8MM_HSIO_HSK_PWRDNREQN		(BIT(5) | BIT(6))
78 
79 #define IMX8MN_HSIO_HSK_PWRDNACKN		BIT(23)
80 #define IMX8MN_HSIO_HSK_PWRDNREQN		BIT(5)
81 
82 #define IMX8MP_HSIOMIX_PWRDNACKN		BIT(28)
83 #define IMX8MP_HSIOMIX_PWRDNREQN		BIT(12)
84 
85 /*
86  * The PGC offset values in Reference Manual
87  * (Rev. 1, 01/2018 and the older ones) GPC chapter's
88  * GPC_PGC memory map are incorrect, below offset
89  * values are from design RTL.
90  */
91 #define IMX8M_PGC_PCIE1			17
92 #define IMX8M_PGC_OTG1			18
93 #define IMX8M_PGC_OTG2			19
94 #define IMX8M_PGC_PCIE2			29
95 
96 #define IMX8MM_PGC_PCIE			17
97 #define IMX8MM_PGC_OTG1			18
98 #define IMX8MM_PGC_OTG2			19
99 
100 #define IMX8MN_PGC_OTG1			18
101 
102 #define IMX8MP_PGC_PCIE			13
103 #define IMX8MP_PGC_USB1			14
104 #define IMX8MP_PGC_USB2			15
105 #define IMX8MP_PGC_HSIOMIX		29
106 
107 #define GPC_PGC_CTRL(n)			(0x800 + (n) * 0x40)
108 #define GPC_PGC_SR(n)			(GPC_PGC_CTRL(n) + 0xc)
109 
110 #define GPC_PGC_CTRL_PCR		BIT(0)
111 
112 struct imx_pgc_regs {
113 	u16 map;
114 	u16 pup;
115 	u16 pdn;
116 	u16 hsk;
117 };
118 
119 struct imx_pgc_domain {
120 	unsigned long pgc;
121 
122 	const struct {
123 		u32 pxx;
124 		u32 map;
125 		u32 hskreq;
126 		u32 hskack;
127 	} bits;
128 
129 	const bool keep_clocks;
130 };
131 
132 struct imx_pgc_domain_data {
133 	const struct imx_pgc_domain *domains;
134 	size_t domains_num;
135 	const struct imx_pgc_regs *pgc_regs;
136 };
137 
138 struct imx8m_power_domain_plat {
139 	struct power_domain pd;
140 	const struct imx_pgc_domain *domain;
141 	const struct imx_pgc_regs *regs;
142 	struct clk_bulk clk;
143 	void __iomem *base;
144 	int resource_id;
145 	int has_pd;
146 };
147 
148 #if defined(CONFIG_IMX8MM) || defined(CONFIG_IMX8MN) || defined(CONFIG_IMX8MQ)
149 static const struct imx_pgc_regs imx7_pgc_regs = {
150 	.map = GPC_PGC_CPU_MAPPING,
151 	.pup = GPC_PU_PGC_SW_PUP_REQ,
152 	.pdn = GPC_PU_PGC_SW_PDN_REQ,
153 	.hsk = GPC_PU_PWRHSK,
154 };
155 #endif
156 
157 #ifdef CONFIG_IMX8MQ
158 static const struct imx_pgc_domain imx8m_pgc_domains[] = {
159 	[IMX8M_POWER_DOMAIN_PCIE1] = {
160 		.bits  = {
161 			.pxx = IMX8M_PCIE1_SW_Pxx_REQ,
162 			.map = IMX8M_PCIE1_A53_DOMAIN,
163 		},
164 		.pgc   = BIT(IMX8M_PGC_PCIE1),
165 	},
166 
167 	[IMX8M_POWER_DOMAIN_USB_OTG1] = {
168 		.bits  = {
169 			.pxx = IMX8M_OTG1_SW_Pxx_REQ,
170 			.map = IMX8M_OTG1_A53_DOMAIN,
171 		},
172 		.pgc   = BIT(IMX8M_PGC_OTG1),
173 	},
174 
175 	[IMX8M_POWER_DOMAIN_USB_OTG2] = {
176 		.bits  = {
177 			.pxx = IMX8M_OTG2_SW_Pxx_REQ,
178 			.map = IMX8M_OTG2_A53_DOMAIN,
179 		},
180 		.pgc   = BIT(IMX8M_PGC_OTG2),
181 	},
182 
183 	[IMX8M_POWER_DOMAIN_PCIE2] = {
184 		.bits  = {
185 			.pxx = IMX8M_PCIE2_SW_Pxx_REQ,
186 			.map = IMX8M_PCIE2_A53_DOMAIN,
187 		},
188 		.pgc   = BIT(IMX8M_PGC_PCIE2),
189 	},
190 };
191 
192 static const struct imx_pgc_domain_data imx8m_pgc_domain_data = {
193 	.domains = imx8m_pgc_domains,
194 	.domains_num = ARRAY_SIZE(imx8m_pgc_domains),
195 	.pgc_regs = &imx7_pgc_regs,
196 };
197 #endif
198 
199 #ifdef CONFIG_IMX8MM
200 static const struct imx_pgc_domain imx8mm_pgc_domains[] = {
201 	[IMX8MM_POWER_DOMAIN_HSIOMIX] = {
202 		.bits  = {
203 			.pxx = 0, /* no power sequence control */
204 			.map = 0, /* no power sequence control */
205 			.hskreq = IMX8MM_HSIO_HSK_PWRDNREQN,
206 			.hskack = IMX8MM_HSIO_HSK_PWRDNACKN,
207 		},
208 		.keep_clocks = true,
209 	},
210 
211 	[IMX8MM_POWER_DOMAIN_PCIE] = {
212 		.bits  = {
213 			.pxx = IMX8MM_PCIE_SW_Pxx_REQ,
214 			.map = IMX8MM_PCIE_A53_DOMAIN,
215 		},
216 		.pgc   = BIT(IMX8MM_PGC_PCIE),
217 	},
218 
219 	[IMX8MM_POWER_DOMAIN_OTG1] = {
220 		.bits  = {
221 			.pxx = IMX8MM_OTG1_SW_Pxx_REQ,
222 			.map = IMX8MM_OTG1_A53_DOMAIN,
223 		},
224 		.pgc   = BIT(IMX8MM_PGC_OTG1),
225 	},
226 
227 	[IMX8MM_POWER_DOMAIN_OTG2] = {
228 		.bits  = {
229 			.pxx = IMX8MM_OTG2_SW_Pxx_REQ,
230 			.map = IMX8MM_OTG2_A53_DOMAIN,
231 		},
232 		.pgc   = BIT(IMX8MM_PGC_OTG2),
233 	},
234 };
235 
236 static const struct imx_pgc_domain_data imx8mm_pgc_domain_data = {
237 	.domains = imx8mm_pgc_domains,
238 	.domains_num = ARRAY_SIZE(imx8mm_pgc_domains),
239 	.pgc_regs = &imx7_pgc_regs,
240 };
241 #endif
242 
243 #ifdef CONFIG_IMX8MN
244 static const struct imx_pgc_domain imx8mn_pgc_domains[] = {
245 	[IMX8MN_POWER_DOMAIN_HSIOMIX] = {
246 		.bits  = {
247 			.pxx = 0, /* no power sequence control */
248 			.map = 0, /* no power sequence control */
249 			.hskreq = IMX8MN_HSIO_HSK_PWRDNREQN,
250 			.hskack = IMX8MN_HSIO_HSK_PWRDNACKN,
251 		},
252 		.keep_clocks = true,
253 	},
254 
255 	[IMX8MN_POWER_DOMAIN_OTG1] = {
256 		.bits  = {
257 			.pxx = IMX8MN_OTG1_SW_Pxx_REQ,
258 			.map = IMX8MN_OTG1_A53_DOMAIN,
259 		},
260 		.pgc   = BIT(IMX8MN_PGC_OTG1),
261 	},
262 };
263 
264 static const struct imx_pgc_domain_data imx8mn_pgc_domain_data = {
265 	.domains = imx8mn_pgc_domains,
266 	.domains_num = ARRAY_SIZE(imx8mn_pgc_domains),
267 	.pgc_regs = &imx7_pgc_regs,
268 };
269 #endif
270 
271 #ifdef CONFIG_IMX8MP
272 static const struct imx_pgc_domain imx8mp_pgc_domains[] = {
273 	[IMX8MP_POWER_DOMAIN_PCIE_PHY] = {
274 		.bits = {
275 			.pxx = IMX8MP_PCIE_PHY_SW_Pxx_REQ,
276 			.map = IMX8MP_PCIE_PHY_A53_DOMAIN,
277 		},
278 		.pgc = BIT(IMX8MP_PGC_PCIE),
279 	},
280 
281 	[IMX8MP_POWER_DOMAIN_USB1_PHY] = {
282 		.bits = {
283 			.pxx = IMX8MP_USB1_PHY_Pxx_REQ,
284 			.map = IMX8MP_USB1_PHY_A53_DOMAIN,
285 		},
286 		.pgc = BIT(IMX8MP_PGC_USB1),
287 	},
288 
289 	[IMX8MP_POWER_DOMAIN_USB2_PHY] = {
290 		.bits = {
291 			.pxx = IMX8MP_USB2_PHY_Pxx_REQ,
292 			.map = IMX8MP_USB2_PHY_A53_DOMAIN,
293 		},
294 		.pgc = BIT(IMX8MP_PGC_USB2),
295 	},
296 
297 	[IMX8MP_POWER_DOMAIN_HSIOMIX] = {
298 		.bits = {
299 			.pxx = IMX8MP_HSIOMIX_Pxx_REQ,
300 			.map = IMX8MP_HSIOMIX_A53_DOMAIN,
301 			.hskreq = IMX8MP_HSIOMIX_PWRDNREQN,
302 			.hskack = IMX8MP_HSIOMIX_PWRDNACKN,
303 		},
304 		.pgc = BIT(IMX8MP_PGC_HSIOMIX),
305 		.keep_clocks = true,
306 	},
307 };
308 
309 static const struct imx_pgc_regs imx8mp_pgc_regs = {
310 	.map = IMX8MP_GPC_PGC_CPU_MAPPING,
311 	.pup = IMX8MP_GPC_PU_PGC_SW_PUP_REQ,
312 	.pdn = IMX8MP_GPC_PU_PGC_SW_PDN_REQ,
313 	.hsk = IMX8MP_GPC_PU_PWRHSK,
314 };
315 
316 static const struct imx_pgc_domain_data imx8mp_pgc_domain_data = {
317 	.domains = imx8mp_pgc_domains,
318 	.domains_num = ARRAY_SIZE(imx8mp_pgc_domains),
319 	.pgc_regs = &imx8mp_pgc_regs,
320 };
321 #endif
322 
imx8m_power_domain_on(struct power_domain * power_domain)323 static int imx8m_power_domain_on(struct power_domain *power_domain)
324 {
325 	struct udevice *dev = power_domain->dev;
326 	struct imx8m_power_domain_plat *pdata = dev_get_plat(dev);
327 	const struct imx_pgc_domain *domain = pdata->domain;
328 	const struct imx_pgc_regs *regs = pdata->regs;
329 	void __iomem *base = pdata->base;
330 	u32 pgc;
331 	int ret;
332 
333 	if (pdata->clk.count) {
334 		ret = clk_enable_bulk(&pdata->clk);
335 		if (ret) {
336 			dev_err(dev, "failed to enable reset clocks\n");
337 			return ret;
338 		}
339 	}
340 
341 	if (domain->bits.pxx) {
342 		/* request the domain to power up */
343 		setbits_le32(base + regs->pup, domain->bits.pxx);
344 
345 		/*
346 		 * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
347 		 * for PUP_REQ/PDN_REQ bit to be cleared
348 		 */
349 		ret = wait_for_bit_le32(base + regs->pup, domain->bits.pxx,
350 					false, 1000, false);
351 		if (ret) {
352 			dev_err(dev, "failed to command PGC\n");
353 			goto out_clk_disable;
354 		}
355 
356 		/* disable power control */
357 		for_each_set_bit(pgc, &domain->pgc, 32) {
358 			clrbits_le32(base + GPC_PGC_CTRL(pgc),
359 				     GPC_PGC_CTRL_PCR);
360 		}
361 	}
362 
363 	/* delay for reset to propagate */
364 	udelay(5);
365 
366 	/* request the ADB400 to power up */
367 	if (domain->bits.hskreq)
368 		setbits_le32(base + regs->hsk, domain->bits.hskreq);
369 
370 	/* Disable reset clocks for all devices in the domain */
371 	if (!domain->keep_clocks && pdata->clk.count)
372 		clk_disable_bulk(&pdata->clk);
373 
374 	return 0;
375 
376 out_clk_disable:
377 	if (pdata->clk.count)
378 		clk_disable_bulk(&pdata->clk);
379 	return ret;
380 }
381 
imx8m_power_domain_off(struct power_domain * power_domain)382 static int imx8m_power_domain_off(struct power_domain *power_domain)
383 {
384 	struct udevice *dev = power_domain->dev;
385 	struct imx8m_power_domain_plat *pdata = dev_get_plat(dev);
386 	const struct imx_pgc_domain *domain = pdata->domain;
387 	const struct imx_pgc_regs *regs = pdata->regs;
388 	void __iomem *base = pdata->base;
389 	u32 pgc;
390 	int ret;
391 
392 	/* Enable reset clocks for all devices in the domain */
393 	if (!domain->keep_clocks && pdata->clk.count) {
394 		ret = clk_enable_bulk(&pdata->clk);
395 		if (ret)
396 			return ret;
397 	}
398 
399 	/* request the ADB400 to power down */
400 	if (domain->bits.hskreq) {
401 		clrbits_le32(base + regs->hsk, domain->bits.hskreq);
402 
403 		ret = wait_for_bit_le32(base + regs->hsk, domain->bits.hskack,
404 					false, 1000, false);
405 		if (ret) {
406 			dev_err(dev, "failed to power down ADB400\n");
407 			goto out_clk_disable;
408 		}
409 	}
410 
411 	if (domain->bits.pxx) {
412 		/* enable power control */
413 		for_each_set_bit(pgc, &domain->pgc, 32) {
414 			setbits_le32(base + GPC_PGC_CTRL(pgc),
415 				     GPC_PGC_CTRL_PCR);
416 		}
417 
418 		/* request the domain to power down */
419 		setbits_le32(base + regs->pdn, domain->bits.pxx);
420 
421 		/*
422 		 * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
423 		 * for PUP_REQ/PDN_REQ bit to be cleared
424 		 */
425 		ret = wait_for_bit_le32(base + regs->pdn, domain->bits.pxx,
426 					false, 1000, false);
427 		if (ret) {
428 			dev_err(dev, "failed to command PGC\n");
429 			goto out_clk_disable;
430 		}
431 	}
432 
433 	/* Disable reset clocks for all devices in the domain */
434 	if (pdata->clk.count)
435 		clk_disable_bulk(&pdata->clk);
436 
437 	if (pdata->has_pd)
438 		power_domain_off(&pdata->pd);
439 
440 	return 0;
441 
442 out_clk_disable:
443 	if (!domain->keep_clocks && pdata->clk.count)
444 		clk_disable_bulk(&pdata->clk);
445 
446 	return ret;
447 }
448 
imx8m_power_domain_of_xlate(struct power_domain * power_domain,struct ofnode_phandle_args * args)449 static int imx8m_power_domain_of_xlate(struct power_domain *power_domain,
450 				      struct ofnode_phandle_args *args)
451 {
452 	return 0;
453 }
454 
imx8m_power_domain_bind(struct udevice * dev)455 static int imx8m_power_domain_bind(struct udevice *dev)
456 {
457 	int offset;
458 	const char *name;
459 	int ret = 0;
460 
461 	offset = dev_of_offset(dev);
462 	for (offset = fdt_first_subnode(gd->fdt_blob, offset); offset > 0;
463 	     offset = fdt_next_subnode(gd->fdt_blob, offset)) {
464 		/* Bind the subnode to this driver */
465 		name = fdt_get_name(gd->fdt_blob, offset, NULL);
466 
467 		/* Descend into 'pgc' subnode */
468 		if (!strstr(name, "power-domain")) {
469 			offset = fdt_first_subnode(gd->fdt_blob, offset);
470 			name = fdt_get_name(gd->fdt_blob, offset, NULL);
471 		}
472 
473 		ret = device_bind_with_driver_data(dev, dev->driver, name,
474 						   dev->driver_data,
475 						   offset_to_ofnode(offset),
476 						   NULL);
477 
478 		if (ret == -ENODEV)
479 			printf("Driver '%s' refuses to bind\n",
480 			       dev->driver->name);
481 
482 		if (ret)
483 			printf("Error binding driver '%s': %d\n",
484 			       dev->driver->name, ret);
485 	}
486 
487 	return 0;
488 }
489 
imx8m_power_domain_probe(struct udevice * dev)490 static int imx8m_power_domain_probe(struct udevice *dev)
491 {
492 	struct imx8m_power_domain_plat *pdata = dev_get_plat(dev);
493 	int ret;
494 
495 	/* Nothing to do for non-"power-domain" driver instances. */
496 	if (!strstr(dev->name, "power-domain"))
497 		return 0;
498 
499 	/* Grab optional power domain clock. */
500 	ret = clk_get_bulk(dev, &pdata->clk);
501 	if (ret && ret != -ENOENT) {
502 		dev_err(dev, "Failed to get domain clock (%d)\n", ret);
503 		return ret;
504 	}
505 
506 	return 0;
507 }
508 
imx8m_power_domain_of_to_plat(struct udevice * dev)509 static int imx8m_power_domain_of_to_plat(struct udevice *dev)
510 {
511 	struct imx8m_power_domain_plat *pdata = dev_get_plat(dev);
512 	struct imx_pgc_domain_data *domain_data =
513 		(struct imx_pgc_domain_data *)dev_get_driver_data(dev);
514 
515 	pdata->resource_id = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
516 					    "reg", -1);
517 	pdata->domain = &domain_data->domains[pdata->resource_id];
518 	pdata->regs = domain_data->pgc_regs;
519 	pdata->base = dev_read_addr_ptr(dev->parent);
520 
521 	if (!power_domain_get(dev, &pdata->pd))
522 		pdata->has_pd = 1;
523 
524 	return 0;
525 }
526 
527 static const struct udevice_id imx8m_power_domain_ids[] = {
528 #ifdef CONFIG_IMX8MQ
529 	{ .compatible = "fsl,imx8mq-gpc", .data = (long)&imx8m_pgc_domain_data },
530 #endif
531 #ifdef CONFIG_IMX8MM
532 	{ .compatible = "fsl,imx8mm-gpc", .data = (long)&imx8mm_pgc_domain_data },
533 #endif
534 #ifdef CONFIG_IMX8MN
535 	{ .compatible = "fsl,imx8mn-gpc", .data = (long)&imx8mn_pgc_domain_data },
536 #endif
537 #ifdef CONFIG_IMX8MP
538 	{ .compatible = "fsl,imx8mp-gpc", .data = (long)&imx8mp_pgc_domain_data },
539 #endif
540 	{ }
541 };
542 
543 struct power_domain_ops imx8m_power_domain_ops = {
544 	.on = imx8m_power_domain_on,
545 	.off = imx8m_power_domain_off,
546 	.of_xlate = imx8m_power_domain_of_xlate,
547 };
548 
549 U_BOOT_DRIVER(imx8m_power_domain) = {
550 	.name = "imx8m_power_domain",
551 	.id = UCLASS_POWER_DOMAIN,
552 	.of_match = imx8m_power_domain_ids,
553 	.bind = imx8m_power_domain_bind,
554 	.probe = imx8m_power_domain_probe,
555 	.of_to_plat = imx8m_power_domain_of_to_plat,
556 	.plat_auto	= sizeof(struct imx8m_power_domain_plat),
557 	.ops = &imx8m_power_domain_ops,
558 };
559