From f756f435f7dd823f2d4bd593ce1bf3168def1308 Mon Sep 17 00:00:00 2001 From: Marek Vasut Date: Sat, 16 Oct 2021 23:05:47 +0200 Subject: soc: imx: gpcv2: Synchronously suspend MIX domains In case the following power domain sequence happens, iMX8M Mini always hangs: gpumix:on -> gpu:on -> gpu:off -> gpu:on This is likely due to another quirk of the GPC block. This situation can be prevented by always synchronously powering off both the domain and MIX domain. Make it so. This turns the aforementioned sequence into: gpumix:on -> gpu:on -> gpu:off -> gpumix:off -> gpumix:on -> gpu:on Signed-off-by: Marek Vasut Cc: Frieder Schrempf Cc: Lucas Stach Cc: NXP Linux Team Cc: Peng Fan Cc: Shawn Guo Acked-by: Lucas Stach Signed-off-by: Shawn Guo --- drivers/soc/imx/gpcv2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/soc/imx') diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index b8d52d8d29db..e757044ab751 100644 --- a/drivers/soc/imx/gpcv2.c +++ b/drivers/soc/imx/gpcv2.c @@ -377,7 +377,7 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd) } } - pm_runtime_put(domain->dev); + pm_runtime_put_sync_suspend(domain->dev); return 0; -- cgit v1.2.3-59-g8ed1b From 8361b8b29f9389084b679db854cf733375c64763 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Sat, 20 Nov 2021 13:39:16 -0600 Subject: soc: imx: gpcv2: keep i.MX8MM VPU-H1 bus clock active Enable the vpu-h1 clock when the domain is active because reading or writing to the VPU-H1 IP block cause the system to hang. Fixes: 656ade7aa42a ("soc: imx: gpcv2: keep i.MX8M* bus clocks enabled") Signed-off-by: Adam Ford Reviewed-by: Fabio Estevam Signed-off-by: Shawn Guo --- drivers/soc/imx/gpcv2.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/soc/imx') diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index e757044ab751..8176380b02e6 100644 --- a/drivers/soc/imx/gpcv2.c +++ b/drivers/soc/imx/gpcv2.c @@ -734,6 +734,7 @@ static const struct imx_pgc_domain imx8mm_pgc_domains[] = { .map = IMX8MM_VPUH1_A53_DOMAIN, }, .pgc = BIT(IMX8MM_PGC_VPUH1), + .keep_clocks = true, }, [IMX8MM_POWER_DOMAIN_DISPMIX] = { -- cgit v1.2.3-59-g8ed1b From e2a6d22f3b48dffcab1dbcb162572ef5a923f24d Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 14 Dec 2021 18:46:18 -0600 Subject: soc: imx: gpcv2: keep i.MX8MN gpumix bus clock enabled Like the i.MX8MM, keep the gpumix clocks running when the domain is active. Signed-off-by: Adam Ford Reviewed-by: Lucas Stach Signed-off-by: Shawn Guo --- drivers/soc/imx/gpcv2.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/soc/imx') diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index 8176380b02e6..a0eab9f41a71 100644 --- a/drivers/soc/imx/gpcv2.c +++ b/drivers/soc/imx/gpcv2.c @@ -841,6 +841,7 @@ static const struct imx_pgc_domain imx8mn_pgc_domains[] = { .hskack = IMX8MN_GPUMIX_HSK_PWRDNACKN, }, .pgc = BIT(IMX8MN_PGC_GPUMIX), + .keep_clocks = true, }, }; -- cgit v1.2.3-59-g8ed1b From a0ec8a3a4c8122c1abae04e90c66e79e77eed357 Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 14 Dec 2021 18:46:19 -0600 Subject: soc: imx: gpcv2: Add dispmix and mipi domains to imx8mn The dispmix will be needed for the blkctl driver, so add it to the gpcv2. Signed-off-by: Adam Ford Reviewed-by: Lucas Stach Signed-off-by: Shawn Guo --- drivers/soc/imx/gpcv2.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers/soc/imx') diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index a0eab9f41a71..3e59d479d001 100644 --- a/drivers/soc/imx/gpcv2.c +++ b/drivers/soc/imx/gpcv2.c @@ -843,6 +843,31 @@ static const struct imx_pgc_domain imx8mn_pgc_domains[] = { .pgc = BIT(IMX8MN_PGC_GPUMIX), .keep_clocks = true, }, + + [IMX8MN_POWER_DOMAIN_DISPMIX] = { + .genpd = { + .name = "dispmix", + }, + .bits = { + .pxx = IMX8MN_DISPMIX_SW_Pxx_REQ, + .map = IMX8MN_DISPMIX_A53_DOMAIN, + .hskreq = IMX8MN_DISPMIX_HSK_PWRDNREQN, + .hskack = IMX8MN_DISPMIX_HSK_PWRDNACKN, + }, + .pgc = BIT(IMX8MN_PGC_DISPMIX), + .keep_clocks = true, + }, + + [IMX8MN_POWER_DOMAIN_MIPI] = { + .genpd = { + .name = "mipi", + }, + .bits = { + .pxx = IMX8MN_MIPI_SW_Pxx_REQ, + .map = IMX8MN_MIPI_A53_DOMAIN, + }, + .pgc = BIT(IMX8MN_PGC_MIPI), + }, }; static const struct regmap_range imx8mn_yes_ranges[] = { -- cgit v1.2.3-59-g8ed1b From 7f511d514e8c34b6dd0c17b5496e48b2a6a2626c Mon Sep 17 00:00:00 2001 From: Adam Ford Date: Tue, 14 Dec 2021 18:46:22 -0600 Subject: soc: imx: imx8m-blk-ctrl: add i.MX8MN DISP blk-ctrl This adds the description for the i.MX8MN disp blk-ctrl. Signed-off-by: Adam Ford Reviewed-by: Lucas Stach Signed-off-by: Shawn Guo --- drivers/soc/imx/imx8m-blk-ctrl.c | 77 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) (limited to 'drivers/soc/imx') diff --git a/drivers/soc/imx/imx8m-blk-ctrl.c b/drivers/soc/imx/imx8m-blk-ctrl.c index 519b3651d1d9..58a7f11e7e08 100644 --- a/drivers/soc/imx/imx8m-blk-ctrl.c +++ b/drivers/soc/imx/imx8m-blk-ctrl.c @@ -14,6 +14,7 @@ #include #include +#include #define BLK_SFT_RSTN 0x0 #define BLK_CLK_EN 0x4 @@ -498,6 +499,77 @@ static const struct imx8m_blk_ctrl_data imx8mm_disp_blk_ctl_dev_data = { .num_domains = ARRAY_SIZE(imx8mm_disp_blk_ctl_domain_data), }; + +static int imx8mn_disp_power_notifier(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct imx8m_blk_ctrl *bc = container_of(nb, struct imx8m_blk_ctrl, + power_nb); + + if (action != GENPD_NOTIFY_ON && action != GENPD_NOTIFY_PRE_OFF) + return NOTIFY_OK; + + /* Enable bus clock and deassert bus reset */ + regmap_set_bits(bc->regmap, BLK_CLK_EN, BIT(8)); + regmap_set_bits(bc->regmap, BLK_SFT_RSTN, BIT(8)); + + /* + * On power up we have no software backchannel to the GPC to + * wait for the ADB handshake to happen, so we just delay for a + * bit. On power down the GPC driver waits for the handshake. + */ + if (action == GENPD_NOTIFY_ON) + udelay(5); + + + return NOTIFY_OK; +} + +static const struct imx8m_blk_ctrl_domain_data imx8mn_disp_blk_ctl_domain_data[] = { + [IMX8MN_DISPBLK_PD_MIPI_DSI] = { + .name = "dispblk-mipi-dsi", + .clk_names = (const char *[]){ "dsi-pclk", "dsi-ref", }, + .num_clks = 2, + .gpc_name = "mipi-dsi", + .rst_mask = BIT(0) | BIT(1), + .clk_mask = BIT(0) | BIT(1), + .mipi_phy_rst_mask = BIT(17), + }, + [IMX8MN_DISPBLK_PD_MIPI_CSI] = { + .name = "dispblk-mipi-csi", + .clk_names = (const char *[]){ "csi-aclk", "csi-pclk" }, + .num_clks = 2, + .gpc_name = "mipi-csi", + .rst_mask = BIT(2) | BIT(3), + .clk_mask = BIT(2) | BIT(3), + .mipi_phy_rst_mask = BIT(16), + }, + [IMX8MN_DISPBLK_PD_LCDIF] = { + .name = "dispblk-lcdif", + .clk_names = (const char *[]){ "lcdif-axi", "lcdif-apb", "lcdif-pix", }, + .num_clks = 3, + .gpc_name = "lcdif", + .rst_mask = BIT(4) | BIT(5), + .clk_mask = BIT(4) | BIT(5), + }, + [IMX8MN_DISPBLK_PD_ISI] = { + .name = "dispblk-isi", + .clk_names = (const char *[]){ "disp_axi", "disp_apb", "disp_axi_root", + "disp_apb_root"}, + .num_clks = 4, + .gpc_name = "isi", + .rst_mask = BIT(6) | BIT(7), + .clk_mask = BIT(6) | BIT(7), + }, +}; + +static const struct imx8m_blk_ctrl_data imx8mn_disp_blk_ctl_dev_data = { + .max_reg = 0x84, + .power_notifier_fn = imx8mn_disp_power_notifier, + .domains = imx8mn_disp_blk_ctl_domain_data, + .num_domains = ARRAY_SIZE(imx8mn_disp_blk_ctl_domain_data), +}; + static const struct of_device_id imx8m_blk_ctrl_of_match[] = { { .compatible = "fsl,imx8mm-vpu-blk-ctrl", @@ -505,7 +577,10 @@ static const struct of_device_id imx8m_blk_ctrl_of_match[] = { }, { .compatible = "fsl,imx8mm-disp-blk-ctrl", .data = &imx8mm_disp_blk_ctl_dev_data - } ,{ + }, { + .compatible = "fsl,imx8mn-disp-blk-ctrl", + .data = &imx8mn_disp_blk_ctl_dev_data + }, { /* Sentinel */ } }; -- cgit v1.2.3-59-g8ed1b