drivers/gpu/drm/msm/adreno/a6xx_gpu.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/msm/adreno/a6xx_gpu.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/msm/adreno/a6xx_gpu.c- Extension
.c- Size
- 87209 bytes
- Lines
- 2923
- 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.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
msm_gem.hmsm_mmu.hmsm_gpu_trace.hmsm_perfcntr.ha6xx_gpu.ha6xx_gmu.xml.hlinux/bitfield.hlinux/devfreq.hlinux/pm_domain.hlinux/soc/qcom/llcc-qcom.h
Detected Declarations
function a6xx_gmu_get_timestampfunction fence_status_checkfunction fenced_writefunction a6xx_fenced_writefunction _a6xx_check_idlefunction a6xx_idlefunction update_shadow_rptrfunction a6xx_flushfunction a6xx_flush_yieldfunction get_stats_counterfunction a6xx_set_pagetablefunction a6xx_submitfunction a6xx_emit_set_pseudo_regfunction a7xx_submitfunction a6xx_set_hwcgfunction a6xx_set_cp_protectfunction a6xx_set_ubwc_configfunction a7xx_patch_pwrup_reglistfunction a7xx_preempt_startfunction a6xx_cp_initfunction a7xx_cp_initfunction a6xx_ucode_check_versionfunction a640function a6xx_ucode_loadfunction a6xx_zap_shader_initfunction hw_initfunction a6xx_hw_initfunction a6xx_dumpfunction a6xx_recoverfunction a6xx_fault_handlerfunction a6xx_cp_hw_err_irqfunction a6xx_fault_detect_irqfunction a7xx_sw_fuse_violation_irqfunction a6xx_gpu_keepalive_votefunction irq_poll_fencefunction a6xx_irqfunction a6xx_llc_deactivatefunction a6xx_llc_activatefunction a7xx_llc_activatefunction a6xx_llc_slices_destroyfunction a6xx_llc_slices_initfunction a6xx_bus_clear_pending_transactionsfunction a6xx_gpu_sw_resetfunction a6xx_gmu_pm_resumefunction a6xx_pm_resumefunction a6xx_gmu_pm_suspendfunction a6xx_pm_suspendfunction a6xx_get_timestamp
Annotated Snippet
fence_status_check(gpu, offset, value, status, mask), 0, 1000)) {
/*
* The 'delay' warning is here because the pause to print this
* warning will allow gpu to move to power collapse which
* defeats the purpose of continuous polling for 2 ms
*/
dev_err_ratelimited(gmu->dev, "delay in fenced register write (0x%x)\n",
offset);
return 0;
}
dev_err_ratelimited(gmu->dev, "fenced register write (0x%x) fail\n",
offset);
return -ETIMEDOUT;
}
int a6xx_fenced_write(struct a6xx_gpu *a6xx_gpu, u32 offset, u64 value, u32 mask, bool is_64b)
{
int ret;
ret = fenced_write(a6xx_gpu, offset, lower_32_bits(value), mask);
if (ret)
return ret;
if (!is_64b)
return 0;
ret = fenced_write(a6xx_gpu, offset + 1, upper_32_bits(value), mask);
return ret;
}
static inline bool _a6xx_check_idle(struct msm_gpu *gpu)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
/* Check that the GMU is idle */
if (!adreno_has_gmu_wrapper(adreno_gpu) && !a6xx_gmu_isidle(&a6xx_gpu->gmu))
return false;
/* Check tha the CX master is idle */
if (gpu_read(gpu, REG_A6XX_RBBM_STATUS) &
~A6XX_RBBM_STATUS_CP_AHB_BUSY_CX_MASTER)
return false;
return !(gpu_read(gpu, REG_A6XX_RBBM_INT_0_STATUS) &
A6XX_RBBM_INT_0_MASK_RBBM_HANG_DETECT);
}
static bool a6xx_idle(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
{
/* wait for CP to drain ringbuffer: */
if (!adreno_idle(gpu, ring))
return false;
if (spin_until(_a6xx_check_idle(gpu))) {
DRM_ERROR("%s: %ps: timeout waiting for GPU to idle: status %8.8X irq %8.8X rptr/wptr %d/%d\n",
gpu->name, __builtin_return_address(0),
gpu_read(gpu, REG_A6XX_RBBM_STATUS),
gpu_read(gpu, REG_A6XX_RBBM_INT_0_STATUS),
gpu_read(gpu, REG_A6XX_CP_RB_RPTR),
gpu_read(gpu, REG_A6XX_CP_RB_WPTR));
return false;
}
return true;
}
static void update_shadow_rptr(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
/* Expanded APRIV doesn't need to issue the WHERE_AM_I opcode */
if (a6xx_gpu->has_whereami && !adreno_gpu->base.hw_apriv) {
OUT_PKT7(ring, CP_WHERE_AM_I, 2);
OUT_RING(ring, lower_32_bits(shadowptr(a6xx_gpu, ring)));
OUT_RING(ring, upper_32_bits(shadowptr(a6xx_gpu, ring)));
}
}
void a6xx_flush(struct msm_gpu *gpu, struct msm_ringbuffer *ring)
{
struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu);
struct a6xx_gpu *a6xx_gpu = to_a6xx_gpu(adreno_gpu);
uint32_t wptr;
unsigned long flags;
Annotation
- Immediate include surface: `msm_gem.h`, `msm_mmu.h`, `msm_gpu_trace.h`, `msm_perfcntr.h`, `a6xx_gpu.h`, `a6xx_gmu.xml.h`, `linux/bitfield.h`, `linux/devfreq.h`.
- Detected declarations: `function a6xx_gmu_get_timestamp`, `function fence_status_check`, `function fenced_write`, `function a6xx_fenced_write`, `function _a6xx_check_idle`, `function a6xx_idle`, `function update_shadow_rptr`, `function a6xx_flush`, `function a6xx_flush_yield`, `function get_stats_counter`.
- 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.