[PATCH v3 1/7] soc: imx: gpcv2: add PGC control register indirection
Laurent Pinchart
laurent.pinchart at ideasonboard.com
Mon Feb 28 12:34:56 PST 2022
Hi Lucas,
Thank you for the patch.
On Mon, Feb 28, 2022 at 09:17:25PM +0100, Lucas Stach wrote:
> 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 <l.stach at pengutronix.de>
Reviewed-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
> ---
> drivers/soc/imx/gpcv2.c | 43 ++++++++++++++++++++++++++++++-----------
> 1 file changed, 32 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c
> index 3e59d479d001..01f46b078df3 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) {
> @@ -441,10 +450,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[] = {
> @@ -613,6 +630,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[] = {
> @@ -803,6 +821,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[] = {
> @@ -894,6 +913,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)
> @@ -926,7 +946,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);
> @@ -952,7 +972,7 @@ static int imx_pgc_domain_probe(struct platform_device *pdev)
> 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);
>
> @@ -967,7 +987,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);
> @@ -1098,6 +1118,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;
>
--
Regards,
Laurent Pinchart
More information about the linux-arm-kernel
mailing list