drivers/gpu/drm/vc4/vc4_crtc.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/vc4/vc4_crtc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/vc4/vc4_crtc.c- Extension
.c- Size
- 44527 bytes
- Lines
- 1543
- 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
linux/clk.hlinux/component.hlinux/of.hlinux/platform_device.hlinux/pm_runtime.hdrm/drm_atomic.hdrm/drm_atomic_helper.hdrm/drm_atomic_uapi.hdrm/drm_fb_dma_helper.hdrm/drm_framebuffer.hdrm/drm_drv.hdrm/drm_print.hdrm/drm_probe_helper.hdrm/drm_vblank.hvc4_drv.hvc4_hdmi.hvc4_regs.h
Detected Declarations
struct vc4_async_flip_statefunction vc4_crtc_get_cob_allocationfunction bitsfunction vc4_crtc_get_scanout_positionfunction vc4_get_fifo_full_levelfunction vc4_crtc_get_fifo_full_level_bitsfunction vc4_crtc_pixelvalve_resetfunction vc4_crtc_config_pvfunction require_hvs_enabledfunction vc4_crtc_disablefunction vc4_crtc_disable_at_bootfunction vc4_crtc_send_vblankfunction vc4_crtc_atomic_disablefunction vc4_crtc_atomic_enablefunction vc4_crtc_mode_validfunction vc4_crtc_get_marginsfunction vc4_crtc_get_marginsfunction vc4_crtc_atomic_checkfunction for_each_new_connector_in_statefunction vc4_enable_vblankfunction vc4_disable_vblankfunction vc4_crtc_handle_page_flipfunction vc4_crtc_handle_vblankfunction vc4_crtc_irq_handlerfunction vc4_async_page_flip_completefunction vc4_async_page_flip_complete_with_cleanupfunction vc4_async_page_flip_fence_completefunction vc4_async_set_fence_cbfunction vc4_async_page_flip_commonfunction vc4_async_page_flipfunction vc5_async_page_flipfunction vc4_page_flipfunction vc4_crtc_destroy_statefunction vc4_crtc_resetfunction vc4_crtc_late_registerfunction vc4_set_crtc_possible_masksfunction drm_for_each_encoderfunction vc4_crtc_initfunction vc4_crtc_initfunction vc4_crtc_bindfunction vc4_crtc_unbindfunction vc4_crtc_dev_probefunction vc4_crtc_dev_remove
Annotated Snippet
struct vc4_async_flip_state {
struct drm_crtc *crtc;
struct drm_framebuffer *fb;
struct drm_framebuffer *old_fb;
struct drm_pending_vblank_event *event;
struct dma_fence_cb cb;
};
/* Called when the V3D execution for the BO being flipped to is done, so that
* we can actually update the plane's address to point to it.
*/
static void
vc4_async_page_flip_complete(struct vc4_async_flip_state *flip_state)
{
struct drm_crtc *crtc = flip_state->crtc;
struct drm_device *dev = crtc->dev;
struct drm_plane *plane = crtc->primary;
vc4_plane_async_set_fb(plane, flip_state->fb);
if (flip_state->event) {
unsigned long flags;
spin_lock_irqsave(&dev->event_lock, flags);
drm_crtc_send_vblank_event(crtc, flip_state->event);
spin_unlock_irqrestore(&dev->event_lock, flags);
}
drm_crtc_vblank_put(crtc);
drm_framebuffer_put(flip_state->fb);
if (flip_state->old_fb)
drm_framebuffer_put(flip_state->old_fb);
kfree(flip_state);
}
static void vc4_async_page_flip_complete_with_cleanup(struct dma_fence *fence,
struct dma_fence_cb *cb)
{
struct vc4_async_flip_state *flip_state =
container_of(cb, struct vc4_async_flip_state, cb);
struct vc4_bo *bo = NULL;
if (flip_state->old_fb) {
struct drm_gem_dma_object *dma_bo =
drm_fb_dma_get_gem_obj(flip_state->old_fb, 0);
bo = to_vc4_bo(&dma_bo->base);
}
vc4_async_page_flip_complete(flip_state);
dma_fence_put(fence);
/*
* Decrement the BO usecnt in order to keep the inc/dec
* calls balanced when the planes are updated through
* the async update path.
*
* FIXME: we should move to generic async-page-flip when
* it's available, so that we can get rid of this
* hand-made cleanup_fb() logic.
*/
if (bo)
vc4_bo_dec_usecnt(bo);
}
static void vc4_async_page_flip_fence_complete(struct dma_fence *fence,
struct dma_fence_cb *cb)
{
struct vc4_async_flip_state *flip_state =
container_of(cb, struct vc4_async_flip_state, cb);
vc4_async_page_flip_complete(flip_state);
dma_fence_put(fence);
}
static int vc4_async_set_fence_cb(struct drm_device *dev,
struct vc4_async_flip_state *flip_state)
{
struct drm_framebuffer *fb = flip_state->fb;
struct drm_gem_dma_object *dma_bo = drm_fb_dma_get_gem_obj(fb, 0);
dma_fence_func_t async_page_flip_complete_function;
struct vc4_dev *vc4 = to_vc4_dev(dev);
struct dma_fence *fence;
int ret;
if (vc4->gen == VC4_GEN_4)
async_page_flip_complete_function = vc4_async_page_flip_complete_with_cleanup;
else
async_page_flip_complete_function = vc4_async_page_flip_fence_complete;
Annotation
- Immediate include surface: `linux/clk.h`, `linux/component.h`, `linux/of.h`, `linux/platform_device.h`, `linux/pm_runtime.h`, `drm/drm_atomic.h`, `drm/drm_atomic_helper.h`, `drm/drm_atomic_uapi.h`.
- Detected declarations: `struct vc4_async_flip_state`, `function vc4_crtc_get_cob_allocation`, `function bits`, `function vc4_crtc_get_scanout_position`, `function vc4_get_fifo_full_level`, `function vc4_crtc_get_fifo_full_level_bits`, `function vc4_crtc_pixelvalve_reset`, `function vc4_crtc_config_pv`, `function require_hvs_enabled`, `function vc4_crtc_disable`.
- 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.