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