Linux Audio

Check our new training course

Loading...
v5.9
  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_device.h>
 13#include <linux/platform_device.h>
 14#include <linux/pm_domain.h>
 
 15#include <linux/regmap.h>
 16#include <linux/regulator/consumer.h>
 
 17#include <linux/sizes.h>
 18#include <dt-bindings/power/imx7-power.h>
 19#include <dt-bindings/power/imx8mq-power.h>
 
 
 
 20
 21#define GPC_LPCR_A_CORE_BSC			0x000
 22
 23#define GPC_PGC_CPU_MAPPING		0x0ec
 
 24
 25#define IMX7_USB_HSIC_PHY_A_CORE_DOMAIN		BIT(6)
 26#define IMX7_USB_OTG2_PHY_A_CORE_DOMAIN		BIT(5)
 27#define IMX7_USB_OTG1_PHY_A_CORE_DOMAIN		BIT(4)
 28#define IMX7_PCIE_PHY_A_CORE_DOMAIN		BIT(3)
 29#define IMX7_MIPI_PHY_A_CORE_DOMAIN		BIT(2)
 30
 31#define IMX8M_PCIE2_A53_DOMAIN			BIT(15)
 32#define IMX8M_MIPI_CSI2_A53_DOMAIN		BIT(14)
 33#define IMX8M_MIPI_CSI1_A53_DOMAIN		BIT(13)
 34#define IMX8M_DISP_A53_DOMAIN			BIT(12)
 35#define IMX8M_HDMI_A53_DOMAIN			BIT(11)
 36#define IMX8M_VPU_A53_DOMAIN			BIT(10)
 37#define IMX8M_GPU_A53_DOMAIN			BIT(9)
 38#define IMX8M_DDR2_A53_DOMAIN			BIT(8)
 39#define IMX8M_DDR1_A53_DOMAIN			BIT(7)
 40#define IMX8M_OTG2_A53_DOMAIN			BIT(5)
 41#define IMX8M_OTG1_A53_DOMAIN			BIT(4)
 42#define IMX8M_PCIE1_A53_DOMAIN			BIT(3)
 43#define IMX8M_MIPI_A53_DOMAIN			BIT(2)
 44
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 45#define GPC_PU_PGC_SW_PUP_REQ		0x0f8
 46#define GPC_PU_PGC_SW_PDN_REQ		0x104
 47
 48#define IMX7_USB_HSIC_PHY_SW_Pxx_REQ		BIT(4)
 49#define IMX7_USB_OTG2_PHY_SW_Pxx_REQ		BIT(3)
 50#define IMX7_USB_OTG1_PHY_SW_Pxx_REQ		BIT(2)
 51#define IMX7_PCIE_PHY_SW_Pxx_REQ		BIT(1)
 52#define IMX7_MIPI_PHY_SW_Pxx_REQ		BIT(0)
 53
 54#define IMX8M_PCIE2_SW_Pxx_REQ			BIT(13)
 55#define IMX8M_MIPI_CSI2_SW_Pxx_REQ		BIT(12)
 56#define IMX8M_MIPI_CSI1_SW_Pxx_REQ		BIT(11)
 57#define IMX8M_DISP_SW_Pxx_REQ			BIT(10)
 58#define IMX8M_HDMI_SW_Pxx_REQ			BIT(9)
 59#define IMX8M_VPU_SW_Pxx_REQ			BIT(8)
 60#define IMX8M_GPU_SW_Pxx_REQ			BIT(7)
 61#define IMX8M_DDR2_SW_Pxx_REQ			BIT(6)
 62#define IMX8M_DDR1_SW_Pxx_REQ			BIT(5)
 63#define IMX8M_OTG2_SW_Pxx_REQ			BIT(3)
 64#define IMX8M_OTG1_SW_Pxx_REQ			BIT(2)
 65#define IMX8M_PCIE1_SW_Pxx_REQ			BIT(1)
 66#define IMX8M_MIPI_SW_Pxx_REQ			BIT(0)
 67
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 68#define GPC_M4_PU_PDN_FLG		0x1bc
 69
 
 70#define GPC_PU_PWRHSK			0x1fc
 71
 
 
 
 72#define IMX8M_GPU_HSK_PWRDNREQN			BIT(6)
 73#define IMX8M_VPU_HSK_PWRDNREQN			BIT(5)
 74#define IMX8M_DISP_HSK_PWRDNREQN		BIT(4)
 75
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 76/*
 77 * The PGC offset values in Reference Manual
 78 * (Rev. 1, 01/2018 and the older ones) GPC chapter's
 79 * GPC_PGC memory map are incorrect, below offset
 80 * values are from design RTL.
 81 */
 82#define IMX7_PGC_MIPI			16
 83#define IMX7_PGC_PCIE			17
 84#define IMX7_PGC_USB_HSIC		20
 85
 86#define IMX8M_PGC_MIPI			16
 87#define IMX8M_PGC_PCIE1			17
 88#define IMX8M_PGC_OTG1			18
 89#define IMX8M_PGC_OTG2			19
 90#define IMX8M_PGC_DDR1			21
 91#define IMX8M_PGC_GPU			23
 92#define IMX8M_PGC_VPU			24
 93#define IMX8M_PGC_DISP			26
 94#define IMX8M_PGC_MIPI_CSI1		27
 95#define IMX8M_PGC_MIPI_CSI2		28
 96#define IMX8M_PGC_PCIE2			29
 97
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 98#define GPC_PGC_CTRL(n)			(0x800 + (n) * 0x40)
 99#define GPC_PGC_SR(n)			(GPC_PGC_CTRL(n) + 0xc)
