Re: [PATCH 5/9] drm/panthor: Implement support for multiple power domains

Alexander Stein
2025-02-28T10:10:10Z

Am Donnerstag, 27. Februar 2025, 17:58:05 CET schrieb Marek Vasut:
> The driver code power domain binding to driver instances only works
> for single power domain, in case there are multiple power domains,
> it is necessary to explicitly attach via dev_pm_domain_attach*().
> As DT bindings list support for up to 5 power domains, add support
> for attaching them all. This is useful on Freescale i.MX95 which
> does have two power domains.
>
> Signed-off-by: Marek Vasut <marex@denx.de>
> ---
> Cc: Boris Brezillon <boris.brezillon@collabora.com>
> Cc: Conor Dooley <conor+dt@kernel.org>
> Cc: David Airlie <airlied@gmail.com>
> Cc: Fabio Estevam <festevam@gmail.com>
> Cc: Krzysztof Kozlowski <krzk+dt@kernel.org>
> Cc: Liviu Dudau <liviu.dudau@arm.com>
> Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
> Cc: Maxime Ripard <mripard@kernel.org>
> Cc: Pengutronix Kernel Team <kernel@pengutronix.de>
> Cc: Philipp Zabel <p.zabel@pengutronix.de>
> Cc: Rob Herring <robh@kernel.org>
> Cc: Sascha Hauer <s.hauer@pengutronix.de>
> Cc: Sebastian Reichel <sre@kernel.org>
> Cc: Shawn Guo <shawnguo@kernel.org>
> Cc: Simona Vetter <simona@ffwll.ch>
> Cc: Steven Price <steven.price@arm.com>
> Cc: Thomas Zimmermann <tzimmermann@suse.de>
> Cc: devicetree@vger.kernel.org
> Cc: dri-devel@lists.freedesktop.org
> Cc: imx@lists.linux.dev
> Cc: linux-arm-kernel@lists.infradead.org
> ---
> drivers/gpu/drm/panthor/panthor_device.c | 56 ++++++++++++++++++++++++
> drivers/gpu/drm/panthor/panthor_device.h | 5 +++
> 2 files changed, 61 insertions(+)
>
> diff --git a/drivers/gpu/drm/panthor/panthor_device.c b/drivers/gpu/drm/panthor/panthor_device.c
> index 51ee9cae94504..4348b7e917b64 100644
> --- a/drivers/gpu/drm/panthor/panthor_device.c
> +++ b/drivers/gpu/drm/panthor/panthor_device.c
> @@ -75,6 +75,58 @@ static int panthor_reset_init(struct panthor_device *ptdev)
> return 0;
> }
>
> +/* Generic power domain handling code, see drivers/gpu/drm/tiny/simpledrm.c */
> +static void panthor_detach_genpd(void *res)
> +{
> + struct panthor_device *ptdev = res;
> + int i;
> +
> + if (ptdev->pwr_dom_count <= 1)
> + return;
> +
> + for (i = ptdev->pwr_dom_count - 1; i >= 0; i--)
> + dev_pm_domain_detach(ptdev->pwr_dom_devs[i], true);
> +}
> +
> +static int panthor_genpd_init(struct panthor_device *ptdev)
> +{
> + struct device *dev = ptdev->base.dev;
> + int i, ret;
> +
> + ptdev->pwr_dom_count = of_count_phandle_with_args(dev->of_node, "power-domains",
> + "#power-domain-cells");
> + /*
> + * Single power-domain devices are handled by driver core nothing to do
> + * here. The same for device nodes without "power-domains" property.
> + */
> + if (ptdev->pwr_dom_count <= 1)
> + return 0;
> +
> + if (ptdev->pwr_dom_count > ARRAY_SIZE(ptdev->pwr_dom_devs)) {
> + drm_warn(&ptdev->base, "Too many power domains (%d) for this device\n",
> + ptdev->pwr_dom_count);
> + return -EINVAL;
> + }
> +
> + for (i = 0; i < ptdev->pwr_dom_count; i++) {
> + ptdev->pwr_dom_devs[i] = dev_pm_domain_attach_by_id(dev, i);
> + if (!IS_ERR(ptdev->pwr_dom_devs[i]))
> + continue;
> +
> + ret = PTR_ERR(ptdev->pwr_dom_devs[i]);
> + if (ret != -EPROBE_DEFER) {
> + drm_warn(&ptdev->base, "pm_domain_attach_by_id(%u) failed: %d\n", i, ret);
> + continue;

Is it a good idea to continue if a power-domain is missing? Any access might
stuck completely. IMHO returning an error is more sensible.
Also some dev_err_probe() should be added here.

Best regards
Alexander

> + }
> +
> + /* Missing dependency, try again. */
> + panthor_detach_genpd(ptdev);
> + return ret;
> + }
> +
> + return devm_add_action_or_reset(dev, panthor_detach_genpd, ptdev);
> +}
> +
> void panthor_device_unplug(struct panthor_device *ptdev)
> {
> /* This function can be called from two different path: the reset work
> @@ -232,6 +284,10 @@ int panthor_device_init(struct panthor_device *ptdev)
> if (ret)
> return ret;
>
> + ret = panthor_genpd_init(ptdev);
> + if (ret)
> + return ret;
> +
> ret = panthor_devfreq_init(ptdev);
> if (ret)
> return ret;
> diff --git a/drivers/gpu/drm/panthor/panthor_device.h b/drivers/gpu/drm/panthor/panthor_device.h
> index fea3a05778e2e..7fb65447253e9 100644
> --- a/drivers/gpu/drm/panthor/panthor_device.h
> +++ b/drivers/gpu/drm/panthor/panthor_device.h
> @@ -114,6 +114,11 @@ struct panthor_device {
> /** @resets: GPU reset. */
> struct reset_control *resets;
>
> + /** @pwr_dom_count: Power domain count */
> + int pwr_dom_count;
> + /** @pwr_dom_dev: Power domain devices */
> + struct device *pwr_dom_devs[5];
> +
> /** @coherent: True if the CPU/GPU are memory coherent. */
> bool coherent;
>
>

--
TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht München, HRB 105018
Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider