brintos

brintos / linux-shallow public Read only

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