drivers/gpu/drm/imx/lcdc/imx-lcdc.c
Source file repositories/reference/linux-study-clean/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
File Facts
- System
- Linux kernel
- Corpus path
drivers/gpu/drm/imx/lcdc/imx-lcdc.c- Extension
.c- Size
- 17931 bytes
- Lines
- 536
- 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
drm/clients/drm_client_setup.hdrm/drm_bridge.hdrm/drm_bridge_connector.hdrm/drm_damage_helper.hdrm/drm_drv.hdrm/drm_fbdev_dma.hdrm/drm_fb_dma_helper.hdrm/drm_fourcc.hdrm/drm_framebuffer.hdrm/drm_gem_atomic_helper.hdrm/drm_gem_dma_helper.hdrm/drm_gem_framebuffer_helper.hdrm/drm_of.hdrm/drm_print.hdrm/drm_probe_helper.hdrm/drm_simple_kms_helper.hdrm/drm_vblank.hlinux/bitfield.hlinux/clk.hlinux/dma-mapping.hlinux/mod_devicetable.hlinux/module.hlinux/platform_device.h
Detected Declarations
struct imx_lcdcfunction imx_lcdc_get_formatfunction imx_lcdc_update_hw_registersfunction imx_lcdc_pipe_enablefunction imx_lcdc_pipe_disablefunction imx_lcdc_pipe_checkfunction imx_lcdc_pipe_updatefunction imx_lcdc_irq_handlerfunction imx_lcdc_probefunction imx_lcdc_removefunction imx_lcdc_shutdown
Annotated Snippet
struct imx_lcdc {
struct drm_device drm;
struct drm_simple_display_pipe pipe;
struct drm_connector *connector;
void __iomem *base;
struct clk *clk_ipg;
struct clk *clk_ahb;
struct clk *clk_per;
};
static const u32 imx_lcdc_formats[] = {
DRM_FORMAT_RGB565, DRM_FORMAT_XRGB8888,
};
static inline struct imx_lcdc *imx_lcdc_from_drmdev(struct drm_device *drm)
{
return container_of(drm, struct imx_lcdc, drm);
}
static unsigned int imx_lcdc_get_format(unsigned int drm_format)
{
switch (drm_format) {
default:
DRM_WARN("Format not supported - fallback to XRGB8888\n");
fallthrough;
case DRM_FORMAT_XRGB8888:
return BPP_XRGB8888;
case DRM_FORMAT_RGB565:
return BPP_RGB565;
}
}
static void imx_lcdc_update_hw_registers(struct drm_simple_display_pipe *pipe,
struct drm_plane_state *old_state,
bool mode_set)
{
struct drm_crtc *crtc = &pipe->crtc;
struct drm_plane_state *new_state = pipe->plane.state;
struct drm_framebuffer *fb = new_state->fb;
struct imx_lcdc *lcdc = imx_lcdc_from_drmdev(pipe->crtc.dev);
u32 lpcr, lvcr, lhcr;
u32 framesize;
dma_addr_t addr;
addr = drm_fb_dma_get_gem_addr(fb, new_state, 0);
/* The LSSAR register specifies the LCD screen start address (SSA). */
writel(addr, lcdc->base + IMX21LCDC_LSSAR);
if (!mode_set)
return;
/* Disable PER clock to make register write possible */
if (old_state && old_state->crtc && old_state->crtc->enabled)
clk_disable_unprepare(lcdc->clk_per);
/* Framesize */
framesize = FIELD_PREP(IMX21LCDC_LSR_XMAX, crtc->mode.hdisplay >> 4) |
FIELD_PREP(IMX21LCDC_LSR_YMAX, crtc->mode.vdisplay);
writel(framesize, lcdc->base + IMX21LCDC_LSR);
/* HSYNC */
lhcr = FIELD_PREP(IMX21LCDC_LHCR_HFPORCH, crtc->mode.hsync_start - crtc->mode.hdisplay - 1) |
FIELD_PREP(IMX21LCDC_LHCR_HWIDTH, crtc->mode.hsync_end - crtc->mode.hsync_start - 1) |
FIELD_PREP(IMX21LCDC_LHCR_HBPORCH, crtc->mode.htotal - crtc->mode.hsync_end - 3);
writel(lhcr, lcdc->base + IMX21LCDC_LHCR);
/* VSYNC */
lvcr = FIELD_PREP(IMX21LCDC_LVCR_VFPORCH, crtc->mode.vsync_start - crtc->mode.vdisplay) |
FIELD_PREP(IMX21LCDC_LVCR_VWIDTH, crtc->mode.vsync_end - crtc->mode.vsync_start) |
FIELD_PREP(IMX21LCDC_LVCR_VBPORCH, crtc->mode.vtotal - crtc->mode.vsync_end);
writel(lvcr, lcdc->base + IMX21LCDC_LVCR);
lpcr = readl(lcdc->base + IMX21LCDC_LPCR);
lpcr &= ~IMX21LCDC_LPCR_BPIX;
lpcr |= FIELD_PREP(IMX21LCDC_LPCR_BPIX, imx_lcdc_get_format(fb->format->format));
writel(lpcr, lcdc->base + IMX21LCDC_LPCR);
/* Virtual Page Width */
writel(new_state->fb->pitches[0] / 4, lcdc->base + IMX21LCDC_LVPWR);
/* Enable PER clock */
if (new_state->crtc->enabled)
clk_prepare_enable(lcdc->clk_per);
}
static void imx_lcdc_pipe_enable(struct drm_simple_display_pipe *pipe,
struct drm_crtc_state *crtc_state,
Annotation
- Immediate include surface: `drm/clients/drm_client_setup.h`, `drm/drm_bridge.h`, `drm/drm_bridge_connector.h`, `drm/drm_damage_helper.h`, `drm/drm_drv.h`, `drm/drm_fbdev_dma.h`, `drm/drm_fb_dma_helper.h`, `drm/drm_fourcc.h`.
- Detected declarations: `struct imx_lcdc`, `function imx_lcdc_get_format`, `function imx_lcdc_update_hw_registers`, `function imx_lcdc_pipe_enable`, `function imx_lcdc_pipe_disable`, `function imx_lcdc_pipe_check`, `function imx_lcdc_pipe_update`, `function imx_lcdc_irq_handler`, `function imx_lcdc_probe`, `function imx_lcdc_remove`.
- 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.