From: Lucas Stach Date: Wed, 30 Mar 2022 10:46:16 +0000 (+0200) Subject: soc: imx: gpcv2: add PGC control register indirection X-Git-Tag: v6.1-rc5~1258^2~3^2~7 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=d9651b99dd65e861b1c525d0e8ab8da0d37642ca;p=platform%2Fkernel%2Flinux-starfive.git soc: imx: gpcv2: add PGC control register indirection The PGC control registers in the shared (not per-PGC) region of the GPC address space have different offsets on i.MX8MP to make space for additional interrupt control registers. Signed-off-by: Lucas Stach Reviewed-by: Laurent Pinchart Tested-by: Peng Fan Signed-off-by: Shawn Guo --- diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c index 3cb1230..677c5c5 100644 --- a/drivers/soc/imx/gpcv2.c +++ b/drivers/soc/imx/gpcv2.c @@ -184,9 +184,17 @@ #define GPC_PGC_CTRL_PCR BIT(0) +struct imx_pgc_regs { + u16 map; + u16 pup; + u16 pdn; + u16 hsk; +}; + struct imx_pgc_domain { struct generic_pm_domain genpd; struct regmap *regmap; + const struct imx_pgc_regs *regs; struct regulator *regulator; struct reset_control *reset; struct clk_bulk_data *clks; @@ -210,6 +218,7 @@ struct imx_pgc_domain_data { const struct imx_pgc_domain *domains; size_t domains_num; const struct regmap_access_table *reg_access_table; + const struct imx_pgc_regs *pgc_regs; }; static inline struct imx_pgc_domain * @@ -249,14 +258,14 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd) if (domain->bits.pxx) { /* request the domain to power up */ - regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PUP_REQ, + regmap_update_bits(domain->regmap, domain->regs->pup, domain->bits.pxx, domain->bits.pxx); /* * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait * for PUP_REQ/PDN_REQ bit to be cleared */ ret = regmap_read_poll_timeout(domain->regmap, - GPC_PU_PGC_SW_PUP_REQ, reg_val, + domain->regs->pup, reg_val, !(reg_val & domain->bits.pxx), 0, USEC_PER_MSEC); if (ret) { @@ -278,11 +287,11 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd) /* request the ADB400 to power up */ if (domain->bits.hskreq) { - regmap_update_bits(domain->regmap, GPC_PU_PWRHSK, + regmap_update_bits(domain->regmap, domain->regs->hsk, domain->bits.hskreq, domain->bits.hskreq); /* - * ret = regmap_read_poll_timeout(domain->regmap, GPC_PU_PWRHSK, reg_val, + * ret = regmap_read_poll_timeout(domain->regmap, domain->regs->hsk, reg_val, * (reg_val & domain->bits.hskack), 0, * USEC_PER_MSEC); * Technically we need the commented code to wait handshake. But that needs @@ -329,10 +338,10 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd) /* request the ADB400 to power down */ if (domain->bits.hskreq) { - regmap_clear_bits(domain->regmap, GPC_PU_PWRHSK, + regmap_clear_bits(domain->regmap, domain->regs->hsk, domain->bits.hskreq); - ret = regmap_read_poll_timeout(domain->regmap, GPC_PU_PWRHSK, + ret = regmap_read_poll_timeout(domain->regmap, domain->regs->hsk, reg_val, !(reg_val & domain->bits.hskack), 0, USEC_PER_MSEC); @@ -350,14 +359,14 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd) } /* request the domain to power down */ - regmap_update_bits(domain->regmap, GPC_PU_PGC_SW_PDN_REQ, + regmap_update_bits(domain->regmap, domain->regs->pdn, domain->bits.pxx, domain->bits.pxx); /* * As per "5.5.9.4 Example Code 4" in IMX7DRM.pdf wait * for PUP_REQ/PDN_REQ bit to be cleared */ ret = regmap_read_poll_timeout(domain->regmap, - GPC_PU_PGC_SW_PDN_REQ, reg_val, + domain->regs->pdn, reg_val, !(reg_val & domain->bits.pxx), 0, USEC_PER_MSEC); if (ret) { @@ -442,10 +451,18 @@ static const struct regmap_access_table imx7_access_table = { .n_yes_ranges = ARRAY_SIZE(imx7_yes_ranges), }; +static const struct imx_pgc_regs imx7_pgc_regs = { + .map = GPC_PGC_CPU_MAPPING, + .pup = GPC_PU_PGC_SW_PUP_REQ, + .pdn = GPC_PU_PGC_SW_PDN_REQ, + .hsk = GPC_PU_PWRHSK, +}; + static const struct imx_pgc_domain_data imx7_pgc_domain_data = { .domains = imx7_pgc_domains, .domains_num = ARRAY_SIZE(imx7_pgc_domains), .reg_access_table = &imx7_access_table, + .pgc_regs = &imx7_pgc_regs, }; static const struct imx_pgc_domain imx8m_pgc_domains[] = { @@ -614,6 +631,7 @@ static const struct imx_pgc_domain_data imx8m_pgc_domain_data = { .domains = imx8m_pgc_domains, .domains_num = ARRAY_SIZE(imx8m_pgc_domains), .reg_access_table = &imx8m_access_table, + .pgc_regs = &imx7_pgc_regs, }; static const struct imx_pgc_domain imx8mm_pgc_domains[] = { @@ -804,6 +822,7 @@ 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, + .pgc_regs = &imx7_pgc_regs, }; static const struct imx_pgc_domain imx8mn_pgc_domains[] = { @@ -895,6 +914,7 @@ static const struct imx_pgc_domain_data imx8mn_pgc_domain_data = { .domains = imx8mn_pgc_domains, .domains_num = ARRAY_SIZE(imx8mn_pgc_domains), .reg_access_table = &imx8mn_access_table, + .pgc_regs = &imx7_pgc_regs, }; static int imx_pgc_domain_probe(struct platform_device *pdev) @@ -927,7 +947,7 @@ static int imx_pgc_domain_probe(struct platform_device *pdev) pm_runtime_enable(domain->dev); if (domain->bits.map) - regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, + regmap_update_bits(domain->regmap, domain->regs->map, domain->bits.map, domain->bits.map); ret = pm_genpd_init(&domain->genpd, NULL, true); @@ -953,7 +973,7 @@ out_genpd_remove: pm_genpd_remove(&domain->genpd); out_domain_unmap: if (domain->bits.map) - regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, + regmap_update_bits(domain->regmap, domain->regs->map, domain->bits.map, 0); pm_runtime_disable(domain->dev); @@ -968,7 +988,7 @@ static int imx_pgc_domain_remove(struct platform_device *pdev) pm_genpd_remove(&domain->genpd); if (domain->bits.map) - regmap_update_bits(domain->regmap, GPC_PGC_CPU_MAPPING, + regmap_update_bits(domain->regmap, domain->regs->map, domain->bits.map, 0); pm_runtime_disable(domain->dev); @@ -1099,6 +1119,7 @@ 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->genpd.power_on = imx_pgc_power_up; domain->genpd.power_off = imx_pgc_power_down;