soc: imx: gpcv2: add support for i.MX8MM power domains
authorLucas Stach <l.stach@pengutronix.de>
Mon, 10 May 2021 04:00:43 +0000 (12:00 +0800)
committerShawn Guo <shawnguo@kernel.org>
Thu, 27 May 2021 01:01:36 +0000 (09:01 +0800)
This adds support for the power domains found on i.MX8MM. The 2D and 3D
GPU domains are abstracted as a single domain in the driver, as they can't
be powered up/down individually due to a shared reset.

Tested-by: Frieder Schrempf <frieder.schrempf@kontron.de>
Reviewed-by: Frieder Schrempf <frieder.schrempf@kontron.de>
Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
Signed-off-by: Peng Fan <peng.fan@nxp.com>
Signed-off-by: Shawn Guo <shawnguo@kernel.org>
drivers/soc/imx/gpcv2.c

index 04ce643..d676e65 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/sizes.h>
 #include <dt-bindings/power/imx7-power.h>
 #include <dt-bindings/power/imx8mq-power.h>
+#include <dt-bindings/power/imx8mm-power.h>
 
 #define GPC_LPCR_A_CORE_BSC                    0x000
 
 #define IMX8M_PCIE1_A53_DOMAIN                 BIT(3)
 #define IMX8M_MIPI_A53_DOMAIN                  BIT(2)
 
+#define IMX8MM_VPUH1_A53_DOMAIN                        BIT(15)
+#define IMX8MM_VPUG2_A53_DOMAIN                        BIT(14)
+#define IMX8MM_VPUG1_A53_DOMAIN                        BIT(13)
+#define IMX8MM_DISPMIX_A53_DOMAIN              BIT(12)
+#define IMX8MM_VPUMIX_A53_DOMAIN               BIT(10)
+#define IMX8MM_GPUMIX_A53_DOMAIN               BIT(9)
+#define IMX8MM_GPU_A53_DOMAIN                  (BIT(8) | BIT(11))
+#define IMX8MM_DDR1_A53_DOMAIN                 BIT(7)
+#define IMX8MM_OTG2_A53_DOMAIN                 BIT(5)
+#define IMX8MM_OTG1_A53_DOMAIN                 BIT(4)
+#define IMX8MM_PCIE_A53_DOMAIN                 BIT(3)
+#define IMX8MM_MIPI_A53_DOMAIN                 BIT(2)
+
 #define GPC_PU_PGC_SW_PUP_REQ          0x0f8
 #define GPC_PU_PGC_SW_PDN_REQ          0x104
 
 #define IMX8M_PCIE1_SW_Pxx_REQ                 BIT(1)
 #define IMX8M_MIPI_SW_Pxx_REQ                  BIT(0)
 
+#define IMX8MM_VPUH1_SW_Pxx_REQ                        BIT(13)
+#define IMX8MM_VPUG2_SW_Pxx_REQ                        BIT(12)
+#define IMX8MM_VPUG1_SW_Pxx_REQ                        BIT(11)
+#define IMX8MM_DISPMIX_SW_Pxx_REQ              BIT(10)
+#define IMX8MM_VPUMIX_SW_Pxx_REQ               BIT(8)
+#define IMX8MM_GPUMIX_SW_Pxx_REQ               BIT(7)
+#define IMX8MM_GPU_SW_Pxx_REQ                  (BIT(6) | BIT(9))
+#define IMX8MM_DDR1_SW_Pxx_REQ                 BIT(5)
+#define IMX8MM_OTG2_SW_Pxx_REQ                 BIT(3)
+#define IMX8MM_OTG1_SW_Pxx_REQ                 BIT(2)
+#define IMX8MM_PCIE_SW_Pxx_REQ                 BIT(1)
+#define IMX8MM_MIPI_SW_Pxx_REQ                 BIT(0)
+
 #define GPC_M4_PU_PDN_FLG              0x1bc
 
 #define GPC_PU_PWRHSK                  0x1fc
 #define IMX8M_VPU_HSK_PWRDNREQN                        BIT(5)
 #define IMX8M_DISP_HSK_PWRDNREQN               BIT(4)
 