100
101#define GPC_PGC_CTRL_PCR		BIT(0)
102
103#define GPC_CLK_MAX		6
 
 
 
 
 
104
105struct imx_pgc_domain {
106	struct generic_pm_domain genpd;
107	struct regmap *regmap;
 
108	struct regulator *regulator;
109	struct clk *clk[GPC_CLK_MAX];
 
110	int num_clks;
111
112	unsigned int pgc;
113
114	const struct {
115		u32 pxx;
116		u32 map;
117		u32 hsk;
 
118	} bits;
119
120	const int voltage;
 
121	struct device *dev;
 
 
 
122};
123
124struct imx_pgc_domain_data {
125	const struct imx_pgc_domain *domains;
126	size_t domains_num;
127	const struct regmap_access_table *reg_access_table;
 
128};
129
130static int imx_gpc_pu_pgc_sw_pxx_req(struct generic_pm_domain *genpd,
131				      bool on)
132{
133	struct imx_pgc_domain *domain = container_of(genpd,
134						      struct imx_pgc_domain,
135						      genpd);
136	unsigned int offset = on ?
137		GPC_PU_PGC_SW_PUP_REQ : GPC_PU_PGC_SW_PDN_REQ;
138	const bool enable_power_control = !on;
139	const bool has_regulator = !IS_ERR(domain->regulator);
140	int i, ret = 0;
141	u32 pxx_req;
142
143	regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING,
144			   domain->bits.map, domain->bits.map);
 
 
 
145
146	if (has_regulator && on) {
 
 
 
 
 
 
147		ret = regulator_enable(domain->regulator);
148		if (ret) {
149			dev_err(domain->dev, "failed to enable regulator\n");
150			goto unmap;
 
 
151		}
152	}
153
154	/* Enable reset clocks for all devices in the domain */
155	for (i = 0; i < domain->num_clks; i++)
156		clk_prepare_enable(domain->clk[i]);
157
158	if (enable_power_control)
159		regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc),
160				   GPC_PGC_CTRL_PCR, GPC_PGC_CTRL_PCR);
161
162	if (domain->bits.hsk)
163		regmap_update_bits(domain->regmap, GPC_PU_PWRHSK,
164				   domain->bits.hsk, on ? domain->bits.hsk : 0);
165
166	regmap_update_bits(domain->regmap, offset,
167			   domain->bits.pxx, domain->bits.pxx);
168
169	/*
170	 * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait
171	 * for PUP_REQ/PDN_REQ bit to be cleared
172	 */
173	ret = regmap_read_poll_timeout(domain->regmap, offset, pxx_req,
174				       !(pxx_req & domain->bits.pxx),
175				       0, USEC_PER_MSEC);
176	if (ret) {
177		dev_err(domain->dev, "failed to command PGC\n");
178		/*
179		 * If we were in a process of enabling a
180		 * domain and failed we might as well disable
181		 * the regulator we just enabled. And if it
182		 * was the opposite situation and we failed to
183		 * power down -- keep the regulator on
184		 */
185		on = !on;
 
 
 
 
 
 
 
 
 
 
 
 
 
186	}
187
188	if (enable_power_control)
189		regmap_update_bits(domain->regmap, GPC_PGC_CTRL(domain->pgc),
190				   GPC_PGC_CTRL_PCR, 0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
192	/* Disable reset clocks for all devices in the domain */
193	for (i = 0; i < domain->num_clks; i++)
194		clk_disable_unprepare(domain->clk[i]);
195
196	if (has_regulator && !on) {
197		int err;
 
 
 
 
 
 
 
198
199		err = regulator_disable(domain->regulator);
200		if (err)
201			dev_err(domain->dev,
202				"failed to disable regulator: %d\n", err);
203		/* Preserve earlier error code */
204		ret = ret ?: err;
205	}
206unmap:
207	regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING,
208			   domain->bits.map, 0);
209	return ret;
210}
211
212static int imx_gpc_pu_pgc_sw_pup_req(struct generic_pm_domain *genpd)
213{
214	return imx_gpc_pu_pgc_sw_pxx_req(genpd, true);
215}
 
