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