xref: /linux/drivers/pmdomain/imx/gpcv2.c (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2017 Impinj, Inc
4  * Author: Andrey Smirnov <andrew.smirnov@gmail.com>
5  *
6  * Based on the code of analogus driver:
7  *
8  * Copyright 2015-2017 Pengutronix, Lucas Stach <kernel@pengutronix.de>
9  */
10 
11 #include <linux/clk.h>
12 #include <linux/of.h>
13 #include <linux/platform_device.h>
14 #include <linux/pm_domain.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/regmap.h>
17 #include <linux/regulator/consumer.h>
18 #include <linux/reset.h>
19 #include <linux/sizes.h>
20 #include <dt-bindings/power/imx7-power.h>
21 #include <dt-bindings/power/imx8mq-power.h>
22 #include <dt-bindings/power/imx8mm-power.h>
23 #include <dt-bindings/power/imx8mn-power.h>
24 #include <dt-bindings/power/imx8mp-power.h>
25 
26 #define GPC_LPCR_A_CORE_BSC			0x000
27 
28 #define GPC_PGC_CPU_MAPPING		0x0ec
29 #define IMX8MP_GPC_PGC_CPU_MAPPING	0x1cc
30 
31 #define IMX7_USB_HSIC_PHY_A_CORE_DOMAIN		BIT(6)
32 #define IMX7_USB_OTG2_PHY_A_CORE_DOMAIN		BIT(5)
33 #define IMX7_USB_OTG1_PHY_A_CORE_DOMAIN		BIT(4)
34 #define IMX7_PCIE_PHY_A_CORE_DOMAIN		BIT(3)
35 #define IMX7_MIPI_PHY_A_CORE_DOMAIN		BIT(2)
36 
37 #define IMX8M_PCIE2_A53_DOMAIN			BIT(15)
38 #define IMX8M_MIPI_CSI2_A53_DOMAIN		BIT(14)
39 #define IMX8M_MIPI_CSI1_A53_DOMAIN		BIT(13)
40 #define IMX8M_DISP_A53_DOMAIN			BIT(12)
41 #define IMX8M_HDMI_A53_DOMAIN			BIT(11)
42 #define IMX8M_VPU_A53_DOMAIN			BIT(10)
43 #define IMX8M_GPU_A53_DOMAIN			BIT(9)
44 #define IMX8M_DDR2_A53_DOMAIN			BIT(8)
45 #define IMX8M_DDR1_A53_DOMAIN			BIT(7)
46 #define IMX8M_OTG2_A53_DOMAIN			BIT(5)
47 #define IMX8M_OTG1_A53_DOMAIN			BIT(4)
48 #define IMX8M_PCIE1_A53_DOMAIN			BIT(3)
49 #define IMX8M_MIPI_A53_DOMAIN			BIT(2)
50 
51 #define IMX8MM_VPUH1_A53_DOMAIN			BIT(15)
52 #define IMX8MM_VPUG2_A53_DOMAIN			BIT(14)
53 #define IMX8MM_VPUG1_A53_DOMAIN			BIT(13)
54 #define IMX8MM_DISPMIX_A53_DOMAIN		BIT(12)
55 #define IMX8MM_VPUMIX_A53_DOMAIN		BIT(10)
56 #define IMX8MM_GPUMIX_A53_DOMAIN		BIT(9)
57 #define IMX8MM_GPU_A53_DOMAIN			(BIT(8) | BIT(11))
58 #define IMX8MM_DDR1_A53_DOMAIN			BIT(7)
59 #define IMX8MM_OTG2_A53_DOMAIN			BIT(5)
60 #define IMX8MM_OTG1_A53_DOMAIN			BIT(4)
61 #define IMX8MM_PCIE_A53_DOMAIN			BIT(3)
62 #define IMX8MM_MIPI_A53_DOMAIN			BIT(2)
63 
64 #define IMX8MN_DISPMIX_A53_DOMAIN		BIT(12)
65 #define IMX8MN_GPUMIX_A53_DOMAIN		BIT(9)
66 #define IMX8MN_DDR1_A53_DOMAIN		BIT(7)
67 #define IMX8MN_OTG1_A53_DOMAIN		BIT(4)
68 #define IMX8MN_MIPI_A53_DOMAIN		BIT(2)
69 
70 #define IMX8MP_MEDIA_ISPDWP_A53_DOMAIN	BIT(20)
71 #define IMX8MP_HSIOMIX_A53_DOMAIN		BIT(19)
72 #define IMX8MP_MIPI_PHY2_A53_DOMAIN		BIT(18)
73 #define IMX8MP_HDMI_PHY_A53_DOMAIN		BIT(17)
74 #define IMX8MP_HDMIMIX_A53_DOMAIN		BIT(16)
75 #define IMX8MP_VPU_VC8000E_A53_DOMAIN		BIT(15)
76 #define IMX8MP_VPU_G2_A53_DOMAIN		BIT(14)
77 #define IMX8MP_VPU_G1_A53_DOMAIN		BIT(13)
78 #define IMX8MP_MEDIAMIX_A53_DOMAIN		BIT(12)
79 #define IMX8MP_GPU3D_A53_DOMAIN			BIT(11)
80 #define IMX8MP_VPUMIX_A53_DOMAIN		BIT(10)
81 #define IMX8MP_GPUMIX_A53_DOMAIN		BIT(9)
82 #define IMX8MP_GPU2D_A53_DOMAIN			BIT(8)
83 #define IMX8MP_AUDIOMIX_A53_DOMAIN		BIT(7)
84 #define IMX8MP_MLMIX_A53_DOMAIN			BIT(6)
85 #define IMX8MP_USB2_PHY_A53_DOMAIN		BIT(5)
86 #define IMX8MP_USB1_PHY_A53_DOMAIN		BIT(4)
87 #define IMX8MP_PCIE_PHY_A53_DOMAIN		BIT(3)
88 #define IMX8MP_MIPI_PHY1_A53_DOMAIN		BIT(2)
89 
90 #define IMX8MP_GPC_PU_PGC_SW_PUP_REQ	0x0d8
91 #define IMX8MP_GPC_PU_PGC_SW_PDN_REQ	0x0e4
92 
93 #define GPC_PU_PGC_SW_PUP_REQ		0x0f8
94 #define GPC_PU_PGC_SW_PDN_REQ		0x104
95 
96 #define IMX7_USB_HSIC_PHY_SW_Pxx_REQ		BIT(4)
97 #define IMX7_USB_OTG2_PHY_SW_Pxx_REQ		BIT(3)
98 #define IMX7_USB_OTG1_PHY_SW_Pxx_REQ		BIT(2)
99 #define IMX7_PCIE_PHY_SW_Pxx_REQ		BIT(1)
100 #define IMX7_MIPI_PHY_SW_Pxx_REQ		BIT(0)
101 
102 #define IMX8M_PCIE2_SW_Pxx_REQ			BIT(13)
103 #define IMX8M_MIPI_CSI2_SW_Pxx_REQ		BIT(12)
104 #define IMX8M_MIPI_CSI1_SW_Pxx_REQ		BIT(11)
105 #define IMX8M_DISP_SW_Pxx_REQ			BIT(10)
106 #define IMX8M_HDMI_SW_Pxx_REQ			BIT(9)
107 #define IMX8M_VPU_SW_Pxx_REQ			BIT(8)
108 #define IMX8M_GPU_SW_Pxx_REQ			BIT(7)
109 #define IMX8M_DDR2_SW_Pxx_REQ			BIT(6)
110 #define IMX8M_DDR1_SW_Pxx_REQ			BIT(5)
111 #define IMX8M_OTG2_SW_Pxx_REQ			BIT(3)
112 #define IMX8M_OTG1_SW_Pxx_REQ			BIT(2)
113 #define IMX8M_PCIE1_SW_Pxx_REQ			BIT(1)
114 #define IMX8M_MIPI_SW_Pxx_REQ			BIT(0)
115 
116 #define IMX8MM_VPUH1_SW_Pxx_REQ			BIT(13)
117 #define IMX8MM_VPUG2_SW_Pxx_REQ			BIT(12)
118 #define IMX8MM_VPUG1_SW_Pxx_REQ			BIT(11)
119 #define IMX8MM_DISPMIX_SW_Pxx_REQ		BIT(10)
120 #define IMX8MM_VPUMIX_SW_Pxx_REQ		BIT(8)
121 #define IMX8MM_GPUMIX_SW_Pxx_REQ		BIT(7)
122 #define IMX8MM_GPU_SW_Pxx_REQ			(BIT(6) | BIT(9))
123 #define IMX8MM_DDR1_SW_Pxx_REQ			BIT(5)
124 #define IMX8MM_OTG2_SW_Pxx_REQ			BIT(3)
125 #define IMX8MM_OTG1_SW_Pxx_REQ			BIT(2)
126 #define IMX8MM_PCIE_SW_Pxx_REQ			BIT(1)
127 #define IMX8MM_MIPI_SW_Pxx_REQ			BIT(0)
128 
129 #define IMX8MN_DISPMIX_SW_Pxx_REQ		BIT(10)
130 #define IMX8MN_GPUMIX_SW_Pxx_REQ		BIT(7)
131 #define IMX8MN_DDR1_SW_Pxx_REQ		BIT(5)
132 #define IMX8MN_OTG1_SW_Pxx_REQ		BIT(2)
133 #define IMX8MN_MIPI_SW_Pxx_REQ		BIT(0)
134 
135 #define IMX8MP_DDRMIX_Pxx_REQ			BIT(19)
136 #define IMX8MP_MEDIA_ISP_DWP_Pxx_REQ		BIT(18)
137 #define IMX8MP_HSIOMIX_Pxx_REQ			BIT(17)
138 #define IMX8MP_MIPI_PHY2_Pxx_REQ		BIT(16)
139 #define IMX8MP_HDMI_PHY_Pxx_REQ			BIT(15)
140 #define IMX8MP_HDMIMIX_Pxx_REQ			BIT(14)
141 #define IMX8MP_VPU_VC8K_Pxx_REQ			BIT(13)
142 #define IMX8MP_VPU_G2_Pxx_REQ			BIT(12)
143 #define IMX8MP_VPU_G1_Pxx_REQ			BIT(11)
144 #define IMX8MP_MEDIMIX_Pxx_REQ			BIT(10)
145 #define IMX8MP_GPU_3D_Pxx_REQ			BIT(9)
146 #define IMX8MP_VPU_MIX_SHARE_LOGIC_Pxx_REQ	BIT(8)
147 #define IMX8MP_GPU_SHARE_LOGIC_Pxx_REQ		BIT(7)
148 #define IMX8MP_GPU_2D_Pxx_REQ			BIT(6)
149 #define IMX8MP_AUDIOMIX_Pxx_REQ			BIT(5)
150 #define IMX8MP_MLMIX_Pxx_REQ			BIT(4)
151 #define IMX8MP_USB2_PHY_Pxx_REQ			BIT(3)
152 #define IMX8MP_USB1_PHY_Pxx_REQ			BIT(2)
153 #define IMX8MP_PCIE_PHY_SW_Pxx_REQ		BIT(1)
154 #define IMX8MP_MIPI_PHY1_SW_Pxx_REQ		BIT(0)
155 
156 #define GPC_M4_PU_PDN_FLG		0x1bc
157 
158 #define IMX8MP_GPC_PU_PWRHSK		0x190
159 #define GPC_PU_PWRHSK			0x1fc
160 
161 #define IMX8M_GPU_HSK_PWRDNACKN			BIT(26)
162 #define IMX8M_VPU_HSK_PWRDNACKN			BIT(25)
163 #define IMX8M_DISP_HSK_PWRDNACKN		BIT(24)
164 #define IMX8M_GPU_HSK_PWRDNREQN			BIT(6)
165 #define IMX8M_VPU_HSK_PWRDNREQN			BIT(5)
166 #define IMX8M_DISP_HSK_PWRDNREQN		BIT(4)
167 
168 #define IMX8MM_GPUMIX_HSK_PWRDNACKN		BIT(29)
169 #define IMX8MM_GPU_HSK_PWRDNACKN		(BIT(27) | BIT(28))
170 #define IMX8MM_VPUMIX_HSK_PWRDNACKN		BIT(26)
171 #define IMX8MM_DISPMIX_HSK_PWRDNACKN		BIT(25)
172 #define IMX8MM_HSIO_HSK_PWRDNACKN		(BIT(23) | BIT(24))
173 #define IMX8MM_GPUMIX_HSK_PWRDNREQN		BIT(11)
174 #define IMX8MM_GPU_HSK_PWRDNREQN		(BIT(9) | BIT(10))
175 #define IMX8MM_VPUMIX_HSK_PWRDNREQN		BIT(8)
176 #define IMX8MM_DISPMIX_HSK_PWRDNREQN		BIT(7)
177 #define IMX8MM_HSIO_HSK_PWRDNREQN		(BIT(5) | BIT(6))
178 
179 #define IMX8MN_GPUMIX_HSK_PWRDNACKN		(BIT(29) | BIT(27))
180 #define IMX8MN_DISPMIX_HSK_PWRDNACKN		BIT(25)
181 #define IMX8MN_HSIO_HSK_PWRDNACKN		BIT(23)
182 #define IMX8MN_GPUMIX_HSK_PWRDNREQN		(BIT(11) | BIT(9))
183 #define IMX8MN_DISPMIX_HSK_PWRDNREQN		BIT(7)
184 #define IMX8MN_HSIO_HSK_PWRDNREQN		BIT(5)
185 
186 #define IMX8MP_MEDIAMIX_PWRDNACKN		BIT(30)
187 #define IMX8MP_HDMIMIX_PWRDNACKN		BIT(29)
188 #define IMX8MP_HSIOMIX_PWRDNACKN		BIT(28)
189 #define IMX8MP_VPUMIX_PWRDNACKN			BIT(26)
190 #define IMX8MP_GPUMIX_PWRDNACKN			BIT(25)
191 #define IMX8MP_MLMIX_PWRDNACKN			(BIT(23) | BIT(24))
192 #define IMX8MP_AUDIOMIX_PWRDNACKN		(BIT(20) | BIT(31))
193 #define IMX8MP_MEDIAMIX_PWRDNREQN		BIT(14)
194 #define IMX8MP_HDMIMIX_PWRDNREQN		BIT(13)
195 #define IMX8MP_HSIOMIX_PWRDNREQN		BIT(12)
196 #define IMX8MP_VPUMIX_PWRDNREQN			BIT(10)
197 #define IMX8MP_GPUMIX_PWRDNREQN			BIT(9)
198 #define IMX8MP_MLMIX_PWRDNREQN			(BIT(7) | BIT(8))
199 #define IMX8MP_AUDIOMIX_PWRDNREQN		(BIT(4) | BIT(15))
200 
201 /*
202  * The PGC offset values in Reference Manual
203  * (Rev. 1, 01/2018 and the older ones) GPC chapter's
204  * GPC_PGC memory map are incorrect, below offset
205  * values are from design RTL.
206  */
207 #define IMX7_PGC_MIPI			16
208 #define IMX7_PGC_PCIE			17
209 #define IMX7_PGC_USB_HSIC		20
210 
211 #define IMX8M_PGC_MIPI			16
212 #define IMX8M_PGC_PCIE1			17
213 #define IMX8M_PGC_OTG1			18
214 #define IMX8M_PGC_OTG2			19
215 #define IMX8M_PGC_DDR1			21
216 #define IMX8M_PGC_GPU			23
217 #define IMX8M_PGC_VPU			24
218 #define IMX8M_PGC_DISP			26
219 #define IMX8M_PGC_MIPI_CSI1		27
220 #define IMX8M_PGC_MIPI_CSI2		28
221 #define IMX8M_PGC_PCIE2			29
222 
223 #define IMX8MM_PGC_MIPI			16
224 #define IMX8MM_PGC_PCIE			17
225 #define IMX8MM_PGC_OTG1			18
226 #define IMX8MM_PGC_OTG2			19
227 #define IMX8MM_PGC_DDR1			21
228 #define IMX8MM_PGC_GPU2D		22
229 #define IMX8MM_PGC_GPUMIX		23
230 #define IMX8MM_PGC_VPUMIX		24
231 #define IMX8MM_PGC_GPU3D		25
232 #define IMX8MM_PGC_DISPMIX		26
233 #define IMX8MM_PGC_VPUG1		27
234 #define IMX8MM_PGC_VPUG2		28
235 #define IMX8MM_PGC_VPUH1		29
236 
237 #define IMX8MN_PGC_MIPI		16
238 #define IMX8MN_PGC_OTG1		18
239 #define IMX8MN_PGC_DDR1		21
240 #define IMX8MN_PGC_GPUMIX		23
241 #define IMX8MN_PGC_DISPMIX		26
242 
243 #define IMX8MP_PGC_NOC			9
244 #define IMX8MP_PGC_MIPI1		12
245 #define IMX8MP_PGC_PCIE			13
246 #define IMX8MP_PGC_USB1			14
247 #define IMX8MP_PGC_USB2			15
248 #define IMX8MP_PGC_MLMIX		16
249 #define IMX8MP_PGC_AUDIOMIX		17
250 #define IMX8MP_PGC_GPU2D		18
251 #define IMX8MP_PGC_GPUMIX		19
252 #define IMX8MP_PGC_VPUMIX		20
253 #define IMX8MP_PGC_GPU3D		21
254 #define IMX8MP_PGC_MEDIAMIX		22
255 #define IMX8MP_PGC_VPU_G1		23
256 #define IMX8MP_PGC_VPU_G2		24
257 #define IMX8MP_PGC_VPU_VC8000E		25
258 #define IMX8MP_PGC_HDMIMIX		26
259 #define IMX8MP_PGC_HDMI			27
260 #define IMX8MP_PGC_MIPI2		28
261 #define IMX8MP_PGC_HSIOMIX		29
262 #define IMX8MP_PGC_MEDIA_ISP_DWP	30
263 #define IMX8MP_PGC_DDRMIX		31
264 
265 #define GPC_PGC_CTRL(n)			(0x800 + (n) * 0x40)
266 #define GPC_PGC_SR(n)			(GPC_PGC_CTRL(n) + 0xc)
267 
268 #define GPC_PGC_CTRL_PCR		BIT(0)
269 
270 struct imx_pgc_regs {
271 	u16 map;
272 	u16 pup;
273 	u16 pdn;
274 	u16 hsk;
275 };
276 
277 struct imx_pgc_domain {
278 	struct generic_pm_domain genpd;
279 	struct regmap *regmap;
280 	const struct imx_pgc_regs *regs;
281 	struct regulator *regulator;
282 	struct reset_control *reset;
283 	struct clk_bulk_data *clks;
284 	int num_clks;
285 
286 	unsigned long pgc;
287 
288 	const struct {
289 		u32 pxx;
290 		u32 map;
291 		u32 hskreq;
292 		u32 hskack;
293 	} bits;
294 
295 	const int voltage;
296 	const bool keep_clocks;
297 	struct device *dev;
298 
299 	unsigned int pgc_sw_pup_reg;
300 	unsigned int pgc_sw_pdn_reg;
301 };
302 
303 struct imx_pgc_domain_data {
304 	const struct imx_pgc_domain *domains;
305 	size_t domains_num;
306 	const struct regmap_access_table *reg_access_table;
307 	const struct imx_pgc_regs *pgc_regs;
308 };
309 
310 static inline struct imx_pgc_domain *
to_imx_pgc_domain(struct generic_pm_domain * genpd)311 to_imx_pgc_domain(struct generic_pm_domain *genpd)
312 {
313 	return container_of(genpd, struct imx_pgc_domain, genpd);
314 }
315 
imx_pgc_power_up(struct generic_pm_domain * genpd)316 static int imx_pgc_power_up(struct generic_pm_domain *genpd)
317 {
318 	struct imx_pgc_domain *domain = to_imx_pgc_domain(genpd);
319 	u32 reg_val, pgc;
320 	int ret;
321 
322 	ret = pm_runtime_get_sync(domain->dev);
323 	if (ret < 0) {
324 		pm_runtime_put_noidle(domain->dev);
325 		return ret;
326 	}
327 
328 	if (!IS_ERR(domain->regulator)) {
329 		ret = regulator_enable(domain->regulator);
330 		if (ret) {
331 			dev_err(domain->dev,
332 				"failed to enable regulator: %pe\n",
333 				ERR_PTR(ret));
334 			goto out_put_pm;
335 		}
336 	}
337 
338 	reset_control_assert(domain->reset);
339 
340 	/* Enable reset clocks for all devices in the domain */
341 	ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks);
342 	if (ret) {
343 		dev_err(domain->dev, "failed to enable reset clocks\n");
344 		goto out_regulator_disable;
345 	}
346 
347 	/* delays for reset to propagate */
348 	udelay(5);
349 
350 	if (domain->bits.pxx) {
351 		/* request the domain to power up */
352 		regmap_update_bits(domain->regmap, domain->regs->pup,
353 				   domain->bits.pxx, domain->bits.pxx);
354 		/*
355 		 * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
356 		 * for PUP_REQ/PDN_REQ bit to be cleared
357 		 */
358 		ret = regmap_read_poll_timeout(domain->regmap,
359 					       domain->regs->pup, reg_val,
360 					       !(reg_val & domain->bits.pxx),
361 					       0, USEC_PER_MSEC);
362 		if (ret) {
363 			dev_err(domain->dev, "failed to command PGC\n");
364 			goto out_clk_disable;
365 		}
366 
367 		/* disable power control */
368 		for_each_set_bit(pgc, &domain->pgc, 32) {
369 			regmap_clear_bits(domain->regmap, GPC_PGC_CTRL(pgc),
370 					  GPC_PGC_CTRL_PCR);
371 		}
372 	}
373 
374 	/* delay for reset to propagate */
375 	udelay(5);
376 
377 	reset_control_deassert(domain->reset);
378 
379 	/* request the ADB400 to power up */
380 	if (domain->bits.hskreq) {
381 		regmap_update_bits(domain->regmap, domain->regs->hsk,
382 				   domain->bits.hskreq, domain->bits.hskreq);
383 
384 		/*
385 		 * ret = regmap_read_poll_timeout(domain->regmap, domain->regs->hsk, reg_val,
386 		 *				  (reg_val & domain->bits.hskack), 0,
387 		 *				  USEC_PER_MSEC);
388 		 * Technically we need the commented code to wait handshake. But that needs
389 		 * the BLK-CTL module BUS clk-en bit being set.
390 		 *
391 		 * There is a separate BLK-CTL module and we will have such a driver for it,
392 		 * that driver will set the BUS clk-en bit and handshake will be triggered
393 		 * automatically there. Just add a delay and suppose the handshake finish
394 		 * after that.
395 		 */
396 
397 		/*
398 		 * For some BLK-CTL module (eg. AudioMix on i.MX8MP) doesn't have BUS
399 		 * clk-en bit, it is better to add delay here, as the BLK-CTL module
400 		 * doesn't need to care about how it is powered up.
401 		 *
402 		 * regmap_read_bypassed() is to make sure the above write IO transaction
403 		 * already reaches target before udelay()
404 		 */
405 		regmap_read_bypassed(domain->regmap, domain->regs->hsk, &reg_val);
406 		udelay(5);
407 	}
408 
409 	/* Disable reset clocks for all devices in the domain */
410 	if (!domain->keep_clocks)
411 		clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
412 
413 	return 0;
414 
415 out_clk_disable:
416 	clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
417 out_regulator_disable:
418 	if (!IS_ERR(domain->regulator))
419 		regulator_disable(domain->regulator);
420 out_put_pm:
421 	pm_runtime_put(domain->dev);
422 
423 	return ret;
424 }
425 
imx_pgc_power_down(struct generic_pm_domain * genpd)426 static int imx_pgc_power_down(struct generic_pm_domain *genpd)
427 {
428 	struct imx_pgc_domain *domain = to_imx_pgc_domain(genpd);
429 	u32 reg_val, pgc;
430 	int ret;
431 
432 	/* Enable reset clocks for all devices in the domain */
433 	if (!domain->keep_clocks) {
434 		ret = clk_bulk_prepare_enable(domain->num_clks, domain->clks);
435 		if (ret) {
436 			dev_err(domain->dev, "failed to enable reset clocks\n");
437 			return ret;
438 		}
439 	}
440 
441 	/* request the ADB400 to power down */
442 	if (domain->bits.hskreq) {
443 		regmap_clear_bits(domain->regmap, domain->regs->hsk,
444 				  domain->bits.hskreq);
445 
446 		ret = regmap_read_poll_timeout(domain->regmap, domain->regs->hsk,
447 					       reg_val,
448 					       !(reg_val & domain->bits.hskack),
449 					       0, USEC_PER_MSEC);
450 		if (ret) {
451 			dev_err(domain->dev, "failed to power down ADB400\n");
452 			goto out_clk_disable;
453 		}
454 	}
455 
456 	if (domain->bits.pxx) {
457 		/* enable power control */
458 		for_each_set_bit(pgc, &domain->pgc, 32) {
459 			regmap_update_bits(domain->regmap, GPC_PGC_CTRL(pgc),
460 					   GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR);
461 		}
462 
463 		/* request the domain to power down */
464 		regmap_update_bits(domain->regmap, domain->regs->pdn,
465 				   domain->bits.pxx, domain->bits.pxx);
466 		/*
467 		 * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
468 		 * for PUP_REQ/PDN_REQ bit to be cleared
469 		 */
470 		ret = regmap_read_poll_timeout(domain->regmap,
471 					       domain->regs->pdn, reg_val,
472 					       !(reg_val & domain->bits.pxx),
473 					       0, USEC_PER_MSEC);
474 		if (ret) {
475 			dev_err(domain->dev, "failed to command PGC\n");
476 			goto out_clk_disable;
477 		}
478 	}
479 
480 	/* Disable reset clocks for all devices in the domain */
481 	clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
482 
483 	if (!IS_ERR(domain->regulator)) {
484 		ret = regulator_disable(domain->regulator);
485 		if (ret) {
486 			dev_err(domain->dev,
487 				"failed to disable regulator: %pe\n",
488 				ERR_PTR(ret));
489 			return ret;
490 		}
491 	}
492 
493 	pm_runtime_put_sync_suspend(domain->dev);
494 
495 	return 0;
496 
497 out_clk_disable:
498 	if (!domain->keep_clocks)
499 		clk_bulk_disable_unprepare(domain->num_clks, domain->clks);
500 
501 	return ret;
502 }
503 
504 static const struct imx_pgc_domain imx7_pgc_domains[] = {
505 	[IMX7_POWER_DOMAIN_MIPI_PHY] = {
506 		.genpd = {
507 			.name      = "mipi-phy",
508 		},
509 		.bits  = {
510 			.pxx = IMX7_MIPI_PHY_SW_Pxx_REQ,
511 			.map = IMX7_MIPI_PHY_A_CORE_DOMAIN,
512 		},
513 		.voltage   = 1000000,
514 		.pgc	   = BIT(IMX7_PGC_MIPI),
515 	},
516 
517 	[IMX7_POWER_DOMAIN_PCIE_PHY] = {
518 		.genpd = {
519 			.name      = "pcie-phy",
520 		},
521 		.bits  = {
522 			.pxx = IMX7_PCIE_PHY_SW_Pxx_REQ,
523 			.map = IMX7_PCIE_PHY_A_CORE_DOMAIN,
524 		},
525 		.voltage   = 1000000,
526 		.pgc	   = BIT(IMX7_PGC_PCIE),
527 	},
528 
529 	[IMX7_POWER_DOMAIN_USB_HSIC_PHY] = {
530 		.genpd = {
531 			.name      = "usb-hsic-phy",
532 		},
533 		.bits  = {
534 			.pxx = IMX7_USB_HSIC_PHY_SW_Pxx_REQ,
535 			.map = IMX7_USB_HSIC_PHY_A_CORE_DOMAIN,
536 		},
537 		.voltage   = 1200000,
538 		.pgc	   = BIT(IMX7_PGC_USB_HSIC),
539 	},
540 };
541 
542 static const struct regmap_range imx7_yes_ranges[] = {
543 		regmap_reg_range(GPC_LPCR_A_CORE_BSC,
544 				 GPC_M4_PU_PDN_FLG),
545 		regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_MIPI),
546 				 GPC_PGC_SR(IMX7_PGC_MIPI)),
547 		regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_PCIE),
548 				 GPC_PGC_SR(IMX7_PGC_PCIE)),
549 		regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_USB_HSIC),
550 				 GPC_PGC_SR(IMX7_PGC_USB_HSIC)),
551 };
552 
553 static const struct regmap_access_table imx7_access_table = {
554 	.yes_ranges	= imx7_yes_ranges,
555 	.n_yes_ranges	= ARRAY_SIZE(imx7_yes_ranges),
556 };
557 
558 static const struct imx_pgc_regs imx7_pgc_regs = {
559 	.map = GPC_PGC_CPU_MAPPING,
560 	.pup = GPC_PU_PGC_SW_PUP_REQ,
561 	.pdn = GPC_PU_PGC_SW_PDN_REQ,
562 	.hsk = GPC_PU_PWRHSK,
563 };
564 
565 static const struct imx_pgc_domain_data imx7_pgc_domain_data = {
566 	.domains = imx7_pgc_domains,
567 	.domains_num = ARRAY_SIZE(imx7_pgc_domains),
568 	.reg_access_table = &imx7_access_table,
569 	.pgc_regs = &imx7_pgc_regs,
570 };
571 
572 static const struct imx_pgc_domain imx8m_pgc_domains[] = {
573 	[IMX8M_POWER_DOMAIN_MIPI] = {
574 		.genpd = {
575 			.name      = "mipi",
576 		},
577 		.bits  = {
578 			.pxx = IMX8M_MIPI_SW_Pxx_REQ,
579 			.map = IMX8M_MIPI_A53_DOMAIN,
580 		},
581 		.pgc	   = BIT(IMX8M_PGC_MIPI),
582 	},
583 
584 	[IMX8M_POWER_DOMAIN_PCIE1] = {
585 		.genpd = {
586 			.name = "pcie1",
587 		},
588 		.bits  = {
589 			.pxx = IMX8M_PCIE1_SW_Pxx_REQ,
590 			.map = IMX8M_PCIE1_A53_DOMAIN,
591 		},
592 		.pgc   = BIT(IMX8M_PGC_PCIE1),
593 	},
594 
595 	[IMX8M_POWER_DOMAIN_USB_OTG1] = {
596 		.genpd = {
597 			.name = "usb-otg1",
598 		},
599 		.bits  = {
600 			.pxx = IMX8M_OTG1_SW_Pxx_REQ,
601 			.map = IMX8M_OTG1_A53_DOMAIN,
602 		},
603 		.pgc   = BIT(IMX8M_PGC_OTG1),
604 	},
605 
606 	[IMX8M_POWER_DOMAIN_USB_OTG2] = {
607 		.genpd = {
608 			.name = "usb-otg2",
609 		},
610 		.bits  = {
611 			.pxx = IMX8M_OTG2_SW_Pxx_REQ,
612 			.map = IMX8M_OTG2_A53_DOMAIN,
613 		},
614 		.pgc   = BIT(IMX8M_PGC_OTG2),
615 	},
616 
617 	[IMX8M_POWER_DOMAIN_DDR1] = {
618 		.genpd = {
619 			.name = "ddr1",
620 		},
621 		.bits  = {
622 			.pxx = IMX8M_DDR1_SW_Pxx_REQ,
623 			.map = IMX8M_DDR2_A53_DOMAIN,
624 		},
625 		.pgc   = BIT(IMX8M_PGC_DDR1),
626 	},
627 
628 	[IMX8M_POWER_DOMAIN_GPU] = {
629 		.genpd = {
630 			.name = "gpu",
631 		},
632 		.bits  = {
633 			.pxx = IMX8M_GPU_SW_Pxx_REQ,
634 			.map = IMX8M_GPU_A53_DOMAIN,
635 			.hskreq = IMX8M_GPU_HSK_PWRDNREQN,
636 			.hskack = IMX8M_GPU_HSK_PWRDNACKN,
637 		},
638 		.pgc   = BIT(IMX8M_PGC_GPU),
639 	},
640 
641 	[IMX8M_POWER_DOMAIN_VPU] = {
642 		.genpd = {
643 			.name = "vpu",
644 		},
645 		.bits  = {
646 			.pxx = IMX8M_VPU_SW_Pxx_REQ,
647 			.map = IMX8M_VPU_A53_DOMAIN,
648 			.hskreq = IMX8M_VPU_HSK_PWRDNREQN,
649 			.hskack = IMX8M_VPU_HSK_PWRDNACKN,
650 		},
651 		.pgc   = BIT(IMX8M_PGC_VPU),
652 		.keep_clocks = true,
653 	},
654 
655 	[IMX8M_POWER_DOMAIN_DISP] = {
656 		.genpd = {
657 			.name = "disp",
658 		},
659 		.bits  = {
660 			.pxx = IMX8M_DISP_SW_Pxx_REQ,
661 			.map = IMX8M_DISP_A53_DOMAIN,
662 			.hskreq = IMX8M_DISP_HSK_PWRDNREQN,
663 			.hskack = IMX8M_DISP_HSK_PWRDNACKN,
664 		},
665 		.pgc   = BIT(IMX8M_PGC_DISP),
666 	},
667 
668 	[IMX8M_POWER_DOMAIN_MIPI_CSI1] = {
669 		.genpd = {
670 			.name = "mipi-csi1",
671 		},
672 		.bits  = {
673 			.pxx = IMX8M_MIPI_CSI1_SW_Pxx_REQ,
674 			.map = IMX8M_MIPI_CSI1_A53_DOMAIN,
675 		},
676 		.pgc   = BIT(IMX8M_PGC_MIPI_CSI1),
677 	},
678 
679 	[IMX8M_POWER_DOMAIN_MIPI_CSI2] = {
680 		.genpd = {
681 			.name = "mipi-csi2",
682 		},
683 		.bits  = {
684 			.pxx = IMX8M_MIPI_CSI2_SW_Pxx_REQ,
685 			.map = IMX8M_MIPI_CSI2_A53_DOMAIN,
686 		},
687 		.pgc   = BIT(IMX8M_PGC_MIPI_CSI2),
688 	},
689 
690 	[IMX8M_POWER_DOMAIN_PCIE2] = {
691 		.genpd = {
692 			.name = "pcie2",
693 		},
694 		.bits  = {
695 			.pxx = IMX8M_PCIE2_SW_Pxx_REQ,
696 			.map = IMX8M_PCIE2_A53_DOMAIN,
697 		},
698 		.pgc   = BIT(IMX8M_PGC_PCIE2),
699 	},
700 };
701 
702 static const struct regmap_range imx8m_yes_ranges[] = {
703 		regmap_reg_range(GPC_LPCR_A_CORE_BSC,
704 				 GPC_PU_PWRHSK),
705 		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI),
706 				 GPC_PGC_SR(IMX8M_PGC_MIPI)),
707 		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_PCIE1),
708 				 GPC_PGC_SR(IMX8M_PGC_PCIE1)),
709 		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_OTG1),
710 				 GPC_PGC_SR(IMX8M_PGC_OTG1)),
711 		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_OTG2),
712 				 GPC_PGC_SR(IMX8M_PGC_OTG2)),
713 		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_DDR1),
714 				 GPC_PGC_SR(IMX8M_PGC_DDR1)),
715 		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_GPU),
716 				 GPC_PGC_SR(IMX8M_PGC_GPU)),
717 		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_VPU),
718 				 GPC_PGC_SR(IMX8M_PGC_VPU)),
719 		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_DISP),
720 				 GPC_PGC_SR(IMX8M_PGC_DISP)),
721 		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI_CSI1),
722 				 GPC_PGC_SR(IMX8M_PGC_MIPI_CSI1)),
723 		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI_CSI2),
724 				 GPC_PGC_SR(IMX8M_PGC_MIPI_CSI2)),
725 		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_PCIE2),
726 				 GPC_PGC_SR(IMX8M_PGC_PCIE2)),
727 };
728 
729 static const struct regmap_access_table imx8m_access_table = {
730 	.yes_ranges	= imx8m_yes_ranges,
731 	.n_yes_ranges	= ARRAY_SIZE(imx8m_yes_ranges),
732 };
733 
734 static const struct imx_pgc_domain_data imx8m_pgc_domain_data = {
735 	.domains = imx8m_pgc_domains,
736 	.domains_num = ARRAY_SIZE(imx8m_pgc_domains),
737 	.reg_access_table = &imx8m_access_table,
738 	.pgc_regs = &imx7_pgc_regs,
739 };
740 
741 static const struct imx_pgc_domain imx8mm_pgc_domains[] = {
742 	[IMX8MM_POWER_DOMAIN_HSIOMIX] = {
743 		.genpd = {
744 			.name = "hsiomix",
745 		},
746 		.bits  = {
747 			.pxx = 0, /* no power sequence control */
748 			.map = 0, /* no power sequence control */
749 			.hskreq = IMX8MM_HSIO_HSK_PWRDNREQN,
750 			.hskack = IMX8MM_HSIO_HSK_PWRDNACKN,
751 		},
752 		.keep_clocks = true,
753 	},
754 
755 	[IMX8MM_POWER_DOMAIN_PCIE] = {
756 		.genpd = {
757 			.name = "pcie",
758 		},
759 		.bits  = {
760 			.pxx = IMX8MM_PCIE_SW_Pxx_REQ,
761 			.map = IMX8MM_PCIE_A53_DOMAIN,
762 		},
763 		.pgc   = BIT(IMX8MM_PGC_PCIE),
764 	},
765 
766 	[IMX8MM_POWER_DOMAIN_OTG1] = {
767 		.genpd = {
768 			.name = "usb-otg1",
769 			.flags = GENPD_FLAG_ACTIVE_WAKEUP,
770 		},
771 		.bits  = {
772 			.pxx = IMX8MM_OTG1_SW_Pxx_REQ,
773 			.map = IMX8MM_OTG1_A53_DOMAIN,
774 		},
775 		.pgc   = BIT(IMX8MM_PGC_OTG1),
776 	},
777 
778 	[IMX8MM_POWER_DOMAIN_OTG2] = {
779 		.genpd = {
780 			.name = "usb-otg2",
781 			.flags = GENPD_FLAG_ACTIVE_WAKEUP,
782 		},
783 		.bits  = {
784 			.pxx = IMX8MM_OTG2_SW_Pxx_REQ,
785 			.map = IMX8MM_OTG2_A53_DOMAIN,
786 		},
787 		.pgc   = BIT(IMX8MM_PGC_OTG2),
788 	},
789 
790 	[IMX8MM_POWER_DOMAIN_GPUMIX] = {
791 		.genpd = {
792 			.name = "gpumix",
793 		},
794 		.bits  = {
795 			.pxx = IMX8MM_GPUMIX_SW_Pxx_REQ,
796 			.map = IMX8MM_GPUMIX_A53_DOMAIN,
797 			.hskreq = IMX8MM_GPUMIX_HSK_PWRDNREQN,
798 			.hskack = IMX8MM_GPUMIX_HSK_PWRDNACKN,
799 		},
800 		.pgc   = BIT(IMX8MM_PGC_GPUMIX),
801 		.keep_clocks = true,
802 	},
803 
804 	[IMX8MM_POWER_DOMAIN_GPU] = {
805 		.genpd = {
806 			.name = "gpu",
807 		},
808 		.bits  = {
809 			.pxx = IMX8MM_GPU_SW_Pxx_REQ,
810 			.map = IMX8MM_GPU_A53_DOMAIN,
811 			.hskreq = IMX8MM_GPU_HSK_PWRDNREQN,
812 			.hskack = IMX8MM_GPU_HSK_PWRDNACKN,
813 		},
814 		.pgc   = BIT(IMX8MM_PGC_GPU2D) | BIT(IMX8MM_PGC_GPU3D),
815 	},
816 
817 	[IMX8MM_POWER_DOMAIN_VPUMIX] = {
818 		.genpd = {
819 			.name = "vpumix",
820 		},
821 		.bits  = {
822 			.pxx = IMX8MM_VPUMIX_SW_Pxx_REQ,
823 			.map = IMX8MM_VPUMIX_A53_DOMAIN,
824 			.hskreq = IMX8MM_VPUMIX_HSK_PWRDNREQN,
825 			.hskack = IMX8MM_VPUMIX_HSK_PWRDNACKN,
826 		},
827 		.pgc   = BIT(IMX8MM_PGC_VPUMIX),
828 		.keep_clocks = true,
829 	},
830 
831 	[IMX8MM_POWER_DOMAIN_VPUG1] = {
832 		.genpd = {
833 			.name = "vpu-g1",
834 		},
835 		.bits  = {
836 			.pxx = IMX8MM_VPUG1_SW_Pxx_REQ,
837 			.map = IMX8MM_VPUG1_A53_DOMAIN,
838 		},
839 		.pgc   = BIT(IMX8MM_PGC_VPUG1),
840 	},
841 
842 	[IMX8MM_POWER_DOMAIN_VPUG2] = {
843 		.genpd = {
844 			.name = "vpu-g2",
845 		},
846 		.bits  = {
847 			.pxx = IMX8MM_VPUG2_SW_Pxx_REQ,
848 			.map = IMX8MM_VPUG2_A53_DOMAIN,
849 		},
850 		.pgc   = BIT(IMX8MM_PGC_VPUG2),
851 	},
852 
853 	[IMX8MM_POWER_DOMAIN_VPUH1] = {
854 		.genpd = {
855 			.name = "vpu-h1",
856 		},
857 		.bits  = {
858 			.pxx = IMX8MM_VPUH1_SW_Pxx_REQ,
859 			.map = IMX8MM_VPUH1_A53_DOMAIN,
860 		},
861 		.pgc   = BIT(IMX8MM_PGC_VPUH1),
862 		.keep_clocks = true,
863 	},
864 
865 	[IMX8MM_POWER_DOMAIN_DISPMIX] = {
866 		.genpd = {
867 			.name = "dispmix",
868 		},
869 		.bits  = {
870 			.pxx = IMX8MM_DISPMIX_SW_Pxx_REQ,
871 			.map = IMX8MM_DISPMIX_A53_DOMAIN,
872 			.hskreq = IMX8MM_DISPMIX_HSK_PWRDNREQN,
873 			.hskack = IMX8MM_DISPMIX_HSK_PWRDNACKN,
874 		},
875 		.pgc   = BIT(IMX8MM_PGC_DISPMIX),
876 		.keep_clocks = true,
877 	},
878 
879 	[IMX8MM_POWER_DOMAIN_MIPI] = {
880 		.genpd = {
881 			.name = "mipi",
882 		},
883 		.bits  = {
884 			.pxx = IMX8MM_MIPI_SW_Pxx_REQ,
885 			.map = IMX8MM_MIPI_A53_DOMAIN,
886 		},
887 		.pgc   = BIT(IMX8MM_PGC_MIPI),
888 	},
889 };
890 
891 static const struct regmap_range imx8mm_yes_ranges[] = {
892 		regmap_reg_range(GPC_LPCR_A_CORE_BSC,
893 				 GPC_PU_PWRHSK),
894 		regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_MIPI),
895 				 GPC_PGC_SR(IMX8MM_PGC_MIPI)),
896 		regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_PCIE),
897 				 GPC_PGC_SR(IMX8MM_PGC_PCIE)),
898 		regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_OTG1),
899 				 GPC_PGC_SR(IMX8MM_PGC_OTG1)),
900 		regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_OTG2),
901 				 GPC_PGC_SR(IMX8MM_PGC_OTG2)),
902 		regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_DDR1),
903 				 GPC_PGC_SR(IMX8MM_PGC_DDR1)),
904 		regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_GPU2D),
905 				 GPC_PGC_SR(IMX8MM_PGC_GPU2D)),
906 		regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_GPUMIX),
907 				 GPC_PGC_SR(IMX8MM_PGC_GPUMIX)),
908 		regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_VPUMIX),
909 				 GPC_PGC_SR(IMX8MM_PGC_VPUMIX)),
910 		regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_GPU3D),
911 				 GPC_PGC_SR(IMX8MM_PGC_GPU3D)),
912 		regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_DISPMIX),
913 				 GPC_PGC_SR(IMX8MM_PGC_DISPMIX)),
914 		regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_VPUG1),
915 				 GPC_PGC_SR(IMX8MM_PGC_VPUG1)),
916 		regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_VPUG2),
917 				 GPC_PGC_SR(IMX8MM_PGC_VPUG2)),
918 		regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_VPUH1),
919 				 GPC_PGC_SR(IMX8MM_PGC_VPUH1)),
920 };
921 
922 static const struct regmap_access_table imx8mm_access_table = {
923 	.yes_ranges	= imx8mm_yes_ranges,
924 	.n_yes_ranges	= ARRAY_SIZE(imx8mm_yes_ranges),
925 };
926 
927 static const struct imx_pgc_domain_data imx8mm_pgc_domain_data = {
928 	.domains = imx8mm_pgc_domains,
929 	.domains_num = ARRAY_SIZE(imx8mm_pgc_domains),
930 	.reg_access_table = &imx8mm_access_table,
931 	.pgc_regs = &imx7_pgc_regs,
932 };
933 
934 static const struct imx_pgc_domain imx8mp_pgc_domains[] = {
935 	[IMX8MP_POWER_DOMAIN_MIPI_PHY1] = {
936 		.genpd = {
937 			.name = "mipi-phy1",
938 		},
939 		.bits = {
940 			.pxx = IMX8MP_MIPI_PHY1_SW_Pxx_REQ,
941 			.map = IMX8MP_MIPI_PHY1_A53_DOMAIN,
942 		},
943 		.pgc = BIT(IMX8MP_PGC_MIPI1),
944 	},
945 
946 	[IMX8MP_POWER_DOMAIN_PCIE_PHY] = {
947 		.genpd = {
948 			.name = "pcie-phy1",
949 		},
950 		.bits = {
951 			.pxx = IMX8MP_PCIE_PHY_SW_Pxx_REQ,
952 			.map = IMX8MP_PCIE_PHY_A53_DOMAIN,
953 		},
954 		.pgc = BIT(IMX8MP_PGC_PCIE),
955 	},
956 
957 	[IMX8MP_POWER_DOMAIN_USB1_PHY] = {
958 		.genpd = {
959 			.name = "usb-otg1",
960 		},
961 		.bits = {
962 			.pxx = IMX8MP_USB1_PHY_Pxx_REQ,
963 			.map = IMX8MP_USB1_PHY_A53_DOMAIN,
964 		},
965 		.pgc = BIT(IMX8MP_PGC_USB1),
966 	},
967 
968 	[IMX8MP_POWER_DOMAIN_USB2_PHY] = {
969 		.genpd = {
970 			.name = "usb-otg2",
971 		},
972 		.bits = {
973 			.pxx = IMX8MP_USB2_PHY_Pxx_REQ,
974 			.map = IMX8MP_USB2_PHY_A53_DOMAIN,
975 		},
976 		.pgc = BIT(IMX8MP_PGC_USB2),
977 	},
978 
979 	[IMX8MP_POWER_DOMAIN_MLMIX] = {
980 		.genpd = {
981 			.name = "mlmix",
982 		},
983 		.bits = {
984 			.pxx = IMX8MP_MLMIX_Pxx_REQ,
985 			.map = IMX8MP_MLMIX_A53_DOMAIN,
986 			.hskreq = IMX8MP_MLMIX_PWRDNREQN,
987 			.hskack = IMX8MP_MLMIX_PWRDNACKN,
988 		},
989 		.pgc = BIT(IMX8MP_PGC_MLMIX),
990 		.keep_clocks = true,
991 	},
992 
993 	[IMX8MP_POWER_DOMAIN_AUDIOMIX] = {
994 		.genpd = {
995 			.name = "audiomix",
996 		},
997 		.bits = {
998 			.pxx = IMX8MP_AUDIOMIX_Pxx_REQ,
999 			.map = IMX8MP_AUDIOMIX_A53_DOMAIN,
1000 			.hskreq = IMX8MP_AUDIOMIX_PWRDNREQN,
1001 			.hskack = IMX8MP_AUDIOMIX_PWRDNACKN,
1002 		},
1003 		.pgc = BIT(IMX8MP_PGC_AUDIOMIX),
1004 		.keep_clocks = true,
1005 	},
1006 
1007 	[IMX8MP_POWER_DOMAIN_GPU2D] = {
1008 		.genpd = {
1009 			.name = "gpu2d",
1010 		},
1011 		.bits = {
1012 			.pxx = IMX8MP_GPU_2D_Pxx_REQ,
1013 			.map = IMX8MP_GPU2D_A53_DOMAIN,
1014 		},
1015 		.pgc = BIT(IMX8MP_PGC_GPU2D),
1016 	},
1017 
1018 	[IMX8MP_POWER_DOMAIN_GPUMIX] = {
1019 		.genpd = {
1020 			.name = "gpumix",
1021 		},
1022 		.bits = {
1023 			.pxx = IMX8MP_GPU_SHARE_LOGIC_Pxx_REQ,
1024 			.map = IMX8MP_GPUMIX_A53_DOMAIN,
1025 			.hskreq = IMX8MP_GPUMIX_PWRDNREQN,
1026 			.hskack = IMX8MP_GPUMIX_PWRDNACKN,
1027 		},
1028 		.pgc = BIT(IMX8MP_PGC_GPUMIX),
1029 		.keep_clocks = true,
1030 	},
1031 
1032 	[IMX8MP_POWER_DOMAIN_VPUMIX] = {
1033 		.genpd = {
1034 			.name = "vpumix",
1035 		},
1036 		.bits = {
1037 			.pxx = IMX8MP_VPU_MIX_SHARE_LOGIC_Pxx_REQ,
1038 			.map = IMX8MP_VPUMIX_A53_DOMAIN,
1039 			.hskreq = IMX8MP_VPUMIX_PWRDNREQN,
1040 			.hskack = IMX8MP_VPUMIX_PWRDNACKN,
1041 		},
1042 		.pgc = BIT(IMX8MP_PGC_VPUMIX),
1043 		.keep_clocks = true,
1044 	},
1045 
1046 	[IMX8MP_POWER_DOMAIN_GPU3D] = {
1047 		.genpd = {
1048 			.name = "gpu3d",
1049 		},
1050 		.bits = {
1051 			.pxx = IMX8MP_GPU_3D_Pxx_REQ,
1052 			.map = IMX8MP_GPU3D_A53_DOMAIN,
1053 		},
1054 		.pgc = BIT(IMX8MP_PGC_GPU3D),
1055 	},
1056 
1057 	[IMX8MP_POWER_DOMAIN_MEDIAMIX] = {
1058 		.genpd = {
1059 			.name = "mediamix",
1060 		},
1061 		.bits = {
1062 			.pxx = IMX8MP_MEDIMIX_Pxx_REQ,
1063 			.map = IMX8MP_MEDIAMIX_A53_DOMAIN,
1064 			.hskreq = IMX8MP_MEDIAMIX_PWRDNREQN,
1065 			.hskack = IMX8MP_MEDIAMIX_PWRDNACKN,
1066 		},
1067 		.pgc = BIT(IMX8MP_PGC_MEDIAMIX),
1068 		.keep_clocks = true,
1069 	},
1070 
1071 	[IMX8MP_POWER_DOMAIN_VPU_G1] = {
1072 		.genpd = {
1073 			.name = "vpu-g1",
1074 		},
1075 		.bits = {
1076 			.pxx = IMX8MP_VPU_G1_Pxx_REQ,
1077 			.map = IMX8MP_VPU_G1_A53_DOMAIN,
1078 		},
1079 		.pgc = BIT(IMX8MP_PGC_VPU_G1),
1080 	},
1081 
1082 	[IMX8MP_POWER_DOMAIN_VPU_G2] = {
1083 		.genpd = {
1084 			.name = "vpu-g2",
1085 		},
1086 		.bits = {
1087 			.pxx = IMX8MP_VPU_G2_Pxx_REQ,
1088 			.map = IMX8MP_VPU_G2_A53_DOMAIN
1089 		},
1090 		.pgc = BIT(IMX8MP_PGC_VPU_G2),
1091 	},
1092 
1093 	[IMX8MP_POWER_DOMAIN_VPU_VC8000E] = {
1094 		.genpd = {
1095 			.name = "vpu-h1",
1096 		},
1097 		.bits = {
1098 			.pxx = IMX8MP_VPU_VC8K_Pxx_REQ,
1099 			.map = IMX8MP_VPU_VC8000E_A53_DOMAIN,
1100 		},
1101 		.pgc = BIT(IMX8MP_PGC_VPU_VC8000E),
1102 	},
1103 
1104 	[IMX8MP_POWER_DOMAIN_HDMIMIX] = {
1105 		.genpd = {
1106 			.name = "hdmimix",
1107 		},
1108 		.bits = {
1109 			.pxx = IMX8MP_HDMIMIX_Pxx_REQ,
1110 			.map = IMX8MP_HDMIMIX_A53_DOMAIN,
1111 			.hskreq = IMX8MP_HDMIMIX_PWRDNREQN,
1112 			.hskack = IMX8MP_HDMIMIX_PWRDNACKN,
1113 		},
1114 		.pgc = BIT(IMX8MP_PGC_HDMIMIX),
1115 		.keep_clocks = true,
1116 	},
1117 
1118 	[IMX8MP_POWER_DOMAIN_HDMI_PHY] = {
1119 		.genpd = {
1120 			.name = "hdmi-phy",
1121 		},
1122 		.bits = {
1123 			.pxx = IMX8MP_HDMI_PHY_Pxx_REQ,
1124 			.map = IMX8MP_HDMI_PHY_A53_DOMAIN,
1125 		},
1126 		.pgc = BIT(IMX8MP_PGC_HDMI),
1127 	},
1128 
1129 	[IMX8MP_POWER_DOMAIN_MIPI_PHY2] = {
1130 		.genpd = {
1131 			.name = "mipi-phy2",
1132 		},
1133 		.bits = {
1134 			.pxx = IMX8MP_MIPI_PHY2_Pxx_REQ,
1135 			.map = IMX8MP_MIPI_PHY2_A53_DOMAIN,
1136 		},
1137 		.pgc = BIT(IMX8MP_PGC_MIPI2),
1138 	},
1139 
1140 	[IMX8MP_POWER_DOMAIN_HSIOMIX] = {
1141 		.genpd = {
1142 			.name = "hsiomix",
1143 		},
1144 		.bits = {
1145 			.pxx = IMX8MP_HSIOMIX_Pxx_REQ,
1146 			.map = IMX8MP_HSIOMIX_A53_DOMAIN,
1147 			.hskreq = IMX8MP_HSIOMIX_PWRDNREQN,
1148 			.hskack = IMX8MP_HSIOMIX_PWRDNACKN,
1149 		},
1150 		.pgc = BIT(IMX8MP_PGC_HSIOMIX),
1151 		.keep_clocks = true,
1152 	},
1153 
1154 	[IMX8MP_POWER_DOMAIN_MEDIAMIX_ISPDWP] = {
1155 		.genpd = {
1156 			.name = "mediamix-isp-dwp",
1157 		},
1158 		.bits = {
1159 			.pxx = IMX8MP_MEDIA_ISP_DWP_Pxx_REQ,
1160 			.map = IMX8MP_MEDIA_ISPDWP_A53_DOMAIN,
1161 		},
1162 		.pgc = BIT(IMX8MP_PGC_MEDIA_ISP_DWP),
1163 	},
1164 };
1165 
1166 static const struct regmap_range imx8mp_yes_ranges[] = {
1167 		regmap_reg_range(GPC_LPCR_A_CORE_BSC,
1168 				 IMX8MP_GPC_PGC_CPU_MAPPING),
1169 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_NOC),
1170 				 GPC_PGC_SR(IMX8MP_PGC_NOC)),
1171 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_MIPI1),
1172 				 GPC_PGC_SR(IMX8MP_PGC_MIPI1)),
1173 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_PCIE),
1174 				 GPC_PGC_SR(IMX8MP_PGC_PCIE)),
1175 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_USB1),
1176 				 GPC_PGC_SR(IMX8MP_PGC_USB1)),
1177 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_USB2),
1178 				 GPC_PGC_SR(IMX8MP_PGC_USB2)),
1179 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_MLMIX),
1180 				 GPC_PGC_SR(IMX8MP_PGC_MLMIX)),
1181 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_AUDIOMIX),
1182 				 GPC_PGC_SR(IMX8MP_PGC_AUDIOMIX)),
1183 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_GPU2D),
1184 				 GPC_PGC_SR(IMX8MP_PGC_GPU2D)),
1185 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_GPUMIX),
1186 				 GPC_PGC_SR(IMX8MP_PGC_GPUMIX)),
1187 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_VPUMIX),
1188 				 GPC_PGC_SR(IMX8MP_PGC_VPUMIX)),
1189 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_GPU3D),
1190 				 GPC_PGC_SR(IMX8MP_PGC_GPU3D)),
1191 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_MEDIAMIX),
1192 				 GPC_PGC_SR(IMX8MP_PGC_MEDIAMIX)),
1193 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_VPU_G1),
1194 				 GPC_PGC_SR(IMX8MP_PGC_VPU_G1)),
1195 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_VPU_G2),
1196 				 GPC_PGC_SR(IMX8MP_PGC_VPU_G2)),
1197 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_VPU_VC8000E),
1198 				 GPC_PGC_SR(IMX8MP_PGC_VPU_VC8000E)),
1199 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_HDMIMIX),
1200 				 GPC_PGC_SR(IMX8MP_PGC_HDMIMIX)),
1201 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_HDMI),
1202 				 GPC_PGC_SR(IMX8MP_PGC_HDMI)),
1203 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_MIPI2),
1204 				 GPC_PGC_SR(IMX8MP_PGC_MIPI2)),
1205 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_HSIOMIX),
1206 				 GPC_PGC_SR(IMX8MP_PGC_HSIOMIX)),
1207 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_MEDIA_ISP_DWP),
1208 				 GPC_PGC_SR(IMX8MP_PGC_MEDIA_ISP_DWP)),
1209 		regmap_reg_range(GPC_PGC_CTRL(IMX8MP_PGC_DDRMIX),
1210 				 GPC_PGC_SR(IMX8MP_PGC_DDRMIX)),
1211 };
1212 
1213 static const struct regmap_access_table imx8mp_access_table = {
1214 	.yes_ranges	= imx8mp_yes_ranges,
1215 	.n_yes_ranges	= ARRAY_SIZE(imx8mp_yes_ranges),
1216 };
1217 
1218 static const struct imx_pgc_regs imx8mp_pgc_regs = {
1219 	.map = IMX8MP_GPC_PGC_CPU_MAPPING,
1220 	.pup = IMX8MP_GPC_PU_PGC_SW_PUP_REQ,
1221 	.pdn = IMX8MP_GPC_PU_PGC_SW_PDN_REQ,
1222 	.hsk = IMX8MP_GPC_PU_PWRHSK,
1223 };
1224 static const struct imx_pgc_domain_data imx8mp_pgc_domain_data = {
1225 	.domains = imx8mp_pgc_domains,
1226 	.domains_num = ARRAY_SIZE(imx8mp_pgc_domains),
1227 	.reg_access_table = &imx8mp_access_table,
1228 	.pgc_regs = &imx8mp_pgc_regs,
1229 };
1230 
1231 static const struct imx_pgc_domain imx8mn_pgc_domains[] = {
1232 	[IMX8MN_POWER_DOMAIN_HSIOMIX] = {
1233 		.genpd = {
1234 			.name = "hsiomix",
1235 		},
1236 		.bits  = {
1237 			.pxx = 0, /* no power sequence control */
1238 			.map = 0, /* no power sequence control */
1239 			.hskreq = IMX8MN_HSIO_HSK_PWRDNREQN,
1240 			.hskack = IMX8MN_HSIO_HSK_PWRDNACKN,
1241 		},
1242 		.keep_clocks = true,
1243 	},
1244 
1245 	[IMX8MN_POWER_DOMAIN_OTG1] = {
1246 		.genpd = {
1247 			.name = "usb-otg1",
1248 			.flags = GENPD_FLAG_ACTIVE_WAKEUP,
1249 		},
1250 		.bits  = {
1251 			.pxx = IMX8MN_OTG1_SW_Pxx_REQ,
1252 			.map = IMX8MN_OTG1_A53_DOMAIN,
1253 		},
1254 		.pgc   = BIT(IMX8MN_PGC_OTG1),
1255 	},
1256 
1257 	[IMX8MN_POWER_DOMAIN_GPUMIX] = {
1258 		.genpd = {
1259 			.name = "gpumix",
1260 		},
1261 		.bits  = {
1262 			.pxx = IMX8MN_GPUMIX_SW_Pxx_REQ,
1263 			.map = IMX8MN_GPUMIX_A53_DOMAIN,
1264 			.hskreq = IMX8MN_GPUMIX_HSK_PWRDNREQN,
1265 			.hskack = IMX8MN_GPUMIX_HSK_PWRDNACKN,
1266 		},
1267 		.pgc   = BIT(IMX8MN_PGC_GPUMIX),
1268 		.keep_clocks = true,
1269 	},
1270 
1271 	[IMX8MN_POWER_DOMAIN_DISPMIX] = {
1272 		.genpd = {
1273 			.name = "dispmix",
1274 		},
1275 			.bits  = {
1276 			.pxx = IMX8MN_DISPMIX_SW_Pxx_REQ,
1277 			.map = IMX8MN_DISPMIX_A53_DOMAIN,
1278 			.hskreq = IMX8MN_DISPMIX_HSK_PWRDNREQN,
1279 			.hskack = IMX8MN_DISPMIX_HSK_PWRDNACKN,
1280 		},
1281 		.pgc   = BIT(IMX8MN_PGC_DISPMIX),
1282 		.keep_clocks = true,
1283 	},
1284 
1285 	[IMX8MN_POWER_DOMAIN_MIPI] = {
1286 		.genpd = {
1287 			.name = "mipi",
1288 		},
1289 			.bits  = {
1290 			.pxx = IMX8MN_MIPI_SW_Pxx_REQ,
1291 			.map = IMX8MN_MIPI_A53_DOMAIN,
1292 		},
1293 		.pgc   = BIT(IMX8MN_PGC_MIPI),
1294 	},
1295 };
1296 
1297 static const struct regmap_range imx8mn_yes_ranges[] = {
1298 	regmap_reg_range(GPC_LPCR_A_CORE_BSC,
1299 			 GPC_PU_PWRHSK),
1300 	regmap_reg_range(GPC_PGC_CTRL(IMX8MN_PGC_MIPI),
1301 			 GPC_PGC_SR(IMX8MN_PGC_MIPI)),
1302 	regmap_reg_range(GPC_PGC_CTRL(IMX8MN_PGC_OTG1),
1303 			 GPC_PGC_SR(IMX8MN_PGC_OTG1)),
1304 	regmap_reg_range(GPC_PGC_CTRL(IMX8MN_PGC_DDR1),
1305 			 GPC_PGC_SR(IMX8MN_PGC_DDR1)),
1306 	regmap_reg_range(GPC_PGC_CTRL(IMX8MN_PGC_GPUMIX),
1307 			 GPC_PGC_SR(IMX8MN_PGC_GPUMIX)),
1308 	regmap_reg_range(GPC_PGC_CTRL(IMX8MN_PGC_DISPMIX),
1309 			 GPC_PGC_SR(IMX8MN_PGC_DISPMIX)),
1310 };
1311 
1312 static const struct regmap_access_table imx8mn_access_table = {
1313 	.yes_ranges	= imx8mn_yes_ranges,
1314 	.n_yes_ranges	= ARRAY_SIZE(imx8mn_yes_ranges),
1315 };
1316 
1317 static const struct imx_pgc_domain_data imx8mn_pgc_domain_data = {
1318 	.domains = imx8mn_pgc_domains,
1319 	.domains_num = ARRAY_SIZE(imx8mn_pgc_domains),
1320 	.reg_access_table = &imx8mn_access_table,
1321 	.pgc_regs = &imx7_pgc_regs,
1322 };
1323 
imx_pgc_domain_probe(struct platform_device * pdev)1324 static int imx_pgc_domain_probe(struct platform_device *pdev)
1325 {
1326 	struct imx_pgc_domain *domain = pdev->dev.platform_data;
1327 	int ret;
1328 
1329 	domain->dev = &pdev->dev;
1330 
1331 	domain->regulator = devm_regulator_get_optional(domain->dev, "power");
1332 	if (IS_ERR(domain->regulator)) {
1333 		if (PTR_ERR(domain->regulator) != -ENODEV)
1334 			return dev_err_probe(domain->dev, PTR_ERR(domain->regulator),
1335 					     "Failed to get domain's regulator\n");
1336 	} else if (domain->voltage) {
1337 		regulator_set_voltage(domain->regulator,
1338 				      domain->voltage, domain->voltage);
1339 	}
1340 
1341 	domain->num_clks = devm_clk_bulk_get_all(domain->dev, &domain->clks);
1342 	if (domain->num_clks < 0)
1343 		return dev_err_probe(domain->dev, domain->num_clks,
1344 				     "Failed to get domain's clocks\n");
1345 
1346 	domain->reset = devm_reset_control_array_get_optional_exclusive(domain->dev);
1347 	if (IS_ERR(domain->reset))
1348 		return dev_err_probe(domain->dev, PTR_ERR(domain->reset),
1349 				     "Failed to get domain's resets\n");
1350 
1351 	pm_runtime_enable(domain->dev);
1352 
1353 	if (domain->bits.map)
1354 		regmap_update_bits(domain->regmap, domain->regs->map,
1355 				   domain->bits.map, domain->bits.map);
1356 
1357 	ret = pm_genpd_init(&domain->genpd, NULL, true);
1358 	if (ret) {
1359 		dev_err(domain->dev, "Failed to init power domain\n");
1360 		goto out_domain_unmap;
1361 	}
1362 
1363 	if (IS_ENABLED(CONFIG_LOCKDEP) &&
1364 	    of_property_read_bool(domain->dev->of_node, "power-domains"))
1365 		lockdep_set_subclass(&domain->genpd.mlock, 1);
1366 
1367 	ret = of_genpd_add_provider_simple(domain->dev->of_node,
1368 					   &domain->genpd);
1369 	if (ret) {
1370 		dev_err(domain->dev, "Failed to add genpd provider\n");
1371 		goto out_genpd_remove;
1372 	}
1373 
1374 	return 0;
1375 
1376 out_genpd_remove:
1377 	pm_genpd_remove(&domain->genpd);
1378 out_domain_unmap:
1379 	if (domain->bits.map)
1380 		regmap_update_bits(domain->regmap, domain->regs->map,
1381 				   domain->bits.map, 0);
1382 	pm_runtime_disable(domain->dev);
1383 
1384 	return ret;
1385 }
1386 
imx_pgc_domain_remove(struct platform_device * pdev)1387 static void imx_pgc_domain_remove(struct platform_device *pdev)
1388 {
1389 	struct imx_pgc_domain *domain = pdev->dev.platform_data;
1390 
1391 	of_genpd_del_provider(domain->dev->of_node);
1392 	pm_genpd_remove(&domain->genpd);
1393 
1394 	if (domain->bits.map)
1395 		regmap_update_bits(domain->regmap, domain->regs->map,
1396 				   domain->bits.map, 0);
1397 
1398 	pm_runtime_disable(domain->dev);
1399 }
1400 
1401 #ifdef CONFIG_PM_SLEEP
imx_pgc_domain_suspend(struct device * dev)1402 static int imx_pgc_domain_suspend(struct device *dev)
1403 {
1404 	int ret;
1405 
1406 	/*
1407 	 * This may look strange, but is done so the generic PM_SLEEP code
1408 	 * can power down our domain and more importantly power it up again
1409 	 * after resume, without tripping over our usage of runtime PM to
1410 	 * power up/down the nested domains.
1411 	 */
1412 	ret = pm_runtime_get_sync(dev);
1413 	if (ret < 0) {
1414 		pm_runtime_put_noidle(dev);
1415 		return ret;
1416 	}
1417 
1418 	return 0;
1419 }
1420 
imx_pgc_domain_resume(struct device * dev)1421 static int imx_pgc_domain_resume(struct device *dev)
1422 {
1423 	return pm_runtime_put(dev);
1424 }
1425 #endif
1426 
1427 static const struct dev_pm_ops imx_pgc_domain_pm_ops = {
1428 	SET_SYSTEM_SLEEP_PM_OPS(imx_pgc_domain_suspend, imx_pgc_domain_resume)
1429 };
1430 
1431 static const struct platform_device_id imx_pgc_domain_id[] = {
1432 	{ "imx-pgc-domain", },
1433 	{ },
1434 };
1435 
1436 static struct platform_driver imx_pgc_domain_driver = {
1437 	.driver = {
1438 		.name = "imx-pgc",
1439 		.pm = &imx_pgc_domain_pm_ops,
1440 	},
1441 	.probe    = imx_pgc_domain_probe,
1442 	.remove_new = imx_pgc_domain_remove,
1443 	.id_table = imx_pgc_domain_id,
1444 };
builtin_platform_driver(imx_pgc_domain_driver)1445 builtin_platform_driver(imx_pgc_domain_driver)
1446 
1447 static int imx_gpcv2_probe(struct platform_device *pdev)
1448 {
1449 	const struct imx_pgc_domain_data *domain_data =
1450 			of_device_get_match_data(&pdev->dev);
1451 
1452 	struct regmap_config regmap_config = {
1453 		.reg_bits	= 32,
1454 		.val_bits	= 32,
1455 		.reg_stride	= 4,
1456 		.rd_table	= domain_data->reg_access_table,
1457 		.wr_table	= domain_data->reg_access_table,
1458 		.max_register   = SZ_4K,
1459 	};
1460 	struct device *dev = &pdev->dev;
1461 	struct device_node *pgc_np;
1462 	struct regmap *regmap;
1463 	void __iomem *base;
1464 	int ret;
1465 
1466 	pgc_np = of_get_child_by_name(dev->of_node, "pgc");
1467 	if (!pgc_np) {
1468 		dev_err(dev, "No power domains specified in DT\n");
1469 		return -EINVAL;
1470 	}
1471 
1472 	base = devm_platform_ioremap_resource(pdev, 0);
1473 	if (IS_ERR(base))
1474 		return PTR_ERR(base);
1475 
1476 	regmap = devm_regmap_init_mmio(dev, base, &regmap_config);
1477 	if (IS_ERR(regmap)) {
1478 		ret = PTR_ERR(regmap);
1479 		dev_err(dev, "failed to init regmap (%d)\n", ret);
1480 		return ret;
1481 	}
1482 
1483 	for_each_child_of_node_scoped(pgc_np, np) {
1484 		struct platform_device *pd_pdev;
1485 		struct imx_pgc_domain *domain;
1486 		u32 domain_index;
1487 
1488 		if (!of_device_is_available(np))
1489 			continue;
1490 
1491 		ret = of_property_read_u32(np, "reg", &domain_index);
1492 		if (ret) {
1493 			dev_err(dev, "Failed to read 'reg' property\n");
1494 			return ret;
1495 		}
1496 
1497 		if (domain_index >= domain_data->domains_num) {
1498 			dev_warn(dev,
1499 				 "Domain index %d is out of bounds\n",
1500 				 domain_index);
1501 			continue;
1502 		}
1503 
1504 		pd_pdev = platform_device_alloc("imx-pgc-domain",
1505 						domain_index);
1506 		if (!pd_pdev) {
1507 			dev_err(dev, "Failed to allocate platform device\n");
1508 			return -ENOMEM;
1509 		}
1510 
1511 		ret = platform_device_add_data(pd_pdev,
1512 					       &domain_data->domains[domain_index],
1513 					       sizeof(domain_data->domains[domain_index]));
1514 		if (ret) {
1515 			platform_device_put(pd_pdev);
1516 			return ret;
1517 		}
1518 
1519 		domain = pd_pdev->dev.platform_data;
1520 		domain->regmap = regmap;
1521 		domain->regs = domain_data->pgc_regs;
1522 
1523 		domain->genpd.power_on  = imx_pgc_power_up;
1524 		domain->genpd.power_off = imx_pgc_power_down;
1525 
1526 		pd_pdev->dev.parent = dev;
1527 		device_set_node(&pd_pdev->dev, of_fwnode_handle(np));
1528 
1529 		ret = platform_device_add(pd_pdev);
1530 		if (ret) {
1531 			platform_device_put(pd_pdev);
1532 			return ret;
1533 		}
1534 	}
1535 
1536 	return 0;
1537 }
1538 
1539 static const struct of_device_id imx_gpcv2_dt_ids[] = {
1540 	{ .compatible = "fsl,imx7d-gpc", .data = &imx7_pgc_domain_data, },
1541 	{ .compatible = "fsl,imx8mm-gpc", .data = &imx8mm_pgc_domain_data, },
1542 	{ .compatible = "fsl,imx8mn-gpc", .data = &imx8mn_pgc_domain_data, },
1543 	{ .compatible = "fsl,imx8mp-gpc", .data = &imx8mp_pgc_domain_data, },
1544 	{ .compatible = "fsl,imx8mq-gpc", .data = &imx8m_pgc_domain_data, },
1545 	{ }
1546 };
1547 
1548 static struct platform_driver imx_gpc_driver = {
1549 	.driver = {
1550 		.name = "imx-gpcv2",
1551 		.of_match_table = imx_gpcv2_dt_ids,
1552 	},
1553 	.probe = imx_gpcv2_probe,
1554 };
1555 builtin_platform_driver(imx_gpc_driver)
1556