216
217static int imx_gpc_pu_pgc_sw_pdn_req(struct generic_pm_domain *genpd)
218{
219	return imx_gpc_pu_pgc_sw_pxx_req(genpd, false);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220}
221
222static const struct imx_pgc_domain imx7_pgc_domains[] = {
223	[IMX7_POWER_DOMAIN_MIPI_PHY] = {
224		.genpd = {
225			.name      = "mipi-phy",
226		},
227		.bits  = {
228			.pxx = IMX7_MIPI_PHY_SW_Pxx_REQ,
229			.map = IMX7_MIPI_PHY_A_CORE_DOMAIN,
230		},
231		.voltage   = 1000000,
232		.pgc	   = IMX7_PGC_MIPI,
233	},
234
235	[IMX7_POWER_DOMAIN_PCIE_PHY] = {
236		.genpd = {
237			.name      = "pcie-phy",
238		},
239		.bits  = {
240			.pxx = IMX7_PCIE_PHY_SW_Pxx_REQ,
241			.map = IMX7_PCIE_PHY_A_CORE_DOMAIN,
242		},
243		.voltage   = 1000000,
244		.pgc	   = IMX7_PGC_PCIE,
245	},
246
247	[IMX7_POWER_DOMAIN_USB_HSIC_PHY] = {
248		.genpd = {
249			.name      = "usb-hsic-phy",
250		},
251		.bits  = {
252			.pxx = IMX7_USB_HSIC_PHY_SW_Pxx_REQ,
253			.map = IMX7_USB_HSIC_PHY_A_CORE_DOMAIN,
254		},
255		.voltage   = 1200000,
256		.pgc	   = IMX7_PGC_USB_HSIC,
257	},
258};
259
260static const struct regmap_range imx7_yes_ranges[] = {
261		regmap_reg_range(GPC_LPCR_A_CORE_BSC,
262				 GPC_M4_PU_PDN_FLG),
263		regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_MIPI),
264				 GPC_PGC_SR(IMX7_PGC_MIPI)),
265		regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_PCIE),
266				 GPC_PGC_SR(IMX7_PGC_PCIE)),
267		regmap_reg_range(GPC_PGC_CTRL(IMX7_PGC_USB_HSIC),
268				 GPC_PGC_SR(IMX7_PGC_USB_HSIC)),
269};
270
271static const struct regmap_access_table imx7_access_table = {
272	.yes_ranges	= imx7_yes_ranges,
273	.n_yes_ranges	= ARRAY_SIZE(imx7_yes_ranges),
274};
275
 
 
 
 
 
 
 
