From: Peng Fan <peng.fan@xxxxxxx> The NoC reset value for GPU and MLMIX is not valid, need to set it to a valid value after power up. Signed-off-by: Peng Fan <peng.fan@xxxxxxx> --- drivers/soc/imx/gpcv2.c | 56 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index 85aa86e1338a..7199cf8e148e 100644 --- a/drivers/soc/imx/gpcv2.c +++ b/drivers/soc/imx/gpcv2.c @@ -9,6 +9,7 @@ */ #include <linux/clk.h> +#include <linux/mfd/syscon.h> #include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/pm_domain.h> @@ -274,9 +275,17 @@ struct imx_pgc_regs { u16 hsk; }; +struct imx_pgc_noc_data { + u32 off; + u32 priority; + u32 mode; + u32 extctrl; +}; + struct imx_pgc_domain { struct generic_pm_domain genpd; struct regmap *regmap; + struct regmap *noc_regmap; const struct imx_pgc_regs *regs; struct regulator *regulator; struct reset_control *reset; @@ -298,6 +307,7 @@ struct imx_pgc_domain { unsigned int pgc_sw_pup_reg; unsigned int pgc_sw_pdn_reg; + const struct imx_pgc_noc_data *noc_data; }; struct imx_pgc_domain_data { @@ -313,6 +323,21 @@ to_imx_pgc_domain(struct generic_pm_domain *genpd) return container_of(genpd, struct imx_pgc_domain, genpd); } +static int imx_pgc_noc_set(struct imx_pgc_domain *domain) +{ + const struct imx_pgc_noc_data *data = domain->noc_data; + struct regmap *regmap = domain->noc_regmap; + + if (!data || !regmap) + return 0; + + regmap_write(regmap, data->off + 0x8, data->priority); + regmap_write(regmap, data->off + 0xc, data->mode); + regmap_write(regmap, data->off + 0x18, data->extctrl); + + return 0; +} + static int imx_pgc_power_up(struct generic_pm_domain *genpd) { struct imx_pgc_domain *domain = to_imx_pgc_domain(genpd); @@ -394,6 +419,8 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd) if (!domain->keep_clocks) clk_bulk_disable_unprepare(domain->num_clks, domain->clks); + imx_pgc_noc_set(domain); + return 0; out_clk_disable: @@ -911,6 +938,25 @@ static const struct imx_pgc_domain_data imx8mm_pgc_domain_data = { .pgc_regs = &imx7_pgc_regs, }; +#define IMX8MP_MLMIX 0 +#define IMX8MP_GPU2D 1 +#define IMX8MP_GPU3D 2 + +static const struct imx_pgc_noc_data imx8mp_pgc_noc_data[] = { + [IMX8MP_MLMIX] = { + .off = 0x180, + .priority = 0x80000303, + }, + [IMX8MP_GPU2D] = { + .off = 0x500, + .priority = 0x80000303, + }, + [IMX8MP_GPU3D] = { + .off = 0x580, + .priority = 0x80000303, + }, +}; + static const struct imx_pgc_domain imx8mp_pgc_domains[] = { [IMX8MP_POWER_DOMAIN_MIPI_PHY1] = { .genpd = { @@ -968,6 +1014,7 @@ static const struct imx_pgc_domain imx8mp_pgc_domains[] = { }, .pgc = BIT(IMX8MP_PGC_MLMIX), .keep_clocks = true, + .noc_data = &imx8mp_pgc_noc_data[IMX8MP_MLMIX], }, [IMX8MP_POWER_DOMAIN_AUDIOMIX] = { @@ -993,6 +1040,7 @@ static const struct imx_pgc_domain imx8mp_pgc_domains[] = { .map = IMX8MP_GPU2D_A53_DOMAIN, }, .pgc = BIT(IMX8MP_PGC_GPU2D), + .noc_data = &imx8mp_pgc_noc_data[IMX8MP_GPU2D], }, [IMX8MP_POWER_DOMAIN_GPUMIX] = { @@ -1032,6 +1080,7 @@ static const struct imx_pgc_domain imx8mp_pgc_domains[] = { .map = IMX8MP_GPU3D_A53_DOMAIN, }, .pgc = BIT(IMX8MP_PGC_GPU3D), + .noc_data = &imx8mp_pgc_noc_data[IMX8MP_GPU3D], }, [IMX8MP_POWER_DOMAIN_MEDIAMIX] = { @@ -1440,7 +1489,7 @@ static int imx_gpcv2_probe(struct platform_device *pdev) }; struct device *dev = &pdev->dev; struct device_node *pgc_np, *np; - struct regmap *regmap; + struct regmap *regmap, *noc_regmap; void __iomem *base; int ret; @@ -1461,6 +1510,8 @@ static int imx_gpcv2_probe(struct platform_device *pdev) return ret; } + noc_regmap = syscon_regmap_lookup_by_compatible("fsl,imx8m-noc"); + for_each_child_of_node(pgc_np, np) { struct platform_device *pd_pdev; struct imx_pgc_domain *domain; @@ -1503,6 +1554,9 @@ static int imx_gpcv2_probe(struct platform_device *pdev) domain = pd_pdev->dev.platform_data; domain->regmap = regmap; domain->regs = domain_data->pgc_regs; + domain->noc_data = domain_data->domains[domain_index].noc_data; + if (!IS_ERR(noc_regmap)) + domain->noc_regmap = noc_regmap; domain->genpd.power_on = imx_pgc_power_up; domain->genpd.power_off = imx_pgc_power_down; -- 2.25.1