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, ®_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, ®map_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