276static const struct imx_pgc_domain_data imx7_pgc_domain_data = {
277	.domains = imx7_pgc_domains,
278	.domains_num = ARRAY_SIZE(imx7_pgc_domains),
279	.reg_access_table = &imx7_access_table,
 
280};
281
282static const struct imx_pgc_domain imx8m_pgc_domains[] = {
283	[IMX8M_POWER_DOMAIN_MIPI] = {
284		.genpd = {
285			.name      = "mipi",
286		},
287		.bits  = {
288			.pxx = IMX8M_MIPI_SW_Pxx_REQ,
289			.map = IMX8M_MIPI_A53_DOMAIN,
290		},
291		.pgc	   = IMX8M_PGC_MIPI,
292	},
293
294	[IMX8M_POWER_DOMAIN_PCIE1] = {
295		.genpd = {
296			.name = "pcie1",
297		},
298		.bits  = {
299			.pxx = IMX8M_PCIE1_SW_Pxx_REQ,
300			.map = IMX8M_PCIE1_A53_DOMAIN,
301		},
302		.pgc   = IMX8M_PGC_PCIE1,
303	},
304
305	[IMX8M_POWER_DOMAIN_USB_OTG1] = {
306		.genpd = {
307			.name = "usb-otg1",
308		},
309		.bits  = {
310			.pxx = IMX8M_OTG1_SW_Pxx_REQ,
311			.map = IMX8M_OTG1_A53_DOMAIN,
312		},
313		.pgc   = IMX8M_PGC_OTG1,
314	},
315
316	[IMX8M_POWER_DOMAIN_USB_OTG2] = {
317		.genpd = {
318			.name = "usb-otg2",
319		},
320		.bits  = {
321			.pxx = IMX8M_OTG2_SW_Pxx_REQ,
322			.map = IMX8M_OTG2_A53_DOMAIN,
323		},
324		.pgc   = IMX8M_PGC_OTG2,
325	},
326
327	[IMX8M_POWER_DOMAIN_DDR1] = {
328		.genpd = {
329			.name = "ddr1",
330		},
331		.bits  = {
332			.pxx = IMX8M_DDR1_SW_Pxx_REQ,
333			.map = IMX8M_DDR2_A53_DOMAIN,
334		},
335		.pgc   = IMX8M_PGC_DDR1,
336	},
337
338	[IMX8M_POWER_DOMAIN_GPU] = {
339		.genpd = {
340			.name = "gpu",
341		},
342		.bits  = {
343			.pxx = IMX8M_GPU_SW_Pxx_REQ,
344			.map = IMX8M_GPU_A53_DOMAIN,
345			.hsk = IMX8M_GPU_HSK_PWRDNREQN,
 
346		},
347		.pgc   = IMX8M_PGC_GPU,
348	},
349
350	[IMX8M_POWER_DOMAIN_VPU] = {
351		.genpd = {
352			.name = "vpu",
353		},
354		.bits  = {
355			.pxx = IMX8M_VPU_SW_Pxx_REQ,
356			.map = IMX8M_VPU_A53_DOMAIN,
357			.hsk = IMX8M_VPU_HSK_PWRDNREQN,
 
358		},
359		.pgc   = IMX8M_PGC_VPU,
 
360	},
361
362	[IMX8M_POWER_DOMAIN_DISP] = {
363		.genpd = {
364			.name = "disp",
365		},
366		.bits  = {
367			.pxx = IMX8M_DISP_SW_Pxx_REQ,
368			.map = IMX8M_DISP_A53_DOMAIN,
369			.hsk = IMX8M_DISP_HSK_PWRDNREQN,
 
370		},
371		.pgc   = IMX8M_PGC_DISP,
372	},
373
374	[IMX8M_POWER_DOMAIN_MIPI_CSI1] = {
375		.genpd = {
376			.name = "mipi-csi1",
377		},
378		.bits  = {
379			.pxx = IMX8M_MIPI_CSI1_SW_Pxx_REQ,
380			.map = IMX8M_MIPI_CSI1_A53_DOMAIN,
381		},
382		.pgc   = IMX8M_PGC_MIPI_CSI1,
383	},
384
385	[IMX8M_POWER_DOMAIN_MIPI_CSI2] = {
386		.genpd = {
387			.name = "mipi-csi2",
388		},
389		.bits  = {
390			.pxx = IMX8M_MIPI_CSI2_SW_Pxx_REQ,
391			.map = IMX8M_MIPI_CSI2_A53_DOMAIN,
392		},
393		.pgc   = IMX8M_PGC_MIPI_CSI2,
394	},
395
396	[IMX8M_POWER_DOMAIN_PCIE2] = {
397		.genpd = {
398			.name = "pcie2",
399		},
400		.bits  = {
401			.pxx = IMX8M_PCIE2_SW_Pxx_REQ,
402			.map = IMX8M_PCIE2_A53_DOMAIN,
403		},
404		.pgc   = IMX8M_PGC_PCIE2,
405	},
406};
407
408static const struct regmap_range imx8m_yes_ranges[] = {
409		regmap_reg_range(GPC_LPCR_A_CORE_BSC,
410				 GPC_PU_PWRHSK),
411		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI),
412				 GPC_PGC_SR(IMX8M_PGC_MIPI)),
413		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_PCIE1),
414				 GPC_PGC_SR(IMX8M_PGC_PCIE1)),
415		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_OTG1),
416				 GPC_PGC_SR(IMX8M_PGC_OTG1)),
417		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_OTG2),
418				 GPC_PGC_SR(IMX8M_PGC_OTG2)),
419		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_DDR1),
420				 GPC_PGC_SR(IMX8M_PGC_DDR1)),
421		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_GPU),
422				 GPC_PGC_SR(IMX8M_PGC_GPU)),
423		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_VPU),
424				 GPC_PGC_SR(IMX8M_PGC_VPU)),
425		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_DISP),
426				 GPC_PGC_SR(IMX8M_PGC_DISP)),
427		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI_CSI1),
428				 GPC_PGC_SR(IMX8M_PGC_MIPI_CSI1)),
429		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_MIPI_CSI2),
430				 GPC_PGC_SR(IMX8M_PGC_MIPI_CSI2)),
431		regmap_reg_range(GPC_PGC_CTRL(IMX8M_PGC_PCIE2),
432				 GPC_PGC_SR(IMX8M_PGC_PCIE2)),
433};
434
435static const struct regmap_access_table imx8m_access_table = {
436	.yes_ranges	= imx8m_yes_ranges,
437	.n_yes_ranges	= ARRAY_SIZE(imx8m_yes_ranges),
438};
439
440static const struct imx_pgc_domain_data imx8m_pgc_domain_data = {
441	.domains = imx8m_pgc_domains,
442	.domains_num = ARRAY_SIZE(imx8m_pgc_domains),
443	.reg_access_table = &imx8m_access_table,
 
444};
445
446static int imx_pgc_get_clocks(struct imx_pgc_domain *domain)
447{
448	int i, ret;
 
 
 
 
 
 
 
 
 
 
449
450	for (i = 0; ; i++) {
451		struct clk *clk = of_clk_get(domain->dev->of_node, i);
452		if (IS_ERR(clk))
453			break;
454		if (i >= GPC_CLK_MAX) {
455			dev_err(domain->dev, "more than %d clocks\n",
456				GPC_CLK_MAX);
457			ret = -EINVAL;
458			goto clk_err;
459		}
460		domain->clk[i] = clk;
461	}
462	domain->num_clks = i;
463
464	return 0;
 
 
 
 
 
 
 
 
 
 
465
466clk_err:
467	while (i--)
468		clk_put(domain->clk[i]);
 
 
 
 
 
 
 
 
469
470	return ret;
471}
 
 
 
 
 
 
 
 
 
 
 
