Message ID | 20250227170012.124768-6-marex@denx.de (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | arm64: dts: imx95: Add support for Mali G310 GPU | expand |
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; > >
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; + } + + /* 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;
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(+)