drivers/gpu/drm/stm/ltdc.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/stm/ltdc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/stm/ltdc.c- Extension
.c- Size
- 64825 bytes
- Lines
- 2115
- 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/delay.hlinux/interrupt.hlinux/media-bus-format.hlinux/module.hlinux/of.hlinux/of_graph.hlinux/pinctrl/consumer.hlinux/platform_device.hlinux/pm_runtime.hlinux/regmap.hlinux/reset.hdrm/drm_atomic.hdrm/drm_atomic_helper.hdrm/drm_blend.hdrm/drm_bridge.hdrm/drm_device.hdrm/drm_edid.hdrm/drm_fb_dma_helper.hdrm/drm_fourcc.hdrm/drm_framebuffer.hdrm/drm_gem_atomic_helper.hdrm/drm_gem_dma_helper.hdrm/drm_of.hdrm/drm_print.hdrm/drm_probe_helper.hdrm/drm_simple_kms_helper.hdrm/drm_vblank.hdrm/drm_managed.hvideo/videomode.hltdc.h
Detected Declarations
enum ltdc_pix_fmtfunction to_ltdc_pixelformatfunction ltdc_set_flexible_pixel_formatfunction is_xrgbfunction ltdc_set_ycbcr_configfunction ltdc_set_ycbcr_coeffsfunction ltdc_irq_crc_handlefunction ltdc_irq_threadfunction ltdc_irqfunction ltdc_crtc_update_clutfunction ltdc_crtc_atomic_enablefunction ltdc_crtc_atomic_disablefunction ltdc_crtc_mode_validfunction ltdc_crtc_mode_fixupfunction ltdc_crtc_mode_set_nofbfunction ltdc_crtc_atomic_flushfunction ltdc_crtc_get_scanout_positionfunction ltdc_crtc_enable_vblankfunction ltdc_crtc_disable_vblankfunction ltdc_crtc_set_crc_sourcefunction ltdc_crtc_verify_crc_sourcefunction ltdc_crtc_atomic_print_statefunction ltdc_plane_atomic_checkfunction ltdc_plane_atomic_updatefunction ltdc_plane_atomic_disablefunction ltdc_plane_atomic_print_statefunction ltdc_crtc_initfunction ltdc_encoder_disablefunction ltdc_encoder_enablefunction ltdc_encoder_mode_setfunction ltdc_encoder_initfunction ltdc_get_capsfunction ltdc_suspendfunction ltdc_resumefunction ltdc_loadfunction ltdc_unload
Annotated Snippet
if (en_iter->crtc == crtc) {
encoder = en_iter;
break;
}
if (encoder) {
/* get bridge from encoder */
list_for_each_entry(br_iter, &encoder->bridge_chain, chain_node)
if (br_iter->encoder == encoder) {
bridge = br_iter;
break;
}
/* Get the connector from encoder */
drm_connector_list_iter_begin(ddev, &iter);
drm_for_each_connector_iter(connector, &iter)
if (connector->encoder == encoder)
break;
drm_connector_list_iter_end(&iter);
}
if (bridge && bridge->timings) {
bus_flags = bridge->timings->input_bus_flags;
} else if (connector) {
bus_flags = connector->display_info.bus_flags;
if (connector->display_info.num_bus_formats)
bus_formats = connector->display_info.bus_formats[0];
}
if (!pm_runtime_active(ddev->dev)) {
ret = pm_runtime_get_sync(ddev->dev);
if (ret) {
drm_err(crtc->dev, "Failed to set mode, cannot get sync\n");
return;
}
}
drm_dbg_driver(crtc->dev, "CRTC:%d mode:%s\n", crtc->base.id, mode->name);
drm_dbg_driver(crtc->dev, "Video mode: %dx%d", mode->hdisplay, mode->vdisplay);
drm_dbg_driver(crtc->dev, " hfp %d hbp %d hsl %d vfp %d vbp %d vsl %d\n",
mode->hsync_start - mode->hdisplay,
mode->htotal - mode->hsync_end,
mode->hsync_end - mode->hsync_start,
mode->vsync_start - mode->vdisplay,
mode->vtotal - mode->vsync_end,
mode->vsync_end - mode->vsync_start);
/* Convert video timings to ltdc timings */
hsync = mode->hsync_end - mode->hsync_start - 1;
vsync = mode->vsync_end - mode->vsync_start - 1;
accum_hbp = mode->htotal - mode->hsync_start - 1;
accum_vbp = mode->vtotal - mode->vsync_start - 1;
accum_act_w = accum_hbp + mode->hdisplay;
accum_act_h = accum_vbp + mode->vdisplay;
total_width = mode->htotal - 1;
total_height = mode->vtotal - 1;
/* Configures the HS, VS, DE and PC polarities. Default Active Low */
val = 0;
if (mode->flags & DRM_MODE_FLAG_PHSYNC)
val |= GCR_HSPOL;
if (mode->flags & DRM_MODE_FLAG_PVSYNC)
val |= GCR_VSPOL;
if (bus_flags & DRM_BUS_FLAG_DE_LOW)
val |= GCR_DEPOL;
if (bus_flags & DRM_BUS_FLAG_PIXDATA_DRIVE_NEGEDGE)
val |= GCR_PCPOL;
regmap_update_bits(ldev->regmap, LTDC_GCR,
GCR_HSPOL | GCR_VSPOL | GCR_DEPOL | GCR_PCPOL, val);
/* Set Synchronization size */
val = (hsync << 16) | vsync;
regmap_update_bits(ldev->regmap, LTDC_SSCR, SSCR_VSH | SSCR_HSW, val);
/* Set Accumulated Back porch */
val = (accum_hbp << 16) | accum_vbp;
regmap_update_bits(ldev->regmap, LTDC_BPCR, BPCR_AVBP | BPCR_AHBP, val);
/* Set Accumulated Active Width */
val = (accum_act_w << 16) | accum_act_h;
regmap_update_bits(ldev->regmap, LTDC_AWCR, AWCR_AAW | AWCR_AAH, val);
/* Set total width & height */
val = (total_width << 16) | total_height;
regmap_update_bits(ldev->regmap, LTDC_TWCR, TWCR_TOTALH | TWCR_TOTALW, val);
Annotation
- Immediate include surface: `linux/clk.h`, `linux/component.h`, `linux/delay.h`, `linux/interrupt.h`, `linux/media-bus-format.h`, `linux/module.h`, `linux/of.h`, `linux/of_graph.h`.
- Detected declarations: `enum ltdc_pix_fmt`, `function to_ltdc_pixelformat`, `function ltdc_set_flexible_pixel_format`, `function is_xrgb`, `function ltdc_set_ycbcr_config`, `function ltdc_set_ycbcr_coeffs`, `function ltdc_irq_crc_handle`, `function ltdc_irq_thread`, `function ltdc_irq`, `function ltdc_crtc_update_clut`.
- 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.