472
473static void imx_pgc_put_clocks(struct imx_pgc_domain *domain)
474{
475	int i;
 
 
 
 
 
 
 
 
 
476
477	for (i = domain->num_clks - 1; i >= 0; i--)
478		clk_put(domain->clk[i]);
479}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
480
481static int imx_pgc_domain_probe(struct platform_device *pdev)
482{
483	struct imx_pgc_domain *domain = pdev->dev.platform_data;
484	int ret;
485
486	domain->dev = &pdev->dev;
487
488	domain->regulator = devm_regulator_get_optional(domain->dev, "power");
489	if (IS_ERR(domain->regulator)) {
490		if (PTR_ERR(domain->regulator) != -ENODEV) {
491			if (PTR_ERR(domain->regulator) != -EPROBE_DEFER)
492				dev_err(domain->dev, "Failed to get domain's regulator\n");
493			return PTR_ERR(domain->regulator);
494		}
495	} else if (domain->voltage) {
496		regulator_set_voltage(domain->regulator,
497				      domain->voltage, domain->voltage);
498	}
499
500	ret = imx_pgc_get_clocks(domain);
501	if (ret) {
502		if (ret != -EPROBE_DEFER)
503			dev_err(domain->dev, "Failed to get domain's clocks\n");
504		return ret;
505	}
 
 
 
 
 
 
 
 
 
506
507	ret = pm_genpd_init(&domain->genpd, NULL, true);
508	if (ret) {
509		dev_err(domain->dev, "Failed to init power domain\n");
510		imx_pgc_put_clocks(domain);
511		return ret;
512	}
513
 
 
 
 
514	ret = of_genpd_add_provider_simple(domain->dev->of_node,
515					   &domain->genpd);
516	if (ret) {
517		dev_err(domain->dev, "Failed to add genpd provider\n");
518		pm_genpd_remove(&domain->genpd);
519		imx_pgc_put_clocks(domain);
520	}
521
 
 
 
 
 
 
 
 
 
 
522	return ret;
523}
524
525static int imx_pgc_domain_remove(struct platform_device *pdev)
526{
527	struct imx_pgc_domain *domain = pdev->dev.platform_data;
528
529	of_genpd_del_provider(domain->dev->of_node);
530	pm_genpd_remove(&domain->genpd);
531	imx_pgc_put_clocks(domain);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
532
533	return 0;
534}
535
 
 
 
 
 
 
 
 
 
 
536static const struct platform_device_id imx_pgc_domain_id[] = {
537	{ "imx-pgc-domain", },
538	{ },
539};
540
541static struct platform_driver imx_pgc_domain_driver = {
542	.driver = {
543		.name = "imx-pgc",
 
544	},
545	.probe    = imx_pgc_domain_probe,
546	.remove   = imx_pgc_domain_remove,
547	.id_table = imx_pgc_domain_id,
548};
549builtin_platform_driver(imx_pgc_domain_driver)
550
551static int imx_gpcv2_probe(struct platform_device *pdev)
552{
553	const struct imx_pgc_domain_data *domain_data =
554			of_device_get_match_data(&pdev->dev);
555
556	struct regmap_config regmap_config = {
557		.reg_bits	= 32,
558		.val_bits	= 32,
559		.reg_stride	= 4,
560		.rd_table	= domain_data->reg_access_table,
561		.wr_table	= domain_data->reg_access_table,
562		.max_register   = SZ_4K,
563	};
564	struct device *dev = &pdev->dev;
565	struct device_node *pgc_np, *np;
566	struct regmap *regmap;
567	void __iomem *base;
568	int ret;
569
570	pgc_np = of_get_child_by_name(dev->of_node, "pgc");
571	if (!pgc_np) {
572		dev_err(dev, "No power domains specified in DT\n");
573		return -EINVAL;
574	}
575
576	base = devm_platform_ioremap_resource(pdev, 0);
577	if (IS_ERR(base))
578		return PTR_ERR(base);
579
580	regmap = devm_regmap_init_mmio(dev, base, &regmap_config);
581	if (IS_ERR(regmap)) {
582		ret = PTR_ERR(regmap);
583		dev_err(dev, "failed to init regmap (%d)\n", ret);
584		return ret;
585	}
586
587	for_each_child_of_node(pgc_np, np) {
588		struct platform_device *pd_pdev;
589		struct imx_pgc_domain *domain;
590		u32 domain_index;
591
 
 
 
592		ret = of_property_read_u32(np, "reg", &domain_index);
593		if (ret) {
594			dev_err(dev, "Failed to read 'reg' property\n");
595			of_node_put(np);
596			return ret;
597		}
598
599		if (domain_index >= domain_data->domains_num) {
600			dev_warn(dev,
601				 "Domain index %d is out of bounds\n",
602				 domain_index);
603			continue;
604		}
605
606		pd_pdev = platform_device_alloc("imx-pgc-domain",
607						domain_index);
608		if (!pd_pdev) {
609			dev_err(dev, "Failed to allocate platform device\n");
610			of_node_put(np);
611			return -ENOMEM;
612		}
613
614		ret = platform_device_add_data(pd_pdev,
615					       &domain_data->domains[domain_index],
616					       sizeof(domain_data->domains[domain_index]));
617		if (ret) {
618			platform_device_put(pd_pdev);
619			of_node_put(np);
620			return ret;
621		}
622
623		domain = pd_pdev->dev.platform_data;
624		domain->regmap = regmap;
625		domain->genpd.power_on  = imx_gpc_pu_pgc_sw_pup_req;
626		domain->genpd.power_off = imx_gpc_pu_pgc_sw_pdn_req;
 
 
627
628		pd_pdev->dev.parent = dev;
629		pd_pdev->dev.of_node = np;
630
631		ret = platform_device_add(pd_pdev);
632		if (ret) {
633			platform_device_put(pd_pdev);
634			of_node_put(np);
635			return ret;
636		}
637	}
638
639	return 0;
640}
641
642static const struct of_device_id imx_gpcv2_dt_ids[] = {
643	{ .compatible = "fsl,imx7d-gpc", .data = &imx7_pgc_domain_data, },
 
 
 
644	{ .compatible = "fsl,imx8mq-gpc", .data = &imx8m_pgc_domain_data, },
645	{ }
646};
647
648static struct platform_driver imx_gpc_driver = {
649	.driver = {
650		.name = "imx-gpcv2",
651		.of_match_table = imx_gpcv2_dt_ids,
652	},
653	.probe = imx_gpcv2_probe,
654};
655builtin_platform_driver(imx_gpc_driver)
v6.2
   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_device.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		pd_pdev->dev.of_node = 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)