+
+#define IMX8MM_GPUMIX_HSK_PWRDNACKN            BIT(29)
+#define IMX8MM_GPU_HSK_PWRDNACKN               (BIT(27) | BIT(28))
+#define IMX8MM_VPUMIX_HSK_PWRDNACKN            BIT(26)
+#define IMX8MM_DISPMIX_HSK_PWRDNACKN           BIT(25)
+#define IMX8MM_HSIO_HSK_PWRDNACKN              (BIT(23) | BIT(24))
+#define IMX8MM_GPUMIX_HSK_PWRDNREQN            BIT(11)
+#define IMX8MM_GPU_HSK_PWRDNREQN               (BIT(9) | BIT(10))
+#define IMX8MM_VPUMIX_HSK_PWRDNREQN            BIT(8)
+#define IMX8MM_DISPMIX_HSK_PWRDNREQN           BIT(7)
+#define IMX8MM_HSIO_HSK_PWRDNREQN              (BIT(5) | BIT(6))
 /*
  * The PGC offset values in Reference Manual
  * (Rev. 1, 01/2018 and the older ones) GPC chapter's
 #define IMX8M_PGC_MIPI_CSI2            28
 #define IMX8M_PGC_PCIE2                        29
 
+#define IMX8MM_PGC_MIPI                        16
+#define IMX8MM_PGC_PCIE                        17
+#define IMX8MM_PGC_OTG1                        18
+#define IMX8MM_PGC_OTG2                        19
+#define IMX8MM_PGC_DDR1                        21
+#define IMX8MM_PGC_GPU2D               22
+#define IMX8MM_PGC_GPUMIX              23
+#define IMX8MM_PGC_VPUMIX              24
+#define IMX8MM_PGC_GPU3D               25
+#define IMX8MM_PGC_DISPMIX             26
+#define IMX8MM_PGC_VPUG1               27
+#define IMX8MM_PGC_VPUG2               28
+#define IMX8MM_PGC_VPUH1               29
+
 #define GPC_PGC_CTRL(n)                        (0x800 + (n) * 0x40)
 #define GPC_PGC_SR(n)                  (GPC_PGC_CTRL(n) + 0xc)
 
@@ -527,6 +579,121 @@ static const struct imx_pgc_domain_data imx8m_pgc_domain_data = {
        .reg_access_table = &imx8m_access_table,
 };
 
+static const struct imx_pgc_domain imx8mm_pgc_domains[] = {
+       [IMX8MM_POWER_DOMAIN_HSIOMIX] = {
+               .genpd = {
+                       .name = "hsiomix",
+               },
+               .bits  = {
+                       .pxx = 0, /* no power sequence control */
+                       .map = 0, /* no power sequence control */
+                       .hskreq = IMX8MM_HSIO_HSK_PWRDNREQN,
+                       .hskack = IMX8MM_HSIO_HSK_PWRDNACKN,
+               },
+       },
+
+       [IMX8MM_POWER_DOMAIN_PCIE] = {
+               .genpd = {
+                       .name = "pcie",
+               },
+               .bits  = {
+                       .pxx = IMX8MM_PCIE_SW_Pxx_REQ,
+                       .map = IMX8MM_PCIE_A53_DOMAIN,
+               },
+               .pgc   = IMX8MM_PGC_PCIE,
+       },
+
+       [IMX8MM_POWER_DOMAIN_OTG1] = {
+               .genpd = {
+                       .name = "usb-otg1",
+               },
+               .bits  = {
+                       .pxx = IMX8MM_OTG1_SW_Pxx_REQ,
+                       .map = IMX8MM_OTG1_A53_DOMAIN,
+               },
+               .pgc   = IMX8MM_PGC_OTG1,
+       },
+
+       [IMX8MM_POWER_DOMAIN_OTG2] = {
+               .genpd = {
+                       .name = "usb-otg2",
+               },
+               .bits  = {
+                       .pxx = IMX8MM_OTG2_SW_Pxx_REQ,
+                       .map = IMX8MM_OTG2_A53_DOMAIN,
+               },
+               .pgc   = IMX8MM_PGC_OTG2,
+       },
+
+       [IMX8MM_POWER_DOMAIN_GPUMIX] = {
+               .genpd = {
+                       .name = "gpumix",
+               },
+               .bits  = {
+                       .pxx = IMX8MM_GPUMIX_SW_Pxx_REQ,
+                       .map = IMX8MM_GPUMIX_A53_DOMAIN,
+                       .hskreq = IMX8MM_GPUMIX_HSK_PWRDNREQN,
+                       .hskack = IMX8MM_GPUMIX_HSK_PWRDNACKN,
+               },
+               .pgc   = IMX8MM_PGC_GPUMIX,
+       },
+
+       [IMX8MM_POWER_DOMAIN_GPU] = {
+               .genpd = {
+                       .name = "gpu",
+               },
+               .bits  = {
+                       .pxx = IMX8MM_GPU_SW_Pxx_REQ,
+                       .map = IMX8MM_GPU_A53_DOMAIN,
+                       .hskreq = IMX8MM_GPU_HSK_PWRDNREQN,
+                       .hskack = IMX8MM_GPU_HSK_PWRDNACKN,
+               },
+               .pgc   = IMX8MM_PGC_GPU2D,
+       },
+};
+
+static const struct regmap_range imx8mm_yes_ranges[] = {
+               regmap_reg_range(GPC_LPCR_A_CORE_BSC,
+                                GPC_PU_PWRHSK),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_MIPI),
+                                GPC_PGC_SR(IMX8MM_PGC_MIPI)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_PCIE),
+                                GPC_PGC_SR(IMX8MM_PGC_PCIE)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_OTG1),
+                                GPC_PGC_SR(IMX8MM_PGC_OTG1)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_OTG2),
+                                GPC_PGC_SR(IMX8MM_PGC_OTG2)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_DDR1),
+                                GPC_PGC_SR(IMX8MM_PGC_DDR1)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_GPU2D),
+                                GPC_PGC_SR(IMX8MM_PGC_GPU2D)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_GPUMIX),
+                                GPC_PGC_SR(IMX8MM_PGC_GPUMIX)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_VPUMIX),
+                                GPC_PGC_SR(IMX8MM_PGC_VPUMIX)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_GPU3D),
+                                GPC_PGC_SR(IMX8MM_PGC_GPU3D)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_DISPMIX),
+                                GPC_PGC_SR(IMX8MM_PGC_DISPMIX)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_VPUG1),
+                                GPC_PGC_SR(IMX8MM_PGC_VPUG1)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_VPUG2),
+                                GPC_PGC_SR(IMX8MM_PGC_VPUG2)),
+               regmap_reg_range(GPC_PGC_CTRL(IMX8MM_PGC_VPUH1),
+                                GPC_PGC_SR(IMX8MM_PGC_VPUH1)),
+};
+
+static const struct regmap_access_table imx8mm_access_table = {
+       .yes_ranges     = imx8mm_yes_ranges,
+       .n_yes_ranges   = ARRAY_SIZE(imx8mm_yes_ranges),
+};
+
+static const struct imx_pgc_domain_data imx8mm_pgc_domain_data = {
+       .domains = imx8mm_pgc_domains,
+       .domains_num = ARRAY_SIZE(imx8mm_pgc_domains),
+       .reg_access_table = &imx8mm_access_table,
+};
+
 static int imx_pgc_domain_probe(struct platform_device *pdev)
 {
        struct imx_pgc_domain *domain = pdev->dev.platform_data;
@@ -710,6 +877,7 @@ static int imx_gpcv2_probe(struct platform_device *pdev)
 
 static const struct of_device_id imx_gpcv2_dt_ids[] = {
        { .compatible = "fsl,imx7d-gpc", .data = &imx7_pgc_domain_data, },
+       { .compatible = "fsl,imx8mm-gpc", .data = &imx8mm_pgc_domain_data, },
        { .compatible = "fsl,imx8mq-gpc", .data = &imx8m_pgc_domain_data, },
        { }
 };