On 28/05/2026 16:05, Karunika Choo wrote:
> On Mali v15 AM systems, frequency scaling is handled outside panthor by
> the AM_GOVERNOR block, so the GPU DT node may not provide an OPP table.
>
> Make panthor_devfreq_init() return early when operating-points-v2 is
> absent, and guard the devfreq helper paths against a missing devfreq
> instance.
>
> This keeps devfreq enabled for existing platforms while allowing v15 AM
> systems to probe without a local devfreq setup.
>
> Signed-off-by: Karunika Choo <[email protected]>
> ---
> drivers/gpu/drm/panthor/panthor_devfreq.c | 13 ++++++++-----
> 1 file changed, 8 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpu/drm/panthor/panthor_devfreq.c
> b/drivers/gpu/drm/panthor/panthor_devfreq.c
> index 2249b41ca4af..c3252ce54437 100644
> --- a/drivers/gpu/drm/panthor/panthor_devfreq.c
> +++ b/drivers/gpu/drm/panthor/panthor_devfreq.c
> @@ -148,6 +148,9 @@ int panthor_devfreq_init(struct panthor_device *ptdev)
> unsigned long freq = ULONG_MAX;
> int ret;
>
> + if (!device_property_read_bool(ptdev->base.dev, "operating-points-v2"))
Don't you want device_property_present() here?
I'm also a little wary of encoding operating-points-v2 as the check -
e.g. it potentially breaks if there's ever a "-v3" or some other way of
describing the opps. Can we use the -ENODEV returned from the
devm_pm_opp functions instead?
> + return 0;
> +
> pdevfreq = drmm_kzalloc(&ptdev->base, sizeof(*ptdev->devfreq),
> GFP_KERNEL);
> if (!pdevfreq)
> return -ENOMEM;
> @@ -267,7 +270,7 @@ void panthor_devfreq_resume(struct panthor_device *ptdev)
> {
> struct panthor_devfreq *pdevfreq = ptdev->devfreq;
>
> - if (!pdevfreq->devfreq)
> + if (!pdevfreq || !pdevfreq->devfreq)
> return;
>
> panthor_devfreq_reset(pdevfreq);
> @@ -279,7 +282,7 @@ void panthor_devfreq_suspend(struct panthor_device *ptdev)
> {
> struct panthor_devfreq *pdevfreq = ptdev->devfreq;
>
> - if (!pdevfreq->devfreq)
> + if (!pdevfreq || !pdevfreq->devfreq)
> return;
>
> drm_WARN_ON(&ptdev->base, devfreq_suspend_device(pdevfreq->devfreq));
> @@ -290,7 +293,7 @@ void panthor_devfreq_record_busy(struct panthor_device
> *ptdev)
> struct panthor_devfreq *pdevfreq = ptdev->devfreq;
> unsigned long irqflags;
>
> - if (!pdevfreq->devfreq)
> + if (!pdevfreq || !pdevfreq->devfreq)
> return;
>
> spin_lock_irqsave(&pdevfreq->lock, irqflags);
> @@ -306,7 +309,7 @@ void panthor_devfreq_record_idle(struct panthor_device
> *ptdev)
> struct panthor_devfreq *pdevfreq = ptdev->devfreq;
> unsigned long irqflags;
>
> - if (!pdevfreq->devfreq)
> + if (!pdevfreq || !pdevfreq->devfreq)
> return;
>
> spin_lock_irqsave(&pdevfreq->lock, irqflags);
> @@ -323,7 +326,7 @@ unsigned long panthor_devfreq_get_freq(struct
> panthor_device *ptdev)
> unsigned long freq = 0;
> int ret;
>
> - if (!pdevfreq->devfreq)
> + if (!pdevfreq || !pdevfreq->devfreq)
> return 0;
This has the unfortunate effect of reporting a bogus frequency in
panthor_gpu_show_fdinfo(). We should avoid reporting a frequency at all
if we don't know it. Or of course even better report the actual
frequency the governor block has set.
Thanks,
Steve
>
> ret = pdevfreq->devfreq->profile->get_cur_freq(ptdev->base.dev, &freq);