File Index
Files and directories
Sign in
FILE

gpcv2.c

File preview with syntax highlighting.

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