drivers/gpu/drm/panfrost/panfrost_devfreq.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/panfrost/panfrost_devfreq.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/panfrost/panfrost_devfreq.c- Extension
.c- Size
- 7149 bytes
- Lines
- 289
- Domain
- Driver Families
- Bucket
- drivers/gpu
- Inferred role
- Driver Families: implementation source
- Status
- source implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/clk.hlinux/devfreq.hlinux/devfreq_cooling.hlinux/nvmem-consumer.hlinux/platform_device.hlinux/pm_opp.hdrm/drm_print.hpanfrost_device.hpanfrost_devfreq.h
Detected Declarations
function panfrost_devfreq_update_utilizationfunction panfrost_devfreq_targetfunction panfrost_devfreq_resetfunction panfrost_devfreq_get_dev_statusfunction panfrost_read_speedbinfunction panfrost_devfreq_initfunction panfrost_devfreq_finifunction panfrost_devfreq_resumefunction panfrost_devfreq_suspendfunction panfrost_devfreq_record_busyfunction panfrost_devfreq_record_idle
Annotated Snippet
if (ret != -ENOENT && ret != -EOPNOTSUPP) {
DRM_DEV_ERROR(dev, "Cannot read speed-bin (%d).", ret);
return ret;
}
return 0;
}
DRM_DEV_DEBUG(dev, "Using speed-bin = 0x%x\n", val);
return devm_pm_opp_set_supported_hw(dev, &val, 1);
}
int panfrost_devfreq_init(struct panfrost_device *pfdev)
{
int ret;
struct dev_pm_opp *opp;
unsigned long cur_freq;
struct device *dev = pfdev->base.dev;
struct devfreq *devfreq;
struct thermal_cooling_device *cooling;
struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
unsigned long freq = ULONG_MAX;
if (pfdev->comp->num_supplies > 1) {
/*
* GPUs with more than 1 supply require platform-specific handling:
* continue without devfreq
*/
DRM_DEV_INFO(dev, "More than 1 supply is not supported yet\n");
return 0;
}
ret = panfrost_read_speedbin(dev);
if (ret)
return ret;
ret = devm_pm_opp_set_regulators(dev, pfdev->comp->supply_names);
if (ret) {
/* Continue if the optional regulator is missing */
if (ret != -ENODEV) {
if (ret != -EPROBE_DEFER)
DRM_DEV_ERROR(dev, "Couldn't set OPP regulators\n");
return ret;
}
}
ret = devm_pm_opp_of_add_table(dev);
if (ret) {
/* Optional, continue without devfreq */
if (ret == -ENODEV)
ret = 0;
return ret;
}
pfdevfreq->opp_of_table_added = true;
spin_lock_init(&pfdevfreq->lock);
panfrost_devfreq_reset(pfdevfreq);
cur_freq = clk_get_rate(pfdev->clock);
opp = devfreq_recommended_opp(dev, &cur_freq, 0);
if (IS_ERR(opp))
return PTR_ERR(opp);
panfrost_devfreq_profile.initial_freq = cur_freq;
/*
* We could wait until panfrost_devfreq_target() to set this value, but
* since the simple_ondemand governor works asynchronously, there's a
* chance by the time someone opens the device's fdinfo file, current
* frequency hasn't been updated yet, so let's just do an early set.
*/
pfdevfreq->current_frequency = cur_freq;
/*
* Set the recommend OPP this will enable and configure the regulator
* if any and will avoid a switch off by regulator_late_cleanup()
*/
ret = dev_pm_opp_set_opp(dev, opp);
dev_pm_opp_put(opp);
if (ret) {
DRM_DEV_ERROR(dev, "Couldn't set recommended OPP\n");
return ret;
}
/* Find the fastest defined rate */
opp = dev_pm_opp_find_freq_floor(dev, &freq);
if (IS_ERR(opp))
return PTR_ERR(opp);
Annotation
- Immediate include surface: `linux/clk.h`, `linux/devfreq.h`, `linux/devfreq_cooling.h`, `linux/nvmem-consumer.h`, `linux/platform_device.h`, `linux/pm_opp.h`, `drm/drm_print.h`, `panfrost_device.h`.
- Detected declarations: `function panfrost_devfreq_update_utilization`, `function panfrost_devfreq_target`, `function panfrost_devfreq_reset`, `function panfrost_devfreq_get_dev_status`, `function panfrost_read_speedbin`, `function panfrost_devfreq_init`, `function panfrost_devfreq_fini`, `function panfrost_devfreq_resume`, `function panfrost_devfreq_suspend`, `function panfrost_devfreq_record_busy`.
- Atlas domain: Driver Families / drivers/gpu.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.