drivers/gpu/drm/msm/adreno/a6xx_gmu.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/msm/adreno/a6xx_gmu.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/msm/adreno/a6xx_gmu.c- Extension
.c- Size
- 68178 bytes
- Lines
- 2492
- 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.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/bitfield.hlinux/clk.hlinux/firmware/qcom/qcom_scm.hlinux/interconnect.hlinux/of_platform.hlinux/platform_device.hlinux/pm_domain.hlinux/pm_opp.hsoc/qcom/cmd-db.hsoc/qcom/tcs.hdrm/drm_gem.ha6xx_gpu.ha6xx_gmu.xml.hmsm_gem.hmsm_gpu_trace.hmsm_mmu.h
Detected Declarations
struct a6xx_gmu_oob_bitsstruct block_headerstruct bcm_dbfunction a6xx_gmu_faultfunction a6xx_gmu_irqfunction a6xx_hfi_irqfunction a6xx_gmu_sptprac_is_onfunction a6xx_gmu_gx_is_onfunction a7xx_gmu_gx_is_onfunction a8xx_gmu_gx_is_onfunction a6xx_gmu_set_freqfunction a6xx_gmu_get_freqfunction a6xx_gmu_check_idle_levelfunction a6xx_gmu_wait_for_idlefunction a6xx_gmu_startfunction a6xx_gmu_hfi_startfunction a6xx_gmu_set_oobfunction a6xx_gmu_clear_oobfunction a6xx_sptprac_enablefunction a6xx_sptprac_disablefunction a6xx_gmu_gfx_rail_onfunction a6xx_gemnoc_workaroundfunction a6xx_gmu_notify_slumberfunction a6xx_rpmh_startfunction a6xx_rpmh_stopfunction pdc_writefunction a6xx_gmu_rpmh_initfunction adreno_is_a7xxfunction cyclesfunction fw_block_memfunction a6xx_gmu_fw_loadfunction a6xx_gmu_fw_startfunction a6xx_gmu_irq_disablefunction a6xx_gmu_rpmh_offfunction a6xx_gmu_force_offfunction a6xx_gmu_set_initial_freqfunction a6xx_gmu_set_initial_bwfunction a6xx_gmu_secure_initfunction a6xx_gmu_gxpd_getfunction a6xx_gmu_gxpd_putfunction a6xx_gmu_resumefunction a6xx_gmu_isidlefunction a6xx_gmu_shutdownfunction a6xx_gmu_stopfunction a6xx_gmu_memory_freefunction a6xx_gmu_memory_allocfunction a6xx_gmu_memory_probefunction a6xx_gmu_rpmh_bw_votes_init
Annotated Snippet
struct a6xx_gmu_oob_bits {
int set, ack, set_new, ack_new, clear, clear_new;
const char *name;
};
/* These are the interrupt / ack bits for each OOB request that are set
* in a6xx_gmu_set_oob and a6xx_clear_oob
*/
static const struct a6xx_gmu_oob_bits a6xx_gmu_oob_bits[] = {
[GMU_OOB_GPU_SET] = {
.name = "GPU_SET",
.set = 16,
.ack = 24,
.set_new = 30,
.ack_new = 31,
.clear = 24,
.clear_new = 31,
},
[GMU_OOB_PERFCOUNTER_SET] = {
.name = "PERFCOUNTER",
.set = 17,
.ack = 25,
.set_new = 28,
.ack_new = 30,
.clear = 25,
.clear_new = 29,
},
[GMU_OOB_BOOT_SLUMBER] = {
.name = "BOOT_SLUMBER",
.set = 22,
.ack = 30,
.clear = 30,
},
[GMU_OOB_DCVS_SET] = {
.name = "GPU_DCVS",
.set = 23,
.ack = 31,
.clear = 31,
},
};
/* Trigger a OOB (out of band) request to the GMU */
int a6xx_gmu_set_oob(struct a6xx_gmu *gmu, enum a6xx_gmu_oob_state state)
{
struct a6xx_gpu *a6xx_gpu = container_of(gmu, struct a6xx_gpu, gmu);
struct adreno_gpu *adreno_gpu = &a6xx_gpu->base;
int ret;
u32 val;
int request, ack;
WARN_ON_ONCE(!mutex_is_locked(&gmu->lock));
/* Skip OOB calls since RGMU is not enabled */
if (adreno_has_rgmu(adreno_gpu))
return 0;
if (state >= ARRAY_SIZE(a6xx_gmu_oob_bits))
return -EINVAL;
if (gmu->legacy) {
request = a6xx_gmu_oob_bits[state].set;
ack = a6xx_gmu_oob_bits[state].ack;
} else {
request = a6xx_gmu_oob_bits[state].set_new;
ack = a6xx_gmu_oob_bits[state].ack_new;
if (!request || !ack) {
DRM_DEV_ERROR(gmu->dev,
"Invalid non-legacy GMU request %s\n",
a6xx_gmu_oob_bits[state].name);
return -EINVAL;
}
}
/* Trigger the equested OOB operation */
gmu_write(gmu, REG_A6XX_GMU_HOST2GMU_INTR_SET, 1 << request);
do {
/* Wait for the acknowledge interrupt */
ret = gmu_poll_timeout(gmu, REG_A6XX_GMU_GMU2HOST_INTR_INFO, val,
val & (1 << ack), 100, 10000);
if (!ret)
break;
if (completion_done(&a6xx_gpu->base.fault_coredump_done))
break;
Annotation
- Immediate include surface: `linux/bitfield.h`, `linux/clk.h`, `linux/firmware/qcom/qcom_scm.h`, `linux/interconnect.h`, `linux/of_platform.h`, `linux/platform_device.h`, `linux/pm_domain.h`, `linux/pm_opp.h`.
- Detected declarations: `struct a6xx_gmu_oob_bits`, `struct block_header`, `struct bcm_db`, `function a6xx_gmu_fault`, `function a6xx_gmu_irq`, `function a6xx_hfi_irq`, `function a6xx_gmu_sptprac_is_on`, `function a6xx_gmu_gx_is_on`, `function a7xx_gmu_gx_is_on`, `function a8xx_gmu_gx_is_on`.
- 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.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.