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